pax_global_header00006660000000000000000000000064147703476200014524gustar00rootroot0000000000000052 comment=4f6235c2edf7d7a053723d940218ed5f2a3183b8 backintime-1.5.4/000077500000000000000000000000001477034762000136415ustar00rootroot00000000000000backintime-1.5.4/.codespellrc000066400000000000000000000033141477034762000161420ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian Buhtz # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory # go to # and . [codespell] # Folders and files to skip skip = .codespellrc,*.po,Makefile,*.desktop,.git,__pycache__,*.pyc,#*#,languages.py,_build,TRANSLATIONS,./doc/manual/html,mkdocs.yml,configure # Print N lines of surrounding context context = 1 # Check hidden files also (empty means True) check-hidden= # Print number of errors as last line on stderr (empty means True) count= # Dictionaries to use (default: "clear,rare"). Current: all. builtin = clear,rare,informal,usage,code,names,en-GB_to_en-US # Allowed (ignored) words ignore-words-list=master,whitelist,manuel,dum,assertIn # Allowed (ignored) words in URLs and URIs uri-ignore-words-list=mitre,Archiv # Good to know about allowed/ignored words: # Codespell acts a bit unusual when it comes to case-sensitivity. # By default the word "Manuel" is an error and codespell recommends to # modify it into "Manual". To allow this German name "Manuel" we have to # add "manual" (lower case!) to the "ignore-words-list". The upper-case # version do not work. # See: https://github.com/codespell-project/codespell/issues/3210 # Simulate "# noqa" and ignore all lines with "# codespell-ignore" at the end. # Credits: https://github.com/codespell-project/codespell/issues/1212#issuecomment-1721152455 ignore-regex=.*# codespell-ignore$ backintime-1.5.4/.github/000077500000000000000000000000001477034762000152015ustar00rootroot00000000000000backintime-1.5.4/.github/ISSUE_TEMPLATE/000077500000000000000000000000001477034762000173645ustar00rootroot00000000000000backintime-1.5.4/.github/ISSUE_TEMPLATE/bug.yml000066400000000000000000000020731477034762000206660ustar00rootroot00000000000000name: Bug report description: Submit a bug report body: - type: markdown attributes: value: | 👉 Ask **support questions** in the GNU/Linux community or on our [mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org). Please respect the limited resources of the maintenance team. 👉 Provide the output of the console command `backintime --diagnostics`, to help us diagnose the problem quickly. 👉 Please specify as precisely as you can the package or installation source where you got _Back In Time_ from. 👉 As an **alternative** fell free to use our [mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org) for every topic about _Back In Time_. - type: textarea attributes: label: "Describe the problem, feature or ask a question:" description: "Please remember that this project is maintained by volunteers in their free time – human beings just like you – so we kindly ask for your understanding and constructive feedback as we work to address reported issues." backintime-1.5.4/.github/ISSUE_TEMPLATE/config.yml000066400000000000000000000000341477034762000213510ustar00rootroot00000000000000blank_issues_enabled: false backintime-1.5.4/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000003101477034762000207740ustar00rootroot00000000000000AI-generated content is strictly prohibited. Accounts submitting such material will be reported for abuse to Microsoft GitHub . Consider adding a CHANGELOG entry. Run "codespell" to check for typos. backintime-1.5.4/.github/REUSE.toml000066400000000000000000000011721477034762000167620ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = ["*.md", "**/*.yml"] SPDX-License-Identifier = "CC0-1.0" SPDX-FileCopyrightText = "© 2022 Back In Time" backintime-1.5.4/.gitignore000066400000000000000000000023361477034762000156350ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See folder LICENSES or # go to # and . # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # editor backup and temp files *~ *.sic *.swp \#*\# .\#* # packaging *.deb debian/debhelper-build-stamp debian/*.debhelper debian/*.debhelper.log debian/*.substvars debian/files debian/backintime-common debian/backintime-gnome debian/backintime-kde debian/backintime-kde4 debian/backintime-notify debian/backintime-qt # compressed files *.gz # Compiled translations *.mo # Makefile common/Makefile qt/Makefile # coveralls.io status .coverage # coverage result files (raw data and reports) # .coverage # already ignored, see above **/htmlcov/** # sphinx doc build common/doc-dev/_build/doctrees common/doc-dev/_build/html # MkDocs doc/manual/html/ # PyCharm IDE project settings .idea # Linter configuration .flake8 backintime-1.5.4/.readthedocs.yaml000066400000000000000000000026421477034762000170740ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or # go to # and . # # This is the configuration file for the Read the Docs service. # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details. # Required version: 2 # Set the version of Python and other tools you might need build: os: ubuntu-22.04 tools: python: "3" jobs: # Workaround: See PR #1554 for details. # When migrating to use a pyprojects.toml file switch from this # workaround to the use of "python: install: extra_requirements..." # See also: https://docs.readthedocs.io/en/stable/config-file/v2.html#packages post_create_environment: - python -m pip install sphinx_rtd_theme # Build documentation in the docs/ directory with Sphinx sphinx: configuration: common/doc-dev/conf.py # fail_on_warning: true # We recommend specifying your dependencies to enable reproducible builds: # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html # python: # install: # - method: pip # path: . # extra_requirements: # - foo backintime-1.5.4/.travis.yml000066400000000000000000000041421477034762000157530ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # # TravisCI (https://travis-ci.org) configuration file os: linux # Support End of "Focal" (20.04 LTS) is April 2025 # dist: focal # Support End of "Jammy" (22.04 LTS) is April 2027 # dist: jammy # Support End of "noble" (24.04 LTS) is April 2029 dist: noble language: python arch: - amd64 python: - "3.9" - "3.10" - "3.11" - "3.12" - "3.13" addons: # add localhost to known_hosts to prevent ssh unknown host prompt during unit tests ssh_known_hosts: localhost env: # TravisCI support said this could prevent errors from "make". PYTHONUNBUFFERED=1 before_install: # disable mongodb as we don't need it and it sometimes temporary fails # https://github.com/travis-ci/travis-ci/issues/4937#issuecomment-149289729 - sudo rm -f /etc/apt/sources.list.d/mongodb*.list - sudo apt-key del 90CFB1F5 - sudo apt-get -qq update # install screen, and util-linux (provides flock) for test_sshtools - sudo apt-get install -y sshfs screen util-linux libdbus-1-dev # jobs: # exclude: # - python: "3.9" # - python: "3.10" # - python: "3.11" # - python: "3.12" install: - pip install -U pip - pip install pylint ruff flake8 pyfakefs keyring - pip install pyqt6 dbus-python # add ssh public / private key pair to ensure user can start ssh session to localhost for tests - ssh-keygen -b 2048 -t rsa -f /home/travis/.ssh/id_rsa -N "" - cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # start ssh-agent so that we can add private keys - eval `ssh-agent -s` script: # compile all files - ensure that syntax is correct - python -m compileall common common/test common/plugins qt qt/test qt/plugins # run unit tests - ensure that functionality is correct - cd common - ./configure - make unittest-v - cd .. - cd qt - ./configure - make - pytest --verbose backintime-1.5.4/AUTHORS000066400000000000000000000003421477034762000147100ustar00rootroot00000000000000Oprea Dan () Bart de Koning () Richard Bailey () Germar Reitze () Taylor Raack () Christian Buhtz Michael Büker Jürgen Altfeld backintime-1.5.4/CHANGES000066400000000000000000001767171477034762000146570ustar00rootroot00000000000000Back In Time Version 1.5.4 (2025-03-24) * Breaking Change: Auto-remove rules "Free inodes" and "Free space" disabled by default in new created profiles (#1976) * Changed: Completed license information to conform to REUSE.software and SPDX standards. * Changed: More clear and intense warning about EncFS deprecation and removal (#1904) * Changed: Updated desktop entry files * Changed: Move several values from config file into new introduce state file ($XDG_STATE_HOME/backintime.json) * Fix!: Smart-remove rule "Keep one snapshots per week or the last week" use calendar weeks * Fix: Exclude patterns are now case-sensitive when added (#2040) * Fix: The width of the fourth column in files view is now saved * Fix: Snapshot compare copy symlink as symlink (#1902) (Peter Sevens @sevens) * Fix: Crash when comparing a snapshot with a symlink pointing to a nonexistent target (Peter Sevens @sevens) * Fix: Crash (KeyError) opening language setup dialog with unknown locale/language * Doc: Remove & Retention (formally known as Auto-/Smart-Remove) with improved GUI and user manual section (#2000) * Feature: Open user manual (local if available otherwise online) via Help menu * Feature: Toolbar context menu to display the buttons in different combinations with icons and text (#1105, #2002) (Samuel Moore @s4moore) * Feature: Add offset minutes to hourly schedules (David Gibbs @fallingrock) Version 1.5.3 (2024-11-13) * Doc: User manual (build with MkDocs) (#1838) (Kosta Vukicevic @stcksmsh) * Doc: User-callback topic in user manual (#1659) * Feature: Support language Interlingua (Occidental) * Feature: Warn if destination directory is formatted as NTFS (#1854) (David Gibbs @fallingrock) * Breaking Change: Minimal Python version 3.9 required (#1731) * Breaking Change: Auto migration of config version 4 or lower not longer supported (#1857) * Fix: Prevent duplicates in Exclude/Include list of Manage Profiles dialog * Fix: Fix Qt segmentation fault when canceling out of unconfigured BiT (#1095) (Derek Veit @DerekVeit) * Fix: Correct global flock fallbacks (#1834) (Timothy Southwick @NickNackGus) * Fix: Use SSH key password only if it is valid, otherwise request it from user (#1852) (David Wales @daviewales) * Feature: Support fcron (#610) * Feature: User message about release candidate (#1906) * Refactor: General tab and its Schedule section * Refactor: Own module for Manage Profiles dialog and separate Generals tab code (#1865) * Refactor: Remove class OrderedSet * Refactor: Remove os.system() from class Execute * Refactor: Systray notifications send utilize DBUS instead of notify-send (#1156) (Felix Stupp @Zocker1999NET) * Refactor!: Remove unused config field "user_callback.no_logging" (#1887) * Refactor!: Remove eCryptFS check for home folder (#1855) * Dependency: Remove libnotify-bin (notify-send) (#1156) * Dependency: PyFakeFS minimal version 5.6 (#1911) * Build: Replace "pycodestyle" linter with "flake8" (#1839) Version 1.5.2 (2024-08-06) * Fix: Ensure crontab with ending newline (#781) * Fix(translation): Correct corrupt translated strings in Basque, Islandic and Spanish causing application crashes (#1828) * Build(translation): Language helper script processing syntax checks on po-files Version 1.5.1 (2024-07-27) * Fix: Use correct port to ping SSH Proxy (#1815) Version 1.5.0 (2024-07-26) * Dependency: Migration to PyQt6 * Breaking Change: EncFS deprecation warning (#1735, #1734) * Breaking Change: GUI started with --debug does no longer add --debug to the crontab for scheduled profiles. Use the new "enable logging for debug messages" in the 'Schedule' section of the 'Manage profiles' GUI instead. * Feature: Warn if Cron is not running (#1747) * Feature: Profile and GUI allow to activate debug output for scheduled jobs by adding '--debug' to crontab entry (#1616, contributed by @stcksmsh Kosta Vukicevic) * Feature: Support SSH proxy (jump) host (#1688) (@cgrinham, Christie Grinham) * Feature: Support rsync '--one-file-system' in Expert Options (#1598) * Feature: "*-dev" version strings contain last commit hash (#1637) * Fix: Global flock fallback to single-user mode if insufficient permissions (#1743, #1751) * Fix: Fix Qt segmentation fault with uninstall ExtraMouseButtonEventFilter when closing main window (#1095) * Fix: Names of weekdays and months translated correct (#1729) * Fix: Global flock for multiple users (#1122, #1676) * Fix bug: "Backup folders" list does reflect the selected snapshot (#1585) (@rafaelhdr Rafael Hurpia da Rocha) * Fix: Validation of diff command settings in compare snapshots dialog (#1662) (@stcksmsh Kosta Vukicevic) * Fix bug: Open symlinked folders in file view (#1476) * Fix bug: Respect dark mode using color roles (#1601) * Fix: "Highly recommended" exclusion pattern in "Manage Profile" dialog's "Exclude" tab show missing only (#1620) * Fix bug: `make install` ignored $(DEST) in file migration part (#1630) * Removed: Context menu in LogViewDialog (#1578) * Removed: Field "filesystem_mount" and "snapshot_version" in "info" file (#1684) * Refactor: Replace Config.user() with getpass.getuser() (#1694) * Chore!: Remove "debian" folder (#1548) * Build: Enable several PyLint rules (#1755, #1766) * Build: Add AppStream meta data (#1642) * Build: PyLint unit test is skipped if PyLint isn't installed, but will always run on TravisCI (#1634) * Build: Git commit hash is presevered while "make install" (#1637) * Build: Fix bash-completion symlink creation while installing & adding --diagnostics (#1615) * Build: TravisCI use PyQt (except arch "ppc64le") Version 1.4.3 (2024-01-30) * Feature: Exclude 'SingletonLock' and 'SingletonCookie' (Discord) and 'lock' (Mozilla Firefox) files by default (part of #1555) * Work around: Relax `rsync` exit code 23: Ignore instead of error now (part of #1587) * Feature (experimental): Add new snapshot log filter `rsync transfer failures (experimental)` to find them easier (they are normally not shown as "error"). This feature is experimental because it is based on hard-coded error message strings in the rsync source code and may possibly not find all rsync messages or show false positives. * Fix bug: 'qt5_probing.py' hangs when BiT is run as root and no user is logged into a desktop environment (#1592 and #1580) * Fix bug: Launching BiT GUI (root) hangs on Wayland without showing the GUI (#836) * Improve: Launcher for BiT GUI (root) does not enforce Wayland anymore but uses same settings as for BiT GUI (userland) (#1350) * Fix bug: Disabling suspend during taking a backup ("inhibit suspend") hangs when BiT is run as root and no user is logged into a desktop environment (#1592) * Change of semantics: BiT running as root never disables suspend during taking a backup ("inhibit suspend") even though this may have worked before in BiT <= v1.4.1 sometimes (required to fix #1592) * Fix bug: RTE: module 'qttools' has no attribute 'initate_translator' with encFS when prompting the user for a password (#1553). * Fix bug: Schedule dropdown menu used "minutes" instead of "hours". * Fix bug: Unhandled exception "TypeError: 'NoneType' object is not callable" in tools.py function __log_keyring_warning (#820). Logging thread removed and logger module correctly initialized as fix. Is "Heisenbug" so 100 % retesting was not possible. * Build: Use PyLint in unit testing to catch E1101 (no-member) errors. * Build: Activate PyLint warning W1401 (anomalous-backslash-in-string). * Build: Add codespell config. * Build: Allow manual specification of python executable (--python=PYTHON_PATH) in common/configure and qt/configure * Build: All starter scripts do use an absolute path to the python executable by default now via common/configure and qt/configure (#1574) * Build: Install dbus configuration file to /usr/share not /etc (#1596) * Build: `configure` does delete old installed files (`qt4plugin.py` and `net.launchpad.backintime.serviceHelper.conf`) that were renamed or moved in a previous release (#1596) * Translation: Minor modifications in source strings and updating language files. * Refactor: Solved circular dependency between tools.py and logger.py to fix #820 * Improved: qtsystrayicon.py, qt5_probing.py, usercallbackplugin.py and all parts of app.py do now also use "backintime" as logging namespace in the syslog to ensure complete log output with `journalctl | grep -i backintime` Version 1.4.1 (2023-10-01) * Dependency: Add "qt translations" to GUI runtime dependencies (#1538). * Build: Unit tests do generically ignore all instead of well-known warnings now (#1539). * Build: Warnings about missing Qt translation now are ignored while testing (#1537). * Fix bug: GUI didn't start when "show hidden files" button was on (#1535). Version 1.4.0 (2023-09-14) * Project: Renamed branch "master" to "main" and started "gitflow" branching model. * Refactor: Renamed qt4plugin.py to systrayiconplugin.py (we are using Qt5 for years now ;-) * Refactor: Removed unfinished feature "Full system backup" (#1526) * Fix bug: AttributeError: can't set attribute 'showHiddenFiles' in app.py (#1532) * Fix bug: Check SSH login works on machines with limited commands (#1442) * Fix bug: Missing icon in SSH private key button (#1364) * Fix bug: Master issue for missing or empty system-tray icon (#1306) * Fix bug: System-tray icon missing or empty (GUI and cron) (#1236) * Fix bug: Improve KDE plasma icon compatibility (#1159) * GUI Change: View last (snapshot) log button in GUI uses "document-open-recent" icon now instead of "document-new" (#1386) * Fix bug: Unit test fails on some machines due to warning "Ignoring XDG_SESSION_TYPE=wayland on Gnome..." (#1429) * Fix bug: Generation of config-manpage caused an error with Debian's Lintian (#1398). * Fix bug: Return empty list in smartRemove (#1392, Debian Bug Report 973760) * Fix bug: Taking a snapshot reports `rsync` errors now even if no snapshot was taken (#1491) * Fix bug: takeSnapshot() recognizes errors now by also evaluating the rsync exit code (#489) Fixes related problem: Killing `rsync` was not handled gracefully (by ignoring the rsync exit code) * Fix bug: The error user-callback is now always called if an error happened while taking a snapshot (#1491) * Fix bug: D-Bus serviceHelper error "LimitExceeded: Maximum length of command line reached (100)": Max command length is now 120 instead of 100 (#1027) * Feature: Introduce new error codes for the "error" user callback (as part of #1491): 5: Error while taking a snapshot. 6: New snapshot taken but with errors. * Feature: The `rsync` exit code is now contained in the snapshot log (part of #489). Example: [E] Error: 'rsync' ended with exit code -9 (negative values are signal numbers, see 'kill -l') * Fix bug: Treat rsync exit code 24 as INFO instead of ERROR (#1506) * Breaking change: Minimal Python version 3.8 required (#1358). * Removed: Handling and checking of user group "fuse" (#1472). * Feature: Exclude /swapfile by default (#1053) * Feature: Rearranged menu bar and its entries in the main window (#1487, #1478). * Feature: Configure user interface language via config file and GUI. * Documentation: Removed outdated docbook (#1345). * Testing: TravisCI now can use dbus * Build: Introduced .readthedocs.yaml as asked by ReadTheDocs.org (#1443). * Dependency: The oxygen icons should be installed with the BiT Qt GUI since they are used as fallback in case of missing icons * Fix bug: Add support for ChainerBackend class as keyring which iterates over all supported keyring backends (#1410) * Translation: Strings to translate now easier to understand for translators (#1448, #1457, #1462, #1465). * Translation: Improved completeness of translations and additional modifications of source strings (#1454, #1512) * Translation: Plural forms support (#1488). * Removed: Translation in Canadian English, British English and Javanese (#1455). * Added: Translation in Persian and Vietnamese (#1460). * Added: Message to users (after 10 starts of BIT Gui) to motivate them contributing translations (#1473). Version 1.3.3 (2023-01-04) * Feature: New command line argument "--diagnostics" to show helpful info for better issue support (#1100) * GUI change: Remove Exit button from the toolbar (#172) * GUI change: Define accelerator keys for menu bar and tabs, as well as toolbar shortcuts (#1104) * Desktop integration: Update .desktop file to mark Back In Time as a single main window program (#1258) * Feature: Write all log output to stderr; do not pollute stdout with INFO and WARNING messages anymore (#1337) * Fix bug: RTE "reentrant call inside io.BufferedWriter" in logFile.flush() during backup (#1003) * Fix bug: Incompatibility with rsync 3.2.4 or later because of rsync's "new argument protection" (#1247). Deactivate "--old-args" rsync argument earlier recommended to users as a workaround. * Fix bug: DeprecationWarnings about invalid escape sequences. * Fix bug: AttributeError in "Diff Options" dialog (#898) * Fix bug: Settings GUI: "Save password to Keyring" was disabled due to "no appropriate keyring found" (#1321) * Fix bug: Back in Time did not start with D-Bus error "dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NameHasNoOwner: Could not get owner of name 'net.launchpad.backintime.serviceHelper': no such name" (fixes client-side part of #921 - system D-Bus part of the Udev serviceHelper is still under investigation). * Fix bug: Avoid logging errors while waiting for a target drive to be mounted (#1142, #1143, #1328) * Fix bug: [Arch Linux] AUR pkg "backintime-git": Build tests fails and installation is aborted (#1233, fixed with #921) * Fix bug: Wrong systray icon showing in Wayland (#1244) * Documentation update: Correct description of profile.schedule.time in backintime-config manpage (#1270) * Translation update: Brazilian Portuguese (#1267) * Translation update: Italian (#1110, #1123) * Translation update: French (#1077) * Testing: Fix a test fail when dealing with an empty crontab (#1181) * Testing: Fix a test fail when dealing with an empty config file (#1305) * Testing: Skip "test_quiet_mode" (does not work reliably) * Testing: Improve "test_diagnostics_arg" (introduced with #1100) to no longer fail when JSON output was mixed with logging output (part of #921, fixes #1233) * Testing: Numerous fixes and extensions to testing (#1115, #1213, #1279, #1280, #1281, #1285, #1288, #1290, #1293, #1309, #1334) Version 1.3.2 (2022-03-12) * Fix bug: Tests no longer work with Python 3.10 (https://github.com/bit-team/backintime/issues/1175) Version 1.3.1 (2021-07-05) * bump version, forgot to push branch to Github before releasing Version 1.3.0 (2021-07-04) * Merge PR: Fix FileNotFoundError exception in mount.mounted, Thanks tatokis (https://github.com/bit-team/backintime/pull/1157) * Merge PR: qt/plugins/notifyplugin: Fix setting self.user, not local variable, Thanks Zocker1999NET (https://github.com/bit-team/backintime/pull/1155) * Merge PR: Use Link Color instead of lightGray as not to break theming, Thanks newhinton (https://github.com/bit-team/backintime/pull/1153) * Merge PR: Match old and new rsync version format, Thanks TheTimeWalker (https://github.com/bit-team/backintime/pull/1139) * Merge PR: 'TempPasswordThread' object has no attribute 'isAlive', Thanks FMeinicke (https://github.com/bit-team/backintime/pull/1135) * Merge PR: Keep permissions of an existing mountpoint from being overridden, Thanks bentolor (https://github.com/bit-team/backintime/pull/1058) * Fix bug: YEAR missing in config (https://github.com/bit-team/backintime/issues/1023) * Fix bug: SSH module didn't send identification string while checking if remote host is available (https://github.com/bit-team/backintime/issues/1030) Version 1.2.1 (2019-08-25) * Fix bug: TypeError in backintime.py if mount failed while running a snapshot (https://github.com/bit-team/backintime/issues/1005) Version 1.2.0 (2019-04-27) * Fix bug: Exit code is linked to the wrong status message (https://github.com/bit-team/backintime/issues/906) * minor changes to allow running BiT inside Docker (https://github.com/bit-team/backintime/pull/959) * Fix bug: AppName showed 'python3' instead of 'Back In Time' (https://github.com/bit-team/backintime/issues/950) * Fix bug: configured cipher is not used with all ssh-commands (https://github.com/bit-team/backintime/issues/934) * remove progressbar on systray icon until BiT has it's own icon (https://github.com/bit-team/backintime/issues/902) * Fix bug: 'make test' fails because local SSH server is running on non-standard port (https://github.com/bit-team/backintime/issues/945) * clarify 'nocache' option (https://github.com/bit-team/backintime/issues/857) * create a config-backup in root dir if backup is encrypted (https://github.com/bit-team/backintime/issues/556) * Fix bug: 23:00 is missing in the list of every day hours (https://github.com/bit-team/backintime/issues/736) * Fix bug: ssh-agent output changed (https://github.com/bit-team/backintime/issues/840) * remove unused and undocumented userscript plugin * Fix bug: exception on making backintime folder world writable (https://github.com/bit-team/backintime/issues/812) * Fix bug: stat free space for snapshot folder instead of backintime folder (https://github.com/bit-team/backintime/issues/733) * add contextmenu for logview dialog which can copy, exclude and decode lines * move progressbar under statusbar * Fix bug: backintime root crontab doesn't run; missing line-feed 0x0A on last line (https://github.com/bit-team/backintime/issues/781) * Fix bug: IndexError in inhibitSuspend (https://github.com/bit-team/backintime/issues/772) * alleviate default exclude [Tt]rash* (https://github.com/bit-team/backintime/issues/759) * enable high DPI scaling (https://github.com/bit-team/backintime/issues/732) * Fix bug: polkit CheckAuthorization: race condition in privilege authorization (https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7572) * Fix bug: OSError when running backup-job from systemd (https://github.com/bit-team/backintime/issues/720) * Smart Remove try to keep healthy snapshots (https://github.com/bit-team/backintime/issues/703) * Fix critical bug: restore filesystem-root without 'Full rsync mode' with ACL and/or xargs activated broke whole system (https://github.com/bit-team/backintime/issues/708) * Fix bug: use current folder if no file is selected in files view (https://github.com/bit-team/backintime/issues/687, https://github.com/bit-team/backintime/issues/685) * Fix bug: don't reload profile after editing profile name (https://github.com/bit-team/backintime/issues/706) * Fix bug: Exception in FileInfo * ask for restore-to path before confirm (https://github.com/bit-team/backintime/issues/678) * fix 'Back in Time (root)' on wayland (https://github.com/bit-team/backintime/issues/640) * sort int values in config numerical instead if alphabetical (https://github.com/bit-team/backintime/issues/175#issuecomment-272941811) * set timestamp directly after new snapshot (https://github.com/bit-team/backintime/issues/584) * add shortcut CTRL+H for toggle show hidden files to fileselect dialog (https://github.com/bit-team/backintime/issues/378) * add 'Edit user-callback' dialog * Fix bug: failed to restore suid permissions (https://github.com/bit-team/backintime/issues/661) * redesign restore menu (https://github.com/bit-team/backintime/issues/661) * Fix bug: on remount user-callback got called AFTER trying to mount (https://github.com/bit-team/backintime/issues/654) * add ability to disable SSH command- and ping-check (https://github.com/bit-team/backintime/issues/647) * enable bwlimit for local profiles (https://github.com/bit-team/backintime/issues/646) * import remote host-key into known_hosts from Settings * copy public SSH key to remote host from Settings * create a new SSH key from Settings * Fix bug: confirm restore dialog has no scroll bar (https://github.com/bit-team/backintime/issues/625) * Fix bug: DEFAULT_EXCLUDE not deletable (https://github.com/bit-team/backintime/issues/634) * rename debian package from backintime-qt4 into backintime-qt * rename paths and methods from *qt4* into *qt* * rename executable backintime-qt4 into backintime-qt * new config version 6, rename qt4 keys into qt, add new domain for schedule * check crontab entries on every GUI startup (https://github.com/bit-team/backintime/issues/129) * start a new ssh-agent instance only if necessary * add cli command 'shutdown' (https://github.com/bit-team/backintime/issues/596) * Fix bug: GUI status bar unreadable (https://github.com/bit-team/backintime/issues/612) * Fix bug: udev schedule not working (https://github.com/bit-team/backintime/issues/605) * add cli command 'smart-remove' * make LogView and Settings Dialog non-modal (https://github.com/bit-team/backintime/issues/608) * Fix bug: decode path spooled from /etc/mtab (https://github.com/bit-team/backintime/pull/607) * Fix bug: in snapshots.py, gives more helpful advice if a lock file is present that shouldn't be. (https://github.com/bit-team/backintime/issues/601) * port to Qt5/pyqt5 (https://github.com/bit-team/backintime/issues/518) * Fix bug: Fail to create remote snapshot path with spaces (https://github.com/bit-team/backintime/issues/567) * Fix bug: broken new_snapshot can run into infinite saveToContinue loop (https://github.com/bit-team/backintime/issues/583) * Recognize changes on previous runs while continuing new snapshots * Fix bug: udev schedule didn't work with LUKS encrypted drives (https://github.com/bit-team/backintime/issues/466) * Add pause, resume and stop function for running snapshots (https://github.com/bit-team/backintime/issues/474, https://github.com/bit-team/backintime/issues/195) * Fix bug: sshMaxArg failed on none default ssh port (https://github.com/bit-team/backintime/issues/581) * Fix bug: failed if remote host send SSH banner (https://github.com/bit-team/backintime/issues/581) * Fix bug: incorrect handling of IPv6 addresses (https://github.com/bit-team/backintime/issues/577) * use rsync to save permissions * replace os.system calls with subprocess.Popen * automatically refresh log view if a snapshot is currently running * Fix bug: Snapshot Log View freeze on big log files (https://github.com/bit-team/backintime/issues/456) * Fix bug: 'inotify_add_watch failed: file or directory not found' after deleting snapshot * remove dependency for extended 'find' command on remote host * make full-rsync mode default, remove the other mode * Fix bug: a continued snapshot was not incremental (https://github.com/bit-team/backintime/issues/557) * use rsync to remove snapshots which will give a nice speedup (https://github.com/bit-team/backintime/issues/151) * open temporary local copy of files instead of original backup on double-click in GUI * add option to decrypt paths in systray menu with mode ssh-encrypted * open current log directly from systray icon during taking a snapshot * add tool-tips to restore menu * Fix bug: config backup in snapshot had wrong name if using --config option * add --share-path option * use Monospace font in logview * add restore option --only-new * add button 'Take snapshot with checksums' * Fix bug: Can't open files with spaces in name (https://github.com/bit-team/backintime/issues/552) * Fix bug: BIT-root won't start from .desktop file (https://github.com/bit-team/backintime/issues/549) * Fix bug: Keyring doesn't work with KDE Plasma5 (https://github.com/bit-team/backintime/issues/545) * Fix bug: Qt4 built-in phrases where not translated (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=816197) * Fix bug: configure ignore unknown args (https://github.com/bit-team/backintime/issues/547) * Fix bug: snapshots-list on command-line was not sorted * Fix bug: SHA256 ssh-key fingerprint was not detected * change default configure option to --no-fuse-group as Ubuntu >= 12.04 don't need fuse group-membership anymore * Fix bug: new snapshot did not show up after finished * Fix bug: TimeLine headers were not correct * Fix lintian warning: manpage-has-errors-from-man: bad argument name 'P' * Fix bug: wildcards ? and [] wasn't recognized correctly * Fix bug: last char of last element in tools.get_rsync_caps got cut off * Fix bug: TypeError in tools.get_git_ref_hash * Do not print 'SnapshotID' or 'SnapshotPath' if running 'snapshots-list' command (and other) with '--quiet' * Remove dependency 'ps' * Fix bug: don't include empty values in list (https://github.com/bit-team/backintime/issues/521) * Fix bug: bash-completion doesn't work for backintime-qt4 * Fix bug: 'make unittest' incorrectly used 'coverage' by default (https://github.com/bit-team/backintime/issues/522) * Fix bug: pm-utils is deprecated; Remove dependency (https://github.com/bit-team/backintime/issues/519) * rewrite huge parts of snapshots.py * remove backwards compatibility to version < 1.0 Version 1.1.24 (2017-11-07) * fix critical bug: CVE-2017-16667: shell injection in notify-send (https://github.com/bit-team/backintime/issues/834) Version 1.1.22 (2017-10-28) * fix bug: stat free space for snapshot folder instead of backintime folder (https://github.com/bit-team/backintime/issues/552733) * backport bug fix: backintime root crontab doesn't run; missing line-feed 0x0A on last line (https://github.com/bit-team/backintime/issues/552781) * backport bug fix: can't open files with spaces in name (https://github.com/bit-team/backintime/issues/552552) Version 1.1.20 (2017-04-09) * backport bug fix: CVE-2017-7572: polkit CheckAuthorization: race condition in privilege authorization Version 1.1.18 (2017-03-29) * Fix bug: manual snapshots from GUI didn't work (https://github.com/bit-team/backintime/issues/728) Version 1.1.16 (2017-03-28) * backport bug fix: start a new ssh-agent instance only if necessary (https://github.com/bit-team/backintime/issues/722) * Fix bug: OSError when running backup-job from systemd (https://github.com/bit-team/backintime/issues/720) Version 1.1.14 (2017-03-05) * backport bug fix: udev schedule not working (https://github.com/bit-team/backintime/issues/605) * backport bug fix: Keyring doesn't work with KDE Plasma5 (https://github.com/bit-team/backintime/issues/545) * backport bug fix: nameError in tools.make_dirs (https://github.com/bit-team/backintime/issues/622) * backport bug fix: use current folder if no file is selected in files view * Fix critical bug: restore filesystem-root without 'Full rsync mode' with ACL and/or xargs activated broke whole system (https://github.com/bit-team/backintime/issues/708) Version 1.1.12 (2016-01-11) * Fix bug: remove x-terminal-emulator dependency (https://github.com/bit-team/backintime/issues/515) * Fix bug: AttributeError in About Dialog (https://github.com/bit-team/backintime/issues/515) Version 1.1.10 (2016-01-09) * Fix bug: failed to remove empty lock file (https://github.com/bit-team/backintime/issues/505) * Add Icon 'show-hidden' (https://github.com/bit-team/backintime/issues/507) * Add Modify for Full System Backup button to settings page, to change some profile settings * Fix bug: Restore the correct file owner and group fail if they are not present in system (https://github.com/bit-team/backintime/issues/58) * add get|set_list_value to configfile * Fix bug: QObject::startTimer error on closing app * subclass ApplicationInstance in GUIApplicationInstance to reduce redundant code * speed up app start by adding snapshots to timeline in background thread * add warning on failed permission restore (https://github.com/bit-team/backintime/issues/58) * add unittest (thanks to Dorian, Alexandre, Aurélien and Gregory from IAGL) * Fix bug: FileNotFoundError while starting pw-cache from source * continue an unfinished new_snapshot if possible (https://github.com/bit-team/backintime/issues/400) * Fix bug: suppress warning about failed inhibit suspend if run as root (https://github.com/bit-team/backintime/issues/500) * Fix bug: UI blocked/grayed out while removing snapshot (https://github.com/bit-team/backintime/issues/487) * Fix bug: pw-cache failed on leftover PID file, using ApplicationInstance now (https://github.com/bit-team/backintime/issues/468) * Fix bug: failed to parse some arguments (https://github.com/bit-team/backintime/issues/492) * Fix bug: failed to start GUI if launched from systray icon * Fix bug: deleted snapshot is still listed in Timeline if using mode SSH (https://github.com/bit-team/backintime/issues/493) * Fix bug: PermissionError while deleting readonly files on sshfs mounted share (https://github.com/bit-team/backintime/issues/490) * Add Nautilus-like shortcuts for navigating in file browser (https://github.com/bit-team/backintime/issues/483) * speed up mounting of SSH+encrypted profiles * Fix bug: create new encrypted profiles with encfs >= 1.8.0 failed (https://github.com/bit-team/backintime/issues/477) * Fix bug: AttributeError in common/tools.py if keyring is missing (https://github.com/bit-team/backintime/issues/473) * Fix bug: remote rename of 'new_snapshot' folder sometimes isn't recognized locally; rename local now (https://answers.launchpad.net/questions/271792) * Move source code and bug tracking to GitHub Version 1.1.8 (2015-09-28) * Fix bug: unlock private SSH key run into 5sec timeout if password is empty * show current app name and profile ID in syslog (https://launchpad.net/bugs/906213) * Fix bug: BiT freeze when activate 'Decode path' in 'Snapshot Log View' * Show 'Profiles' dropdown only in 'Last Log Viewer', add 'Snapshots' dropdown in 'Snapshot Log Viewer' (https://launchpad.net/bugs/1478219) * Fix bug: empty gray window appears when starting the gui as root (https://launchpad.net/bugs/1493020) * do not restore permission if they are identical with current permissions * Fix bug: gnu_find_suffix_support doesn't set back to True (https://launchpad.net/bugs/1487781) * security issue: do not run user-callback in a shell * add option to not log user-callback output * Fix lintian warning dbus-policy-without-send-destination * apply timestamps-in-gzip.patch from Debian backintime/1.1.6-1 package * run multiple smart-remove jobs in one screen session (https://launchpad.net/bugs/1487781) * add error messages if PID file creation fail * Fix bug: dbus exception if dbus systembus is not running * Fix bug: depend on virtual package cron-daemon instead of cron for compatibility with other cron implementations (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776856) * Fix bug: wasn't able to start from alternate install dir (https://launchpad.net/bugs/478689) * Fix bug: wasn't able to start from source dir * Add Warning about unsupported filesystems * use native Python code to check mountpoint * Add expert option for stdout and stderr redirection in cronjobs (https://answers.launchpad.net/questions/270105) * Fix bug: 'Inhibit Suspend' fails with 'org.freedesktop.PowerManagement.Inhibit' (https://launchpad.net/bugs/1485242) * Fix bug: No mounting while selecting a secondary profile in the gui (https://launchpad.net/bugs/1481267) * remove shebang in common/askpass.py and common/create-manpage-backintime-config.py * Fix bug: fix for bug #1419466 broke crontab on Slackware (https://launchpad.net/bugs/1478576) * Fix bug: fix for bug #1431305 broke pw-cache on Ubuntu (https://launchpad.net/bugs/1431305) * Fix bash-complete * show 'man backintime' on Help; remove link to backintime.le-web.org (https://launchpad.net/bugs/1475995) * add --debug argument * Fix bug: Settings accepted empty strings for Host/User/Profile-ID (https://launchpad.net/bugs/1477733) * Fix bug: IndexError on 'check_remote_commands' due to too long args (https://launchpad.net/bugs/1471930) * add --local-backup, --no-local-backup and --delete option to restore on command-line (https://launchpad.net/bugs/1467239) * add 'backup on restore' option to confirm dialog * add check-config command for command-line * rewrite command-line argument parsing. Now using argparse * add expert option SSH command prefix * Fix bug: Makefile has no uninstall target (https://launchpad.net/bugs/1469152) Version 1.1.6 (2015-06-27) * show Profile name in systrayicon menu * Fix bug: encrypted remote backup hangs on 'start encfsctl encode process' (https://launchpad.net/bugs/1455925) * make own Exceptions a childclass from BackInTimeException * Fix bug: missing profile.name crashed GUI * Fix bug: Segmentation fault caused by two QApplication instances (https://launchpad.net/bugs/1463732) * remove consolekit from dependencies * Fix bug: no Changes [C] log entries with 'Check for changes' disabled (https://launchpad.net/bugs/1463367) * Fix bug: some changed options from Settingsdialog where not respected during automatic tests after hitting OK * Fix bug: python version check fails on python 3.3 (https://launchpad.net/bugs/1463686) * Specifying the SSH private key whenever ssh is called (https://launchpad.net/bugs/1433682) * add to in-/exclude directly from mainwindow (https://launchpad.net/bugs/1454856) * Fix bug: pw-cache didn't start on Mint KDE because of missing stdout and stderr (https://launchpad.net/bugs/1431305) * add option to run Smart Remove in background on remote host (https://launchpad.net/bugs/1457210) * Use current profile when starting GUI from Systray * Fix bug: failed to restore file names with white spaces using CLI (https://launchpad.net/bugs/1435602) * Fix bug: UnboundLocalError with 'last_snapshot' in _free_space (https://launchpad.net/bugs/1437623) Version 1.1.4 (2015-03-22) * add option to keep new snapshot with 'full rsync mode' regardless of changes (https://launchpad.net/bugs/1434722) * Fix bug: wrong quote in 'Save config file' * Fix bug: Deleting the last snapshot does not update the last_snapshot symlink (https://launchpad.net/bugs/1434724) * remove base64 encoding for passwords as it doesn't add any security but broke the password process (https://launchpad.net/bugs/1431305) * add confirm dialog before restoring (https://launchpad.net/bugs/438079) * Fix bug: Wrong status text in the tray icon (https://launchpad.net/bugs/1429400) * add option to run only one snapshot at a time * Fix bug: restore permissions of lots of files made BackInTime unresponsive (https://launchpad.net/bugs/1428423) * Fix bug: failed to restore file owner and group * cache uuid in config so it doesn't fail if the device isn't plugged in (https://launchpad.net/bugs/1426881) * add warning about wrong Python version in configure * prevent snapshots from being removed with restore and delete; show warning if restore and delete filesystem root (https://answers.launchpad.net/questions/262837) * Fix bug: OSError in free_space; add alternate method to get free space * add bash-completion * Fix bug: ugly theme while running as root on Gnome based DEs (https://launchpad.net/bugs/1418447) * Fix bug: UnicodeError thrown if filename has broken charset (https://launchpad.net/bugs/1419694) * use 'crontab' instead of 'crontab -' to read from stdin (https://launchpad.net/bugs/1419466) Version 1.1.2 (2015-02-04) * sort 'Backup folders' in main window * save in- and exclude sort order * use PolicyKit to install Udev rules * move compression from install to build in Makefiles * use pkexec to start backintime-qt4 as root Version 1.1.0 (2015-01-15) * add tooltips for rsync options * make only one debian/control * multiselect files to restore (https://launchpad.net/bugs/1135886) * force run manual snapshots on battery (https://launchpad.net/bugs/861553) * backup encfs config to local config folder * apply 'install-docs-move.patch' from Debian package by Jonathan Wiltshire * add restore option to delete new files during restore (https://launchpad.net/bugs/1371951) * use flock to prevent two instances running at the same time * restore config dialog added (https://launchpad.net/bugs/480391) * inhibit suspend/hibernate while take_snapshot or restore * use more reliable code for get_user * implement anacrons functions inside BIT => more flexible schedules and no new timestamp if there was an error * automatically run in background if started with 'backintime --backup-job' * fix typos and style warnings in manpages reported by Lintian (https://lintian.debian.org/full/jmw@debian.org.html#backintime_1.0.34-0.1) * add exclude files by size (https://launchpad.net/bugs/823719) * remove 'Auto Host/User/Profile-ID' as this is more confusing than helping * Fix bug: check procname of pid-locks (https://launchpad.net/bugs/1341414) * optional run 'rsync' with 'nocache' (https://launchpad.net/bugs/1344528) * mark invalid exclude pattern with mode ssh-encrypted * make Settingsdialog tabs scrollable * remove colon (:) restriction in exclude pattern * prevent starting new snapshot if restore is running * Fix bug: Port check failed on IPv6 (https://launchpad.net/bugs/1361634) * add top-level directory for tarball (https://launchpad.net/bugs/1359076) * add more user-callback events (on App start and exit, on mount and unmount) * add context menu to files view * remove snapshots from commandline * multi selection in timeline => remove multiple snapshots with one click * print warning if started with sudo * add more default exclude; remove [Cc]ache* from exclude * Fix bug: 'inotify_add_watch failed' while closing BIT * add option for custom rsync-options * add ProgressBar for rsync * add progress for smart-remove * remove old status-bar message after a snapshot crashed. * ask to include symlinks target instead link (https://launchpad.net/bugs/1117709) * port to Python 3.x * returncode >0 if there was an error (https://launchpad.net/bugs/1040995) * Enable user-callback script to cancel a backup by returning a non-zero exit code. * merge backintime-notify into backintime-qt4 * add --gksu/--gksudo arg to qt4/configure * remember last path for each profile (https://bugs.launchpad.net/bugs/1254870) * sort include and exclude list (https://bugs.launchpad.net/bugs/1193149) * Timeline show tooltip 'Last check' * Fix bug: systray icon didn't show up (https://bugs.launchpad.net/backintime/+bug/658424) * show hidden files in FileDialog (https://bugs.launchpad.net/backintime/+bug/995925) * add button text for all buttons (https://bugs.launchpad.net/backintime/+bug/992020) * add shortcuts (https://bugs.launchpad.net/backintime/+bug/686694) * add menubar (https://bugs.launchpad.net/backintime/+bug/528851) * port KDE4 GUI to pure Qt4 to replace both KDE4 and Gnome GUI Version 1.0.40 (2014-11-02) * use fingerprint to check if ssh key was unlocked correctly (https://answers.launchpad.net/questions/256408) * add fallback method to get UUID (https://answers.launchpad.net/questions/254140) * Fix bug: 'Attempt to unlock mutex that was not locked'... this time for good Version 1.0.38 (2014-10-01) * Fix bug: 'Attempt to unlock mutex that was not locked' in gnomeplugin (https://answers.launchpad.net/questions/255225) * compare os.path.realpath instead of os.stat to get devices UUID * Fix bug: housekeeping by gnome-session-daemon might delete backup and original data (https://bugs.launchpad.net/bugs/1374343) * Fix bug: Type Error in 'backintime --decode' (https://bugs.launchpad.net/bugs/1365072) * Fix bug: take_snapshot didn't wait for snapshot folder come available if notifications are disabled (https://bugs.launchpad.net/bugs/1332979) Version 1.0.36 (2014-08-06) * remove UbuntuOne from exclude (https://bugs.launchpad.net/bugs/1340131) * Gray out 'Add Profile' if 'Main Profile' isn't configured yet (https://bugs.launchpad.net/bugs/1335545) * Don't check for fuse group-membership if group doesn't exist * Fix bug: backintime-kde4 as root failed to load ssh-key (https://bugs.launchpad.net/bugs/1276348) * Fix bug: kdesystrayicon.py crashes because of missing environ (https://bugs.launchpad.net/bugs/1332126) * Fix bug: OSError if sshfs/encfs is not installed (https://bugs.launchpad.net/bugs/1316288) * Fix bug: TypeError in config.py check_config() (https://bugzilla.redhat.com/show_bug.cgi?id=1091644) * Fix bug: unhandled exception in create_last_snapshot_symlink() (https://bugs.launchpad.net/bugs/1269991) * disable keyring for root Version 1.0.34 (2013-12-21) * sync/flush all disks before shutdown (https://bugs.launchpad.net/bugs/1261031) * Fix bug: BIT running as root shutdown after snapshot, regardless of option checked (https://bugs.launchpad.net/bugs/1261022) Version 1.0.32 (2013-12-13) * Fix bug: cron scheduled snapshots won't start with 1.0.30 Version 1.0.30 (2013-12-12) * scheduled and manual snapshots use --config * make configure scripts portable (https://bugs.launchpad.net/backintime/+bug/377429) * Fix bug: udev rule doesn't finish (https://bugs.launchpad.net/backintime/+bug/1249466) * add symlink last_snapshot (https://bugs.launchpad.net/backintime/+bug/787118) * add virtual package backintime-kde for PPA * Fix multiple errors in PPA build process; reorganize updateversion.sh * Fix bug: Mate and xfce desktop didn't show systray icon (https://bugs.launchpad.net/backintime/+bug/658424/comments/31) * add option to run rsync with 'nice' or 'ionice' on remote host (https://bugs.launchpad.net/backintime/+bug/1240301) * add Shutdown button to shutdown system after snapshot has finished (https://bugs.launchpad.net/backintime/+bug/838742) * Fix bug: Ubuntu Lucid doesn't provide SecretServiceKeyring (https://bugs.launchpad.net/backintime/+bug/1243911) * wrap long lines for syslog * Fix bug: 'gksu backintime-gnome' failed with dbus.exceptions.DBusException Version 1.0.28 (2013-10-19) * remove config on 'apt-get purge' * add more options for configure scripts; update README * add udev schedule (run BIT as soon as the drive is connected) * Fix bug: AttributeError with python-keyring>1.6.1 (https://bugs.launchpad.net/backintime/+bug/1234024) * Fix bug: TypeError: KDirModel.removeColumns() is a private method in kde4/app.py (https://bugs.launchpad.net/backintime/+bug/1232694) * add '--checksum' commandline option (https://bugs.launchpad.net/backintime/+bug/886021) * Fix bug: sshfs mount disconnect after a while due to some firewalls (add ServerAliveInterval) (https://answers.launchpad.net/backintime/+question/235685) * Fix bug: Ping fails if ICMP is disabled on remote host (https://bugs.launchpad.net/backintime/+bug/1226718) * Fix bug: KeyError in getgrnam if there is no 'fuse' group (https://bugs.launchpad.net/backintime/+bug/1225561) * Fix bug: anacrontab won't work with profilename with spaces (https://bugs.launchpad.net/backintime/+bug/1224620) * Fix bug: NameError in tools.move_snapshots_folder (https://bugs.launchpad.net/backintime/+bug/871466) * Fix bug: KPassivePopup is not defined (https://bugs.launchpad.net/backintime/+bug/871475) * multi selection for include and exclude list (https://bugs.launchpad.net/backintime/+bug/660753) * Fix bug: ValueError while reading pw-cache PID (https://answers.launchpad.net/backintime/+question/235407) Version 1.0.26 (2013-09-07) * add feature: keep min free inodes * roll back commit 836.1.5 (check free-space on ssh remote host): statvfs DOES work over sshfs. But not with quite outdated sshd * add daily anacron schedule * add delete button and 'list only equal' in Snapshot dialog; multiSelect in snapshot list * add manpage backintime-config and config-examples * Fix bug: Restore makes files public during the operation * Fix bug: Cannot keep modifications to cron (https://bugs.launchpad.net/backintime/+bug/698106) * add feature: restore from command line; add option --config * Fix bug: cannot stat 'backintime-kde4-root.desktop.kdesudo' (https://bugs.launchpad.net/backintime/+bug/696659) * Fix bug: unreadable dark KDE color schemes (https://bugs.launchpad.net/backintime/+bug/1184920) * use 'ps ax' to check if 'backintime --pw-cache' is still running * mount after locking, unmount before unlocking in take_snapshot * Fix bug: permission denied if remote uid wasn't the same as local uid * add option --bwlimit for rsync * redirect logger.error and .warning to stderr; new argument --quiet * deactivate 'Save Password' if no keyring is available * use Password-cache for user-input too * handle two Passwords * add 'SSH encrypted': mount / with encfs reverse and sync encrypted with rsync. EXPERIMENTAL! * add 'Local encrypted': mount encfs Version 1.0.24 (2013-05-08) * hide check_for_canges if full_rsync_mode is checked * DEFAULT_EXCLUDE system folders with /foo/* so at least the folder itself will backup * DEFAULT_EXCLUDE /run; exclude MOUNT_ROOT with higher priority and not with DEFAULT_EXCLUDE anymore * Fix bug: 'CalledProcessError' object has no attribute 'strerror' * Fix bug: quote rsync remote path with spaces * 'Save Password' default off to avoid problems with existing profiles * if restore uid/gid failed try to restore at least gid * SSH need to store permissions in separate file with "Full rsync mode" because remote user might not be able to store ownership * Fix bug: restore permission failed on "Full rsync mode" * Fix bug: glib.GError: Unknown internal child: selection * Fix bug: GtkWarning: Unknown property: GtkLabel.margin-top * Fix bug: check keyring backend only if password is needed * switch to 'find -exec cmd {} +' (https://bugs.launchpad.net/backintime/+bug/1157639) * change all indent tabs to 4 spaces Version 1.0.22 (2013-03-26) * check free-space on ssh remote host (statvfs didn't work over sshfs) * Add Password storage mode ssh * Add "Full rsync mode" (can be faster but ...) * Fix bug: "Restore to..." failed due to spaces in directory name (https://bugs.launchpad.net/backintime/+bug/1096319) * Fix bug: host not found in known_hosts if port != 22 (https://bugs.launchpad.net/backintime/+bug/1130356) * Fix bug: sshtools.py used not POSIX conform conditionals Version 1.0.20 (2012-12-15) * Fix bug: restore remote path with spaces using mode ssh returned error Version 1.0.18 (2012-11-17) * Fix packages: man & translations * Fix bug: https://bugs.launchpad.net/backintime/+bug/1077446 * Fix bug: https://bugs.launchpad.net/backintime/+bug/1078979 * Fix bug: https://bugs.launchpad.net/backintime/+bug/1079479 * Map multiple arguments for gettext so they can be rearranged by translators Version 1.0.16 (2012-11-15) * Fix a package dependency problem ... this time for good (https://bugs.launchpad.net/backintime/+bug/1077446) Version 1.0.14 (2012-11-09) * Fix a package dependency problem Version 1.0.12 (2012-11-08) * Add links to: website, documentation, report a bug, answers, faq * Use libnotify for gnome/kde4 notifications instead of gnome specific libraries * Fix bug: https://bugs.launchpad.net/backintime/+bug/1059247 * Add more schedule options: every 30 min, every 2 hours, every 4 hours, every 6 hours & every 12 hours * Add generic mount-framework * Add mode 'SSH' for backups on remote host using ssh protocol. * Fix bug: wrong path if restore system root * Fix bug: glade (xml) files did not translate * Fix bug: https://bugs.launchpad.net/backintime/+bug/1073867 Version 1.0.10 (2012-03-06) * Add "Restore to ..." in replacement of copy (with or without drag & drop) because copy don't restore user/group/rights Version 1.0.8 (2011-06-18) * Fix bug: https://bugs.launchpad.net/backintime/+bug/723545 * Fix bug: https://bugs.launchpad.net/backintime/+bug/705237 * Fix bug: https://bugs.launchpad.net/backintime/+bug/696663 * Fix bug: https://bugs.launchpad.net/backintime/+bug/671946 Version 1.0.6 (2011-01-02) * Fix bug: https://bugs.launchpad.net/backintime/+bug/676223 * Smart remove: configurable options (https://bugs.launchpad.net/backintime/+bug/406765) * Fix bug: https://bugs.launchpad.net/backintime/+bug/672705 Version 1.0.4 (2010-10-28) * SettingsDialog: show highly recommended excludes * Fix bug: https://bugs.launchpad.net/backintime/+bug/664783 * Option to use checksum to detect changes (https://bugs.launchpad.net/backintime/+bug/666964) * Option to select log verbosity (https://bugs.launchpad.net/backintime/+bug/664423) * Gnome: use gloobus-preview if installed Version 1.0.2 (2010-10-16) * reduce log file (no more duplicate "Compare with..." lines) * declare backintime-kde4 packages as a replacement of backintime-kde Version 1.0 (2010-10-16) * add '.dropbox*' to default exclude patterns (https://bugs.launchpad.net/backintime/+bug/628172) * add option to take a snapshot at every boot (https://bugs.launchpad.net/backintime/+bug/621810) * fix xattr * add continue on errors (https://bugs.launchpad.net/backintime/+bug/616299) * add expert options: copy unsafe links & copy links * "user-callback" replace "user.callback" and receive profile information * documentation: on-line only (easier to maintain) * add error log and error log view dialog (Gnome & KDE4) * merge with: lp:~dave2010/backintime/minor-edits * merge with: lp:~mcfonty/backintime/unique-snapshots-view * fix bug: https://bugs.launchpad.net/backintime/+bug/588841 * fix bug: https://bugs.launchpad.net/backintime/+bug/588215 * fix bug: https://bugs.launchpad.net/backintime/+bug/588393 * fix bug: https://bugs.launchpad.net/backintime/+bug/426400 * fix bug: https://bugs.launchpad.net/backintime/+bug/575022 * fix bug: https://bugs.launchpad.net/backintime/+bug/571894 * fix bug: https://bugs.launchpad.net/backintime/+bug/553441 * fix bug: https://bugs.launchpad.net/backintime/+bug/550765 * fix bug: https://bugs.launchpad.net/backintime/+bug/507246 * fix bug: https://bugs.launchpad.net/backintime/+bug/538855 * fix bug: https://bugs.launchpad.net/backintime/+bug/386230 * fix bug: https://bugs.launchpad.net/backintime/+bug/527039 * reduce memory usage during compare with previous snapshot process * fix bug: https://bugs.launchpad.net/backintime/+bug/520956 * fix bug: https://bugs.launchpad.net/backintime/+bug/520930 * fix bug: https://bugs.launchpad.net/backintime/+bug/521223 * custom backup hour (for daily backups or mode): https://bugs.launchpad.net/backintime/+bug/507451 * fix bug: https://bugs.launchpad.net/backintime/+bug/516066 * fix bug: https://bugs.launchpad.net/backintime/+bug/512813 * smart remove was slightly changed (https://bugs.launchpad.net/backintime/+bug/502435) * fix bug: https://bugs.launchpad.net/backintime/+bug/503859 * make backup on restore optional * fix bug: https://bugs.launchpad.net/backintime/+bug/501285 * add ionice support for user/cron backup process * fix bug: https://bugs.launchpad.net/backintime/+bug/493558 * fix bug that could cause "ghost" folders in snapshots (LP: 406092) * fix bug that converted / into // (LP: #455149) * fix bug: https://bugs.launchpad.net/backintime/+bug/441628 * remove "schedule per included directory" (profiles do that) (+ bug LP: #412470) * fig bug: https://bugs.launchpad.net/backintime/+bug/489380 * fix bug: https://bugs.launchpad.net/backintime/+bug/489319 * fix bug: https://bugs.launchpad.net/backintime/+bug/447841 * fix bug: https://bugs.launchpad.net/backintime/+bug/412695 * update Slovak translation (Tomáš Vadina ) * multiple profiles support * GNOME: fix notification * backintime snapshot folder is restructured to ../backintime/machine/user/profile_id/ * added the possibility to include other snapshot folders within a profile, it can only read those, there is not a GUI implementation yet * added a tag suffix to the snapshot_id, to avoid double snapshot_ids * added a desktop file for kdesu and a test if kdesu or kdesudo should be used (LP: #389988) * added expert option to disable snapshots when on battery (LP: #388178) * fix bug handling big files by the GNOME GUI (LP: #409130) * fix bug in handling of & characters by GNOME GUI (LP: #415848) * fix a security bug in chmods before snapshot removal (LP: #419774) * snapshots are stored entirely read-only (LP: #386275) * fix exclude patterns in KDE4 (LP:#432537) * fix opening german files with external applications in KDE (LP: #404652) * changed default exclude patterns to caches, thumbnails, trashbins, and backups (LP: #422132) * write access to snapshot folder is checked & change to snapshot version 2 (LP: #423086) * fix small bugs (a.o. LP: #474307) * Used a more standard crontab syntax (LP: #409783) * Stop the "Over zealous removal of crontab entries" (LP: #451811) Version 0.9.26 (2009-05-19) * update translations from Launchpad * Fix a bug in smart-remove algorithm (https://bugs.launchpad.net/backintime/+bug/376104) * Fix bug: https://bugs.launchpad.net/backintime/+bug/374477 * Fix bug: https://bugs.launchpad.net/backintime/+bug/375113 * update German translation (Michael Wiedmann ) * add '--no-check' option to configure scripts * use only 'folder' term (more consistent with GNOME/KDE) * add 'expert option': enable/disable nice for cron jobs * GNOME & KDE4: refresh snapshots button force files view to update too * you can include a backup parent directory (backup directory will auto-exclude itself) * fix some small bugs Version 0.9.24 (2009-05-07) * update translations * KDE4: fix python string <=> QString problems * KDE4 FilesView/SnapshotsDialog: ctrl-click just select (don't execute) * KDE4: fix crush after "take snapshot" process (https://bugs.launchpad.net/backintime/+bug/366241) * store basic permission in a special file so it can restore them correctly (event from NTFS) * add config version * implement Gnome/KDE4 systray icons and user.callback as plugins * reorganize code: common/GNOME/KDE4 * GNOME: break the big glade file in multiple file * backintime is no longer aware of 'backintime-gnome' and 'backintime-kde4' (you need run 'backintime-gnome' for GNOME version and 'backintime-kde4' for KDE4 version) Version 0.9.22.1 (2009-04-27) * fix French translation Version 0.9.22 (2009-04-24) * update translations from Launchpad * KDE4: fix some translation problems * remove --safe-links for save/restore (this means copy symlinks as symlinks) * update German translation (Michael Wiedmann ) * create directory now use python os.makedirs (replace use of mkdir command) * KDE4: fix a crush related to QString - python string conversion * GNOME & KDE4 SettingsDialog: if schedule automatic backups per directory is set, global schedule is hidden * GNOME FilesView: thread "*~" files (backup files) as hidden files * GNOME: use gtk-preferences icon for SettingsDialog (replace gtk-execute icon) * expert option: $XDG_CONFIG_HOME/backintime/user.callback (if exists) is called a different steps of a "take snapshot" process (before, after, on error, is a new snapshot was taken). * add more command line options: --snapshots-list, --snapshots-list-path, --last-snapshot, --last-snapshot-path * follow FreeDesktop directories specs: $XDG_DATA_HOME (default: $HOME/.local/share) to store app.lock files $XDG_CONFIG_HOME (default: $HOME/.config) to save settings * new install system: use more common steps (./configure; make; sudo make install) Version 0.9.20 (2009-04-06) * smart remove: fix an important bug and make it more verbose in syslog * update Spanish translation (Francisco Manuel García Claramonte ) Version 0.9.18 (2009-04-02) * update translations from Launchpad * update Slovak translation (Tomáš Vadina ) * update French translation (Michel Corps ) * update German translation (Michael Wiedmann ) * GNOME bugfix: fix a crush in files view for files with special characters (ex: "a%20b") * GNOME SettingsDialog bugfix: if snapshots path is a new created folder, snapshots navigation (files view) don't work * update doc * GNOME & KDE4 MainWindow: Rename "Places" list with "Snapshots" * GNOME SettingsDialog bugfix: modify something, then press cancel. If you reopen the dialog it show wrong values (the ones before cancel) * GNOME & KDE4: add root mode menu entries (use gksu for gnome and kdesudo for kde) * GNOME & KDE4: MainWindow - Files view: if the current directory don't exists in current snapshot display a message * SettingDialog: add an expert option to enable to schedule automatic backups per directory * SettingDialog: schedule automatic backups - if the application can't find crontab it show an error * SettingDialog: if the application can't write in snapshots directory there should be an error message * add Polish translation (Paweł Hołuj ) * add cron in common package dependencies * GNOME & KDE4: rework settings dialog * SettingDialog: add an option to enable/disable notifications Version 0.9.16.1 (2009-03-16) * fix a bug/crush for French version Version 0.9.16 (2009-03-13) * update Spanish translation (Francisco Manuel García Claramonte ) * add Slovak translation (Tomáš Vadina ) * update Swedish translation (Niklas Grahn ) * update French translation (Michel Corps ) * update German translation (Michael Wiedmann ) * update Slovenian translation (Vanja Cvelbar ) * don't show the snapshot that is being taken in snapshots list * GNOME & KDE4: when the application starts and snapshots directory don't exists show a messagebox * give more information for 'take snapshot' progress (to prove that is not blocked) * MainWindow: rename 'Timeline' column with 'Snapshots' * when it tries to take a snapshot if the snapshots directory don't exists (it is on a removable drive that is not plugged) it will notify and wait maximum 30 seconds (for the drive to be plugged) * GNOME & KDE4: add notify if the snapshots directory don't exists * KDE4: rework MainWindow Version 0.9.14 (2009-03-05) * update German translation (Michael Wiedmann ) * update Swedish translation (Niklas Grahn ) * update Spanish translation (Francisco Manuel García Claramonte ) * update French translation (Michel Corps ) * GNOME & KDE4: rework MainWindow * GNOME & KDE4: rework SettingsDialog * GNOME & KDE4: add "smart" remove Version 0.9.12 (2009-02-28) * bug fix: now if you include ".abc" folder and exclude ".*", ".abc" will be saved in the snapshot * KDE4: add help * add Slovenian translation (Vanja Cvelbar ) * bug fix (GNOME): bookmarks with special characters Version 0.9.10 (2009-02-24) * add Swedish translation (Niklas Grahn ) * KDE4: drop and drop from backintime files view to any file manager * bug fix: fix a segfault when running from cron Version 0.9.8 (2009-02-20) * update Spanish translation (Francisco Manuel García Claramonte ) * bug fix: unable to restore files that contains space char in their name * unsafe links are ignored (that means that a link to a file/directory outside of include directories are ignored) * KDE4: add copy to clipboard * KDE4: sort files by name, size or date * cron 5/10 minutes: replace multiple lines with a single crontab line using divide (*/5 or */10) * cron: when called from cron redirect output (stdout & stderr) to /dev/null Version 0.9.6 (2009-02-09) * update Spanish translation (Francisco Manuel García Claramonte ) * update German translation (Michael Wiedmann ) * GNOME: update docbook * KDE4: add snapshots dialog * GNOME & KDE4: add update snapshots button * GNOME: handle special folders icons (home, desktop) Version 0.9.4 (2009-01-30) * update German translation (Michael Wiedmann ) * gnome: better handling of 'take snapshot' status icon * KDE4 (>= 4.1): first version (not finished) * update man Version 0.9.2 (2009-01-16) * update Spanish translation (Francisco Manuel García Claramonte ) * update German translation (Michael Wiedmann ) * bug fix: if you add "/a" in include directories and "/a/b" in exclude patterns, "/a/b*" items are not excluded * replace diff with rsync to check if a new snapshot is needed * code cleanup * add show hidden & backup files toggle button for files view * bug fix: it does not include ".*" items even if they are not excluded (the items was included but not showed because hidden & backup files was never displayed in files view in previous versions) Version 0.9 (2009-01-09) * update Spanish translation (Francisco Manuel García Claramonte ) * make deb packages more debian friendly (thanks to Michael Wiedmann ) * update German translation (Michael Wiedmann ) * bug fix: when you open snapshots dialog for the second time ( or more ) and you make a diff it will make the diff on the file for the first dialog ( all previous dialogs ) and then for the current one * better separation between common and gnome specific files and divide backintime package in backintime-common & backintime-gnome (this will allow me to write other GUI front-ends like KDE4 or KDE) * code cleanup Version 0.8.20 (2008-12-22) * bug fix: sorting files/directories by name is now case insensitive * getmessages.sh: ignore "gtk-" items (this are gtk stock item ids and should not be changed) Version 0.8.18 (2008-12-17) * update man/docbook * add sort columns in MainWindow/FileView (by name, by size or by date) and SnapshotsDialog (by date) * fix German translation (Michael Wiedmann ) Version 0.8.16 (2008-12-11) * add Drag & Drop from MainWindow:FileView/SnapshotsDialog to Nautilus * update German translation (Michael Wiedmann ) Version 0.8.14 (2008-12-07) * add more command line parameters ( --version, --snapshots, --help ) * fix a crush for getting info on dead symbolic links * when taking a new backup based on the previous one don't copy the previous extra info (ex: name) * copy unsafe links when taking a snapshot Version 0.8.12 (2008-12-01) * add German translation (Michael Wiedmann ) * add SnapshotNameDialog * add Name/Remove snapshot in main toolbar * change the way it detects if the mainwindow is the active window (no dialogs) * toolbars: show icons only * update Spanish translation (Francisco Manuel García Claramonte ) Version 0.8.10 (2008-11-22) * SnapshotsDialog: add right-click popup-menu and a toolbar with copy & restore buttons * use a more robust backup lock file * log using syslog * fix a small bug in copy to clipboard * update Spanish translation (Francisco Manuel García Claramonte ) Version 0.8.8 (2008-11-19) * SnapshotsDialog: add diff * update Spanish translation (Francisco Manuel García Claramonte ) Version 0.8.6 (2008-11-17) * fix change backup path crush * add SnapshotsDialog Version 0.8.2 (2008-11-14) * add right-click menu in files list: open (using gnome-open), copy (you can paste in Nautilus), restore (for snapshots only) * add Copy toolbar button for files list Version 0.8.1 (2008-11-10) * add every 5/10 minutes automatic backup Version 0.8 (2008-11-07) * don't show backup files (*~) * add backup files to default exclude patterns (*~) * makedeb.sh: make a single package with all languages included * install.sh: install all languages * add English manual (man) * add English help (docbook) * add help button in main toolbar * the application can be started with a 'path' to a folder or file as command line parameter * when the application start, if it is already running pass its command line to the first instance (this allow a basic integration with file-managers - see README) * bug fix: when the application was started a second time it raise the first application's window but not always focused Version 0.7.4 (2008-11-03) * if there is already a GUI instance running raise it * add Spanish translation (Francisco Manuel García Claramonte ) Version 0.7.2 (2008-10-28) * better integration with gnome icons (use mime-types) * remember last path * capitalize month in timeline (bug in french translation) Version 0.7 (2008-10-22) * fix cron segfault * fix a crush when launched the very first time (not configured) * multi-lingual support * add French translation Version 0.6.4 (2008-10-20) * remove About & Settings dialogs from the pager * allow only one instance of the application Version 0.6.2 (2008-10-16) * remember window position & size Version 0.6 (2008-10-13) * when it make a snapshot it display an icon in systray area * the background color for group items in timeline and places reflect more the system color scheme * during restore only restore button is grayed ( even if everything is blocked ) Version 0.5.1 (2008-10-10) * add size & date columns in files view * changed some texts Version 0.5 (2008-10-03) * This is the first release. backintime-1.5.4/CONTRIBUTING.md000066400000000000000000000560401477034762000160770ustar00rootroot00000000000000 # How to contribute to _Back In Time_ 😊 **Thanks for taking the time to contribute.** 😊 🟢 **Contributions can be much more than code.** 🟢 The maintenance team welcomes all types of contributions. No contribution will be rejected solely because it doesn't meet our quality standards, guidelines, or rules. Every contribution is reviewed, and if necessary, improved in collaboration with the maintenance team. New contributors who may need assistance or are less experienced are warmly welcomed and will be mentored by the maintenance team upon request. There are many ways to contribute beyond coding: [translating the project](https://github.com/bit-team/backintime/issues/1915), performing manual tests, analyzing and reproducing [bugs](https://github.com/bit-team/backintime/issues), reviewing and testing [pull requests](https://github.com/bit-team/backintime/pulls), providing feedback on new features, designing an [application logo](https://github.com/bit-team/backintime/issues/1961), or reviewing the documentation and suggesting improvements. 🚀 Every contribution helps the project grow! 🚀 # Index - [Quick guide](#quick-guide) - [Best practice and recommendations](#best-practice-and-recommendations) - [Resources & Further Readings](#resources--further-readings) - [Build & Install](#build--install) - [Dependencies](#dependencies) - [Build and install via `make` system (recommended)](#build-and-install-via-make-system-recommended) - [Build own `deb` file](#build-own-deb-file) - [Testing](#testing) - [SSH](#SSH) - [What happens after you opened a Pull Request (PR)?](#what-happens-after-you-opened-a-pull-request-PR) - [Instructions about translation](#instructions-about-translation) - [Terminology](#terminology) - [General recommendations for developers](#general-recommendations-for-developers) - [Consider Right-to-Left (RTL) and Bidirectional (BIDI) languages](#consider-right-to-left-rtl-and-bidirectional-bidi-languages) - [Be aware of shortcut indicators and possible duplicates](#be-aware-of-shortcut-indicators-and-possible-duplicates) - [Treat other translators work with respect](#treat-other-translators-work-with-respect) - [Strategy Outline](#strategy-outline) - [Licensing of contributed material](#licensing-of-contributed-material) # Quick guide > [!IMPORTANT] > Please remember to create a new branch before you begin any modifications. > Baseline your feature or bug fix branch on `dev` > (reflecting the latest development state). 1. Fork this repository. See Microsoft GitHub's own documentation about [how to fork](https://docs.github.com/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo). 2. Clone your own fork to your local machine and enter the directory: $ git clone git@github.com:YOURNAME/backintime.git $ cd backintime 3. Create and checkout your own feature or bugfix branch with `dev` as baseline branch: $ git checkout -b myfancyfeature dev 4. Now you can add your modifications. 5. Commit and push it to your forked repo: $ git commit -am 'commit message' $ git push 6. Test your modifications. See section [Build & Install](#build--install) and [Testing](#testing) for further details. 7. Visit your own repository on Microsoft GitHub's website and create a Pull Request. See Microsoft GitHub's own documentation about [how to create a Pull Request based on your own fork](https://docs.github.com/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). # Best practice and recommendations If possible, please consider the following best practices. This will reduce the workload of the maintainers and increase the chances of your pull request being accepted. - Follow [PEP 8](https://peps.python.org/pep-0008/) as a minimal Style Guide for Python Code. - About strings: - Prefer _single quotes_ (e.g. `'Hello World'`) over _double qutoes_ (e.g. `"Hello World"`). Exceptions are when single quotes contained in the string (e.g. `"Can't unmount"`). - Enclose translatable strings like this: `_('Translate me')`. Find more details in our [localization docu](doc/maintain/2_localization.md#instructions-for-the-translation-process). - For docstrings follow [Google Style Guide](https://sphinxcontrib-napoleon.readthedocs.org/en/latest/example_google.html) (see our own [HOWTO about doc generation](doc/maintain/1_doc_howto.md)). - Avoid the use of automatic formatters like `black` but mention the use of them when opening a pull request. - Run unit tests before you open a pull request. You can run them via `make`-system with `cd common && ./configure && make && make test` or using a regular unittest runner of your choice (e.g. `pytest`). See section [Build and install via `make` system](#build-and-install-via-make-system-recommended) for further details. - Try to create new unit tests if appropriate. Use the style of regular Python `unittest` rather than `pytest`. If you know the difference, please try to follow the _Classical (aka Detroit) school_ instead of _London (aka mockist) school_. - See recommendations about [how to handle translatable strings](doc/maintain/2_localization.md#instructions-for-the-translation-process). # Resources & Further readings - [Mailing list _bit-dev_](https://mail.python.org/mailman3/lists/bit-dev.python.org/) - [Source code documentation for developers](https://backintime-dev.readthedocs.org) - [Translations](https://translate.codeberg.org/engage/backintime) are done on a separate platform. - [HowTo's and maintenance](doc/maintain/README.md) - Further readings - [contribution-guide.org](https://www.contribution-guide.org) - [How to submit a contribution (opensource.guide)](https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution) - [mozillascience.github.io/working-open-workshop/contributing](https://mozillascience.github.io/working-open-workshop/contributing) # Build & Install This section describes how to build and install _Back In Time_ in preparation of your own contributions. It is assumed that you `git clone` this repository first. ## Dependencies The following dependencies are based on _Debian GNU/Linux_. Please [open an Issue](https://github.com/bit-team/backintime/issues/new/choose) if something is missing. If you use another GNU/Linux distribution, please install the corresponding packages. Even if some packages are available from PyPi stick to the packages provided by the official repository of your GNU/Linux distribution. * Runtime dependencies for the CLI - `python3` (>= 3.9) - `rsync` - `cron-daemon` - `openssh-client` - `sshfs` - `python3-keyring` - `python3-dbus` - `python3-packaging` - Recommended - `encfs` * Runtime dependencies for the GUI - `x11-utils` - `python3-pyqt6` (not from _PyPi_ via `pip`) - `python3-dbus.mainloop.pyqt6` (not available from _PyPi_ via `pip`) - `pkexec` - `polkitd` - `qttranslations6-l10n` - `qtwayland6` (if Wayland is used as display server instead of X11) - Recommended - For SSH key storage **one** of these packages - `python3-secretstorage` - `python3-keyring-kwallet` - `python3-gnomekeyring` - For diff-like comparing files between backup snapshots **one** of these packages - `kompare` - or `meld` - Optional: Default icons - The `oxygen` icons should be offered as optional dependency since they are used as fallback in case of missing icons (mainly app and system-tray icons) * Build and testing dependencies - All CLI runtime dependencies including the recommended - All GUI runtime dependencies including the recommended - `build-essential` - `gzip` - `gettext` - `python3-pyfakefs` (>= 5.7) - Optional but recommended: - `pylint` (>= 3.3.0) - `flake8` - `ruff` (>= 0.6.0) - `codespell` - `reuse` (>= 4.0.0) * Dependencies to build documentation - All runtime, build, testing dependencies including the recommended - `mkdocs` - `mkdocs-material` ## Build and install via `make` system (recommended) > [!IMPORTANT] > Install [Dependencies](#dependencies) before you build and install. Remember that _Back In Time_ does consist of two packages, which must be built and installed separately accordingly. * Command line tool 1. `cd common` 2. `./configure && make` 3. Run unit tests via `make test` 4. `sudo make install` * Qt GUI 1. `cd qt` 2. `./configure && make` 3. Run unit tests via `make test` 4. `sudo make install` You can use optional arguments to `./configure` for creating a Makefile. See `common/configure --help` and `qt/configure --help` for details. # Testing > [!IMPORTANT] > Remember to **manually** test _Back In Time_ and not rely solely on > the automatic test suite. See section > [Manual testing](doc/maintain/BiT_release_process.md#manual-testing---recommendations) > about recommendations how to perform such tests. After [building and installing](#build--install), `make` can be used to run the test suite. Since _Back In Time_ consists of two components, `common` and `qt`, the tests are segregated accordingly. $ cd common $ make test Or $ cd qt $ make test Alternatively use `make test-v` for a more verbose output. The `make` system will use `pytest` as test runner if available otherwise Python's own `unittest` module. ## SSH Some tests require an available SSH server. Those tests get skipped if no SSH server is available. The goal is to log into the SSH server on your local computer via `ssh localhost` without using a password: - Generate an RSA key pair executing `ssh-keygen`. Use the default file name and don't use a passphrase for the key. - Populate the public key to the server executing `ssh-copy-id`. - Make the `ssh` instance run. - The port `22` (SSH default) should be available. - _Authorize_ the key with `$ ssh localhost` and insert your user accounts password. To test the connection just execute `ssh localhost` and you should see an SSH shell **without** being asked for a password. For detailed setup instructions see the [how to setup openssh for unit tests](doc/maintain/3_How_to_set_up_openssh_server_for_ssh_unit_tests.md). # What happens after you opened a Pull Request (PR)? In short: 1. The maintenance team will review your PR in days or weeks. 2. Modifications may be requested, and the PR will eventually be approved. 3. One of two labels will be added to the PR: - [PR: Merge after creative-break](https://github.com/bit-team/backintime/labels/PR%3A%20Merge%20after%20creative-break): Merge, but with a minimum delay of one week to allow other maintainers to review. - [PR: Waiting for review](https://github.com/bit-team/backintime/labels/PR%3A%20Waiting%20for%20review): Wait until a second approval from another maintainer. The maintenance team members are promptly notified of your request. One of them will respond within days or weeks. Note that all team members perform their duties voluntarily in their limited spare time. Please read the maintainers' responses carefully, answer their questions, and try to follow their instructions. Do not hesitate to ask for clarification if needed. At least one maintainer will review and ultimately approve your pull request. Depending on the topic or impact of the PR, the maintainer may decide that an approval from a second maintainer is needed. This may result in additional waiting time. Please remain patient. In such cases, the PR will be labeled [PR: Waiting for review](https://github.com/bit-team/backintime/labels/PR%3A%20Waiting%20for%20review). If no second approval is necessary, the PR is labeled [PR: Merge after creative-break](https://github.com/bit-team/backintime/labels/PR%3A%20Merge%20after%20creative-break) and will remain open for minimum of one week. This rule allows all maintainers the chance to review and potentially veto the pull request. # Instructions about translation ## Terminology - The translators, as native speakers, are the maintainers of the translation in their language and have the final decision. All following points are strong recommendations, but not written in stone. Language maintainers are free to overule them for good reasons. - "Directory" or "Folder"? We prefer "Directory". In our opinion, it is a clearly defined technical term and more precise in describing an element in the file system. - Translate "Back In Time"? It is the name of the application. That shouldn't be translated at all. - Some points of the following [General recommendations for developers](#general-recommendations-for-develoeprs) are also relevant for translators. ## General recommendations for developers The following points are about creating translatable source strings. - Be aware that most of our translators not skilled in Python programming. They might don't know about GNU gettext internals and other technical details. They only see the translatable string in the web-frontend of our [translation platform](https://translate.codeberg.org/engage/backintime). - Avoid escape characters in the strings. - Give translators enough context with providing meaningful placeholder names. - Avoid addressing the person with "you". - Don't "scream" by using upper case letters (e.g. `WARNING`) or an exclamation mark (`!`). - Please provide a screenshot when introducing new translatable strings or modifying them. The picture will be used on the translation web-frontend to provide translators with more context. - [Consider Right-to-Left (RTL) and Bidiretional (BIDI) languages](#consider-right-to-left-rtl-and-bidiretional-bidi-languages). - [Be aware of shortcut indicators and possible duplicates](#be-aware-of-shortcut-indicators-and-possible-duplicates). - [Treat other translators work with respect](#treat-other-translators-work-with-respect). ```python # Avoid escape characters for string delimiters problematic = _('Hello \'World\'') correct = _("Hello 'World'") # Avoid escape characters like new lines problematic = _('One\nTwo')` correct = _('One') + '\n' + _('Two') # <- Separation into multiple strings is # no problem, because the translator # will have a screenshot. # Provide meaningful placeholder names problematic = _('Can not delete {var}.') correct = _('Can not delete {snapshot_path}.') # Avoid addressing the person with "you" problematic = _('Do you really want to delete this snapshot?') correct = _('Is it really intended to delete this snapshot?') ``` ## Consider Right-to-Left (RTL) and Bidirectional (BIDI) languages In short: Always include punctuation marks (e.g. colons) in the strings to translate. Languages such as Arabic or Hebrew are read from right to left (RTL). To be more precise, they can have mixed reading directions (BIDI). The GUI library used by _Back In Time_ takes this into account when arrange elements in a window. For example, a text-input widget is left from a label widget. This switched order is the reason why punctuation marks (e.g. colons) in the string of a label widget need to change their direction as well. This task can only be performed by the translator themselves, which is why punctuation marks need to be included in the string to translate. ## Be aware of shortcut indicators and possible duplicates In short: 1. Use the character `&` to indicate the letter to access a GUI element via keyboard shortcut. 2. Be careful not to create conflicts by using the same letter multiple times in the same GUI context. The _Back In Time_ GUI can be controlled via keyboard shortcuts. In the English version, for example, the menu _Back In Time_ in the main window can be unfolded via `Alt+T`, _Backup_ via `Alt+B`, or _Help_ via `Alt+H`. The keyboard letters to use are indicated in the GUI with an underlined letter. The original string in the source code uses the character `&` in front of a letter to indicate the shortcut and produce this underline. The example above use the source strings `Back In &Time`, `&Backup`, and `&Help`. This illustrates why it is not appropriate to always use the first letter for shortcuts. Here in this example, `&Back In Time` and `&Backup` would use the same letter. Translating `&Backup` and `&Help` into Turkish becomes `&Yedek` and `Y&ardım`, where using the first letter only would produce conflicts again. That is why the translator needs to decide which letter to use. ## Treat other translators work with respect Sometimes it is a matter of taste or habit how do you translate something. People are different, therefore their translation are also different. When modifying an existing translation please consider _Comments_ and _History_ section of that string on our translation platform. There might be another translator who has good reason for this translation. Don't waste other people work for no good reason. Also use the _Comments_ to document your own reasons if you expect discussions or conflicts. The translation for some specific languages (e.g. [German](https://translate.codeberg.org/projects/backintime/common/de/)) do have rules every translator should follow. That rules can be found in a colored box on top of the translation platform. Open an issue if you think they should be modified. # Strategy Outline This is a broad overview of the tasks or steps to enhance _Back In Time_ as a software and as a project. The schedule is not fixed, nor is the order of priority. - [Analyzing code and behavior](#analyzing-code-and-behavior) - [Code quality & unit tests](#code-quality--unit-tests) - [Issues](#issues) - [Replace and remove encryption library EncFS](#replace-and-remove-encryption-library-encfs) - [Project infrastructure](#project-infrastructure) - [Graphical User Interface (GUI): Redesign and Refactoring](#graphical-user-interface-gui-redesign-and-refactoring) - [Terminal User Interface (TUI)](#terminal-user-interface-tui) ## Analyzing code and behavior As none of the current team members were involved in the original development of _Back In Time_, there is a lack of deep understanding of certain aspects of the codebase and its functionality. Part of the work done in this project involves conducting research on the code, its features, infrastructure, and documenting the findings. ## Code quality & unit tests One challenge resembles a chicken-and-egg problem: the code structure lacks sufficient isolation, making it difficult, if not nearly impossible in some cases, to write valuable unit tests. Heavy refactoring of the code is necessary, but this carries a high risk of introducing new bugs. To mitigate this risk, unit tests are essential to catch any potential bugs or unintended changes in the behavior of _Back In Time_. Each of the problems is blocking the solution to the other problem. Considering the three major types of tests (_unit_, _integration_, _system_), the current test suite primarily consists of _system tests_. While these _system tests_ are valuable, their purpose differs from that of _unit tests_. Due to the lack of _unit tests_ in the test suite, the codebase has notably low test coverage (see [Issue #1489](https://github.com/bit-team/backintime/issues/1489)). The codebase does not adhere to [PEP8](https://peps.python.org/pep-0008/), which serves as the minimum Python coding style. Utilizing linters in their default configuration is currently not feasible. One of our objectives is to align with PEP8 standards and meet the requirements of code linters. See [Issue #1755](https://github.com/bit-team/backintime/issues/1755) about it. ## Issues All existing issues have been triaged by the current team. [Labels](https://github.com/bit-team/backintime/labels) are assigned to indicate priority, along with a [milestone](https://github.com/bit-team/backintime/milestones) indicating which planned release will address the issue. Some of these issues persists for a long time and involve multiple complex problems. They can be challenging to diagnose due to various factors. Enhancing test coverage and code quality is one aspect aimed at finding and implementing solutions for these issues. ## Replace and remove encryption library EncFS Currently, _Back In Time_ uses [EncFS](https://github.com/vgough/encfs) for encrypting backups, but it has known security vulnerabilities (see issue [#1549](https://github.com/bit-team/backintime/issues/1549)). This requires to remove it. A potential candidate for replacement is [GoCryptFS](https://github.com/rfjakob/gocryptfs). However, lack of resources hinders this effort. If no volunteers step forward, the encryption feature will be removed, prioritizing user security and team maintenance efforts. See [Issue #1734](https://github.com/bit-team/backintime/issues/1734) about the transition process and the discussion about alternatives to EncFS. ## Project infrastructure At present, _Back In Time_ utilizes a build system that relies on `make`. However, this approach has several shortcomings and does not adhere to modern standards in Python packaging ([PEP 621](https://peps.python.org/pep-0621), [PEP 517](https://peps.python.org/pep-0517), [src layout](https://packaging.python.org/en/latest/tutorials/packaging-projects), [pyproject.toml](https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html)). The team intends to migrate to these contemporary standards to streamline the maintenance of _Back In Time_ ([#1575](https://github.com/bit-team/backintime/issues/1575)). ## Graphical User Interface (GUI): Redesign and Refactoring Over the years, the GUI has become increasingly complex. It requires a visual redesign as well as code refactoring. Additionally, it lacks tests. ## Terminal User Interface (TUI) Various people use _Back In Time_ via the terminal, for example, through an SSH shell on a headless server. There is an idea of creating a terminal user interface (TUI) or to enhance the existing command-line interface (CLI) ([#254](https://github.com/bit-team/backintime/issues/254)) or to create a web-frontend ([#209](https://github.com/bit-team/backintime/issues/209)). The later idea was rejected. The TUI idea also has been postponed for now. As an alternative, it is currently being considered to change the format of the configuration file to TOML ([#1984](https://github.com/bit-team/backintime/issues/1984)), assuming that a TUI, while convenient and pleasant, would no longer be necessary. # Licensing of contributed material Keep in mind as you contribute, that code, docs and other material submitted to the project are considered licensed under the same terms as the rest of the work. With a few exceptions, this is [GNU General Public License Version 2 or later](https://spdx.org/licenses/GPL-2.0-or-later.html) (`GPL-2.0-or-later`). This project uses [SPDX metadata](https://spdx.dev/) to provide detailed license and copyright information. This data is also machine-readable with [REUSE tools](https://reuse.software/). January 2025 backintime-1.5.4/FAQ.md000066400000000000000000001665341477034762000146110ustar00rootroot00000000000000 January 2025 # FAQ - Frequently Asked Questions - [General](#general) * [Does _Back in Time_ support full system backups?](#does-back-in-time-support-full-system-backups) * [Does _Back in Time_ support backups on cloud storage like OneDrive or Google Drive?](#does-back-in-time-support-backups-on-cloud-storage-like-onedrive-or-google-drive) * [Where is the log file?](#where-is-the-log-file) * [How to read log entries?](#how-to-read-log-entries) * [How to move snapshots to a new hard-drive?](#how-to-move-snapshots-to-a-new-hard-drive) * [How to move a large directory in the backup source without duplicating the files in the backup?](#how-to-move-a-large-directory-in-the-backup-source-without-duplicating-the-files-in-the-backup) - [Backups (snapshots)](#backups-snapshots) * [Does _Back In Time_ create incremental or full backups?](#does-back-in-time-create-incremental-or-full-backups) * [How do snapshots with hard-links work?](#how-do-snapshots-with-hard-links-work) * [How can I check if my snapshots are using hard-links?](#how-can-i-check-if-my-snapshots-are-using-hard-links) * [How to use checksum to find corrupt files periodically?](#how-to-use-checksum-to-find-corrupt-files-periodically) * [What is the meaning of the leading 11 characters (e.g. "cf...p.....") in my snapshot logs?](#what-is-the-meaning-of-the-leading-11-characters-eg-cfp-in-my-snapshot-logs) * [Snapshot "WITH ERRORS": [E] 'rsync' ended with exit code 23: See 'man rsync' for more details](#snapshot-with-errors-e-rsync-ended-with-exit-code-23-see-man-rsync-for-more-details) * [What happens when I remove a snapshot?](#what-happens-when-i-remove-a-snapshot) * [How can I exclude cache folders to improve backup speed and reduce storage?](#how-can-i-exclude-cache-folders-to-improve-backup-speed-and-reduce-storage) - [Restore](#restore) * [After Restore I have duplicates with extension ".backup.20131121"](#after-restore-i-have-duplicates-with-extension-backup20131121) * [Back In Time doesn't find my old Snapshots on my new Computer](#back-in-time-doesnt-find-my-old-snapshots-on-my-new-computer) - [Schedule](#schedule) * [How does the 'Repeatedly (anacron)' schedule work?](#how-does-the-repeatedly-anacron-schedule-work) * [Will a scheduled snapshot run as soon as the computer is back on?](#will-a-scheduled-snapshot-run-as-soon-as-the-computer-is-back-on) * [If I edit my crontab and add additional entries, will that be a problem for BIT as long as I don't touch its entries? What does it look for in the crontab to find its own entries?](#if-i-edit-my-crontab-and-add-additional-entries-will-that-be-a-problem-for-bit-as-long-as-i-dont-touch-its-entries-what-does-it-look-for-in-the-crontab-to-find-its-own-entries) * [Can I use a systemd timer instead of cron?](#can-i-use-a-systemd-timer-instead-of-cron) - [Problems, Errors & Solutions](#problems-errors--solutions) * [WARNING: A backup is already running](#warning-a-backup-is-already-running) * [_Back in Time_ does not start and shows: The application is already running! (pid: 1234567)](#back-in-time-does-not-start-and-shows-the-application-is-already-running-pid-1234567) * [Switching to dark or light mode in the desktop environment is ignored by BIT](#switching-to-dark-or-light-mode-in-the-desktop-environment-is-ignored-by-bit) * [Segmentation fault on Exit](#segmentation-fault-on-exit) * [Version >= 1.2.0 works very slow / Unchanged files are backed up](#version--120-works-very-slow--unchanged-files-are-backed-up) * [What happens if I hibernate the computer while a backup is running?](#what-happens-if-i-hibernate-the-computer-while-a-backup-is-running) * [What happens if I power down the computer while a backup is running, or if a power outage happens?](#what-happens-if-i-power-down-the-computer-while-a-backup-is-running-or-if-a-power-outage-happens) * [What happens if there is not enough disk space for the current backup?](#what-happens-if-there-is-not-enough-disk-space-for-the-current-backup) * [NTFS Compatibility](#ntfs-compatibility) * [GUI does not scale on high resolution or 4k monitors](#gui-does-not-scale-on-high-resolution-or-4k-monitors) * [Tray icon or other icons not shown correctly](#tray-icon-or-other-icons-not-shown-correctly) * [Non-working password safe and BiT forgets passwords (keyring backend issues)](#non-working-password-safe-and-bit-forgets-passwords-keyring-backend-issues) * [Incompatibility with rsync >= 3.2.4](#incompatibility-with-rsync-324-or-newer) - [user-callback and other PlugIns](#user-callback-and-other-plugins) * [How to backup Debian/Ubuntu Package selection?](#how-to-backup-debianubuntu-package-selection) * [How to restore Debian/Ubuntu Package selection?](#how-to-restore-debianubuntu-package-selection) - [Hardware-specific Setup](#hardware-specific-setup) * [How to use QNAP QTS NAS with BIT over SSH](#how-to-use-qnap-qts-nas-with-bit-over-ssh) * [How to use Synology DSM 5 with BIT over SSH](#how-to-use-synology-dsm-5-with-bit-over-ssh) * [How to use Synology DSM 6 with BIT over SSH](#how-to-use-synology-dsm-6-with-bit-over-ssh) * [How to use Synology DSM 7 with BIT over SSH](#how-to-use-synology-dsm-7-with-bit-over-ssh) * [Synology: "sshfs: No such file or directory" using BIT but manually ssh with rsync works](#synology-sshfs-no-such-file-or-directory-using-bit-but-manually-ssh-with-rsync-works) * [How to use Western Digital MyBook World Edition with BIT over ssh?](#how-to-use-western-digital-mybook-world-edition-with-bit-over-ssh) - [Project & Contributing & more](#project--Contributing--more) * [Which additional features on top of a GUI does BIT provide over a self-configured rsync backup? Are there additional benefits?](#which-additional-features-on-top-of-a-gui-does-bit-provide-over-a-self-configured-rsync-backup-are-there-additional-benefits) * [Support for specific package formats (deb, rpm, Flatpack, AppImage, Snaps, PPA, …)](#support-for-specific-package-formats-deb-rpm-flatpack-appimage-snaps-ppa-) + [Is BIT really not supported by Canonical Ubuntu?](#is-bit-really-not-supported-by-canonical-ubuntu) * [Move project to alternative code hoster (e.g. Codeberg, GitLab, …)](#move-project-to-alternative-code-hoster-eg-codeberg-gitlab-) * [How to review a Pull Request](#how-to-review-a-pull-request) - [Testing & Building](#testing--building) * [SSH related tests are skipped](#ssh-related-tests-are-skipped) * [Setup SSH Server to run unit tests](#setup-ssh-server-to-run-unit-tests) # General ## Does _Back in Time_ support full system backups? _Back in Time_ is suited for file-based backups. A full system backup is neither supported nor recommended (even though you could use _Back in Time (root)_ and include your root folder `\`) because - Mounted file systems (even remote locations) - the backup needed to be done from within the running system - Linux kernel special files (eg. /proc) must be excluded - locked or open files (in an inconsistent state) must be handled - backups of additional disk partitions (bootloader, EFI...) are required to be able to boot - a restore cannot overwrite the running system (where the backups software is running) without the risk of crashes or losing data (for that a restore must be done from a separate boot device normally) - ... For full system backups look for - a disk imaging ("cloning") solution (eg. [Clonezilla](https://clonezilla.org/)) - file-based backup tools that are designed for this (eg. [`Timeshift`](https://github.com/linuxmint/timeshift)) ## Does _Back in Time_ support backups on cloud storage like OneDrive or Google Drive? Cloud storage as backup source or target is not support because _Back in Time_ uses `rsync` as backend for file transfer and therefore a locally mounted file system or a `ssh` connection is required. Neither is supported by cloud storage. Even with native support for mounting a cloud storage, most of the time it won't work because of limited support for 'special' file access which is used by BiT (eg. Linux hardlinks, atime). Typically "locally mounted" cloud storage uses a web-based API (REST-API) which does not support `rsync`. For a discussion about this topic see [Backup on OneDrive or Google Drive](https://github.com/bit-team/backintime/issues/1166). ## Where is the log file? There are three distinct logs generated: 1. The _snapshot log_ contains messages specific to a particular snapshot at a given time. It is stored within each snapshot and can be accessed through the GUI. 2. The _restore log_ contains messages specific to a particular restore process. It is displayed in the GUI after each restore. It is also located in the folder `~/.local/share/backintime/` and is named `restore_.log` for the main profile, `restore_2.log` for the second, and so forth. 3. The _application log_ is generated using the syslog feature of the operating system. See [How to read log entries?](#how-to-read-log-entries) for further details. ## How to read log entries? Both the _snapshot_ and _restore_ log files are plain text files and can be read accordingly. Refer to [Where is the log file?](#where-is-the-log-file). The _application_ log is generated via [syslog](https://en.wikipedia.org/wiki/Syslog) using the identifier `backintime`. Depending on the version of _Back In time_ and the GNU/Linux distribution used, there are three ways to get the log entries. 1. On modern systems: `journalctl --identifier backintime` 2. With an older _Back In Time_ version (1.4.2 or older): `journalctl --grep backintime` 3. If the error message `journalctl: command not found` appears, directly examine the syslog files: `sudo grep backintime /var/log/syslog` ## How to move snapshots to a new hard-drive? There are three different solutions: 1. clone the drive with ``dd`` and enlarge the partition on the new drive to use all space. This will **destroy all data** on the destination drive! ```bash sudo dd if=/dev/sdbX of=/dev/sdcX bs=4M ``` where ``/dev/sdbX`` is the partition on the source drive and ``/dev/sdcX`` is the destination drive Finally use ``gparted`` to resize the partition. Take a look at the [Ubuntu Docu](https://help.ubuntu.com/community/HowtoPartition/ResizingPartition) for more info on that. 1. copy all files using ``rsync -H`` ```bash rsync -avhH --info=progress2 /SOURCE /DESTINATION ``` 1. copy all files using ``tar`` ```bash cd /SOURCE; tar cf - * | tar -C /DESTINATION/ -xf - ``` Make sure that your `/DESTINATION` contains a folder named `backintime`, which contains all the snapshots. BiT expects this folder, and needs it to import existing snapshots. ## How to move a large directory in the backup source without duplicating the files in the backup? If you move a file/folder in the source ("include") location that is backed-up by BiT it will treat this like a new file/folder and create a new backup file for it (not hard-linked to the old one). With large directories this can fill up your backup drive quite fast. You can avoid this by moving the file/folder in the last snapshot too: 1. Create a new snapshot 2. Move the original folder 3. Manually move the same folder inside BiTs last snapshot in the same way you did with the original folder 4. Create a new snapshot 5. Remove the next to last snapshot (the one where you moved the folder manually) to avoid problems with permissions when you try to restore from that snapshot # Backups (snapshots) ## Does _Back In Time_ create incremental or full backups? Back In Time does use `rsync` and its `--hard-links` feature. Because of that each snapshot is technically a full backup (contains each file) but copies only the really changed files (to save disk space) and "reuses" unchanged files by setting a so-called "hard-link". In technical terms it is not an [incremental backups](https://en.wikipedia.org/wiki/Incremental_backup). ## How do snapshots with hard-links work? From the answer on Launchpad to the question [_Does auto remove smart mode merge incremental backups?_](https://answers.launchpad.net/backintime/+question/123486) If you create a new file on a Linux filesystem (e.g. ext3) the data will have a unique number that is called inode. The path of the file is a link to this inode (there is a database which stores which file point to which inode). Also every inode has a counter for how many links point to this inode. After you created a new file the counter is 1. Now you make a new hardlink. The filesystem now just has to store the new path pointing to the existing inode into the database and increase the counter of our inode by 1. If you remove a file than only the link from the path to that inode is removed and the counter is decreased by 1. If you have removed all links to that inode so the counter is zero the filesystem knows that it can override that block next time you save a new file. First time you create a new backup with BIT all files will have an inode counter = 1. #### snapshot0 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 1 | | fileB | 2 | 1 | | fileC | 3 | 1 | Let's say you now change ``fileB``, delete ``fileC`` and have a new ``fileD``. BIT first makes hardlinks of all files. ``rsync`` than delete all hardlinks of files that has changed and copy the new files. #### snapshot0 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 2 | | fileB | 2 | 1 | | fileC | 3 | 1 | #### snapshot1 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 2 | | fileB | 4 | 1 | | fileD | 5 | 1 | Now change ``fileB`` again and make a new snapshot #### snapshot0 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 3 | | fileB | 2 | 1 | | fileC | 3 | 1 | #### snapshot1 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 3 | | fileB | 4 | 1 | | fileC | 5 | 2 | #### snapshot2 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 3 | | fileB | 6 | 1 | | fileD | 5 | 2 | Finally smart-remove is going to remove **snapshot0**. All that is done by smart-remove is to ``rm -rf`` (force delete everything) the whole directory of **snapshot0**. #### snapshot0 (no longer exist) | path | inode | counter | |:-------|--------:|----------:| | (empty) | 1 | 2 | | (empty) | 2 | 0 | | (empty) | 3 | 0 | #### snapshot1 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 2 | | fileB | 4 | 1 | | fileD | 5 | 2 | #### snapshot2 | path | inode | counter | |:-------|--------:|----------:| | fileA | 1 | 2 | | fileB | 6 | 1 | | fileD | 5 | 2 | ``fileA`` is still untouched, ``fileB`` is still available in two different versions and ``fileC`` is gone for good. The blocks on your hdd that stored the data for inode 2 and 3 can now get overridden. I hope this will shed a light on the "magic" behind BIT. If it's even more confusing don't hesitate to ask ;) ## How can I check if my snapshots are using hard-links? Please compare the inodes of a file that definitely didn't change between two snapshots. For this open two Terminals and ``cd`` into both snapshot folder. ``ls -lai`` will print a list where the first column is the inode which should be equal for the same file in both snapshots if the file didn't change and the snapshots are incremental. The third column is a counter (if the file is no directory) on how many hard-links exist for this inode. It should be >1. So if you took e.g. 3 snapshots it should be 3. Don't be confused on the size of each snapshot. If you right click on preferences for a snapshot in a file manager and look for its size, it will look like they are all full snapshots (not incremental). But that's not (necessary) the case. To get the correct size of each snapshot with respect on the hard-links you can run: ```bash du -chd0 /media//backintime///1/* ``` Compare with option `-l` to count hardlinks multiple times: ```bash du -chld0 /media//backintime///1/* ``` (``ncdu`` isn't installed by default so I won't recommend using it) ## How to use checksum to find corrupt files periodically? Starting with BIT Version 1.0.28 there is a new command line option ``--checksum`` which will do the same as *Use checksum to detect changes* in Options. It will calculate checksums for both the source and the last snapshots files and will only use this checksum to decide whether a file has changed or not. The normal mode (without checksums) is to compare modification times and sizes of the files which is much faster to detect changed files. Because this takes ages, you may want to use this only on Sundays or only the first Sunday per month. Please deactivate the schedule for your profile in that case. Then run ``crontab -e`` For daily snapshots on 2AM and ``--checksum`` every Sunday add: ``` # min hour day month dayOfWeek command 0 2 * * 1-6 nice -n 19 ionice -c2 -n7 /usr/bin/backintime --backup-job >/dev/null 2>&1 0 2 * * Sun nice -n 19 ionice -c2 -n7 /usr/bin/backintime --checksum --backup-job >/dev/null 2>&1 ``` For ``--checksum`` only at first Sunday per month add: ``` # min hour day month dayOfWeek command 0 2 * * 1-6 nice -n 19 ionice -c2 -n7 /usr/bin/backintime --backup-job >/dev/null 2>&1 0 2 * * Sun [ "$(date '+\%d')" -gt 7 ] && nice -n 19 ionice -c2 -n7 /usr/bin/backintime --backup-job >/dev/null 2>&1 0 2 * * Sun [ "$(date '+\%d')" -le 7 ] && nice -n 19 ionice -c2 -n7 /usr/bin/backintime --checksum --backup-job >/dev/null 2>&1 ``` Press CTRL + O to save and CTRL + X to exit (if you editor is `nano`. Maybe different depending on your default text editor). ## What is the meaning of the leading 11 characters (e.g. "cf...p.....") in my snapshot logs? This are from `rsync` and indicating what changed and why. Please see the section `--itemize-changes` in the [manpage](https://download.samba.org/pub/rsync/rsync.1#opt--itemize-changes) of `rsync`. See also some [rephrased explanations on Stack Overflow](https://stackoverflow.com/a/36851784/4865723). ## Snapshot "WITH ERRORS": [E] 'rsync' ended with exit code 23: See 'man rsync' for more details [BiT Version 1.4.0 (2023-09-14)](https://github.com/bit-team/backintime/releases/tag/v1.4.0) introduced the **evaluation of `rsync` exit codes for better error recognition**: Before this release `rsync` exit codes were ignored and only the snapshot files parsed for errors (which does not find each error, eg. dead symbolic links logged as `symlink has no referent`). This "exit code 23" message may occur at the end of snapshot logs and BiT logs when `rsync` was not able to transfer some (or even all) files See [this comment in issue 1587](https://github.com/bit-team/backintime/issues/1587#issuecomment-1856490208) for a list all known reasons for `rsync`'s exit code 23. Currently you can ignore this error after checking the full snapshot log which error is hidden behind "exit code 23" (and possibly fix it - eg. delete or update dead symbolic links). We plan to implement an improved handling of exit code 23 in the future (presumably by introducing warnings into the snapshot log). ## What happens when I remove a snapshot? Each snapshot is stored in a dated subdirectory of the "full snapshot path" shown in Settings. It contains a ``backup`` directory of all the files as well as a log of the snapshot's creation and some other details. Removing the snapshot removes this whole directory. Each snapshot is independent of the others, so other snapshots are not affected. However, the data of identical files is not stored redundantly by multiple snapshots, so removing a snapshot will only recover the space used by files that are unique to that snapshot. ## How can I exclude cache folders to improve backup speed and reduce storage? **Why exclude cache folders?** Cache folders typically contain temporary files that are not necessary for backups. Excluding them can significantly improve backup speed and reduce storage usage. **How to exclude cache folders:** 1. Open Back in Time. 2. Go to the **Exclude Patterns** settings: - Click the "Exclude" tab in the configuration window. - Click the **Add** button to create a new exclude pattern. 3. Add the following patterns to exclude common cache directories: ```plaintext .var/app/**/[Cc]ache/ .var/app/**/media_cache/ .mozilla/firefox/**/cache/ .config/BraveSoftware/Brave-Browser/Default/Service Worker/CacheStorage/ ``` **Explanation**: - `/**/` matches any directory structure leading to the specified folder. - `[Cc]ache` matches folder names with either uppercase or lowercase "Cache." 4. Decide whether to include or exclude the folder itself: - To exclude only the folder’s content, use `/*` at the end of the pattern: ```plaintext .var/app/**/[Cc]ache/* ``` - To exclude the folder and its contents, omit the `/*`: ```plaintext .var/app/**/[Cc]ache/ ``` **Tips for better results:** - **Check Backup Logs**: After running a backup, review the logs to identify additional folders that may slow down the process. Example log entries for cache files: ```plaintext [E] Skipping file /path/to/cache/file: Too many small files. ``` - **Customize Patterns**: Adjust the patterns to suit your specific applications. For example, modify paths for browsers or other software you use. - **Test Exclude Patterns**: Test your backup after adding patterns to ensure they work as intended. # Restore ## After Restore I have duplicates with extension ".backup.20131121" This is because *Backup files on restore* in Options was enabled. This is the default setting to prevent overriding files on restore. If you don't need them any more you can delete those files. Open a terminal and run: ```bash find /path/to/files -regextype posix-basic -regex ".*\.backup\.[[:digit:]]\{8\}" ``` Check if this correctly listed all those files you want to delete and than run: ```bash find /path/to/files -regextype posix-basic -regex ".*\.backup\.[[:digit:]]\{8\}" -delete ``` ## Back In Time doesn't find my old Snapshots on my new Computer Back In Time prior to version 1.1.0 had an option called *Auto Host/User/Profile ID* (hidden under *General* > *Advanced*) which will always use the current host- and username for the full snapshot path. When (re-)installing your computer you probably chose a different host name or username than on your old machine. With *Auto Host/User/Profile ID* activated Back In Time now try to find your Snapshots under the new host- and username underneath the ``/path/to/backintime/`` path. The *Auto Host/User/Profile ID* option is gone in version 1.1.0 and above. It was totally confusing and didn't add any good. You have three options to fix this: - Disable *Auto Host/User/Profile ID* and change *Host* and *User* to match your old machine. - Rename the Snapshot path ``/path/to/backintime/OLDHOSTNAME/OLDUSERNAME/profile_id`` to match your new host- and username. - Upgrade to a more recent version of Back In Time (1.1.0 or above). The *Auto Host/User/Profile ID* option is gone and it also comes with an assistant to restore the config from an old Snapshot on first start. # Schedule ## How does the 'Repeatedly (anacron)' schedule work? In fact *Back In Time* doesn't use anacron anymore. It was to inflexible. But that schedule mimics anacron. BIT will create a crontab entry which will start ``backintime --backup-job`` every 15min (or once an hour if the schedule is set to *weeks*). With the ``--backup-job`` command, BIT will check if the profile is supposed to be run this time or exit immediately. For this it will read the time of the last successful run from ``~/.local/share/backintime/anacron/ID_PROFILENAME``. If this is older than the configured time, it will continue creating a snapshot. If the snapshot was successful without errors, BIT will write the current time into ``~/.local/share/backintime/anacron/ID_PROFILENAME`` (even if *Repeatedly (anacron)* isn't chosen). So, if there was an error, BIT will try again at the next quarter hour. ``backintime --backup`` will always create a new snapshot. No matter how many time elapsed since last successful snapshot. ## Will a scheduled snapshot run as soon as the computer is back on? Depends on which schedule you choose: - the schedule ``Repeatedly (anacron)`` will use an anacron-like code. So if your computer is back on it will start the job if the given time is gone till last snapshot. - with ``When drive get connected (udev)`` *Back In Time* will start a snapshot as soon as you connect your drive ;-) - old fashion schedules like ``Every Day`` will use cron. This will only start a new snapshot at the given time. If your computer is off, no snapshot will be created. ## If I edit my crontab and add additional entries, will that be a problem for BIT as long as I don't touch its entries? What does it look for in the crontab to find its own entries? You can add your own crontab entries as you like. *Back In Time* will not touch them. It will identify its own entries by the comment line ``#Back In Time system entry, this will be edited by the gui:`` and the following command. You should not remove/change that line. If there are no automatic schedules defined *Back In Time* will add an extra comment line ``#Please don't delete these two lines, or all custom backintime entries are going to be deleted next time you call the gui options!`` which will prevent *Back In Time* to remove user defined schedules. ## Can I use a systemd timer instead of cron? While there is no support within *Back In Time* to directly create a systemd timer, users can create a user timer and service units. Templates are provided below. Optionally adjust the value for `OnCalendar=` with a valid setting. See [`man systemd.timer`](https://manpages.debian.org/testing/systemd/systemd.timer.5) for more. **Timer**: ```ini # ~/.config/systemd/user/backintime-backup-job.timer [Unit] Description=Start a backintime snapshot once daily [Timer] OnCalendar=daily AccuracySec=1m Persistent=true [Install] WantedBy=timers.target ``` **Service**: ```ini # ~/.config/systemd/user/backintime-backup-job.service [Unit] Description=Run backintime snapshot generation [Service] Type=oneshot ExecStart=/usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 /usr/bin/backintime backup-job ``` # Problems, Errors & Solutions ## WARNING: A backup is already running _Back In Time_ uses signal files like `worker.lock` to avoid starting the same backup twice. Normally it is deleted as soon as the backup finishes. In some case something went wrong so that _Back In Time_ was forcefully stopped without having the chance to delete this signal file. Since _Back In Time_ does only start a new backup job (for the same profile) if the signal file does not exist, such a file need to be deleted first. But before this is done manually, it must be ensured that _Back In Time_ really is not running anymore. It can be ensured via ```bash ps aux | grep -i backintime ``` If the output shows a running instance of _Back In Time_ it must be waited until it finishes or killed via `kill `. For more details see the developer documentation: [Usage of control files (locks, flocks, logs and others)](doc/maintain/4_Control_files_usage_(locks_flocks_logs_and_others).md) ## _Back in Time_ does not start and shows: The application is already running! (pid: 1234567) This message occurs when _Back In Time_ is either already running or did not finish regularly (e.g. due to a crash) and wasn't able to delete its application lock file. Before deleting that file manually make sure no backintime process is running via `ps aux | grep -i backintime`. Otherwise, kill the process. After that look into the folder `~/.local/share/backintime` for the file `app.lock.pid` and delete it. For more details see the developer documentation: [Usage of control files (locks, flocks, logs and others)](doc/maintain/4_Control_files_usage_(locks_flocks_logs_and_others).md) ## Switching to dark or light mode in the desktop environment is ignored by BIT After restart _Back In Time_ it should adapt to the desktops current used color theme. It happens because Qt does not detect theme modifications out of the box. [Workarounds are known](https://stackoverflow.com/q/75457687), but generate a relatively large amount of code and in our opinion are not worth the effort. ## Segmentation fault on Exit This problem existed at least since version 1.2.1, and will hopefully be fixed with version 1.5.0. For all affected versions, it does not impact the functionality of _Back In Time_ or jeopardize backup integrity. It can be safely ignored. See also: - [#1768](https://github.com/bit-team/backintime/pull/1768) - [#1095](https://github.com/bit-team/backintime/issues/1095) ## Version >= 1.2.0 works very slow / Unchanged files are backed up After updating to >= 1.2.0, BiT does a (nearly) full backup because file permissions are handled differently. Before 1.2.0 all destination file permissions were set to `-rw-r--r--`. In 1.2.0 rsync is executed with `--perms` option which tells rsync to preserve the source file permission. That's why so many files seem to be changed. If you don't like the new behavior, you can use "Expert Options" -> "Paste additional options to rsync" to add the value `--no-perms --no-group --no-owner` in that field. ## What happens if I hibernate the computer while a backup is running? *Back In Time* will inhibit automatic suspend/hibernate while a snapshot/restore is running. If you manually force hibernate this will freeze the current process. It will continue as soon as you wake up the system again. ## What happens if I power down the computer while a backup is running, or if a power outage happens? This will kill the current process. The new snapshot will stay in ``new_snapshot`` folder. Depending on which state the process was while killing the next scheduled snapshot can continue the leftover ``new_snapshot`` or it will remove it first and start a new one. ## What happens if there is not enough disk space for the current backup? *Back In Time* will try to create a new snapshot but rsync will fail when there is not enough space. Depending on ``Continue on errors`` setting the failed snapshot will be kept and marked ``With Errors`` or it will be removed. By default, *Back In Time* will finally remove the oldest snapshots until there is more than 1 GiB free space again. ## NTFS Compatibility Although devices formatted with the NTFS file system can generally be used with *Back In Time*, there are some limitations to be aware of. NTFS File systems do not support the following characters in filenames or directories: ```text < (less than) > (greater than) : (colon) " (double quote) / (forward slash) \ (backslash) | (vertical bar or pipe) ? (question mark) * (asterisk) ``` If *Back In Time* tries to copy files where the filename contains those character, an "Invalid argument (22)" error message will be displayed. It is recommended that only devices formatted with Unix style file systems (such as ext4) be used. For more information, refer to [this Microsoft page](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file#naming-conventions). ## GUI does not scale on high resolution or 4k monitors The technical details are complex and many components of the operating system are involved. BIT itself is not involved and also not responsible for it. Several approaches might help: - Check your desktop environment or window manager for settings regarding scaling. - Because BIT is using Qt for its GUI, modifying the environment variable `QT_SCALE_FACTOR` or `QT_AUTO_SCREEN_SCALE_FACTOR`. See [this article](https://doc.qt.io/qt-6/highdpi.html) and [Issue #1946](https://github.com/bit-team/backintime/issues/1946) about more details. ## Tray icon or other icons not shown correctly **Status: Fixed in v1.4.0** Missing installations of Qt-supported themes and icons can cause this effect. _Back In Time_ may activate the wrong theme in this case leading to some missing icons. A fix for the next release is in preparation. As clean solution, please check your Linux settings (Appearance, Styles, Icons) and install all themes and icons packages for your preferred style via your package manager. See issues [#1306](https://github.com/bit-team/backintime/issues/1306) and [#1364](https://github.com/bit-team/backintime/issues/1364). ## Non-working password safe and BiT forgets passwords (keyring backend issues) **Status: Fixed in v1.3.3 (mostly) and v1.4.0** _Back in Time_ does only support selected "known-good" backends to set and query passwords from a user-session password safe by using the [`keyring`](https://github.com/jaraco/keyring) library. Enabling a supported keyring requires manual configuration of a configuration file until there is e.g. a settings GUI for this. Symptoms are DEBUG log output (with the command line argument `--debug`) of keyring problems can be recognized by output like: ``` DEBUG: [common/tools.py:829 keyringSupported] No appropriate keyring found. 'keyring.backends...' can't be used with BackInTime DEBUG: [common/tools.py:829 keyringSupported] No appropriate keyring found. 'keyring.backends.chainer' can't be used with BackInTime ``` To diagnose and solve this follow these steps in a terminal: ``` # Show default backend python3 -c "import keyring.util.platform_; print(keyring.get_keyring().__module__)" # List available backends: keyring --list-backends # Find out the config file folder: python3 -c "import keyring.util.platform_; print(keyring.util.platform_.config_root())" # Create a config file named "keyringrc.cfg" in this folder with one of the available backends (listed above) [backend] default-keyring=keyring.backends.kwallet.DBusKeyring ``` See also issue [#1321](https://github.com/bit-team/backintime/issues/1321) ## Incompatibility with rsync 3.2.4 or newer **Status: Fixed in v1.3.3** The release (`1.3.2`) and earlier versions of _Back In Time_ are incompatible with `rsync >= 3.2.4` ([#1247](https://github.com/bit-team/backintime/issues/1247)). If you use `rsync >= 3.2.4` and `backintime <= 1.3.2` there is a workaround. Add `--old-args` in [_Expert Options_ / _Additional options to rsync_](https://backintime.readthedocs.io/en/latest/settings.html#expert-options). Note that some GNU/Linux distributions (e.g. Manjaro) using a workaround with environment variable `RSYNC_OLD_ARGS` in their distro-specific packages for _Back In Time_. In that case you may not see any problems. # user-callback and other PlugIns ## How to backup Debian/Ubuntu Package selection? There is a [user-callback example](https://github.com/bit-team/user-callback/blob/master/user-callback.apt-backup) which will backup all package selections, sources and repository keys which are necessary to reinstall exactly the same packages again. It will even backup whether a package was installed manually or automatically because of dependencies. Download the script, copy it to ``~/.config/backintime/user-callback`` and make it executable with ``chmod 755 ~/.config/backintime/user-callback`` It will run every time a new snapshot is taken. Make sure to include ``~/.apt-backup``. ## How to restore Debian/Ubuntu Package selection? If you made snapshots including apt-get package selection as described in the FAQ "`How to backup Debian/Ubuntu Package selection?`_" you can easily restore your system after a disaster/on a new machine. 1. install Debian/Ubuntu on your new hard drive as usual 1. install backintime-qt4 from our PPA ```bash sudo add-apt-repository ppa:bit-team/stable sudo apt-get update sudo apt-get install backintime-qt4 ``` 1. connect your external drive with the snapshots 1. Start *Back In Time*. It will ask you if you want to restore your config. Sure you want! *Back In Time* should find your snapshots automatically. Just select the one from which you want to restore the config and click Ok. 1. restore your home 1. recreate your ``/etc/apt/sources.list`` if you had something special in there. If your Debian/Ubuntu version changed don't just copy them from ``~/.apt-backup/sources.list`` 1. copy your repositories with ```bash sudo cp ~/.apt-backup/sources.list.d/* /etc/apt/sources.list.d/ ``` 1. restore apt-keys for your PPAs with ```bash sudo apt-key add ~/.apt-backup/repo.keys ``` 1. install and update `dselect` with ```bash sudo apt-get install dselect sudo dselect update install ``` 1. Make some *housecleaning* in ``~/.apt-backup/package.list``. For example, you don't want to install the old kernel again. So run ```bash sed -e "/^linux-\(image\|headers\)/d" -i ~/.apt-backup/package.list ``` 1. install your old packages again with ```bash sudo apt-get update sudo dpkg --set-selections < ~/.apt-backup/package.list sudo apt-get dselect-upgrade ``` 1. If you used the new script which uses apt-mark to backup package selection proceed with next step. (there should be files ``~/.apt-backup/pkg_auto.list`` and ``~/.apt-backup /pkg_manual.list``). Otherwise, you can stop here. Restore package selection with ```bash sudo apt-mark auto $(cat ~/.apt-backup/pkg_auto.list) sudo apt-mark manual $(cat ~/.apt-backup/pkg_manual.list) ``` # Hardware-specific Setup ## How to use QNAP QTS NAS with BIT over SSH To use *BackInTime* over SSH with a QNAP NAS there is still some work to be done in the terminal. **WARNING**: DON'T use the changes for ``sh`` suggested in ``man backintime``. This will damage the QNAP admin account (and even more). Changing ``sh`` for another user doesn't make sense either because SSH only works with the QNAP admin account! Please test this Tutorial and give some feedback! 1. Activate the SSH prefix: ``PATH=/opt/bin:/opt/sbin:\$PATH`` in ``Expert Options`` 1. Use ``admin`` (default QNAP admin) as remote user. Only this user can connect through SSH. Also activate on the QNAP `SFTP` on the SSH settings page. 1. Path should be something like ``/share/Public/`` 1. Create the public/private key pair for the password-less login with the user you use for *BackInTime* and copy the public key to the NAS. ```bash ssh-keygen -t rsa ssh-copy-id -i ~/.ssh/id_rsa.pub @ ``` To fix the message about not supported ``find PATH -type f -exec`` you need to install ``Entware-ng``. QNAPs QTS is based on Linux but some of its packages have limited functionalities. And so do some of the necessary ones for *BackInTime*. Please follow [this install instruction](https://github.com/Entware-ng/Entware-ng/wiki/Install-on-QNAP-NAS) to install ``Entware-ng`` on your QNAP NAS. Because there is no web interface yet for ``Entware-ng``, you must configure it by SSH on the NAS. Some Packages will be installed by default for example ``findutils``. Login on the NAS and updated the Database and Packages of ``Entware-ng`` with ```bash ssh @ opkg update opkg upgrade ``` Finally install the current packages of ``bash``, ``coreutils`` and ``rsync`` ```bash opkg install bash coreutils rsync ``` Now the error message should be gone and you should be able to take a first snapshot with *BackInTime*. *BackInTime* changes permissions on the backup path. The owner of the backup has read permission, other users have no access. This way can change with newer versions of *BackInTime* or QNAPs QTS! ## How to use Synology DSM 5 with BIT over SSH **Issue** *BackInTime* cannot use Synology DSM 5 directly because the SSH connection to the NAS refers to a different root file system than SFTP does. With SSH you access the real root, with SFTP you access a fake root (`/volume1`) **Solution** Mount `/volume1/backups` to `/volume1/volume1/backups` **Suggestion** DSM 5 isn't really up to date any more and might be a security risk. It is strongly advised to upgrade to DSM 6! Also the setup with DSM 6 is much easier! 1. Make a new volume named ``volume1`` (should already exist, else create it) 1. Enable User Home Service (Control Panel / User) 1. Make a new share named ``backups`` on ``volume1`` 1. Make a new share named ``volume1`` on ``volume1`` (It must be the same name) 1. Make a new user named ``backup`` 1. Give to user ``backup`` rights Read/Write to share ``backups`` and ``volume1`` and also permission for FTP 1. Enable SSH (Control Panel / Terminal & SNMP / Terminal) 1. Enable SFTP (Control Panel / File Service / FTP / SFTP) 1. Enable rsync service (Control Panel / File Service / rsync) 1. Since DSM 5.1: Enable Backup Service (Backup & Replication / Backup Service) (This seems not to be available/required anymore with DSM 6!) 1. Log on as root by SSH 1. Modify the shell of user ``backup``. Set it to ``/bin/sh`` (``vi /etc/passwd`` then navigate to the line that begins with ``backup``, press :kbd:`I` to enter ``Insert Mode``, replace ``/sbin/nologin`` with ``/bin/sh``, then finally save and exit by pressing :kbd:`ESC` and type ``:wq`` followed by :kbd:`Enter`) This step might have to be repeated after a major update of the Synology DSM! Note: This is quite a dirty hack! It is suggested to upgrade to DSM 6 which doesn't need this any more! 1. Make a new directory ``/volume1/volume1/backups`` ```bash mkdir /volume1/volume1/backups ``` 1. Mount ``/volume1/backups`` on ``/volume1/volume1/backups`` ```bash mount -o bind /volume1/backups /volume1/volume1/backups ``` 1. To auto-mount it make a script ``/usr/syno/etc/rc.d/S99zzMountBind.sh`` ```bash #!/bin/sh start() { /bin/mount -o bind /volume1/backups /volume1/volume1/backups } stop() { /bin/umount /volume1/volume1/backups } case "$1" in start) start ;; stop) stop ;; *) ;; esac ``` Note: If the folder ``/usr/syno/etc/rc.d`` doesn't exist, check if ``/usr/local/etc/rc.d/`` exists. If so, put it there. (After I updated to Synology DSM 6.0beta, the first one did not exist anymore). Make sure the execution flag of the file is checked , else it will not get run at start! To make it executable, run: ``chmod +x /usr/local/etc/rc.d/S99zzMountBind.sh`` 1. On the workstation on which you try to use BIT make SSH keys for user ``backup``, send the public key to the NAS ```bash ssh-keygen -t rsa -f ~/.ssh/backup_id_rsa ssh-add ~/.ssh/backup_id_rsa ssh-copy-id -i ~/.ssh/backup_id_rsa.pub backup@ ssh backup@ ``` 1. You might get the following error: ```bash /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system. ``` 1. If so, copy the public key manually to the NAS as root with ```bash scp ~/.ssh/id_rsa.pub backup@:/var/services/homes/backup/ ssh backup@ cat /var/services/homes/backup/id_rsa.pub >> /var/services/homes/backup/.ssh/authorized_keys # you'll still be asked for your password on these both commands # after this you should be able to login password-less ``` 1. And proceed with the next step 1. If you are still prompted for your password when running ``ssh backup@``, check the permissions of the file ``/var/services/homes/backup/.ssh/authorized_keys``. It should be ``-rw-------``. If this is not the case, run the command ```bash ssh backup@ chmod 600 /var/services/homes/backup/.ssh/authorized_keys ``` 1. Now you can use *BackInTime* to perform your backup to your NAS with the user ``backup``. ## How to use Synology DSM 6 with BIT over SSH **HowTo** 1. Enable User Home Service (Control Panel / User / Advanced). There is no need to create a volume since everything is stored in the home directory. 1. Make a new user named ``backup`` (or use your existing account). Add this user to the user group ``Administrators``. Without this, you will not be able to log in! 1. Enable SSH (Control Panel / Terminal & SNMP / Terminal) 1. Enable SFTP (Control Panel / File Service / FTP / SFTP) 1. Since DSM 5.1: Enable Backup Service (Backup & Replication / Backup Service) (This seems not to be available/required anymore with DSM 6!) (Tests needed!) 1. On DSM 6 you can edit the user-root-dir for sFTP: Control Panel -> File Services -> FTP -> General -> Advanced Settings -> Security Settings -> Change user root directories -> Select User Now select the user ``backup`` and Change root directory to ``User home`` 1. On the workstation on which you try to use BIT make SSH keys for user ``backup``, send the public key to the NAS ```bash ssh-keygen -t rsa -f ~/.ssh/backup_id_rsa ssh-add ~/.ssh/backup_id_rsa ssh-copy-id -i ~/.ssh/backup_id_rsa.pub backup@ ssh backup@ ``` 1. You might get the following error: ```bash /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system. ``` 1. If so, copy the public key manually to the NAS as root with ```bash scp ~/.ssh/id_rsa.pub backup@:/var/services/homes/backup/ ssh backup@ cat /var/services/homes/backup/id_rsa.pub >> /var/services/homes/backup/.ssh/authorized_keys # you'll still be asked for your password on these both commands # after this you should be able to login password-less ``` 1. And proceed with the next step 1. If you are still prompted for your password when running ``ssh backup@``, check the permissions of the file ``/var/services/homes/backup/.ssh/authorized_keys``. It should be ``-rw-------``. If this is not the case, run the command ```bash ssh backup@ chmod 600 /var/services/homes/backup/.ssh/authorized_keys ``` 1. In *BackInTime* settings dialog leave the *Path* field empty 1. Now you can use *BackInTime* to perform your backup to your NAS with the user ``backup``. **Using a non-standard port with a Synology NAS** If you want to use the Synology NAS with non-standard SSH/SFTP port (standard is 22), you have to change the Port on total 3 places: 1. Control Panel > Terminal: Port = 1. Control Panel > FTP > SFTP: Port = 1. Backup & Replication > Backup Services > Network Backup Destination: SSH encryption port = Only if all 3 of them are set to the same port, *BackInTime* is able to establish the connection. As a test, one can run the command ```bash rsync -rtDHh --checksum --links --no-p --no-g --no-o --info=progress2 --no-i-r --rsh="ssh -p -o IdentityFile=/home//.ssh/id_rsa" --dry-run --chmod=Du+wx /tmp/ "@:/volume1/Backups/BackinTime" ``` in a terminal (on the client PC). ## How to use Synology DSM 7 with BIT over SSH **HowTo** 1. Enable User Home Service (Control Panel > User & Group > Advanced). 1. Make a new user named ``backup`` (or use your existing account) and add this user to the user group ``Administrators``. 1. Enable SSH (Control Panel > Terminal & SNMP > Terminal) 1. Enable SFTP (Control Panel > File Services > FTP > SFTP) 1. Enable rsync (Control Panel > File Services > rsync) 1. Edit the user-root-directory for SFTP: Control Panel > File Services > FTP > General > Advanced Settings > Security Settings > Change user root directories > Select User > select the user ``backup`` > Edit and Change root directory to ``User home`` 1. Make sure the 'homes' shared folder has the default permissions and that non-admin users and groups are not assigned Read or Write permissions on the 'homes' folder. The default permissions are described in [this guide](https://kb.synology.com/DSM/tutorial/default_permissions_of_homes) 1. On the workstation on which you need to use BIT, make an SSH key pair for user ``backup``, and send the public key to the NAS: ```bash ssh-keygen -t rsa -f ~/.ssh/backup_id_rsa ssh-copy-id -i ~/.ssh/backup_id_rsa.pub backup@ ssh backup@ ``` 1. Although not strictly necessary, Synology recommend setting the permissions for the .ssh directory and the authorized_keys file to 700, and 600 respectively: ```bash backup@NAS:~$ chmod 700 .ssh backup@NAS:~$ chmod 600 .ssh/authorized_keys ``` 1. In *BackInTime* settings dialog leave the *Path* field empty 1. Now you can use *BackInTime* to perform your backup to your NAS with the user ``backup``. **Using a non-standard SSH port with a Synology NAS** If you want to use the Synology NAS with a non-standard SSH/SFTP port as advised by the Security Advisor package, you have to change the Port in 3 places (the default port number for all three is 22): 1. Control Panel > Terminal & SNMP > Terminal: Port = 1. Control Panel > File Services > FTP > SFTP: Port number = 1. Control Panel > File Services > rsync > SSH encryption port = Only if all 3 are set to the same port is *BackInTime* able to establish the connection (don't forget to set the new port number in the BIT profiles). To sign in with ssh using the new port number: ```bash ssh -p PORT_NUMBER backup@ ``` or, for convenience you can edit or create ``~/.ssh/config`` with the following: ``` Host Port PORT_NUMBER ``` and then use just: ```bash ssh backup@ ``` ## Synology: "sshfs: No such file or directory" using BIT but manually ssh with rsync works The reason (known for DSM version 7) is that the setup of ssh and sftp is customized by Synology. Solution ([Screenshot in Issue #1674](https://github.com/bit-team/backintime/issues/1674#issuecomment-2106059151)): 1. Go to: _Control Panel_ > _File Services_ > _Advanced Settings_ > _Change user root directories_ > _Select User_ 2. Add the name of the user used for SSH on the Synology in that list. 3. At _Change root directory to:_ select _User home_. See also - [Issue #1674](https://github.com/bit-team/backintime/issues/1674) - ["Change the default folder in a Synology NAS" - StackOverflow](https://stackoverflow.com/a/77454561/4865723) ## How to use Western Digital MyBook World Edition with BIT over ssh? Device: *WesternDigital MyBook World Edition (white light) version 01.02.14 (WD MBWE)* The BusyBox that is used by WD in MBWE for serving basic commands like ``cp`` (copy) doesn't support hardlinks. Which is a rudimentary function for BackInTime's way of creating incremental backups. As a work-around you can install Optware on the MBWE. Before proceeding please make a backup of your MBWE. There is a significant chance to break your device and lose all your data. There is good documentation about Optware on http://mybookworld.wikidot.com/optware. 1. You have to login to MBWE's web admin and change to *Advanced Mode*. Under *System | Advanced* you have to enable *SSH Access*. Now you can log in as root over ssh and install Optware (assuming ```` is the address of your MyBook). Type in terminal: ```bash ssh root@ #enter 'welc0me' for password (you should change this by typing 'passwd') wget http://mybookworld.wikidot.com/local--files/optware/setup-whitelight.sh sh setup-whitelight.sh echo 'export PATH=$PATH:/opt/bin:/opt/sbin' >> /root/.bashrc echo 'export PATH=/opt/bin:/opt/sbin:$PATH' >> /etc/profile echo 'PermitUserEnvironment yes' >> /etc/sshd_config /etc/init.d/S50sshd restart /opt/bin/ipkg install bash coreutils rsync nano exit ``` 1. Back in MBWE's web admin go to *Users* and add a new user (```` in this How-to) with *Create User Private Share* set to *Yes*. In terminal: ```bash ssh root@ chown /shares/ chmod 700 /shares/ /opt/bin/nano /etc/passwd #change the line #:x:503:1000:Linux User,,,:/shares:/bin/sh #to #:x:503:1000:Linux User,,,:/shares/:/opt/bin/bash #save and exit by press CTRL+O and CTRL+X exit ``` 1. Next create the ssh-key for your local user. In the terminal ```bash ssh @ mkdir .ssh chmod 700 .ssh echo 'PATH=/opt/bin:/opt/sbin:/usr/bin:/bin:/usr/sbin:/sbin' >> .ssh/environment exit ssh-keygen -t rsa #enter for default path ssh-add ~/.ssh/id_rsa scp ~/.ssh/id_rsa.pub @:./ #enter password from above ssh @ #you will still have to enter your password cat id_rsa.pub >> .ssh/authorized_keys rm id_rsa.pub chmod 600 .ssh/* exit ssh @ #this time you shouldn't been asked for password anymore exit ``` 1. You can test if everything is done by enter this ```bash ssh @ cp --help ``` The output should look like: ```bash Usage: cp [OPTION]... [-T] SOURCE DEST or: cp [OPTION]... SOURCE... DIRECTORY or: cp [OPTION]... -t DIRECTORY SOURCE... Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY. Mandatory arguments to long options are mandatory for short options too. -a, --archive same as -dR --preserve=all --backup[=CONTROL] make a backup of each existing destination file -b like --backup but does not accept an argument --copy-contents copy contents of special files when recursive ... (lot more lines with options) ``` But if your output looks like below you are still using the BusyBox and will not be able to run backups with *BackInTime* over ssh: ```bash BusyBox v1.1.1 (2009.12.24-08:39+0000) multi-call binary Usage: cp [OPTION]... SOURCE DEST ``` # Project & Contributing & more ## Which additional features on top of a GUI does BIT provide over a self-configured rsync backup? Are there additional benefits? Actually it's the other way around ;) *Back In Time* stores the user and group name which will make it possible to restore permissions correctly even if UID/GID changed. Additionally it will store the current User -> UID and Group -> GID map so if the User/Group doesn't exist on the system during restore it will restore to the old UID/GID. Hard to say which additional features *Back In Time* provides. You can script all of them in your own rsync script, too. But to name some features: - Inhibit suspend/hibernate during take snapshot - Shutdown system after finish - Auto- and Smart-Removal - Plugin- and user-callback support ## Support for specific package formats (deb, rpm, Flatpack, AppImage, Snaps, PPA, …) We assist and support other projects providing specific distribution packages. Thus, we suggest creating your own repository to manage and maintain such packages. It will be mentioned in our documentation as an alternative source for installation. We do not directly support third-party distribution channels associated with specific GNU/Linux distributions, unofficial repositories (e.g. Arch AUR, Launchpad PPA) or FlatPack & Co. One reasons is our lack of resources and the need to prioritize tasks. Another reasons is that their are distro maintainers with much more experience and skills in packaging. We always recommend using the official repositories of GNU/Linux distributions and contacting their maintainers if _Back In Time_ is unavailable or out dated. ## Is BIT really not supported by Canonical Ubuntu? Ubuntu consists of [several repositories](https://help.ubuntu.com/community/Repositories), each offering different levels of support. The `main` repository is maintained by Canonical and receives regular security updates and bug fixes throughout the 5-year support period of LTS releases. In contrast, the `universe` repository is community-managed, meaning security updates and bug fixes are not guaranteed and depend heavily on community activity and volunteers. Therefore, packages in `universe` may not always be up-to-date with the same but well-maintained packages in Debian GNU/Linux and might miss important fixes. _Back In Time_ is one such package in the `universe` repository. That [package](https://packages.ubuntu.com/search?suite=all&searchon=names&keywords=backintime) is copied from the [Debian GNU/Linux repository](https://packages.debian.org/search?searchon=sourcenames&keywords=backintime). It can be said that _Back In Time_ is not maintained by Canonical Ubuntu, but by volunteers from the Community of Ubuntu. ## Move project to alternative code hoster (e.g. Codeberg, GitLab, …) We also believe that staying with Microsoft GitHub is not a good idea. Microsoft GitHub does not offer any exclusive feature for our project that another hoster could not also provide. But a migration is a matter of time and resources we currently do not have. But it is on our list. And with the current state of discussion we seem to target [Codeberg.org](https://codeberg.org). For more details please see [this thread on the mailing list](https://mail.python.org/archives/list/bit-dev@python.org/message/O5XZ5SPW6WIFBFKWUBHSOUIBKEUIBPNM/). ## How to review a Pull Request Reviewing a Pull Request (PR) isn’t just about the code—it’s also about functionality. Changes can be tested by installing _Back In Time_ and trying them out, even without reading the code. This allows issues to be identified from a user’s perspective. A second pair of eyes helps catch errors, spot overlooked issues, and improve overall quality. Fresh perspectives, knowledge sharing, and better maintainability contribute to the long-term stability of the project. Check PRs labeled with [PR: Waiting for review](https://github.com/bit-team/backintime/pulls?q=is%3Aopen+is%3Apr+label%3A%22PR%3A+Waiting+for+review%22). Checking the [milestone](https://github.com/bit-team/backintime/milestones) assigned to PR can also help gauge their priority and urgency. - Start by carefully reading the PR description to understand the proposed changes. Ask back if something is not clear. - When giving feedback, consider the contributor’s level of experience and skills. Keep it polite and constructive—every beginner could be a future maintainer. To **test functionality**, [check out the PR code locally](https://docs.github.com//pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally) on a virtual machine or your local machine. Running _Back In Time_ in a test environment provides insights, that can be shared as findings, observations, or suggestions for improvement. About **code review**: - Code should follow [project standards](CONTRIBUTING.md#best-practice-and-recommendations) and be structured for long-term maintainability. - Is a PR too large or complex, suggest to breaking it down into smaller parts. - How is the documentation? - Are there unit tests? - Does the changelog need an entry? # Testing & Building ## SSH related tests are skipped They get skipped if no SSH server is available. Please see section [Testing & Building](CONTRIBUTING.md#testing--building) about how to setup a SSH server on your system. ## Setup SSH Server to run unit tests Please see section [Testing - SSH](CONTRIBUTING.md#ssh). backintime-1.5.4/HISTORY.md000066400000000000000000000164051477034762000153320ustar00rootroot00000000000000 # Looking back in time at _Back In Time_ *by Michael Büker, 2024* The development of _Back In Time_ was inspired by [FlyBack](https://en.wikipedia.org/wiki/FlyBack). The history of the _Back In Time_ project, which at the time of this writing already spans nearly 16 years and is best understood in four periods: 1. The **First Era** from 2008 to 2012, releases 0.5 to ~1.0.12 2. The **Second Era** from 2012 to 2019, releases ~1.0.14 to 1.2 3. A **Dark Age** from 2019 to 2022, releases 1.2.0 to 1.3.2 4. The **Third Era** since 2022, since release 1.3.3 These periods correspond roughly to who was maintaining and developing _Back In Time_. Important technical and organizational changes happened at various moments in between. For details, refer to [CHANGES](CHANGES). For a glimpse into the future, see the [Strategy Outline](CONTRIBUTING.md#strategy-outline). ## The First Era: 0.5 to ~1.0.12 (2008–2012) ### Maintenance _Back In Time_ was created by **Oprea Dan** and first published on a private blog in late 2008 ([wayback link](https://web.archive.org/web/20081014041759/http://www.le-web.org/2008/10/03/back-in-time-version-05/)). Shortly thereafter, collaborative development started happening on Launchpad. Sometime around 2010, development and publication appears to have moved entirely to Launchpad, with the private blog being discontinued. ### Core functionality At first, _Back In Time_ used `diff` to compare the latest snapshot with the source, in order to check if a new snapshot was necessary. If the answer was yes, it would use `cp` to create a new snapshot. This was changed in version 0.9.2 in early 2009, when `diff` was replaced by `rsync` for the comparison. Copying was still done by `cp`, apparently without special permissions handling. This changed when, shortly thereafter, version 0.9.24 introduced `fileinfo.bz2`, which holds permissions information on all files in a snapshot. Introduced to allow saving backups on non-Unix-permission-aware filesystems like NTFS, `fileinfo.bz2` is consulted upon restoring a file in order to recreate its original ownership and permissions. ### GUI Initially, _Back In Time_ had only a GNOME GUI. Version 0.9 from early 2009 separated the backend (`backintime-common`) from the GUI, allowing for different frontends. Over the course of 2009, finishing roughly with version 0.9.24, two separate frontends were completed: `backintime-gnome` and `backintime-kde4`. ## The Second Era: ~1.0.14 to 1.2 (2012–2019) ### Maintenance Around 2012, **Germar Reitze** took over publication, maintenance and further development from Oprea Dan. In early 2016, starting with version 1.1.10, development and publication moved to Microsoft GitHub, leaving the Launchpad project mostly abandoned (except for translation management and PPA publication). ### Core functionality Development during the Second Era centered largely around remote backup capabilities. In late 2012, version 1.0.12 introduced remote backup locations enabled by `ssh`. In early 2013, version 1.0.22 introduced an optional "full rsync mode". This replaced `cp` with `rsync` for all operations, including full replication of permissions. In late 2013, version 1.0.26 introduced encrypted backup locations enabled by `encfs`. ### GUI In early 2015, version 1.1.0 eliminated the separate `backintime-gnome` and `backintime-kde4` frontends and introduced `backintime-qt4` as the only frontend. ## The Dark Age: 1.2.0 to 1.3.2 (2019–2022) In 2019, version 1.2.0 was released. It was the first release since version 1.1.24 in late 2017 and contained many bugfixes accumulated over the previous 1.5 years. Version 1.2.0 introduced a fundamental change: ***"make full-rsync mode default, remove the other mode"***. This meant that files would always be transferred by `rsync` instead of `cp`. Specifically, `rsync` was instructed to retain full ownership and permissions information when transferring the files to the backup (*in addition* to the information stored in `fileinfo.bz2`). This caused bug [#988](https://github.com/bit-team/backintime/issues/988), which broke _Back In Time_'s core functionality for any backup created with version <1.2.0 (unless "full rsync mode" had been enabled): many unchanged files were no longer hardlinked upon transferring, but unnecessarily copied. This led to very long backup times and high disk usage. A related bug with a somewhat smaller impact is [#994](https://github.com/bit-team/backintime/issues/994). As these bugs are currently understood, the underlying reason for the problem is differing ownership/permissions between the files in the source and on the backup drive. Since multiple hardlinks to the same file are, by definition, identical, they cannot have differing permissions. `rsync` fails to handle this case correctly when a new snapshot is created, leading to the files in question being copied unnecessarily. With many users complaining and trading workarounds on Microsoft GitHub, development soon came to a halt. Some bugs were fixed with version 1.3.0 in 2021, but [#988](https://github.com/bit-team/backintime/issues/988) and [#994](https://github.com/bit-team/backintime/issues/994) remained. ## The Third Era: since 1.3.3 (since 2022) In early 2022, an epic discussion on the state of the project arose in [#1232](https://github.com/bit-team/backintime/issues/1232). Many users declared their love for _Back In Time_, and a few were ready to step up and restart development. With help and permission from Germar Reitze, **Christian Buhtz**, **Jürgen Altfeld** and **Michael Büker** formed a new core team. The team first curated and triaged over 200 open issues that had accumulated since 2019. The first release by the new team was version 1.3.3 in early 2023. Early work focused on ensuring compatibility with rsync 3.2.4, fixing keyring issues for SSH operations, system tray functionality in both X11 and Wayland as well as testing, coding style and other modernization to align _Back In Time_ with current Python practices. ### Core functionality Work on fixing [#988](https://github.com/bit-team/backintime/issues/988) and [#994](https://github.com/bit-team/backintime/issues/994) is still ongoing as of this writing. These bugs are largely understood now, but any possible fix could potentially have grave consequences for existing backups, which have not been thoroughly tested for. Given that EncFS suffers from known security issues and is not actively maintained, _Back In Time_ is preparing to deprecate it in the foreseeable future ([#1734](https://github.com/bit-team/backintime/issues/1734)). ### GUI The GUI is slated for a redesign and code refactoring, as it has become complex and convoluted over the years. A commonly requested feature is a terminal user interface (TUI), or an enhancement of the existing command-line interface (CLI), as discussed in [#254](https://github.com/bit-team/backintime/issues/254). The proposal for a web frontend was rejected ([#209](https://github.com/bit-team/backintime/issues/209)), but separate projects offering a web fronted would be supported. backintime-1.5.4/LICENSE000066400000000000000000000431031477034762000146470ustar00rootroot00000000000000 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. backintime-1.5.4/LICENSES/000077500000000000000000000000001477034762000150465ustar00rootroot00000000000000backintime-1.5.4/LICENSES/CC0-1.0.txt000066400000000000000000000156101477034762000164530ustar00rootroot00000000000000Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer 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, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. backintime-1.5.4/LICENSES/GPL-2.0-or-later.txt000066400000000000000000000416711477034762000202620ustar00rootroot00000000000000GNU 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. 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. one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author 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. signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice backintime-1.5.4/LICENSES/GPL-3.0-or-later.txt000066400000000000000000001035621477034762000202610ustar00rootroot00000000000000GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright © 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 . backintime-1.5.4/LICENSES/MIT.txt000066400000000000000000000020661477034762000162440ustar00rootroot00000000000000MIT 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. backintime-1.5.4/README.md000066400000000000000000000171671477034762000151340ustar00rootroot00000000000000 [![Build Status](https://app.travis-ci.com/bit-team/backintime.svg)](https://app.travis-ci.com/bit-team/backintime) [![Source code documentation Status](https://readthedocs.org/projects/backintime-dev/badge/?version=latest)](https://backintime-dev.readthedocs.io) [![Translation status](https://translate.codeberg.org/widget/backintime/common/svg-badge.svg)](https://translate.codeberg.org/engage/backintime) [![Mailing list bit-dev@python.org](doc/maintain/_images/badge_bit-dev.svg)](https://mail.python.org/mailman3/lists/bit-dev.python.org/) [![Mastodon @backintime@fosstodon.org](doc/maintain/_images/badge_mastodon.svg)](https://fosstodon.org/@backintime) # Back In Time Copyright © 2008-2024 Oprea Dan, Bart de Koning, Richard Bailey, Germar Reitze, Taylor Raack
Copyright © 2022 Christian Buhtz, Michael Büker, Jürgen Altfeld _Back In Time_ is a comfortable and well-configurable graphical frontend for incremental backups using [`rsync`](https://rsync.samba.org/), with a command-line version also available. Modified files are transferred, while unchanged files are linked to the new folder using rsync's hard link feature, saving storage space. Restoring is straightforward via file manager, command line or _Back In Time_ itself. It is written in Python3 and available for all major GNU/Linux distributions (but not for Windows or OS X/macOS) as command line tool `backintime` and GUI `backintime-qt`. Backups can be scheduled and stored locally or remotely through SSH. More background info in [CONTRIBUTING](CONTRIBUTING.md) and [HISTORY](HISTORY.md). ## Maintenance status The project is in active development since the [new team](#the-team) joined in summer 2022. Development is done voluntarilly in spare time so things need to be prioritized. Stick with us, we all ♥️ _Back In Time_. 😁 Current focus is on fixing [major issues](https://github.com/bit-team/backintime/issues?q=is%3Aissue+is%3Aopen+label%3AHigh) instead of implementing new [features](https://github.com/bit-team/backintime/labels/Feature). Stabilize the code base and its test suite is also a matter. Read the [strategy outline](CONTRIBUTING.md#strategy-outline) for details. Please see [CONTRIBUTING](CONTRIBUTING.md) if you are interested in the development and have a look on [open issues](https://github.com/bit-team/backintime/issues) especially those labeled as [good first issues](https://github.com/bit-team/backintime/labels/GOOD%20FIRST%20ISSUE) and [help wanted](https://github.com/bit-team/backintime/issues?q=is%3Aissue+is%3Aopen+label%3AHELP-WANTED). ## The team The current team started in summer of 2022 (with [#1232](https://github.com/bit-team/backintime/issues/1232)) and constitutes the project's 3rd generation of maintainers. Consisting of three members with diverse backgrounds (@aryoda, @buhtz, @emtiu), the team benefits from the assistance of the former maintainer, @Germar, who contributes from behind the scenes. All team members are engaged in every aspect of the project, including code analysis, documentation, solving issues, and the implementation of new features. This work is carried out voluntarily during their limited spare time. # Index - [Documentation](#documentation) - [Contact & Social](#contact--social) - [Installation](#installation) - [Known Problems and Workarounds](#known-problems-and-workarounds) - [Contributing and other ways to support the project](#contributing-and-other-ways-to-support-the-project) --- # Documentation * [FAQ - Frequently Asked Questions](FAQ.md) * [End user documentation](https://backintime.readthedocs.org/) (not totally up-to-date) * [Source code documentation for developers](https://backintime-dev.readthedocs.org) # Contact & Social * **Mailing list**: [bit-dev@python.org](https://mail.python.org/mailman3/lists/bit-dev.python.org/) can be used for **every topic**, question and idea about _Back In Time_. Despite its name it is not restricted to development topics only. * **Fediverse** on **Mastodon**: [@backintime@fosstodon.org](https://fosstodon.org/@backintime) * **Bugs** & **Feature Requests**: [Issues section](https://github.com/bit-team/backintime/issues) # Installation _Back In Time_ is included in [many GNU/Linux distributions](https://repology.org/project/backintime/badges). Use their repositories to install it. If you want to contribute or using the latest development version of _Back In Time_ please see section [Build & Install](CONTRIBUTING.md#build--install) in [`CONTRIBUTING.md`](CONTRIBUTING.md). Also the dependencies are described there. ## Alternative installation options Besides the repositories of the official GNU/Linux distributions, there are other alternative installation options provided and maintained by third parties. Use them at your own risk and please contact that third party maintainers if you encounter problems. - [@Germar](https://github.com/germar)'s Personal Package Archive ([PPA](https://launchpad.net/ubuntu/+ppas)) offering [`ppa:bit-team/stable`](https://launchpad.net/~bit-team/+archive/ubuntu/stable) as stable and [`ppa:bit-team/testing`](https://launchpad.net/~bit-team/+archive/ubuntu/testing) as testing PPA. - [@jean-christophe-manciot](https://github.com/jean-christophe-manciot)'s PPA distributing [_Back In Time_ for the latest stable Ubuntu release](https://git.sdxlive.com/PPA/about). See [PPA requirements](https://git.sdxlive.com/PPA/about/#requirements) and [install instructions](https://git.sdxlive.com/PPA/about/#installing-the-ppa). - The Arch User Repository ([AUR](https://aur.archlinux.org/)) does offer [some packages](https://aur.archlinux.org/packages?K=backintime). # Known Problems and Workarounds In the latest stable release: - [File permissions handling and therefore possible non-differential backups](#file-permissions-handling-and-therefore-possible-non-differential-backups) - [`qt_probing.py` may hang with high CPU usage when running BiT as `root` via `cron`](#qt_probingpy-may-hang-with-high-cpu-usage-when-running-bit-as-root-via-cron) More problems described in [this FAQ section](FAQ.md#problems-errors--solutions). ## File permissions handling and therefore possible non-differential backups In version 1.2.0, the handling of file permissions changed. In versions <= 1.1.24 (until 2017) all file permissions were set to `-rw-r--r--` in the backup target. In versions >= 1.2.0 (since 2019) `rsync` is executed with `--perms` option which tells `rsync` to preserve the source file permission. Therefore backups can be larger and slower, especially the first backup after upgrading to a version >= 1.2.0. If you don't like the new behavior, you can use _Expert Options_ -> _Paste additional options to rsync_ to add `--no-perms --no-group --no-owner` to it. Note that the exact file permissions can still be found in `fileinfo.bz2` and are also considered when restoring files. ## `qt_probing.py` may hang with high CPU usage when running BiT as `root` via `cron` See the related issue [#1592](https://github.com/bit-team/backintime/issues/1592). The only reliable work-around is to delete (or move into another folder) the file `/usr/share/backintime/common/qt_probing.py`: `mv /usr/share/backintime/common/qt_probing.py /usr/share/backintime/` Renaming does *not* work! # Contributing and other ways to support the project See [CONTRIBUTING](CONTRIBUTING.md) file for an overview about the projects workflow and strategy. --- March 2025 backintime-1.5.4/REUSE.toml000066400000000000000000000016241477034762000154240ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = [ "AUTHORS", "VERSION", "CHANGES", "TRANSLATIONS", "common/config-example-*", "common/test/config", ] SPDX-License-Identifier = "CC0-1.0" SPDX-FileCopyrightText = "© 2008 Back In Time Team" [[annotations]] path = [ "common/man/C/*", "qt/man/C/*", ] SPDX-License-Identifier = "GPL-2.0-or-later" SPDX-FileCopyrightText = "© 2008 Back In Time Team" backintime-1.5.4/TRANSLATIONS000066400000000000000000000046411477034762000155120ustar00rootroot00000000000000Arabic [ar]: - Maytham Alsudany - Jad Madi (@jadmadi) Basque [eu]: Alexander Gabilondo Bokmål (Norwegian) [nb_NO]: Hans Fredrik Nordhaug Catalan [ca]: Josep Sanchez Chinese (Simplified) [zh_CN,zh_Hans]: Kuntao Zhao Chinese (Traditional) [zh_TW,zh_Hant]: Kuntao Zhao Danish [da]: Adam Sjøgren Finnish [fi]: - Ellen Rönnholm French [fr]: - bubu of Debian-l10n-fr - Michel Corps (@jej) German [de]: Michael Wiedmann Greek [el]: - Dimitris Tzemos - Iliana Panagopoulou (hpanago) - Paraskevas Leivadaros Hebrew [he]: Yaron Shahrabani Hungarian [hu]: Balázs Úr (@urbalazs) Indonesian [id]: Andika Triwidada Interlingua [ie]: "OIS" Japanese [ja]: - Sadaharu Wakisaka - Ayako Buhtz - AmaseCocoa (甘瀬ここあ) Nynorsk (Norwegian) [nn] - Hans Fredrik Nordhaug - VL Persian (Farsi) [fa]: - Farooq Karimi Zadeh - Parsa Ranjbar Polish [pl]: Paweł Hołuj Portuguese (Brazilian) [pt_BR]: - Scythemare - Andre Desgualdo Pereira - Yuri Musachio Portuguese [pt]: - Yuri Musachio - Filipe Oliveira (@filipeaaoliveira) Romanian [ro]: Florentina Mușat Russian [ru]: Vadim Peretokin Serbian (Latin) [sr_Latn]: - Mališa "Maki711" Jevremović Slovak [sk]: Tomáš Vadina Slovenian [sl]: - Vanja Cvelbar - Liam Starič (ravijol1) Spanish [es]: - Francisco Manuel García Claramonte - Mauricio J. Adonis C. Swedish [sv]: - Luna Jernberg - Niklas Grahn Turkish [tr]: - Taner Orak - Onur Esat Karabacak Vietnamese [vi]: Hai Nam Other languages: - Launchpad translators - - - Several mailing lists in Debian (@lists.debian.org) & Ubuntu (@lists.ubuntu.com) especially the user related lists backintime-1.5.4/VERSION000066400000000000000000000000061477034762000147050ustar00rootroot000000000000001.5.4 backintime-1.5.4/common/000077500000000000000000000000001477034762000151315ustar00rootroot00000000000000backintime-1.5.4/common/applicationinstance.py000066400000000000000000000210671477034762000215410ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """ This module holds the ApplicationInstance class, used to handle the one application instance mechanism. """ import os import fcntl import logger import tools # TODO This class name is a misnomer (there may be more than # one app instance eg. if a restore is running and another # backup starts). # Rename it to eg. LockFileManager # TODO2 When refactoring have a look at "common/flock.py" still implementing # a contxt manager for that problem. class ApplicationInstance: """ Class used to handle one application instance mechanism. Args: pidFile (str): full path of file used to save pid and procname autoExit (bool): automatically call sys.exit if there is an other instance running flock (bool): use file-locks to make sure only one instance is checking at the same time """ def __init__(self, pidFile, autoExit=True, flock=False): self.pidFile = pidFile self.pid = 0 self.procname = '' self.flock = None if flock: self.flockExclusiv() if autoExit: if self.check(True): self.startApplication() def __del__(self): self.flockUnlock() # TODO Rename to is_single_instance() to make the purpose more obvious def check(self, autoExit=False): """Check if the current application is already running. Args: autoExit (bool): Automatically call ``sys.exit()`` if there is another instance running. Returns: bool: ``True`` if this is the only application instance. """ # check if the pidfile exists if not os.path.isfile(self.pidFile): return True self.pid, self.procname = self.readPidFile() # check if the process (PID) that created the pid file still exists if 0 == self.pid: return True if not tools.processAlive(self.pid): return True # check if the process has the same procname # check cmdline for backwards compatibility if self.procname and \ self.procname != tools.processName(self.pid) and \ self.procname != tools.processCmdline(self.pid): return True if autoExit: # exit the application print("The application is already running !") # exit raise an exception so don't put it in a try/except block exit(0) return False def busy(self): """ Check if one application with this instance is currently running. Returns: bool: ``True`` if an other instance is currently running. """ return not self.check() def startApplication(self): """ Called when the single instance starts to save its pid """ pid = os.getpid() procname = tools.processName(pid) try: with open(self.pidFile, 'wt') as f: f.write('{}\n{}'.format(pid, procname)) except OSError as e: logger.error( 'Failed to write PID file %s: [%s] %s' % (e.filename, e.errno, e.strerror)) # The flock is removed here because it shall only ensure serialized access to the "pidFile" (lock file): # Without setting flock in __init__ another process could also check for the existences of the "pidFile" # in parallel and also create a new one (overwriting the one created here). self.flockUnlock() def exitApplication(self): """ Called when the single instance exit (remove pid file) """ try: os.remove(self.pidFile) except: pass def flockExclusiv(self): """ Create an exclusive advisory file lock named .flock to block the creation of a second instance while the first instance is still in the process of starting (but has not yet completely started). The purpose is to make 1. the check if the PID lock file already exists 2. and the subsequent creation of the PID lock file an atomic operation by using a blocking "flock" file lock on a second file to avoid that two or more processes check for an existing PID lock file, find none and create a new one (so that only the last creator wins). Dev notes: ---------- buhtz (2023-09): Not sure but just log an ERROR without doing anything else is IMHO not enough. aryoda (2023-12): It seems the purpose of this additional lock file using an exclusive lock is to block the other process to continue until this exclusive lock is released (= serialize execution). Therefore advisory locks are used via fcntl.flock (see: man 2 fcntl) buhtz (2024-05): Have a look at the new :mod:`flock` module providing an flock context manager. """ flock_file_URI = self.pidFile + '.flock' logger.debug(f"Trying to put an advisory lock on the flock file {flock_file_URI}") try: self.flock = open(flock_file_URI, 'w') # This opens an advisory lock which which is considered only # if other processes cooperate by explicitly acquiring locks # (which BiT does IMHO). # TODO Does this lock request really block if another processes # already holds a lock (until the lock is released)? # = Is the execution serialized? # Provisional answer: # Yes, fcntl.flock seems to wait until the lock is removed # from the file. # Tested by starting one process in the console via # python3 applicationinstance.py # and then (while the first process is still running) # the same command in a 2nd terminal. # The ApplicationInstance constructor call needs # to be changed for this by adding "False, True" # to trigger an exclusive lock. fcntl.flock(self.flock, fcntl.LOCK_EX) except OSError as e: logger.error('Failed to write flock file %s: [%s] %s' % (e.filename, e.errno, e.strerror)) def flockUnlock(self): """ Remove the exclusive lock. Second instance can now continue but should find it self to be obsolete. """ if self.flock: logger.debug(f"Trying to remove the advisory lock from the flock file {self.flock.name}") fcntl.fcntl(self.flock, fcntl.LOCK_UN) self.flock.close() try: os.remove(self.flock.name) except: # an other instance was faster # race condition while using 'if os.path.exists(...)' pass self.flock = None def readPidFile(self): """ Read the pid and procname from the file Returns: tuple: tuple of (pid(int), procname(str)) """ pid = 0 procname = '' try: with open(self.pidFile, 'rt') as f: data = f.read() data = data.split('\n', 1) if data[0].isdigit(): pid = int(data[0]) if len(data) > 1: procname = data[1].strip('\n') except OSError as e: logger.warning( 'Failed to read PID and process name from %s: [%s] %s' % (e.filename, e.errno, e.strerror)) except ValueError as e: logger.warning( 'Failed to extract PID and process name from %s: %s' % (self.pidFile, str(e))) return (pid, procname) if __name__ == '__main__': import time # create application instance appInstance = ApplicationInstance('/tmp/myapp.pid') # do something here print("Start MyApp") time.sleep(5) # sleep 5 seconds print("End MyApp") # remove pid file appInstance.exitApplication() backintime-1.5.4/common/askpass.py000066400000000000000000000021701477034762000171500ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import password import password_ipc import tools import config if __name__ == '__main__': """ return password. """ cfg = config.Config() tools.envLoad(cfg.cronEnvFile()) profile_id = os.getenv('ASKPASS_PROFILE_ID', '1') mode = os.getenv('ASKPASS_MODE', 'local') if mode == 'USER': prompt = os.getenv('ASKPASS_PROMPT', None) pw = password.Password(cfg) print(pw.passwordFromUser(None, prompt = prompt)) sys.exit(0) temp_file = os.getenv('ASKPASS_TEMP') if temp_file is None: #normal mode, get password from module password pw = password.Password(cfg) print(pw.password(None, profile_id, mode)) sys.exit(0) #temp mode fifo = password_ipc.FIFO(temp_file) pw = fifo.read(5) if pw: print(pw) backintime-1.5.4/common/backintime000077500000000000000000000026651477034762000171760ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2017 Matthias Gerstner # SPDX-FileCopyrightText: © 2024 Jürgen Altfeld # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Location of this script CUR_PATH="$(dirname $(readlink -m $0))" # Was this script started in the source code folder (normally during development)? if [ -f "${CUR_PATH}/backintime.py" ]; then APP_PATH=$CUR_PATH else # CUR_PATH must be /usr/bin (the default installation path of this script) # or another sibling folder of "share" (in case of an alternative installation # folder like "/var/bin" where BiT must be installed into /var/share/backintime then) APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/common") fi # -E ignores env vars like PYTHONPATH and PYTHONHOME that may modify # the behavior of the interpreter # -s Don't add user site directory to sys.path # TODO Should we use "$APP_PATH" (quoted) to prevent globbing and word splitting? /usr/bin/python3 -Es $APP_PATH/backintime.py "$@" backintime-1.5.4/common/backintime-askpass000077500000000000000000000015751477034762000206400ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2017 Matthias Gerstner # SPDX-FileCopyrightText: © 2024 Jürgen Altfeld # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # fixing gray window error # https://launchpad.net/bugs/1493020 export QT_GRAPHICSSYSTEM="native" CUR_PATH="$(dirname $(readlink -m $0))" if [ -f "${CUR_PATH}/askpass.py" ]; then APP_PATH=$CUR_PATH else APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/common") fi /usr/bin/python3 -Es $APP_PATH/askpass.py "$@" backintime-1.5.4/common/backintime.desktop000066400000000000000000000012431477034762000206320ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2009 Back In Time team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . [Desktop Entry] Version=1.5 Name=Back In Time Password Cache Exec=/bin/sh -c "backintime pw-cache start 2>&1 >/dev/null" Comment=Cache passwords for non-interactive Back In Time cronjobs Icon=gtk-save Terminal=NO Type=Application backintime-1.5.4/common/backintime.py000066400000000000000000001276651477034762000176320ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import argparse import atexit import subprocess from datetime import datetime from time import sleep import json import pathlib import tools # Workaround for situations where startApp() is not invoked. # E.g. when using --diagnostics and other argparse.Action tools.initiate_translation(None) import config import logger import snapshots import sshtools import mount import password import encfstools import cli from bitbase import URL_ENCRYPT_TRANSITION from diagnostics import collect_diagnostics, collect_minimal_diagnostics from exceptions import MountException from applicationinstance import ApplicationInstance from version import __version__ RETURN_OK = 0 RETURN_ERR = 1 RETURN_NO_CFG = 2 parsers = {} def takeSnapshotAsync(cfg, checksum=False): """ Fork a new backintime process with 'backup' command which will take a new snapshot in background. Args: cfg (config.Config): config that should be used """ cmd = [] if cfg.ioniceOnUser(): cmd.extend(('ionice', '-c2', '-n7')) cmd.append('backintime') if '1' != cfg.currentProfile(): cmd.extend(('--profile-id', str(cfg.currentProfile()))) if cfg._LOCAL_CONFIG_PATH is not cfg._DEFAULT_CONFIG_PATH: cmd.extend(('--config', cfg._LOCAL_CONFIG_PATH)) if cfg._LOCAL_DATA_FOLDER is not cfg._DEFAULT_LOCAL_DATA_FOLDER: cmd.extend(('--share-path', cfg.DATA_FOLDER_ROOT)) if logger.DEBUG: cmd.append('--debug') if checksum: cmd.append('--checksum') cmd.append('backup') # child process need to start its own ssh-agent because otherwise # it would be lost without ssh-agent if parent will close env = os.environ.copy() for i in ('SSH_AUTH_SOCK', 'SSH_AGENT_PID'): try: del env[i] except: pass subprocess.Popen(cmd, env = env) def takeSnapshot(cfg, force=True): """ Take a new snapshot. Args: cfg (config.Config): config that should be used force (bool): take the snapshot even if it wouldn't need to or would be prevented (e.g. running on battery) Returns: bool: ``True`` if there was an error """ tools.envLoad(cfg.cronEnvFile()) ret = snapshots.Snapshots(cfg).backup(force) return ret def _mount(cfg): """ Mount external filesystems. Args: cfg (config.Config): Config that should be used. """ try: hash_id = mount.Mount(cfg=cfg).mount() except MountException as ex: logger.error(str(ex)) sys.exit(RETURN_ERR) else: cfg.setCurrentHashId(hash_id) def _umount(cfg): """ Unmount external filesystems. Args: cfg (config.Config): Config that should be used. """ try: mount.Mount(cfg=cfg).umount(cfg.current_hash_id) except MountException as ex: logger.error(str(ex)) def createParsers(app_name='backintime'): """ Define parsers for commandline arguments. Args: app_name (str): string representing the current application """ global parsers #define debug debugArgsParser = argparse.ArgumentParser(add_help = False) debugArgsParser.add_argument('--debug', action = 'store_true', help = 'Increase verbosity.') #define config argument configArgsParser = argparse.ArgumentParser(add_help = False) configArgsParser.add_argument('--config', metavar = 'PATH', type = str, action = 'store', help = 'Read config from %(metavar)s. ' + 'Default = ~/.config/backintime/config') configArgsParser.add_argument('--share-path', metavar = 'PATH', type = str, action = 'store', help = 'Write runtime data (locks, messages, log and mountpoints) to %(metavar)s.') #define common arguments which are used for all commands commonArgsParser = argparse.ArgumentParser(add_help = False, parents = [configArgsParser, debugArgsParser]) profileGroup = commonArgsParser.add_mutually_exclusive_group() profileGroup.add_argument ('--profile', metavar = 'NAME', type = str, action = 'store', help = 'Select profile by %(metavar)s.') profileGroup.add_argument ('--profile-id', metavar = 'ID', type = int, action = 'store', help = 'Select profile by %(metavar)s.') commonArgsParser.add_argument('--quiet', action = 'store_true', help = 'Be quiet. Suppress messages on stdout.') #define arguments which are only used by snapshots-path, snapshots-list-path and last-snapshot-path snapshotPathParser = argparse.ArgumentParser(add_help = False) snapshotPathParser.add_argument('--keep-mount', action = 'store_true', help = "Don't unmount on exit.") #define arguments which are used by rsync commands (backup and restore) rsyncArgsParser = argparse.ArgumentParser(add_help = False) rsyncArgsParser.add_argument('--checksum', action = 'store_true', help = 'force to use checksum for checking if files have been changed.') #define arguments for snapshot remove removeArgsParser = argparse.ArgumentParser(add_help = False) removeArgsParser.add_argument('SNAPSHOT_ID', type = str, action = 'store', nargs = '*', help = 'ID of snapshots which should be removed.') #define main argument parser parser = argparse.ArgumentParser(prog = app_name, parents = [commonArgsParser], description = '%(app)s - a simple backup tool for GNU/Linux.' % {'app': config.Config.APP_NAME}, epilog = "For backwards compatibility commands can also be used with trailing '--'. " "All listed arguments will work with all commands. Some commands have extra arguments. " "Run '%(app_name)s -h' to see the extra arguments." % {'app_name': app_name}) parsers['main'] = parser parser.add_argument('--version', '-v', action = 'version', version = '%(prog)s ' + __version__, help = "show %(prog)s's version number.") parser.add_argument('--license', action = printLicense, nargs = 0, help = "show %(prog)s's license.") parser.add_argument('--diagnostics', action = printDiagnostics, nargs = 0, help = "show helpful info for better support in case of issues (in JSON format)") ####################### ### define commands ### ####################### epilog = "Run '%(app_name)s -h' to get help for additional arguments. " %{'app_name': app_name} epilogCommon = epilog + 'Additional arguments: --config, --debug, --profile, --profile-id, --quiet' epilogConfig = epilog + 'Additional arguments: --config, --debug' subparsers = parser.add_subparsers(title = 'Commands', dest = 'command') command = 'backup' nargs = 0 aliases = [(command, nargs), ('b', nargs)] description = 'Take a new snapshot. Ignore if the profile ' +\ 'is not scheduled or if the machine is running on battery.' backupCP = subparsers.add_parser(command, parents = [rsyncArgsParser], epilog = epilogCommon, help = description, description = description) backupCP.set_defaults(func = backup) parsers[command] = backupCP command = 'backup-job' nargs = 0 aliases.append((command, nargs)) description = 'Take a new snapshot in background only ' +\ 'if the profile is scheduled and the machine ' +\ 'is not on battery. This is used by cron jobs.' backupJobCP = subparsers.add_parser(command, parents = [rsyncArgsParser], epilog = epilogCommon, help = description, description = description) backupJobCP.set_defaults(func = backupJob) parsers[command] = backupJobCP command = 'benchmark-cipher' nargs = '?' aliases.append((command, nargs)) description = 'Show a benchmark of all ciphers for ssh transfer.' benchmarkCipherCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) benchmarkCipherCP.set_defaults(func = benchmarkCipher) parsers[command] = benchmarkCipherCP benchmarkCipherCP.add_argument ('FILE_SIZE', type = int, action = 'store', default = 40, nargs = '?', help = 'File size used for benchmark.') command = 'check-config' description = 'Check the profiles configuration and install crontab entries.' checkConfigCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) checkConfigCP.add_argument ('--no-crontab', action = 'store_true', help = 'Do not install crontab entries.') checkConfigCP.set_defaults(func = checkConfig) parsers[command] = checkConfigCP command = 'decode' nargs = '*' aliases.append((command, nargs)) description = "Decode paths with 'encfsctl decode'" decodeCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) decodeCP.set_defaults(func = decode) parsers[command] = decodeCP decodeCP.add_argument ('PATH', type = str, action = 'store', nargs = '*', help = 'Decode PATH. If no PATH is specified on command line ' +\ 'a list of filenames will be read from stdin.') command = 'last-snapshot' nargs = 0 aliases.append((command, nargs)) description = 'Show the ID of the last snapshot.' lastSnapshotCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) lastSnapshotCP.set_defaults(func = lastSnapshot) parsers[command] = lastSnapshotCP command = 'last-snapshot-path' nargs = 0 aliases.append((command, nargs)) description = 'Show the path of the last snapshot.' lastSnapshotsPathCP = subparsers.add_parser(command, parents = [snapshotPathParser], epilog = epilogCommon, help = description, description = description) lastSnapshotsPathCP.set_defaults(func = lastSnapshotPath) parsers[command] = lastSnapshotsPathCP command = 'pw-cache' nargs = '*' aliases.append((command, nargs)) description = 'Control Password Cache for non-interactive cronjobs.' pwCacheCP = subparsers.add_parser(command, epilog = epilogConfig, help = description, description = description) pwCacheCP.set_defaults(func = pwCache) parsers[command] = pwCacheCP pwCacheCP.add_argument ('ACTION', action = 'store', choices = ['start', 'stop', 'restart', 'reload', 'status'], nargs = '?', help = 'Command to send to Password Cache daemon.') command = 'remove' nargs = '*' aliases.append((command, nargs)) description = 'Remove a snapshot.' removeCP = subparsers.add_parser(command, parents = [removeArgsParser], epilog = epilogCommon, help = description, description = description) removeCP.set_defaults(func = remove) parsers[command] = removeCP command = 'remove-and-do-not-ask-again' nargs = '*' aliases.append((command, nargs)) description = "Remove snapshots and don't ask for confirmation before. Be careful!" removeDoNotAskCP = subparsers.add_parser(command, parents = [removeArgsParser], epilog = epilogCommon, help = description, description = description) removeDoNotAskCP.set_defaults(func = removeAndDoNotAskAgain) parsers[command] = removeDoNotAskCP command = 'restore' nargs = '*' aliases.append((command, nargs)) description = 'Restore files.' restoreCP = subparsers.add_parser(command, parents = [rsyncArgsParser], epilog = epilogCommon, help = description, description = description) restoreCP.set_defaults(func = restore) parsers[command] = restoreCP backupGroup = restoreCP.add_mutually_exclusive_group() restoreCP.add_argument ('WHAT', type = str, action = 'store', nargs = '?', help = 'Restore file or directory WHAT.') restoreCP.add_argument ('WHERE', type = str, action = 'store', nargs = '?', help = "Restore to WHERE. An empty argument '' will restore to original destination.") restoreCP.add_argument ('SNAPSHOT_ID', type = str, action = 'store', nargs = '?', help = 'Which SNAPSHOT_ID should be used. This can be a snapshot ID or ' +\ 'an integer starting with 0 for the last snapshot, 1 for the second to last, ... ' +\ 'the very first snapshot is -1') restoreCP.add_argument ('--delete', action = 'store_true', help = 'Restore and delete newer files which are not in the snapshot. ' +\ 'WARNING: deleting files in filesystem root could break your whole system!!!') backupGroup.add_argument ('--local-backup', action = 'store_true', help = 'Create backup files before changing local files.') backupGroup.add_argument ('--no-local-backup', action = 'store_true', help = 'Temporarily disable creation of backup files before changing local files. ' +\ 'This can be switched off permanently in Settings, too.') restoreCP.add_argument ('--only-new', action = 'store_true', help = 'Only restore files which do not exist or are newer than ' +\ 'those in destination. Using "rsync --update" option.') command = 'shutdown' nargs = 0 description = 'Shut down the computer after the snapshot is done.' shutdownCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) shutdownCP.set_defaults(func = shutdown) parsers[command] = shutdownCP command = 'smart-remove' nargs = 0 description = 'Remove snapshots based on "Smart Removal" pattern.' smartRemoveCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) smartRemoveCP.set_defaults(func = smartRemove) parsers[command] = smartRemoveCP command = 'snapshots-list' nargs = 0 aliases.append((command, nargs)) description = 'Show a list of snapshot IDs.' snapshotsListCP = subparsers.add_parser(command, parents = [snapshotPathParser], epilog = epilogCommon, help = description, description = description) snapshotsListCP.set_defaults(func = snapshotsList) parsers[command] = snapshotsListCP command = 'snapshots-list-path' nargs = 0 aliases.append((command, nargs)) description = "Show the paths to snapshots." snapshotsListPathCP = subparsers.add_parser(command, parents = [snapshotPathParser], epilog = epilogCommon, help = description, description = description) snapshotsListPathCP.set_defaults(func = snapshotsListPath) parsers[command] = snapshotsListPathCP command = 'snapshots-path' nargs = 0 aliases.append((command, nargs)) description = 'Show the path where snapshots are stored.' snapshotsPathCP = subparsers.add_parser(command, parents = [snapshotPathParser], epilog = epilogCommon, help = description, description = description) snapshotsPathCP.set_defaults(func = snapshotsPath) parsers[command] = snapshotsPathCP command = 'unmount' nargs = 0 aliases.append((command, nargs)) description = 'Unmount the profile.' unmountCP = subparsers.add_parser(command, epilog = epilogCommon, help = description, description = description) unmountCP.set_defaults(func = unmount) parsers[command] = unmountCP #define aliases for all commands with trailing -- group = parser.add_mutually_exclusive_group() for alias, nargs in aliases: if len(alias) == 1: arg = '-%s' % alias else: arg = '--%s' % alias group.add_argument(arg, nargs=nargs, action=PseudoAliasAction, help=argparse.SUPPRESS) def encfs_deprecation_warning(): """Warn about encfs deprecation in syslog. See Issue #1734 for details. This function is a workraound and will be removed if #1734 is closed. """ # Don't warn if EncFS isn't installed if not tools.checkCommand('encfs'): return # Timestamp file xdg_state = os.environ.get('XDG_STATE_HOME', None) if xdg_state: xdg_state = pathlib.Path(xdg_state) else: xdg_state = pathlib.Path.home() / '.local' / 'state' fp = xdg_state / 'backintime.encfs-warning.timestamp' # ensure existence if not fp.exists(): fp.parent.mkdir(parents=True, exist_ok=True) fp.touch() # Calculate age of that file delta = datetime.now() - datetime.fromtimestamp(fp.stat().st_mtime) # Don't warn if to young if delta.days < 30: return logger.warning('EncFS encrypted profiles are deprecated in Back In Time. ' 'Removal is schedule for minor release 1.7 in year 2026. ' 'For details and alternatives ' f'read: {URL_ENCRYPT_TRANSITION}') # refresh timestamp fp.touch() def startApp(app_name='backintime'): """ Start the requested command or return config if there was no command in arguments. Args: app_name (str): string representing the current application Returns: config.Config: current config if no command was given in arguments """ createParsers(app_name) logger.openlog() args = argParse(None) # Name, Version, As Root, OS msg = '' for key, val in collect_minimal_diagnostics().items(): msg = f'{msg}; {key}: {val}' logger.debug(msg[2:]) # Add source path to $PATH environ if running from source if tools.runningFromSource(): tools.addSourceToPathEnviron() # Warn about sudo if (tools.usingSudo() and os.getenv('BIT_SUDO_WARNING_PRINTED', 'false') == 'false'): os.putenv('BIT_SUDO_WARNING_PRINTED', 'true') logger.warning( "It looks like you're using 'sudo' to start " f"{config.Config.APP_NAME}. This will cause some trouble. " f"Please use either 'sudo -i {app_name}' or 'pkexec {app_name}'.") encfs_deprecation_warning() # Call commands if 'func' in dir(args): args.func(args) else: setQuiet(args) printHeader() return getConfig(args, False) def argParse(args): """ Parse arguments given on commandline. Args: args (argparse.Namespace): Namespace that should be enhanced or ``None`` Returns: argparser.Namespace: new parsed Namespace """ def join(args, subArgs): """ Add new arguments to existing Namespace. Args: args (argparse.Namespace): main Namespace that should get new arguments subArgs (argparse.Namespace): second Namespace which have new arguments that should be merged into ``args`` """ for key, value in vars(subArgs).items(): # Only add new values if it isn't set already or if there really IS # a value if getattr(args, key, None) is None or value: setattr(args, key, value) # First parse the main parser without subparsers # otherwise positional args in subparsers will be to greedy # but only if -h or --help is not involved because otherwise # help will not work for subcommands mainParser = parsers['main'] sub = [] if '-h' not in sys.argv and '--help' not in sys.argv: for i in mainParser._actions: if isinstance(i, argparse._SubParsersAction): # Remove subparsers mainParser._remove_action(i) sub.append(i) args, unknownArgs = mainParser.parse_known_args(args) # Read subparsers again if sub: [mainParser._add_action(i) for i in sub] # Parse it again for unknown args if unknownArgs: subArgs, unknownArgs = mainParser.parse_known_args(unknownArgs) join(args, subArgs) # Finally parse only the command parser, otherwise we miss some arguments # from command if unknownArgs and 'command' in args and args.command in parsers: commandParser = parsers[args.command] subArgs, unknownArgs = commandParser.parse_known_args(unknownArgs) join(args, subArgs) try: logger.DEBUG = args.debug except AttributeError: pass args_dict = vars(args) used_args = { key: args_dict[key] for key in filter(lambda key: args_dict[key] is not None, args_dict) } logger.debug(f'Argument(s) used: {used_args}') # Report unknown arguments but not if we run aliasParser next because we # will parse again in there. if unknownArgs and not ('func' in args and args.func is aliasParser): mainParser.error(f'Unknown argument(s): {unknownArgs}') return args def printHeader(): """ Print application name, version and legal notes. """ print('') print('Back In Time') print('Version: ' + __version__) print('') print('Back In Time comes with ABSOLUTELY NO WARRANTY.') print('This is free software, and you are welcome to redistribute it') print("under certain conditions; type `backintime --license' for details.") print('') class PseudoAliasAction(argparse.Action): """ Translate '--COMMAND' into 'COMMAND' for backwards compatibility. """ def __call__(self, parser, namespace, values, option_string=None): """ Translate '--COMMAND' into 'COMMAND' for backwards compatibility. Args: parser (argparse.ArgumentParser): NotImplemented namespace (argparse.Namespace): Namespace that should get modified values: NotImplemented option_string: NotImplemented """ #TODO: find a more elegant way to solve this dest = self.dest.replace('_', '-') if self.dest == 'b': replace = '-b' alias = 'backup' else: replace = '--%s' % dest alias = dest setattr(namespace, 'func', aliasParser) setattr(namespace, 'replace', replace) setattr(namespace, 'alias', alias) def aliasParser(args): """ Call commands which where given with leading -- for backwards compatibility. Args: args (argparse.Namespace): previously parsed arguments """ if not args.quiet: logger.info("Run command '%(alias)s' instead of argument '%(replace)s' due to backwards compatibility." % {'alias': args.alias, 'replace': args.replace}) argv = [w.replace(args.replace, args.alias) for w in sys.argv[1:]] newArgs = argParse(argv) if 'func' in dir(newArgs): newArgs.func(newArgs) def getConfig(args, check=True): """ Load config and change to profile selected on commandline. Args: args (argparse.Namespace): previously parsed arguments check (bool): if ``True`` check if config is valid Returns: config.Config: current config with requested profile selected Raises: SystemExit: 1 if ``profile`` or ``profile_id`` is no valid profile 2 if ``check`` is ``True`` and config is not configured """ cfg = config.Config(config_path=args.config, data_path=args.share_path) logger.debug('config file: "{}"; share path: "{}"; profiles: "{}"'.format( cfg._LOCAL_CONFIG_PATH, cfg._LOCAL_DATA_FOLDER, ', '.join(f'{profile_id}={cfg.profileName(profile_id)}' for profile_id in cfg.profiles()) )) if 'profile_id' in args and args.profile_id: if not cfg.setCurrentProfile(args.profile_id): logger.error('Profile-ID not found: %s' % args.profile_id) sys.exit(RETURN_ERR) if 'profile' in args and args.profile: if not cfg.setCurrentProfileByName(args.profile): logger.error('Profile not found: %s' % args.profile) sys.exit(RETURN_ERR) if check and not cfg.isConfigured(): logger.error('%(app)s is not configured!' % {'app': cfg.APP_NAME}) sys.exit(RETURN_NO_CFG) if 'checksum' in args: cfg.forceUseChecksum = args.checksum return cfg def setQuiet(args): """ Redirect :py:data:`sys.stdout` to ``/dev/null`` if ``--quiet`` was set on commandline. Return the original :py:data:`sys.stdout` file object which can be used to print absolute necessary information. Args: args (argparse.Namespace): previously parsed arguments Returns: sys.stdout: default sys.stdout """ force_stdout = sys.stdout if args.quiet: # do not replace with subprocess.DEVNULL - will not work sys.stdout = open(os.devnull, 'w') atexit.register(sys.stdout.close) atexit.register(force_stdout.close) return force_stdout class printLicense(argparse.Action): """ Print custom license """ def __init__(self, *args, **kwargs): super(printLicense, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): license_path = pathlib.Path(tools.docPath()) / 'LICENSE' print(license_path.read_text('utf-8')) sys.exit(RETURN_OK) class printDiagnostics(argparse.Action): """ Print information that is helpful for the support team to narrow down problems and bugs. The info is printed using the machine- and human-readable JSON format """ def __init__(self, *args, **kwargs): super(printDiagnostics, self).__init__(*args, **kwargs) def __call__(self, *args, **kwargs): diagnostics = collect_diagnostics() print(json.dumps(diagnostics, indent=4)) sys.exit(RETURN_OK) def backup(args, force=True): """ Command for force taking a new snapshot. Args: args (argparse.Namespace): previously parsed arguments force (bool): take the snapshot even if it wouldn't need to or would be prevented (e.g. running on battery) Raises: SystemExit: 0 if successful, 1 if not """ setQuiet(args) printHeader() cfg = getConfig(args) ret = takeSnapshot(cfg, force) sys.exit(int(ret)) def backupJob(args): """ Command for taking a new snapshot in background. Mainly used for cronjobs. This will run the snapshot inside a daemon and detach from it. It will return immediately back to commandline. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ cli.BackupJobDaemon(backup, args).start() def shutdown(args): """ Command for shutting down the computer after the current snapshot has finished. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 if successful; 1 if it failed either because there is no active snapshot for this profile or shutdown is not supported. """ setQuiet(args) printHeader() cfg = getConfig(args) sd = tools.ShutDown() if not sd.canShutdown(): logger.warning('Shutdown is not supported.') sys.exit(RETURN_ERR) instance = ApplicationInstance(cfg.takeSnapshotInstanceFile(), False) profile = '='.join((cfg.currentProfile(), cfg.profileName())) if not instance.busy(): logger.info('There is no active snapshot for profile %s. Skip shutdown.' %profile) sys.exit(RETURN_ERR) print('Shutdown is waiting for the snapshot in profile %s to end.\nPress CTRL+C to interrupt shutdown.\n' %profile) sd.activate_shutdown = True try: while instance.busy(): logger.debug('Snapshot is still active. Wait for shutdown.') sleep(5) except KeyboardInterrupt: print('Shutdown interrupted.') else: logger.info('Shutdown now.') sd.shutdown() sys.exit(RETURN_OK) def snapshotsPath(args): """ Command for printing the full snapshot path of current profile. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) if args.keep_mount: _mount(cfg) if args.quiet: msg = '{}' else: msg = 'SnapshotsPath: {}' print(msg.format(cfg.snapshotsFullPath()), file=force_stdout) sys.exit(RETURN_OK) def snapshotsList(args): """ Command for printing a list of all snapshots in current profile. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) _mount(cfg) if args.quiet: msg = '{}' else: msg = 'SnapshotID: {}' no_sids = True #use snapshots.listSnapshots instead of iterSnapshots because of sorting for sid in snapshots.listSnapshots(cfg, reverse = False): print(msg.format(sid), file=force_stdout) no_sids = False if no_sids: logger.error("There are no snapshots in '%s'" % cfg.profileName()) if not args.keep_mount: _umount(cfg) sys.exit(RETURN_OK) def snapshotsListPath(args): """ Command for printing a list of all snapshots paths in current profile. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) _mount(cfg) if args.quiet: msg = '{}' else: msg = 'SnapshotPath: {}' no_sids = True #use snapshots.listSnapshots instead of iterSnapshots because of sorting for sid in snapshots.listSnapshots(cfg, reverse = False): print(msg.format(sid.path()), file=force_stdout) no_sids = False if no_sids: logger.error("There are no snapshots in '%s'" % cfg.profileName()) if not args.keep_mount: _umount(cfg) sys.exit(RETURN_OK) def lastSnapshot(args): """ Command for printing the very last snapshot in current profile. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) _mount(cfg) sid = snapshots.lastSnapshot(cfg) if sid: if args.quiet: msg = '{}' else: msg = 'SnapshotID: {}' print(msg.format(sid), file=force_stdout) else: logger.error("There are no snapshots in '%s'" % cfg.profileName()) _umount(cfg) sys.exit(RETURN_OK) def lastSnapshotPath(args): """ Command for printing the path of the very last snapshot in current profile. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) _mount(cfg) sid = snapshots.lastSnapshot(cfg) if sid: if args.quiet: msg = '{}' else: msg = 'SnapshotPath: {}' print(msg.format(sid.path()), file=force_stdout) else: logger.error("There are no snapshots in '%s'" % cfg.profileName()) if not args.keep_mount: _umount(cfg) sys.exit(RETURN_OK) def unmount(args): """ Command for unmounting all filesystems. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ setQuiet(args) cfg = getConfig(args) _mount(cfg) _umount(cfg) sys.exit(RETURN_OK) def benchmarkCipher(args): """ Command for transferring a file with scp to remote host with all available ciphers and print its speed and time. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ setQuiet(args) printHeader() cfg = getConfig(args) if cfg.snapshotsMode() in ('ssh', 'ssh_encfs'): ssh = sshtools.SSH(cfg) ssh.benchmarkCipher(args.FILE_SIZE) sys.exit(RETURN_OK) else: logger.error("SSH is not configured for profile '%s'!" % cfg.profileName()) sys.exit(RETURN_ERR) def pwCache(args): """ Command for starting password cache daemon. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 if daemon is running, 1 if not """ force_stdout = setQuiet(args) printHeader() cfg = getConfig(args) ret = RETURN_OK daemon = password.Password_Cache(cfg) if args.ACTION and args.ACTION != 'status': getattr(daemon, args.ACTION)() elif args.ACTION == 'status': print('%(app)s Password Cache: ' % {'app': cfg.APP_NAME}, end=' ', file=force_stdout) if daemon.status(): print(cli.bcolors.OKGREEN + 'running' + cli.bcolors.ENDC, file=force_stdout) ret = RETURN_OK else: print(cli.bcolors.FAIL + 'not running' + cli.bcolors.ENDC, file=force_stdout) ret = RETURN_ERR else: daemon.run() sys.exit(ret) def decode(args): """ Command for decoding paths given paths with 'encfsctl'. Will listen on stdin if no path was given. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ force_stdout = setQuiet(args) cfg = getConfig(args) if cfg.snapshotsMode() not in ('local_encfs', 'ssh_encfs'): logger.error("Profile '%s' is not encrypted." % cfg.profileName()) sys.exit(RETURN_ERR) _mount(cfg) d = encfstools.Decode(cfg) if not args.PATH: while True: try: path = input() except EOFError: break if not path: break print(d.path(path), file=force_stdout) else: print('\n'.join(d.list(args.PATH)), file=force_stdout) d.close() _umount(cfg) sys.exit(RETURN_OK) def remove(args, force=False): """ Command for removing snapshots. Args: args (argparse.Namespace): previously parsed arguments force (bool): don't ask before removing (BE CAREFUL!) Raises: SystemExit: 0 """ setQuiet(args) printHeader() cfg = getConfig(args) _mount(cfg) cli.remove(cfg, args.SNAPSHOT_ID, force) _umount(cfg) sys.exit(RETURN_OK) def removeAndDoNotAskAgain(args): """ Command for removing snapshots without asking before remove (BE CAREFUL!) Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ remove(args, True) def smartRemove(args): """ Command for running Smart-Removal from Terminal. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 if okay 2 if Smart-Removal is not configured """ setQuiet(args) printHeader() cfg = getConfig(args) sn = snapshots.Snapshots(cfg) enabled, keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month = cfg.smartRemove() if enabled: _mount(cfg) del_snapshots = sn.smartRemoveList(datetime.today(), keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month) logger.info('Smart Removal will remove {} snapshots'.format(len(del_snapshots))) sn.smartRemove(del_snapshots, log = logger.info) _umount(cfg) sys.exit(RETURN_OK) else: logger.error('Smart Removal is not configured.') sys.exit(RETURN_NO_CFG) def restore(args): """ Command for restoring files from snapshots. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 """ setQuiet(args) printHeader() cfg = getConfig(args) _mount(cfg) if cfg.backupOnRestore() and not args.no_local_backup: backup = True else: backup = args.local_backup cli.restore(cfg, args.SNAPSHOT_ID, args.WHAT, args.WHERE, delete=args.delete, backup=backup, only_new=args.only_new) _umount(cfg) sys.exit(RETURN_OK) def checkConfig(args): """ Command for checking the config file. Args: args (argparse.Namespace): previously parsed arguments Raises: SystemExit: 0 if config is okay, 1 if not """ force_stdout = setQuiet(args) printHeader() cfg = getConfig(args) if cli.checkConfig(cfg, crontab=not args.no_crontab): print("\nConfig %(cfg)s profile '%(profile)s' is fine." % {'cfg': cfg._LOCAL_CONFIG_PATH, 'profile': cfg.profileName()}, file=force_stdout) sys.exit(RETURN_OK) else: print("\nConfig %(cfg)s profile '%(profile)s' has errors." % {'cfg': cfg._LOCAL_CONFIG_PATH, 'profile': cfg.profileName()}, file=force_stdout) sys.exit(RETURN_ERR) if __name__ == '__main__': startApp() backintime-1.5.4/common/bash-completion/000077500000000000000000000000001477034762000202155ustar00rootroot00000000000000backintime-1.5.4/common/bash-completion/backintime000066400000000000000000000073511477034762000222540ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2015 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . # extract profile and config arguments _bit_extr_opts() { local c=0 last="" opts="" while [[ $c -le ${COMP_CWORD} ]]; do case "${last}" in --profile|--profile-id|--config) if [[ ${COMP_WORDS[$c]} != -* ]]; then opts="${opts} ${last} ${COMP_WORDS[$c]}" fi ;; esac last=${COMP_WORDS[$c]} c=$[$c+1] done echo "${opts}" } # return a list of all snapshots _bit_snapshots_list() { backintime$(_bit_extr_opts) --quiet snapshots-list | awk '{print $2}' } _backintime() { local cur prev actions opts pw_cache_commands local cur_action='' pos_action=0 c=0 COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts="--profile --profile-id --quiet --config --version --license \ --help --debug --checksum --no-crontab --keep-mount --delete \ --local-backup --no-local-backup --only-new --share-path \ --diagnostics" actions="backup backup-job snapshots-path snapshots-list \ snapshots-list-path last-snapshot last-snapshot-path unmount \ benchmark-cipher pw-cache decode remove restore check-config \ smart-remove shutdown" pw_cache_commands="start stop restart reload status" # extract the current action while [[ $c -le $[${COMP_CWORD} - 1] ]]; do case ${actions} in *"${COMP_WORDS[$c]}"*) cur_action="${COMP_WORDS[$c]}" pos_action=${c} break ;; esac c=$[${c}+1] done case "${cur_action}" in restore) if [[ ${cur} != -* ]]; then #which positional argument is $cur? case $[${COMP_CWORD}-${pos_action}] in #first arg is a filename 1) _filedir return 0 ;; #second arg is a dirname 2) _filedir -d return 0 ;; #third arg is snapshot-id 3) COMPREPLY=( $(compgen -W "$(_bit_snapshots_list)" -- ${cur}) ) return 0 ;; esac fi ;; remove|remove-and-do-not-ask-again) if [[ ${cur} != -* ]]; then #snapshot-ids COMPREPLY=( $(compgen -W "$(_bit_snapshots_list)" -- ${cur}) ) return 0 else #other args COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi ;; esac case "${prev}" in --config|decode|restore|--share-path) if [[ ${cur} != -* ]]; then _filedir return 0 fi ;; pw-cache) if [[ ${cur} != -* ]]; then COMPREPLY=( $(compgen -W "${pw_cache_commands}" -- ${cur}) ) return 0 fi ;; *) if [[ -z "${cur_action}" ]]; then opts="${opts} ${actions}" fi COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 ;; esac } complete -F _backintime backintime complete -F _backintime backintime-qt backintime-1.5.4/common/bcolors.py000066400000000000000000000014261477034762000171510ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2015-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import sys if sys.stdout.isatty(): HEADER = '\033[95m' # light magenta OKBLUE = '\033[94m' # light blue OKGREEN = '\033[92m' # light green WARNING = '\033[93m' # light yellow FAIL = '\033[91m' # light red CRITICAL = '\033[31m' # dark red ENDC = '\033[0m' BOLD = '\033[1m' UNDERLINE = '\033[4m' else: HEADER = '' OKBLUE = '' OKGREEN = '' WARNING = '' FAIL = '' CRITICAL = '' ENDC = '' BOLD = '' UNDERLINE = '' backintime-1.5.4/common/bitbase.py000066400000000000000000000025401477034762000171150ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Basic constants used in multiple modules.""" from enum import Enum from pathlib import Path # See issue #1734 and #1735 URL_ENCRYPT_TRANSITION = 'https://github.com/bit-team/backintime' \ '/blob/-/doc/ENCRYPT_TRANSITION.md' USER_MANUAL_ONLINE_URL = 'https://backintime.readthedocs.io' USER_MANUAL_LOCAL_PATH = Path('/') / 'usr' / 'share' / 'doc' / \ 'backintime-common' / 'manual' / 'index.html' USER_MANUAL_LOCAL_AVAILABLE = USER_MANUAL_LOCAL_PATH.exists() # About transition of encryption feature and the removal of EncFS (see #1734). # The warnings and deprecation messages are gradually increased in intensity # and clarity. This constant is the currently desired stage of intensity. The # last shown intensity is stored in the state data file. If they don't fit, the # message is displayed. ENCFS_MSG_STAGE = 2 class TimeUnit(Enum): """Describe time units used in context of scheduling. """ HOUR = 10 # Config.HOUR DAY = 20 # Config.DAY WEEK = 30 # Config.WEEK MONTH = 40 # Config.MONTH backintime-1.5.4/common/cli.py000066400000000000000000000151631477034762000162600ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import os import sys import tools import daemon import snapshots import bcolors def restore(cfg, snapshot_id = None, what = None, where = None, **kwargs): if what is None: what = input('File to restore: ') what = tools.preparePath(os.path.abspath(os.path.expanduser(what))) if where is None: where = input('Restore to (empty for original path): ') if where: where = tools.preparePath(os.path.abspath(os.path.expanduser(where))) snapshotsList = snapshots.listSnapshots(cfg) sid = selectSnapshot(snapshotsList, cfg, snapshot_id, 'SnapshotID to restore') print('') RestoreDialog(cfg, sid, what, where, **kwargs).run() def remove(cfg, snapshot_ids = None, force = None): snapshotsList = snapshots.listSnapshots(cfg) if not snapshot_ids: snapshot_ids = (None,) sids = [selectSnapshot(snapshotsList, cfg, sid, 'SnapshotID to remove') for sid in snapshot_ids] if not force: print('Do you really want to remove these snapshots?') [print(sid.displayName) for sid in sids] if not 'yes' == input('(no/yes): '): return s = snapshots.Snapshots(cfg) [s.remove(sid) for sid in sids] def checkConfig(cfg, crontab = True): import mount from exceptions import MountException def announceTest(): print() print(frame(test)) def failed(): print(test + ': ' + bcolors.FAIL + 'failed' + bcolors.ENDC) def okay(): print(test + ': ' + bcolors.OKGREEN + 'done' + bcolors.ENDC) def errorHandler(msg): print(bcolors.WARNING + 'WARNING: ' + bcolors.ENDC + msg) cfg.setErrorHandler(errorHandler) mode = cfg.snapshotsMode() if cfg.SNAPSHOT_MODES[mode][0] is not None: # preMountCheck test = 'Run mount tests' announceTest() mnt = mount.Mount(cfg = cfg, tmp_mount = True) try: mnt.preMountCheck(mode = mode, first_run = True) except MountException as ex: failed() print(str(ex)) return False okay() # okay, let's try to mount test = 'Mount' announceTest() try: hash_id = mnt.mount(mode=mode, check=False) except MountException as ex: failed() print(str(ex)) return False okay() test = 'Check/prepare snapshot path' announceTest() snapshots_mountpoint = cfg.get_snapshots_mountpoint(tmp_mount=True) ret = tools.validate_and_prepare_snapshots_path( path=snapshots_mountpoint, host_user_profile=cfg.hostUserProfile(), mode=mode, copy_links=cfg.copyLinks(), error_handler=cfg.notifyError) if not ret: failed() return False okay() # umount if not cfg.SNAPSHOT_MODES[mode][0] is None: test = 'Unmount' announceTest() try: mnt.umount(hash_id=hash_id) except MountException as ex: failed() print(str(ex)) return False okay() test = 'Check config' announceTest() if not cfg.checkConfig(): failed() return False okay() if crontab: test = 'Install crontab' announceTest() if not cfg.setupCron(): failed() return False okay() return True def selectSnapshot(snapshotsList, cfg, snapshot_id = None, msg = 'SnapshotID'): """ check if given snapshot is valid. If not print a list of all snapshots and ask to choose one """ len_snapshots = len(snapshotsList) if not snapshot_id is None: try: sid = snapshots.SID(snapshot_id, cfg) if sid in snapshotsList: return sid else: print('SnapshotID %s not found.' % snapshot_id) except ValueError: try: index = int(snapshot_id) return snapshotsList[index] except (ValueError, IndexError): print('Invalid SnaphotID index: %s' % snapshot_id) snapshot_id = None columns = (terminalSize()[1] - 25) // 26 + 1 rows = len_snapshots // columns if len_snapshots % columns > 0: rows += 1 print('SnapshotID\'s:') for row in range(rows): line = [] for column in range(columns): index = row + column * rows if index > len_snapshots - 1: continue line.append('{i:>4}: {s}'.format(i = index, s = snapshotsList[index])) print(' '.join(line)) print('') while snapshot_id is None: try: index = int(input(msg + ' (0 - %d): ' % (len_snapshots - 1))) snapshot_id = snapshotsList[index] except (ValueError, IndexError): print('Invalid Input') continue return snapshot_id def terminalSize(): """ get terminal size """ for fd in (sys.stdin, sys.stdout, sys.stderr): try: import fcntl import termios import struct return [int(x) for x in struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))] except ImportError: pass return [24, 80] def frame(msg, size = 32): ret = ' +' + '-' * size + '+\n' ret += ' |' + msg.center(size) + '|\n' ret += ' +' + '-' * size + '+' return ret class RestoreDialog: def __init__(self, cfg, sid, what, where, **kwargs): self.config = cfg self.sid = sid self.what = what self.where = where self.kwargs = kwargs self.logFile = self.config.restoreLogFile() if os.path.exists(self.logFile): os.remove(self.logFile) def callback(self, line, *params): if not line: return print(line) with open(self.logFile, 'a') as log: log.write(line + '\n') def run(self): s = snapshots.Snapshots(self.config) s.restore(self.sid, self.what, self.callback, self.where, **self.kwargs) print('\nLog saved to %s' % self.logFile) class BackupJobDaemon(daemon.Daemon): def __init__(self, func, args): super(BackupJobDaemon, self).__init__() self.func = func self.args = args def run(self): self.func(self.args, False) backintime-1.5.4/common/config-example-local000066400000000000000000000045051477034762000210460ustar00rootroot00000000000000profile1.snapshots.automatic_backup_day=1 profile1.snapshots.automatic_backup_mode=0 profile1.snapshots.automatic_backup_time=0 profile1.snapshots.automatic_backup_weekday=7 profile1.snapshots.backup_on_restore.enabled=true profile1.snapshots.bwlimit.enabled=false profile1.snapshots.bwlimit.value=3000 profile1.snapshots.continue_on_errors=true profile1.snapshots.copy_links=false profile1.snapshots.copy_unsafe_links=false profile1.snapshots.cron.ionice=true profile1.snapshots.cron.nice=true profile1.snapshots.custom_backup_time=8,12,18,23 profile1.snapshots.dont_remove_named_snapshots=true profile1.snapshots.exclude.1.value=.gvfs profile1.snapshots.exclude.10.value=/proc/* profile1.snapshots.exclude.11.value=/sys/* profile1.snapshots.exclude.12.value=/dev/* profile1.snapshots.exclude.13.value=/run/* profile1.snapshots.exclude.2.value=.cache* profile1.snapshots.exclude.3.value=[Cc]ache* profile1.snapshots.exclude.4.value=.thumbnails* profile1.snapshots.exclude.5.value=[Tt]rash* profile1.snapshots.exclude.6.value=*.backup* profile1.snapshots.exclude.7.value=*~ profile1.snapshots.exclude.8.value=/home/USER/Ubuntu One profile1.snapshots.exclude.9.value=.dropbox* profile1.snapshots.exclude.size=13 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=/home/USER profile1.snapshots.include.size=1 profile1.snapshots.local_encfs.path= profile1.snapshots.log_level=3 profile1.snapshots.min_free_space.enabled=true profile1.snapshots.min_free_space.unit=20 profile1.snapshots.min_free_space.value=1 profile1.snapshots.mode=local profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=/mnt/backup profile1.snapshots.path.auto=true profile1.snapshots.path.host=HOST profile1.snapshots.path.profile=1 profile1.snapshots.path.user=USER profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.smart_remove=false profile1.snapshots.smart_remove.keep_all=2 profile1.snapshots.smart_remove.keep_one_per_day=7 profile1.snapshots.smart_remove.keep_one_per_month=24 profile1.snapshots.smart_remove.keep_one_per_week=4 profile1.snapshots.use_checksum=false profile1.snapshots.user_backup.ionice=false profiles.version=1 backintime-1.5.4/common/config-example-ssh000066400000000000000000000051741477034762000205540ustar00rootroot00000000000000profile1.snapshots.automatic_backup_day=1 profile1.snapshots.automatic_backup_mode=0 profile1.snapshots.automatic_backup_time=0 profile1.snapshots.automatic_backup_weekday=7 profile1.snapshots.backup_on_restore.enabled=true profile1.snapshots.bwlimit.enabled=false profile1.snapshots.bwlimit.value=3000 profile1.snapshots.continue_on_errors=true profile1.snapshots.copy_links=false profile1.snapshots.copy_unsafe_links=false profile1.snapshots.cron.ionice=true profile1.snapshots.cron.nice=true profile1.snapshots.custom_backup_time=8,12,18,23 profile1.snapshots.dont_remove_named_snapshots=true profile1.snapshots.exclude.1.value=.gvfs profile1.snapshots.exclude.10.value=/proc/* profile1.snapshots.exclude.11.value=/sys/* profile1.snapshots.exclude.12.value=/dev/* profile1.snapshots.exclude.13.value=/run/* profile1.snapshots.exclude.2.value=.cache* profile1.snapshots.exclude.3.value=[Cc]ache* profile1.snapshots.exclude.4.value=.thumbnails* profile1.snapshots.exclude.5.value=[Tt]rash* profile1.snapshots.exclude.6.value=*.backup* profile1.snapshots.exclude.7.value=*~ profile1.snapshots.exclude.8.value=/home/USER/Ubuntu One profile1.snapshots.exclude.9.value=.dropbox* profile1.snapshots.exclude.size=13 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=/home/USER profile1.snapshots.include.size=1 profile1.snapshots.local_encfs.path= profile1.snapshots.log_level=3 profile1.snapshots.min_free_space.enabled=true profile1.snapshots.min_free_space.unit=20 profile1.snapshots.min_free_space.value=1 profile1.snapshots.mode=ssh profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path= profile1.snapshots.path.auto=true profile1.snapshots.path.host=HOST profile1.snapshots.path.profile=1 profile1.snapshots.path.user=USER profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.smart_remove=false profile1.snapshots.smart_remove.keep_all=2 profile1.snapshots.smart_remove.keep_one_per_day=7 profile1.snapshots.smart_remove.keep_one_per_month=24 profile1.snapshots.smart_remove.keep_one_per_week=4 profile1.snapshots.ssh.cipher=default profile1.snapshots.ssh.host=REMOTE_HOST profile1.snapshots.ssh.password.save=false profile1.snapshots.ssh.password.use_cache=true profile1.snapshots.ssh.path= profile1.snapshots.ssh.port=22 profile1.snapshots.ssh.private_key_file=/home/USER/.ssh/id_dsa profile1.snapshots.ssh.user=USER profile1.snapshots.use_checksum=false profile1.snapshots.user_backup.ionice=false profiles.version=1 backintime-1.5.4/common/config.py000066400000000000000000002114051477034762000167530ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Configuration handling and logic. This module and its `Config` class contain the application logic handling the configuration of Back In Time. The handling of the configuration file itself is separated in the module :py:mod:`configfile`. Development notes: Some of the methods have code comments starting with `#? ` instead of `# `. These special comments are used to generate the manpage `backintime-config`. The script `create-manpage-backintime-config.py` parses this module for that. """ import os import sys import datetime import socket import random import getpass import shlex # Workaround: Mostly relevant on TravisCI but not exclusively. # While unittesting and without regular invocation of BIT the GNU gettext # class-based API isn't setup yet. # The bigger problem with config.py is that it do use translatable strings. # Strings like this do not belong into a config file or its context. try: _('Warning') except NameError: _ = lambda val: val import tools import configfile import logger import sshtools import encfstools import password import pluginmanager import schedule from exceptions import PermissionDeniedByPolicy, \ InvalidChar, \ InvalidCmd, \ LimitExceeded class Config(configfile.ConfigFileWithProfiles): APP_NAME = 'Back In Time' COPYRIGHT = 'Copyright (C) 2008-2024 Oprea Dan, Bart de Koning, ' \ 'Richard Bailey, Germar Reitze, Christian Buhtz, ' \ 'Michael Büker, Jürgen Altfeld et al.' CONFIG_VERSION = 6 """Latest or highest possible version of Back in Time's config file.""" NONE = 0 AT_EVERY_BOOT = 1 _5_MIN = 2 _10_MIN = 4 _30_MIN = 7 HOUR = 10 _1_HOUR = 10 _2_HOURS = 12 _4_HOURS = 14 _6_HOURS = 16 _12_HOURS = 18 CUSTOM_HOUR = 19 DAY = 20 REPEATEDLY = 25 UDEV = 27 WEEK = 30 MONTH = 40 YEAR = 80 HOURLY_BACKUPS = (HOUR, _2_HOURS, _4_HOURS, _6_HOURS, _12_HOURS, CUSTOM_HOUR) DISK_UNIT_MB = 10 DISK_UNIT_GB = 20 # Used when new snapshot profile is created. DEFAULT_EXCLUDE = [ '.gvfs', '.cache/*', '.thumbnails*', '.local/share/[Tt]rash*', '*.backup*', '*~', '.dropbox*', '/proc/*', '/sys/*', '/dev/*', '/run/*', '/etc/mtab', '/var/cache/apt/archives/*.deb', 'lost+found/*', '/tmp/*', '/var/tmp/*', '/var/backups/*', '.Private', '/swapfile', # Discord files # See also: https://github.com/bit-team/backintime/issues/1555#issuecomment-1787230708 'SingletonLock', 'SingletonCookie', # Mozilla files # See also: https://github.com/bit-team/backintime/issues/1555#issuecomment-1787111063 'lock' ] DEFAULT_RUN_NICE_FROM_CRON = True DEFAULT_RUN_NICE_ON_REMOTE = False DEFAULT_RUN_IONICE_FROM_CRON = True DEFAULT_RUN_IONICE_FROM_USER = False DEFAULT_RUN_IONICE_ON_REMOTE = False DEFAULT_RUN_NOCACHE_ON_LOCAL = False DEFAULT_RUN_NOCACHE_ON_REMOTE = False DEFAULT_SSH_PREFIX = 'PATH=/opt/bin:/opt/sbin:\\$PATH' DEFAULT_REDIRECT_STDOUT_IN_CRON = True DEFAULT_REDIRECT_STDERR_IN_CRON = False DEFAULT_OFFSET = 0 ENCODE = encfstools.Bounce() PLUGIN_MANAGER = pluginmanager.PluginManager() def __init__(self, config_path=None, data_path=None): """Back In Time configuration (and much more then this). Args: config_path (str): Full path to the config file (default: `~/.config/backintime/config`). data_path (str): It is $XDG_DATA_HOME (default: `~/.local/share`). """ # Note: The main profiles name here is translated using the systems # current locale because the language code in the config file wasn't # read yet. configfile.ConfigFileWithProfiles.__init__(self, _('Main profile')) self._GLOBAL_CONFIG_PATH = '/etc/backintime/config' HOME_FOLDER = os.path.expanduser('~') DATA_FOLDER = '.local/share' CONFIG_FOLDER = '.config' BIT_FOLDER = 'backintime' self._DEFAULT_LOCAL_DATA_FOLDER = os.path.join(HOME_FOLDER, DATA_FOLDER, BIT_FOLDER) self._LOCAL_CONFIG_FOLDER = os.path.join(HOME_FOLDER, CONFIG_FOLDER, BIT_FOLDER) self._MOUNT_ROOT = os.path.join(DATA_FOLDER, BIT_FOLDER, 'mnt') if data_path: self.DATA_FOLDER_ROOT = data_path self._LOCAL_DATA_FOLDER = os.path.join(data_path, DATA_FOLDER, BIT_FOLDER) self._LOCAL_MOUNT_ROOT = os.path.join(data_path, self._MOUNT_ROOT) else: self.DATA_FOLDER_ROOT = HOME_FOLDER self._LOCAL_DATA_FOLDER = self._DEFAULT_LOCAL_DATA_FOLDER self._LOCAL_MOUNT_ROOT = os.path.join(HOME_FOLDER, self._MOUNT_ROOT) tools.makeDirs(self._LOCAL_CONFIG_FOLDER) tools.makeDirs(self._LOCAL_DATA_FOLDER) tools.makeDirs(self._LOCAL_MOUNT_ROOT) self._DEFAULT_CONFIG_PATH = os.path.join(self._LOCAL_CONFIG_FOLDER, 'config') if config_path is None: self._LOCAL_CONFIG_PATH = self._DEFAULT_CONFIG_PATH else: self._LOCAL_CONFIG_PATH = os.path.abspath(config_path) self._LOCAL_CONFIG_FOLDER = os.path.dirname(self._LOCAL_CONFIG_PATH) # Load global config file self.load(self._GLOBAL_CONFIG_PATH) # Append local config file self.append(self._LOCAL_CONFIG_PATH) # Get the version of the config file # or assume the highest config version if it isn't set. currentConfigVersion \ = self.intValue('config.version', self.CONFIG_VERSION) if currentConfigVersion < self.CONFIG_VERSION: if currentConfigVersion < 5: logger.error( 'The config file version is 4 or lower. This config was ' 'made with a version of Back In Time that is out dated. ' 'Because of that upgrading config to the current version ' 'is not possible. The latest Back In Time version ' 'supporting upgrade the config file was v1.5.2.', self) sys.exit(2) if currentConfigVersion < 6: logger.info('Update to config version 6', self) # remap some keys for profile in self.profiles(): # make a 'schedule' domain for everything relating schedules self.remapProfileKey('snapshots.automatic_backup_anacron_period', 'schedule.repeatedly.period', profile) self.remapProfileKey('snapshots.automatic_backup_anacron_unit', 'schedule.repeatedly.unit', profile) self.remapProfileKey('snapshots.automatic_backup_day', 'schedule.day', profile) self.remapProfileKey('snapshots.automatic_backup_mode', 'schedule.mode', profile) self.remapProfileKey('snapshots.automatic_backup_time', 'schedule.time', profile) self.remapProfileKey('snapshots.automatic_backup_weekday', 'schedule.weekday', profile) self.remapProfileKey('snapshots.custom_backup_time', 'schedule.custom_time', profile) # we don't have 'full rsync mode' anymore self.remapProfileKey('snapshots.full_rsync.take_snapshot_regardless_of_changes', 'snapshots.take_snapshot_regardless_of_changes', profile) # remap 'qt4' keys self.remapKeyRegex(r'qt4', 'qt') # remove old gnome and kde keys self.removeKeysStartsWith('gnome') self.removeKeysStartsWith('kde') self.save() self.current_hash_id = 'local' self.pw = None self.forceUseChecksum = False self.xWindowId = None self.inhibitCookie = None self.setupUdev = tools.SetupUdev() language_used = tools.initiate_translation(self.language()) # Development note (2023-08 by buhtz): # Not the best location for a variable like this. self.language_used = language_used """ISO-639 language code of the used language. See `tools._determine_current_used_language_code()` for details.""" # Workaround self.default_profile_name = _('Main profile') # ToDo Those hidden labels exist to speed up their translation. # Unhide them after the upcoming release (1.5.0). # See: https://github.com/bit-team/backintime/issues/ # 1735#issuecomment-2197646518 _HIDDEN_NEW_MODE_LABELS = ( _('Local (EncFS encrypted)'), _('SSH (EncFS encrypted)') ) self.SNAPSHOT_MODES = { # mode: ( # , # 'ComboBox Text', # need_pw|lbl_pw_1, # need_2_pw|lbl_pw_2 # ), 'local': ( None, _('Local'), False, False), 'ssh': ( sshtools.SSH, _('SSH'), _('SSH private key'), False), 'local_encfs': ( encfstools.EncFS_mount, _('Local encrypted'), _('Encryption'), False ), 'ssh_encfs': ( encfstools.EncFS_SSH, _('SSH encrypted'), _('SSH private key'), _('Encryption') ) } self.SSH_CIPHERS = { 'default': _('Default'), 'aes128-ctr': 'AES128-CTR', 'aes192-ctr': 'AES192-CTR', 'aes256-ctr': 'AES256-CTR', 'arcfour256': 'ARCFOUR256', 'arcfour128': 'ARCFOUR128', 'aes128-cbc': 'AES128-CBC', '3des-cbc': '3DES-CBC', 'blowfish-cbc': 'Blowfish-CBC', 'cast128-cbc': 'Cast128-CBC', 'aes192-cbc': 'AES192-CBC', 'aes256-cbc': 'AES256-CBC', 'arcfour': 'ARCFOUR' } def save(self): self.setIntValue('config.version', self.CONFIG_VERSION) return super(Config, self).save(self._LOCAL_CONFIG_PATH) def checkConfig(self): profiles = self.profiles() for profile_id in profiles: profile_name = self.profileName(profile_id) snapshots_path = self.snapshotsPath(profile_id) logger.debug(f'Check profile {profile_name}', self) # check snapshots path if not snapshots_path: self.notifyError( '{}\n{}'.format( _('Profile: "{name}"').format(name=profile_name), _('Snapshots directory is not valid.') ) ) return False # check include include_list = self.include(profile_id) if not include_list: self.notifyError( '{}\n{}'.format( _('Profile: "{name}"').format(name=profile_name), _('At least one directory must be selected ' 'for backup.') ) ) return False snapshots_path2 = snapshots_path + '/' for item in include_list: if item[1] != 0: continue path = item[0] if path == snapshots_path: self.notifyError( '{}\n{}\n{}'.format( _('Profile: "{name}"').format(name=profile_name), _('Directory: {path}').format(path=path), _('This directory cannot be included in the ' 'backup as it is part of the backup ' 'destination itself.') ) ) return False if len(path) >= len(snapshots_path2): if path[: len(snapshots_path2)] == snapshots_path2: self.notifyError( '{}\n{}\n{}'.format( _('Profile: "{name}"').format( name=profile_name), _('Directory: {path}').format(path=path), _('This directory cannot be included in the ' 'backup as it is part of the backup ' 'destination itself.') ) ) return False return True def host(self): return socket.gethostname() def get_snapshots_mountpoint(self, profile_id=None, mode=None, tmp_mount=False): """Return the profiles snapshot path in form of a mount point.""" if profile_id is None: profile_id = self.currentProfile() if mode is None: mode = self.snapshotsMode(profile_id) if mode == 'local': return self.get_snapshots_path(profile_id) # else: ssh/local_encfs/ssh_encfs symlink = f'{profile_id}_{os.getpid()}' if tmp_mount: symlink = f'tmp_{symlink}' return os.path.join(self._LOCAL_MOUNT_ROOT, symlink) def snapshotsPath(self, profile_id=None, mode=None, tmp_mount=False): """Return the snapshot path (backup destination) as a mount point. That method is a surrogate for `self.get_snapshots_mountpoint()`. """ return self.get_snapshots_mountpoint( profile_id=profile_id, mode=mode, tmp_mount=tmp_mount) def snapshotsFullPath(self, profile_id = None): """ Returns the full path for the snapshots: .../backintime/machine/user/profile_id/ """ host, user, profile = self.hostUserProfile(profile_id) return os.path.join(self.snapshotsPath(profile_id), 'backintime', host, user, profile) def get_snapshots_path(self, profile_id): """Return the value of the snapshot path (backup destination) field.""" return self.profileStrValue('snapshots.path', '', profile_id) def set_snapshots_path(self, value, profile_id=None): """Sets the snapshot path to value.""" if profile_id is None: profile_id = self.currentProfile() self.setProfileStrValue('snapshots.path', value, profile_id) def snapshotsMode(self, profile_id=None): #? Use mode (or backend) for this snapshot. Look at 'man backintime' #? section 'Modes'.;local|local_encfs|ssh|ssh_encfs return self.profileStrValue('snapshots.mode', 'local', profile_id) def setSnapshotsMode(self, value, profile_id = None): self.setProfileStrValue('snapshots.mode', value, profile_id) def setCurrentHashId(self, hash_id): self.current_hash_id = hash_id def hashCollision(self): #?Internal value used to prevent hash collisions on mountpoints. Do not change this. return self.intValue('global.hash_collision', 0) def incrementHashCollision(self): value = self.hashCollision() + 1 self.setIntValue('global.hash_collision', value) def language(self) -> str: #?Language code (ISO 639) used to translate the user interface. #?If empty the operating systems current local is used. If 'en' the #?translation is not active and the original English source strings #?are used. It is the same if the value is unknown. return self.strValue('global.language', '') def setLanguage(self, language: str): self.setStrValue('global.language', language if language else '') # SSH def sshSnapshotsPath(self, profile_id = None): #?Snapshot path on remote host. If the path is relative (no leading '/') #?it will start from remote Users homedir. An empty path will be replaced #?with './'.;absolute or relative path return self.profileStrValue('snapshots.ssh.path', '', profile_id) def sshSnapshotsFullPath(self, profile_id = None): """ Returns the full path for the snapshots: .../backintime/machine/user/profile_id/ """ path = self.sshSnapshotsPath(profile_id) if not path: path = './' host, user, profile = self.hostUserProfile(profile_id) return os.path.join(path, 'backintime', host, user, profile) def setSshSnapshotsPath(self, value, profile_id = None): self.setProfileStrValue('snapshots.ssh.path', value, profile_id) return True def sshHost(self, profile_id = None): #?Remote host used for mode 'ssh' and 'ssh_encfs'.;IP or domain address return self.profileStrValue('snapshots.ssh.host', '', profile_id) def setSshHost(self, value, profile_id = None): self.setProfileStrValue('snapshots.ssh.host', value, profile_id) def sshPort(self, profile_id = None): #?SSH Port on remote host.;0-65535 return self.profileIntValue('snapshots.ssh.port', '22', profile_id) def setSshPort(self, value, profile_id = None): self.setProfileIntValue('snapshots.ssh.port', value, profile_id) def sshCipher(self, profile_id = None): #?Cipher that is used for encrypting the SSH tunnel. Depending on the #?environment (network bandwidth, cpu and hdd performance) a different #?cipher might be faster.;default | aes192-cbc | aes256-cbc | aes128-ctr | #? aes192-ctr | aes256-ctr | arcfour | arcfour256 | arcfour128 | aes128-cbc | #? 3des-cbc | blowfish-cbc | cast128-cbc return self.profileStrValue('snapshots.ssh.cipher', 'default', profile_id) def setSshCipher(self, value, profile_id = None): self.setProfileStrValue('snapshots.ssh.cipher', value, profile_id) def sshUser(self, profile_id = None): #?Remote SSH user;;local users name return self.profileStrValue('snapshots.ssh.user', getpass.getuser(), profile_id) def setSshUser(self, value, profile_id = None): self.setProfileStrValue('snapshots.ssh.user', value, profile_id) def sshHostUserPortPathCipher(self, profile_id = None): host = self.sshHost(profile_id) port = self.sshPort(profile_id) user = self.sshUser(profile_id) path = self.sshSnapshotsPath(profile_id) cipher = self.sshCipher(profile_id) if not path: path = './' return (host, port, user, path, cipher) def sshPrivateKeyFile(self, profile_id = None): ssh = self.sshPrivateKeyFolder() default = '' for f in ['id_dsa', 'id_rsa', 'identity']: private_key = os.path.join(ssh, f) if os.path.isfile(private_key): default = private_key break #?Private key file used for password-less authentication on remote host. #?;absolute path to private key file;~/.ssh/id_dsa f = self.profileStrValue('snapshots.ssh.private_key_file', default, profile_id) if f: return f return default def sshPrivateKeyFolder(self): return os.path.join(os.path.expanduser('~'), '.ssh') def setSshPrivateKeyFile(self, value, profile_id = None): self.setProfileStrValue('snapshots.ssh.private_key_file', value, profile_id) def sshProxyHost(self, profile_id=None): #?Proxy host used to connect to remote host.;;IP or domain address return self.profileStrValue('snapshots.ssh.proxy_host', '', profile_id) def setSshProxyHost(self, value, profile_id=None): self.setProfileStrValue('snapshots.ssh.proxy_host', value, profile_id) def sshProxyPort(self, profile_id=None): #?Proxy host port used to connect to remote host.;0-65535 return self.profileIntValue('snapshots.ssh.proxy_host_port', '22', profile_id) def setSshProxyPort(self, value, profile_id = None): self.setProfileIntValue('snapshots.ssh.proxy_host_port', value, profile_id) def sshProxyUser(self, profile_id=None): #?Remote SSH user;;the local users name return self.profileStrValue('snapshots.ssh.proxy_user', getpass.getuser(), profile_id) def setSshProxyUser(self, value, profile_id=None): self.setProfileStrValue('snapshots.ssh.proxy_user', value, profile_id) def sshMaxArgLength(self, profile_id = None): #?Maximum command length of commands run on remote host. This can be tested #?for all ssh profiles in the configuration #?with 'python3 /usr/share/backintime/common/ssh_max_arg.py LENGTH'.\n #?0 = unlimited;0, >700 value = self.profileIntValue('snapshots.ssh.max_arg_length', 0, profile_id) if value and value < 700: raise ValueError('SSH max arg length %s is too low to run commands' % value) return value def setSshMaxArgLength(self, value, profile_id = None): self.setProfileIntValue('snapshots.ssh.max_arg_length', value, profile_id) def sshCheckCommands(self, profile_id = None): #?Check if all commands (used during takeSnapshot) work like expected #?on the remote host. return self.profileBoolValue('snapshots.ssh.check_commands', True, profile_id) def setSshCheckCommands(self, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.check_commands', value, profile_id) def sshCheckPingHost(self, profile_id = None): #?Check if the remote host is available before trying to mount. return self.profileBoolValue('snapshots.ssh.check_ping', True, profile_id) def setSshCheckPingHost(self, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.check_ping', value, profile_id) def sshDefaultArgs(self, profile_id = None): """ Default arguments used for ``ssh`` and ``sshfs`` commands. Returns: list: arguments for ssh """ # keep connection alive args = ['-o', 'ServerAliveInterval=240'] # disable ssh banner args += ['-o', 'LogLevel=Error'] # specifying key file here allows to override for potentially # conflicting .ssh/config key entry args += ['-o', 'IdentityFile={}'.format(self.sshPrivateKeyFile(profile_id))] return args def sshCommand(self, cmd=None, custom_args=None, port=True, cipher=True, user_host=True, ionice=True, nice=True, quote=False, prefix=True, profile_id=None): """ Return SSH command with all arguments. Args: cmd (list): command that should run on remote host custom_args (list): additional arguments paste to the command port (bool): use port from config cipher (bool): use cipher from config user_host (bool): use user@host from config ionice (bool): use ionice if configured nice (bool): use nice if configured quote (bool): quote remote command prefix (bool): use prefix from config before remote command profile_id (str): profile ID that should be used in config Returns: list: ssh command with chosen arguments """ # Refactor: Use of assert is discouraged in productive code. # Raise Exceptions instead. assert cmd is None or isinstance(cmd, list), "cmd '{}' is not list instance".format(cmd) assert custom_args is None or isinstance(custom_args, list), "custom_args '{}' is not list instance".format(custom_args) ssh = ['ssh'] ssh += self.sshDefaultArgs(profile_id) # Proxy (aka Jump host) if self.sshProxyHost(profile_id): ssh += ['-J', '{}@{}:{}'.format( self.sshProxyUser(profile_id), self.sshProxyHost(profile_id), self.sshProxyPort(profile_id) )] # remote port if port: ssh += ['-p', str(self.sshPort(profile_id))] # cipher used to transfer data c = self.sshCipher(profile_id) if cipher and c != 'default': ssh += ['-o', f'Ciphers={c}'] # custom arguments if custom_args: ssh += custom_args # user@host if user_host: ssh.append('{}@{}'.format(self.sshUser(profile_id), self.sshHost(profile_id))) # quote the command running on remote host if quote and cmd: ssh.append("'") # run 'ionice' on remote host if ionice and self.ioniceOnRemote(profile_id) and cmd: ssh += ['ionice', '-c2', '-n7'] # run 'nice' on remote host if nice and self.niceOnRemote(profile_id) and cmd: ssh += ['nice', '-n19'] # run prefix on remote host if prefix and cmd and self.sshPrefixEnabled(profile_id): ssh += self.sshPrefixCmd(profile_id, cmd_type=type(cmd)) # add the command if cmd: ssh += cmd # close quote if quote and cmd: ssh.append("'") logger.debug(f'SSH command: {ssh}', self) return ssh # EncFS def localEncfsPath(self, profile_id = None): #?Where to save snapshots in mode 'local_encfs'.;absolute path return self.profileStrValue('snapshots.local_encfs.path', '', profile_id) def setLocalEncfsPath(self, value, profile_id = None): self.setProfileStrValue('snapshots.local_encfs.path', value, profile_id) def passwordSave(self, profile_id = None, mode = None): if mode is None: mode = self.snapshotsMode(profile_id) #?Save password to system keyring (gnome-keyring or kwallet). #? must be the same as \fIprofile.snapshots.mode\fR return self.profileBoolValue('snapshots.%s.password.save' % mode, False, profile_id) def setPasswordSave(self, value, profile_id = None, mode = None): if mode is None: mode = self.snapshotsMode(profile_id) self.setProfileBoolValue('snapshots.%s.password.save' % mode, value, profile_id) def passwordUseCache(self, profile_id = None, mode = None): if mode is None: mode = self.snapshotsMode(profile_id) #?Cache password in RAM so it can be read by cronjobs. #?Security issue: root might be able to read that password, too. #? must be the same as \fIprofile.snapshots.mode\fR;;true return self.profileBoolValue('snapshots.%s.password.use_cache' % mode, True, profile_id) def setPasswordUseCache(self, value, profile_id = None, mode = None): if mode is None: mode = self.snapshotsMode(profile_id) self.setProfileBoolValue('snapshots.%s.password.use_cache' % mode, value, profile_id) def password(self, parent=None, profile_id=None, mode=None, pw_id=1, only_from_keyring=False): if self.pw is None: self.pw = password.Password(self) if profile_id is None: profile_id = self.currentProfile() if mode is None: mode = self.snapshotsMode(profile_id) return self.pw.password( parent, profile_id, mode, pw_id, only_from_keyring) def setPassword(self, password, profile_id=None, mode=None, pw_id=1): if self.pw is None: self.pw = password.Password(self) if profile_id is None: profile_id = self.currentProfile() if mode is None: mode = self.snapshotsMode(profile_id) self.pw.setPassword(password, profile_id, mode, pw_id) def modeNeedPassword(self, mode, pw_id = 1): need_pw = self.SNAPSHOT_MODES[mode][pw_id + 1] if need_pw is False: return False return True def keyringServiceName(self, profile_id = None, mode = None, pw_id = 1): if mode is None: mode = self.snapshotsMode(profile_id) if pw_id > 1: return 'backintime/%s_%s' % (mode, pw_id) return 'backintime/%s' % mode def keyringUserName(self, profile_id = None): if profile_id is None: profile_id = self.currentProfile() return 'profile_id_%s' % profile_id def hostUserProfileDefault(self, profile_id=None): host = socket.gethostname() user = getpass.getuser() profile = profile_id if profile is None: profile = self.currentProfile() return (host, user, profile) def hostUserProfile(self, profile_id = None): default_host, default_user, default_profile = self.hostUserProfileDefault(profile_id) #?Set Host for snapshot path;;local hostname host = self.profileStrValue('snapshots.path.host', default_host, profile_id) #?Set User for snapshot path;;local username user = self.profileStrValue('snapshots.path.user', default_user, profile_id) #?Set Profile-ID for snapshot path;1-99999;current Profile-ID profile = self.profileStrValue('snapshots.path.profile', default_profile, profile_id) return (host, user, profile) def setHostUserProfile(self, host, user, profile, profile_id = None): self.setProfileStrValue('snapshots.path.host', host, profile_id) self.setProfileStrValue('snapshots.path.user', user, profile_id) self.setProfileStrValue('snapshots.path.profile', profile, profile_id) def include(self, profile_id=None): #?Include this file or folder. must be a counter starting with 1;absolute path:: #?Specify if \fIprofile.snapshots.include..value\fR is a folder (0) or a file (1).;0|1;0 return self.profileListValue(key='snapshots.include', type_key=('str:value', 'int:type'), default=[], profile_id=profile_id) def setInclude(self, values, profile_id = None): self.setProfileListValue('snapshots.include', ('str:value', 'int:type'), values, profile_id) def exclude(self, profile_id = None): """ Gets the exclude patterns """ #?Exclude this file or folder. must be a counter #?starting with 1;file, folder or pattern (relative or absolute) return self.profileListValue('snapshots.exclude', 'str:value', self.DEFAULT_EXCLUDE, profile_id) def setExclude(self, values, profile_id = None): self.setProfileListValue('snapshots.exclude', 'str:value', values, profile_id) def excludeBySizeEnabled(self, profile_id = None): #?Enable exclude files by size. return self.profileBoolValue('snapshots.exclude.bysize.enabled', False, profile_id) def excludeBySize(self, profile_id = None): #?Exclude files bigger than value in MiB. #?With 'Full rsync mode' disabled this will only affect new files #?because for rsync this is a transfer option, not an exclude option. #?So big files that has been backed up before will remain in snapshots #?even if they had changed. return self.profileIntValue('snapshots.exclude.bysize.value', 500, profile_id) def setExcludeBySize(self, enabled, value, profile_id = None): self.setProfileBoolValue('snapshots.exclude.bysize.enabled', enabled, profile_id) self.setProfileIntValue('snapshots.exclude.bysize.value', value, profile_id) def tag(self, profile_id = None): #?!ignore this in manpage return self.profileStrValue('snapshots.tag', str(random.randint(100, 999)), profile_id) def scheduleMode(self, profile_id = None): #?Which schedule used for crontab. The crontab entry will be #?generated with 'backintime check-config'.\n #? 0 = Disabled\n 1 = at every boot\n 2 = every 5 minute\n #? 4 = every 10 minute\n 7 = every 30 minute\n10 = every hour\n #?12 = every 2 hours\n14 = every 4 hours\n16 = every 6 hours\n #?18 = every 12 hours\n19 = custom defined hours\n20 = every day\n #?25 = daily anacron\n27 = when drive get connected\n30 = every week\n #?40 = every month\n80 = every year #?;0|1|2|4|7|10|12|14|16|18|19|20|25|27|30|40|80;0 return self.profileIntValue('schedule.mode', self.NONE, profile_id) def setScheduleMode(self, value, profile_id = None): self.setProfileIntValue('schedule.mode', value, profile_id) def schedule_offset(self, profile_id = None): return self.profileIntValue('schedule.offset', Config.DEFAULT_OFFSET, profile_id) def set_schedule_offset(self, value, profile_id = None): self.setProfileIntValue('schedule.offset', value, profile_id) def scheduleDebug(self, profile_id = None): #?Enable debug output to system log for schedule mode. return self.profileBoolValue('schedule.debug', False, profile_id) def setScheduleDebug(self, value, profile_id = None): self.setProfileBoolValue('schedule.debug', value, profile_id) def scheduleTime(self, profile_id = None): #?Position-coded number with the format "hhmm" to specify the hour #?and minute the cronjob should start (eg. 2015 means a quarter #?past 8pm). Leading zeros can be omitted (eg. 30 = 0030). #?Only valid for #?\fIprofile.schedule.mode\fR = 20 (daily), 30 (weekly), #?40 (monthly) and 80 (yearly);0-2400 return self.profileIntValue('schedule.time', 0, profile_id) def setScheduleTime(self, value, profile_id = None): self.setProfileIntValue('schedule.time', value, profile_id) def scheduleDay(self, profile_id = None): #?Which day of month the cronjob should run? Only valid for #?\fIprofile.schedule.mode\fR >= 40;1-28 return self.profileIntValue('schedule.day', 1, profile_id) def setScheduleDay(self, value, profile_id = None): self.setProfileIntValue('schedule.day', value, profile_id) def scheduleWeekday(self, profile_id = None): #?Which day of week the cronjob should run? Only valid for #?\fIprofile.schedule.mode\fR = 30;1 = monday \- 7 = sunday return self.profileIntValue('schedule.weekday', 7, profile_id) def setScheduleWeekday(self, value, profile_id = None): self.setProfileIntValue('schedule.weekday', value, profile_id) def customBackupTime(self, profile_id = None): #?Custom hours for cronjob. Only valid for #?\fIprofile.schedule.mode\fR = 19 #?;comma separated int (8,12,18,23) or */3;8,12,18,23 return self.profileStrValue('schedule.custom_time', '8,12,18,23', profile_id) def setCustomBackupTime(self, value, profile_id = None): self.setProfileStrValue('schedule.custom_time', value, profile_id) def scheduleRepeatedPeriod(self, profile_id = None): #?How many units to wait between new snapshots with anacron? Only valid #?for \fIprofile.schedule.mode\fR = 25|27 return self.profileIntValue('schedule.repeatedly.period', 1, profile_id) def setScheduleRepeatedPeriod(self, value, profile_id = None): self.setProfileIntValue('schedule.repeatedly.period', value, profile_id) def scheduleRepeatedUnit(self, profile_id = None): #?Units to wait between new snapshots with anacron.\n #?10 = hours\n20 = days\n30 = weeks\n40 = months\n #?Only valid for \fIprofile.schedule.mode\fR = 25|27; #?10|20|30|40;20 return self.profileIntValue('schedule.repeatedly.unit', self.DAY, profile_id) def setScheduleRepeatedUnit(self, value, profile_id = None): self.setProfileIntValue('schedule.repeatedly.unit', value, profile_id) def removeOldSnapshots(self, profile_id = None): #?Remove all snapshots older than value + unit return (self.profileBoolValue('snapshots.remove_old_snapshots.enabled', True, profile_id), #?Snapshots older than this times units will be removed self.profileIntValue('snapshots.remove_old_snapshots.value', 10, profile_id), #?20 = days\n30 = weeks\n80 = years;20|30|80;80 self.profileIntValue('snapshots.remove_old_snapshots.unit', self.YEAR, profile_id)) def keepOnlyOneSnapshot(self, profile_id = None): #?NOT YET IMPLEMENTED. Remove all snapshots but one. return self.profileBoolValue('snapshots.keep_only_one_snapshot.enabled', False, profile_id) def setKeepOnlyOneSnapshot(self, value, profile_id = None): self.setProfileBoolValue('snapshots.keep_only_one_snapshot.enabled', value, profile_id) def removeOldSnapshotsEnabled(self, profile_id = None): return self.profileBoolValue('snapshots.remove_old_snapshots.enabled', True, profile_id) def removeOldSnapshotsDate(self, profile_id=None): enabled, value, unit = self.removeOldSnapshots(profile_id) if not enabled: return datetime.date(1, 1, 1) return _remove_old_snapshots_date(value, unit) def setRemoveOldSnapshots(self, enabled, value, unit, profile_id = None): self.setProfileBoolValue('snapshots.remove_old_snapshots.enabled', enabled, profile_id) self.setProfileIntValue('snapshots.remove_old_snapshots.value', value, profile_id) self.setProfileIntValue('snapshots.remove_old_snapshots.unit', unit, profile_id) def minFreeSpace(self, profile_id = None): #?Remove snapshots until \fIprofile.snapshots.min_free_space.value\fR #?free space is reached. return (self.profileBoolValue('snapshots.min_free_space.enabled', True, profile_id), #?Keep at least value + unit free space.;1-99999 self.profileIntValue('snapshots.min_free_space.value', 1, profile_id), #?10 = MB\n20 = GB;10|20;20 self.profileIntValue('snapshots.min_free_space.unit', self.DISK_UNIT_GB, profile_id)) def minFreeSpaceEnabled(self, profile_id = None): return self.profileBoolValue('snapshots.min_free_space.enabled', False, profile_id) def minFreeSpaceMib(self, profile_id = None): enabled, value, unit = self.minFreeSpace(profile_id) if not enabled: return 0 if self.DISK_UNIT_MB == unit: return value value *= 1024 #Gb if self.DISK_UNIT_GB == unit: return value return 0 def setMinFreeSpace(self, enabled, value, unit, profile_id = None): self.setProfileBoolValue('snapshots.min_free_space.enabled', enabled, profile_id) self.setProfileIntValue('snapshots.min_free_space.value', value, profile_id) self.setProfileIntValue('snapshots.min_free_space.unit', unit, profile_id) def minFreeInodes(self, profile_id = None): #?Keep at least value % free inodes.;1-15 return self.profileIntValue('snapshots.min_free_inodes.value', 2, profile_id) def minFreeInodesEnabled(self, profile_id = None): #?Remove snapshots until \fIprofile.snapshots.min_free_inodes.value\fR #?free inodes in % is reached. return self.profileBoolValue('snapshots.min_free_inodes.enabled', False, profile_id) def setMinFreeInodes(self, enabled, value, profile_id = None): self.setProfileBoolValue('snapshots.min_free_inodes.enabled', enabled, profile_id) self.setProfileIntValue('snapshots.min_free_inodes.value', value, profile_id) def dontRemoveNamedSnapshots(self, profile_id = None): #?Keep snapshots with names during smart_remove. return self.profileBoolValue('snapshots.dont_remove_named_snapshots', True, profile_id) def setDontRemoveNamedSnapshots(self, value, profile_id = None): self.setProfileBoolValue('snapshots.dont_remove_named_snapshots', value, profile_id) def smartRemove(self, profile_id = None): #?Run smart_remove to clean up old snapshots after a new snapshot was created. return (self.profileBoolValue('snapshots.smart_remove', False, profile_id), #?Keep all snapshots for X days. self.profileIntValue('snapshots.smart_remove.keep_all', 2, profile_id), #?Keep one snapshot per day for X days. self.profileIntValue('snapshots.smart_remove.keep_one_per_day', 7, profile_id), #?Keep one snapshot per week for X weeks. self.profileIntValue('snapshots.smart_remove.keep_one_per_week', 4, profile_id), #?Keep one snapshot per month for X month. self.profileIntValue('snapshots.smart_remove.keep_one_per_month', 24, profile_id)) def setSmartRemove(self, value, keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month, profile_id = None): self.setProfileBoolValue('snapshots.smart_remove', value, profile_id) self.setProfileIntValue('snapshots.smart_remove.keep_all', keep_all, profile_id) self.setProfileIntValue('snapshots.smart_remove.keep_one_per_day', keep_one_per_day, profile_id) self.setProfileIntValue('snapshots.smart_remove.keep_one_per_week', keep_one_per_week, profile_id) self.setProfileIntValue('snapshots.smart_remove.keep_one_per_month', keep_one_per_month, profile_id) def smartRemoveRunRemoteInBackground(self, profile_id = None): #?If using mode SSH or SSH-encrypted, run smart_remove in background on remote machine return self.profileBoolValue('snapshots.smart_remove.run_remote_in_background', False, profile_id) def setSmartRemoveRunRemoteInBackground(self, value, profile_id = None): self.setProfileBoolValue('snapshots.smart_remove.run_remote_in_background', value, profile_id) def notify(self, profile_id = None): #?Display notifications (errors, warnings) through libnotify. return self.profileBoolValue('snapshots.notify.enabled', True, profile_id) def setNotify(self, value, profile_id = None): self.setProfileBoolValue('snapshots.notify.enabled', value, profile_id) def backupOnRestore(self, profile_id = None): #?Rename existing files before restore into FILE.backup.YYYYMMDD return self.profileBoolValue('snapshots.backup_on_restore.enabled', True, profile_id) def setBackupOnRestore(self, value, profile_id = None): self.setProfileBoolValue('snapshots.backup_on_restore.enabled', value, profile_id) def niceOnCron(self, profile_id = None): #?Run cronjobs with 'nice \-n19'. This will give BackInTime the #?lowest CPU priority to not interrupt any other working process. return self.profileBoolValue('snapshots.cron.nice', self.DEFAULT_RUN_NICE_FROM_CRON, profile_id) def setNiceOnCron(self, value, profile_id = None): self.setProfileBoolValue('snapshots.cron.nice', value, profile_id) def ioniceOnCron(self, profile_id = None): #?Run cronjobs with 'ionice \-c2 \-n7'. This will give BackInTime the #?lowest IO bandwidth priority to not interrupt any other working process. return self.profileBoolValue('snapshots.cron.ionice', self.DEFAULT_RUN_IONICE_FROM_CRON, profile_id) def setIoniceOnCron(self, value, profile_id = None): self.setProfileBoolValue('snapshots.cron.ionice', value, profile_id) def ioniceOnUser(self, profile_id = None): #?Run BackInTime with 'ionice \-c2 \-n7' when taking a manual snapshot. #?This will give BackInTime the lowest IO bandwidth priority to not #?interrupt any other working process. return self.profileBoolValue('snapshots.user_backup.ionice', self.DEFAULT_RUN_IONICE_FROM_USER, profile_id) def setIoniceOnUser(self, value, profile_id = None): self.setProfileBoolValue('snapshots.user_backup.ionice', value, profile_id) def niceOnRemote(self, profile_id = None): #?Run rsync and other commands on remote host with 'nice \-n19' return self.profileBoolValue('snapshots.ssh.nice', self.DEFAULT_RUN_NICE_ON_REMOTE, profile_id) def setNiceOnRemote(self, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.nice', value, profile_id) def ioniceOnRemote(self, profile_id = None): #?Run rsync and other commands on remote host with 'ionice \-c2 \-n7' return self.profileBoolValue('snapshots.ssh.ionice', self.DEFAULT_RUN_IONICE_ON_REMOTE, profile_id) def setIoniceOnRemote(self, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.ionice', value, profile_id) def nocacheOnLocal(self, profile_id = None): #?Run rsync on local machine with 'nocache'. #?This will prevent files from being cached in memory. return self.profileBoolValue('snapshots.local.nocache', self.DEFAULT_RUN_NOCACHE_ON_LOCAL, profile_id) def setNocacheOnLocal(self, value, profile_id = None): self.setProfileBoolValue('snapshots.local.nocache', value, profile_id) def nocacheOnRemote(self, profile_id = None): #?Run rsync on remote host with 'nocache'. #?This will prevent files from being cached in memory. return self.profileBoolValue('snapshots.ssh.nocache', self.DEFAULT_RUN_NOCACHE_ON_REMOTE, profile_id) def setNocacheOnRemote(self, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.nocache', value, profile_id) def redirectStdoutInCron(self, profile_id = None): #?redirect stdout to /dev/null in cronjobs return self.profileBoolValue('snapshots.cron.redirect_stdout', self.DEFAULT_REDIRECT_STDOUT_IN_CRON, profile_id) def redirectStderrInCron(self, profile_id = None): #?redirect stderr to /dev/null in cronjobs;;self.DEFAULT_REDIRECT_STDERR_IN_CRON if self.isConfigured(profile_id): default = True else: default = self.DEFAULT_REDIRECT_STDERR_IN_CRON return self.profileBoolValue('snapshots.cron.redirect_stderr', default, profile_id) def setRedirectStdoutInCron(self, value, profile_id = None): self.setProfileBoolValue('snapshots.cron.redirect_stdout', value, profile_id) def setRedirectStderrInCron(self, value, profile_id = None): self.setProfileBoolValue('snapshots.cron.redirect_stderr', value, profile_id) def bwlimitEnabled(self, profile_id = None): #?Limit rsync bandwidth usage over network. Use this with mode SSH. #?For mode Local you should rather use ionice. return self.profileBoolValue('snapshots.bwlimit.enabled', False, profile_id) def bwlimit(self, profile_id = None): #?Bandwidth limit in KB/sec. return self.profileIntValue('snapshots.bwlimit.value', 3000, profile_id) def setBwlimit(self, enabled, value, profile_id = None): self.setProfileBoolValue('snapshots.bwlimit.enabled', enabled, profile_id) self.setProfileIntValue('snapshots.bwlimit.value', value, profile_id) def noSnapshotOnBattery(self, profile_id = None): #?Don't take snapshots if the Computer runs on battery. return self.profileBoolValue('snapshots.no_on_battery', False, profile_id) def setNoSnapshotOnBattery(self, value, profile_id = None): self.setProfileBoolValue('snapshots.no_on_battery', value, profile_id) def preserveAcl(self, profile_id = None): #?Preserve ACL. The source and destination systems must have #?compatible ACL entries for this option to work properly. return self.profileBoolValue('snapshots.preserve_acl', False, profile_id) def setPreserveAcl(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.preserve_acl', value, profile_id) def preserveXattr(self, profile_id = None): #?Preserve extended attributes (xattr). return self.profileBoolValue('snapshots.preserve_xattr', False, profile_id) def setPreserveXattr(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.preserve_xattr', value, profile_id) def copyUnsafeLinks(self, profile_id = None): #?This tells rsync to copy the referent of symbolic links that point #?outside the copied tree. Absolute symlinks are also treated like #?ordinary files. return self.profileBoolValue('snapshots.copy_unsafe_links', False, profile_id) def setCopyUnsafeLinks(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.copy_unsafe_links', value, profile_id) def copyLinks(self, profile_id = None): #?When symlinks are encountered, the item that they point to #?(the reference) is copied, rather than the symlink. return self.profileBoolValue('snapshots.copy_links', False, profile_id) def setCopyLinks(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.copy_links', value, profile_id) def oneFileSystem(self, profile_id = None): #?Use rsync's "--one-file-system" to avoid crossing filesystem #?boundaries when recursing. return self.profileBoolValue('snapshots.one_file_system', False, profile_id) def setOneFileSystem(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.one_file_system', value, profile_id) def rsyncOptionsEnabled(self, profile_id = None): #?Past additional options to rsync return self.profileBoolValue('snapshots.rsync_options.enabled', False, profile_id) def rsyncOptions(self, profile_id = None): #?rsync options. Options must be quoted e.g. \-\-exclude-from="/path/to/my exclude file" return self.profileStrValue('snapshots.rsync_options.value', '', profile_id) def setRsyncOptions(self, enabled, value, profile_id = None): self.setProfileBoolValue('snapshots.rsync_options.enabled', enabled, profile_id) self.setProfileStrValue('snapshots.rsync_options.value', value, profile_id) def sshPrefixEnabled(self, profile_id = None): #?Add prefix to every command which run through SSH on remote host. return self.profileBoolValue('snapshots.ssh.prefix.enabled', False, profile_id) def sshPrefix(self, profile_id = None): #?Prefix to run before every command on remote host. Variables need to be escaped with \\$FOO. #?This doesn't touch rsync. So to add a prefix for rsync use #?\fIprofile.snapshots.rsync_options.value\fR with #?--rsync-path="FOO=bar:\\$FOO /usr/bin/rsync" return self.profileStrValue('snapshots.ssh.prefix.value', self.DEFAULT_SSH_PREFIX, profile_id) def setSshPrefix(self, enabled, value, profile_id = None): self.setProfileBoolValue('snapshots.ssh.prefix.enabled', enabled, profile_id) self.setProfileStrValue('snapshots.ssh.prefix.value', value, profile_id) def sshPrefixCmd(self, profile_id=None, cmd_type=str): """Return the config value of sshPrefix if enabled. Dev note by buhtz (2024-04): Good opportunity to refactor. To much implicit behavior in it. """ if cmd_type == list: if self.sshPrefixEnabled(profile_id): return shlex.split(self.sshPrefix(profile_id)) return [] if cmd_type == str: if self.sshPrefixEnabled(profile_id): return self.sshPrefix(profile_id).strip() + ' ' return '' raise TypeError(f'Unable to handle type {cmd_type}.') def continueOnErrors(self, profile_id = None): #?Continue on errors. This will keep incomplete snapshots rather than #?deleting and start over again. return self.profileBoolValue('snapshots.continue_on_errors', True, profile_id) def setContinueOnErrors(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.continue_on_errors', value, profile_id) def useChecksum(self, profile_id = None): #?Use checksum to detect changes rather than size + time. return self.profileBoolValue('snapshots.use_checksum', False, profile_id) def setUseChecksum(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.use_checksum', value, profile_id) def logLevel(self, profile_id = None): #?Log level used during takeSnapshot.\n1 = Error\n2 = Changes\n3 = Info;1-3 return self.profileIntValue('snapshots.log_level', 3, profile_id) def setLogLevel(self, value, profile_id = None): return self.setProfileIntValue('snapshots.log_level', value, profile_id) def takeSnapshotRegardlessOfChanges(self, profile_id = None): #?Create a new snapshot regardless if there were changes or not. return self.profileBoolValue('snapshots.take_snapshot_regardless_of_changes', False, profile_id) def setTakeSnapshotRegardlessOfChanges(self, value, profile_id = None): return self.setProfileBoolValue('snapshots.take_snapshot_regardless_of_changes', value, profile_id) def globalFlock(self): #?Prevent multiple snapshots (from different profiles or users) to be run at the same time return self.boolValue('global.use_flock', False) def setGlobalFlock(self, value): self.setBoolValue('global.use_flock', value) def appInstanceFile(self): return os.path.join(self._LOCAL_DATA_FOLDER, 'app.lock') def fileId(self, profile_id=None): if profile_id is None: profile_id = self.currentProfile() if profile_id == '1': return '' return profile_id def takeSnapshotLogFile(self, profile_id = None): return os.path.join(self._LOCAL_DATA_FOLDER, "takesnapshot_%s.log" % self.fileId(profile_id)) def takeSnapshotMessageFile(self, profile_id = None): return os.path.join(self._LOCAL_DATA_FOLDER, "worker%s.message" % self.fileId(profile_id)) def takeSnapshotProgressFile(self, profile_id = None): return os.path.join(self._LOCAL_DATA_FOLDER, "worker%s.progress" % self.fileId(profile_id)) def takeSnapshotInstanceFile(self, profile_id=None): return os.path.join( self._LOCAL_DATA_FOLDER, "worker%s.lock" % self.fileId(profile_id)) def takeSnapshotUserCallback(self): return os.path.join(self._LOCAL_CONFIG_FOLDER, "user-callback") def passwordCacheFolder(self): return os.path.join(self._LOCAL_DATA_FOLDER, "password_cache") def passwordCachePid(self): return os.path.join(self.passwordCacheFolder(), "PID") def passwordCacheFifo(self): return os.path.join(self.passwordCacheFolder(), "FIFO") def passwordCacheInfo(self): return os.path.join(self.passwordCacheFolder(), "info") def cronEnvFile(self): return os.path.join(self._LOCAL_DATA_FOLDER, "cron_env") def anacronSpool(self): # ~/.local/share/backintime/anacron return os.path.join(self._LOCAL_DATA_FOLDER, 'anacron') def anacronSpoolFile(self, profile_id=None): """Return the timestamp file related to the current profile. Despite the methods name anacron is not involved. But the anacron behavior is imitated by Back In Time. This timestamp files are an element of this behavior. """ # ~/.local/share/backintime/anacron/1_Main_profile return os.path.join(self.anacronSpool(), self.anacronJobIdentify(profile_id)) def anacronJobIdentify(self, profile_id=None): if not profile_id: profile_id = self.currentProfile() profile_name = self.profileName(profile_id) # "Main profile" -> "1_Main_profile" return profile_id + '_' + profile_name.replace(' ', '_') def udevRulesPath(self): return os.path.join('/etc/udev/rules.d', '99-backintime-%s.rules' % getpass.getuser()) def restoreLogFile(self, profile_id = None): return os.path.join(self._LOCAL_DATA_FOLDER, "restore_%s.log" % self.fileId(profile_id)) def restoreInstanceFile(self, profile_id=None): return os.path.join( self._LOCAL_DATA_FOLDER, "restore%s.lock" % self.fileId(profile_id)) def lastSnapshotSymlink(self, profile_id = None): return os.path.join(self.snapshotsFullPath(profile_id), 'last_snapshot') def encfsconfigBackupFolder(self, profile_id = None): return os.path.join(self._LOCAL_DATA_FOLDER, 'encfsconfig_backup_%s' % self.fileId(profile_id)) def preparePath(self, path): if len(path) > 1: if path[-1] == os.sep: path = path[: -1] return path def isConfigured(self, profile_id=None): """Checks if the program is configured. It is assumed as configured if a snapshot path (backup destination) is and include files/directories (backup source) are given. """ path = self.snapshotsPath(profile_id) includes = self.include(profile_id) if bool(path and includes): return True else: logger.debug(f'Profile ({profile_id=}) is not configured because ' f'snapshot path is "{bool(path)}" and/or includes ' f'are "{bool(includes)}".', self) return False def canBackup(self, profile_id=None): """Checks if snapshots_path exists. """ if not self.isConfigured(profile_id): return False path = self.snapshotsFullPath(profile_id) if not os.path.exists(path): logger.warning(f'Snapshot path does not exists: {path}', self) return False if not os.path.isdir(path): logger.warning(f'Snapshot path is not a directory: {path}', self) return False return True def backupScheduled(self, profile_id = None): """Check if the profile is supposed to be run this time. Returns: (bool): The answer. """ if self.scheduleMode(profile_id) not in (self.REPEATEDLY, self.UDEV): return True last_time = tools.readTimeStamp(self.anacronSpoolFile(profile_id)) if not last_time: return True return tools.older_than( dt=last_time, value=self.scheduleRepeatedPeriod(profile_id), unit=self.scheduleRepeatedUnit(profile_id) ) def setupCron(self): """Update the current users crontab file based on profile settings. The crontab files is read, all entries related to Back In Time are removed and after it added again for each profile based on the profile settings. The difference between a backintime related entry created by Back In Time itself or by the user manually is determined by a comment before each entry. See :data:`schedule._MARKER` and :func:`schedule.remove_bit_from_crontab()` for details. Returns: bool: ``True`` if successful or ``False`` on errors. """ self.setupUdev.clean() # Lines of current users crontab file org_crontab_lines = schedule.read_crontab() # Remove all auto-generated BIT entries from crontab crontab_lines = schedule.remove_bit_from_crontab(org_crontab_lines) # Add a new entry to existing crontab content based on the current # snapshot profile and its schedule settings. crontab_lines = schedule.append_bit_to_crontab( crontab_lines, self.profiles_cron_lines()) # Save Udev rules try: if self.setupUdev.isReady and self.setupUdev.save(): logger.debug('Udev rules added successfully', self) except PermissionDeniedByPolicy as err: logger.error(str(err), self) self.notifyError(str(err)) return False # Crontab modified? if crontab_lines == org_crontab_lines: return True if schedule.write_crontab(crontab_lines) == False: logger.error('Failed to write new crontab.') self.notifyError(_('Failed to write new crontab.')) return False if not schedule.is_cron_running(): logger.error( 'Cron is not running despite the crontab command being ' 'available. Scheduled backup jobs will not run.') self.notifyError(_( 'Cron is not running despite the crontab command being ' 'available. Scheduled backup jobs will not run. ' 'Cron might be installed but not enabled. Try the command ' '"systemctl enable cron" or consult the support channels of ' 'your GNU/Linux distribution.')) return True def profiles_cron_lines(self): """Return a list of crontab lines for each of the existing profiles. Return: list: The list of crontab lines. """ profile_ids = self.profiles() # For each profile: cronline and the command (backintime) cron_lines = [ self._cron_line(pid).replace('{cmd}', self._cron_cmd(pid)) for pid in profile_ids ] # Remove empty lines (profiles not scheduled) cron_lines = list(filter(None, cron_lines)) return cron_lines def _cron_line(self, profile_id): """Create a crontab line based on the snapshot profiles settings.""" cron_line = '' profile_name = self.profileName(profile_id) backup_mode = self.scheduleMode(profile_id) logger.debug( f"Profile: {profile_name} | Automatic backup: {backup_mode}", self) if self.NONE == backup_mode: return cron_line hour = self.scheduleTime(profile_id) // 100 minute = self.scheduleTime(profile_id) % 100 day = self.scheduleDay(profile_id) weekday = self.scheduleWeekday(profile_id) offset = str(self.schedule_offset(profile_id)) if self.AT_EVERY_BOOT == backup_mode: cron_line = '@reboot {cmd}' elif self._5_MIN == backup_mode: cron_line = '*/5 * * * * {cmd}' elif self._10_MIN == backup_mode: cron_line = '*/10 * * * * {cmd}' elif self._30_MIN == backup_mode: cron_line = '*/30 * * * * {cmd}' elif self._1_HOUR == backup_mode: cron_line = offset + ' * * * * {cmd}' elif self._2_HOURS == backup_mode: cron_line = offset + ' */2 * * * {cmd}' elif self._4_HOURS == backup_mode: cron_line = offset + ' */4 * * * {cmd}' elif self._6_HOURS == backup_mode: cron_line = offset + ' */6 * * * {cmd}' elif self._12_HOURS == backup_mode: cron_line = offset + ' */12 * * * {cmd}' elif self.CUSTOM_HOUR == backup_mode: cron_line = offset + ' ' + self.customBackupTime(profile_id) + ' * * * {cmd}' elif self.DAY == backup_mode: cron_line = '%s %s * * * {cmd}' % (minute, hour) elif self.REPEATEDLY == backup_mode: if self.scheduleRepeatedUnit(profile_id) <= self.DAY: cron_line = '*/15 * * * * {cmd}' else: cron_line = '0 * * * * {cmd}' elif self.UDEV == backup_mode: if not self.setupUdev.isReady: logger.error( "Failed to install Udev rule for profile %s. DBus " "Service 'net.launchpad.backintime.serviceHelper' not " "available" % profile_id, self) self.notifyError(_( "Could not install Udev rule for profile {profile_id}. " "DBus Service '{dbus_interface}' wasn't available") .format(profile_id=profile_id, dbus_interface='net.launchpad.backintime.' 'serviceHelper')) mode = self.snapshotsMode(profile_id) if mode == 'local': dest_path = self.snapshotsFullPath(profile_id) elif mode == 'local_encfs': dest_path = self.localEncfsPath(profile_id) else: logger.error( f"Udev scheduling doesn't work with mode {mode}", self) self.notifyError(_( "Udev schedule doesn't work with mode {mode}") .format(mode=mode)) return False uuid = tools.uuidFromPath(dest_path) if uuid is None: #try using cached uuid #?Devices uuid used to automatically set up udev rule if the drive is not connected. uuid = self.profileStrValue('snapshots.path.uuid', '', profile_id) if not uuid: logger.error( "Couldn't find UUID for \"{dest_path}\"", self) self.notifyError(_("Couldn't find UUID for {path}") .format(path=f'"{dest_path}"')) return False else: #cache uuid in config self.setProfileStrValue('snapshots.path.uuid', uuid, profile_id) try: self.setupUdev.addRule(self._cron_cmd(profile_id), uuid) except (InvalidChar, InvalidCmd, LimitExceeded) as e: logger.error(str(e), self) self.notifyError(str(e)) return False elif self.WEEK == backup_mode: cron_line = '%s %s * * %s {cmd}' %(minute, hour, weekday) elif self.MONTH == backup_mode: cron_line = '%s %s %s * * {cmd}' %(minute, hour, day) elif self.YEAR == backup_mode: cron_line = '%s %s 1 1 * {cmd}' %(minute, hour) return cron_line def _cron_cmd(self, profile_id): """Generates the command used in the crontab file based on the settings for the current profile. Returns: str: The crontab line. """ # Get full path of the Back In Time binary cmd = tools.which('backintime') + ' ' # The "--profile-id" argument is used only for profiles different from # first profile if profile_id != '1': cmd += '--profile-id %s ' % profile_id # User defined path to config file if not self._LOCAL_CONFIG_PATH is self._DEFAULT_CONFIG_PATH: cmd += '--config %s ' % self._LOCAL_CONFIG_PATH # Enable debug output if self.scheduleDebug(profile_id): cmd += '--debug ' # command cmd += 'backup-job' # Redirect stdout to nirvana if self.redirectStdoutInCron(profile_id): cmd += ' >/dev/null' # Redirect stderr ... if self.redirectStderrInCron(profile_id): if self.redirectStdoutInCron(profile_id): # ... to stdout cmd += ' 2>&1' else: # ... to nirvana cmd += ' 2>/dev/null' # IO priority: low (-n7) in "best effort" class (-c2) if self.ioniceOnCron(profile_id) and tools.checkCommand('ionice'): cmd = tools.which('ionice') + ' -c2 -n7 ' + cmd # CPU priority: very low if self.niceOnCron(profile_id) and tools.checkCommand('nice'): cmd = tools.which('nice') + ' -n19 ' + cmd return cmd def _remove_old_snapshots_date(value, unit): """Dev note (buhtz, 2025-01): The function exist to decople that code from Config class and make it testable to investigate its behavior. See issue #1943 for further reading. """ if unit == Config.DAY: date = datetime.date.today() date = date - datetime.timedelta(days=value) return date if unit == Config.WEEK: date = datetime.date.today() # Always beginning (Monday) of the week date = date - datetime.timedelta(days=date.weekday() + 7 * value) return date if unit == Config.YEAR: date = datetime.date.today() return date.replace(day=1, year=date.year - value) return datetime.date(1, 1, 1) backintime-1.5.4/common/configfile.py000066400000000000000000000602031477034762000176110ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import collections import re import logger class ConfigFile: """Store options in a plain text file in form of: key=value """ def __init__(self): self.dict = {} self.errorHandler = None self.questionHandler = None def setErrorHandler(self, handler): """ Register a function that should be called for notifying errors. handler (method): callable function """ self.errorHandler = handler def setQuestionHandler(self, handler): """ Register a function that should be called for asking questions. handler (method): callable function """ self.questionHandler = handler def clearHandlers(self): """ Reset error and question handlers. """ self.errorHandler = None self.questionHandler = None def notifyError(self, message): """ Call previously registered function to show an error. Args: message (str): error message that should be shown """ if self.errorHandler is None: return self.errorHandler(message) def askQuestion(self, message): """ Call previously registered function to ask a question. Args: message (str): question that should be shown """ if self.questionHandler is None: return False return self.questionHandler(message) def save(self, filename): """ Save all options to file. Args: filename (str): full path Returns: bool: ``True`` if successful """ def numsort(key): """ Sort int in keys in numeric order instead of alphabetical by adding leading zeros to int's """ return re.sub(r'\d+', lambda m: m.group(0).zfill(6), key) try: with open(filename, 'wt') as f: keys = list(self.dict.keys()) keys.sort(key=numsort) for key in keys: f.write("%s=%s\n" % (key, self.dict[key])) except OSError as e: logger.error('Failed to save config: %s' % str(e), self) self.notifyError( '{}: {}'.format(_('Failed to save config'), str(e))) return False return True def load(self, filename, **kwargs): """ Reset current options and load new options from file. Args: filename (str): full path """ self.dict = {} self.append(filename, **kwargs) def append(self, filename, maxsplit=1): """ Load options from file and append them to current options. Args: filename (str): full path maxsplit (int): split lines only n times on '=' """ lines = [] if not os.path.isfile(filename): return try: with open(filename, 'rt') as f: lines = f.readlines() except OSError as e: logger.error('Failed to load config: %s' % str(e), self) self.notifyError( '{}: {}'.format(_('Failed to load config'), str(e))) for line in lines: items = line.strip('\n').split('=', maxsplit) if len(items) == 2: self.dict[items[0]] = items[1] def remapKey(self, old_key, new_key): """ Remap keys to a new key name. Args: old_key (str): old key name new_key (str): new key name """ if old_key != new_key: if old_key in self.dict: if new_key not in self.dict: self.dict[new_key] = self.dict[old_key] del self.dict[old_key] def remapKeyRegex(self, pattern, replace): """ Remap keys to a new key name using :py:func:`re.sub`. Args: pattern (str): part of key name that should be replaced replace (:py:class:`str`, method): string or a callable function which will be used to replace all matches of ``pattern``. """ c = re.compile(pattern) for key in list(self.dict): newKey = c.sub(replace, key) if key != newKey: self.remapKey(key, newKey) def hasKey(self, key): """ ``True`` if key is set. Args: key (str): string used as key Returns: bool: ``True`` if the ``key`` is set """ return key in self.dict def strValue(self, key, default=''): """ Return a 'str' instance of key's value. Args: key (str): Key identifying the value in the config file. default (str): Default value if ``key`` is not present. Returns: str: Value of ``key`` or ``default``. """ if key in self.dict: return self.dict[key] else: return default def setStrValue(self, key, value): """ Set a string value for key. Args: key (str): string used as key value (str): store this value """ self.dict[key] = value def intValue(self, key, default=0): """ Return a 'int' instance of key's value. Args: key (str): string used as key default (int): return this if ``key`` is not set Returns: int: value of ``key`` or ``default`` if ``key`` is not set. """ try: return int(self.dict[key]) except Exception: return default def setIntValue(self, key, value): """ Set an integer value for key. Args: key (str): string used as key value (int): store this option """ self.setStrValue(key, str(value)) def boolValue(self, key, default=False): """ Return a 'bool' instance of key's value. Args: key (str): string used as key default (bool): return this if key is not set Returns: bool: value of 'key' or 'default' if 'key' is not set. """ try: val = self.dict[key] if "1" == val or "TRUE" == val.upper(): return True return False except Exception: return default def setBoolValue(self, key, value): """ Set a bool value for key. Args: key (str): string used as key value (bool): store this option """ if value: self.setStrValue(key, 'true') else: self.setStrValue(key, 'false') def listValue(self, key, type_key='str:value', default=[]): """ Return a list of values Size of the list must be stored in key.size Args: key (str): used base-key type_key (str): pattern of 'value-type:value-name'. See examples below. default (list): default value Returns: list: value of ``key`` or ``default`` if ``key`` is not set. ``type_key`` pattern examples:: 'str:value' => return str values from key.value 'int:type' => return int values from key.type 'bool:enabled' => return bool values from key.enabled ('str:value', 'int:type') => return tuple of values """ def typeKeySplit(tk): t, k = '', '' if isinstance(tk, str): t, k = tk.split(':', maxsplit=1) return (t, k) def value(key, tk): t, k = typeKeySplit(tk) if t in ('str', 'int', 'bool'): func = getattr(self, '%sValue' % t) return func('%s.%s' % (key, k)) raise TypeError('Invalid type_key: %s' % tk) size = self.intValue('%s.size' % key, -1) if size < 0: return default ret = [] for i in range(1, size + 1): if isinstance(type_key, str): if not self.hasKey('%s.%s.%s' % (key, i, typeKeySplit(type_key)[1])): continue ret.append(value('%s.%s' % (key, i), type_key)) elif isinstance(type_key, tuple): if not self.hasKey('%s.%s.%s' % (key, i, typeKeySplit(type_key[0])[1])): continue items = [] for tk in type_key: items.append(value('%s.%s' % (key, i), tk)) ret.append(tuple(items)) else: raise TypeError('Invalid type_key: %s' % type_key) return ret def setListValue(self, key, type_key, value): """ Set a list of values. Size of the list will be stored in key.size Args: key (str): used base-key type_key (str): pattern of 'value-type:value-name'. See examples below. value (list): that should be stored ``type_key`` pattern examples:: 'str:value' => return str values from key.value 'int:type' => return int values from key.type 'bool:enabled' => return bool values from key.enabled ('str:value', 'int:type') => return tuple of values """ def setValue(key, tk, v): t = '' if isinstance(tk, str): t, k = tk.split(':', maxsplit=1) if t in ('str', 'int', 'bool'): func = getattr(self, 'set%sValue' % t.capitalize()) return func('%s.%s' % (key, k), v) raise TypeError('Invalid type_key: %s' % tk) if not isinstance(value, (list, tuple)): raise TypeError('value has wrong type: %s' % value) old_size = self.intValue('%s.size' % key, -1) self.setIntValue('%s.size' % key, len(value)) for i, v in enumerate(value, start=1): if isinstance(type_key, str): setValue('%s.%s' % (key, i), type_key, v) elif isinstance(type_key, tuple): for iv, tk in enumerate(type_key): if len(v) > iv: setValue('%s.%s' % (key, i), tk, v[iv]) else: self.removeKey('%s.%s.%s' % (key, i, tk.split(':')[1])) else: raise TypeError('Invalid type_key: %s' % type_key) if len(value) < old_size: for i in range(len(value) + 1, old_size + 1): if isinstance(type_key, str): self.removeKey( '%s.%s.%s' % (key, i, type_key.split(':')[1])) elif isinstance(type_key, tuple): for tk in type_key: self.removeKey( '%s.%s.%s' % (key, i, tk.split(':')[1])) def removeKey(self, key): """ Remove key from options. Args: key (str): string used as key """ if key in self.dict: del self.dict[key] def removeKeysStartsWith(self, prefix): """ Remove key from options which start with given prefix. Args: prefix (str): prefix for keys (key starts with this string) that should be removed """ removeKeys = [] for key in self.dict.keys(): if key.startswith(prefix): removeKeys.append(key) for key in removeKeys: del self.dict[key] def keys(self): return list(self.dict.keys()) class ConfigFileWithProfiles(ConfigFile): """ Store options in profiles as 'profileX.key=value' Args: default_profile_name (str): default name of the first profile. """ def __init__(self, default_profile_name=''): ConfigFile.__init__(self) self.default_profile_name = default_profile_name self.current_profile_id = '1' self.setCurrentProfile(self.current_profile_id) def load(self, filename): """ Reset current options and load new options from file. Args: filename (str): full path """ self.current_profile_id = '1' super(ConfigFileWithProfiles, self).load(filename) def append(self, filename): """ Load options from file and append them to current options. Args: filename (str): full path """ super(ConfigFileWithProfiles, self).append(filename) found = False profiles = self.profiles() for profile_id in profiles: if profile_id == self.current_profile_id: found = True break if not found and profiles: self.current_profile_id = profiles[0] if self.intValue('profiles.version') <= 0: rename_keys = [] for key in self.dict.keys(): if key.startswith('profile.0.'): rename_keys.append(key) for old_key in rename_keys: new_key = 'profile1.' + old_key[10:] self.dict[new_key] = self.dict[old_key] del self.dict[old_key] if self.intValue('profiles.version') != 1: self.setIntValue('profiles.version', 1) def profiles(self): """ List of all available profile IDs. Profile IDs are strings! Returns: list: List with strings of profile IDs as strings. """ return self.strValue(key='profiles', default='1').split(':') def profilesSortedByName(self): """ List of available profile IDs alphabetically sorted by their names. Profile IDs are strings! Returns: list: all available profile IDs as strings """ profiles_unsorted = self.profiles() if len(profiles_unsorted) <= 1: return profiles_unsorted profiles_dict = {} for profile_id in profiles_unsorted: profiles_dict[self.profileName(profile_id).upper()] = profile_id # sort the dictionary by key (the profile name) profiles_sorted = collections.OrderedDict( sorted(profiles_dict.items())) # return the names as a list return list(profiles_sorted.values()) def currentProfile(self): """ Currently selected profile ID. Profile IDs are strings! Returns: str: profile ID """ return self.current_profile_id def setCurrentProfile(self, profile_id): """ Change the current profile. Args: profile_id (str, int): valid profile ID Returns: bool: ``True`` if successful """ if isinstance(profile_id, int): profile_id = str(profile_id) profiles = self.profiles() for i in profiles: if i == profile_id: profile_name = self.profileName(profile_id) self.current_profile_id = profile_id logger.changeProfile(profile_id, profile_name) logger.debug( f'Change current profile: {profile_id}={profile_name}', self) return True return False def setCurrentProfileByName(self, name): """ Change the current profile by a given name. Args: name (str): valid profile name Returns: bool: ``True`` if successful """ # Find the profile_id to this name... for profile_id in self.profiles(): if self.profileName(profile_id) == name: # ...and set current profile by this id. return self.setCurrentProfile(profile_id) return False def profileExists(self, profile_id): """ ``True`` if the profile exists. Args: profile_id (str, int): profile ID Returns: bool: ``True`` if ``profile_id`` exists. """ if isinstance(profile_id, int): profile_id = str(profile_id) return profile_id in self.profiles() def profileExistsByName(self, name): """ ``True`` if the profile exists. Args: name (str): profile name Returns: bool: ``True`` if ``name`` exists. """ profiles = self.profiles() for profile_id in profiles: if self.profileName(profile_id) == name: return True return False def profileName(self, profile_id=None): """Name of the profile. Args: profile_id (str, int): Valid profile ID Returns: str: Name of profile. """ if isinstance(profile_id, int): profile_id = str(profile_id) if profile_id is None: profile_id = self.current_profile_id if profile_id == '1': default = self.default_profile_name else: default = 'Profile %s' % profile_id return self.profileStrValue('name', default, profile_id) def addProfile(self, name): """ Add a new profile if the name is not already in use. Args: name (str): new profile name Returns: str: new profile ID """ profiles = self.profiles() for profile_id in profiles: if self.profileName(profile_id) == name: self.notifyError(_( 'Profile "{name}" already exists.').format(name=name)) return None new_id = 1 while True: ok = True if str(new_id) in profiles: ok = False if ok: break new_id = new_id + 1 new_id = str(new_id) profiles.append(new_id) self.setStrValue('profiles', ':'.join(profiles)) self.setProfileStrValue('name', name, new_id) return new_id def removeProfile(self, profile_id=None): """ Remove profile and all its keys and values. Args: profile_id (str, int): valid profile ID Returns: bool: ``True`` if successful """ if isinstance(profile_id, int): profile_id = str(profile_id) if profile_id is None: profile_id = self.current_profile_id profiles = self.profiles() if len(profiles) <= 1: self.notifyError(_("The last profile cannot be removed.")) return False found = False index = 0 for profile in profiles: if profile == profile_id: self.removeKeysStartsWith(self.profileKey('', profile_id)) del profiles[index] self.setStrValue('profiles', ':'.join(profiles)) found = True break index = index + 1 if not found: return False if self.current_profile_id == profile_id: self.current_profile_id = '1' return True def setProfileName(self, name, profile_id=None): """ Change the name of the profile. Args: name (str): new profile name profile_id (str, int): valid profile ID Returns: bool: ``True`` if successful. """ if isinstance(profile_id, int): profile_id = str(profile_id) if profile_id is None: profile_id = self.current_profile_id profiles = self.profiles() for profile in profiles: if self.profileName(profile) == name: if profile[0] != profile_id: self.notifyError(_( 'Profile "{name}" already exists.').format(name=name)) return False self.setProfileStrValue('name', name, profile_id) return True def profileKey(self, key, profile_id=None): """ Prefix for keys with profile. e.g. 'profile1.key' Args: key (str): Key identifier. profile_id (str, int): Valid profile ID. Returns: str: Key with prefix 'profile1.key' """ if isinstance(profile_id, int): profile_id = str(profile_id) if profile_id is None: profile_id = self.current_profile_id return 'profile' + profile_id + '.' + key def removeProfileKey(self, key, profile_id=None): """ Remove the key from profile. Args: key (str): key name profile_id (str, int): valid profile ID """ self.removeKey(self.profileKey(key, profile_id)) def removeProfileKeysStartsWith(self, prefix, profile_id=None): """ Remove the keys starting with prefix from profile. Args: prefix (str): prefix for keys (key starts with this string) that should be removed. profile_id (str, int): valid profile ID """ self.removeKeysStartsWith(self.profileKey(prefix, profile_id)) def remapProfileKey(self, oldKey, newKey, profileId=None): """ Remap profile keys to a new key name. Args: oldKey (str): old key name newKey (str): new key name profileId (str, int): valid profile ID """ self.remapKey(self.profileKey(oldKey, profileId), self.profileKey(newKey, profileId)) def hasProfileKey(self, key, profile_id=None): """ ``True`` if key is set in profile. Args: key (str): string used as key profile_id (str, int): valid profile ID Returns: bool: ``True`` if ``key`` is set. """ return self.profileKey(key, profile_id) in self.dict def profileStrValue(self, key, default='', profile_id=None): """Return the value of ``key`` related to ``profile_id``. Returns: str: The value. """ return self.strValue(self.profileKey(key, profile_id), default) def setProfileStrValue(self, key, value, profile_id=None): self.setStrValue(self.profileKey(key, profile_id), value) def profileIntValue(self, key, default=0, profile_id=None): return self.intValue(self.profileKey(key, profile_id), default) def setProfileIntValue(self, key, value, profile_id=None): self.setIntValue(self.profileKey(key, profile_id), value) def profileBoolValue(self, key, default=False, profile_id=None): return self.boolValue(self.profileKey(key, profile_id), default) def setProfileBoolValue(self, key, value, profile_id=None): self.setBoolValue(self.profileKey(key, profile_id), value) def profileListValue(self, key, type_key='str:value', default=[], profile_id=None): return self.listValue( self.profileKey(key, profile_id), type_key, default) def setProfileListValue(self, key, type_key, value, profile_id=None): self.setListValue(self.profileKey(key, profile_id), type_key, value) backintime-1.5.4/common/configure000077500000000000000000000250211477034762000170400ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2009 Oprea Dan # SPDX-FileCopyrightText: © 2013 Germar Reitze # SPDX-FileCopyrightText: © 2022 Jürgen Altfeld # SPDX-FileCopyrightText: © 2022 Christian Buhtz # SPDX-FileCopyrightText: © 2023 Kian-Meng Ang # SPDX-FileCopyrightText: © 2023 Fabio Fantoni # SPDX-FileCopyrightText: © 2024 Tejas Guruswamy # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # # This is the configuration file for the Read the Docs service. # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details. # Clean up if [ -e Makefile ]; then rm Makefile; fi # Tmp files MAKEFILE="$(mktemp)" UNINSTALL_FILES="$(mktemp)" UNINSTALL_DIRS="$(mktemp)" # set default options PYTHON="/usr/bin/python3" USR_BIN_FILES="backintime backintime-askpass" usage () { echo "Usage:" echo "$0 [--python | --python3 | --python=PYTHON_BINARY]" echo "" echo "--python" echo "\tuse 'python' to start Python3" echo "--python3" echo "\tuse 'python3' to start Python3" echo "--python=PYTHON_BINARY" echo "\tuse PYTHON_BINARY to start Python3" } addInstallFiles () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi for i in $(ls $file); do addInstallFile "$i" "$dest" "$mode" done } addInstallFile () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallFile "$file" "$dest" } addSymlink () { dst=$1 src=$2 printf "\tln --symbolic --force $dst \$(DEST)$src\n" >> ${MAKEFILE} addUninstallFile "$src" } addInstallFileRename () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallFileRename "$dest" } addUninstallFile () { if [ $# -eq 2 ]; then file=$(basename "$1") dest=$2 path="\$(DEST)$dest/$file" else path="\$(DEST)$1" fi printf "\trm -f $path\n" >> ${UNINSTALL_FILES} } addUninstallFileRename () { file=$1 printf "\trm -f \$(DEST)$file\n" >> ${UNINSTALL_FILES} } addInstallDir () { dest=$1 printf "\tinstall -d \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallDir "$dest" } addUninstallDir () { dest=$1 printf "\tif [ -d \$(DEST)$dest ]; then rmdir --ignore-fail-on-non-empty \$(DEST)$dest; fi\n" >> ${UNINSTALL_DIRS} } addComment () { printf "\t# Install $1\n" >> ${MAKEFILE} printf "\t# Uninstall files $1\n" >> ${UNINSTALL_FILES} printf "\t# Uninstall directory $1\n" >> ${UNINSTALL_DIRS} } addNewline () { printf "\n" >> ${MAKEFILE} printf "\n" >> ${UNINSTALL_FILES} printf "\n" >> ${UNINSTALL_DIRS} } onTravis () { [ "${TRAVIS}" = "true" ] } # Get commandline arguments unknown_args="" for arg in $*; do case $arg in --python=*) PYTHON=$(echo $arg | cut -f2 -d'=') ;; --python3) PYTHON="/usr/bin/python3" ;; --python) PYTHON="/usr/bin/python" ;; --help | -h) usage; exit 0;; *) unknown_args="$unknown_args $arg";; esac done if [ -n "$unknown_args" ]; then echo "Unknown Arguments: $unknown_args" fi # Check if the python binary file exists if [ ! -f "$PYTHON" ]; then echo "Warning: \"${PYTHON}\" not found on this computer" fi if [ -n "$(sed -e "s#^/usr/bin/python3\? #${PYTHON} #gw /dev/stdout" -i $USR_BIN_FILES)" ] then echo "Replacement of python path with \"${PYTHON}\" successful." else echo "WARNING: Replacement of python path with \"${PYTHON}\" FAILED. Maybe you ran configure more than once?" fi # Check languages mos="" langs="" for langfile in `ls po/*.po`; do lang=`echo $langfile | cut -d/ -f2 | cut -d. -f1` mos="po/$lang.mo $mos" langs="$lang $langs" done # Start Makefile printf "LANGS=$langs\n\n" >> ${MAKEFILE} printf "PREFIX=/usr\n" >> ${MAKEFILE} printf "DEST=\$(DESTDIR)\$(PREFIX)\n\n" >> ${MAKEFILE} printf "all:\tbuild\n\n" >> ${MAKEFILE} printf "build:\ttranslate compress\n" >> ${MAKEFILE} printf "clean:\n" >> ${MAKEFILE} printf "\trm -f po/*.mo\n" >> ${MAKEFILE} printf "\trm -f man/C/*.gz\n" >> ${MAKEFILE} printf "\trm -f config-example-*.gz\n" >> ${MAKEFILE} printf "\trm -rf doc-dev/_build/*\n" >> ${MAKEFILE} printf "\n" >> ${MAKEFILE} # Create install and uninstall target printf "install:\tinstall_translations\n" >> ${MAKEFILE} printf "\n\t# Inject version string into source files\n" >> ${MAKEFILE} printf "\t(cd .. && ./updateversion.sh)\n\n" >> ${MAKEFILE} addComment "python" addUninstallDir "/share/backintime/common/__pycache__" addUninstallFile "*.pyc" "/share/backintime/common/__pycache__" addInstallDir "/share/backintime/common" addInstallFiles "*.py" "/share/backintime/common" addNewline addComment "plugins" addUninstallDir "/share/backintime/plugins/__pycache__" addUninstallFile "*.pyc" "/share/backintime/plugins/__pycache__" addInstallDir "/share/backintime/plugins" addInstallFiles "plugins/*.py" "/share/backintime/plugins" addUninstallDir "/share/backintime" addNewline addComment "documentation" addInstallDir "/share/doc/backintime-common" addInstallFile "../AUTHORS" "/share/doc/backintime-common" addInstallFile "../README.md" "/share/doc/backintime-common" addInstallFile "../FAQ.md" "/share/doc/backintime-common" addInstallFile "../TRANSLATIONS" "/share/doc/backintime-common" addInstallFile "../CHANGES" "/share/doc/backintime-common" addInstallFile "../LICENSE" "/share/doc/backintime-common" addInstallDir "/share/doc/backintime-common/LICENSES" addInstallFiles "../LICENSES/*" "/share/doc/backintime-common/LICENSES" addNewline addComment "config and user-callback examples" addInstallDir "/share/doc/backintime-common/examples" addInstallFile "config-example-local.gz" "/share/doc/backintime-common/examples" addInstallFile "config-example-ssh.gz" "/share/doc/backintime-common/examples" addInstallDir "/share/doc/backintime-common/user-callback-examples" addInstallFiles "../doc/user-callback-examples/user-callback.*" "/share/doc/backintime-common/user-callback-examples" addUninstallDir "/share/doc/backintime-common" addUninstallDir "/share/doc" addNewline addComment "man" addInstallDir "/share/man/man1" addInstallFile "man/C/backintime.1.gz" "/share/man/man1" addInstallFile "man/C/backintime-askpass.1.gz" "/share/man/man1" addInstallFile "man/C/backintime-config.1.gz" "/share/man/man1" addUninstallDir "/share/man" addNewline addComment "application" addInstallDir "/bin" addInstallFile "backintime" "/bin" "755" addInstallFile "backintime-askpass" "/bin" "755" addNewline addComment "autostart" addInstallDir "/../etc/xdg/autostart" addInstallFile "backintime.desktop" "/../etc/xdg/autostart" addUninstallDir "/../etc/xdg" addUninstallDir "/../etc" addNewline addComment "bash-completion" addInstallDir "/share/bash-completion/completions" addInstallFiles "bash-completion/*" "/share/bash-completion/completions" addSymlink "backintime" "/share/bash-completion/completions/backintime-qt" addUninstallDir "/share/bash-completion" addNewline # compress printf "compress:\n" >> ${MAKEFILE} printf "\t# Man pages\n" >> ${MAKEFILE} printf "\tfor i in \$\$(ls -1 man/C/); do case \$\$i in *.gz|*~) continue;; *) gzip -n --best -c man/C/\$\$i > man/C/\$\${i}.gz;; esac; done\n\n" >> ${MAKEFILE} printf "\t# Config-examples\n" >> ${MAKEFILE} printf "\tgzip -n --best -c config-example-local > config-example-local.gz\n" >> ${MAKEFILE} printf "\tgzip -n --best -c config-example-ssh > config-example-ssh.gz\n\n" >> ${MAKEFILE} # translate printf "translate:\t$mos\n\n" >> ${MAKEFILE} for lang in $langs; do printf "po/$lang.mo: po/$lang.po\n" >> ${MAKEFILE} printf "\tmsgfmt -o po/$lang.mo po/$lang.po\n\n" >> ${MAKEFILE} done # common langs printf "install_translations:\n" >> ${MAKEFILE} addComment "translations" for lang in $langs; do addInstallDir "/share/locale/$lang/LC_MESSAGES" addInstallFileRename "po/$lang.mo" "/share/locale/$lang/LC_MESSAGES/backintime.mo" addUninstallDir "/share/locale/$lang" done addUninstallDir "/share/locale" addUninstallDir "/share" addNewline # uninstall printf "uninstall:\tuninstall_files uninstall_dirs\n\n" >> ${MAKEFILE} printf "uninstall_files:\n" >> ${MAKEFILE} cat ${UNINSTALL_FILES} >> ${MAKEFILE} printf "uninstall_dirs:\n" >> ${MAKEFILE} cat ${UNINSTALL_DIRS} >> ${MAKEFILE} # test for i in "pytest" "py.test-3" "py.test-3.6" "py.test-3.5" "py.test-3.4"; do PYTEST=$(which $i 2>/dev/null) if [ -n "${PYTEST}" ]; then break fi done # Use "python", "python3" or if available "py.test-3" CMD="${PYTHON}" printf "test:\tunittest\n\n" >> ${MAKEFILE} printf "test-v:\tunittest-v\n\n" >> ${MAKEFILE} for v in "" "-v"; do # Provide unittests with and without verbosity -v printf "unittest${v}:\n" >> ${MAKEFILE} # Use pytest if available if [ -n "${PYTEST}" ]; then printf "\t${PYTEST} ${v}\n" >> ${MAKEFILE} # Fallback to unittest module else for i in $(ls -1 test/test_*.py); do printf "\t${CMD} -m unittest ${v} -b $i\n" >> ${MAKEFILE} done fi printf "\n" >> ${MAKEFILE} done # Copy Makefile mv ${MAKEFILE} Makefile chmod 644 Makefile # Clean up for i in "${UNINSTALL_FILES}" "${UNINSTALL_DIRS}"; do if [ -e "$i" ]; then rm "$i" fi done # check python version PYTHON_VERSION_REQUIRED="3.9" PYTHON_VERSION_CURRENT=$(${PYTHON} --version | tr --delete 'Python ') # Credits: https://unix.stackexchange.com/a/285928/136851 if [ "$(printf '%s\n' "$PYTHON_VERSION_REQUIRED" "$PYTHON_VERSION_CURRENT" | sort -V | head -n1)" != "$PYTHON_VERSION_REQUIRED" ]; then printf "Error: Wrong Python version ${PYTHON_VERSION_CURRENT}. " printf "But minimal version ${PYTHON_VERSION_REQUIRED} required.\n" exit 1 fi printf "All OK. Now run:\n" printf " make\n" printf " sudo make install\n" backintime-1.5.4/common/daemon.py000066400000000000000000000166571477034762000167650ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2007 Sander Marechal # SPDX-FileCopyrightText: © 2016 Germar Reitze # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See file/folder LICENSE or # go to # and . """A generic daemon class. Original from: http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python Copyright © 2007 Sander Marechal License CC0 or Public Domain Notes about the license (by buhtz, 2024-08-13): The linked blog article is licensed under CC BY-SA 3.0 which is not compatible with GPLv2 used by Back In Time. But the original author clarified that the code used in the blog article is public domain. See this original email. Date: Tue, 13 Aug 2024 14:19:48 +0200 Subject: Re: Your Daemon code in Back In Time Message-ID: <06084b4b-2293-4a28-a290-96fa4d309a8b@email.android.com> In-Reply-To: <3d57067b590e271ce6f361ce4147ac08@posteo.de> From: Sander Marechal To: c.buhtz@posteo.jp Hello Christian, As far as I am concerned that daemon code is public domain. You can use it under any license you want. There are only a few ways to start a daemon so technically the code can't be copyrighted as far as I am concerned. That CC license is just for my articles in general. Kind regards, -- Sander Marechal """ import sys import os import signal import atexit import errno from time import sleep import logger from applicationinstance import ApplicationInstance def fdDup(old, new_fd, mode='w'): """Duplicate file descriptor `old` to `new_fd` and closing the latter first. Used to redirect stdin, stdout and stderr from daemonized threads. Args: old (str): Path to the old file (e.g. /dev/stdout). new_fd (_io.TextIOWrapper): File object for the new file. mode (str): Mode in which the old file should be opened. """ try: fd = open(old, mode) os.dup2(fd.fileno(), new_fd.fileno()) except OSError as e: logger.debug('Failed to redirect {}: {}'.format(old, str(e))) class Daemon: """A generic daemon class. Usage: subclass the Daemon class and override the run() method """ def __init__(self, pidfile=None, stdin='/dev/null', stdout='/dev/stdout', stderr='/dev/null', umask=0o022): self.stdin = stdin self.stdout = stdout self.stderr = stderr self.pidfile = pidfile self.umask = umask if pidfile: self.appInstance = ApplicationInstance( pidfile, autoExit=False, flock=False) def daemonize(self): """Converts the current process into a daemon. It is a process running in the background, sending a SIGTERM signal to the current process. This is done via the UNIX double-fork magic, see Stevens' 'Advanced Programming in the UNIX Environment' for details (ISBN 0201563177) and this explanation: https://stackoverflow.com/a/6011298 """ try: pid = os.fork() logger.debug('first fork pid: {}'.format(pid), self) if pid > 0: # exit first parent sys.exit(0) except OSError as e: logger.error("fork #1 failed: %d (%s)" % (e.errno, str(e)), self) sys.exit(1) # Decouple from parent environment logger.debug('decouple from parent environment', self) os.chdir("/") os.setsid() os.umask(self.umask) # Do second fork try: pid = os.fork() logger.debug('second fork pid: {}'.format(pid), self) if pid > 0: # exit from second parent sys.exit(0) except OSError as e: logger.error("fork #2 failed: %d (%s)" % (e.errno, str(e)), self) sys.exit(1) # redirect standard file descriptors logger.debug('redirect standard file descriptors', self) sys.stdout.flush() sys.stderr.flush() fdDup(self.stdin, sys.stdin, 'r') fdDup(self.stdout, sys.stdout, 'w') fdDup(self.stderr, sys.stderr, 'w') signal.signal(signal.SIGTERM, self.cleanupHandler) if self.pidfile: atexit.register(self.appInstance.exitApplication) # write pidfile logger.debug('write pidfile', self) self.appInstance.startApplication() def cleanupHandler(self, signum, frame): if self.pidfile: self.appInstance.exitApplication() sys.exit(0) def start(self): """Start the daemon.""" # Check for a pidfile to see if the daemon already runs if self.pidfile and not self.appInstance.check(): logger.error(f'pidfile {self.pidfile} already exists. ' 'Daemon already running?\n', self) sys.exit(1) # Start the daemon self.daemonize() self.run() def stop(self): """Stop the daemon.""" if not self.pidfile: logger.debug( "Unattended daemon can't be stopped. No PID file", self) return # Get the pid from the pidfile pid = self.appInstance.readPidFile()[0] if not pid: message = "pidfile %s does not exist. Daemon not running?\n" logger.error(message % self.pidfile, self) return # not an error in a restart # Try killing the daemon process try: while True: os.kill(pid, signal.SIGTERM) sleep(0.1) except OSError as err: if err.errno == errno.ESRCH: # No such process self.appInstance.exitApplication() else: logger.error(str(err), self) sys.exit(1) def restart(self): """Restart the daemon.""" self.stop() self.start() def reload(self): """Send SIGHUP signal to process.""" if not self.pidfile: logger.debug( "Unattended daemon can't be reloaded. No PID file", self) return # Get the pid from the pidfile pid = self.appInstance.readPidFile()[0] if not pid: logger.error(f'pidfile {self.pidfile} does not exist. ' 'Daemon not running?\n', self) return # Try killing the daemon process try: os.kill(pid, signal.SIGHUP) except OSError as err: if err.errno == errno.ESRCH: # no such process self.appInstance.exitApplication() else: sys.stderr.write(str(err)) sys.exit(1) def status(self): """Return status.""" if not self.pidfile: logger.debug( "Unattended daemon can't be checked. No PID file", self) return return not self.appInstance.check() def run(self): """Override this method when subclass ``Daemon``. It will be called after the process has been daemonized by ``start()`` or ``restart()``. """ pass backintime-1.5.4/common/diagnostics.py000066400000000000000000000323741477034762000200230ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2022 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Provides the ability to collect diagnostic information on Back In Time. These are version numbers of the dependent tools, environment variables, paths, operating system and the like. This is used to enhance error reports and to enrich them with the necessary information as uncomplicated as possible. """ import sys import os import itertools from pathlib import Path import pwd import platform import locale import subprocess import json import re import config import tools import version def collect_minimal_diagnostics(): """Collect minimal information about backintime and the operating system. Returns: dict: A nested dictionary. """ return { 'backintime': { 'name': config.Config.APP_NAME, 'version': version.__version__, 'running-as-root': pwd.getpwuid(os.getuid()).pw_name == 'root', }, 'host-setup': { 'OS': _get_os_release() } } def collect_diagnostics(): """Collect information about environment, versions of tools and packages used by Back In Time. The information can be used e.g. for debugging and bug reports. Returns: dict: A nested dictionary. """ result = collect_minimal_diagnostics() # === BACK IN TIME === # work-around: Instantiate to get the user-callback folder # (should be singleton) cfg = config.Config() result['backintime'].update({ 'latest-config-version': config.Config.CONFIG_VERSION, 'local-config-file': cfg._LOCAL_CONFIG_PATH, 'local-config-file-found': Path(cfg._LOCAL_CONFIG_PATH).exists(), 'global-config-file': cfg._GLOBAL_CONFIG_PATH, 'global-config-file-found': Path(cfg._GLOBAL_CONFIG_PATH).exists(), # 'distribution-package': str(distro_path), 'started-from': str(Path(config.__file__).parent), 'user-callback': cfg.takeSnapshotUserCallback(), 'keyring-supported': tools.keyringSupported() }) # Git repo bit_root_path = Path(tools.backintimePath("")) git_info = tools.get_git_repository_info(bit_root_path) if git_info: result['backintime']['git-project-root'] = str(bit_root_path) for key in git_info: result['backintime'][f'git-{key}'] = git_info[key] # == HOST setup === result['host-setup'].update({ # Kernel & Architecture 'platform': platform.platform(), # OS Version (and maybe name) 'system': f'{platform.system()} {platform.version()}' }) # Display system (X11 or Wayland) # This doesn't catch all edge cases. # For more details see: https://unix.stackexchange.com/q/202891/136851 result['host-setup']['display-system'] = os.environ.get( 'XDG_SESSION_TYPE', '($XDG_SESSION_TYPE not set)') # locale (system language etc) # # Implementation note: With env var "LC_ALL=C" getlocale() will return # (None, None). # This throws an error in "join()": # TypeError: sequence item 0: expected str instance, NoneType found my_locale = locale.getlocale() if all(x is None for x in my_locale): my_locale = ["(Unknown)"] result['host-setup']['locale'] = ', '.join(my_locale) # PATH environment variable result['host-setup']['PATH'] = os.environ.get('PATH', '($PATH unknown)') # RSYNC environment variables for var in ['RSYNC_OLD_ARGS', 'RSYNC_PROTECT_ARGS']: result['host-setup'][var] = os.environ.get(var, '(not set)') # === PYTHON setup === python = ' '.join(( platform.python_version(), ' '.join(platform.python_build()), platform.python_implementation(), platform.python_compiler() )) # Python branch and revision if available branch = platform.python_branch() if branch: python = f'{python} branch: {branch}' rev = platform.python_revision() if rev: python = f'{python} rev: {rev}' python_executable = Path(sys.executable) # Python interpreter result['python-setup'] = { 'python': python, 'python-executable': str(python_executable), 'python-executable-symlink': python_executable.is_symlink(), } # Real interpreter path if it is used via a symlink if result['python-setup']['python-executable-symlink']: result['python-setup']['python-executable-resolved'] \ = str(python_executable.resolve()) result['python-setup']['sys.path'] = sys.path result['python-setup']['qt'] = _get_qt_information() # === EXTERN TOOL === result['external-programs'] = {} result['external-programs']['rsync'] = _get_rsync_info() # ssh result['external-programs']['ssh'] = _get_extern_versions(['ssh', '-V']) # sshfs result['external-programs']['sshfs'] \ = _get_extern_versions(['sshfs', '-V'], r'SSHFS version (.*)\n') # EncFS # Using "[Vv]" in the pattern because encfs does translate its output. # e.g. In German it is "Version" in English "version". result['external-programs']['encfs'] \ = _get_extern_versions(['encfs'], r'Build: encfs [Vv]ersion (.*)\n') # Shell SHELL_ERR_MSG = '($SHELL not exists)' shell = os.environ.get('SHELL', SHELL_ERR_MSG) result['external-programs']['shell'] = shell if shell != SHELL_ERR_MSG: shell_version = _get_extern_versions([shell, '--version']) result['external-programs']['shell-version'] \ = shell_version.split('\n')[0] result = _replace_username_paths( result=result, username=pwd.getpwuid(os.getuid()).pw_name ) return result def _get_qt_information(): """Collect Version and Theme information from Qt. If environment variable ``DISPLAY`` is set a temporary QApplication instances is created. """ # pylint: disable=import-outside-toplevel try: import PyQt6.QtCore import PyQt6.QtGui import PyQt6.QtWidgets except ImportError: return '(Cannot import PyQt6)' # Themes theme_info = {} if tools.checkXServer(): # TODO use tools.is_Qt_working() when stable qapp = PyQt6.QtWidgets.QApplication([]) theme_info = { 'Theme': PyQt6.QtGui.QIcon.themeName(), 'Theme Search Paths': PyQt6.QtGui.QIcon.themeSearchPaths(), 'Fallback Theme': PyQt6.QtGui.QIcon.fallbackThemeName(), 'Fallback Search Paths': PyQt6.QtGui.QIcon.fallbackSearchPaths() } qapp.quit() return { 'Version': f'PyQt {PyQt6.QtCore.PYQT_VERSION_STR} ' f'/ Qt {PyQt6.QtCore.QT_VERSION_STR}', **theme_info } def _get_extern_versions(cmd, pattern=None, try_json=False, error_pattern=None): """Get the version of an external tools using :class:`subprocess.Popen`. Args: cmd (list[str]): Commandline arguments that will be passed to ``Popen()``. pattern (str) : A regex pattern to extract the version string from the commands output. try_json (bool): Interpret the output as json first (default: ``False``). If it could be parsed the result is a dict error_pattern (str): Regex pattern to identify a message in the output that indicates an error. Returns: Version information as :obj:`str` or :obj:`dict`. The latter is used if the ``cmd`` requested offer its information in JSON format. ``None`` if the error_pattern did match (to indicate an error). """ try: # as context manager to prevent ResourceWarning's with subprocess.Popen(cmd, env={'LC_ALL': 'C'}, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) as proc: error_output = proc.stderr.read() std_output = proc.stdout.read() except FileNotFoundError: result = f'(no {cmd[0]})' else: # Check for errors if error_pattern: match_result = re.findall(error_pattern, error_output) if match_result: return None # some tools use "stderr" for version info result = std_output if std_output else error_output # Expect JSON string if try_json: try: result = json.loads(result) except json.decoder.JSONDecodeError: # Wasn't a json. Try regex in the next block. pass else: return result # as JSON # extract version string if pattern: result = re.findall(pattern, result)[0] return result.strip() # as string def _get_rsync_info(): """Collect infos about rsync. Returns: dict: Collected info """ # rsync # rsync >= 3.2.7: -VV return a json # rsync <= 3.2.6 and > (somewhere near) 3.1.3: -VV return the same as -V # rsync <= (somewhere near) 3.1.3: -VV doesn't exists # rsync == 3.1.3 (Ubuntu 20 LTS) doesn't even know '-V' # This works when rsync understands -VV and returns json or human readable info = _get_extern_versions( ['rsync', '-VV'], r'rsync version (.*) protocol version', try_json=True, error_pattern=r'unknown option' ) # When -VV was unknown use -V and parse the human readable output if not info: # try the old way info = _get_extern_versions( ['rsync', '--version'], r'rsync version (.*) protocol version' ) elif isinstance(info, dict): # Rsync (>= 3.2.7)provided its information in JSON format. # Remove some irrelevant information. for key in ['program', 'copyright', 'url', 'license', 'caveat']: try: del info[key] except KeyError: pass # Reduce use of vertical space with transforming lists and dicts into # strings. for key in ['daemon_auth_list', 'compress_list', 'checksum_list', 'optimizations', 'capabilities']: if isinstance(info[key], list): info[key] = ', '.join(info[key]) elif isinstance(info[key], dict): info[key] = '; '.join( f'{k}: {v}' for k, v in info[key].items()) return info def _get_os_release(): """Try to get the name and version of the operating system used. First it extract infos from the file ``/etc/os-release``. Because not all GNU/Linux distributions follow the standards it will also look for alternative release files (pattern: ``/etc/*release``). See http://linuxmafia.com/faq/Admin/release-files.html for examples. Returns: A string with the name of the operating system, e.g. "Debian GNU/Linux 11 (bullseye)" or a dictionary if alternative release files where found. """ def _get_pretty_name_or_content(fp): """Return value of PRETTY_NAME from a release file or return the whole file content.""" # Read content from file try: with fp.open('r') as handle: content = handle.read() except FileNotFoundError: return f'({fp.name} file not found)' # Try to extract the pretty name try: return re.findall('PRETTY_NAME=\"(.*)\"', content)[0] except IndexError: # Return full content when no PRETTY_NAME was found return content etc_path = Path('/etc') os_files = list(filter(lambda p: p.is_file(), itertools.chain( etc_path.glob('*release*'), etc_path.glob('*version*')) )) # "os-release" is standard and should be on top of the list fp_osrelease = etc_path / 'os-release' try: os_files.remove(fp_osrelease) except ValueError: pass else: os_files = [fp_osrelease] + os_files # each release/version file found osrelease = {str(fp): _get_pretty_name_or_content(fp) for fp in os_files} # No alternative release files found if len(osrelease) == 1: return osrelease[str(fp_osrelease)] return osrelease def _replace_username_paths(result, username): """User's real ``HOME`` path and login name are replaced with surrogtes. This is because of security reasons. Args: result (dict): Dict possibly containing the username and its home path. username (str): The user's real login name to look for. Returns: A dictionary with replacements. """ # Replace home folder user names with this dummy name # for privacy reasons USER_REPLACED = 'UsernameReplaced' # JSON to string result = json.dumps(result) result = result.replace(f'/home/{username}', f'/home/{USER_REPLACED}') result = result.replace(f'~/{username}', f'~/{USER_REPLACED}') # string to JSON return json.loads(result) backintime-1.5.4/common/doc-dev/000077500000000000000000000000001477034762000164525ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/Makefile000066400000000000000000000152601477034762000201160ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/BackInTime.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/BackInTime.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/BackInTime" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/BackInTime" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." htmlOpen: html xdg-open $(BUILDDIR)/html/index.html backintime-1.5.4/common/doc-dev/REUSE.toml000066400000000000000000000012401477034762000202270ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = [ "**/*.rst", "Makefile", "conf.py" ] SPDX-License-Identifier = "GPL-2.0-or-later" SPDX-FileCopyrightText = "© 2022 Back In Time" backintime-1.5.4/common/doc-dev/_static/000077500000000000000000000000001477034762000201005ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/_static/.dummy000066400000000000000000000000001477034762000212220ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/_templates/000077500000000000000000000000001477034762000206075ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/_templates/.dummy000066400000000000000000000000001477034762000217310ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/applicationinstance.rst000066400000000000000000000002241477034762000232320ustar00rootroot00000000000000applicationinstance module ========================== .. automodule:: applicationinstance :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/askpass.rst000066400000000000000000000001601477034762000206460ustar00rootroot00000000000000askpass module ============== .. automodule:: askpass :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/backintime.rst000066400000000000000000000001711477034762000213110ustar00rootroot00000000000000backintime module ================= .. automodule:: backintime :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/bcolors.rst000066400000000000000000000001601477034762000206440ustar00rootroot00000000000000bcolors module ============== .. automodule:: bcolors :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/cli.rst000066400000000000000000000001441477034762000177520ustar00rootroot00000000000000cli module ========== .. automodule:: cli :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/conf.py000066400000000000000000000101671477034762000177560ustar00rootroot00000000000000#!/usr/bin/env python3 import sys import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath(os.path.join(os.pardir))) sys.path.insert(0, os.path.abspath(os.path.join(os.pardir, "plugins"))) # -- General configuration ------------------------------------------------ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', 'sphinx_rtd_theme' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = 'BackInTime' copyright = '2016, Germar Reitze' author = 'Germar Reitze' # Don't edit this variable. It is updated automatically by "updateversion.sh". import version as version_module version = version_module.__version__ # The full version, including alpha/beta/rc tags. release = version # '1.3.3-dev' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' autodoc_default_options = { 'members': True, 'member-order': 'bysource', 'private-members': True, 'undoc-members': True, 'special-members': True, 'exclude-members': '__weakref__,__dict__,__module__,__annotations__', } # -- Intersphinx options -------------------------------------------------- intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), # PyQt is not mappable because of a known issue. See # https://riverbankcomputing.com/pipermail/pyqt/2013-March/032528.html } # -- Napoleon include private members which have docstrings --------------- napoleon_include_private_with_doc = True # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'classic' html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y, %H:%M (%Z)' # Output file base name for HTML help builder. htmlhelp_basename = 'BackInTimeDevDoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'BackInTime.tex', 'Back In Time Development Documentation', 'Germar Reitze', 'manual'), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'backintime', 'Back In Time Development Documentation', ['Germar Reitze'], 1) ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'BackInTime', 'Back In Time Development Documentation', 'Germar Reitze', 'BackInTime', 'One line description of project.', 'Miscellaneous'), ] backintime-1.5.4/common/doc-dev/config.rst000066400000000000000000000001551477034762000204520ustar00rootroot00000000000000config module ============= .. automodule:: config :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/configfile.rst000066400000000000000000000001711477034762000213100ustar00rootroot00000000000000configfile module ================= .. automodule:: configfile :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/diagnostics.rst000066400000000000000000000001741477034762000215150ustar00rootroot00000000000000diagnostics module ================== .. automodule:: diagnostics :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/encfstools.rst000066400000000000000000000001711477034762000213620ustar00rootroot00000000000000encfstools module ================= .. automodule:: encfstools :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/exceptions.rst000066400000000000000000000001711477034762000213640ustar00rootroot00000000000000exceptions module ================= .. automodule:: exceptions :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/flock.rst000066400000000000000000000001521477034762000203000ustar00rootroot00000000000000flock module ============ .. automodule:: flock :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/guiapplicationinstance.rst000066400000000000000000000002351477034762000237410ustar00rootroot00000000000000guiapplicationinstance module ============================= .. automodule:: guiapplicationinstance :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/index.rst000066400000000000000000000007351477034762000203200ustar00rootroot00000000000000.. BackInTime documentation master file, created by sphinx-quickstart on Sat Jan 9 00:04:35 2016. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to Back In Time's documentation ======================================= Contents: .. toctree:: :maxdepth: 2 modules.rst plugins/modules.rst Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` backintime-1.5.4/common/doc-dev/logger.rst000066400000000000000000000001551477034762000204640ustar00rootroot00000000000000logger module ============= .. automodule:: logger :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/modules.rst000066400000000000000000000005551477034762000206610ustar00rootroot00000000000000common ====== .. toctree:: :maxdepth: 4 applicationinstance askpass backintime bcolors cli config configfile diagnostics encfstools exceptions flock guiapplicationinstance logger mount password password_ipc pluginmanager progress schedule snapshotlog snapshots ssh_max_arg sshtools tools backintime-1.5.4/common/doc-dev/mount.rst000066400000000000000000000001521477034762000203440ustar00rootroot00000000000000mount module ============ .. automodule:: mount :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/password.rst000066400000000000000000000001631477034762000210460ustar00rootroot00000000000000password module =============== .. automodule:: password :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/password_ipc.rst000066400000000000000000000001771477034762000217060ustar00rootroot00000000000000password_ipc module =================== .. automodule:: password_ipc :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/pluginmanager.rst000066400000000000000000000002021477034762000220270ustar00rootroot00000000000000pluginmanager module ==================== .. automodule:: pluginmanager :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/plugins/000077500000000000000000000000001477034762000201335ustar00rootroot00000000000000backintime-1.5.4/common/doc-dev/plugins/modules.rst000066400000000000000000000001051477034762000223310ustar00rootroot00000000000000plugins ======= .. toctree:: :maxdepth: 4 usercallbackplugin backintime-1.5.4/common/doc-dev/plugins/usercallbackplugin.rst000066400000000000000000000002211477034762000245320ustar00rootroot00000000000000usercallbackplugin module ========================= .. automodule:: usercallbackplugin :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/progress.rst000066400000000000000000000001631477034762000210500ustar00rootroot00000000000000progress module =============== .. automodule:: progress :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/schedule.rst000066400000000000000000000001631477034762000210000ustar00rootroot00000000000000schedule module =============== .. automodule:: schedule :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/snapshotlog.rst000066400000000000000000000001741477034762000215470ustar00rootroot00000000000000snapshotlog module ================== .. automodule:: snapshotlog :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/snapshots.rst000066400000000000000000000001661477034762000212310ustar00rootroot00000000000000snapshots module ================ .. automodule:: snapshots :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/ssh_max_arg.rst000066400000000000000000000001741477034762000215010ustar00rootroot00000000000000ssh_max_arg module ================== .. automodule:: ssh_max_arg :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/sshtools.rst000066400000000000000000000001631477034762000210620ustar00rootroot00000000000000sshtools module =============== .. automodule:: sshtools :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/doc-dev/tools.rst000066400000000000000000000001521477034762000203420ustar00rootroot00000000000000tools module ============ .. automodule:: tools :members: :undoc-members: :show-inheritance: backintime-1.5.4/common/encfstools.py000066400000000000000000000674711477034762000177010ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # SPDX-FileCopyrightText: © 2012-2022 Taylor Raack # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import subprocess import re import shutil import tempfile from datetime import datetime from packaging.version import Version import config import password import password_ipc import tools import sshtools import logger from mount import MountControl from exceptions import MountException, EncodeValueError class EncFS_mount(MountControl): """Mount encrypted paths with encfs.""" def __init__(self, *args, **kwargs): # init MountControl super(EncFS_mount, self).__init__(*args, **kwargs) # Workaround for some linters. self.path = None self.reverse = None self.config_path = None self.setattrKwargs('path', self.config.localEncfsPath(self.profile_id), **kwargs) self.setattrKwargs('reverse', False, **kwargs) self.setattrKwargs('config_path', None, **kwargs) self.setattrKwargs('password', None, store = False, **kwargs) self.setattrKwargs('hash_id_1', None, **kwargs) self.setattrKwargs('hash_id_2', None, **kwargs) self.setDefaultArgs() self.mountproc = 'encfs' self.log_command = '%s: %s' % (self.mode, self.path) self.symlink_subfolder = None def _mount(self): """ mount the service """ if self.password is None: self.password = self.config.password(self.parent, self.profile_id, self.mode) logger.debug('Provide password through temp FIFO', self) thread = password_ipc.TempPasswordThread(self.password) env = self.env() env['ASKPASS_TEMP'] = thread.temp_file with thread.starter(): encfs = [self.mountproc, '--extpass=backintime-askpass'] if self.reverse: encfs += ['--reverse'] if not self.isConfigured(): encfs += ['--standard'] encfs += [self.path, self.currentMountpoint] logger.debug('Call mount command: %s' %' '.join(encfs), self) proc = subprocess.Popen(encfs, env = env, stdout = subprocess.PIPE, stderr = subprocess.STDOUT, universal_newlines = True) output = proc.communicate()[0] self.backupConfig() if proc.returncode: raise MountException( '{}:\n\n{}'.format( _("Unable to mount '{command}'") .format(command=' '.join(encfs)), output)) def preMountCheck(self, first_run=False): """Check what ever conditions must be given for the mount. Raises: Several exceptions. """ self.checkFuse() if first_run: self.checkVersion() return True def env(self): """ return environment with encfs configfile """ env = os.environ.copy() cfg = self.configFile() if os.path.isfile(cfg): env['ENCFS6_CONFIG'] = cfg return env def configFile(self): """ return encfs config file """ f = '.encfs6.xml' if self.config_path is None: cfg = os.path.join(self.path, f) else: cfg = os.path.join(self.config_path, f) return cfg def isConfigured(self): """ check if encfs config file exist. If not and if we are in settingsdialog ask for password confirmation. _mount will then create a new config """ cfg = self.configFile() if os.path.isfile(cfg): logger.debug(f'Found encfs config in {cfg}', self) return True else: logger.debug(f'No encfs config in {cfg}', self) msg = _('Configuration for the encrypted directory not found.') if not self.tmp_mount: raise MountException(msg) else: question = '{}\n{}'.format( msg, _('Create a new encrypted directory?') ) if not self.config.askQuestion(question): # TODO # This string can appear in a "critical" message dialog. # Let us know the steps to reproduce that behavior. raise MountException(_('Cancel')) else: pw = password.Password(self.config) password_confirm = pw.passwordFromUser( self.parent, prompt=_('Please confirm the password.')) if self.password == password_confirm: return False else: raise MountException(_("Password doesn't match.")) def checkVersion(self): """Check encfs version. 1.7.2 had a bug with --reverse that will create corrupt files Dev note (buhtz, 2024-05): Looking at upstream it seems that the 1.7.2 release was widthdrawn. The release before and after are from the year 2010. In consequence this code is definitely out dated and a candidate for removal. """ logger.debug('Check version', self) if self.reverse: proc = subprocess.Popen(['encfs', '--version'], stdout = subprocess.PIPE, stderr = subprocess.STDOUT, universal_newlines = True) output = proc.communicate()[0] m = re.search(r'(\d\.\d\.\d)', output) if m and Version(m.group(1)) <= Version('1.7.2'): logger.debug('Wrong encfs version %s' % m.group(1), self) raise MountException( 'encfs version 1.7.2 and before has a bug with ' 'option --reverse. Please update encfs.') def backupConfig(self): """ create a backup of encfs config file into local config folder so in cases of the config file get deleted or corrupt user can restore it from there """ cfg = self.configFile() if not os.path.isfile(cfg): logger.warning('No encfs config in %s. Skip backup of config file.' %cfg, self) return backup_folder = self.config.encfsconfigBackupFolder(self.profile_id) tools.makeDirs(backup_folder) old_backups = os.listdir(backup_folder) old_backups.sort(reverse = True) if len(old_backups): last_backup = os.path.join(backup_folder, old_backups[0]) #don't create a new backup if config hasn't changed if tools.md5sum(cfg) == \ tools.md5sum(last_backup): logger.debug('Encfs config did not change. Skip backup', self) return new_backup_file = '.'.join((os.path.basename(cfg), datetime.now().strftime('%Y%m%d%H%M'))) new_backup = os.path.join(backup_folder, new_backup_file) logger.debug('Create backup of encfs config %s to %s' %(cfg, new_backup), self) shutil.copy2(cfg, new_backup) class EncFS_SSH(EncFS_mount): """ Mount encrypted remote path with sshfs and encfs. Mount / with encfs --reverse. rsync will then sync the encrypted view on / to the remote path """ def __init__(self, cfg = None, profile_id = None, mode = None, parent = None,*args, **kwargs): self.config = cfg or config.Config() self.profile_id = profile_id or self.config.currentProfile() self.mode = mode if self.mode is None: self.mode = self.config.snapshotsMode(self.profile_id) self.parent = parent self.args = args self.kwargs = kwargs self.ssh = sshtools.SSH(*self.args, symlink = False, **self.splitKwargs('ssh')) self.rev_root = EncFS_mount(*self.args, symlink = False, **self.splitKwargs('encfs_reverse')) super(EncFS_SSH, self).__init__(*self.args, **self.splitKwargs('encfs')) def mount(self, *args, **kwargs): """ call mount for sshfs, encfs --reverse and encfs register 'encfsctl encode' in config.ENCODE """ logger.debug('Mount sshfs', self) self.ssh.mount(*args, **kwargs) #mount fsroot with encfs --reverse first. #If the config does not exist already this will make sure #the new created config works with --reverse if not os.path.isfile(self.configFile()): #encfs >= 1.8.0 changed behavior when ENCFS6_CONFIG environ variable #file does not exist. It will not create a new one anymore but just fail. #As encfs would create the config in /.encfs6.xml (which will most likely fail) #we need to mount a temp folder with reverse first and copy the config when done. logger.debug('Mount temp directory with encfs --reverse to create a new encfs config', self) with tempfile.TemporaryDirectory() as src: tmp_kwargs = self.splitKwargs('encfs_reverse') tmp_kwargs['path'] = src tmp_kwargs['config_path'] = src tmp_mount = EncFS_mount(*self.args, symlink = False, **tmp_kwargs) tmp_mount.mount(*args, **kwargs) tmp_mount.umount() cfg = tmp_mount.configFile() if os.path.isfile(cfg): logger.debug('Copy new encfs config %s to its original place %s' %(cfg, self.ssh.currentMountpoint), self) shutil.copy2(cfg, self.ssh.currentMountpoint) else: logger.error('New encfs config %s not found' %cfg, self) logger.debug('Mount local filesystem root with encfs --reverse', self) self.rev_root.mount(*args, **kwargs) logger.debug('Mount encfs', self) kwargs['check'] = False ret = super(EncFS_SSH, self).mount(*args, **kwargs) self.config.ENCODE = Encode(self) return ret def umount(self, *args, **kwargs): """ close 'encfsctl encode' process and set config.ENCODE back to the dummy class. call umount for encfs, encfs --reverse and sshfs """ self.config.ENCODE.close() self.config.ENCODE = Bounce() logger.debug('Unmount encfs', self) super(EncFS_SSH, self).umount(*args, **kwargs) logger.debug('Unmount local filesystem root mount encfs --reverse', self) self.rev_root.umount(*args, **kwargs) logger.debug('Unmount sshfs', self) self.ssh.umount(*args, **kwargs) def preMountCheck(self, *args, **kwargs): """Call preMountCheck for sshfs, encfs --reverse and encfs. """ if (self.ssh.preMountCheck(*args, **kwargs) and self.rev_root.preMountCheck(*args, **kwargs) and super(EncFS_SSH, self).preMountCheck(*args, **kwargs)): # Dev note (buhtz, 2024-09): Seems unnecessary. No one checks this # return value. return True def splitKwargs(self, mode): """ split all given arguments for the desired mount class """ d = self.kwargs.copy() d['cfg'] = self.config d['profile_id'] = self.profile_id d['mode'] = self.mode d['parent'] = self.parent if mode == 'ssh': if 'path' in d: d.pop('path') if 'ssh_path' in d: d['path'] = d.pop('ssh_path') if 'ssh_password' in d: d['password'] = d.pop('ssh_password') else: d['password'] = self.config.password(parent = self.parent, profile_id = self.profile_id, mode = self.mode) if 'hash_id' in d: d.pop('hash_id') if 'hash_id_2' in d: d['hash_id'] = d['hash_id_2'] return d elif mode == 'encfs': d['path'] = self.ssh.currentMountpoint d['hash_id_1'] = self.rev_root.hash_id d['hash_id_2'] = self.ssh.hash_id if 'encfs_password' in d: d['password'] = d.pop('encfs_password') else: d['password'] = self.config.password(parent = self.parent, profile_id = self.profile_id, mode = self.mode, pw_id = 2) return d elif mode == 'encfs_reverse': d['reverse'] = True d['path'] = '/' d['config_path'] = self.ssh.currentMountpoint if 'encfs_password' in d: d['password'] = d.pop('encfs_password') else: d['password'] = self.config.password(parent = self.parent, profile_id = self.profile_id, mode = self.mode, pw_id = 2) if 'hash_id' in d: d.pop('hash_id') if 'hash_id_1' in d: d['hash_id'] = d['hash_id_1'] return d class Encode: """ encode path with encfsctl. ENCFS_SSH will replace config.ENCODE with this """ def __init__(self, encfs): self.encfs = encfs self.password = self.encfs.password self.chroot = self.encfs.rev_root.currentMountpoint if not self.chroot[-1] == os.sep: self.chroot += os.sep self.remote_path = self.encfs.ssh.path if not self.remote_path[-1] == os.sep: self.remote_path += os.sep #precompile some regular expressions self.re_asterisk = re.compile(r'\*') self.re_separate_asterisk = re.compile(r'(.*?)(\*+)(.*)') def __del__(self): self.close() def startProcess(self): """ start 'encfsctl encode' process in pipe mode. """ thread = password_ipc.TempPasswordThread(self.password) env = self.encfs.env() env['ASKPASS_TEMP'] = thread.temp_file with thread.starter(): logger.debug('start \'encfsctl encode\' process', self) encfsctl = ['encfsctl', 'encode', '--extpass=backintime-askpass', '/'] logger.debug('Call command: %s' %' '.join(encfsctl), self) self.p = subprocess.Popen(encfsctl, env = env, bufsize = 0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines = True) def path(self, path): """ write plain path to encfsctl stdin and read encrypted path from stdout """ if not 'p' in vars(self): self.startProcess() if not self.p.returncode is None: logger.warning('\'encfsctl encode\' process terminated. Restarting.', self) del self.p self.startProcess() self.p.stdin.write(path + '\n') ret = self.p.stdout.readline().strip('\n') if not len(ret) and len(path): logger.debug('Failed to encode %s. Got empty string' %path, self) raise EncodeValueError() return ret def exclude(self, path): """ encrypt paths for snapshots.takeSnapshot exclude list. After encoding the path a wildcard would not match anymore so all paths with wildcards are ignored. Only single and double asterisk that will match a full file or folder name will work. """ if tools.patternHasNotEncryptableWildcard(path): return None enc = '' m = self.re_asterisk.search(path) if not m is None: path_ = path[:] while True: #search for foo/*, foo/*/bar, */bar or **/bar #but not foo* or foo/*bar m = self.re_separate_asterisk.search(path_) if m is None: return None if m.group(1): if not m.group(1).endswith(os.sep): return None enc = os.path.join(enc, self.path(m.group(1))) enc = os.path.join(enc, m.group(2)) if m.group(3): if not m.group(3).startswith(os.sep): return None m1 = self.re_asterisk.search(m.group(3)) if m1 is None: enc = os.path.join(enc, self.path(m.group(3))) break else: path_ = m.group(3) continue else: break else: enc = self.path(path) if os.path.isabs(path): return os.path.join(os.sep, enc) return enc def include(self, path): """ encrypt paths for snapshots.takeSnapshot include list. """ return os.path.join(os.sep, self.path(path)) def remote(self, path): """ encode the path on remote host starting from backintime/host/user/... """ enc_path = self.path(path[len(self.remote_path):]) return os.path.join(self.remote_path, enc_path) def close(self): """ stop encfsctl process """ if 'p' in vars(self) and self.p.returncode is None: logger.debug('stop \'encfsctl encode\' process', self) self.p.communicate() class Bounce: """ Dummy class that will simply return all input. This is the standard for config.ENCODE """ def __init__(self): self.chroot = os.sep def path(self, path): return path def exclude(self, path): return path def include(self, path): return path def remote(self, path): return path def close(self): pass class Decode: """ decode path with encfsctl. """ def __init__(self, cfg, string = True): self.config = cfg self.mode = cfg.snapshotsMode() if self.mode == 'local_encfs': self.password = cfg.password(pw_id = 1) elif self.mode == 'ssh_encfs': self.password = cfg.password(pw_id = 2) self.encfs = cfg.SNAPSHOT_MODES[self.mode][0](cfg) self.remote_path = cfg.sshSnapshotsPath() if not self.remote_path: self.remote_path = './' if not self.remote_path[-1] == os.sep: self.remote_path += os.sep # German translation changed from Snapshot to Schnappschuss. # Catch both variants otherwise old logs wouldn't get decoded. # Warning (2023-11): Do not modify the source string. # See #1559 for details. takeSnapshot = _('Take snapshot') \ .replace('Schnappschuss', '(?:Schnappschuss|Snapshot)') #precompile some regular expressions host, _post, user, path, _cipher = cfg.sshHostUserPortPathCipher() #replace: --exclude"" or --include"" self.re_include_exclude = re.compile( r'(--(?:ex|in)clude=")(.*?)(")') # codespell-ignore #replace: 'USER@HOST:"PATH"' self.re_remote_path = re.compile(r'(\'%s@%s:"%s)(.*?)("\')' %(user, host, path)) #replace: --link-dest="../../" self.re_link_dest = re.compile(r'(--link-dest="\.\./\.\./)(.*?)(")') #search for: [C] self.re_change = re.compile(r'(^\[C\] .{11} )(.*)') #search for: [I] Take snapshot (rsync: BACKINTIME: ) # [I] Take snapshot (rsync: deleting ) # [I] Take snapshot (rsync: rsync: readlink_stat("...mountpoint/") # [I] Take snapshot (rsync: rsync: send_files failed to open "...mountpoint/": Permission denied (13)) # [I] Take snapshot (rsync: file has vanished: "...mountpoint/") # [I] Take snapshot (rsync: ) pattern = [] pattern.append(r' BACKINTIME: .{11} ') pattern.append(r' deleting ') pattern.append(r' rsync: readlink_stat\(".*?mountpoint/') pattern.append(r' rsync: send_files failed to open ".*?mountpoint/') pattern.append(r' file has vanished: ".*?mountpoint/') pattern.append(r' ') self.re_info = re.compile(r'(^(?:\[I\] )?%s \(rsync:(?:%s))(.*?)(\).*|".*)' % (takeSnapshot, '|'.join(pattern))) #search for: [E] Error: rsync readlink_stat("...mountpoint/") # [E] Error: rsync: send_files failed to open "...mountpoint/": Permission denied (13) # [E] Error: rsync: recv_generator: failed to stat "/": File name too long (36) # [E] Error: rsync: recv_generator: mkdir "/": File name too long (36) pattern = [] pattern.append(r' rsync: readlink_stat\(".*?mountpoint/') pattern.append(r' rsync: send_files failed to open ".*?mountpoint/') if self.remote_path == './': pattern.append(r' rsync: recv_generator: failed to stat "/home/[^/]*/') pattern.append(r' rsync: recv_generator: mkdir "/home/[^/]*/') else: pattern.append(r' rsync: recv_generator: failed to stat ".*?{}'.format(self.remote_path)) pattern.append(r' rsync: recv_generator: mkdir ".*?{}'.format(self.remote_path)) pattern.append(r' rsync: .*?".*?mountpoint/') self.re_error = re.compile(r'(^(?:\[E\] )?Error:(?:%s))(.*?)(".*)' % '|'.join(pattern)) #search for: [I] ssh USER@HOST cp -aRl "PATH"* "PATH" self.re_info_cp= re.compile(r'(^\[I\] .*? cp -aRl "%s/)(.*?)("\* "%s/)(.*?)(")' % (path, path)) #search for all chars except * self.re_all_except_asterisk = re.compile(r'[^\*]+') #search for: -> self.re_all_except_arrow = re.compile(r'(.*?)((?: [-=]> )+)(.*)') #skip: [I] Take snapshot (rsync: sending incremental file list) # [I] Take snapshot (rsync: building file list ... done) # [I] Take snapshot (rsync: sent 26569703 bytes received 239616 bytes 85244.26 bytes/sec) # [I] Take snapshot (rsync: total size is 9130263449 speedup is 340.56) # [I] Take snapshot (rsync: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1070) [sender=3.0.9]) # [I] Take snapshot (rsync: rsync warning: some files vanished before they could be transferred (code 24) at main.c(1070) [sender=3.0.9]) pattern = [] pattern.append(r'sending incremental file list') pattern.append(r'building file list ... done') pattern.append(r'sent .*? received') pattern.append(r'total size is .*? speedup is') pattern.append(r'rsync error: some files/attrs were not transferred') pattern.append(r'rsync warning: some files vanished before they could be transferred') self.re_skip = re.compile(r'^(?:\[I\] )?%s \(rsync: (%s)' % (takeSnapshot, '|'.join(pattern))) self.string = string if string: self.newline = '\n' else: self.newline = b'\n' def __del__(self): self.close() def startProcess(self): """ start 'encfsctl decode' process in pipe mode. """ thread = password_ipc.TempPasswordThread(self.password) env = os.environ.copy() env['ASKPASS_TEMP'] = thread.temp_file with thread.starter(): logger.debug('start \'encfsctl decode\' process', self) encfsctl = ['encfsctl', 'decode', '--extpass=backintime-askpass', self.encfs.path] logger.debug('Call command: %s' %' '.join(encfsctl), self) self.p = subprocess.Popen(encfsctl, env = env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines = self.string, #return string (if True) or bytes bufsize = 0) def path(self, path): """ write encrypted path to encfsctl stdin and read plain path from stdout if stdout is empty (most likely because there was an error) return crypt path """ if self.string: assert isinstance(path, str), 'path is not str type: %s' % path else: assert isinstance(path, bytes), 'path is not bytes type: %s' % path if not 'p' in vars(self): self.startProcess() if not self.p.returncode is None: logger.warning('\'encfsctl decode\' process terminated. Restarting.', self) del self.p self.startProcess() self.p.stdin.write(path + self.newline) ret = self.p.stdout.readline() ret = ret.strip(self.newline) if ret: return ret return path #TODO: rename this, 'list' is corrupting sphinx doc def list(self, list_): """ decode a list of paths """ output = [] for path in list_: output.append(self.path(path)) return output def log(self, line): """ decode paths in takesnapshot.log """ #rsync cmd if line.startswith('[I] rsync') or line.startswith('[I] nocache rsync'): line = self.re_include_exclude.sub(self.replace, line) line = self.re_remote_path.sub(self.replace, line) line = self.re_link_dest.sub(self.replace, line) return line #[C] Change lines m = self.re_change.match(line) if not m is None: return m.group(1) + self.pathWithArrow(m.group(2)) #[I] Information lines m = self.re_skip.match(line) if not m is None: return line m = self.re_info.match(line) if not m is None: return m.group(1) + self.pathWithArrow(m.group(2)) + m.group(3) #[E] Error lines m = self.re_error.match(line) if not m is None: return m.group(1) + self.path(m.group(2)) + m.group(3) #cp cmd m = self.re_info_cp.match(line) if not m is None: return m.group(1) + self.path(m.group(2)) + m.group(3) + self.path(m.group(4)) + m.group(5) return line def replace(self, m): """ return decoded string for re.sub """ decrypt = self.re_all_except_asterisk.sub(self.pathMatch, m.group(2)) if os.path.isabs(m.group(2)): decrypt = os.path.join(os.sep, decrypt) return m.group(1) + decrypt + m.group(3) def pathMatch(self, m): """ return decoded path of a match object """ return self.path(m.group(0)) def pathWithArrow(self, path): """ rsync print symlinks like 'dest -> src'. This will decode both and also normal paths """ m = self.re_all_except_arrow.match(path) if not m is None: return self.path(m.group(1)) + m.group(2) + self.path(m.group(3)) else: return self.path(path) def remote(self, path): """ decode the path on remote host starting from backintime/host/user/... """ assert isinstance(path, bytes), 'path is not bytes type: %s' % path remote_path = self.remote_path.encode() dec_path = self.path(path[len(remote_path):]) return os.path.join(remote_path, dec_path) def close(self): """ stop encfsctl process """ if 'p' in vars(self) and self.p.returncode is None: logger.debug('stop \'encfsctl decode\' process', self) self.p.communicate() backintime-1.5.4/common/exceptions.py000066400000000000000000000025011477034762000176620ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2015-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . class BackInTimeException(Exception): pass class MountException(BackInTimeException): pass class NoPubKeyLogin(MountException): pass class KnownHost(MountException): pass class HashCollision(BackInTimeException): pass class EncodeValueError(BackInTimeException): pass class StopException(BackInTimeException): pass class Timeout(BackInTimeException): pass class LastSnapshotSymlink(BackInTimeException): pass class InvalidChar(BackInTimeException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg class InvalidCmd(BackInTimeException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg class LimitExceeded(BackInTimeException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg class PermissionDeniedByPolicy(BackInTimeException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg backintime-1.5.4/common/flock.py000066400000000000000000000137641477034762000166140ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Manage file lock. Offer context managers to manage file lock (flock) files. """ import os import fcntl from pathlib import Path import logger class _FlockContext: """Context manager to manage file locks (flock). It will be tried to establish a multi-user file lock; if not feasible a single-user file lock will be used. It depends on the GNU/Linux distribution used and the write permissions to the file lock locations in the file system. Usage example :: class MyFlock(_FlockContext): def __init__(self): super().__init__('my.lock') with MyFlock(): do_fancy_things() The following directories will be checked in sequence to determine if they exist, if a file lock file exists within them, or if there are sufficient permissions to create such a file within them. :: /run/lock /var/lock /run/user// ~/.cache The first and second directory in that list is for multi-user file lock. To the experience of the developers on Debian-based distributions there is no problem having a multi-user file lock. But on Arch-based distributions only a user with root privileges is able to do it. Because of that on Arch a single-user file lock is used by default until Back In Time is started once as root. """ def __init__(self, filename: str, disable: bool = False): """Check if an flock file can be used or created. See the classes documentation about details. Args: filename: The filename (without path) used for the flock file. disabled: Disable the whole context managers behavior. This is a workaround. See #1751 and :func:``Snapshots.backup()`` for details. Raises: RuntimeError: If it wasn't possible to use """ self._file_path = None """Full path used for the flock file""" self._flock_handle = None """File handle (descriptor) to the flock file.""" # Workaround for #1751. Remove after refactoring Snapshots.backup() if disable: return None folder = Path(Path.cwd().root) / 'run' / 'lock' if not folder.exists(): # On older systems folder = Path(Path.cwd().root) / 'var' / 'lock' self._file_path = folder / filename if self._can_use_file(self._file_path): return None # Try user specific file lock # e.g. /run/user/ self._file_path = Path( os.environ.get('XDG_RUNTIME_DIR', f'/run/user/{os.getuid()}') ) / filename if self._can_use_file(self._file_path): return None # At last, try users cache dir. self._file_path = Path( os.environ.get('XDG_CACHE_HOME', Path.home() / '.cache') ) / filename if self._can_use_file(self._file_path): return None raise RuntimeError( f'Can not establish global flock file {self._file_path}') def _can_use_file(self, file_path: Path) -> bool: """Check if ``file_path`` is usable as an flock file. The answer is ``True`` if the file exists without checking its permissions. If not the file will be created and if successful ``True`` will be returned. Returns: bool: The answer. Raises: PermissionError: Not enough permissions to create the file. Exception: Any other error. """ if file_path.exists(): return True # Try to create it try: file_path.touch(mode=0o666) except PermissionError: logger.debug(f'Cannot use file lock on {file_path}.') except Exception as err: logger.error( f'Unknown error while testing file lock on {file_path}. ' f'Please open a bug report. Error was {err}.') else: logger.debug(f'Use {file_path} for file lock.') return True return False def __enter__(self): """Request an exclucive file lock on :data:``self._file_path``. """ # Workaround for #1751. Remove after refactoring Snapshots.backup() # See __init__() for details if self._file_path is None: return None self._log('Set') # Open file for reading self._flock_handle = self._file_path.open(mode='r') # blocks (waits) until an existing flock is released fcntl.flock(self._flock_handle, fcntl.LOCK_EX) return self def __exit__(self, exc_type, exc_value, exc_tb): # Workaround for #1751. Remove after refactoring Snapshots.backup() # See __init__() for details if self._flock_handle is None: return None self._log('Release') fcntl.fcntl(self._flock_handle, fcntl.LOCK_UN) self._flock_handle.close() def _log(self, prefix: str): """Generate a log message including the current lock files path and the process ID. Args: prefix: Used in front of the log message. """ logger.debug(f'{prefix} flock {self._file_path} by PID {os.getpid()}') class GlobalFlock(_FlockContext): """Context manager used for global file lock in Back In Time. If it is a multi-user or single-user flock depends on the several aspects. See :class:`_FlockContext` for details. """ def __init__(self, disable: bool = False): """See :func:`_FlockContext.__init__()` for details. """ super().__init__('backintime.lock', disable=disable) backintime-1.5.4/common/guiapplicationinstance.py000066400000000000000000000043311477034762000222410ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import logger from applicationinstance import ApplicationInstance class GUIApplicationInstance(ApplicationInstance): """Handle one application instance mechanism. """ def __init__(self, baseControlFile, raiseCmd=''): """Specify the base for control files.""" self.raiseFile = baseControlFile + '.raise' self.raiseCmd = raiseCmd super(GUIApplicationInstance, self).__init__( baseControlFile + '.pid', False, False) # Remove raiseFile is already exists if os.path.exists(self.raiseFile): os.remove(self.raiseFile) self.check() self.startApplication() def check(self): """Check if the current application is already running.""" ret = super(GUIApplicationInstance, self).check(False) if not ret: print(f'The application is already running. (pid: {self.pid})') # Notify raise try: with open(self.raiseFile, 'wt') as f: f.write(self.raiseCmd) except OSError as e: logger.error(f'Failed to write raise file {e.filename}: ' f'[{e.errno}] {e.strerror}') # Exit raise an exception so don't put it in a try/except block exit(0) else: return ret def raiseCommand(self): """ check if the application must to be raised return None if no raise needed, or a string command to raise """ ret_val = None try: if os.path.isfile(self.raiseFile): with open(self.raiseFile, 'rt') as f: ret_val = f.read() os.remove(self.raiseFile) except: pass return ret_val backintime-1.5.4/common/languages.py000066400000000000000000002133351477034762000174600ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . # # Generated at Sun Mar 23 19:11:52 2025 with help # of package "babel" and "polib". # https://babel.pocoo.org # https://github.com/python-babel/babel # pylint: disable=too-many-lines,missing-module-docstring names = { 'ar': { '_native': 'العربية', 'ar': 'العربية', 'bg': 'арабски', 'bs': 'arapski', 'ca': 'àrab', 'cs': 'arabština', 'da': 'arabisk', 'de': 'Arabisch', 'el': 'Αραβικά', 'en': 'Arabic', 'eo': 'araba', 'es': 'árabe', 'et': 'araabia', 'eu': 'arabiera', 'fa': 'عربی', 'fi': 'arabia', 'fo': 'arabiskt', 'fr': 'arabe', 'gl': 'árabe', 'he': 'ערבית', 'hr': 'arapski', 'hu': 'arab', 'id': 'Arab', 'ie': 'arabic', 'is': 'arabíska', 'it': 'arabo', 'ja': 'アラビア語', 'ko': '아랍어', 'lt': 'arabų', 'nb': 'arabisk', 'nl': 'Arabisch', 'nn': 'arabisk', 'pl': 'arabski', 'pt': 'árabe', 'pt_BR': 'árabe', 'ro': 'arabă', 'ru': 'арабский', 'sk': 'arabčina', 'sl': 'arabščina', 'sr': 'арапски', 'sr_Latn': 'arapski', 'sv': 'arabiska', 'th': 'อาหรับ', 'tr': 'Arapça', 'uk': 'арабська', 'vi': 'Tiếng Ả Rập', 'zh_CN': '阿拉伯语', 'zh_TW': '阿拉伯文', }, 'bg': { '_native': 'български', 'ar': 'البلغارية', 'bg': 'български', 'bs': 'bugarski', 'ca': 'búlgar', 'cs': 'bulharština', 'da': 'bulgarsk', 'de': 'Bulgarisch', 'el': 'Βουλγαρικά', 'en': 'Bulgarian', 'eo': 'bulgara', 'es': 'búlgaro', 'et': 'bulgaaria', 'eu': 'bulgariera', 'fa': 'بلغاری', 'fi': 'bulgaria', 'fo': 'bulgarskt', 'fr': 'bulgare', 'gl': 'búlgaro', 'he': 'בולגרית', 'hr': 'bugarski', 'hu': 'bolgár', 'id': 'Bulgaria', 'ie': 'bulgarian', 'is': 'búlgarska', 'it': 'bulgaro', 'ja': 'ブルガリア語', 'ko': '불가리아어', 'lt': 'bulgarų', 'nb': 'bulgarsk', 'nl': 'Bulgaars', 'nn': 'bulgarsk', 'pl': 'bułgarski', 'pt': 'búlgaro', 'pt_BR': 'búlgaro', 'ro': 'bulgară', 'ru': 'болгарский', 'sk': 'bulharčina', 'sl': 'bolgarščina', 'sr': 'бугарски', 'sr_Latn': 'bugarski', 'sv': 'bulgariska', 'th': 'บัลแกเรีย', 'tr': 'Bulgarca', 'uk': 'болгарська', 'vi': 'Tiếng Bulgaria', 'zh_CN': '保加利亚语', 'zh_TW': '保加利亞文', }, 'bs': { '_native': 'bosanski', 'ar': 'البوسنية', 'bg': 'босненски', 'bs': 'bosanski', 'ca': 'bosnià', 'cs': 'bosenština', 'da': 'bosnisk', 'de': 'Bosnisch', 'el': 'Βοσνιακά', 'en': 'Bosnian', 'eo': 'bosna', 'es': 'bosnio', 'et': 'bosnia', 'eu': 'bosniera', 'fa': 'بوسنیایی', 'fi': 'bosnia', 'fo': 'bosniskt', 'fr': 'bosniaque', 'gl': 'bosníaco', 'he': 'בוסנית', 'hr': 'bosanski', 'hu': 'bosnyák', 'id': 'Bosnia', 'ie': 'bosnian', 'is': 'bosníska', 'it': 'bosniaco', 'ja': 'ボスニア語', 'ko': '보스니아어', 'lt': 'bosnių', 'nb': 'bosnisk', 'nl': 'Bosnisch', 'nn': 'bosnisk', 'pl': 'bośniacki', 'pt': 'bósnio', 'pt_BR': 'bósnio', 'ro': 'bosniacă', 'ru': 'боснийский', 'sk': 'bosniačtina', 'sl': 'bosanščina', 'sr': 'босански', 'sr_Latn': 'bosanski', 'sv': 'bosniska', 'th': 'บอสเนีย', 'tr': 'Boşnakça', 'uk': 'боснійська', 'vi': 'Tiếng Bosnia', 'zh_CN': '波斯尼亚语', 'zh_TW': '波士尼亞文', }, 'ca': { '_native': 'català', 'ar': 'الكتالانية', 'bg': 'каталонски', 'bs': 'katalonski', 'ca': 'català', 'cs': 'katalánština', 'da': 'catalansk', 'de': 'Katalanisch', 'el': 'Καταλανικά', 'en': 'Catalan', 'eo': 'kataluna', 'es': 'catalán', 'et': 'katalaani', 'eu': 'katalana', 'fa': 'کاتالان', 'fi': 'katalaani', 'fo': 'katalani', 'fr': 'catalan', 'gl': 'catalán', 'he': 'קטלאנית', 'hr': 'katalonski', 'hu': 'katalán', 'id': 'Katalan', 'ie': 'catalan', 'is': 'katalónska', 'it': 'catalano', 'ja': 'カタロニア語', 'ko': '카탈로니아어', 'lt': 'katalonų', 'nb': 'katalansk', 'nl': 'Catalaans', 'nn': 'katalansk', 'pl': 'kataloński', 'pt': 'catalão', 'pt_BR': 'catalão', 'ro': 'catalană', 'ru': 'каталанский', 'sk': 'katalánčina', 'sl': 'katalonščina', 'sr': 'каталонски', 'sr_Latn': 'katalonski', 'sv': 'katalanska', 'th': 'คาตาลัน', 'tr': 'Katalanca', 'uk': 'каталонська', 'vi': 'Tiếng Catalan', 'zh_CN': '加泰罗尼亚语', 'zh_TW': '加泰蘭文', }, 'cs': { '_native': 'čeština', 'ar': 'التشيكية', 'bg': 'чешки', 'bs': 'češki', 'ca': 'txec', 'cs': 'čeština', 'da': 'tjekkisk', 'de': 'Tschechisch', 'el': 'Τσεχικά', 'en': 'Czech', 'eo': 'ĉeĥa', 'es': 'checo', 'et': 'tšehhi', 'eu': 'txekiera', 'fa': 'چکی', 'fi': 'tšekki', 'fo': 'kekkiskt', 'fr': 'tchèque', 'gl': 'checo', 'he': 'צ׳כית', 'hr': 'češki', 'hu': 'cseh', 'id': 'Cheska', 'ie': 'tchec', 'is': 'tékkneska', 'it': 'ceco', 'ja': 'チェコ語', 'ko': '체코어', 'lt': 'čekų', 'nb': 'tsjekkisk', 'nl': 'Tsjechisch', 'nn': 'tsjekkisk', 'pl': 'czeski', 'pt': 'tcheco', 'pt_BR': 'tcheco', 'ro': 'cehă', 'ru': 'чешский', 'sk': 'čeština', 'sl': 'češčina', 'sr': 'чешки', 'sr_Latn': 'češki', 'sv': 'tjeckiska', 'th': 'เช็ก', 'tr': 'Çekçe', 'uk': 'чеська', 'vi': 'Tiếng Séc', 'zh_CN': '捷克语', 'zh_TW': '捷克文', }, 'da': { '_native': 'dansk', 'ar': 'الدانمركية', 'bg': 'датски', 'bs': 'danski', 'ca': 'danès', 'cs': 'dánština', 'da': 'dansk', 'de': 'Dänisch', 'el': 'Δανικά', 'en': 'Danish', 'eo': 'dana', 'es': 'danés', 'et': 'taani', 'eu': 'daniera', 'fa': 'دانمارکی', 'fi': 'tanska', 'fo': 'danskt', 'fr': 'danois', 'gl': 'dinamarqués', 'he': 'דנית', 'hr': 'danski', 'hu': 'dán', 'id': 'Dansk', 'ie': 'danesi', 'is': 'danska', 'it': 'danese', 'ja': 'デンマーク語', 'ko': '덴마크어', 'lt': 'danų', 'nb': 'dansk', 'nl': 'Deens', 'nn': 'dansk', 'pl': 'duński', 'pt': 'dinamarquês', 'pt_BR': 'dinamarquês', 'ro': 'daneză', 'ru': 'датский', 'sk': 'dánčina', 'sl': 'danščina', 'sr': 'дански', 'sr_Latn': 'danski', 'sv': 'danska', 'th': 'เดนมาร์ก', 'tr': 'Danca', 'uk': 'данська', 'vi': 'Tiếng Đan Mạch', 'zh_CN': '丹麦语', 'zh_TW': '丹麥文', }, 'de': { '_native': 'Deutsch', 'ar': 'الألمانية', 'bg': 'немски', 'bs': 'njemački', 'ca': 'alemany', 'cs': 'němčina', 'da': 'tysk', 'de': 'Deutsch', 'el': 'Γερμανικά', 'en': 'German', 'eo': 'germana', 'es': 'alemán', 'et': 'saksa', 'eu': 'alemana', 'fa': 'آلمانی', 'fi': 'saksa', 'fo': 'týskt', 'fr': 'allemand', 'gl': 'alemán', 'he': 'גרמנית', 'hr': 'njemački', 'hu': 'német', 'id': 'Jerman', 'ie': 'german', 'is': 'þýska', 'it': 'tedesco', 'ja': 'ドイツ語', 'ko': '독일어', 'lt': 'vokiečių', 'nb': 'tysk', 'nl': 'Duits', 'nn': 'tysk', 'pl': 'niemiecki', 'pt': 'alemão', 'pt_BR': 'alemão', 'ro': 'germană', 'ru': 'немецкий', 'sk': 'nemčina', 'sl': 'nemščina', 'sr': 'немачки', 'sr_Latn': 'nemački', 'sv': 'tyska', 'th': 'เยอรมัน', 'tr': 'Almanca', 'uk': 'німецька', 'vi': 'Tiếng Đức', 'zh_CN': '德语', 'zh_TW': '德文', }, 'el': { '_native': 'Ελληνικά', 'ar': 'اليونانية', 'bg': 'гръцки', 'bs': 'grčki', 'ca': 'grec', 'cs': 'řečtina', 'da': 'græsk', 'de': 'Griechisch', 'el': 'Ελληνικά', 'en': 'Greek', 'eo': 'greka', 'es': 'griego', 'et': 'kreeka', 'eu': 'greziera', 'fa': 'یونانی', 'fi': 'kreikka', 'fo': 'grikskt', 'fr': 'grec', 'gl': 'grego', 'he': 'יוונית', 'hr': 'grčki', 'hu': 'görög', 'id': 'Yunani', 'ie': 'grec', 'is': 'gríska', 'it': 'greco', 'ja': 'ギリシャ語', 'ko': '그리스어', 'lt': 'graikų', 'nb': 'gresk', 'nl': 'Grieks', 'nn': 'gresk', 'pl': 'grecki', 'pt': 'grego', 'pt_BR': 'grego', 'ro': 'greacă', 'ru': 'греческий', 'sk': 'gréčtina', 'sl': 'grščina', 'sr': 'грчки', 'sr_Latn': 'grčki', 'sv': 'grekiska', 'th': 'กรีก', 'tr': 'Yunanca', 'uk': 'грецька', 'vi': 'Tiếng Hy Lạp', 'zh_CN': '希腊语', 'zh_TW': '希臘文', }, 'en': { '_native': 'English', 'ar': 'الإنجليزية', 'bg': 'английски', 'bs': 'engleski', 'ca': 'anglès', 'cs': 'angličtina', 'da': 'engelsk', 'de': 'Englisch', 'el': 'Αγγλικά', 'en': 'English', 'eo': 'angla', 'es': 'inglés', 'et': 'inglise', 'eu': 'ingelesa', 'fa': 'انگلیسی', 'fi': 'englanti', 'fo': 'enskt', 'fr': 'anglais', 'gl': 'inglés', 'he': 'אנגלית', 'hr': 'engleski', 'hu': 'angol', 'id': 'Inggris', 'ie': 'anglesi', 'is': 'enska', 'it': 'inglese', 'ja': '英語', 'ko': '영어', 'lt': 'anglų', 'nb': 'engelsk', 'nl': 'Engels', 'nn': 'engelsk', 'pl': 'angielski', 'pt': 'inglês', 'pt_BR': 'inglês', 'ro': 'engleză', 'ru': 'английский', 'sk': 'angličtina', 'sl': 'angleščina', 'sr': 'енглески', 'sr_Latn': 'engleski', 'sv': 'engelska', 'th': 'อังกฤษ', 'tr': 'İngilizce', 'uk': 'англійська', 'vi': 'Tiếng Anh', 'zh_CN': '英语', 'zh_TW': '英文', }, 'eo': { '_native': 'Esperanto', 'ar': 'الإسبرانتو', 'bg': 'есперанто', 'bs': 'esperanto', 'ca': 'esperanto', 'cs': 'esperanto', 'da': 'esperanto', 'de': 'Esperanto', 'el': 'Εσπεράντο', 'en': 'Esperanto', 'eo': 'Esperanto', 'es': 'esperanto', 'et': 'esperanto', 'eu': 'esperantoa', 'fa': 'اسپرانتو', 'fi': 'esperanto', 'fo': 'esperanto', 'fr': 'espéranto', 'gl': 'esperanto', 'he': 'אספרנטו', 'hr': 'esperanto', 'hu': 'eszperantó', 'id': 'Esperanto', 'ie': 'Esperanto', 'is': 'esperantó', 'it': 'esperanto', 'ja': 'エスペラント語', 'ko': '에스페란토어', 'lt': 'esperanto', 'nb': 'esperanto', 'nl': 'Esperanto', 'nn': 'esperanto', 'pl': 'esperanto', 'pt': 'esperanto', 'pt_BR': 'esperanto', 'ro': 'esperanto', 'ru': 'эсперанто', 'sk': 'esperanto', 'sl': 'esperanto', 'sr': 'есперанто', 'sr_Latn': 'esperanto', 'sv': 'esperanto', 'th': 'เอสเปรันโต', 'tr': 'Esperanto', 'uk': 'есперанто', 'vi': 'Tiếng Quốc Tế Ngữ', 'zh_CN': '世界语', 'zh_TW': '世界文', }, 'es': { '_native': 'español', 'ar': 'الإسبانية', 'bg': 'испански', 'bs': 'španski', 'ca': 'espanyol', 'cs': 'španělština', 'da': 'spansk', 'de': 'Spanisch', 'el': 'Ισπανικά', 'en': 'Spanish', 'eo': 'hispana', 'es': 'español', 'et': 'hispaania', 'eu': 'gaztelania', 'fa': 'اسپانیایی', 'fi': 'espanja', 'fo': 'spanskt', 'fr': 'espagnol', 'gl': 'español', 'he': 'ספרדית', 'hr': 'španjolski', 'hu': 'spanyol', 'id': 'Spanyol', 'ie': 'hispan', 'is': 'spænska', 'it': 'spagnolo', 'ja': 'スペイン語', 'ko': '스페인어', 'lt': 'ispanų', 'nb': 'spansk', 'nl': 'Spaans', 'nn': 'spansk', 'pl': 'hiszpański', 'pt': 'espanhol', 'pt_BR': 'espanhol', 'ro': 'spaniolă', 'ru': 'испанский', 'sk': 'španielčina', 'sl': 'španščina', 'sr': 'шпански', 'sr_Latn': 'španski', 'sv': 'spanska', 'th': 'สเปน', 'tr': 'İspanyolca', 'uk': 'іспанська', 'vi': 'Tiếng Tây Ban Nha', 'zh_CN': '西班牙语', 'zh_TW': '西班牙文', }, 'et': { '_native': 'eesti', 'ar': 'الإستونية', 'bg': 'естонски', 'bs': 'estonski', 'ca': 'estonià', 'cs': 'estonština', 'da': 'estisk', 'de': 'Estnisch', 'el': 'Εσθονικά', 'en': 'Estonian', 'eo': 'estona', 'es': 'estonio', 'et': 'eesti', 'eu': 'estoniera', 'fa': 'استونیایی', 'fi': 'viro', 'fo': 'estiskt', 'fr': 'estonien', 'gl': 'estoniano', 'he': 'אסטונית', 'hr': 'estonski', 'hu': 'észt', 'id': 'Esti', 'ie': 'estonian', 'is': 'eistneska', 'it': 'estone', 'ja': 'エストニア語', 'ko': '에스토니아어', 'lt': 'estų', 'nb': 'estisk', 'nl': 'Estisch', 'nn': 'estisk', 'pl': 'estoński', 'pt': 'estoniano', 'pt_BR': 'estoniano', 'ro': 'estonă', 'ru': 'эстонский', 'sk': 'estónčina', 'sl': 'estonščina', 'sr': 'естонски', 'sr_Latn': 'estonski', 'sv': 'estniska', 'th': 'เอสโตเนีย', 'tr': 'Estonca', 'uk': 'естонська', 'vi': 'Tiếng Estonia', 'zh_CN': '爱沙尼亚语', 'zh_TW': '愛沙尼亞文', }, 'eu': { '_native': 'euskara', 'ar': 'الباسكية', 'bg': 'баски', 'bs': 'baskijski', 'ca': 'basc', 'cs': 'baskičtina', 'da': 'baskisk', 'de': 'Baskisch', 'el': 'Βασκικά', 'en': 'Basque', 'eo': 'eŭska', 'es': 'euskera', 'et': 'baski', 'eu': 'euskara', 'fa': 'باسکی', 'fi': 'baski', 'fo': 'baskiskt', 'fr': 'basque', 'gl': 'éuscaro', 'he': 'בסקית', 'hr': 'baskijski', 'hu': 'baszk', 'id': 'Basque', 'ie': 'basc', 'is': 'baskneska', 'it': 'basco', 'ja': 'バスク語', 'ko': '바스크어', 'lt': 'baskų', 'nb': 'baskisk', 'nl': 'Baskisch', 'nn': 'baskisk', 'pl': 'baskijski', 'pt': 'basco', 'pt_BR': 'basco', 'ro': 'bască', 'ru': 'баскский', 'sk': 'baskičtina', 'sl': 'baskovščina', 'sr': 'баскијски', 'sr_Latn': 'baskijski', 'sv': 'baskiska', 'th': 'บาสก์', 'tr': 'Baskça', 'uk': 'баскська', 'vi': 'Tiếng Basque', 'zh_CN': '巴斯克语', 'zh_TW': '巴斯克文', }, 'fa': { '_native': 'فارسی', 'ar': 'الفارسية', 'bg': 'персийски', 'bs': 'perzijski', 'ca': 'persa', 'cs': 'perština', 'da': 'persisk', 'de': 'Persisch', 'el': 'Περσικά', 'en': 'Persian', 'eo': 'persa', 'es': 'persa', 'et': 'pärsia', 'eu': 'persiera', 'fa': 'فارسی', 'fi': 'persia', 'fo': 'persiskt', 'fr': 'persan', 'gl': 'persa', 'he': 'פרסית', 'hr': 'perzijski', 'hu': 'perzsa', 'id': 'Persia', 'ie': 'persian', 'is': 'persneska', 'it': 'persiano', 'ja': 'ペルシア語', 'ko': '페르시아어', 'lt': 'persų', 'nb': 'persisk', 'nl': 'Perzisch', 'nn': 'persisk', 'pl': 'perski', 'pt': 'persa', 'pt_BR': 'persa', 'ro': 'persană', 'ru': 'персидский', 'sk': 'perzština', 'sl': 'perzijščina', 'sr': 'персијски', 'sr_Latn': 'persijski', 'sv': 'persiska', 'th': 'เปอร์เซีย', 'tr': 'Farsça', 'uk': 'перська', 'vi': 'Tiếng Ba Tư', 'zh_CN': '波斯语', 'zh_TW': '波斯文', }, 'fi': { '_native': 'suomi', 'ar': 'الفنلندية', 'bg': 'фински', 'bs': 'finski', 'ca': 'finès', 'cs': 'finština', 'da': 'finsk', 'de': 'Finnisch', 'el': 'Φινλανδικά', 'en': 'Finnish', 'eo': 'finna', 'es': 'finés', 'et': 'soome', 'eu': 'finlandiera', 'fa': 'فنلاندی', 'fi': 'suomi', 'fo': 'finskt', 'fr': 'finnois', 'gl': 'finés', 'he': 'פינית', 'hr': 'finski', 'hu': 'finn', 'id': 'Suomi', 'ie': 'finn', 'is': 'finnska', 'it': 'finlandese', 'ja': 'フィンランド語', 'ko': '핀란드어', 'lt': 'suomių', 'nb': 'finsk', 'nl': 'Fins', 'nn': 'finsk', 'pl': 'fiński', 'pt': 'finlandês', 'pt_BR': 'finlandês', 'ro': 'finlandeză', 'ru': 'финский', 'sk': 'fínčina', 'sl': 'finščina', 'sr': 'фински', 'sr_Latn': 'finski', 'sv': 'finska', 'th': 'ฟินแลนด์', 'tr': 'Fince', 'uk': 'фінська', 'vi': 'Tiếng Phần Lan', 'zh_CN': '芬兰语', 'zh_TW': '芬蘭文', }, 'fo': { '_native': 'føroyskt', 'ar': 'الفاروية', 'bg': 'фарьорски', 'bs': 'farski', 'ca': 'feroès', 'cs': 'faerština', 'da': 'færøsk', 'de': 'Färöisch', 'el': 'Φεροϊκά', 'en': 'Faroese', 'eo': 'feroa', 'es': 'feroés', 'et': 'fääri', 'eu': 'faroera', 'fa': 'فارویی', 'fi': 'fääri', 'fo': 'føroyskt', 'fr': 'féroïen', 'gl': 'feroés', 'he': 'פארואזית', 'hr': 'ferojski', 'hu': 'feröeri', 'id': 'Faroe', 'ie': 'feroesi', 'is': 'færeyska', 'it': 'faroese', 'ja': 'フェロー語', 'ko': '페로어', 'lt': 'farerų', 'nb': 'færøysk', 'nl': 'Faeröers', 'nn': 'færøysk', 'pl': 'farerski', 'pt': 'feroês', 'pt_BR': 'feroês', 'ro': 'feroeză', 'ru': 'фарерский', 'sk': 'faerčina', 'sl': 'ferščina', 'sr': 'фарски', 'sr_Latn': 'farski', 'sv': 'färöiska', 'th': 'แฟโร', 'tr': 'Faroe dili', 'uk': 'фарерська', 'vi': 'Tiếng Faroe', 'zh_CN': '法罗语', 'zh_TW': '法羅文', }, 'fr': { '_native': 'français', 'ar': 'الفرنسية', 'bg': 'френски', 'bs': 'francuski', 'ca': 'francès', 'cs': 'francouzština', 'da': 'fransk', 'de': 'Französisch', 'el': 'Γαλλικά', 'en': 'French', 'eo': 'franca', 'es': 'francés', 'et': 'prantsuse', 'eu': 'frantsesa', 'fa': 'فرانسوی', 'fi': 'ranska', 'fo': 'franskt', 'fr': 'français', 'gl': 'francés', 'he': 'צרפתית', 'hr': 'francuski', 'hu': 'francia', 'id': 'Prancis', 'ie': 'francesi', 'is': 'franska', 'it': 'francese', 'ja': 'フランス語', 'ko': '프랑스어', 'lt': 'prancūzų', 'nb': 'fransk', 'nl': 'Frans', 'nn': 'fransk', 'pl': 'francuski', 'pt': 'francês', 'pt_BR': 'francês', 'ro': 'franceză', 'ru': 'французский', 'sk': 'francúzština', 'sl': 'francoščina', 'sr': 'француски', 'sr_Latn': 'francuski', 'sv': 'franska', 'th': 'ฝรั่งเศส', 'tr': 'Fransızca', 'uk': 'французька', 'vi': 'Tiếng Pháp', 'zh_CN': '法语', 'zh_TW': '法文', }, 'gl': { '_native': 'galego', 'ar': 'الجاليكية', 'bg': 'галисийски', 'bs': 'galicijski', 'ca': 'gallec', 'cs': 'galicijština', 'da': 'galicisk', 'de': 'Galicisch', 'el': 'Γαλικιανά', 'en': 'Galician', 'eo': 'galega', 'es': 'gallego', 'et': 'galeegi', 'eu': 'galiziera', 'fa': 'گالیسیایی', 'fi': 'galicia', 'fo': 'galisiskt', 'fr': 'galicien', 'gl': 'galego', 'he': 'גליציאנית', 'hr': 'galicijski', 'hu': 'gallego', 'id': 'Galisia', 'ie': 'galician', 'is': 'galisíska', 'it': 'galiziano', 'ja': 'ガリシア語', 'ko': '갈리시아어', 'lt': 'galisų', 'nb': 'galisisk', 'nl': 'Galicisch', 'nn': 'galisisk', 'pl': 'galicyjski', 'pt': 'galego', 'pt_BR': 'galego', 'ro': 'galiciană', 'ru': 'галисийский', 'sk': 'galícijčina', 'sl': 'galicijščina', 'sr': 'галицијски', 'sr_Latn': 'galicijski', 'sv': 'galiciska', 'th': 'กาลิเซีย', 'tr': 'Galiçyaca', 'uk': 'галісійська', 'vi': 'Tiếng Galician', 'zh_CN': '加利西亚语', 'zh_TW': '加利西亞文', }, 'he': { '_native': 'עברית', 'ar': 'العبرية', 'bg': 'иврит', 'bs': 'hebrejski', 'ca': 'hebreu', 'cs': 'hebrejština', 'da': 'hebraisk', 'de': 'Hebräisch', 'el': 'Εβραϊκά', 'en': 'Hebrew', 'eo': 'hebrea', 'es': 'hebreo', 'et': 'heebrea', 'eu': 'hebreera', 'fa': 'عبری', 'fi': 'heprea', 'fo': 'hebraiskt', 'fr': 'hébreu', 'gl': 'hebreo', 'he': 'עברית', 'hr': 'hebrejski', 'hu': 'héber', 'id': 'Ibrani', 'ie': 'hebreic', 'is': 'hebreska', 'it': 'ebraico', 'ja': 'ヘブライ語', 'ko': '히브리어', 'lt': 'hebrajų', 'nb': 'hebraisk', 'nl': 'Hebreeuws', 'nn': 'hebraisk', 'pl': 'hebrajski', 'pt': 'hebraico', 'pt_BR': 'hebraico', 'ro': 'ebraică', 'ru': 'иврит', 'sk': 'hebrejčina', 'sl': 'hebrejščina', 'sr': 'хебрејски', 'sr_Latn': 'hebrejski', 'sv': 'hebreiska', 'th': 'ฮิบรู', 'tr': 'İbranice', 'uk': 'іврит', 'vi': 'Tiếng Do Thái', 'zh_CN': '希伯来语', 'zh_TW': '希伯來文', }, 'hr': { '_native': 'hrvatski', 'ar': 'الكرواتية', 'bg': 'хърватски', 'bs': 'hrvatski', 'ca': 'croat', 'cs': 'chorvatština', 'da': 'kroatisk', 'de': 'Kroatisch', 'el': 'Κροατικά', 'en': 'Croatian', 'eo': 'kroata', 'es': 'croata', 'et': 'horvaadi', 'eu': 'kroaziera', 'fa': 'کروات', 'fi': 'kroatia', 'fo': 'kroatiskt', 'fr': 'croate', 'gl': 'croata', 'he': 'קרואטית', 'hr': 'hrvatski', 'hu': 'horvát', 'id': 'Kroasia', 'ie': 'croatian', 'is': 'króatíska', 'it': 'croato', 'ja': 'クロアチア語', 'ko': '크로아티아어', 'lt': 'kroatų', 'nb': 'kroatisk', 'nl': 'Kroatisch', 'nn': 'kroatisk', 'pl': 'chorwacki', 'pt': 'croata', 'pt_BR': 'croata', 'ro': 'croată', 'ru': 'хорватский', 'sk': 'chorvátčina', 'sl': 'hrvaščina', 'sr': 'хрватски', 'sr_Latn': 'hrvatski', 'sv': 'kroatiska', 'th': 'โครเอเชีย', 'tr': 'Hırvatça', 'uk': 'хорватська', 'vi': 'Tiếng Croatia', 'zh_CN': '克罗地亚语', 'zh_TW': '克羅埃西亞文', }, 'hu': { '_native': 'magyar', 'ar': 'الهنغارية', 'bg': 'унгарски', 'bs': 'mađarski', 'ca': 'hongarès', 'cs': 'maďarština', 'da': 'ungarsk', 'de': 'Ungarisch', 'el': 'Ουγγρικά', 'en': 'Hungarian', 'eo': 'hungara', 'es': 'húngaro', 'et': 'ungari', 'eu': 'hungariera', 'fa': 'مجاری', 'fi': 'unkari', 'fo': 'ungarskt', 'fr': 'hongrois', 'gl': 'húngaro', 'he': 'הונגרית', 'hr': 'mađarski', 'hu': 'magyar', 'id': 'Hungaria', 'ie': 'hungarian', 'is': 'ungverska', 'it': 'ungherese', 'ja': 'ハンガリー語', 'ko': '헝가리어', 'lt': 'vengrų', 'nb': 'ungarsk', 'nl': 'Hongaars', 'nn': 'ungarsk', 'pl': 'węgierski', 'pt': 'húngaro', 'pt_BR': 'húngaro', 'ro': 'maghiară', 'ru': 'венгерский', 'sk': 'maďarčina', 'sl': 'madžarščina', 'sr': 'мађарски', 'sr_Latn': 'mađarski', 'sv': 'ungerska', 'th': 'ฮังการี', 'tr': 'Macarca', 'uk': 'угорська', 'vi': 'Tiếng Hungary', 'zh_CN': '匈牙利语', 'zh_TW': '匈牙利文', }, 'id': { '_native': 'Indonesia', 'ar': 'الإندونيسية', 'bg': 'индонезийски', 'bs': 'indonezijski', 'ca': 'indonesi', 'cs': 'indonéština', 'da': 'indonesisk', 'de': 'Indonesisch', 'el': 'Ινδονησιακά', 'en': 'Indonesian', 'eo': 'indonezia', 'es': 'indonesio', 'et': 'indoneesia', 'eu': 'indonesiera', 'fa': 'اندونزیایی', 'fi': 'indonesia', 'fo': 'indonesiskt', 'fr': 'indonésien', 'gl': 'indonesio', 'he': 'אינדונזית', 'hr': 'indonezijski', 'hu': 'indonéz', 'id': 'Indonesia', 'ie': 'indonesian', 'is': 'indónesíska', 'it': 'indonesiano', 'ja': 'インドネシア語', 'ko': '인도네시아어', 'lt': 'indoneziečių', 'nb': 'indonesisk', 'nl': 'Indonesisch', 'nn': 'indonesisk', 'pl': 'indonezyjski', 'pt': 'indonésio', 'pt_BR': 'indonésio', 'ro': 'indoneziană', 'ru': 'индонезийский', 'sk': 'indonézština', 'sl': 'indonezijščina', 'sr': 'индонежански', 'sr_Latn': 'indonežanski', 'sv': 'indonesiska', 'th': 'อินโดนีเซีย', 'tr': 'Endonezce', 'uk': 'індонезійська', 'vi': 'Tiếng Indonesia', 'zh_CN': '印度尼西亚语', 'zh_TW': '印尼文', }, 'ie': { '_native': 'Interlingue', 'ar': 'الإنترلينج', 'bg': 'оксидентал', 'bs': 'interlingve', 'ca': 'interlingue', 'cs': 'interlingue', 'da': 'interlingue', 'de': 'Interlingue', 'el': 'Ιντερλίνγκουε', 'en': 'Interlingue', 'eo': 'Interlingveo', 'es': 'interlingue', 'et': 'interlingue', 'eu': 'interlingue', 'fa': 'اکسیدنتال', 'fi': 'interlingue', 'fo': 'interlingue', 'fr': 'interlingue', 'gl': 'None', 'he': 'אינטרלינגה', 'hr': 'interligua', 'hu': 'interlingue', 'id': 'Interlingue', 'ie': 'Interlingue', 'is': 'interlingve', 'it': 'interlingue', 'ja': 'インターリング', 'ko': '인테르링구에', 'lt': 'interkalba', 'nb': 'interlingue', 'nl': 'Interlingue', 'nn': 'interlingue', 'pl': 'interlingue', 'pt': 'interlingue', 'pt_BR': 'interlingue', 'ro': 'interlingue', 'ru': 'интерлингве', 'sk': 'interlingue', 'sl': 'interlingve', 'sr': 'интерлингве', 'sr_Latn': 'interlingve', 'sv': 'interlingue', 'th': 'อินเตอร์ลิงกิว', 'tr': 'Interlingue', 'uk': 'інтерлінгве', 'vi': 'Tiếng Interlingue', 'zh_CN': '国际文字(E)', 'zh_TW': '國際文(E)', }, 'is': { '_native': 'íslenska', 'ar': 'الأيسلندية', 'bg': 'исландски', 'bs': 'islandski', 'ca': 'islandès', 'cs': 'islandština', 'da': 'islandsk', 'de': 'Isländisch', 'el': 'Ισλανδικά', 'en': 'Icelandic', 'eo': 'islanda', 'es': 'islandés', 'et': 'islandi', 'eu': 'islandiera', 'fa': 'ایسلندی', 'fi': 'islanti', 'fo': 'íslendskt', 'fr': 'islandais', 'gl': 'islandés', 'he': 'איסלנדית', 'hr': 'islandski', 'hu': 'izlandi', 'id': 'Islandia', 'ie': 'islandesi', 'is': 'íslenska', 'it': 'islandese', 'ja': 'アイスランド語', 'ko': '아이슬란드어', 'lt': 'islandų', 'nb': 'islandsk', 'nl': 'IJslands', 'nn': 'islandsk', 'pl': 'islandzki', 'pt': 'islandês', 'pt_BR': 'islandês', 'ro': 'islandeză', 'ru': 'исландский', 'sk': 'islandčina', 'sl': 'islandščina', 'sr': 'исландски', 'sr_Latn': 'islandski', 'sv': 'isländska', 'th': 'ไอซ์แลนด์', 'tr': 'İzlandaca', 'uk': 'ісландська', 'vi': 'Tiếng Iceland', 'zh_CN': '冰岛语', 'zh_TW': '冰島文', }, 'it': { '_native': 'italiano', 'ar': 'الإيطالية', 'bg': 'италиански', 'bs': 'italijanski', 'ca': 'italià', 'cs': 'italština', 'da': 'italiensk', 'de': 'Italienisch', 'el': 'Ιταλικά', 'en': 'Italian', 'eo': 'itala', 'es': 'italiano', 'et': 'itaalia', 'eu': 'italiera', 'fa': 'ایتالیایی', 'fi': 'italia', 'fo': 'italskt', 'fr': 'italien', 'gl': 'italiano', 'he': 'איטלקית', 'hr': 'talijanski', 'hu': 'olasz', 'id': 'Italia', 'ie': 'italian', 'is': 'ítalska', 'it': 'italiano', 'ja': 'イタリア語', 'ko': '이탈리아어', 'lt': 'italų', 'nb': 'italiensk', 'nl': 'Italiaans', 'nn': 'italiensk', 'pl': 'włoski', 'pt': 'italiano', 'pt_BR': 'italiano', 'ro': 'italiană', 'ru': 'итальянский', 'sk': 'taliančina', 'sl': 'italijanščina', 'sr': 'италијански', 'sr_Latn': 'italijanski', 'sv': 'italienska', 'th': 'อิตาลี', 'tr': 'İtalyanca', 'uk': 'італійська', 'vi': 'Tiếng Italy', 'zh_CN': '意大利语', 'zh_TW': '義大利文', }, 'ja': { '_native': '日本語', 'ar': 'اليابانية', 'bg': 'японски', 'bs': 'japanski', 'ca': 'japonès', 'cs': 'japonština', 'da': 'japansk', 'de': 'Japanisch', 'el': 'Ιαπωνικά', 'en': 'Japanese', 'eo': 'japana', 'es': 'japonés', 'et': 'jaapani', 'eu': 'japoniera', 'fa': 'ژاپنی', 'fi': 'japani', 'fo': 'japanskt', 'fr': 'japonais', 'gl': 'xaponés', 'he': 'יפנית', 'hr': 'japanski', 'hu': 'japán', 'id': 'Jepang', 'ie': 'japanesi', 'is': 'japanska', 'it': 'giapponese', 'ja': '日本語', 'ko': '일본어', 'lt': 'japonų', 'nb': 'japansk', 'nl': 'Japans', 'nn': 'japansk', 'pl': 'japoński', 'pt': 'japonês', 'pt_BR': 'japonês', 'ro': 'japoneză', 'ru': 'японский', 'sk': 'japončina', 'sl': 'japonščina', 'sr': 'јапански', 'sr_Latn': 'japanski', 'sv': 'japanska', 'th': 'ญี่ปุ่น', 'tr': 'Japonca', 'uk': 'японська', 'vi': 'Tiếng Nhật', 'zh_CN': '日语', 'zh_TW': '日文', }, 'ko': { '_native': '한국어', 'ar': 'الكورية', 'bg': 'корейски', 'bs': 'korejski', 'ca': 'coreà', 'cs': 'korejština', 'da': 'koreansk', 'de': 'Koreanisch', 'el': 'Κορεατικά', 'en': 'Korean', 'eo': 'korea', 'es': 'coreano', 'et': 'korea', 'eu': 'koreera', 'fa': 'کره‌ای', 'fi': 'korea', 'fo': 'koreanskt', 'fr': 'coréen', 'gl': 'coreano', 'he': 'קוריאנית', 'hr': 'korejski', 'hu': 'koreai', 'id': 'Korea', 'ie': 'korean', 'is': 'kóreska', 'it': 'coreano', 'ja': '韓国語', 'ko': '한국어', 'lt': 'korėjiečių', 'nb': 'koreansk', 'nl': 'Koreaans', 'nn': 'koreansk', 'pl': 'koreański', 'pt': 'coreano', 'pt_BR': 'coreano', 'ro': 'coreeană', 'ru': 'корейский', 'sk': 'kórejčina', 'sl': 'korejščina', 'sr': 'корејски', 'sr_Latn': 'korejski', 'sv': 'koreanska', 'th': 'เกาหลี', 'tr': 'Korece', 'uk': 'корейська', 'vi': 'Tiếng Hàn', 'zh_CN': '韩语', 'zh_TW': '韓文', }, 'lt': { '_native': 'lietuvių', 'ar': 'الليتوانية', 'bg': 'литовски', 'bs': 'litvanski', 'ca': 'lituà', 'cs': 'litevština', 'da': 'litauisk', 'de': 'Litauisch', 'el': 'Λιθουανικά', 'en': 'Lithuanian', 'eo': 'litova', 'es': 'lituano', 'et': 'leedu', 'eu': 'lituaniera', 'fa': 'لیتوانیایی', 'fi': 'liettua', 'fo': 'litaviskt', 'fr': 'lituanien', 'gl': 'lituano', 'he': 'ליטאית', 'hr': 'litavski', 'hu': 'litván', 'id': 'Lituavi', 'ie': 'lituan', 'is': 'litháíska', 'it': 'lituano', 'ja': 'リトアニア語', 'ko': '리투아니아어', 'lt': 'lietuvių', 'nb': 'litauisk', 'nl': 'Litouws', 'nn': 'litauisk', 'pl': 'litewski', 'pt': 'lituano', 'pt_BR': 'lituano', 'ro': 'lituaniană', 'ru': 'литовский', 'sk': 'litovčina', 'sl': 'litovščina', 'sr': 'литвански', 'sr_Latn': 'litvanski', 'sv': 'litauiska', 'th': 'ลิทัวเนีย', 'tr': 'Litvanca', 'uk': 'литовська', 'vi': 'Tiếng Litva', 'zh_CN': '立陶宛语', 'zh_TW': '立陶宛文', }, 'nb': { '_native': 'norsk bokmål', 'ar': 'النرويجية بوكمال', 'bg': 'норвежки (букмол)', 'bs': 'norveški (Bokmal)', 'ca': 'noruec bokmål', 'cs': 'norština (bokmål)', 'da': 'bokmål', 'de': 'Norwegisch (Bokmål)', 'el': 'Νορβηγικά Μποκμάλ', 'en': 'Norwegian Bokmål', 'eo': 'dannorvega', 'es': 'noruego bokmal', 'et': 'norra bokmål', 'eu': 'bokmål (norvegiera)', 'fa': 'نروژی بوک‌مُل', 'fi': 'norjan bokmål', 'fo': 'norskt bókmál', 'fr': 'norvégien bokmål', 'gl': 'noruegués bokmål', 'he': 'נורווגית ספרותית', 'hr': 'norveški bokmål', 'hu': 'norvég (bokmål)', 'id': 'Bokmål Norwegia', 'ie': 'norvegian, bokmål', 'is': 'norskt bókmál', 'it': 'norvegese bokmål', 'ja': 'ノルウェー語(ブークモール)', 'ko': '노르웨이어(보크말)', 'lt': 'norvegų bukmolas', 'nb': 'norsk bokmål', 'nl': 'Noors - Bokmål', 'nn': 'norsk bokmål', 'pl': 'norweski (bokmål)', 'pt': 'bokmål norueguês', 'pt_BR': 'bokmål norueguês', 'ro': 'norvegiană bokmål', 'ru': 'норвежский букмол', 'sk': 'nórčina (bokmal)', 'sl': 'knjižna norveščina', 'sr': 'норвешки букмол', 'sr_Latn': 'norveški bukmol', 'sv': 'norskt bokmål', 'th': 'นอร์เวย์บุคมอล', 'tr': 'Norveççe Bokmål', 'uk': 'норвезька (букмол)', 'vi': 'Tiếng Na Uy (Bokmål)', 'zh_CN': '书面挪威语', 'zh_TW': '巴克摩挪威文', }, 'nl': { '_native': 'Nederlands', 'ar': 'الهولندية', 'bg': 'нидерландски', 'bs': 'nizozemski', 'ca': 'neerlandès', 'cs': 'nizozemština', 'da': 'nederlandsk', 'de': 'Niederländisch', 'el': 'Ολλανδικά', 'en': 'Dutch', 'eo': 'nederlanda', 'es': 'neerlandés', 'et': 'hollandi', 'eu': 'nederlandera', 'fa': 'هلندی', 'fi': 'hollanti', 'fo': 'hálendskt', 'fr': 'néerlandais', 'gl': 'neerlandés', 'he': 'הולנדית', 'hr': 'nizozemski', 'hu': 'holland', 'id': 'Belanda', 'ie': 'hollandesi', 'is': 'hollenska', 'it': 'olandese', 'ja': 'オランダ語', 'ko': '네덜란드어', 'lt': 'olandų', 'nb': 'nederlandsk', 'nl': 'Nederlands', 'nn': 'nederlandsk', 'pl': 'niderlandzki', 'pt': 'holandês', 'pt_BR': 'holandês', 'ro': 'neerlandeză', 'ru': 'нидерландский', 'sk': 'holandčina', 'sl': 'nizozemščina', 'sr': 'холандски', 'sr_Latn': 'holandski', 'sv': 'nederländska', 'th': 'ดัตช์', 'tr': 'Felemenkçe', 'uk': 'нідерландська', 'vi': 'Tiếng Hà Lan', 'zh_CN': '荷兰语', 'zh_TW': '荷蘭文', }, 'nn': { '_native': 'norsk nynorsk', 'ar': 'النرويجية نينورسك', 'bg': 'норвежки (нюношк)', 'bs': 'norveški (Nynorsk)', 'ca': 'noruec nynorsk', 'cs': 'norština (nynorsk)', 'da': 'nynorsk', 'de': 'Norwegisch (Nynorsk)', 'el': 'Νορβηγικά Νινόρσκ', 'en': 'Norwegian Nynorsk', 'eo': 'novnorvega', 'es': 'noruego nynorsk', 'et': 'uusnorra', 'eu': 'nynorsk (norvegiera)', 'fa': 'نروژی نی‌نُشک', 'fi': 'norjan nynorsk', 'fo': 'nýnorskt', 'fr': 'norvégien nynorsk', 'gl': 'noruegués nynorsk', 'he': 'נורווגית חדשה', 'hr': 'norveški nynorsk', 'hu': 'norvég (nynorsk)', 'id': 'Nynorsk Norwegia', 'ie': 'neo-norvegian', 'is': 'nýnorska', 'it': 'norvegese nynorsk', 'ja': 'ノルウェー語(ニーノシュク)', 'ko': '노르웨이어(니노르스크)', 'lt': 'naujoji norvegų', 'nb': 'norsk nynorsk', 'nl': 'Noors - Nynorsk', 'nn': 'norsk nynorsk', 'pl': 'norweski (nynorsk)', 'pt': 'nynorsk norueguês', 'pt_BR': 'nynorsk norueguês', 'ro': 'norvegiană nynorsk', 'ru': 'нюнорск', 'sk': 'nórčina (nynorsk)', 'sl': 'novonorveščina', 'sr': 'норвешки нинорск', 'sr_Latn': 'norveški ninorsk', 'sv': 'nynorska', 'th': 'นอร์เวย์นีนอสก์', 'tr': 'Norveççe Nynorsk', 'uk': 'норвезька (нюношк)', 'vi': 'Tiếng Na Uy (Nynorsk)', 'zh_CN': '挪威尼诺斯克语', 'zh_TW': '耐諾斯克挪威文', }, 'pl': { '_native': 'polski', 'ar': 'البولندية', 'bg': 'полски', 'bs': 'poljski', 'ca': 'polonès', 'cs': 'polština', 'da': 'polsk', 'de': 'Polnisch', 'el': 'Πολωνικά', 'en': 'Polish', 'eo': 'pola', 'es': 'polaco', 'et': 'poola', 'eu': 'poloniera', 'fa': 'لهستانی', 'fi': 'puola', 'fo': 'pólskt', 'fr': 'polonais', 'gl': 'polaco', 'he': 'פולנית', 'hr': 'poljski', 'hu': 'lengyel', 'id': 'Polski', 'ie': 'polonesi', 'is': 'pólska', 'it': 'polacco', 'ja': 'ポーランド語', 'ko': '폴란드어', 'lt': 'lenkų', 'nb': 'polsk', 'nl': 'Pools', 'nn': 'polsk', 'pl': 'polski', 'pt': 'polonês', 'pt_BR': 'polonês', 'ro': 'poloneză', 'ru': 'польский', 'sk': 'poľština', 'sl': 'poljščina', 'sr': 'пољски', 'sr_Latn': 'poljski', 'sv': 'polska', 'th': 'โปแลนด์', 'tr': 'Lehçe', 'uk': 'польська', 'vi': 'Tiếng Ba Lan', 'zh_CN': '波兰语', 'zh_TW': '波蘭文', }, 'pt': { '_native': 'português', 'ar': 'البرتغالية', 'bg': 'португалски', 'bs': 'portugalski', 'ca': 'portuguès', 'cs': 'portugalština', 'da': 'portugisisk', 'de': 'Portugiesisch', 'el': 'Πορτογαλικά', 'en': 'Portuguese', 'eo': 'portugala', 'es': 'portugués', 'et': 'portugali', 'eu': 'portugesa', 'fa': 'پرتغالی', 'fi': 'portugali', 'fo': 'portugiskiskt', 'fr': 'portugais', 'gl': 'portugués', 'he': 'פורטוגזית', 'hr': 'portugalski', 'hu': 'portugál', 'id': 'Portugis', 'ie': 'portugalesi', 'is': 'portúgalska', 'it': 'portoghese', 'ja': 'ポルトガル語', 'ko': '포르투갈어', 'lt': 'portugalų', 'nb': 'portugisisk', 'nl': 'Portugees', 'nn': 'portugisisk', 'pl': 'portugalski', 'pt': 'português', 'pt_BR': 'português', 'ro': 'portugheză', 'ru': 'португальский', 'sk': 'portugalčina', 'sl': 'portugalščina', 'sr': 'португалски', 'sr_Latn': 'portugalski', 'sv': 'portugisiska', 'th': 'โปรตุเกส', 'tr': 'Portekizce', 'uk': 'португальська', 'vi': 'Tiếng Bồ Đào Nha', 'zh_CN': '葡萄牙语', 'zh_TW': '葡萄牙文', }, 'pt_BR': { '_native': 'português (Brasil)', 'ar': 'البرتغالية (البرازيل)', 'bg': 'португалски (Бразилия)', 'bs': 'portugalski (Brazil)', 'ca': 'portuguès (Brasil)', 'cs': 'portugalština (Brazílie)', 'da': 'portugisisk (Brasilien)', 'de': 'Portugiesisch (Brasilien)', 'el': 'Πορτογαλικά (Βραζιλία)', 'en': 'Portuguese (Brazil)', 'eo': 'portugala (Brazilo)', 'es': 'portugués (Brasil)', 'et': 'portugali (Brasiilia)', 'eu': 'portugesa (Brasil)', 'fa': 'پرتغالی (برزیل)', 'fi': 'portugali (Brasilia)', 'fo': 'portugiskiskt (Brasil)', 'fr': 'portugais (Brésil)', 'gl': 'portugués (O Brasil)', 'he': 'פורטוגזית (ברזיל)', 'hr': 'portugalski (Brazil)', 'hu': 'portugál (Brazília)', 'id': 'Portugis (Brasil)', 'ie': 'portugalesi (Brasilia)', 'is': 'portúgalska (Brasilía)', 'it': 'portoghese (Brasile)', 'ja': 'ポルトガル語 (ブラジル)', 'ko': '포르투갈어 (브라질)', 'lt': 'portugalų (Brazilija)', 'nb': 'portugisisk (Brasil)', 'nl': 'Portugees (Brazilië)', 'nn': 'portugisisk (Brasil)', 'pl': 'portugalski (Brazylia)', 'pt': 'português (Brasil)', 'pt_BR': 'português (Brasil)', 'ro': 'portugheză (Brazilia)', 'ru': 'португальский (Бразилия)', 'sk': 'portugalčina (Brazília)', 'sl': 'portugalščina (Brazilija)', 'sr': 'португалски (Бразил)', 'sr_Latn': 'portugalski (Brazil)', 'sv': 'portugisiska (Brasilien)', 'th': 'โปรตุเกส (บราซิล)', 'tr': 'Portekizce (Brezilya)', 'uk': 'португальська (Бразилія)', 'vi': 'Tiếng Bồ Đào Nha (Brazil)', 'zh_CN': '葡萄牙语 (巴西)', 'zh_TW': '葡萄牙文 (巴西)', }, 'ro': { '_native': 'română', 'ar': 'الرومانية', 'bg': 'румънски', 'bs': 'rumunski', 'ca': 'romanès', 'cs': 'rumunština', 'da': 'rumænsk', 'de': 'Rumänisch', 'el': 'Ρουμανικά', 'en': 'Romanian', 'eo': 'rumana', 'es': 'rumano', 'et': 'rumeenia', 'eu': 'errumaniera', 'fa': 'رومانیایی', 'fi': 'romania', 'fo': 'rumenskt', 'fr': 'roumain', 'gl': 'romanés', 'he': 'רומנית', 'hr': 'rumunjski', 'hu': 'román', 'id': 'Rumania', 'ie': 'rumanian', 'is': 'rúmenska', 'it': 'rumeno', 'ja': 'ルーマニア語', 'ko': '루마니아어', 'lt': 'rumunų', 'nb': 'rumensk', 'nl': 'Roemeens', 'nn': 'rumensk', 'pl': 'rumuński', 'pt': 'romeno', 'pt_BR': 'romeno', 'ro': 'română', 'ru': 'румынский', 'sk': 'rumunčina', 'sl': 'romunščina', 'sr': 'румунски', 'sr_Latn': 'rumunski', 'sv': 'rumänska', 'th': 'โรมาเนีย', 'tr': 'Rumence', 'uk': 'румунська', 'vi': 'Tiếng Romania', 'zh_CN': '罗马尼亚语', 'zh_TW': '羅馬尼亞文', }, 'ru': { '_native': 'русский', 'ar': 'الروسية', 'bg': 'руски', 'bs': 'ruski', 'ca': 'rus', 'cs': 'ruština', 'da': 'russisk', 'de': 'Russisch', 'el': 'Ρωσικά', 'en': 'Russian', 'eo': 'rusa', 'es': 'ruso', 'et': 'vene', 'eu': 'errusiera', 'fa': 'روسی', 'fi': 'venäjä', 'fo': 'russiskt', 'fr': 'russe', 'gl': 'ruso', 'he': 'רוסית', 'hr': 'ruski', 'hu': 'orosz', 'id': 'Rusia', 'ie': 'russ', 'is': 'rússneska', 'it': 'russo', 'ja': 'ロシア語', 'ko': '러시아어', 'lt': 'rusų', 'nb': 'russisk', 'nl': 'Russisch', 'nn': 'russisk', 'pl': 'rosyjski', 'pt': 'russo', 'pt_BR': 'russo', 'ro': 'rusă', 'ru': 'русский', 'sk': 'ruština', 'sl': 'ruščina', 'sr': 'руски', 'sr_Latn': 'ruski', 'sv': 'ryska', 'th': 'รัสเซีย', 'tr': 'Rusça', 'uk': 'російська', 'vi': 'Tiếng Nga', 'zh_CN': '俄语', 'zh_TW': '俄文', }, 'sk': { '_native': 'slovenčina', 'ar': 'السلوفاكية', 'bg': 'словашки', 'bs': 'slovački', 'ca': 'eslovac', 'cs': 'slovenština', 'da': 'slovakisk', 'de': 'Slowakisch', 'el': 'Σλοβακικά', 'en': 'Slovak', 'eo': 'slovaka', 'es': 'eslovaco', 'et': 'slovaki', 'eu': 'eslovakiera', 'fa': 'اسلواکی', 'fi': 'slovakki', 'fo': 'slovakiskt', 'fr': 'slovaque', 'gl': 'eslovaco', 'he': 'סלובקית', 'hr': 'slovački', 'hu': 'szlovák', 'id': 'Slovak', 'ie': 'slovac', 'is': 'slóvakíska', 'it': 'slovacco', 'ja': 'スロバキア語', 'ko': '슬로바키아어', 'lt': 'slovakų', 'nb': 'slovakisk', 'nl': 'Slowaaks', 'nn': 'slovakisk', 'pl': 'słowacki', 'pt': 'eslovaco', 'pt_BR': 'eslovaco', 'ro': 'slovacă', 'ru': 'словацкий', 'sk': 'slovenčina', 'sl': 'slovaščina', 'sr': 'словачки', 'sr_Latn': 'slovački', 'sv': 'slovakiska', 'th': 'สโลวัก', 'tr': 'Slovakça', 'uk': 'словацька', 'vi': 'Tiếng Slovak', 'zh_CN': '斯洛伐克语', 'zh_TW': '斯洛伐克文', }, 'sl': { '_native': 'slovenščina', 'ar': 'السلوفانية', 'bg': 'словенски', 'bs': 'slovenski', 'ca': 'eslovè', 'cs': 'slovinština', 'da': 'slovensk', 'de': 'Slowenisch', 'el': 'Σλοβενικά', 'en': 'Slovenian', 'eo': 'slovena', 'es': 'esloveno', 'et': 'sloveeni', 'eu': 'esloveniera', 'fa': 'اسلوونیایی', 'fi': 'sloveeni', 'fo': 'slovenskt', 'fr': 'slovène', 'gl': 'esloveno', 'he': 'סלובנית', 'hr': 'slovenski', 'hu': 'szlovén', 'id': 'Sloven', 'ie': 'slovenian', 'is': 'slóvenska', 'it': 'sloveno', 'ja': 'スロベニア語', 'ko': '슬로베니아어', 'lt': 'slovėnų', 'nb': 'slovensk', 'nl': 'Sloveens', 'nn': 'slovensk', 'pl': 'słoweński', 'pt': 'esloveno', 'pt_BR': 'esloveno', 'ro': 'slovenă', 'ru': 'словенский', 'sk': 'slovinčina', 'sl': 'slovenščina', 'sr': 'словеначки', 'sr_Latn': 'slovenački', 'sv': 'slovenska', 'th': 'สโลวีเนีย', 'tr': 'Slovence', 'uk': 'словенська', 'vi': 'Tiếng Slovenia', 'zh_CN': '斯洛文尼亚语', 'zh_TW': '斯洛維尼亞文', }, 'sr': { '_native': 'српски', 'ar': 'الصربية', 'bg': 'сръбски', 'bs': 'srpski', 'ca': 'serbi', 'cs': 'srbština', 'da': 'serbisk', 'de': 'Serbisch', 'el': 'Σερβικά', 'en': 'Serbian', 'eo': 'serba', 'es': 'serbio', 'et': 'serbia', 'eu': 'serbiera', 'fa': 'صربی', 'fi': 'serbia', 'fo': 'serbiskt', 'fr': 'serbe', 'gl': 'serbio', 'he': 'סרבית', 'hr': 'srpski', 'hu': 'szerb', 'id': 'Serbia', 'ie': 'serbian', 'is': 'serbneska', 'it': 'serbo', 'ja': 'セルビア語', 'ko': '세르비아어', 'lt': 'serbų', 'nb': 'serbisk', 'nl': 'Servisch', 'nn': 'serbisk', 'pl': 'serbski', 'pt': 'sérvio', 'pt_BR': 'sérvio', 'ro': 'sârbă', 'ru': 'сербский', 'sk': 'srbčina', 'sl': 'srbščina', 'sr': 'српски', 'sr_Latn': 'srpski', 'sv': 'serbiska', 'th': 'เซอร์เบีย', 'tr': 'Sırpça', 'uk': 'сербська', 'vi': 'Tiếng Serbia', 'zh_CN': '塞尔维亚语', 'zh_TW': '塞爾維亞文', }, 'sr_Latn': { '_native': 'srpski (latinica)', 'ar': 'الصربية (اللاتينية)', 'bg': 'сръбски (латиница)', 'bs': 'srpski (latinica)', 'ca': 'serbi (llatí)', 'cs': 'srbština (latinka)', 'da': 'serbisk (latinsk)', 'de': 'Serbisch (Lateinisch)', 'el': 'Σερβικά (Λατινικό)', 'en': 'Serbian (Latin)', 'eo': 'serba (latina)', 'es': 'serbio (latino)', 'et': 'serbia (ladina)', 'eu': 'serbiera (latinoa)', 'fa': 'صربی (لاتین)', 'fi': 'serbia (latinalainen)', 'fo': 'serbiskt (latínskt)', 'fr': 'serbe (latin)', 'gl': 'serbio (latino)', 'he': 'סרבית (לטיני)', 'hr': 'srpski (latinica)', 'hu': 'szerb (Latin)', 'id': 'Serbia (Latin)', 'ie': 'serbian (latin)', 'is': 'serbneska (latneskt)', 'it': 'serbo (latino)', 'ja': 'セルビア語 (ラテン文字)', 'ko': '세르비아어 (로마자)', 'lt': 'serbų (lotynų)', 'nb': 'serbisk (latinsk)', 'nl': 'Servisch (Latijns)', 'nn': 'serbisk (latinsk)', 'pl': 'serbski (łacińskie)', 'pt': 'sérvio (latim)', 'pt_BR': 'sérvio (latim)', 'ro': 'sârbă (latină)', 'ru': 'сербский (латиница)', 'sk': 'srbčina (latinka)', 'sl': 'srbščina (latinica)', 'sr': 'српски (латиница)', 'sr_Latn': 'srpski (latinica)', 'sv': 'serbiska (latinska)', 'th': 'เซอร์เบีย (ละติน)', 'tr': 'Sırpça (Latin)', 'uk': 'сербська (латиниця)', 'vi': 'Tiếng Serbia (Chữ La tinh)', 'zh_CN': '塞尔维亚语 (拉丁文)', 'zh_TW': '塞爾維亞文 (拉丁文)', }, 'sv': { '_native': 'svenska', 'ar': 'السويدية', 'bg': 'шведски', 'bs': 'švedski', 'ca': 'suec', 'cs': 'švédština', 'da': 'svensk', 'de': 'Schwedisch', 'el': 'Σουηδικά', 'en': 'Swedish', 'eo': 'sveda', 'es': 'sueco', 'et': 'rootsi', 'eu': 'suediera', 'fa': 'سوئدی', 'fi': 'ruotsi', 'fo': 'svenskt', 'fr': 'suédois', 'gl': 'sueco', 'he': 'שוודית', 'hr': 'švedski', 'hu': 'svéd', 'id': 'Swedia', 'ie': 'sved', 'is': 'sænska', 'it': 'svedese', 'ja': 'スウェーデン語', 'ko': '스웨덴어', 'lt': 'švedų', 'nb': 'svensk', 'nl': 'Zweeds', 'nn': 'svensk', 'pl': 'szwedzki', 'pt': 'sueco', 'pt_BR': 'sueco', 'ro': 'suedeză', 'ru': 'шведский', 'sk': 'švédčina', 'sl': 'švedščina', 'sr': 'шведски', 'sr_Latn': 'švedski', 'sv': 'svenska', 'th': 'สวีเดน', 'tr': 'İsveççe', 'uk': 'шведська', 'vi': 'Tiếng Thụy Điển', 'zh_CN': '瑞典语', 'zh_TW': '瑞典文', }, 'th': { '_native': 'ไทย', 'ar': 'التايلاندية', 'bg': 'тайски', 'bs': 'tajlandski', 'ca': 'tai', 'cs': 'thajština', 'da': 'thai', 'de': 'Thailändisch', 'el': 'Ταϊλανδικά', 'en': 'Thai', 'eo': 'taja', 'es': 'tailandés', 'et': 'tai', 'eu': 'thailandiera', 'fa': 'تایلندی', 'fi': 'thai', 'fo': 'tailendskt', 'fr': 'thaï', 'gl': 'tailandés', 'he': 'תאית', 'hr': 'tajlandski', 'hu': 'thai', 'id': 'Thai', 'ie': 'thai', 'is': 'taílenska', 'it': 'thailandese', 'ja': 'タイ語', 'ko': '태국어', 'lt': 'tajų', 'nb': 'thai', 'nl': 'Thai', 'nn': 'thai', 'pl': 'tajski', 'pt': 'tailandês', 'pt_BR': 'tailandês', 'ro': 'thailandeză', 'ru': 'тайский', 'sk': 'thajčina', 'sl': 'tajščina', 'sr': 'тајски', 'sr_Latn': 'tajski', 'sv': 'thailändska', 'th': 'ไทย', 'tr': 'Tayca', 'uk': 'тайська', 'vi': 'Tiếng Thái', 'zh_CN': '泰语', 'zh_TW': '泰文', }, 'tr': { '_native': 'Türkçe', 'ar': 'التركية', 'bg': 'турски', 'bs': 'turski', 'ca': 'turc', 'cs': 'turečtina', 'da': 'tyrkisk', 'de': 'Türkisch', 'el': 'Τουρκικά', 'en': 'Turkish', 'eo': 'turka', 'es': 'turco', 'et': 'türgi', 'eu': 'turkiera', 'fa': 'ترکی استانبولی', 'fi': 'turkki', 'fo': 'turkiskt', 'fr': 'turc', 'gl': 'turco', 'he': 'טורקית', 'hr': 'turski', 'hu': 'török', 'id': 'Turki', 'ie': 'turc', 'is': 'tyrkneska', 'it': 'turco', 'ja': 'トルコ語', 'ko': '터키어', 'lt': 'turkų', 'nb': 'tyrkisk', 'nl': 'Turks', 'nn': 'tyrkisk', 'pl': 'turecki', 'pt': 'turco', 'pt_BR': 'turco', 'ro': 'turcă', 'ru': 'турецкий', 'sk': 'turečtina', 'sl': 'turščina', 'sr': 'турски', 'sr_Latn': 'turski', 'sv': 'turkiska', 'th': 'ตุรกี', 'tr': 'Türkçe', 'uk': 'турецька', 'vi': 'Tiếng Thổ Nhĩ Kỳ', 'zh_CN': '土耳其语', 'zh_TW': '土耳其文', }, 'uk': { '_native': 'українська', 'ar': 'الأوكرانية', 'bg': 'украински', 'bs': 'ukrajinski', 'ca': 'ucraïnès', 'cs': 'ukrajinština', 'da': 'ukrainsk', 'de': 'Ukrainisch', 'el': 'Ουκρανικά', 'en': 'Ukrainian', 'eo': 'ukraina', 'es': 'ucraniano', 'et': 'ukraina', 'eu': 'ukrainera', 'fa': 'اوکراینی', 'fi': 'ukraina', 'fo': 'ukrainskt', 'fr': 'ukrainien', 'gl': 'ucraíno', 'he': 'אוקראינית', 'hr': 'ukrajinski', 'hu': 'ukrán', 'id': 'Ukraina', 'ie': 'ukrainan', 'is': 'úkraínska', 'it': 'ucraino', 'ja': 'ウクライナ語', 'ko': '우크라이나어', 'lt': 'ukrainiečių', 'nb': 'ukrainsk', 'nl': 'Oekraïens', 'nn': 'ukrainsk', 'pl': 'ukraiński', 'pt': 'ucraniano', 'pt_BR': 'ucraniano', 'ro': 'ucraineană', 'ru': 'украинский', 'sk': 'ukrajinčina', 'sl': 'ukrajinščina', 'sr': 'украјински', 'sr_Latn': 'ukrajinski', 'sv': 'ukrainska', 'th': 'ยูเครน', 'tr': 'Ukraynaca', 'uk': 'українська', 'vi': 'Tiếng Ukraina', 'zh_CN': '乌克兰语', 'zh_TW': '烏克蘭文', }, 'vi': { '_native': 'Tiếng Việt', 'ar': 'الفيتنامية', 'bg': 'виетнамски', 'bs': 'vijetnamski', 'ca': 'vietnamita', 'cs': 'vietnamština', 'da': 'vietnamesisk', 'de': 'Vietnamesisch', 'el': 'Βιετναμικά', 'en': 'Vietnamese', 'eo': 'vjetnama', 'es': 'vietnamita', 'et': 'vietnami', 'eu': 'vietnamera', 'fa': 'ویتنامی', 'fi': 'vietnam', 'fo': 'vjetnamesiskt', 'fr': 'vietnamien', 'gl': 'vietnamita', 'he': 'וייטנאמית', 'hr': 'vijetnamski', 'hu': 'vietnámi', 'id': 'Vietnam', 'ie': 'vietnamesi', 'is': 'víetnamska', 'it': 'vietnamita', 'ja': 'ベトナム語', 'ko': '베트남어', 'lt': 'vietnamiečių', 'nb': 'vietnamesisk', 'nl': 'Vietnamees', 'nn': 'vietnamesisk', 'pl': 'wietnamski', 'pt': 'vietnamita', 'pt_BR': 'vietnamita', 'ro': 'vietnameză', 'ru': 'вьетнамский', 'sk': 'vietnamčina', 'sl': 'vietnamščina', 'sr': 'вијетнамски', 'sr_Latn': 'vijetnamski', 'sv': 'vietnamesiska', 'th': 'เวียดนาม', 'tr': 'Vietnamca', 'uk': 'вʼєтнамська', 'vi': 'Tiếng Việt', 'zh_CN': '越南语', 'zh_TW': '越南文', }, 'zh_CN': { '_native': '中文 (简体, 中国)', 'ar': 'الصينية (المبسطة, الصين)', 'bg': 'китайски (опростена, Китай)', 'bs': 'kineski (pojednostavljeno, Kina)', 'ca': 'xinès (simplificat, Xina)', 'cs': 'čínština (zjednodušené, Čína)', 'da': 'kinesisk (forenklet, Kina)', 'de': 'Chinesisch (Vereinfacht, China)', 'el': 'Κινεζικά (Απλοποιημένο, Κίνα)', 'en': 'Chinese (Simplified, China)', 'eo': 'ĉina (simpligita, Ĉinujo)', 'es': 'chino (simplificado, China)', 'et': 'hiina (lihtsustatud, Hiina)', 'eu': 'txinera (sinplifikatua, Txina)', 'fa': 'چینی (ساده‌شده, چین)', 'fi': 'kiina (yksinkertaistettu, Kiina)', 'fo': 'kinesiskt (einkult, Kina)', 'fr': 'chinois (simplifié, Chine)', 'gl': 'chinés (simplificado, A China)', 'he': 'סינית (פשוט, סין)', 'hr': 'kineski (pojednostavljeno pismo, Kina)', 'hu': 'kínai (Egyszerűsített, Kína)', 'id': 'Tionghoa (Sederhana, Tiongkok)', 'ie': 'chinesi (simplificat, China)', 'is': 'kínverska (einfaldað, Kína)', 'it': 'cinese (semplificato, Cina)', 'ja': '中国語 (簡体字, 中国)', 'ko': '중국어 (간체, 중국)', 'lt': 'kinų (supaprastinti, Kinija)', 'nb': 'kinesisk (forenklet, Kina)', 'nl': 'Chinees (vereenvoudigd, China)', 'nn': 'kinesisk (forenkla, Kina)', 'pl': 'chiński (uproszczone, Chiny)', 'pt': 'chinês (simplificado, China)', 'pt_BR': 'chinês (simplificado, China)', 'ro': 'chineză (simplificată, China)', 'ru': 'китайский (упрощенная, Китай)', 'sk': 'čínština (zjednodušené, Čína)', 'sl': 'kitajščina (poenostavljena pisava, Kitajska)', 'sr': 'кинески (поједностављено кинеско писмо, Кина)', 'sr_Latn': 'kineski (pojednostavljeno kinesko pismo, Kina)', 'sv': 'kinesiska (förenklad, Kina)', 'th': 'จีน (ตัวย่อ, จีน)', 'tr': 'Çince (Basitleştirilmiş, Çin)', 'uk': 'китайська (спрощена, Китай)', 'vi': 'Tiếng Trung (Giản thể, Trung Quốc)', 'zh_CN': '中文 (简体, 中国)', 'zh_TW': '中文 (簡體, 中國)', }, 'zh_TW': { '_native': '中文 (繁體, 台灣)', 'ar': 'الصينية (التقليدية, تايوان)', 'bg': 'китайски (традиционна, Тайван)', 'bs': 'kineski (tradicionalno, Tajvan)', 'ca': 'xinès (tradicional, Taiwan)', 'cs': 'čínština (tradiční, Tchaj-wan)', 'da': 'kinesisk (traditionelt, Taiwan)', 'de': 'Chinesisch (Traditionell, Taiwan)', 'el': 'Κινεζικά (Παραδοσιακό, Ταϊβάν)', 'en': 'Chinese (Traditional, Taiwan)', 'eo': 'ĉina (tradicia, Tajvano)', 'es': 'chino (tradicional, Taiwán)', 'et': 'hiina (traditsiooniline, Taiwan)', 'eu': 'txinera (tradizionala, Taiwan)', 'fa': 'چینی (سنتی, تایوان)', 'fi': 'kiina (perinteinen, Taiwan)', 'fo': 'kinesiskt (vanligt, Taivan)', 'fr': 'chinois (traditionnel, Taïwan)', 'gl': 'chinés (tradicional, Taiwán)', 'he': 'סינית (מסורתי, טייוואן)', 'hr': 'kineski (tradicionalno pismo, Tajvan)', 'hu': 'kínai (Hagyományos, Tajvan)', 'id': 'Tionghoa (Tradisional, Taiwan)', 'ie': 'chinesi (traditional, Taiwan)', 'is': 'kínverska (hefðbundið, Taívan)', 'it': 'cinese (tradizionale, Taiwan)', 'ja': '中国語 (繁体字, 台湾)', 'ko': '중국어 (번체, 대만)', 'lt': 'kinų (tradiciniai, Taivanas)', 'nb': 'kinesisk (tradisjonell, Taiwan)', 'nl': 'Chinees (traditioneel, Taiwan)', 'nn': 'kinesisk (tradisjonell, Taiwan)', 'pl': 'chiński (tradycyjne, Tajwan)', 'pt': 'chinês (tradicional, Taiwan)', 'pt_BR': 'chinês (tradicional, Taiwan)', 'ro': 'chineză (tradițională, Taiwan)', 'ru': 'китайский (традиционная, Тайвань)', 'sk': 'čínština (tradičné, Taiwan)', 'sl': 'kitajščina (tradicionalna pisava, Tajvan)', 'sr': 'кинески (традиционално кинеско писмо, Тајван)', 'sr_Latn': 'kineski (tradicionalno kinesko pismo, Tajvan)', 'sv': 'kinesiska (traditionell, Taiwan)', 'th': 'จีน (ตัวเต็ม, ไต้หวัน)', 'tr': 'Çince (Geleneksel, Tayvan)', 'uk': 'китайська (традиційна, Тайвань)', 'vi': 'Tiếng Trung (Phồn thể, Đài Loan)', 'zh_CN': '中文 (繁体, 台湾)', 'zh_TW': '中文 (繁體, 台灣)', }, } completeness = { 'pt': 95, 'nn': 84, 'sk': 100, 'pt_BR': 100, 'zh_CN': 100, 'et': 100, 'it': 100, 'bg': 98, 'ar': 77, 'uk': 100, 'gl': 100, 'sr': 87, 'sr_Latn': 100, 'hr': 40, 'eu': 99, 'ko': 100, 'es': 97, 'ru': 72, 'fa': 99, 'tr': 81, 'fo': 30, 'ie': 32, 'th': 46, 'da': 100, 'nb': 63, 'fi': 100, 'de': 100, 'pl': 100, 'el': 100, 'eo': 73, 'vi': 61, 'zh_TW': 100, 'ro': 73, 'id': 99, 'bs': 17, 'lt': 40, 'is': 77, 'cs': 99, 'sv': 100, 'ja': 100, 'fr': 100, 'ca': 83, 'he': 100, 'nl': 74, 'hu': 99, 'sl': 69, 'en': 100, } backintime-1.5.4/common/logger.py000066400000000000000000000057301477034762000167670ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import syslog import os import sys import atexit import bcolors DEBUG = False # Set to "True" when passing "--debug" as cmd arg SYSLOG_IDENTIFIER = 'backintime' SYSLOG_MESSAGE_PREFIX = '' # Labels for the syslog levels _level_names = { syslog.LOG_INFO: 'INFO', syslog.LOG_WARNING: 'WARNING', syslog.LOG_ERR: 'ERROR', syslog.LOG_CRIT: 'CRITICAL', syslog.LOG_DEBUG: 'DEBUG', } def openlog(): """Initialize the BIT logger system (which uses syslog) Esp. sets the app name as identifier for the log entries in the syslog. Attention: Call it in each sub process that uses logging. """ syslog.openlog(SYSLOG_IDENTIFIER) atexit.register(closelog) def changeProfile(profile_id, profile_name): global SYSLOG_MESSAGE_PREFIX SYSLOG_MESSAGE_PREFIX = f'{profile_name}({profile_id}) :: ' def closelog(): syslog.closelog() def _do_syslog(message: str, level: int) -> str: syslog.syslog(level, '{}{}: {}'.format( SYSLOG_MESSAGE_PREFIX, _level_names[level], message)) def critical(msg, parent=None, traceDepth=0): if DEBUG: msg = _debugHeader(parent, traceDepth) + ' ' + msg print(f'{bcolors.CRITICAL}CRITICAL{bcolors.ENDC}: {msg}', file=sys.stderr) _do_syslog(msg, syslog.LOG_CRIT) def error(msg, parent=None, traceDepth=0): if DEBUG: msg = _debugHeader(parent, traceDepth) + ' ' + msg print(f'{bcolors.FAIL}ERROR{bcolors.ENDC}: {msg}', file=sys.stderr) _do_syslog(msg, syslog.LOG_ERR) def warning(msg, parent=None, traceDepth=0): if DEBUG: msg = _debugHeader(parent, traceDepth) + ' ' + msg print(f'{bcolors.WARNING}WARNING{bcolors.ENDC}: {msg}', file=sys.stderr) _do_syslog(msg, syslog.LOG_WARNING) def info(msg, parent=None, traceDepth=0): if DEBUG: msg = _debugHeader(parent, traceDepth) + ' ' + msg print(f'{bcolors.OKGREEN}INFO{bcolors.ENDC}: {msg}', file=sys.stderr) _do_syslog(msg, syslog.LOG_INFO) def debug(msg, parent=None, traceDepth=0): if not DEBUG: return msg = _debugHeader(parent, traceDepth) + ' ' + msg print(f'{bcolors.OKBLUE}DEBUG{bcolors.ENDC}: {msg}', file=sys.stderr) _do_syslog(msg, syslog.LOG_DEBUG) def _debugHeader(parent, traceDepth): frame = sys._getframe(2 + traceDepth) line = frame.f_lineno func = frame.f_code.co_name fdir, fname = os.path.split(frame.f_code.co_filename) fmodule = os.path.basename(fdir) fclass = f'{parent.__class__.__name__}.' if parent else '' return f'[{fmodule}/{fname}:{line} {fclass}{func}]' backintime-1.5.4/common/man/000077500000000000000000000000001477034762000157045ustar00rootroot00000000000000backintime-1.5.4/common/man/C/000077500000000000000000000000001477034762000160665ustar00rootroot00000000000000backintime-1.5.4/common/man/C/backintime-askpass.1000066400000000000000000000017711477034762000217270ustar00rootroot00000000000000.TH backintime-askpass 1 "March 2025" "version 1.5.4" "USER COMMANDS" .SH NAME backintime-askpass \- a simple backup tool for Linux. .PP This is the command line tool for piping passwords into ssh/sshfs and encfs. .SH SYNOPSIS .B backintime-askpass .SH DESCRIPTION Back In Time is a simple backup tool for Linux. This is a helper tool for piping passwords into ssh/sshfs and encfs. Options will will be read from environ variables. It doesn't provide any useful enduser service. .SH ENVIRON .TP ASKPASS_PROFILE_ID Back In Time Profile-ID. .TP ASKPASS_MODE Backup mode (or backend). Take a look at 'man backintime-config' section \fIprofile.snapshots.mode\fR .TP ASKPASS_TEMP Temp FIFO socket used to pipe the password .SH SEE ALSO .BR backintime (1), .BR backintime-qt (1), .BR backintime-config (1), .PP \fBBack In Time\fP project website: https://github.com/bit-team/backintime .PP \fBBack In Time\fP mailing list: https://mail.python.org/mailman3/lists/bit-dev.python.org .SH AUTHOR \fBBack In Time\fP Team backintime-1.5.4/common/man/C/backintime-config.1000066400000000000000000000462341477034762000215320ustar00rootroot00000000000000.TH backintime-config 1 "November 2024" "version 1.5.4" "USER COMMANDS" .SH NAME config \- BackInTime configuration files. .SH SYNOPSIS ~/.config/backintime/config .br /etc/backintime/config .SH DESCRIPTION Back In Time was developed as pure GUI program and so most functions are only usable with backintime-qt. But it is possible to use Back In Time e.g. on a headless server. You have to create the configuration file (~/.config/backintime/config) manually. Look inside /usr/share/doc/backintime\-common/examples/ for examples. .PP The configuration file has the following format: .br keyword=arguments .PP Arguments don't need to be quoted. All characters are allowed except '='. .PP Run 'backintime check-config' to verify the configfile, create the snapshot folder and crontab entries. .SH POSSIBLE KEYWORDS .IP "\fIglobal.hash_collision\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Internal value used to prevent hash collisions on mountpoints. Do not change this. .PP Default: 0 .RE .IP "\fIglobal.language\fR" 6 .RS Type: str Allowed Values: text .br Language code (ISO 639) used to translate the user interface. If empty the operating systems current local is used. If 'en' the translation is not active and the original English source strings are used. It is the same if the value is unknown. .PP Default: '' .RE .IP "\fIglobal.use_flock\fR" 6 .RS Type: bool Allowed Values: true|false .br Prevent multiple snapshots (from different profiles or users) to be run at the same time .PP Default: false .RE .IP "\fIprofile.name\fR" 6 .RS Type: str Allowed Values: text .br Name of this profile. .PP Default: Main profile .RE .IP "\fIprofile.schedule.custom_time\fR" 6 .RS Type: str Allowed Values: comma separated int (8,12,18,23) or */3 .br Custom hours for cronjob. Only valid for \fIprofile.schedule.mode\fR = 19 .PP Default: 8,12,18,23 .RE .IP "\fIprofile.schedule.day\fR" 6 .RS Type: int Allowed Values: 1-28 .br Which day of month the cronjob should run? Only valid for \fIprofile.schedule.mode\fR >= 40 .PP Default: 1 .RE .IP "\fIprofile.schedule.debug\fR" 6 .RS Type: bool Allowed Values: true|false .br Enable debug output to system log for schedule mode. .PP Default: false .RE .IP "\fIprofile.schedule.mode\fR" 6 .RS Type: int Allowed Values: 0|1|2|4|7|10|12|14|16|18|19|20|25|27|30|40|80 .br Which schedule used for crontab. The crontab entry will be generated with 'backintime check-config'. .br 0 = Disabled .br 1 = at every boot .br 2 = every 5 minute .br 4 = every 10 minute .br 7 = every 30 minute .br 10 = every hour .br 12 = every 2 hours .br 14 = every 4 hours .br 16 = every 6 hours .br 18 = every 12 hours .br 19 = custom defined hours .br 20 = every day .br 25 = daily anacron .br 27 = when drive get connected .br 30 = every week .br 40 = every month .br 80 = every year .PP Default: 0 .RE .IP "\fIprofile.schedule.repeatedly.period\fR" 6 .RS Type: int Allowed Values: 0-99999 .br How many units to wait between new snapshots with anacron? Only valid for \fIprofile.schedule.mode\fR = 25|27 .PP Default: 1 .RE .IP "\fIprofile.schedule.repeatedly.unit\fR" 6 .RS Type: int Allowed Values: 10|20|30|40 .br Units to wait between new snapshots with anacron. .br 10 = hours .br 20 = days .br 30 = weeks .br 40 = months .br Only valid for \fIprofile.schedule.mode\fR = 25|27 .PP Default: 20 .RE .IP "\fIprofile.schedule.time\fR" 6 .RS Type: int Allowed Values: 0-2400 .br Position-coded number with the format "hhmm" to specify the hour and minute the cronjob should start (eg. 2015 means a quarter past 8pm). Leading zeros can be omitted (eg. 30 = 0030). Only valid for \fIprofile.schedule.mode\fR = 20 (daily), 30 (weekly), 40 (monthly) and 80 (yearly) .PP Default: 0 .RE .IP "\fIprofile.schedule.weekday\fR" 6 .RS Type: int Allowed Values: 1 = monday \- 7 = sunday .br Which day of week the cronjob should run? Only valid for \fIprofile.schedule.mode\fR = 30 .PP Default: 7 .RE .IP "\fIprofile.snapshots.backup_on_restore.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Rename existing files before restore into FILE.backup.YYYYMMDD .PP Default: true .RE .IP "\fIprofile.snapshots.bwlimit.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Limit rsync bandwidth usage over network. Use this with mode SSH. For mode Local you should rather use ionice. .PP Default: false .RE .IP "\fIprofile.snapshots.bwlimit.value\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Bandwidth limit in KB/sec. .PP Default: 3000 .RE .IP "\fIprofile.snapshots.continue_on_errors\fR" 6 .RS Type: bool Allowed Values: true|false .br Continue on errors. This will keep incomplete snapshots rather than deleting and start over again. .PP Default: true .RE .IP "\fIprofile.snapshots.copy_links\fR" 6 .RS Type: bool Allowed Values: true|false .br When symlinks are encountered, the item that they point to (the reference) is copied, rather than the symlink. .PP Default: false .RE .IP "\fIprofile.snapshots.copy_unsafe_links\fR" 6 .RS Type: bool Allowed Values: true|false .br This tells rsync to copy the referent of symbolic links that point outside the copied tree. Absolute symlinks are also treated like ordinary files. .PP Default: false .RE .IP "\fIprofile.snapshots.cron.ionice\fR" 6 .RS Type: bool Allowed Values: true|false .br Run cronjobs with 'ionice \-c2 \-n7'. This will give BackInTime the lowest IO bandwidth priority to not interrupt any other working process. .PP Default: true .RE .IP "\fIprofile.snapshots.cron.nice\fR" 6 .RS Type: bool Allowed Values: true|false .br Run cronjobs with 'nice \-n19'. This will give BackInTime the lowest CPU priority to not interrupt any other working process. .PP Default: true .RE .IP "\fIprofile.snapshots.cron.redirect_stderr\fR" 6 .RS Type: bool Allowed Values: true|false .br redirect stderr to /dev/null in cronjobs .PP Default: False .RE .IP "\fIprofile.snapshots.cron.redirect_stdout\fR" 6 .RS Type: bool Allowed Values: true|false .br redirect stdout to /dev/null in cronjobs .PP Default: true .RE .IP "\fIprofile.snapshots.dont_remove_named_snapshots\fR" 6 .RS Type: bool Allowed Values: true|false .br Keep snapshots with names during smart_remove. .PP Default: true .RE .IP "\fIprofile.snapshots.exclude.bysize.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Enable exclude files by size. .PP Default: false .RE .IP "\fIprofile.snapshots.exclude.bysize.value\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Exclude files bigger than value in MiB. With 'Full rsync mode' disabled this will only affect new files because for rsync this is a transfer option, not an exclude option. So big files that has been backed up before will remain in snapshots even if they had changed. .PP Default: 500 .RE .IP "\fIprofile.snapshots.exclude..value\fR" 6 .RS Type: str Allowed Values: file, folder or pattern (relative or absolute) .br Exclude this file or folder. must be a counter starting with 1 .PP Default: '' .RE .IP "\fIprofile.snapshots.exclude.size\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Quantity of profile.snapshots.exclude. entries. .PP Default: \-1 .RE .IP "\fIprofile.snapshots.include..type\fR" 6 .RS Type: int Allowed Values: 0|1 .br Specify if \fIprofile.snapshots.include..value\fR is a folder (0) or a file (1). .PP Default: 0 .RE .IP "\fIprofile.snapshots.include..value\fR" 6 .RS Type: str Allowed Values: absolute path .br Include this file or folder. must be a counter starting with 1 .PP Default: '' .RE .IP "\fIprofile.snapshots.include.size\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Quantity of profile.snapshots.include. entries. .PP Default: \-1 .RE .IP "\fIprofile.snapshots.keep_only_one_snapshot.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br NOT YET IMPLEMENTED. Remove all snapshots but one. .PP Default: false .RE .IP "\fIprofile.snapshots.local.nocache\fR" 6 .RS Type: bool Allowed Values: true|false .br Run rsync on local machine with 'nocache'. This will prevent files from being cached in memory. .PP Default: false .RE .IP "\fIprofile.snapshots.local_encfs.path\fR" 6 .RS Type: str Allowed Values: absolute path .br Where to save snapshots in mode 'local_encfs'. .PP Default: '' .RE .IP "\fIprofile.snapshots.log_level\fR" 6 .RS Type: int Allowed Values: 1-3 .br Log level used during takeSnapshot. .br 1 = Error .br 2 = Changes .br 3 = Info .PP Default: 3 .RE .IP "\fIprofile.snapshots.min_free_inodes.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Remove snapshots until \fIprofile.snapshots.min_free_inodes.value\fR free inodes in % is reached. .PP Default: false .RE .IP "\fIprofile.snapshots.min_free_inodes.value\fR" 6 .RS Type: int Allowed Values: 1-15 .br Keep at least value % free inodes. .PP Default: 2 .RE .IP "\fIprofile.snapshots.min_free_space.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Remove snapshots until \fIprofile.snapshots.min_free_space.value\fR free space is reached. .PP Default: false .RE .IP "\fIprofile.snapshots.min_free_space.unit\fR" 6 .RS Type: int Allowed Values: 10|20 .br 10 = MB .br 20 = GB .PP Default: 20 .RE .IP "\fIprofile.snapshots.min_free_space.value\fR" 6 .RS Type: int Allowed Values: 1-99999 .br Keep at least value + unit free space. .PP Default: 1 .RE .IP "\fIprofile.snapshots.mode\fR" 6 .RS Type: str Allowed Values: local|local_encfs|ssh|ssh_encfs .br Use mode (or backend) for this snapshot. Look at 'man backintime' section 'Modes'. .PP Default: local .RE .IP "\fIprofile.snapshots..password.save\fR" 6 .RS Type: bool Allowed Values: true|false .br Save password to system keyring (gnome-keyring or kwallet). must be the same as \fIprofile.snapshots.mode\fR .PP Default: false .RE .IP "\fIprofile.snapshots..password.use_cache\fR" 6 .RS Type: bool Allowed Values: true|false .br Cache password in RAM so it can be read by cronjobs. Security issue: root might be able to read that password, too. must be the same as \fIprofile.snapshots.mode\fR .PP Default: true if home is not encrypted .RE .IP "\fIprofile.snapshots.no_on_battery\fR" 6 .RS Type: bool Allowed Values: true|false .br Don't take snapshots if the Computer runs on battery. .PP Default: false .RE .IP "\fIprofile.snapshots.notify.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Display notifications (errors, warnings) through libnotify. .PP Default: true .RE .IP "\fIprofile.snapshots.one_file_system\fR" 6 .RS Type: bool Allowed Values: true|false .br Use rsync's "--one-file-system" to avoid crossing filesystem boundaries when recursing. .PP Default: false .RE .IP "\fIprofile.snapshots.path\fR" 6 .RS Type: str Allowed Values: absolute path .br Where to save snapshots in mode 'local'. This path must contain a folderstructure like 'backintime///' .PP Default: '' .RE .IP "\fIprofile.snapshots.path.host\fR" 6 .RS Type: str Allowed Values: text .br Set Host for snapshot path .PP Default: local hostname .RE .IP "\fIprofile.snapshots.path.profile\fR" 6 .RS Type: str Allowed Values: 1-99999 .br Set Profile-ID for snapshot path .PP Default: current Profile-ID .RE .IP "\fIprofile.snapshots.path.user\fR" 6 .RS Type: str Allowed Values: text .br Set User for snapshot path .PP Default: local username .RE .IP "\fIprofile.snapshots.path.uuid\fR" 6 .RS Type: str Allowed Values: text .br Devices uuid used to automatically set up udev rule if the drive is not connected. .PP Default: '' .RE .IP "\fIprofile.snapshots.preserve_acl\fR" 6 .RS Type: bool Allowed Values: true|false .br Preserve ACL. The source and destination systems must have compatible ACL entries for this option to work properly. .PP Default: false .RE .IP "\fIprofile.snapshots.preserve_xattr\fR" 6 .RS Type: bool Allowed Values: true|false .br Preserve extended attributes (xattr). .PP Default: false .RE .IP "\fIprofile.snapshots.remove_old_snapshots.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Remove all snapshots older than value + unit .PP Default: true .RE .IP "\fIprofile.snapshots.remove_old_snapshots.unit\fR" 6 .RS Type: int Allowed Values: 20|30|80 .br 20 = days .br 30 = weeks .br 80 = years .PP Default: 80 .RE .IP "\fIprofile.snapshots.remove_old_snapshots.value\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Snapshots older than this times units will be removed .PP Default: 10 .RE .IP "\fIprofile.snapshots.rsync_options.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Past additional options to rsync .PP Default: false .RE .IP "\fIprofile.snapshots.rsync_options.value\fR" 6 .RS Type: str Allowed Values: text .br rsync options. Options must be quoted e.g. \-\-exclude-from="/path/to/my exclude file" .PP Default: '' .RE .IP "\fIprofile.snapshots.smart_remove\fR" 6 .RS Type: bool Allowed Values: true|false .br Run smart_remove to clean up old snapshots after a new snapshot was created. .PP Default: false .RE .IP "\fIprofile.snapshots.smart_remove.keep_all\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Keep all snapshots for X days. .PP Default: 2 .RE .IP "\fIprofile.snapshots.smart_remove.keep_one_per_day\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Keep one snapshot per day for X days. .PP Default: 7 .RE .IP "\fIprofile.snapshots.smart_remove.keep_one_per_month\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Keep one snapshot per month for X month. .PP Default: 24 .RE .IP "\fIprofile.snapshots.smart_remove.keep_one_per_week\fR" 6 .RS Type: int Allowed Values: 0-99999 .br Keep one snapshot per week for X weeks. .PP Default: 4 .RE .IP "\fIprofile.snapshots.smart_remove.run_remote_in_background\fR" 6 .RS Type: bool Allowed Values: true|false .br If using mode SSH or SSH-encrypted, run smart_remove in background on remote machine .PP Default: false .RE .IP "\fIprofile.snapshots.ssh.check_commands\fR" 6 .RS Type: bool Allowed Values: true|false .br Check if all commands (used during takeSnapshot) work like expected on the remote host. .PP Default: true .RE .IP "\fIprofile.snapshots.ssh.check_ping\fR" 6 .RS Type: bool Allowed Values: true|false .br Check if the remote host is available before trying to mount. .PP Default: true .RE .IP "\fIprofile.snapshots.ssh.cipher\fR" 6 .RS Type: str Allowed Values: default | aes192-cbc | aes256-cbc | aes128-ctr | aes192-ctr | aes256-ctr | arcfour | arcfour256 | arcfour128 | aes128-cbc | 3des-cbc | blowfish-cbc | cast128-cbc .br Cipher that is used for encrypting the SSH tunnel. Depending on the environment (network bandwidth, cpu and hdd performance) a different cipher might be faster. .PP Default: default .RE .IP "\fIprofile.snapshots.ssh.host\fR" 6 .RS Type: str Allowed Values: IP or domain address .br Remote host used for mode 'ssh' and 'ssh_encfs'. .PP Default: '' .RE .IP "\fIprofile.snapshots.ssh.ionice\fR" 6 .RS Type: bool Allowed Values: true|false .br Run rsync and other commands on remote host with 'ionice \-c2 \-n7' .PP Default: false .RE .IP "\fIprofile.snapshots.ssh.max_arg_length\fR" 6 .RS Type: int Allowed Values: 0, >700 .br Maximum command length of commands run on remote host. This can be tested for all ssh profiles in the configuration with 'python3 /usr/share/backintime/common/sshMaxArg.py LENGTH'. .br 0 = unlimited .PP Default: 0 .RE .IP "\fIprofile.snapshots.ssh.nice\fR" 6 .RS Type: bool Allowed Values: true|false .br Run rsync and other commands on remote host with 'nice \-n19' .PP Default: false .RE .IP "\fIprofile.snapshots.ssh.nocache\fR" 6 .RS Type: bool Allowed Values: true|false .br Run rsync on remote host with 'nocache'. This will prevent files from being cached in memory. .PP Default: false .RE .IP "\fIprofile.snapshots.ssh.path\fR" 6 .RS Type: str Allowed Values: absolute or relative path .br Snapshot path on remote host. If the path is relative (no leading '/') it will start from remote Users homedir. An empty path will be replaced with './'. .PP Default: '' .RE .IP "\fIprofile.snapshots.ssh.port\fR" 6 .RS Type: int Allowed Values: 0-65535 .br SSH Port on remote host. .PP Default: 22 .RE .IP "\fIprofile.snapshots.ssh.prefix.enabled\fR" 6 .RS Type: bool Allowed Values: true|false .br Add prefix to every command which run through SSH on remote host. .PP Default: false .RE .IP "\fIprofile.snapshots.ssh.prefix.value\fR" 6 .RS Type: str Allowed Values: text .br Prefix to run before every command on remote host. Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to add a prefix for rsync use \fIprofile.snapshots.rsync_options.value\fR with --rsync-path="FOO=bar:\\$FOO /usr/bin/rsync" .PP Default: 'PATH=/opt/bin:/opt/sbin:\\$PATH' .RE .IP "\fIprofile.snapshots.ssh.private_key_file\fR" 6 .RS Type: str Allowed Values: absolute path to private key file .br Private key file used for password-less authentication on remote host. .PP Default: ~/.ssh/id_dsa .RE .IP "\fIprofile.snapshots.ssh.proxy_host\fR" 6 .RS Type: str Allowed Values: text .br Proxy host used to connect to remote host. .PP Default: IP or domain address .RE .IP "\fIprofile.snapshots.ssh.proxy_host_port\fR" 6 .RS Type: int Allowed Values: 0-65535 .br Proxy host port used to connect to remote host. .PP Default: 22 .RE .IP "\fIprofile.snapshots.ssh.proxy_user\fR" 6 .RS Type: str Allowed Values: text .br Remote SSH user .PP Default: the local users name .RE .IP "\fIprofile.snapshots.ssh.user\fR" 6 .RS Type: str Allowed Values: text .br Remote SSH user .PP Default: local users name .RE .IP "\fIprofile.snapshots.take_snapshot_regardless_of_changes\fR" 6 .RS Type: bool Allowed Values: true|false .br Create a new snapshot regardless if there were changes or not. .PP Default: false .RE .IP "\fIprofile.snapshots.use_checksum\fR" 6 .RS Type: bool Allowed Values: true|false .br Use checksum to detect changes rather than size + time. .PP Default: false .RE .IP "\fIprofile.snapshots.user_backup.ionice\fR" 6 .RS Type: bool Allowed Values: true|false .br Run BackInTime with 'ionice \-c2 \-n7' when taking a manual snapshot. This will give BackInTime the lowest IO bandwidth priority to not interrupt any other working process. .PP Default: false .RE .IP "\fIprofile.user_callback.no_logging\fR" 6 .RS Type: bool Allowed Values: true|false .br Do not catch std{out|err} from user-callback script. The script will only write to current TTY. Default is to catch std{out|err} and write it to syslog and TTY again. .PP Default: false .RE .IP "\fIprofiles\fR" 6 .RS Type: str Allowed Values: int separated by colon (e.g. 1:3:4) .br All active Profiles ( in profile.snapshots...). .PP Default: 1 .RE .IP "\fIprofiles.version\fR" 6 .RS Type: int Allowed Values: 1 .br Internal version of profiles config. .PP Default: 1 .RE .SH SEE ALSO backintime, backintime-qt. .PP Back In Time also has a website: https://github.com/bit-team/backintime .SH AUTHOR This manual page was written by BIT Team(). backintime-1.5.4/common/man/C/backintime.1000066400000000000000000000334321477034762000202630ustar00rootroot00000000000000.TH backintime 1 "March 2025" "version 1.5.4" "USER COMMANDS" .SH NAME backintime \- a simple backup tool for Linux. .PP This is the command line tool. The graphical tool is backintime-qt. .SH SYNOPSIS .B backintime [\-\-checksum] [\-\-config PATH] [\-\-debug] [\-\-delete] [\-\-help | \-h] [\-\-keep\-mount] [\-\-license] [\-\-local\-backup | \-\-no\-local\-backup] [\-\-no\-crontab] [\-\-only\-new] [\-\-profile NAME | \-\-profile\-id ID] [\-\-quiet] [\-\-share\-path PATH] [\-\-version] { backup | backup\-job | benchmark-cipher [FILE-SIZE] | check-config | decode [PATH] | last\-snapshot | last\-snapshot\-path | pw\-cache [start|stop|restart|reload|status] | remove[\-and\-do\-not\-ask\-again] [SNAPSHOT_ID] | restore [WHAT [WHERE [SNAPSHOT_ID]]] | shutdown | smart\-remove | snapshots\-list | snapshots\-list\-path | snapshots\-path | unmount } .SH DESCRIPTION Back In Time is a simple backup tool for Linux. The backup is done by taking snapshots of a specified set of folders. .PP All you have to do is configure: where to save snapshots, what folders to backup. You can also specify a backup schedule: disabled, every 5 minutes, every 10 minutes, every hour, every day, every week, every month. To configure it use one of the graphical interfaces available (backintime-gnome or backintime-kde4). .PP It acts as a 'user mode' backup tool. This means that you can backup/restore only folders you have write access to (actually you can backup read\-only folders, but you can't restore them). .PP If you want to run it as root you need to use 'sudo -i backintime'. .PP A new snapshot is created only if something changed since the last snapshot (if any). .PP A snapshot contains all the files from the selected folders (except for exclude patterns). In order to reduce disk space it use hard\-links (if possible) between snapshots for unchanged files. This way a file of 10MiB, unchanged for 10 snapshots, will use only 10MiB on the disk. .PP When you restore a file 'A', if it already exists on the file system it will be renamed to 'A.backup.currentdate'. .PP For automatic backup it use 'cron' so there is no need for a daemon, but 'cron' must be running. .SS Modes .IP "\fILocal\fR" 4 .RS Store snapshots on local HDD's (internal or USB). The drive has to be mounted before creating a new snapshot. .RE .IP "\fILocal encrypted\fR" 4 .RS Store encrypted snapshots on local HDD's (internal or USB). Back In Time uses 'encfs' with standard configuration to encrypt all data. Please take a look at \fIA NOTE ON SECURITY\fR. .RE .IP "\fISSH \fR" 4 .RS With Mode set to SSH you can store the backup on a remote host using the SecureShellHost protocol (ssh). The remote path will be mount local using sshfs to provide file-access for the graphical interface and the backup process. Rsync and other processes called during backup process will run directly on the remote host using ssh. .PP To prepare your user account for ssh-mode you have to create a password-less login to the remote host (for further information look at http://www.debian-administration.org/articles/152). Type in terminal 'ssh-keygen \-t rsa' hit enter for default path and enter a passphrase for the private key. .PP Finally type 'ssh-copy-id \-i ~/.ssh/id_rsa.pub @' and enter your password on remote host. .PP In Settingsdialog you need to set the host and remote user. If you enter a relative path (no leading / ) it will start from remote users homedir. The password has to be the passphrase for your private key. .PP .B Cipher (the algorithm used to encrypt the data during transfer) .br To optimize performance you can choose the cipher used by ssh. Depending on your environment you can have a massive speed increase compared to the default cipher. .PP \fIbenchmark\-cipher\fR will give you an overview over which cipher is the fastest in your environment. .PP If the bottleneck of your environment is the hard-drive or the network you will not see a big difference between the ciphers. In this case you should rather stay on 'default'. .PP Please read security information about the cipher before using them in untrusted networks (Wifi, Internet). Some of them (Arcfour, 3DES, ...) should be handled as not secure anymore. .PP .B "Remote Host" .br If your remote host is an embedded Linux NAS or any other device with limited functions, you could run into some problems caused by feature-less commands. For example some devices may not have hardlink support for 'cp', 'chmod' and 'rsync'. In this case it may help to install so-called Optware or Entware on your device if available. .PP .B WARNING: THIS IS ONLY FOR EXPERIENCED USERS! .br If you don't know how to compile packages and how to modify a Linux system you should NOT try to do this. There is a significant chance to break your device and make it completely unusable with the following procedure. We will not take any warranty for this. Make a backup of your device before proceed! You have been warned! .PP You should install at least packages called 'bash', 'coreutils' and 'rsync'. You will have to change users default shell from '/bin/sh' to '/opt/bin/bash' in '/etc/passwd'. To add '/opt/bin:/opt/sbin:' to the start of the PATH environment you can use 'Add prefix to SSH commands' in 'Expert Options' with 'PATH=/opt/bin:/opt/sbin:\\$PATH'. .PP To check if it does work you can compare the output of '/bin/cp \-\-help' and '/opt/bin/cp \-\-help'. If 'ssh @ cp \-\-help' called from your PC will print the same as '/opt/bin/cp \-\-help' called on the remote host (via interactive ssh session) you are ready to go. .PP If you have questions on how to install and configure the Optware please refer to the community of your device. You can also take a look on Back In Time FAQ on GitHub https://github.com/bit-team/backintime/blob/-/FAQ.md .PP If you successfully modified your device to be able to make backups over ssh, it would be nice if you write a 'How to' on Launchpad's Answers so we can add this to the FAQ. .RE .IP "\fISSH encrypted\fR" 4 .RS Store encrypted snapshots on remote hosts using SSH. Backintime uses 'encfs \-\-reverse' to mount the root filesystem '/'. Rsync will sync this encrypted view of '/' to a remote host over SSH. All encoding will be done on the local machine. So the password will never be exposed to the remote host and you can use the (normally) more powerful processor in you local machine for encryption instead of weak NAS CPU's. The downside on this is 'encfs \-\-reverse' does not support 'Filename Initialization Vector Chaining' and 'Per-File Initialization Vectors' from the standard configuration (take a look at 'man encfs' for further information). Please take a look at \fIA NOTE ON SECURITY\fR. .PP Because of all data is transferred encrypted the log output shows encrypted filenames, too. In the Logview-Dialog you can use 'decode' option to decrypt the paths automatically or you can use 'backintime decode' to manually decrypt paths. Back In Time will show all snapshots decoded so you can browse all files as normal. .PP Exclude does not support wildcards ('foo*', '[fF]oo', 'fo?') because after encoding a file these wildcards can't match any more. Only separate asterisk that match a full file or folder will work ('foo/*', 'foo/**/bar'). All other excludes that have wildcards will be silently ignored. .PP Please refer to the 'SSH' section above for information on setting up the SSH connection. .RE .SS Password If 'Save Password to Keyring' is activated Back In Time will save the Password into GnomeKeyring (Seahorse) or KDE-KWallet. Both are secure password storages which encrypt the password with the users login-password. So they can only be accessed if the user is logged in. .PP A backup cronjob during the user isn't logged in can not collect the password from keyring. Also if the homedir is encrypted the keyring is not accessible from cronjobs (even if the user is logged in). For these cases the password can be cached in RAM. If 'Cache Password for Cron' is activated Back In Time will start a small daemon in user-space which will collect the password from keyring and provide them for cronjobs. They will never be written to the harddrive but a user with root permissions could access the daemon and read the password. .SS user-callback During backup process the application can call a user callback at different steps. This callback is "$XDG_CONFIG_HOME/backintime/user-callback" (by default $XDG_CONFIG_HOME is ~/.config). .PP The first argument is the profile id (1=Main Profile, ...). .PP The second argument is the profile name. .PP The third argument is the reason: .RS .TP 1 Backup process begins. .TP 2 Backup process ends. .TP 3 A new snapshot was taken. The extra arguments are snapshot ID and snapshot path. .TP 4 There was an error. The second argument is the error code. .RS Error codes: .TP 1 The application is not configured. .TP 2 A "take snapshot" process is already running. .TP 3 Can't find snapshots folder (is it on a removable drive ?). .TP 4 A snapshot for "now" already exist. .RE .TP 5 On (graphical) App start. .TP 6 On (graphical) App close. .TP 7 Mount all necessary drives. .TP 8 Unmount all drives. .SH OPTIONS .TP \-\-checksum Force to use checksum for checking if files have been changed. This is the same as 'Use checksum to detect changes' in Options. But you can use this to periodically run checksums from cronjobs. Only valid with \fIbackup\fR, \fIbackup-job\fR and \fIrestore\fR. .TP \-\-config PATH Read config from PATH. Default = ~/.config/backintime/config .TP --debug Show debug messages. .TP --delete Restore and delete newer files which are not in the snapshot. WARNING: deleting files in filesystem root could break your whole system!!! Only valid with \fIrestore\fR. .TP \-h, \-\-help Display a short help .TP \-\-keep\-mount Don't unmount on exit. Only valid with \fIsnapshots\-path\fR, \fIsnapshots\-list\-path\fR and \fIlast\-snapshot\-path\fR. .TP \-\-license Show license .TP --local-backup Create backup files before changing local files. Only valid with \fIrestore\fR. .TP --no-crontab Do not install crontab entries. Only valid with \fIcheck-config\fR. .TP --no-local-backup Temporary disable creation of backup files before changing local files. Only valid with \fIrestore\fR. .TP --only-new Only restore files which does not exist or are newer than those in destination. Using "rsync --update" option. Only valid with \fIrestore\fR. .TP \-\-profile NAME Select profile by name .TP \-\-profile\-id ID Select profile by id .TP \-\-quiet Suppress status messages on standard output. .TP \-\-share\-path PATH Write runtime data (locks, messages, log and mountpoints) to PATH. .TP \-v, \-\-version Show version .SH COMMANDS .TP backup | \-b | \-\-backup Take a snapshot now. .TP backup\-job | \-\-backup\-job Take a snapshot (if needed) depending on schedule rules (used for cron jobs). Back In Time will run in background for this. .TP benchmark-cipher | \-\-benchmark-cipher [FILE-SIZE] Show a benchmark of all ciphers for ssh transfer. .TP check-config Verify the profile in config, create snapshot path and crontab entries. .TP decode | \-\-decode [PATH] Decode encrypted PATH. If no PATH is given Back In Time will read paths from standard input. .TP last\-snapshot | \-\-last\-snapshot Display last snapshot ID (if any) .TP last\-snapshot\-path | \-\-last\-snapshot\-path Display the path to the last snapshot (if any) .TP pw\-cache | \-\-pw\-cache [start|stop|restart|reload|status] Control the Password Cache Daemon. If no argument is given the Password Cache will start in foreground. .TP remove[\-and\-do\-not\-ask\-again] | \-\-remove[\-and\-do\-not\-ask\-again] [SNAPSHOT_ID] Remove the snapshot. If SNAPSHOT_ID is missing it will be prompted. SNAPSHOT_ID can be an index (starting with 0 for the last snapshot) or the exact SnapshotID (19 characters like '20130606-230501-984'). \fIremove\-and\-do\-not\-ask\-again\fR will remove the snapshot immediately. Be careful with this! .TP restore | \-\-restore [WHAT [WHERE [SNAPSHOT_ID]]] Restore file WHAT to path WHERE from snapshot SNAPSHOT_ID. If arguments are missing they will be prompted. To restore to the original path WHERE can be an empty string '' or just press Enter at the prompt. SNAPSHOT_ID can be an index (starting with 0 for the last snapshot) or the exact SnapshotID (19 characters like '20130606-230501-984') .TP shutdown Shutdown the computer after the snapshot is done. .TP smart\-remove Remove snapshots based on the configured Smart-Remove pattern. .TP snapshots\-list | \-\-snapshots\-list Display the list of snapshot IDs (if any) .TP snapshots\-list\-path | \-\-snapshots\-list\-path Display the paths to snapshots (if any) .TP snapshots\-path | \-\-snapshots\-path Display path where is saves the snapshots (if configured) .TP unmount | \-\-unmount Unmount the profile. .SH A NOTE ON SECURITY AND ENCFS Because of security issues with EncFS it is planned to remove it from Back In Time. To continue the support of encrypted snapshots it is the goal to replace it with an alternative if possible. See this document for details and the current state of the transition process. .PP https://github.com/bit-team/backintime/doc/ENCRYPT_TRANSITION.md .PP The security issues are mentioned in a security audit from 2014 and not fixed until today. The EnCFS project is not maintained anymore and his former maintainer recommend to switch to GoCryptFS. See the following links for further readings: .IP EncFS Security Audit (updated blog post): https://defuse.ca/audits/encfs.htm .IP EncFS Security Audit (original mailing list entry): https://sourceforge.net/p/encfs/mailman/message/31849549 .IP Back In Time Issue #1734 about transition of the encryption feature: https://github.com/bit-team/backintime/issues/1734 .SH SEE ALSO .BR backintime-qt (1), .BR backintime-config (1), .BR backintime-askpass (1) .PP \fBBack In Time\fP project website: https://github.com/bit-team/backintime .PP \fBBack In Time\fP mailing list: https://mail.python.org/mailman3/lists/bit-dev.python.org .SH AUTHOR \fBBack In Time\fP Team backintime-1.5.4/common/mount.py000066400000000000000000001160231477034762000166500ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # SPDX-FileCopyrightText: © 2012-2022 Taylor Raack # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """The mount API. The high-level mount API is :py:class:`Mount` and handles mount, umount, remount and checks for *Back In Time*. The low-level mount API is :py:class:`MountControl`. The latter can be used to create own mounting services via subclassing it. See the following example. Example: See this template to create your own mounting service by inheriting from :py:class:`MountControl`. All you need to do is: - Add your settings in ``qt/settingsdialog.py``. - Add settings in ``common/config.py``. - Use the following template class ``MountDummy``, rename and modify it to your needs. - Please use ``self.currentMountpoint`` as your local mountpoint. - Your class should inherit from :py:class:`mount.MountControl`. As real usage example see the two classes :py:class:`sshtools.SSH` and :py:class:`encfstools.EncFS_mount`. This is the template: :: class MountDummy(mount.MountControl): def __init__(self, *args, **kwargs): super(MountDummy, self).__init__(*args, **kwargs) self.all_kwargs = {} # First we need to map the settings. # If is in kwargs (e.g. if this class is called with # dummytools.Dummy( = ) this will map self. to # kwargs[]; else self. = from config # e.g. self.setattrKwargs(, , **kwargs) self.setattrKwargs( 'user', self.config.get_dummy_user(self.profile_id), **kwargs) self.setattrKwargs( 'host', self.config.get_dummy_host(self.profile_id), **kwargs) self.setattrKwargs( 'port', self.config.get_dummy_port(self.profile_id), **kwargs) self.setattrKwargs( 'password', self.config.password(self.parent, self.profile_id), store = False, **kwargs) self.setDefaultArgs() # If self.currentMountpoint is not the remote snapshot path # you can specify a subfolder of self.currentMountpoint for # the symlink self.symlink_subfolder = None self.mountproc = 'dummy' self.log_command = '%s: %s@%s' % (self.mode, self.user, self.host) def _mount(self): # Mount the service # Implement your mountprocess here. pass def _umount(self): # Umount the service # Implement your unmountprocess here. pass def preMountCheck(self, first_run = False): # Check what ever conditions must be given for the mount to be # done successful. # Raise MountException('Error description') if service can not mount # return True if everything is okay # all pre|post_[u]mount_check can also be used to prepare # things or clean up return True def postMountCheck(self): # Check if mount was successful # Raise MountException('Error description') if not return True def preUmountCheck(self): # Check if service is safe to umount # Raise MountException('Error description') if not return True def postUmountCheck(self): # Check if umount successful # Raise MountException('Error description') if not return True """ import getpass import json import os import subprocess from time import sleep from zlib import crc32 from pathlib import Path import config import logger import password import tools from exceptions import HashCollision, MountException class Mount: """ This is the high-level mount API. This will handle mount, umount, remount and checks on the low-level :py:class:`MountControl` subclass backends for BackInTime. If ``cfg`` is ``None`` this will load the default config. If ``profile_id`` is ``None`` it will use :py:func:`configfile.ConfigFileWithProfiles.currentProfile`. If the current profile uses Password-Cache and the Password-Cache is not running this will try to start it. Args: cfg (config.Config): Current config. profile_id (str): Profile ID to be used. tmp_mount (bool): If ``True`` mount to a temporary destination. parent (QWidget): Parent widget for QDialogs or ``None`` if there is no parent. """ def __init__(self, cfg=None, profile_id=None, tmp_mount=False, parent=None): self.config = cfg or config.Config() self.profile_id = profile_id or self.config.currentProfile() self.tmp_mount = tmp_mount self.parent = parent if self.config.passwordUseCache(self.profile_id): cache = password.Password_Cache(self.config) action = None running = cache.status() if not running: logger.debug('pw-cache is not running', self) action = 'start' if running and not cache.checkVersion(): logger.debug('pw-cache is running but is an old version', self) action = 'restart' bit = tools.which('backintime') if not action is None and not bit is None and len(bit): cmd = [bit, 'pw-cache', action] logger.debug(f'Call command: {cmd}', self) proc = subprocess.Popen(cmd, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL) if proc.returncode: logger.error( f'Failed to {action} pw-cache: {proc.returncode}', self) pass def mount(self, mode=None, check=True, **kwargs): """High-level `mount`. Check if the selected ``mode`` need to be mounted, select the low-level backend and mount it. Args: mode (str): Mode to use. One of 'local', 'ssh', 'local_encfs' or 'ssh_encfs'. check (bool): If ``True`` run :py:func:`MountControl.preMountCheck` before mounting. **kwargs: Keyword arguments paste to low-level :py:class:`MountControl` subclass backend. Returns: str: Hash ID used as mountpoint. Raises: exceptions.MountException: If a check failed. exceptions.HashCollision: If hash ID was used before but umount info wasn't identical. """ self.config.PLUGIN_MANAGER.load(cfg=self.config) self.config.PLUGIN_MANAGER.mount(self.profile_id) if mode is None: mode = self.config.snapshotsMode(self.profile_id) if self.config.SNAPSHOT_MODES[mode][0] is None: # mode doesn't need to mount return 'local' else: while True: # ??? try: mounttools = self.config.SNAPSHOT_MODES[mode][0] backend = mounttools(cfg = self.config, profile_id = self.profile_id, tmp_mount = self.tmp_mount, mode = mode, parent = self.parent, **kwargs) return backend.mount(check = check) except HashCollision as ex: logger.warning(str(ex), self) del backend check = False continue break def umount(self, hash_id=None): """High-level `unmount`. Unmount the low-level backend. This will read unmount infos written next to the mountpoint identified by ``hash_id`` and unmount it. Args: hash_id (bool): Hash ID used as mountpoint before that should get unmounted. Raises: exceptions.MountException: If a check failed. """ self.config.PLUGIN_MANAGER.load(cfg=self.config) self.config.PLUGIN_MANAGER.unmount(self.profile_id) if hash_id is None: hash_id = self.config.current_hash_id if hash_id == 'local': # mode doesn't need to umount return umount_info = os.path.join( self.config._LOCAL_MOUNT_ROOT, hash_id, 'umount') with open(umount_info, 'r') as f: data_string = f.read() f.close() kwargs = json.loads(data_string) mode = kwargs.pop('mode') mounttools = self.config.SNAPSHOT_MODES[mode][0] backend = mounttools(cfg=self.config, profile_id=self.profile_id, tmp_mount=self.tmp_mount, mode=mode, hash_id=hash_id, parent=self.parent, **kwargs) backend.umount() def preMountCheck(self, mode=None, first_run=False, **kwargs): """ High-level check. Run :py:func:`MountControl.preMountCheck` to check if all conditions for :py:func:`Mount.mount` are set. Should be called with ``first_run = True`` to check if new settings are correct before saving them. Args: mode (str): Mode to use. One of 'local', 'ssh', 'local_encfs' or 'ssh_encfs'. first_run (bool): Run intense checks that only need to run after changing settings but not every time before mounting. **kwargs: Keyword arguments paste to low-level :py:class:`MountControl` subclass backend. Returns: bool: ``True`` if all checks where okay. Raises: exceptions.MountException: If a check failed. """ if mode is None: mode = self.config.snapshotsMode(self.profile_id) # sshtools.SSH, encfstools.EncFS_mount, encfstools.EncFS_SSH Mounttools = self.config.SNAPSHOT_MODES[mode][0] # "local" mode if Mounttools is None: # mode doesn't need to mount return True backend = Mounttools(cfg=self.config, profile_id=self.profile_id, tmp_mount=self.tmp_mount, mode=mode, parent=self.parent, **kwargs) return backend.preMountCheck(first_run) def remount(self, new_profile_id, mode = None, hash_id = None, **kwargs): """ High-level `remount`. Unmount the old profile presented by ``hash_id`` and mount new profile ``new_profile_id`` with mode ``mode``. If old and new mounts are the same just add new symlinks and keep the mount. Args map to profiles:: new_profile_id <= new profile mode <= new profile kwargs <= new profile hash_id <= old profile self.profile_id <= old profile Args: new_profile_id (str): Profile ID that should get mounted mode (str): mode to use for new mount. One of 'local', 'ssh', 'local_encfs' or 'ssh_encfs' hash_id (str): Hash ID used as mountpoint on the old mount, that should get unmounted **kwargs: keyword arguments paste to low-level :py:class:`MountControl` subclass backend for the new mount Returns: str: Hash ID used as mountpoint Raises: exceptions.MountException: if a check failed exceptions.HashCollision: if Hash ID was used before but umount info wasn't identical """ if mode is None: mode = self.config.snapshotsMode(new_profile_id) if hash_id is None: hash_id = self.config.current_hash_id if self.config.SNAPSHOT_MODES[mode][0] is None: #new profile don't need to mount. self.umount(hash_id = hash_id) return 'local' if hash_id == 'local': #old profile don't need to umount. self.profile_id = new_profile_id return self.mount(mode = mode, **kwargs) mounttools = self.config.SNAPSHOT_MODES[mode][0] backend = mounttools(cfg = self.config, profile_id = new_profile_id, tmp_mount = self.tmp_mount, mode = mode, parent = self.parent, **kwargs) if backend.compareRemount(hash_id): #profiles uses the same settings. just swap the symlinks backend.removeSymlink(profile_id = self.profile_id) backend.setSymlink(profile_id = new_profile_id, hash_id = hash_id) return hash_id else: #profiles are different. we need to umount and mount again self.umount(hash_id = hash_id) self.profile_id = new_profile_id return self.mount(mode = mode, **kwargs) class MountControl: """This is the low-level mount API. This should be subclassed by backends. Subclasses should have its own ``__init__`` but **must** also call the inherited ``__init__``. See module description (:py:mod:`mount`) for a detailed example. You **must** overwrite methods: - :py:func:`MountControl._mount` You **can** overwrite methods: - :py:func:`MountControl._umount` - :py:func:`MountControl.preMountCheck` - :py:func:`MountControl.postMountCheck` - :py:func:`MountControl.preUmountCheck` - :py:func:`MountControl.postUmountCheck` These arguments (all of type :py:obj:`str`) **must** be defined in ``self`` namespace by subclassing ``__init__`` method: - ``mountproc``: process used to mount - ``log_command``: shortened form of mount command used in logs - ``symlink_subfolder``: mountpoint-subfolder which should be linked Args: cfg (config.Config): current config profile_id (str): profile ID that should be used hash_id (str): crc32 hash used to identify identical mountpoints tmp_mount (bool): if ``True`` mount to a temporary destination parent (QWidget): parent widget for QDialogs or ``None`` if there is no parent symlink (bool): if ``True`` set symlink to mountpoint mode (str): one of ``local``, ``local_encfs``, ``ssh`` or ``ssh_encfs`` hash_collision (int): global value used to prevent hash collisions on mountpoints """ def __init__(self, cfg=None, profile_id=None, hash_id=None, tmp_mount=False, parent=None, symlink=True, *args, **kwargs): # The following members should get valid values from the inheriting # class. self.mode = None self.log_command = None self.mountproc = None self.symlink_subfolder = None self.config = cfg or config.Config() self.profile_id = profile_id or self.config.currentProfile() self.tmp_mount = tmp_mount self.hash_id = hash_id self.parent = parent self.symlink = symlink self.local_host = self.config.host() self.local_user = getpass.getuser() self.pid = str(os.getpid()) self.all_kwargs = {} self.setattrKwargs( 'mode', self.config.snapshotsMode(self.profile_id), **kwargs) self.setattrKwargs( 'hash_collision', self.config.hashCollision(), **kwargs) def setDefaultArgs(self): """ Set some arguments which are necessary for all backends. ``self.all_kwargs`` need to be filled through :py:func:`setattrKwargs` before calling this. """ # self.destination should contain all arguments that are necessary for # mount. args = list(self.all_kwargs.keys()) self.destination = '%s:' % self.all_kwargs['mode'] args.remove('mode') args.sort() for arg in args: self.destination += ' %s' % self.all_kwargs[arg] # Unique id for every different mount settings. Similar settings even # in different profiles will generate the same hash_id and so share # the same mountpoint. if self.hash_id is None: self.hash_id = self.hash(self.destination) # e.g. ~/.local/share/backintime/mnt self.mount_root = self.config._LOCAL_MOUNT_ROOT self.snapshots_path = self.config.snapshotsPath( profile_id=self.profile_id, mode=self.mode, tmp_mount=self.tmp_mount) self.hash_id_path = self.hashIdPath() self.currentMountpoint = self.mountpoint() self.lock_path = self.lockPath() self.umount_info = self.umountInfoPath() def mount(self, check=True): """ Low-level `mount`. Set mountprocess lock and prepare mount, run checks and than call :py:func:`_mount` for the subclassed backend. Finally set mount lock and symlink and release mountprocess lock. Args: check (bool): If ``True`` run :py:func:`preMountCheck` before mounting. Returns: str: Hash ID used as mountpoint. Raises: exceptions.MountException: If a check failed. exceptions.HashCollision: If Hash ID was used before but umount info wasn't identical. """ self.createMountStructure() self.mountProcessLockAcquire() try: if self.mounted(): if not self.compareUmountInfo(): # We probably have a hash collision self.config.incrementHashCollision() raise HashCollision( f'Hash collision occurred in hash_id {self.hash_id}. ' 'Incrementing global value hash_collision and ' 'trying again.') logger.info('Mountpoint {} is already mounted' .format(self.currentMountpoint), self) else: if check: self.preMountCheck() self._mount() self.postMountCheck() logger.info( f'mount {self.log_command} on {self.currentMountpoint}', self) self.writeUmountInfo() except Exception: # ??? raise else: self.mountLockAquire() self.setSymlink() finally: self.mountProcessLockRelease() return self.hash_id def umount(self): """ Low-level `umount`. Set mountprocess lock, run umount checks and call :py:func:`_umount` for the subclassed backend. Finally release mount lock, remove symlink and release mountprocess lock. Raises: exceptions.MountException: if a check failed """ self.mountProcessLockAcquire() msg_begin = f'Mountpoint {self.currentMountpoint} ' try: if not os.path.isdir(self.hash_id_path): logger.info(msg_begin + 'does not exist.', self) else: if not self.mounted(): logger.info(msg_begin + 'is not mounted.', self) else: if self.mountLockCheck(): logger.info(msg_begin + 'still in use. Keep mounted.', self) else: self.preUmountCheck() self._umount() self.postUmountCheck() if os.listdir(self.currentMountpoint): logger.warning( msg_begin + 'not empty after unmount', self) else: logger.info( f'unmount {self.log_command} ' f'from {self.currentMountpoint}', self) except Exception: raise else: self.mountLockRelease() self.removeSymlink() finally: self.mountProcessLockRelease() def _mount(self): """ Backend mount method. This **must** be overwritten in the backend which subclasses :py:class:`MountControl`. """ raise NotImplementedError('_mount need to be overwritten in backend') def _umount(self): """ Unmount with ``fusermount -u`` for fuse based backends. This **can** be overwritten by backends which subclasses :py:class:`MountControl`. Raises: exceptions.MountException: If unmount failed. """ try: subprocess.check_call(['fusermount', '-u', self.currentMountpoint]) except subprocess.CalledProcessError as exc: raise MountException( _('Unable to unmount {mountprocess} from {mountpoint}.') .format(mountprocess=self.mountproc, mountpoint=self.currentMountpoint)) from exc def preMountCheck(self, first_run=False): """ Check what ever conditions must be given for the mount to be done successful. This **can** be overwritten in backends which subclasses :py:class:`MountControl`. Returns: bool: ``True`` if all checks where okay Raises: exceptions.MountException: if backend can not mount Note: This can also be used to prepare things before running :py:func:`_mount` """ return True def postMountCheck(self): """ Check if the mount was successful. This **can** be overwritten in backends which subclasses :py:class:`MountControl`. Returns: bool: ``True`` if all checks where okay Raises: exceptions.MountException: if backend wasn't mount successful Note: This can also be used to clean up after running :py:func:`_mount` """ return True def preUmountCheck(self): """ Check if backend is safe to umount. This **can** be overwritten in backends which subclasses :py:class:`MountControl`. Returns: bool: ``True`` if all checks where okay Raises: exceptions.MountException: if backend can not umount Note: This can also be used to prepare things before running :py:func:`_umount` """ return True def postUmountCheck(self): """ Check if unmount was successful. This **can** be overwritten in backends which subclasses :py:class:`MountControl`. Returns: bool: ``True`` if all checks where okay Raises: exceptions.MountException: if backend wasn't unmounted successful Note: This can also be used to clean up after running :py:func:`_umount` """ return True def checkFuse(self): """ Check if command in ``self.mountproc`` is installed. Raises: exceptions.MountException: If either command is not available. """ if not tools.checkCommand(self.mountproc): logger.debug(f'{self.mountproc} is missing', self) raise MountException( _('{command} not found. Please install it ' '(e.g. via "{installcommand}")').format( command=self.mountproc, installcommand=f"'apt-get install {self.mountproc}'") ) def mounted(self): """ Check if the mountpoint is already mounted. Returns: bool: ``True`` if mountpoint is mounted Raises: exceptions.MountException: if mountpoint is not mounted but also not empty """ if os.path.ismount(self.currentMountpoint): return True else: try: if os.listdir(self.currentMountpoint): raise MountException( _('Mountpoint {mntpoint} not empty.').format( mntpoint=self.currentMountpoint)) except FileNotFoundError: pass return False def createMountStructure(self): """ Create folders that are necessary for mounting. Folder structure in ``~/.local/share/backintime/mnt/`` (``self.mount_root``):: . ├── .lock <= mountprocess lock that will prevent │ different processes modifying │ mountpoints at one time │ ├── / <= ``self.hash_id_path`` will be │ │ shared by all profiles with the │ │ same mount settings │ │ │ ├── mountpoint/ <= ``self.currentMountpoint`` real │ │ mountpoint │ │ │ ├── umount <= ``self.umount_info`` json file with │ │ all necessary args for unmount │ │ │ └── locks/ <= ``self.lock_path`` for each process │ you have a ``.lock`` file │ ├── _/ <= sym-link to the right path. return │ by config.snapshotsPath (can be │ ../mnt//mount_point for ssh │ or ../mnt/// │ for fusesmb ...) │ └── tmp__/ <= sym-link for testing mountpoints in settingsdialog """ tools.mkdir(self.mount_root, 0o700) tools.mkdir(self.hash_id_path, 0o700) tools.mkdir(self.currentMountpoint, 0o700, False) tools.mkdir(self.lock_path, 0o700) def mountProcessLockAcquire(self, timeout=60): """ Create a short term lock only for blocking other processes changing mounts at the same time. Args: timeout (int): Wait ``timeout`` seconds before fail acquiring the lock. Raises: exceptions.MountException: If timed out. """ lock_path = self.mount_root lockSuffix = '.lock' # e.g. ~/.local/share/backintime/mnt/123456.lock lock = os.path.join(lock_path, self.pid + lockSuffix) # Every second count = 0 while self.checkLocks(lock_path, lockSuffix): count += 1 if count == timeout: raise MountException('Mountprocess lock timeout') sleep(1) logger.debug(f'Acquire mountprocess lock {lock}', self) with open(lock, 'w') as f: f.write(self.pid) def mountProcessLockRelease(self): """Remove mountprocess lock.""" lock_path = self.mount_root lockSuffix = '.lock' lock = os.path.join(lock_path, self.pid + lockSuffix) logger.debug(f'Release mountprocess lock {lock}', self) if os.path.exists(lock): os.remove(lock) def mountLockAquire(self): """ Create a lock file for a mountpoint to prevent unmounting as long as this process is running. """ lockSuffix = '.tmp.lock' if self.tmp_mount else '.lock' lock = os.path.join(self.lock_path, self.pid + lockSuffix) logger.debug(f'Set mount lock {lock}', self) with open(lock, 'w') as f: f.write(self.pid) def mountLockCheck(self): """ Check for locks on the current mountpoint. Returns: bool: ``True`` if there are any locks """ lockSuffix = '.lock' return self.checkLocks(self.lock_path, lockSuffix) def mountLockRelease(self): """ Remove mountpoint lock for this process. """ lockSuffix = '.tmp.lock' if self.tmp_mount else '.lock' lock = os.path.join(self.lock_path, self.pid + lockSuffix) if os.path.exists(lock): logger.debug(f'Remove mount lock {lock}', self) os.remove(lock) def checkLocks(self, path, lock_suffix): """Check existence of active and foreign locks. The lock owning process is specified by the PID contained in the filename of the lock file used. Lock files of the current process are ignored and ``False`` is returned if they share the same tmp-mount state. If a lock exist but its process not the lock is removed and ``False`` returned. In that latter case mount symlinks related to that lock also removed. Args: path (str): Full path to lock directory. lock_suffix (str): Last part of locks name. Returns: bool: ``True`` if there are active locks in ``path``. Raises: FileNotFoundError: If the path does not exists. """ if isinstance(path, str): path = Path(path) for lock_fp in path.iterdir(): # Not a lock file? if lock_fp.suffix != lock_suffix: # next file continue # Secondary suffix is "tmp"? (e.g. "12345.tmp.lock") is_tmp = lock_fp.with_suffix('').suffix == '.tmp' # Extract PID from lock file name lock_pid = lock_fp.stem if is_tmp: lock_pid = lock_pid[:-4] # cut ".tmp" from the end # Ignore process's own lock files. if lock_pid == self.pid: # ...with the same tmp-state. if is_tmp == self.tmp_mount: # Dev note (buhtz, 2024-11-22): I have no idea what makes # a mount temporary. continue if tools.processAlive(int(lock_pid)): return True logger.debug(f'Remove old and invalid lock {lock_fp}', self) # Clean up the lock file lock_fp.unlink() # Clean up related symlinks for symlink in Path(self.mount_root).iterdir(): if symlink.name.endswith(f'_{lock_pid}'): symlink.unlink() return False def setattrKwargs(self, arg, default, store=True, **kwargs): """ Set attribute ``arg`` in local namespace (self.arg). Also collect all args in ``self.all_kwargs`` which will be hashed later and used as mountpoint name and also be written as unmount_info. Args: arg (str): argument name default: default value used if ``arg`` is not in ``kwargs`` store (bool): if ``True`` add ``arg`` to ``self.all_kwargs`` **kwargs: arguments given on backend constructor """ if arg in kwargs: value = kwargs[arg] else: value = default setattr(self, arg, value) if store: #make dictionary with all used args for umount self.all_kwargs[arg] = value def writeUmountInfo(self): """ Write content of ``self.all_kwargs`` to file ``~/.local/share/backintime/mnt//umount``. This will be used to unmount the filesystem later. """ data_string = json.dumps(self.all_kwargs) with open(self.umount_info, 'w') as f: f.write(data_string) f.close def readUmountInfo(self, umount_info = None): """ Read keyword arguments from file ``umount_info``. Args: umount_info (str): full path to /umount file. If ``None`` current ``/umount`` file will be used Returns: dict: previously written ``self.all_kwargs`` """ if umount_info is None: umount_info = self.umount_info with open(umount_info, 'r') as f: data_string = f.read() f.close() return json.loads(data_string) def compareUmountInfo(self, umount_info = None): """ Compare current ``self.all_kwargs`` with those from file ``umount_info``. This should prevent hash collisions of two different mounts. Args: umount_info (str): full path to /umount file Returns: bool: ``True`` if ``self.all_kwargs`` and ``kwargs`` read from ``umount_info`` file are identiacal """ #run self.all_kwargs through json first current_kwargs = json.loads(json.dumps(self.all_kwargs)) saved_kwargs = self.readUmountInfo(umount_info) if not len(current_kwargs) == len(saved_kwargs): return False for arg in list(current_kwargs.keys()): if not arg in list(saved_kwargs.keys()): return False if not current_kwargs[arg] == saved_kwargs[arg]: return False return True def compareRemount(self, old_hash_id): """ Compare mount arguments between current and ``old_hash_id``. If they are identical we could reuse the mount and don't need to remount. Args: old_hash_id (str): Hash ID of the old mountpoint Returns: bool: True if the old mountpoint and current are identiacal """ if old_hash_id == self.hash_id: return self.compareUmountInfo(self.umountInfoPath(old_hash_id)) return False def setSymlink(self, profile_id = None, hash_id = None, tmp_mount = None): """ If ``self.symlink`` is ``True`` set symlink ``~/.local/share/backintime/mnt/_``. Target will be either the mountpoint or a subfolder of the mountpoint if ``self.symlink_subfolder`` is set. Args: profile_id (str): Profile ID that should be linked. If ``None`` use ``self.profile_id`` hash_id (str): Hash ID of mountpoint where this sysmlink should point to. If ``None`` use ``self.hash_id`` tmp_mount (bool): Set a temporary symlink just for testing new settings """ if not self.symlink: return if profile_id is None: profile_id = self.profile_id if hash_id is None: hash_id = self.hash_id if tmp_mount is None: tmp_mount = self.tmp_mount dst = self.config.snapshotsPath(profile_id=profile_id, mode=self.mode, tmp_mount=tmp_mount) mountpoint = self.mountpoint(hash_id) if self.symlink_subfolder is None: src = mountpoint else: src = os.path.join(mountpoint, self.symlink_subfolder) if os.path.exists(dst): os.remove(dst) os.symlink(src, dst) def removeSymlink(self, profile_id=None, tmp_mount=None): """ Remove symlink ``~/.local/share/backintime/mnt/_``. Args: profile_id (str): Profile ID for the symlink. tmp_mount (bool): Symlink is a temporary link for testing new settings. """ if not self.symlink: return if profile_id is None: profile_id = self.profile_id if tmp_mount is None: tmp_mount = self.tmp_mount os.remove(self.config.snapshotsPath( profile_id=profile_id, mode=self.mode, tmp_mount=tmp_mount)) def hash(self, s): """ Create a CRC32 hash of string ``s``. Args: s (str): string that should be hashed Returns: str: hash of string ``s`` """ return '%X' % (crc32(s.encode()) & 0xFFFFFFFF) def hashIdPath(self, hash_id = None): """ Get path ``~/.local/share/backintime/mnt/``. Args: hash_id (str): Unique identifier for a mountpoint. If ``None`` use ``self.hash_id`` Returns: str: full path to ```` """ if hash_id is None: hash_id = self.hash_id return os.path.join(self.mount_root, self.hash_id) def mountpoint(self, hash_id = None): """ Get path ``~/.local/share/backintime/mnt//mountpoint``. Args: hash_id (str): Unique identifier for a mountpoint Returns: str: full path to ``/mountpoint`` """ return os.path.join(self.hashIdPath(hash_id), 'mountpoint') def lockPath(self, hash_id = None): """ Get path ``~/.local/share/backintime/mnt//locks``. Args: hash_id (str): Unique identifier for a mountpoint Returns: str: full path to ``/locks``` """ return os.path.join(self.hashIdPath(hash_id), 'locks') def umountInfoPath(self, hash_id = None): """ Get path ``~/.local/share/backintime/mnt//umount``. Args: hash_id (str): Unique identifier for a mountpoint Returns: str: full path to ``/umount``` """ return os.path.join(self.hashIdPath(hash_id), 'umount') backintime-1.5.4/common/password.py000066400000000000000000000267021477034762000173540ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import sys import os import time import atexit import signal import config import configfile import tools import daemon import password_ipc import logger from exceptions import Timeout class Password_Cache(daemon.Daemon): """ Password_Cache get started on User login. It provides passwords for BIT cronjobs because keyring is not available when the User is not logged in. Does not start if there is no password to cache (e.g. no profile allows to cache). """ PW_CACHE_VERSION = 3 def __init__(self, cfg = None, *args, **kwargs): self.config = cfg if self.config is None: self.config = config.Config() cachePath = self.config.passwordCacheFolder() if not tools.mkdir(cachePath, 0o700): msg = 'Failed to create secure Password_Cache folder' logger.error(msg, self) raise PermissionError(msg) pid = self.config.passwordCachePid() super(Password_Cache, self).__init__(pid, umask = 0o077, *args, **kwargs) self.dbKeyring = {} self.dbUsr = {} self.fifo = password_ipc.FIFO(self.config.passwordCacheFifo()) self.keyringSupported = tools.keyringSupported() def run(self): """ wait for password request on FIFO and answer with password from self.db through FIFO. """ info = configfile.ConfigFile() info.setIntValue('version', self.PW_CACHE_VERSION) info.save(self.config.passwordCacheInfo()) os.chmod(self.config.passwordCacheInfo(), 0o600) logger.debug('Keyring supported: %s' %self.keyringSupported, self) tools.envSave(self.config.cronEnvFile()) if not self.collectPasswords(): logger.debug('Nothing to cache. Quit.', self) sys.exit(0) self.fifo.create() atexit.register(self.fifo.delfifo) signal.signal(signal.SIGHUP, self.reloadHandler) logger.debug('Start loop', self) while True: try: request = self.fifo.read() request = request.split('\n')[0] task, value = request.split(':', 1) if task == 'get_pw': key = value if key in list(self.dbKeyring.keys()): answer = 'pw:' + self.dbKeyring[key] elif key in list(self.dbUsr.keys()): answer = 'pw:' + self.dbUsr[key] else: answer = 'none:' self.fifo.write(answer, 5) elif task == 'set_pw': key, value = value.split(':', 1) self.dbUsr[key] = value except IOError as e: logger.error('Error in writing answer to FIFO: %s' % str(e), self) except KeyboardInterrupt: logger.debug('Quit.', self) break except Timeout: # That exception is thrown by tools.Alarm.handle() if the # timeout ends. That Alarm was set by FIFO.read(). logger.error('FIFO timeout', self) except Exception as e: logger.error('ERROR: %s' % str(e), self) def reloadHandler(self, signum, frame): """ reload passwords during runtime. """ time.sleep(2) cfgPath = self.config._LOCAL_CONFIG_PATH del self.config self.config = config.Config(cfgPath) del self.dbKeyring self.dbKeyring = {} self.collectPasswords() def collectPasswords(self): """ search all profiles in config and collect passwords from keyring. """ run_daemon = False profiles = self.config.profiles() for profile_id in profiles: mode = self.config.snapshotsMode(profile_id) for pw_id in (1, 2): if self.config.modeNeedPassword(mode, pw_id): if self.config.passwordUseCache(profile_id): run_daemon = True if self.config.passwordSave(profile_id) and self.keyringSupported: service_name = self.config.keyringServiceName(profile_id, mode, pw_id) user_name = self.config.keyringUserName(profile_id) password = tools.password(service_name, user_name) if password is None: continue self.dbKeyring['%s/%s' %(service_name, user_name)] = password return run_daemon def checkVersion(self): info = configfile.ConfigFile() info.load(self.config.passwordCacheInfo()) if info.intValue('version') < self.PW_CACHE_VERSION: return False return True def cleanupHandler(self, signum, frame): self.fifo.delfifo() super(Password_Cache, self).cleanupHandler(signum, frame) class Password: """Provide passwords for BIT either from keyring, Password_Cache or by asking user. """ def __init__(self, cfg=None): self.config = cfg if self.config is None: self.config = config.Config() self.cache = Password_Cache(self.config) self.fifo = password_ipc.FIFO(self.config.passwordCacheFifo()) self.db = {} self.keyringSupported = tools.keyringSupported() def password(self, parent, profile_id, mode, pw_id=1, only_from_keyring=False, refresh=False): """ Based on profile settings return password from keyring, Password_Cache or by asking User. """ if not self.config.modeNeedPassword(mode, pw_id): return '' service_name = self.config.keyringServiceName(profile_id, mode, pw_id) user_name = self.config.keyringUserName(profile_id) try: return self.db['%s/%s' % (service_name, user_name)] except KeyError: pass password = '' if (self.config.passwordUseCache(profile_id) and not only_from_keyring and not refresh): # From cache password = self.passwordFromCache(service_name, user_name) if password is not None: self.setPasswordDb(service_name, user_name, password) return password if self.config.passwordSave(profile_id) and not refresh: # From keyring password = self.passwordFromKeyring(service_name, user_name) if password is not None: self.setPasswordDb(service_name, user_name, password) return password if refresh or not only_from_keyring: # Ask user and write to cache password = self.passwordFromUser(parent, profile_id, mode, pw_id) if self.config.passwordUseCache(profile_id): self.setPasswordCache(service_name, user_name, password) self.setPasswordDb(service_name, user_name, password) return password return password def passwordFromKeyring(self, service_name, user_name): """ get password from system keyring (seahorse). The keyring is only available if User is logged in. """ if self.keyringSupported: try: return tools.password(service_name, user_name) except Exception: logger.error('get password from Keyring failed', self) return None def passwordFromCache(self, service_name, user_name): """ get password from Password_Cache """ if self.cache.status(): self.cache.checkVersion() self.fifo.write('get_pw:%s/%s' %(service_name, user_name), timeout = 5) answer = self.fifo.read(timeout = 5) mode, pw = answer.split(':', 1) if mode == 'none': return None return pw else: return None def passwordFromUser(self, parent, profile_id=None, mode=None, pw_id=1, prompt=None): """Ask user for password. Use terminal input or a dialog box if X is available. This does even work when run as cronjob and user is logged in. Args: parent: Parent of the ``QMessageDialog``. profile_id(str): Profile identifier. mode(str): Mode identifier (e.g. SSH (encrypted)). pwd_id(int): See :data:`config.SNAPSHOT_MODES` for details. prompt(str): Alternative string used as prompt. Return: str: The password. """ # Default prompt if prompt is None: prompt = _('Enter password for {mode} profile "{profile}":') \ .format( profile=self.config.profileName(profile_id), mode=self.config.SNAPSHOT_MODES[mode][pw_id+1]) tools.registerBackintimePath('qt') x_server = tools.checkXServer() import_successful = False if x_server: try: import messagebox import_successful = True except ImportError: pass if not import_successful or not x_server: import getpass alarm = tools.Alarm() alarm.start(300) try: password = getpass.getpass(prompt + ' ') alarm.stop() except Timeout: password = '' return password # Use QDialog as graphical prompt password = messagebox.askPasswordDialog( parent=parent, title=self.config.APP_NAME, prompt=prompt, language_code=self.config.language(), timeout=300) return password def setPasswordDb(self, service_name, user_name, password): """ internal Password cache. Prevent to ask password several times during runtime. """ self.db['%s/%s' %(service_name, user_name)] = password def setPassword(self, password, profile_id, mode, pw_id): """ store password to keyring and Password_Cache """ if self.config.modeNeedPassword(mode, pw_id): service_name = self.config.keyringServiceName(profile_id, mode, pw_id) user_name = self.config.keyringUserName(profile_id) if self.config.passwordSave(profile_id): self.setPasswordKeyring(service_name, user_name, password) if self.config.passwordUseCache(profile_id): self.setPasswordCache(service_name, user_name, password) self.setPasswordDb(service_name, user_name, password) def setPasswordKeyring(self, service_name, user_name, password): return tools.setPassword(service_name, user_name, password) def setPasswordCache(self, service_name, user_name, password): if self.cache.status(): self.cache.checkVersion() self.fifo.write('set_pw:%s/%s:%s' %(service_name, user_name, password), timeout = 5) backintime-1.5.4/common/password_ipc.py000066400000000000000000000106321477034762000202020ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import os import sys import stat import tools import threading import tempfile from contextlib import contextmanager import logger class FIFO: """Inter-process communication (IPC) with named pipes using the first-in, first-out principle (FIFO). Params: fifo (str): Name of the named pipe file. alarm (tools.Alarm): To handle read/write timeouts. """ def __init__(self, fname): self.fifo = fname self.alarm = tools.Alarm() def delfifo(self): """Remove named pipe file.""" try: os.remove(self.fifo) # TODO: Catch FileNotFoundError only except: pass def create(self): """Create the named pipe file in a way that only the current user has access to it. """ if os.path.exists(self.fifo): self.delfifo() try: # Permissions are "rw- --- ---" os.mkfifo(self.fifo, 0o600) except OSError as e: logger.error(f'Failed to create named pipe file. Error: {e}', self) sys.exit(1) def read(self, timeout=0): """Read from named pipe until timeout. If timeout is 0 it will wait forever for input. """ # sys.stdout.write('read fifo\n') if not self.isFifo(): # TODO raise an Exception or write to stderr sys.exit(1) self.alarm.start(timeout) with open(self.fifo, 'r') as handle: # Will wait until data is available, # or an exception (e.g. exception.Timeout) is raised. # The latter will happen when the timeout is finished. ret = handle.read() # If the alarm timeout ends but read() received not data, a # exception.Timeout will be raised at this point. # The exception will be caught far away in # password.py::Password_Cache.run(). self.alarm.stop() return ret def write(self, string, timeout=0): """Write to named pipe file until timeout. If timeout is 0 it will wait forever for an other process that will read this. """ if not self.isFifo(): # TODO raise an Exception or write to stderr sys.exit(1) self.alarm.start(timeout) with open(self.fifo, 'w') as fifo: fifo.write(string) # See FIFO.read() to learn about "hidden" handling of Timeout # exception. self.alarm.stop() def isFifo(self): """Make sure file is still a FIFO and has correct permissions.""" try: s = os.stat(self.fifo) except OSError: return False if not s.st_uid == os.getuid(): logger.error(f'{self.fifo} is not owned by user', self) return False mode = s.st_mode if not stat.S_ISFIFO(mode): logger.error(f'{self.fifo} is not a named pipe file (FIFO)', self) return False forbidden_perm = stat.S_IXUSR + stat.S_IRWXG + stat.S_IRWXO if mode & forbidden_perm > 0: logger.error(f'{self.fifo} has wrong permissions', self) return False return True class TempPasswordThread(threading.Thread): """ in case BIT is not configured yet provide password through temp FIFO to backintime-askpass. """ def __init__(self, string): super(TempPasswordThread, self).__init__() self.pw = string self.temp_file = os.path.join(tempfile.mkdtemp(), 'FIFO') self.fifo = FIFO(self.temp_file) @contextmanager def starter(self): self.start() yield self.stop() def run(self): self.fifo.create() self.fifo.write(self.pw) self.fifo.delfifo() def read(self): """ read fifo to end the blocking fifo.write use only if thread timeout. """ self.fifo.read() def stop(self): self.join(5) if self.is_alive(): #threading does not support signal.alarm self.read() try: os.rmdir(os.path.dirname(self.temp_file)) except OSError: pass backintime-1.5.4/common/pluginmanager.py000066400000000000000000000261611477034762000203420ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import os import sys import tools tools.registerBackintimePath('common') tools.registerBackintimePath('plugins') tools.registerBackintimePath('common', 'plugins') tools.registerBackintimePath('qt', 'plugins') import logger from exceptions import StopException class Plugin: """ Interface methods to customize behavior for different backup steps Back In Time allows to inform plugins (implemented in Python files) about different steps ("events") in the backup process. Plugins may implement special behavior to predefined "events" that are declared in this interface class as methods. To implement a new plugin create a new class that inherits from this one and implement all methods. Plugins are loaded by calling :py:func:`PluginManager.load`. """ def init(self, snapshots): return True def isGui(self): """Indicates a GUI-related plugin The return value shall indicate if the plugin is related to the Back In Time GUI. Loaded GUI-related plugins are called before non-GUI-related plugins by the PluginManager. Returns: True if plugin is GUI-related, otherwise False """ return False def processBegin(self): """Called before a backup process is started. A new snapshot is only taken if required (as configured). Returns: ``None`` (return value will be ignored anyhow) """ return def processEnd(self): """Called after a backup process has ended Returns: ``None`` (return value will be ignored anyhow) """ return def error(self, code, message): """Indicates errors during the backup process Called to send errors in the backup process (while taking a snapshot) to plugins. Args: code: A Back In Time error code Known error codes: 1: No or no valid configuration (check the configuration file) 2: A backup process is already running. Make sure that automatic and manual backups do not run at once. 3: Snapshots directory not found (eg. when a removable drive is not mounted) 4: The requested snapshot for "now" already exists. ``message`` contains the SID (snapshot ID) then. 5: Error while taking a snapshot. ``message`` contains more information (as string). 6: New snapshot taken but with errors. ``message`` contains the SID (snapshot ID) then. message: The error message for the code (mostly an empty string by default) Returns: ``None`` (return value will be ignored anyhow) """ return def newSnapshot(self, snapshot_id, snapshot_path): """ Called when the backup process has taken a new snapshot. A new snapshot is only taken by the backup process if required (as configured). Args: snapshot_id: The id of the new snapshot snapshot_path: The path to the new snapshot Returns: ``None`` (return value will be ignored anyhow) """ return def message(self, profile_id, profile_name, level, message, timeout): """Send snapshot-related messages to plugins. Args: profile_id: Profile ID from configuration. profile_name: Profile name from the configuration. level: 0 = INFO, 1 = ERROR message: Message text. timeout: Requested timeout in seconds to process the message. Not used at the moment. (default -1 means "no timeout") """ pass def appStart(self): """ Called when the GUI of Back In Time was started. Not called when only the CLI command was started without the GUI. Returns: ``None`` (return value will be ignored anyhow) """ return def appExit(self): """ Called when the GUI of Back In Time is closed Returns: ``None`` (return value will be ignored anyhow) """ return def mount(self, profileID = None): """ Called when mounting a filesystem for the profile may be necessary. Args: profileID: Profile ID from the configuration Returns: ``None`` (return value will be ignored anyhow) """ return def unmount(self, profileID = None): """ Called when unmounting a filesystem for a profile may be necessary Args: profileID: Profile ID from the configuration Returns ``None`` (return value will be ignored anyhow) """ return class PluginManager: """ Central interface for loading plugins and calling their API Back In Time allows to inform plugins (implemented in Python files) about different steps ("events") in the backup process. Use this class to load installed plugin classes and call their methods (see the interface declared by :py:class:`Plugin`). Plugins are loaded by calling :py:func:`PluginManager.load`. When you call a plugin function of the PluginManager it will call this plugin function for all loaded plugins. """ # TODO 09/28/2022: Should inherit from + implement class "Plugin" def __init__(self): self.plugins = [] self.hasGuiPlugins = False self.loaded = False def load(self, snapshots=None, cfg=None, force=False): """Loads plugins Loads all plugins from python source code files that are stored in one of these plugin sub folders in the installation root folder: 'plugins', 'common/plugins', 'qt/plugins' Plugins must inherit from :py:class:`Plugin` otherwise they are silently ignored. Args: snapshots (snapshots.Snapshots): Snapshot info cfg (config.Config): Current configuration force (bool): ``True`` to enforce reloading all plugins (``False`` does only load if not already done) """ if self.loaded and not force: return if snapshots is None: import snapshots as snapshots_ snapshots = snapshots_.Snapshots(cfg) self.loaded = True self.plugins = [] self.hasGuiPlugins = False loadedPlugins = [] # TODO 09/28/2022: Move hard coded plugin folders to configuration for path in ('plugins', 'common/plugins', 'qt/plugins'): fullPath = tools.backintimePath(path) if os.path.isdir(fullPath): logger.debug('Register plugin path %s' %fullPath, self) tools.registerBackintimePath(path) for f in os.listdir(fullPath): if f not in loadedPlugins and f.endswith('.py') and not f.startswith('__'): # logger.debug('Probing plugin %s' % f, self) try: module = __import__(f[: -3]) module_dict = module.__dict__ for key, value in list(module_dict.items()): if key.startswith('__'): continue if type(value) is type: # A plugin must implement this class via inheritance if issubclass(value, Plugin): plugin = value() if plugin.init(snapshots): logger.debug('Add plugin %s' %f, self) if plugin.isGui(): self.hasGuiPlugins = True self.plugins.insert(0, plugin) else: self.plugins.append(plugin) loadedPlugins.append(f) except BaseException as e: logger.error('Failed to load plugin %s: %s' %(f, str(e)), self) def processBegin(self): ret_val = True for plugin in self.plugins: try: plugin.processBegin() except StopException: ret_val = False except BaseException as e: self.logError(plugin, e) return ret_val def processEnd(self): for plugin in reversed(self.plugins): try: plugin.processEnd() except BaseException as e: self.logError(plugin, e) def error(self, code, message = ''): for plugin in self.plugins: try: plugin.error(code, message) except BaseException as e: self.logError(plugin, e) def newSnapshot(self, snapshot_id, snapshot_path): for plugin in self.plugins: try: plugin.newSnapshot(snapshot_id, snapshot_path) except BaseException as e: self.logError(plugin, e) def message(self, profile_id, profile_name, level, message, timeout = -1): for plugin in self.plugins: try: plugin.message(profile_id, profile_name, level, message, timeout) except BaseException as e: self.logError(plugin, e) def appStart(self): for plugin in reversed(self.plugins): try: plugin.appStart() except BaseException as e: self.logError(plugin, e) def appExit(self): for plugin in reversed(self.plugins): try: plugin.appExit() except BaseException as e: self.logError(plugin, e) def mount(self, profileID = None): for plugin in reversed(self.plugins): try: plugin.mount(profileID) except BaseException as e: self.logError(plugin, e) def unmount(self, profileID = None): for plugin in reversed(self.plugins): try: plugin.unmount(profileID) except BaseException as e: self.logError(plugin, e) def logError(self, plugin, e): logger.error('Plugin %s %s failed: %s' %(plugin.__module__, #plugin name sys._getframe(1).f_code.co_name, #method name str(e)), #exception self, 1) backintime-1.5.4/common/plugins/000077500000000000000000000000001477034762000166125ustar00rootroot00000000000000backintime-1.5.4/common/plugins/usercallbackplugin.py000066400000000000000000000104031477034762000230340ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import pluginmanager import logger import gettext from subprocess import Popen, PIPE from exceptions import StopException _ = gettext.gettext class UserCallbackPlugin(pluginmanager.Plugin): """ Executes a script file at different backup steps to customize behavior Back In Time allows to inform plugins (implemented in Python files) about different steps ("events") in the backup process via the :py:class:`pluginmanager.PluginManager`. This plugin calls a user-defined script file ("user-callback"). By default that file is located in the config folder `$XDG_CONFIG_HOME/backintime/` or another folder if command line optioni `--config` is used. The user-callback script is called with up to five positional arguments: 1. The profile ID from the config file (1=Main Profile, ...) 2. The profile name (from the config file) 3. A numeric code to indicate the reason why Back In Time calls the script (see the method implementation for details about the numeric code) 4. Error code (only if argument 3 has the value "4") or snapshot ID (only if argument 3 has the value "3") 5. Snapshot name (only if argument 3 has the value "3") For more details and script examples see: https://github.com/bit-team/user-callback Notes: The user-callback script file is normally implemented as shell script but could theoretically be implemented in any script language (declared via the hash bang "#!" in the first line of the script file. """ def __init__(self): logger.openlog() return def init(self, snapshots): self.config = snapshots.config self.script = self.config.takeSnapshotUserCallback() return os.path.exists(self.script) # TODO 09/28/2022: This method should be private (_callback) def callback(self, *args, profileID=None): if profileID is None: profileID = self.config.currentProfile() profileName = self.config.profileName(profileID) cmd = [self.script, profileID, profileName] cmd.extend(str(x) for x in args) logger.debug(f'Call user-callback: {" ".join(cmd)}', self) stdout, stderr = PIPE, PIPE try: callback = Popen(cmd, stdout=stdout, stderr=stderr, universal_newlines=True) output = callback.communicate() # Stdout if output[0]: logger.info("user-callback returned '" + output[0].strip('\n') + "'", self) # Stderr if output[1]: logger.error("user-callback returned '" + output[1].strip('\n') + "'", self) if callback.returncode != 0: logger.warning( f'user-callback returncode: {callback.returncode}', self) raise StopException() except OSError as e: logger.error( f'Exception when trying to run user callback: {e.strerror}', self) def processBegin(self): self.callback('1') def processEnd(self): self.callback('2') def error(self, code, message): if not message: self.callback('4', code) else: self.callback('4', code, message) def newSnapshot(self, snapshot_id, snapshot_path): self.callback('3', snapshot_id, snapshot_path) def appStart(self): self.callback('5') def appExit(self): self.callback('6') def mount(self, profileID = None): self.callback('7', profileID = profileID) def unmount(self, profileID = None): self.callback('8', profileID = profileID) backintime-1.5.4/common/po/000077500000000000000000000000001477034762000155475ustar00rootroot00000000000000backintime-1.5.4/common/po/README.md000066400000000000000000000011601477034762000170240ustar00rootroot00000000000000 Translation for Back In Time is done at https://translate.codeberg.org/engage/backintime. Please do NOT change files in this folder as they will get overwritten with files exported from translation platform. See [Maintenance documentation about translation and localization](../../doc/maintain/2_localization.md) for details. backintime-1.5.4/common/po/REUSE.toml000066400000000000000000000012641477034762000173320ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = [ "*.pot", "*.po", "*.mo", ] SPDX-License-Identifier = "GPL-2.0-or-later" SPDX-FileCopyrightText = "© 2009 Back In Time team and several translators" backintime-1.5.4/common/po/ar.po000066400000000000000000002112151477034762000165130ustar00rootroot00000000000000# Arabic translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-05 11:12+0000\n" "Last-Translator: buhtz \n" "Language-Team: Arabic \n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "تحذير" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "الملف الشخصي الرئيسي" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "تشفير محلي بصيغة EncFS" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (تشفير EncFS)" #: common/config.py:278 msgid "Local" msgstr "محلي" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "مفتاح SSH خاص" #: common/config.py:283 msgid "Local encrypted" msgstr "مشفرة محليا" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "التعمية" #: common/config.py:289 msgid "SSH encrypted" msgstr "تشفير SSH" #: common/config.py:296 msgid "Default" msgstr "إفتراضيّ" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "الملف الشخصي: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "مُجلد اللقطات غير صالح." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "يجب إختيار مجلد واحد على الأقل للنسخ الاحتياطي." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "استعادة {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "لا يمكن تضمين المجلد للنسخ الاحتياطي." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "فشل كتابة crontab جديد." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "لا يعمل كرون (Cron) رغم توفر أمر crontab. لن يتم تشغيل مهام النسخ الاحتياطي " "المجدولة. قد يكون كرون مثبتًا ولكنه غير مفعل. جرب الأمر \"systemctl enable " "cron\" أو استشر قنوات الدعم لتوزيعة جنو / لينكس الخاصة بك." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "لا يستطيع تثبيت قاعدة Udev ماف الشخصي {profile_id}. خدمة DBus " "'{dbus_interface}' ليس كانت موفره" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "جدول udev لا يعمل مع طريقة {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "لا يستطيع العثور على UUID لـ{path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "فشل في حفظ التكوين" #: common/configfile.py:137 msgid "Failed to load config" msgstr "فشل في جلب التكوين" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "الملف الشخصي \"{name}\" موجود أصلاً." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "لا يستطيع إزالة الملف الشخصي الآخر." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "لا يستطيع ركب '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "لم يوجد التكوين للمجلد المشفر." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "هل تريد انشاء مجلد مشفر جديد؟" #: common/encfstools.py:146 msgid "Cancel" msgstr "إلغاء" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "يرجى تأكيد كلمة السر." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "كلمة السر ليس مطابق." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "خذ لقطة" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "لا يستطيع تفكيك {mountprocess} من {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "لم يتم العثور على الأمر \"{command}\". يرجى تثبيته (على سبيل المثال ، " "باستخدام \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "نقطة التوصيل {mntpoint} ليست فارغة." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "ادخل كلمة المرور لملف التعريف لوضع {mode} يسمى \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "فشل" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "إستعادة الأذونات" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "تم" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "تأجيل النسخ الاحتياطي أثناء وجوده على البطارية" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "لم نتمكن من العثور على مجلد اللقطات." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "إن كان على وحدة تخزين خارجية، يرجى توصيلها." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "ينتظر %s ثانية." msgstr[1] "ينتظر %s ثواني." msgstr[2] "ينتظر %s ثانية." msgstr[3] "ينتظر %s ثواني." msgstr[4] "ينتظر %s ثانية." msgstr[5] "ينتظر %s ثواني." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "فشل بأخذ لقطة {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "الرجاء الانتظار. جاري الانتهاء…" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "لا يمكن إنشاء مجلد" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "يتم حفظ ملف التكوين…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "يتم حفظ الأذونات…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "وجد بقايا اللقطة {snapshot_id} ويمكن الاستمرار فيه." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "يتم إزالة مجلد بقايا {snapshot_id} من العملية الاخيرة" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "لا يُمكن إزالة المُجلد" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "يتم اخذ لقطة" #: common/snapshots.py:1430 msgid "Success" msgstr "نجاح" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "عملية النقل جزئية بسبب حدوث خطأ" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "عملية النقل جزئية بسبب اختفاء ملفات المصدر (انظر 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "انتهت عملية 'rsync' مع رمز الخروج {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "اطلع على 'man rsync' للمزيد من التفاصيل" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "رموز الخروج السلبية لrsync هم ارقام إشارة, اطلع على 'kill -l' و'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "لا شيء تغير, لا حاجة للقطة جديدة" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "لا يمكن إعادة تسمية {new_path} إلى {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "إزالة ذكية" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "تطبيق القواعد لإلزالة اللقطات القديمة" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "تطبيق قواعد الإحتفاظ" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "حاول إبقاء حد أدنى من المساحة فارغة" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "محاولة للحفاظ على الحد الأدنى من {perc} ضمن مساحة الـ inode حرة" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "الآن" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "غير ممكن تركيب {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "لم يتم العثور على ssh-agent. يرجى التأكد من أنه مثبت." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "لم يمكن فتح مفتاح SSH الخاص. كلمة المرور خاطئة أو كلمة المرور غير متاحة لـ " "cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "فشل تشفير {cipher} لـ {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "المسار البعيد موجود لكن ليس مجلدا." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "المسار البعيد غير قابل للكتابة." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "المسار المتباعد ليس قابل للتنفيذ." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "لا يمكن إنشاء المسار البعيد." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "المضيف البعيد {host} لا يدعم {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "انظر إلى 'man backintime' للحصول على مزيد من التعليمات" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "التأكد من الأوامر على المضيف {host} أعاد بخطأ غير معروف" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "المضيف البعيد {host} لا يدعم الروابط الصلبة" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "نسخ مفتاح SSH العام \"{pubkey}\" إلى المضيف البعيد \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "يرجى إدخال كلمة مرور لـ \"{user}\"." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "نظام الملفات الوجهة لـ {path} مُنسق باستخدام FAT، والذي لا يدعم الروابط " "الصعبة. يُرجى استخدام نظام ملفات لينكس أصلي." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "المسار البعيد موجود لكن ليس مجلدا." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "نظام الملفات الوجهة لـ {path} مُنسق باستخدام FAT، والذي لا يدعم الروابط " "الصعبة. يُرجى استخدام نظام ملفات لينكس أصلي." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "نظام الملفات الوجهة لـ {path} هو مشاركة مُركبة عبر SMB. يُرجى التأكد من أن " "خادم SMB البعيد يدعم الروابط الرمزية أو تفعيل {copyLinks} في " "{expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "نسخ الروابط (فك الارتباط بالروابط الرمزية)" #: common/tools.py:504 msgid "Expert Options" msgstr "خيارات الخبراء" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "نظام الملفات الوجهة لـ {path} هو مشاركة مُركبة عبر sshfs. لا يدعم sshfs " "الروابط الصلبة. يُرجى استخدام وضع \"SSH\" بدلاً من ذلك." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "عنْ" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "المطورون" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "الترجمات" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "الرخصة" #: qt/app.py:172 msgid "Shortcuts" msgstr "إختصارات" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "هذه المجلد غير موجود\n" "في اللقطة المختارة حاليا." #: qt/app.py:257 msgid "Add to Include" msgstr "اضف للتضمين" #: qt/app.py:259 msgid "Add to Exclude" msgstr "اضف للاستبعاد" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "يبدو أن تطبيق {app_name} يعمل لأول مرة حيث لم يتم العثور على أي إعدادات." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "هل ترغب باستيراد إعدادات موجودة (من مجلد احتياطي أو من حاسوب آخر)؟" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "إن كان على وحدة تخزين خارجية، يرجى توصيلها ثم اضغط موافق." #: qt/app.py:470 msgid "Take a snapshot" msgstr "خذ لقطة" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "استخدم وقت التعديل والحجم لاكتشاف تغييرات الملفات." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "خذ لقطة (طريقة المجموعة الاختبارية)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "أستخدم المجامع الاختبارية لكشف التغيُّرات في الملفات." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "أوقف عملية التقاط اللقطة" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "استئناف عملية أخذ اللقطة" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "أوقف عملية أخذ اللقطة" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "حدث قائمة اللقطات" #: qt/app.py:497 msgid "Name snapshot" msgstr "سمي اللقطة" #: qt/app.py:501 msgid "Remove snapshot" msgstr "أزل اللقطة" #: qt/app.py:505 msgid "View snapshot log" msgstr "عرض سجل اللقطات" #: qt/app.py:509 msgid "View last log" msgstr "عرض اخر سجل" #: qt/app.py:513 msgid "Manage profiles…" msgstr "إدارة الملفات الشخصية…" #: qt/app.py:517 msgid "Shutdown" msgstr "أطفئ النظام" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "أطفئ النظام بعد اكتمال أخذ اللقطة." #: qt/app.py:521 msgid "Setup language…" msgstr "إعداد اللغة…" #: qt/app.py:525 msgid "Exit" msgstr "خروج" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "العودة بالزمن" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "ملف إعدادات الملفات الشخصية" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "سجل التغييرات" #: qt/app.py:555 msgid "FAQ" msgstr "الأسئلة الأكثر شيوعاً" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "إسأل سُؤالاً" #: qt/app.py:563 msgid "Report a bug" msgstr "بلّغ عن عِلة" #: qt/app.py:566 msgid "Translation" msgstr "الترجمة" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "عرض رسالة المشاركة في الترجمة." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "الإنتقال الى تشفير EncFS" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "عرض الرسالة حول إزالة ميزة التشفير EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "إسترجع" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "إسترجع الملفات والمجلدات المختارة الى اماكنهم الاصلية." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "إسترجع إلى …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "إسترجع الملفات والمجلدات المختارة إلى موقع جديد." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "إسترجع الملفات والمجلدات الظاهرة وكل محتوياتها الى اماكنهم الاصلية." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "إسترجع الملفات والمجلدات الظاهرة وكل محتوياتها إلى موقع جديد." #: qt/app.py:601 msgid "Up" msgstr "أعلى" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "أظهر الملفات المخفيّة" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "قارن اللقطات…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "عرض الرسالة حول إزالة ميزة التشفير EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "العودة بالزمن" #: qt/app.py:681 msgid "&Backup" msgstr "النسخ الاحتياطي" #: qt/app.py:692 msgid "&Restore" msgstr "&استرجع" #: qt/app.py:698 msgid "&Help" msgstr "مُساعدة" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "إذا تم إغلاق هذه النافذة، فإن برنامج الاستعادة سيتوقف عن تشغيل النظام عند " "انتهاء اللقطة." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "هل أنت متأكد من رغبتك في إغلاق النافذة؟" #: qt/app.py:1072 msgid "Working:" msgstr "يعمل:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "تم، لا حاجة إلى النسخ الاحتياطي" #: qt/app.py:1129 msgid "Working" msgstr "يعمل" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "خطأ" #: qt/app.py:1161 msgid "Sent" msgstr "أرسل" #: qt/app.py:1162 msgid "Speed" msgstr "السرعة" #: qt/app.py:1163 msgid "ETA" msgstr "الوقت المتبقي" #: qt/app.py:1225 msgid "Global" msgstr "عام" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "الرئيسية" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "مجلدات النسخ الاحتياطي" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "اسم اللقطة" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "هل أنت متأكد أنك تريد إزالة هذه اللقطة؟" msgstr[1] "هل أنت متأكد أنك تريد إزالة هذه اللقطة؟" msgstr[2] "هل أنت مُتأكد أنك تود إزالة اللقطتان؟" msgstr[3] "هل أنت متأكد أنك تريد إزالة هذه اللقطات؟" msgstr[4] "هل أنت متأكد أنك تريد إزالة هذه اللقطات؟" msgstr[5] "هل أنت متأكد أنك تريد إزالة هذه اللقطات؟" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "إنشاء نسخ احتياطية ملحقة بـ {suffix}\n" "قبل الكتابة فوق العناصر المحلية أو إزالتها." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "سيتم إعادة تسمية الإصدارات الأحدث من الملفات باستخدام ملحق {suffix} قبل " "الاستعادة. إذا لم تعد تحتاج إليها ، يمكنك إزالتها باستخدام الأمر التالي:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "استعادة العناصر الغير موجودة\n" "أو التي هي أحدث من الموجودة في الوجهة فقط.\n" "باستخدام خيار \"rsync --update\"." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "إزالة العناصر الأحدث في المجلد الأصلي." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "استعادة الملفات أو المجلدات المحددة إلى الوجهة الأصلية مع حذف الملفات أو " "المجلدات غير الموجودة في اللقطة. كن حذراً للغاية لأن هذه العملية ستؤدي إلى " "حذف الملفات والمجلدات التي تم استبعادها أثناء أخذ اللقطة." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "هل تريد حقًا استعادة هذا العنصر إلى المجلد الجديد\n" "{path}؟" msgstr[1] "" "هل أنت متأكد أنك ترغب في استرجاع عنصر واحد إلى المجلد الجديد\n" "{path}؟" msgstr[2] "" "هل تريد حقًا استعادة هذان العنصران إلى المجلد الجديد\n" "{path}؟" msgstr[3] "" "هل أنت متأكد أنك ترغب في استرجاع عناصر إلى المجلد الجديد\n" "{path}؟" msgstr[4] "" "هل أنت متأكد أنك ترغب في استرجاع عنصرًا إلى المجلد الجديد\n" "{path}؟" msgstr[5] "" "هل أنت متأكد أنك ترغب في استرجاع عنصرًا إلى المجلد الجديد\n" "{path}؟" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "لا توجد عناصر لاسترجاعها؟" msgstr[1] "هل أنت متأكد أنك ترغب في استرجاع عنصر واحد؟" msgstr[2] "هل أنت متأكد أنك ترغب في استرجاع عنصرين؟" msgstr[3] "هل أنت متأكد أنك ترغب في استرجاع {n} عناصر؟" msgstr[4] "هل أنت متأكد أنك ترغب في استرجاع {n} عنصرًا؟" msgstr[5] "هل أنت متأكد أنك ترغب في استرجاع {n} عنصرًا؟" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "هل أنت متأكد من حذف جميع الملفات الأحدث في {path}؟" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "هل أنت متأكد من حذف جميع الملفات الأحدث في المجلد الأصلي؟" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD} تحذير{BOLDEND}: حذف الملفات في جذر نظام الملفات قد يؤدي إلى تعطل " "نظامك بالكامل." #: qt/app.py:1857 msgid "Snapshot" msgstr "لقطة" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "استعادة {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "استرجع {path} إلى …" # ignore-placeholder-compare #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "مرحبا\n" "لقد استخدمت تطبيق العودة في الزمن باللغة العربية عدة مرات من قبل.\n" "لقد تم ترجمة {perc} من برنامج العودة في الزمن إلى اللغة العربية. بغض النظر إلى خبرتك التقنية, بإمكانك المساهمة في الترجمة ومن ثم برنامج العودة في الزمن نفسه.\n" "الرجاء زيارة موقع {translation_platform_url} إذا رغبت في المشاركة. للمزيد من الاستفسارات او المساعدة, الرجاء زيارة {back_in_time_project_website}.\n" "نعتذر للمقاطعة, هذه الرسالة لن تعرض مرة أخرى. بإمكانك الإطلاع على هذه الرسالة في أي وقت عبر قائمة المساعدة.\n" "فريق العودة في الزمن" #: qt/app.py:2071 msgid "translation platform" msgstr "منصة الترجمة" #: qt/app.py:2076 msgid "Website" msgstr "الموقع الإلكتروني" #: qt/app.py:2090 msgid "Your translation" msgstr "ترجمتك" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "إعدادات اللغة ستُفعّل فقط بعد إعادة تشغيل برنامج العودة بالزمن." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "سيُوقَف دعم EncFS في المستقبل القريب. وبالتالي لا يُوصى باستخدام هذا الوضع " "للملف الشخصي بعد الآن." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "ورقة بيضاء" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "تستخدم الملفات التعريفية التالية التشفير مع EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "لن يتم عرض هذه الرسالة مرة أخرى. هذه النافذة متاحة في أي وقت من خلال قائمة " "المساعدة." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "فريق Back In Time الخاص بك" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "إعداد اللغة" #: qt/languagedialog.py:97 msgid "System default" msgstr "الإعدادات الافتراضية للنظام" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "استخدم لغة نظام التشغيل." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "مترجم: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "عرض السجل الأخير" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "عرض سجل اللقطات" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "الملف الشخصي:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "لقطات:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "مُرَشِح:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "كل" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "تغييرات" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "أخطاء" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "لا توجد معلومات" msgstr[1] "توجد معلومات واحدة" msgstr[2] "توجد معلومتان" msgstr[3] "معلومات" msgstr[4] "معلومات" msgstr[5] "معلومات" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "فشل نقل rsync (تجريبي)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] خطأ، [I] معلومات، [C] تغيير" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "فك تشفير المسارات" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "إدارة الملفات الشخصية" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "تعديل" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "أضف" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "أزل" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&عام" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&ضمْن" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "ضمْن ملفات ومُجلدات" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "أضف ملفاً" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "أضف مُجلدا" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&استثني" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}معلومات{ENDBOLD}: في وضع 'تشفير SSH'، فإن النجوم المفردة أو المزدوجة " "فقط هي التي تعمل (على سبيل المثال {example2}). سيتم تجاهل أنواع أخرى من " "الأحرف البديلة والأنماط (مثل {example1}). أسماء الملفات غير قابلة للتنبؤ في " "هذا الوضع بسبب التشفير بواسطة EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "استثني الأنماط, ملفات أو مُجلدات" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "أضف افتراضيًا" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "استبعاد الملفات الأكبر من:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "استثني الملفات التي يزيد حجمها عن {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "مع تعطيل 'وضع rsync الكامل'، ستؤثر هذه الميزة فقط على الملفات الجديدة، حيث " "إن ذلك يعد خيار نقل لـ rsync، وليس خيار استبعاد. لذلك، ستستمر الملفات " "الكبيرة التي نُسِخَت احتياطيًا سابقًا في الظهور في اللقطات حتى لو تم " "تعديلها." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&خيارات" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "خيارات الخبير" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "استعادة الإعدادات" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "تحرير استدعاء المستخدم" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "ملف شخصي جديد" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "أعِد تسمية الملف الشخصي" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "هل أنت متأكد أنك تريد حذف الملف الشخصي \"{name}\"؟" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}موصى به بشدة{ENDBOLD}: (جميع التوصيات مدرجة بالفعل.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}موصى به بشدة{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "إستثني نمط" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "إستثني ملف" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "إستثني مُجلد" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "ضمْن ملف" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" هو رابط رمزي. لن يتم نسخ الهدف المرتبط حتى تقوم بتضمينه أيضًا.\n" "هل ترغب في تضمين الهدف المرتبط بدلاً من ذلك؟" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "ضمْن مُجلد" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "معطل لأن هذه النمط غير فعال في وضع 'تشفير SSH'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "جدول زمني" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "يوم:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "يوم الأسبوع:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "ساعات:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "قم بتشغيل Back In Time بمجرد توصيل محرك الأقراص (مرة واحدة فقط كل X أيام).\n" "سيتم مطالبتك بكلمة مرور sudo الخاصة بك." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "شغل \"Back In Time\" بشكل متكرر. هذا مفيد إذا لم يكن الكمبيوتر قيد التشغيل " "بانتظام." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "كل:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "تفعيل تسجيل رسائل التصحيح" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "يكتب رسائل مستوى التصحيح في سجل النظام عبر \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "تحذير: استخدم هذا مؤقتًا فقط للتشخيص، لأنه يولد كمية كبيرة من البيانات." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "مُعطل" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "في كل إقلاع/إعادة إقلاع" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "كل {n} دقيقة" msgstr[1] "كل {n} دقيقة" msgstr[2] "كل {n} دقيقتان" msgstr[3] "كل {n} دقائق" msgstr[4] "كل {n} دقيقة" msgstr[5] "كل {n} دقيقة" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "كل{n} ساعة" msgstr[1] "كل {n} ساعة" msgstr[2] "كل {n} ساعتين" msgstr[3] "بضع {n} ساعات" msgstr[4] "كل {n} ساعة" msgstr[5] "كل{n} ساعة" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "كل{n} ساعة" msgstr[1] "كل {n} ساعة" msgstr[2] "كل {n} ساعتين" msgstr[3] "كل {n} ساعات" msgstr[4] "كل {n} ساعة" msgstr[5] "كل {n} ساعة" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "ساعات مخصصة" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "كل يوم" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "متكررة (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "عند وصل وسيط تخزين (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "كل أسبوع" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "كل شهر" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "كل سنة" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "ساعات" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "يوم(أيام)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "أسبوع(أسابيع)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "شهر(شهور)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "يمكن أن تكون الساعات المخصصة قائمة مفصولة بفواصل من الساعات فقط (مثل " "8،12،18،23) أو */3 للنسخ الاحتياطية الدورية كل 3 ساعات." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "وكيل SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "المُضيف:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "المنفذ:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "مستخدم:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "اتصل بالجهاز الهدف من خلال هذا الوكيل (المعروف أيضًا باسم جهاز القفز). راجع " "\"-J\" في وثائق أمر \"ssh\" أو \"ProxyJump\" في صفحة \"ssh_config\" المساعدة" " لمزيد من التفاصيل." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "سؤال" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "قم بتشغيل 'rsync' باستخدام '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "كوظيفة cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "على المضيف البعيد" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "عند أخذ لقطة يدوية" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(يرجى تثبيت 'nocache' لتمكين هذا الخيار)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "في الجهاز المحلي" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "قم بإعادة توجيه stdout إلى /dev/null في وظائف cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "سيرسل نظام cron تلقائيًا بريدًا إلكترونيًا مع المخرجات المرفقة لوظائف cron " "إذا تم تثبيت MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "قم بإعادة توجيه stderr إلى /dev/null في وظائف cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "سيرسل نظام cron تلقائيًا بريدًا إلكترونيًا مع الأخطاء المرفقة لوظائف cron " "إذا تم تثبيت MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "كيلوبايت/ثانية" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "تحديد حد سقف الـBandwidth لـ rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "الحفاظ على ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "المُحافظة على الصفات المُوسعة (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "انسخ الروابط الغير الآمنة (تعمل فقط مع الروابط الأساسية)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "تقييد إلى نظام ملفات واحد" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "يجب أن تكون الخيارات بين علامات اقتباس، مثل {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "ألصق خيارات إضافية إلى rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "بادئة للتشغيل قبل كل أمر على المضيف البعيد." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "يجب الهروب من المتغيرات باستخدام \\$FOO. هذا لا يؤثر على rsync. لذلك، لإضافة" " بادئة لـ rsync، استخدم \"{example_value}\" مع {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "الإفتراضي" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "أضف بادئة إلى أوامر SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "تحقق مما إذا كان المضيف البعيد متصلًا بالإنترنت" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "تحذير: إذا تم تعطيل هذه الميزة ولم يكن المضيف البعيد متاحًا، فقد يؤدي ذلك " "إلى بعض الأخطاء الغريبة." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "تحقق مما إذا كان المضيف البعيد يدعم جميع الأوامر الضرورية." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "تحذير: إذا تم تعطيل هذه الميزة ولم يدعم المضيف البعيد جميع الأوامر الضرورية،" " فقد يؤدي ذلك إلى بعض الأخطاء الغريبة." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(افتراضي: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "مُعطَّل" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "مفعَّل" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "الوضع:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "أين ستُحْفَظ اللقطات" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "إعدادات SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "المسار:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "تشفير:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "مفتاح تشفير خاص:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "اختر ملف مفتاح خاص موجود (عادة ما يسمى \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "إنشاء مفتاح SSH جديد بدون كلمة مرور (غير مسموح إذا تم اختيار ملف مفتاح خاص " "بالفعل)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "كلمة المرور" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "حفظ كلمة المرور في سلسلة المفاتيح" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "تخزين كلمة المرور في ذاكرة التخزين المؤقت لـ Cron (مشكلة أمنية: يمكن لـ root" " قراءة كلمة المرور)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "مُتقدم" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "مسار اللقطة الكاملة:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "لم تقم باختيار ملف مفتاح خاص لـ SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "هل ترغب في إنشاء زوج مفاتيح عام/خاص جديد بدون كلمة مرور؟" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "ملف المفتاح الخاص \"{file}\" غير موجود." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "هل ترغب في نسخ مفتاح SSH العام الخاص بك إلى المضيف البعيد لتمكين تسجيل " "الدخول بدون كلمة مرور؟" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "لا يمكن تأكيد مصداقية المضيف {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "بصمة مفتاح {keytype} هي:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "يرجى التحقق من هذه البصمة. هل ترغب في إضافتها إلى ملف 'known_hosts' الخاص " "بك؟" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "هل أنت متأكد أنك تريد تغيير مجلد اللقطات؟" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "فشل في إنشاء مفتاح SSH جديد في {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "فَعْلّ التنبيهات" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "تعطيل اللقطات عند العمل على البطارية" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "حالة الطاقة غير متاحة من النظام" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "تشغيل لقطة واحدة فقط في كل مرة" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "ستكون اللقطات الأخرى محجوبة حتى يتم الانتهاء من اللقطة الحالية. هذه خيار " "عام. لذا، سيكون له تأثير على جميع الملفات الشخصية لهذا المستخدم. ولكن تحتاج " "إلى تفعيل ذلك لجميع المستخدمين الآخرين أيضًا." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "نسخ احتياطي للملفات المستبدلة في أثناء الاستعادة" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "ستُعَاد تسمية الإصدارات الأحدث من الملفات مع إضافة {suffix} قبل الاستعادة. " "إذا لم تكن بحاجة إليها بعد الآن، يمكنك إزالتها باستخدام {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "استمر عند حدوث خطأ (احتفظ باللقطات غير المكتملة)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "استخدم checksum لاكتشاف التغييرات" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "خذ لقطة جديدة، سواء كانت هناك تغييرات أم لا." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "مستوى السجل:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "لا شيء" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "لا تُزيل اللقطات المُسماّة." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "لا تُزيل اللقطات المُسماّة." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "سنة(سنوات)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "أزل اللقطة" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "تشغيل في الخلفية على المضيف البعيد." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "أبقي كل اللقطات حتى نهاية" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "يوم (أيّام)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "احتفظ بلقطة واحدة يومياً لآخر" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "احتفظ بلقطة واحدة في الأسبوع لآخر" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "أسبوع(أسابيع)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "احتفظ بلقطة واحدة في الشهر لآخر" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "شهر(أشهر)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "أبقي كل اللقطات حتى نهاية" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "إذا كانت المساحة المتاحة أقل من:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "إذا كانت inodes المتوفرة أقل من:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "إزالة اللقطات القديمة" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "سؤال" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "الملف الشخصي: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "عرض أخر سجل" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "تشغيل {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "جارٍ العمل…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "أُرسل:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "السرعة:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "الوقت المتبقي:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "لقطات" #: qt/qttools.py:506 msgid "Today" msgstr "اليوم" #: qt/qttools.py:513 msgid "Yesterday" msgstr "البارحة" #: qt/qttools.py:522 msgid "This week" msgstr "هذا الأسبوع" #: qt/qttools.py:529 msgid "Last week" msgstr "الأسبوع الماضي" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "هذه ليست لقطة ولكن عرض حي لملفاتك المحلية" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "آخر فحص {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "استيراد الإعدادات" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "لم يتم العثور على إعدادات" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "استورد" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "حدد مجلد اللقطة الذي يجب استيراد ملف التكوين منه. قد يبدو المسار كالتالي: " "{samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "إذا كان المجلد موجودًا على محرك خارجي أو بعيد، فيجب تركيبه يدويًا مسبقًا." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "عرض السجل الكامل" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "خيارات حول مقارنة اللقطات" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "الأمر:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "المعلمات:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "استخدم %1 و %2 لوسائط المسار" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "يرجى تعيين أمر diff أو الضغط على إلغاء." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "لا يمكن العثور على الأمر \"{cmd}\" في هذا النظام. يرجى تجربة شيء آخر أو " "الضغط على إلغاء." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "لم يتم تعيين أي معلمات لأمر الفرق. سيتم استخدام القيمة الافتراضية " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "اللقطات المختلفة فقط" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "قم بإدراج اللقطات التي تساوي فقط:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "فحص بعمق (أكثر دقة, ولكن بطيء)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "احذف" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "تحديد الكل" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "مقارنة" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "أذهب إلى" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "خيارات" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "لا تستطيع مُقارنة اللقطة بنفسها." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "هل ترغب حقًا في حذف {file} من اللقطة {snapshot_id}؟" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "هل ترغب حقًا في حذف {file} في {count} لقطات؟" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "تحذير: لا يمكن التراجع عن ذلك." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "استبعاد {path} من اللقطات المستقبلية؟" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "لا يمكن تضمين المجلد الفرعي للنسخ الاحتياطي." backintime-1.5.4/common/po/bg.po000066400000000000000000002404061477034762000165050ustar00rootroot00000000000000# Bulgarian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-12 10:20+0000\n" "Last-Translator: buhtz \n" "Language-Team: Bulgarian \n" "Language: bg\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Внимание" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Основен профил" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Местен (EncFS криптиран)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS криптиран)" #: common/config.py:278 msgid "Local" msgstr "Местен" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Частен SSH ключ" #: common/config.py:283 msgid "Local encrypted" msgstr "Местен - криптиран" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Криптиране" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH криптиран" #: common/config.py:296 msgid "Default" msgstr "По подразбиране" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Профил: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Директорията за моментни архиви не е валидна." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" "Поне една доректория трябва да бъде избрана за резервно копие (бекъп)." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Директория: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Тази директория не може да бъде включена за резервно копие." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Неуспех при създаването на нова периодична задача - crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Програмата за автоматично изпълнение на задачи (Cron) не работи въпреки че " "задачата за автоматично изпълнение е конфигурирана в crontab. Автоматичното " "създаване на резервно копие няма да работи. Програмата Cron е инсталирана но" " е възможно да не конфигурирана за автоматично стартиране. Опитайте да " "изпълните командата \"systemctl enable cron\" или се консултирайте с " "ръководството на работа на вашата GNU/Linux дистрибуция." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Неуспех при задаването на Udev правило за профил {profile_id}. DBus Service " "{dbus_interface} не е открит" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "" "Планираните при монтиране на диск архиви чрез програмта Udev не работят в " "режим {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Не може да бъде намерен UUID за {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Запазването на конфигурацията се провали" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Зареждането на конфигурация се провали" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Профилът \"{name}\" вече съществува." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Последният профил не може да бъде премахнат." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Неуспех в монтирането '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Конфигурацията за криптираната директория не е намерена." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Създаване на нова криптирана директория?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Откажи" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Моля потвърдете паролата." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Паролата не съвпада." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Снимка на екрана" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Неуспех при демонтиране на {mountprocess} от {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command} не е намерен. Моля, инсталирайте чрез {installcommand}" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Монтираната директория {mntpoint} не е празна." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Въведете парола за {mode} профил \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "НЕУСПЕХ" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Възстановете разрешенията" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Готово" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Отлагане на архивирането, докато устройството работи на батерия" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Директорията за моментни архиви не може да бъде намерена." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Директорията за моментни архиви не може да бъде открита. Ако е на преносимо " "устройство, моля включете го и натиснете ОК." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Изчакване %s секунда." msgstr[1] "Изчакване %s секунди." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Неуспех при създаването на моментен архив {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Моля изчакайте. Финализиране…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Директорията не може да бъде създадена." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Запазване на конфигурационен файл…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Запазване на правата…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Намерен е моментен архив {snapshot_id}, който може да бъде продължен." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Премахване на остатъчна {snapshot_id} директория от последния опит" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Директорията не може да бъде премахната" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Създаване на моментен архив" #: common/snapshots.py:1430 msgid "Success" msgstr "Успешно" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Частично прехвърляне поради грешка" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Частично прехвърляне поради изчезнали изходни файлове (вж. 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' завърши с код за изход {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "За повече информация вижте 'man rsync'" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Отрицателните изходни кодове на rsync са номера на сигнали, вижте 'kill -l' " "и 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Няма открити промени, не е нужен нов моментен архив" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "{new_path} не може да бъде преименуван на {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Умно премахване" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Приложи правилата за премахване на старите моментни архиви" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Приложи правилата за запаметяване" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Опит за запазване на минимално свободно пространство" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Опит за запазване на минимум {perc} свободни inode" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Сега" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Неуспех в монтирането на {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent не е намерен. Моля, уверете се, че е инсталиран." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Неуспех при отключване на частния ключ за ssh. Грешна парола или паролата не" " е налична в cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Шифърът {cipher} е неуспешен за {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Отдалеченият път съществува, но не е директория." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Отдалеченият път няма права за запис." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Отдалеченият път не е изпълним." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Не може да се създаде отдалечен път." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Отдалечената система {host} не поддържа {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Вижте 'man backintime' за допълнителни инструкции" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Проверката на командите на системата {host} върна непозната грешка" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Отдалечената система {host} не поддържа твърди връзки" #: common/sshtools.py:1191 #, fuzzy, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Копирай публичния ssh ключ \"{pubkey}\" на отдалечената система \"{host}\"" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Моля въведете паролата за \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Файловата система в {path} е от тип NTFS и не е съвместима с файлови системи" " от тип Unix . Моля, използвайте Linux файлова система." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "Отдалеченият път {path} съществува, но не е директория." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Създаването на следната директория завърши неуспешно:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Възможно е правата за запис да са забранени." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Файлова система за {path} е от тип FAT и не поддържа преки пътища. Моля, " "използвайте GNU/Linux файлова система." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Файлова система за {path} е от споделен тип - SMB. Моля, уверете се, че " "отдалеченият SMB сървър поддържа преки пътища или активирайте " "\"{copyLinks}\" в \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Копирай връзките към файлове (следвай символичните връзки)" #: common/tools.py:504 msgid "Expert Options" msgstr "Експертни настройки" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Файлова система за {path} е от споделен тип - sshfs. Sshfs не поддържа преки" " пътища. Моля, използвайте режим 'SSH'." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Неуспех при създаването на файл в следната директория:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Относно" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Създатели" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Преводачи" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Лизенз за изходния код" #: qt/app.py:172 msgid "Shortcuts" msgstr "Препратки" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Тази директория не съществува\n" "в избрания моментен архив." #: qt/app.py:257 msgid "Add to Include" msgstr "Добавете, за да включите" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Добавете, за да изключите" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} изглежда, че се стартира за първи път, тъй като не е намерена " "конфигурация." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Импортиране на съществуваща конфигурация (от архивирана целева директория " "или от друг компютър)?" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Директорията за моментни архиви не може да бъде открита. Ако е на преносимо " "устройство, моля включете го и натиснете ОК." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Направете моментен архив" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Използвайте времето на модификацията и размера за откриване на промени във " "файловете." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Създаване на моментен архив (режим на контролна сума)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Използване на контролни суми за откриване на промени във файловете." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Пауза на моментното копие" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Продължаване на моментното копие" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Спиране на моментното копие" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Обновяване на списъка с архиви" #: qt/app.py:497 msgid "Name snapshot" msgstr "Наименувай архив" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Премахване на архив" #: qt/app.py:505 msgid "View snapshot log" msgstr "Преглед на дневника на архивите" #: qt/app.py:509 msgid "View last log" msgstr "Преглед на последния дневник" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Управление на профили…" #: qt/app.py:517 msgid "Shutdown" msgstr "Изключване" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Изключване на системата след като моментното архивно копие е готово." #: qt/app.py:521 msgid "Setup language…" msgstr "Език на настройките…" #: qt/app.py:525 msgid "Exit" msgstr "Изход" #: qt/app.py:529 msgid "User manual" msgstr "Ръководство за употреба" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Отваря ръководство за употреба в браузър (локално ако е налично, иначе " "онлайн)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Документация: Назад във Времето" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Показва потребителското ръководство за Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "Документация: Файл за конфигуриране на профили" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Показва потребителството ръководство за конфигурационния файл на профилите " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Уебсайт на проекта" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Отваря уебсайта на Back In Time в браузър" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "История на промените" #: qt/app.py:555 msgid "FAQ" msgstr "ЧЗВ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Отваря Често Задаваните Въпроси (ЧЗВ) в браузър" #: qt/app.py:559 msgid "Ask a question" msgstr "Задайте въпрос" #: qt/app.py:563 msgid "Report a bug" msgstr "Докладвайте неизправност" #: qt/app.py:566 msgid "Translation" msgstr "Превод" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Отново показва съобщението за участие в превода." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Преход на шифроване (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Отново показва съобщението за премахване на EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Възстановяване" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Възстановете избраните файлове или директории на първоначалното място." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Възстановяване в …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Възстановете избраните файлове или директории на друго място." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Възстановете показаната директория и нейното съдържание на първоначалното " "място." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Възстановете показаната директория и нейното съдържание на ново място." #: qt/app.py:601 msgid "Up" msgstr "Нагоре" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Показване на скритите файлове" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Сравни архиви…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Тестова Версия" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Показва отново съобщението за Тестовата Версия." #: qt/app.py:676 msgid "Back In &Time" msgstr "Назад във Времето" #: qt/app.py:681 msgid "&Backup" msgstr "&Резервно копие" #: qt/app.py:692 msgid "&Restore" msgstr "&Възстановяване" #: qt/app.py:698 msgid "&Help" msgstr "&Помощ" #: qt/app.py:743 msgid "Icons only" msgstr "Само иконки" #: qt/app.py:746 msgid "Text only" msgstr "Само текст" #: qt/app.py:749 msgid "Text below icons" msgstr "Текст под иконките" #: qt/app.py:752 msgid "Text beside icon" msgstr "Текст до иконките" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ако затворите този прозорец, Back in Time няма да може да изключи вашата " "система когато моментното копие е завършено." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Наистина ли искате затворите?" #: qt/app.py:1072 msgid "Working:" msgstr "Изпълнение:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Готово, не е необходимо архивиране" #: qt/app.py:1129 msgid "Working" msgstr "Изпълняване" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Грешка" #: qt/app.py:1161 msgid "Sent" msgstr "Изпратено" #: qt/app.py:1162 msgid "Speed" msgstr "Скорост" #: qt/app.py:1163 msgid "ETA" msgstr "Приблизително оставащо време" #: qt/app.py:1225 msgid "Global" msgstr "Глобални" #: qt/app.py:1226 msgid "Root" msgstr "Файлова система" #: qt/app.py:1227 msgid "Home" msgstr "Домашна директория" #: qt/app.py:1255 msgid "Backup directories" msgstr "Резевни директории" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Име на моментния архив" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "" "Сигурни ли сте, че желаете окончателно да премахнете моментния архив?" msgstr[1] "" "Сигурни ли сте, че желаете окончателно да премахнете моментните архиви?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Създайте резервни копия, завършващи със {suffix} преди\n" "да бъдат презаписани или премахнати локални файлове." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "По-новите версии на файловете ще бъдат преименувани с последващ {suffix} " "преди възстановяването. Ако те не са необходими вече, може да ги премахнете " "посредством командата:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Възстановете само файлове, които не съществуват,\n" "или са по-нови от тези в крайната папка.\n" "Използвайки опцията \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Премахнете по-новите файлове от първоначалната директория." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Възстановяване на избраните файлове или директории в първоначалната " "дестинация и изтриване на файлове/папки, които не са в моментният архив. " "Бъдете изключително внимателни, това ще доведе до изтриване на " "файлове/директории, които са били изключени по време на създаването на " "архива или са по-нови от него." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Наистина ли искате да възстановите този файл в новата директория?" msgstr[1] "" "Наистина ли искате да възстановите тези файлове в новата директория?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Наистина ли искате да възстановите този файл?" msgstr[1] "Наистина ли искате да възстановите файловете?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Сигурни ли сте, че желаете окончателно да премахнете всички по-нови файлове " "в {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Сигурни ли сте, че искате да премахнете всички по-нови файлове в " "първоначалната директория?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}ПРЕДУПРЕЖДЕНИЕ{BOLDEND}: Изтриването на файлове в коренната част на " "файловата система може да разруши цялата ви система." #: qt/app.py:1857 msgid "Snapshot" msgstr "Моментно архивно копие" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Възстановете {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Възстановете {path} в …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Здравейте\n" "Вече няколко пъти сте използвали Back In Time на {language} език.\n" "Преводът на инсталираната от вас версия на Back In Time на {language} е {perc}. Независимо от нивото на техническите Ви познания, можете да допринесете за превода и по този начин за самия Back In Time.\n" "Моля, посетете {translation_platform_url}, ако желаете да дадете своя принос. За допълнителна помощ и въпроси, моля, посетете {back_in_time_project_website}.\n" "Извиняваме се за прекъсването и това съобщение няма да бъде показвано отново. Този диалог е достъпен по всяко време чрез менюто за помощ.\n" "Вашият екип на Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "платформа за превод" #: qt/app.py:2076 msgid "Website" msgstr "Уебсайт" #: qt/app.py:2090 msgid "Your translation" msgstr "Вашият превод" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "В Fediverse в платформата Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Писмо до {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Пощенски списък на адрес {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} на уебсайта на проекта." #: qt/app.py:2118 msgid "Open an issue" msgstr "Отвори нов сигнал за нередност" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" "Като алтернатива можете да използвате друг канал за комуникация по ваш " "избор." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Тази версия на Back In Time е Тестова и е предназначена основно за тестване на стабилност в подготовка за следващото официално издание.\n" "Не се събират потребителски данни или телеметрия. Екипът на Back In Time обаче е много заинтересован да разбере дали тези Тестови версии се използват и дали си струва да продължим да предоставяме такива предварителни версии.\n" "Ето защо екипът любезно моли за кратка обратна връзка дали сте тествали тази версия, дори и да не сте срещнали никакви проблеми. Дори един бърз тест от няколко минути би ни помогнал много.\n" "Налични са следните опции за контакт:\n" "{contact_list}\n" "В тази версия това съобщение няма да се показва отново, но може да бъде достъпно по всяко време чрез менюто за помощ.\n" "Благодарим ви за подкрепата и че ни помагате да подобрим Back In Time!\n" "Вашият екип Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Езиковите настройки влизат в сила само след рестартиране на Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Създаването на профил в EncFS ще бъде премахнато в следващото второстепенно " "издание (1.7), планирано за 2026 г." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Вече не се препоръчва използването на този режим за профил." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "проучване" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Поддръжката за EncFS се прекратява поради уязвимости в сигурността." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "За повече подробности, включително потенциални алтернативи, моля, вижте това" " {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Следните профили използват шифроване с EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Предвидена е замяна, но не може да се гарантира, че ще пристигне навреме." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Потребителите са поканени да се включат в тази дискусия. Актуализирани " "подробности за следващите стъпки са налични в този {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Това съобщение няма да се показва отново. Този диалогов прозорец е достъпен " "по всяко време чрез помощното меню." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Екипа Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Език на настройката" #: qt/languagedialog.py:97 msgid "System default" msgstr "Система по подразбиране" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Използвайте езика на операционните системи." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Преведено: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Последно преглеждане на записа със събития" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Преглеждане на записа със събития относно моментните копия" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Профил:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Моментни архиви:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Филтър:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Всичко" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Промени" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Грешки" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Информация" msgstr[1] "Информация" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync неуспешен трансфер (експериментален)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[Г] Грешка, [И] Информация, [П] Промяна" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "декодиране на пътищата" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Управление на профили" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Редактиране" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Добавяне" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Премахване" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Общи" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Включване" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Включване на файлове и директории" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Добавяне на файл" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Добавяне на директории" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Изключване" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}ИНФОРМАЦИЯ{ENDBOLD}: В режим „SSH криптиране“ функционират само " "единични или двойни звездички (напр. {example2}). Други типове заместващи " "символи и шаблони ще бъдат игнорирани (напр. {example1}). Имената на " "файловете са непредвидими в този режим поради криптиране от EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Изключване на пътища, файлове или директории" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Добавете по подразбиране" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Изключете файлове, по-големи от:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Изключете файлове, по-големи от: {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Изключете файлове, по-големи от стойността в %(prefix)s. При изключен 'Full " "rsync mode', това ще засегне само новите файлове, защото това е преносна " "опция за rsync, а не изключваща такава. Така че големите файлове, които са " "били архивирани преди, ще останат в моментните копия дори и да са били " "променени." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Триене & Запазване" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Настройки" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Е&кспертни настройки" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Възстановете конфигурацията" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Променете потребителския скрипт" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Нов профил" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Преименуване на профил" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Сигурни ли сте, че желаете да изтриете профила \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Силно препоръчително{ENDBOLD}: (Всички препоръки вече са приложени.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Силно препоръчително{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Шаблон за изключване" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Изключване на файл" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Изключване на директории" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Включване на файл" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" е пряк път. Целта, към която сочи, няма да бъде архивирана докато не добавите и нея.\n" "Бихте ли искали да добавите крайната цел вместо това?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Включване на директории" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Деактивирано, защото този шаблон не функционира в режим „SSH криптиране“." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Разписание" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Ден:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Работен ден:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Час:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Часа:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "след дадения час" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Минути:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Изпълнявайте Back In Time веднага щом дискът бъде свързан (веднъж на X дни)." " Ще бъдете помолени да въведете вашата sudo парола." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Изпълнявайте Back In Time многократно. Това е полезно, когато компютърът не " "работи редовно." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Всеки:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Разрешете записването на съобщения за грешки" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Записва съобщения на ниво отстраняване на грешки в системния регистър чрез " "\"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Внимание: Използвайте това само временно за диагностика, тъй като генерира " "голямо количество изходни данни." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Изключено" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "При всяко зареждане/рестартиране" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "На всяка {n} минута" msgstr[1] "На всеки {n} минути" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "На всеки час" msgstr[1] "На всеки {n} часове" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "На всеки {n} часа" msgstr[1] "На всеки {n} часове" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Конкретни часове" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Всеки ден" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Многократно (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Когато дискът бъде свързан (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Всяка седмица" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Всеки месец" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Всяка година" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Час (а)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Дни" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Седмици" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Месеци" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Персонализираните часове могат да представляват само списък, разделен със " "запетаи (напр. 8,12,18,23) или */3 за периодични архиви на всеки 3 часа." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Прокси" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Хост:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Порт:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Потребител:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Свържете се с отдалечената система чрез прокси (известен също като междинен " "хост). Вижте \"-J\" в документацията на командата \"ssh\" или \"ProxyJump\" " "в страницата с ръководство на \"ssh_config\" за подробности." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Внимание:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Тези опции са за експертни настройки. Променете само ако сте напълно наясно " "с техните последици." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Изпълнете 'rsync' посредством '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "като периодична задача" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "върху отдалечен хост" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "когато се изпълнява ръчно моментно копие" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "Моля инсталирайте 'nocache', за да активирате тази опция" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "върху настоящата машина" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Пренасочете стандартният изход към /dev/null при периодичните задачи." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron автоматично ще изпрати имейл с прикачен резултат от cronjobs, ако е " "инсталиран MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" "Пренасочете стандартният изход за грешки към /dev/null за периодични задачи." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron автоматично ще изпрати имейл с прикачени грешки на cronjobs, ако е " "инсталиран MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/сек" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Ограничете използваният трафик от rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Запазване на ACL (списък за контрол на достъпа)" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Запазване на разширените атрибути (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Копиране на несигурните връзки (работи само с абсолютни връзки)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Ограничете до една файлова система" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Опциите трябва да бъдат цитирани, напр. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Добавете допълнителни опции към rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Префикс за изпълнение преди всяка команда на отдалечената система." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Променливите трябва да бъдат избегнати с \\$FOO. Това не обхваща rsync. Така" " че, за да добавите префикс за rsync, използвайте \"{example_value}\" с " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "по подразбиране" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Добавете префикс към SSH командите" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Проверете дали отдалеченият хост е онлайн" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Внимание: ако е изключено и отдалечената система не е налична, това може да " "доведе до някои непредвидени грешки." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Проверете дали отдалечената система поддържа всички необходими команди." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Внимание: ако е изключено и отдалечената система не поддържа всички " "необходими команди, това може да довете до неочаквани грешки." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(по подразбиране: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "деактивирано" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "активирано" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Режим:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Къде да се запазват моментните архиви" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH настройки" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Път:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Шифър:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Частен ключ:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Изберете съществуващ частен ключ (обикновено озаглавен \"id_rsa\" или " "\"id_ed25519\" в по-нови системи)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Създайте нов SSH ключ без парола (не е позволено, ако файл с частен ключ е " "вече избран)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Парола" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Запазете паролата в ключодържателя" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Кеширайте паролата за периодичните задачи (Възможен проблем със сигурността:" " потребител root може да достъпва паролата)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Разширени" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Пълен път за моментни архивни копия:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Не сте избрали файл с частен ключ за SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Не сте избрали частен ключ за SSH. Бихте ли искали да се създадете нова " "двойка частен/публичен ключ без парола?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Файлът с частния ключ \"{file}\" не съществува." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Бихте ли искали да копирате вашият публичен SSH ключ върху отдалечената " "система, за да активирате вход без парола?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Достоверността на системата {host} не може да бъде потвърдена." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} ключовият отпечатък е:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Моля потвърдете този отпечатък! Бихте ли искали да го добавите към " "'known_hosts' файлът с позволени хостове?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "" "Сигурни ли сте, че желаете да промените директнорията за моментни архиви?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Неуспех при създаване на нов SSH ключ в {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Включване на известяването" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Изключване на моментни архиви при работа на батерия" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Енергийното състояние не е налично от системата" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Изпълнявайте по едно моментно копие наведжъж" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Останалите моментни копия ще бъдат блокирани докато текущото такова не " "приключи. Това е глобална опция и ще повлияе на всички профили на " "потребителя. Но трябва да я изберете също и за останалите потребители." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Архивирайте подменените файлове при възстановяване" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "По-новите версии на файловете ще бъдат преименувани с последващ {suffix} " "преди възстановяването. Ако те не са необходими вече, може да ги премахнете " "посредством {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Продължаване при грешки (запазване на непълни моментни архиви)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Използвайте checksum, за да засечете промените" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Направете ново моментно копие независимо дали има промени или не." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Ниво на записа:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Нищо" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Следните правила се обработват отгоре надолу. По-късните правила заменят по-" "ранните и не са ограничени от тях. Вижте {manual} за подробности и примери." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "инструкция за употреба" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Отваряне на инструкцията за употреба я браузъра." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Запазване на последните архиви." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Последният или най-нов архив ще бъде запазен без значение от " "обстоятелствата." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Поведението не може да бъде променено." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Да не се премахват именувани архиви." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Като допълнение на времевият маркер наименувани архиви ще бъдат запазени при" " всякакви обстоятелства и няма да бъдат изтривани." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Година(и)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Премахване на моментни архиви по-стари от" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Пълни дни. Текущият ден се игнорира." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Календарни седмици с понеделник като първи ден. Текущата седмица се " "игнорира." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 месечни периоди. Текущият месец се игнорира." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Политика за задържане" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Изпълнява се във фонов режим на отдалечен хост." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Функцията за умно премахване ще бъде извършена директно от отдалечената " "машина. Командите \"bash\", \"screen\" и \"flock\" трябва да бъдат " "инаталирани и достъпни на отдалечената машина." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Ако опцията е избрана, Back In Time първо ще тества отдалечената машина." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Преброяването на дни започва от текущият ден." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Пазете всички временни архиви за последните" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "ден (дни)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Пази едно моментно копие на ден за последните" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Преброяването на седмиците започва от текущата. Седмицата започва в " "понеделник." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Пазете едно моментно копие на седмица за последните" #: qt/manageprofiles/tab_remove_retention.py:336 #, fuzzy msgid "week(s)." msgstr "седмица(и)" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Преброените месеци са календарни, започвайки с текущия." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Пазете едно моментно копие на месец за последните" #: qt/manageprofiles/tab_remove_retention.py:349 #, fuzzy msgid "month(s)." msgstr "месец(и)" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Преброените години са календарни, започвайки с текущата." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Запазете последния моментен архив за всяка година за" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "Всички години." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… свободното пространство е по-малко от" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… свободните inodes са по-малко от" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Премахнете най-старите моментни архиви, ако…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Въпрос" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Профил: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Преглед на последния запис" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Стартиране на {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Изпълняване…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Изпратено:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Скорост:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "приблизително оставащо време:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Моментни архиви" #: qt/qttools.py:506 msgid "Today" msgstr "Днес" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Вчера" #: qt/qttools.py:522 msgid "This week" msgstr "Тази седмица" #: qt/qttools.py:529 msgid "Last week" msgstr "Миналата седмица" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Това НЕ е моментно копие, а текущ изглед на локалните Ви файлове" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Последна проверка {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Вмъкване на конфигурация" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Не е намерена конфигурация" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Вмъкване" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Изберете директорията за моментни архиви, от която трябва да се черпи " "конфигурационният файл. Пътят може да изглежда така: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Ако директорията се намира на външен или отдалечен диск трябва да бъде ръчно" " монтирана предварително." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Покажи всички записани събития" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Опции за сравняване на моментни архиви" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Команда:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Параметри:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Използване на %1 и %2 за параметри на пътя" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Моля изберете diff команда или изберете Отказ." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Командата {cmd} не е открита на тази система. Моля опитайте друга команда " "или натиснете Отказ." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Не са въведени параметри за diff команда. Използване на стандартна стойност " "{params}." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Само различаващи се моментни архиви" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Покажете само съвпадащи моментни архиви до:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Дълбока проверка (по-точна, но бавна)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Изтриване" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Избиране на всички" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Сравни" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Отиване до" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Настройки" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Не можете да сравнявате моментен архив със самия него." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Наистина ли искате да изтриете {file} от моментния архив {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Наистина ли искате да изтриете {file} от {count} моментни архиви?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "Това действие не може да бъде отменено." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Изключете {path} от бъдещите моментни архиви?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Тази под директория не може да бъде добавена за резервно копие!" backintime-1.5.4/common/po/bs.po000066400000000000000000001403771477034762000165270ustar00rootroot00000000000000# Bosnian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-21 12:46+0000\n" "Last-Translator: buhtz \n" "Language-Team: Bosnian \n" "Language: bs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Upozorenje" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Glavni profil" #: common/config.py:266 #, fuzzy msgid "Local (EncFS encrypted)" msgstr "šifrirano" #: common/config.py:267 #, fuzzy msgid "SSH (EncFS encrypted)" msgstr "SSH šifrirano" #: common/config.py:278 msgid "Local" msgstr "Lokalno" #: common/config.py:280 msgid "SSH" msgstr "" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH Privatni kljuc" #: common/config.py:283 #, fuzzy msgid "Local encrypted" msgstr "šifrirano" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Šifriranje" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH šifrirano" #: common/config.py:296 msgid "Default" msgstr "Default" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Folder za slike ekrana nije validan !" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Obnovi {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Backup sub-folder nije moguće dodati." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Pokušaj pisanja novog crontab-a nije uspio." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Zakazani udev ne radi sa modom {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nije bilo moguce pronaci UUID za {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Spremanje configuracije neuspješno" #: common/configfile.py:137 msgid "Failed to load config" msgstr "" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" već postoji." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Poslednji profil ne može biti obrisan." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "" #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Napravi novi encrypted folder?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Odustani" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Molimo Vas potvrdite šifru." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Šifre nisu iste." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Napravi sliku" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, fuzzy, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command} nije pronađen. Molimo instalirajte npr. {installcommand}" #: common/mount.py:733 #, fuzzy, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Mountpoint {mntpoint} nije prazan." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NIJE USPJELO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Spremi dozvole" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Završeno" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Nemoguće kreirati direktorij" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čekaj %s sekundu." msgstr[1] "Čekaj %s sekunde." msgstr[2] "Čekaj %s sekundi." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Nemoguće kreirati direktorij" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Spašava se konfiguracijski fajl…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Spremi dozvole …" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Nemoguće izbrisati direktorij" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "" #: common/snapshots.py:1430 msgid "Success" msgstr "" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Pokušaj pisanja novog crontab-a nije uspio." #: common/snapshots.py:1855 #, fuzzy msgid "Smart removal" msgstr "Pametno brisanje" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Da li zelite izbrisati {file} u {count} snapshots?" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Sad" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "{} nije pronađen. Molimo instalirajte npr. {}" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nemoguće kreirati direktorij." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" #: common/sshtools.py:1193 #, fuzzy, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Molimo Vas potvrdite šifru" #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Odredište sistema datoteka za {path} je formatiran pomoću FAT-a, koji ne " "podržava tvrde linkove. Molimo koristite Linuxov maternji sistem datoteka." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Odredište sistema datoteka za {path} je formatiran pomoću FAT-a, koji ne " "podržava tvrde linkove. Molimo koristite Linuxov maternji sistem datoteka." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Odredište sistema datoteka za {path} je formatiran pomoću FAT-a, koji ne " "podržava tvrde linkove. Molimo koristite Linuxov maternji sistem datoteka." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiraj linkove (dereferenciraj simbolicke linkove)" #: common/tools.py:504 msgid "Expert Options" msgstr "Expert opcije" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Odredište sistema datoteka za {path} je formatiran pomoću FAT-a, koji ne " "podržava tvrde linkove. Molimo koristite Linuxov maternji sistem datoteka." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "" #: qt/app.py:172 msgid "Shortcuts" msgstr "Prečice" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" #: qt/app.py:257 msgid "Add to Include" msgstr "" #: qt/app.py:259 msgid "Add to Exclude" msgstr "" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" #: qt/app.py:470 msgid "Take a snapshot" msgstr "" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "" #: qt/app.py:497 msgid "Name snapshot" msgstr "" #: qt/app.py:501 msgid "Remove snapshot" msgstr "" #: qt/app.py:505 msgid "View snapshot log" msgstr "" #: qt/app.py:509 msgid "View last log" msgstr "" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Glavni profil…" #: qt/app.py:517 msgid "Shutdown" msgstr "" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "" #: qt/app.py:521 msgid "Setup language…" msgstr "" #: qt/app.py:525 msgid "Exit" msgstr "Izlaz" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "" #: qt/app.py:555 msgid "FAQ" msgstr "" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "" #: qt/app.py:563 msgid "Report a bug" msgstr "" #: qt/app.py:566 msgid "Translation" msgstr "" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Obnovi" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Obnovi …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" #: qt/app.py:601 msgid "Up" msgstr "Gore" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Prikaži skrivene datoteke" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Napravi sliku…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "" #: qt/app.py:692 msgid "&Restore" msgstr "Ob&novi" #: qt/app.py:698 msgid "&Help" msgstr "&Pomoć" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/app.py:1072 msgid "Working:" msgstr "" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "" #: qt/app.py:1129 msgid "Working" msgstr "" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "" #: qt/app.py:1161 msgid "Sent" msgstr "" #: qt/app.py:1162 msgid "Speed" msgstr "" #: qt/app.py:1163 msgid "ETA" msgstr "" #: qt/app.py:1225 msgid "Global" msgstr "Globalno" #: qt/app.py:1226 msgid "Root" msgstr "Korijen" #: qt/app.py:1227 msgid "Home" msgstr "" #: qt/app.py:1255 msgid "Backup directories" msgstr "" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "" #: qt/app.py:1398 #, fuzzy msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[1] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[2] "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[1] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[2] "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[1] "Da li zelite izbrisati {file} u {count} snapshots?" msgstr[2] "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" #: qt/app.py:1857 msgid "Snapshot" msgstr "" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Obnovi {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Obnovi {path} …" #: qt/app.py:2042 #, fuzzy, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Pozdrav,\n" "Nekoliko puta do sad ste iskoristili Back In Time na {language} jeziku.\n" "Prijevod Back In Time na {language} na {perc} dovršenosti. Nevezano od vašeg nivoa tehničke vičnosti, možete doprinijeti prijevodu i samim time Back In Time.\n" "Molimo vas da posjetite {translation_platform_url} ukoliko želite učiniti doprinos. Za sva dalja pitanja i pomoć, molimo vas posjetite {back_in_time_project_website}.\n" "Izvinjavamo se na smetnji, neće vam se više prikazivati ova poruka. Ovom dijalogu možete pristupiti u bilo kojem trenutku putem menija za pomoć.\n" "Vaš tim iz Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "" #: qt/app.py:2076 msgid "Website" msgstr "" #: qt/app.py:2090 msgid "Your translation" msgstr "" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 msgid "System default" msgstr "" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Napravi sliku:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "" msgstr[1] "" msgstr[2] "" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Glavni profil" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Opšte" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Uključi" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Uključi direktorij" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dodaje datoteku" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Dodaj direktorij" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Isključi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Op&cije" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Opcije &izvoza" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Uključi direktorij" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Svakih:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Isključeno" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Svakih {n} minuta" msgstr[1] "Svakih {n} minuta" msgstr[2] "Svakih {n} minuta" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" msgstr[2] "" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Svakih {n} sati" msgstr[1] "Svakih {n} sati" msgstr[2] "Svakih {n} sati" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Svaki dan" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Svake sedmice" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Svaki mjesec" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Svake godine" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dan(i)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Sedmica(e)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "Default" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "SSH Privatni kljuc:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Pokušaj pisanja novog crontab-a nije uspio." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Uključi obavijesti" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Napravi sliku" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Napravi sliku" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Godina(e)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dan(i)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Sedmica(e)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Ako je sloboni prostor manji od:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Ako je sloboni prostor manji od:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Napravi sliku…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "" #: qt/qttools.py:506 msgid "Today" msgstr "Danas" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Jučer" #: qt/qttools.py:522 msgid "This week" msgstr "Ove sedmice" #: qt/qttools.py:529 msgid "Last week" msgstr "Prošle sedmice" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 #, fuzzy msgid "Command:" msgstr "Komanda" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Koristite %1 i %2 za parametre putanje" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Idi na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcije" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Da li zelite izbrisati {file} u {count} snapshots?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Backup sub-folder nije moguće dodati." backintime-1.5.4/common/po/ca.po000066400000000000000000001727021477034762000165030ustar00rootroot00000000000000# Catalan translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-20 07:55+0000\n" "Last-Translator: Adolfo Jayme Barrientos \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Avís" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Perfil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (xifrat amb EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (xifrat amb EncFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Clau privada SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Xifrat local" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Xifratge" #: common/config.py:289 msgid "SSH encrypted" msgstr "Xifrat amb SSH" #: common/config.py:296 msgid "Default" msgstr "Per defecte" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Perfil: «{name}»" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "El directori d'instantànies no és vàlid." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Almenys cal seleccionar un directori per la copia de seguretat." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Directori: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Aquest directori no es pot incloure en la còpia de seguretat perquè forma " "part de la destinació mateixa de la còpia." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "No s'ha pogut escriure el nou crontab ." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "El cron no s'executa tot i que l'ordre crontab està disponible. Les tasques " "de còpia de seguretat programades no s'executaran. El cron pot estar " "instal·lat però no activat. Proveu l'ordre «systemctl enable cron» o " "consulteu els canals d'assistència de la vostra distribució GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "No s'ha pogut instal·lar la regla d'Udev per al perfil {profile_id}. El " "servei de DBus Service {dbus_interface} no estava disponible" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "El planificador udev no funciona amb el mode {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "No s'ha pogut trobar l'UUID per a {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "No s'ha pogut desar la configuració" #: common/configfile.py:137 msgid "Failed to load config" msgstr "No s'ha pogut carregar la configuració" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "El perfil «{name}» ja existeix." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "No es pot eliminar l'últim perfil." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "No s'ha pogut muntar «{command}»" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "No s'ha trobat la configuració de la carpeta xifrada." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Voleu crear una nova carpeta xifrada?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Canceŀla" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Si us plau confirmeu la contrasenya." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "La contrasenya no coincideix." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Fes una instantània" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "No es pot desmuntar {mountprocess} des de {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "No s'ha trobat {command}. Si us plau instal·leu p. ex. {installcommand}" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "El punt de muntatge {mntpoint} no és buit." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Introduïu la contrasenya del perfil {mode} «{profile}»:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "S'HA PRODUÏT UN ERROR" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaura els permisos" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Fet" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Es posposa la còpia de seguretat mentre s'utilitza la bateria" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "No es pot trobar el directori d’instantànies." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "Si es troba en una unitat extraïble, connecteu-la i premeu OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Esperant %s segon." msgstr[1] "Esperant %s segons." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "No s'ha pogut fer la instantània {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "No es pot crear la carpeta." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "S'està desant el fitxer de configuració …" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "S'estan desant els permisos …" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "S’ha trobat la instantània remanent «{snapshot_id}» que es pot continuar." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "S'està suprimint la carpeta sobrant de l'última execució: {snapshot_id}" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "No es pot eliminar el directori" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "S'està fent una instantània" #: common/snapshots.py:1430 msgid "Success" msgstr "Èxit" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transferència parcial deguda a un error" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferència parcial a causa de la desaparició dels fitxers d'origen (mireu" " «man rsync»)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "«rsync» ha finalitzat amb el codi de sortida {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Consulteu «man rsync» per a més detalls" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Els codis de sortida negatius de l'rsync són números de senyal; vegeu «kill " "-l» i «man kill»" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "No hi ha canvis, no cal una instantània nova" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "No es pot canviar el nom de {new_path} a {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Esborrat intel·ligent" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Aplica regles per a eliminar instantànies antigues" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Proveu de mantenir un minim d'espai lliure" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Proveu de mantenir mínim un {perc} d'inodes lliures" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Ara" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "No s'ha pogut muntar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "No s'ha trobat l'ssh-agent. Assegureu-vos que està instal·lat." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "No s'ha pogut desbloquejar la clau privada ssh. O la contrasenya és " "incorrecta o no és disponible per al cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "El xifratge {cipher} ha fallat per a {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "El camí remot existeix però no és un directori." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "No es pot escriure al camí remot." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "El camí remot no és executable." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "No s'ha pogut crear el camí remot." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "L'amfitrió remot {host} no admet {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Mireu 'man backintime' per a més instruccions" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Comproveu les ordres a l'amfitrió {host} ha retornat un error desconegut" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "L'amfitrió remot {host} no admet hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copieu la clau SSH pública «{pubkey}» a l'amfitrió remot «{host}»." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Introduïu una contrasenya per a «{user}»." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "El sistema de fitxers de destí per a {path} està formatat amb FAT que no " "admet hard-links. Utilitzeu un sistema de fitxers Linux natiu." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} no és un directori vàlid." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "El sistema de fitxers de destí per a {path} està formatat amb FAT que no " "admet hard-links. Utilitzeu un sistema de fitxers Linux natiu." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "El sistema de fitxers de destinació per a {path} és una compartició muntada " "amb SMB. Assegureu-vos que el servidor remot SMB admet enllaços simbòlics o " "activeu «{copyLinks}» a «{expertOptions}»." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copia enllaços (dereferencia els enllaços simbòlics)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opcions avançades" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "El sistema de fitxers de destí per a {path} és una compartició muntada amb " "sshfs. Sshfs no admet hard-links. Utilitzeu el mode 'SSH' en el seu lloc." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Quant a" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autors" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traduccions" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Llicència" #: qt/app.py:172 msgid "Shortcuts" msgstr "Dreceres" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Aquesta carpeta no existeix\n" "a la instantània seleccionada." #: qt/app.py:257 msgid "Add to Include" msgstr "Afegeix a la inclusió" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Afegeix a l'exclusió" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} sembla que sigui el primer cop que s'executa perquè no s'ha " "trobat cap configuració." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importeu una configuració existent (des d'una carpeta d'una còpia de " "seguretat o d'un altre ordinador)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Si es troba en una unitat extraïble, connecteu-la i premeu OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Fes una instantània" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Utilitza el temps de modificació i mida per a la detecció de canvis de " "fitxers." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Pren una instantània (mode suma de verificació)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Utilitza sumes de verificació per a la detecció de canvis de fitxers." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausa el procés d'instantània" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Reprèn el procés d'instantània" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Atura el procés d'instantània" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Refresca la llista d'instantànies" #: qt/app.py:497 msgid "Name snapshot" msgstr "Anomena la instantània" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Esborra la instantània" #: qt/app.py:505 msgid "View snapshot log" msgstr "Visualitza el registre de les instantànies" #: qt/app.py:509 msgid "View last log" msgstr "Visualitza l'últim registre" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gestiona els perfils…" #: qt/app.py:517 msgid "Shutdown" msgstr "Aturada" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Apaga el sistema després d'acabar la instantània." #: qt/app.py:521 msgid "Setup language…" msgstr "Configura la llengua…" #: qt/app.py:525 msgid "Exit" msgstr "Surt" #: qt/app.py:529 msgid "User manual" msgstr "Manual d'ús" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Retorn al Futur" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Fitxer de configuració de perfils" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "Lloc web del projecte" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Obre el lloc web del Back In Time al navegador" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Registre de canvis" #: qt/app.py:555 msgid "FAQ" msgstr "Preguntes freqüents" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Feu una pregunta" #: qt/app.py:563 msgid "Report a bug" msgstr "Informar d'un error" #: qt/app.py:566 msgid "Translation" msgstr "Traducció" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Mostra de nou el missatge sobre la participació en la traducció." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transició del xifratge (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Mostra de nou el missatge sobre l'eliminació d'EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaura" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "" "Restaura els fitxers o carpetes seleccionades a la destinació original." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaura a …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Restaura els fitxers o carpetes seleccionades a una destinació nova." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaura la carpeta mostrada actualment i tot el seu contingut a la " "destinació original." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaura la carpeta mostrada actualment i tot el seu contingut a una nova " "destinació." #: qt/app.py:601 msgid "Up" msgstr "Amunt" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Mostra els fitxers ocults" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Compara les instantànies…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Mostra de nou el missatge sobre l'eliminació d'EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "Retorn al Futur" #: qt/app.py:681 msgid "&Backup" msgstr "&Còpia de seguretat" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaura" #: qt/app.py:698 msgid "&Help" msgstr "&Ajuda" #: qt/app.py:743 msgid "Icons only" msgstr "Només icones" #: qt/app.py:746 msgid "Text only" msgstr "Només text" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Si tanqueu aquesta finestra, Back In Time no podrà apagar el sistema quan " "s'hagi finalitzat la instantània." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Segur que vols tancar-ho?" #: qt/app.py:1072 msgid "Working:" msgstr "S'està treballant:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Fet, no ha estat necessari crear una còpia de seguretat" #: qt/app.py:1129 msgid "Working" msgstr "Treballant" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Error" #: qt/app.py:1161 msgid "Sent" msgstr "Enviat" #: qt/app.py:1162 msgid "Speed" msgstr "Velocitat" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Arrel" #: qt/app.py:1227 msgid "Home" msgstr "Inici" #: qt/app.py:1255 msgid "Backup directories" msgstr "Directoris de còpia de seguretat" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nom de la instantània" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Segur que voleu esborrar la instantània?" msgstr[1] "Segur que voleu esborrar les instantànies?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Crea còpies de seguretat amb {suffix} al final abans de\n" "sobreescriure o esborrar fitxers locals." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Les versions més noves dels fitxers es canviaran de nom amb el final " "{suffix} abans de restaurar. Si ja no els necessiteu, podeu eliminar-los amb" " la següent comanda:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Restaura només els fitxers que no existeixen o\n" "són més nous que els de destí.\n" "S'utilitza l'opció «rsync --update»." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Esborra els fitxers més nous de la carpeta original." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaura els fitxers o carpetes seleccionats al destí original i suprimeix " "els fitxers o directoris que no són a la instantània. Aneu amb compte perquè" " això suprimirà els fitxers i carpetes exclosos de la instantània." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Segur que voleu restaurar aquest element al directori nou?" msgstr[1] "Segur que voleu restaurar aquests elements al directori nou?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Segur que voleu restaurar aquest element?" msgstr[1] "Segur que voleu restaurar aquests elements?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Esteu segur que voleu eliminar tots els fitxers més nous a {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Esteu segur que voleu eliminar tots els fitxers més nous de la carpeta " "original?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}AVÍS:{BOLDEND} Esborrar fitxers a l'arrel del sistema de fitxers " "podria trencar tot el sistema." #: qt/app.py:1857 msgid "Snapshot" msgstr "Instantàna" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaura {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaura {path} a …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hola\n" "Heu utilitzat el Back In Time en l'idioma {language} unes quantes vegades.\n" "La traducció de la vostra versió instal·lada de Back In Time a {language} està un {perc} completada. Independentment del seu nivell d'experiència tècnica, pot contribuir a la traducció i, per tant, en Back In Time mateix.\n" "Visiteu {translation_platform_url} si voleu col·laborar. Per obtenir més assistència i preguntes, visiteu {back_in_time_project_website}.\n" "Demanem disculpes per la interrupció i aquest missatge no es tornarà a mostrar. Aquest diàleg està disponible en qualsevol moment a través del menú d'ajuda.\n" "L'equip de Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plataforma de traducció" #: qt/app.py:2076 msgid "Website" msgstr "Lloc web" #: qt/app.py:2090 msgid "Your translation" msgstr "la teva traducció" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "La configuració de la llengua només tindrà efecte després de reiniciar Back " "In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "El suport per a EncFS s'interromprà en un futur previsible. A més, no es " "recomana utilitzar aquest mode per a un perfil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "article" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Els perfils següents utilitzen xifratge amb EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Aquest missatge no es tornarà a mostrar. Aquest diàleg està disponible en " "qualsevol moment mitjançant el menú d'ajuda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "El teu equip de Retorn al Futur" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Llenguatge de configuració" #: qt/languagedialog.py:97 msgid "System default" msgstr "sistema per defecte" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Utilitza la llengua del sistema operatiu." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traduït: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Última visualització dels registres" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visualitza el registre d'instantànies" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Perfil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Instantànies:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtre:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tots" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Canvis" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Errors" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informació" msgstr[1] "Informacions" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Errors de transferència de rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E]Error, [I]Informació, [C]Canvia" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "descodifica rutes" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gestiona els perfils" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Edita" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Afegeix" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Elimina" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&General" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inclou" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Inclou fitxers i carpetes" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Afegeix un fitxer" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Afegeix un directori" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Exclou" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informació{ENDBOLD}: en el mode «Xifrat amb SSH», només funcionen els " "asteriscs simples o dobles (p. ex., {example2}). S'ignoraran altres tipus de" " comodins i patrons (p. ex., {example1}). Els noms de fitxers són " "impredictibles en aquest mode a causa del xifratge per EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Exclou fitxers i carpetes" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Afegeix per defecte" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Exclou els fitxers més grans que:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Exclou els fitxers més grans que {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Amb el «Mode rsync complet» desactivat, això només afectarà els fitxers nous" " perquè per al rsync aquesta és una opció de transferència, no una opció " "d'exclusió. Per tant, els fitxers grans ja copiats previament, romandran en " "les instantànies encara que hagin canviat." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opcions" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Opcions d'e&xperts" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaura la configuració" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Edita user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Perfil nou" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Reanomena el perfil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Segur que voleu suprimir el perfil «{name}»?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Molt recomanable{ENDBOLD}: (Totes les recomanacions ja estan " "incloses.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Molt recomanat{ENDBOLD}:{files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Exclou el patró" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Exclou el fitxer" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Exclou el directori" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inclou un fitxer" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "«{path}» és un enllaç simbòlic. L'objectiu enllaçat no es copiarà fins que no l'incloguin.\n" "Voleu incloure l'objectiu de l'enllaç simbòlic?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Inclou el directori" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "S'ha desactivat perquè aquest patró no funciona en el mode «Xifrat amb SSH»." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Planificació" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Día:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Entre setmana:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Hores:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuts:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Executa Back in Time bon punt es connecti la unitat (només una vegada cada X" " dies). Se us demanarà la contrasenya del sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Executa Back In Time repetidament. Això és útil si l'ordinador no s'està " "executant regularment." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Cada:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Activa el registre dels missatges de depuració" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Escriu missatges de nivell de depuració al registre del sistema mitjançant " "«--debug»." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Precaució: utilitzeu-lo només temporalment per a diagnòstics, ja que genera " "una gran quantitat de sortida." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Deshabilitat" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "En cada inici/reinici" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Cada {n} minut" msgstr[1] "Cada {n} minuts" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Cada hora" msgstr[1] "Cada {n} hores" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Cada {n} hora" msgstr[1] "Cada {n} hores" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Hores personalitzades" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Cada dia" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetidament (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Quan la unitat es connecti (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Cada setmana" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Cada mes" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Cada any" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hora(es)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dia(es)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Setmana(es)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mes(os)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Les hores personalitzades només poden ser una llista d'hores separades per " "comes (p.e. 8,12,18,23) o */3 per fer còpies periòdiques cada 3 hores." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Amfitrió:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usuari:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Connecteu-vos a l'amfitrió del destí mitjançant aquest servidor intermediari" " (també conegut com a jump host). Vegeu \"-J\" a la documentació de l'ordre " "\"ssh\" o \"ProxyJump\" a la pàgina del manual \"ssh_config\" per obtenir " "més informació." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Aneu amb compte:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Executa «rsync» amb «{cmd}»:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "com a tasca cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "a l'amfitrió remot" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "en prendre una instantània manual" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Instal·leu «nocache» per a activar aquesta opció." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "a la màquina local" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirigeix la stdout a /dev/null a les funcions cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron enviarà automàticament un correu electrònic amb la sortida adjunta de " "cronjobs si hi ha instal·lat un MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirigeix stderr a /dev/null a les funcions cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron enviarà automàticament un correu electrònic amb errors adjunts de " "cronjobs si hi ha instal·lat un MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limita l'ús de l'amplada de banda del rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preserva ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preserva els atributs extesos (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Copia links insegurs (Només funciona amb links absoluts)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Limiteu-vos a un sistema de fitxers" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Les opcions s'han de citar, p. ex. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Enganxa les opcions addicionals al 'rsync'" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefix per executar-se abans de cada comanda a l'amfitrió remot." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Les variables s'han d'escapar amb «\\$FOO». Això no toca el rsync. Per a " "afegir un prefix per al rsync utilitzeu «{example_value}» amb " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "per defecte" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Afegeix un prefix a les ordres SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Comprova si l'amfitrió remot està connectat" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Avís: si està desactivat i l'amfitrió remot no està disponible, això podria " "comportar alguns errors estranys." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Comprova si l'amfitrió remot admet totes les ordres necessàries." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Avís: si està desactivat i l'amfitrió remot no admet totes les ordres " "necessàries, podria comportar alguns errors estranys." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(per defecte: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "desactivat" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "habilitat" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mode:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "A on desar instanànies" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Paràmetres SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Camí:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Xifratge:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Clau privada:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Trieu un fitxer de clau privada existent (normalment anomenat \"id_ed25519\"" " i en versions anteriors \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Crea una clau SSH nova sense contrasenya (no es permet si ja hi ha " "seleccionat un fitxer de clau privada)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Contrasenya" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Desa la contrasenya a l'anell de claus" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Contrasenya de la memòria cau per al Cron (problema de seguretat: " "l'administrador pot llegir la contrasenya)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avançat" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Camí complet de la instantània:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "No heu escollit un fitxer de clau privada per a SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Voleu generar un nou parell de claus públic/privat sense contrasenya?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "El fitxer de clau privada «{file}» no existeix." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Voleu copiar la vostra clau SSH pública a la màquina remota per a habilitar " "l'inici de sessió sense contrasenya?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "No es pot establir l'autenticitat de l'amfitrió {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "L'empremta digital de la clau {keytype} és:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verifiqueu aquesta empremta digital. Voleu afegir-la al fitxer " "«known_hosts»?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Segur que voleu canviar el directori d'instantànies?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "No s'ha pogut crear una clau SSH nova a {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Activa les notificacions" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Desactiva les instantànies treballant en bateria" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "No està disponible l'estat de l'energia" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Executa només una instantània alhora" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Les altres instantànies es blocaran fins que finalitzi la instantània " "actual. Aquesta és una opció global i, per tant, afectarà tots els perfils " "d'aquest usuari. També ho heu d'activar a la resta d'usuaris." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "La còpia de seguretat ha substituïts fitxers en restaurar" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "A les versions més noves dels fitxers se'ls afegirà el sufix {suffix} al nom" " abans de restaurar-los. Si ja no els necessiteu, podeu eliminar-los amb " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continua amb errors (Mantingues instantànies incompletes)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Utilitza el checksum per detectar canvis" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Preneu una nova instantània tant si hi ha canvis com si no." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivell de registre:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Cap" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual d'ús" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Obre el manual d'utilització al navegador." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Conserva la instantània més recent." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Aquest comportament no es pot modificar." #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "No eliminis les instantànies amb nom." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Any(s)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Esborra la instantània" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Executa en segon pla en un amfitró remot." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "El procediment de supressió intel·ligent s'executarà directament en la " "màquina remota, no localment. Les ordres «bash», «screen» i «flock» han " "d'estar instal·lades i disponibles en la màquina remota." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Mantingues totes les instantànies durant els darrers" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dia(es)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Mantingues una instantània al dia durant els darrers" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Mantingues una instantània a la setmana durant les darreres" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "setmana(es)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Mantingues una instantània al mes durant els darrers" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mes(os)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Mantingues totes les instantànies durant els darrers" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "tots els anys." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... si l'espai lliure és inferior a" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... si els inodes lliures són menys de" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Elimina les instantànies antigues si…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pregunta" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Perfil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Visualitza l'últim registre" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Inicia {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "S'està treballant…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Enviat:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocitat:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Instantànies" #: qt/qttools.py:506 msgid "Today" msgstr "Avui" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ahir" #: qt/qttools.py:522 msgid "This week" msgstr "Aquesta setmana" #: qt/qttools.py:529 msgid "Last week" msgstr "La setmana passada" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "No és una instantània, sinó una vista en directe dels vostres fitxers locals" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Última comprovació {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importa la configuració" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "No s'ha trobat cap configuració" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Seleccioneu la carpeta de snapshots des de la qual s'ha d'importar el fitxer" " de configuració. El path pot semblarse a: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Si la carpeta es troba en una unitat externa o remota, s'ha de muntar " "manualment prèviament." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Mostra el registre complet" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opcions de comparació de les instantànies" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Ordre:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Paràmetres:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Utilitza %1 i %2 per els paràmetres de les rutes" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Definiu una diff command o premeu Cancel·lar." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "L'ordre «{cmd}» no es pot trobar en aquest sistema. Proveu una altra cosa o " "premeu Cancel·la." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "No s'han definit paràmetres per a l'ordre diff. S'utilitza el valor per " "defecte «{params}»." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Només captures diferents" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Llista només les instantànies iguals a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Comprovació a fons (més acurada, però lenta)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Suprimeix" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Selecciona-ho tot" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Compara" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Vés a" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcions" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "No podeu compara una instantània amb sí mateixa." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Realment voleu suprimir {file} a la instantània {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Segur que voleu suprimir {file} a {count} instantànies?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "Avís: aquesta acció no es podrà desfer." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Exclou {path} de les instantànies futures?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "No s'hi pot incloure les subcarpetes en la còpia de seguretat." backintime-1.5.4/common/po/cs.po000066400000000000000000002066721477034762000165310ustar00rootroot00000000000000# Czech translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-21 12:46+0000\n" "Last-Translator: buhtz \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Varování" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hlavní profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Místní (v šifrované podobě)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "Na stroji v síti (v šifrované podobě)" #: common/config.py:278 msgid "Local" msgstr "Místní" #: common/config.py:280 msgid "SSH" msgstr "Na stroji v síti" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Soukromá část SSH klíče" #: common/config.py:283 msgid "Local encrypted" msgstr "Místní (v šifrované podobě)" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Šifrování" #: common/config.py:289 msgid "SSH encrypted" msgstr "Na stroji v síti (v šifrované podobě)" #: common/config.py:296 msgid "Default" msgstr "Výchozí" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: „{name}“" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Složka zachycených stavů není platná." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Je třeba vybrat alespoň jednu složku pro zálohu." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Složka: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Tato složka nemůže být předmětem zálohování, protože je součástí umístění, " "do kterého se zálohuje." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Novou naplánovanou úlohu (crontab) se nepodařilo zapsat." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Plánovač (cron) není spuštěný (i když příkaz crontab je k dispozici). " "Naplánované zálohovací úlohy nebudou spouštěny. Může být, že cron je " "nainstalovaný, ale není zapnutý. Vyzkoušejte proto příkaz „systemctl enable " "--now cron“ nebo se obraťte na kanály podpory vámi využívané linuxové " "distribuce." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Nepodařilo se nainstalovat Udev pravidlo pro profil {profile_id}, protože " "systémová služba DBus „{dbus_interface}“ nebyla k dispozici" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Plán, používající správce zařízení udev, nefunguje v režimu {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nedaří se najít nikde se neopakující identifikátor (UUID) pro {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nastavení se nepodařilo uložit" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nastavení se nepodařilo načíst" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil „{name}“ už existuje." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Nelze odebrat poslední zbývající profil." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nedaří se připojit „{command}“" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Nastavení pro šifrovanou složku nenalezeno." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Vytvořit novou šifrovanou složku?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Storno" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Potvrďte zadání hesla." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Zadání hesla se neshodují." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Pořizování zachyceného stavu" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Nedaří se odpojit {mountprocess} od {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} nenalezen. Nainstalujte ho (např. prostřednictvím " "„{installcommand}“)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Přípojný bod {mntpoint} není prázdný." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Zadejte heslo pro profil {mode} „{profile}“:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NEZDAŘILO SE" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Obnovit oprávnění" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Hotovo" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "" "Zálohování odloženo aby se ušetřila energie z napájejícího akumulátoru" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Nepodařilo se najít složku se zachycenými stavy." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Pokud se nachází na vyjímatelném médiu, připojte ho." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čeká se %s sekundu." msgstr[1] "Čeká se %s sekundy." msgstr[2] "Čeká se %s sekund." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Nepodařilo se pořídit zachycený stav {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Chvíli strpení. Dokončování…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Složku se nepodařilo vytvořit." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Ukládání souboru s nastaveními…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Ukládání oprávnění…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Nalezen pozůstatek „{snapshot_id}“ ve kterém lze pokračovat." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Odebírání složky „{snapshot_id}“, zanechané minulým průchodem" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Složku není možné odstranit" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Pořizování zachyceného stavu" #: common/snapshots.py:1430 msgid "Success" msgstr "Úspěch" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Přenos jen částečně úspěšný kvůli chybě" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Přenesena je část kvůli zmizelým zdrojovým souborům (viz „man rsync“)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "„rsync“ skončilo s návratovým kódem {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Podrobnosti se dozvíte spuštěním „man rsync“" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Záporné návratové kódy z rsync jsou čísly signálů – viz příkazy „kill -l“ a " "„man kill“" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nic se nezměnilo, není tedy třeba pořizovat nový zachycený stav" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Není možné přejmenovat {new_path} na {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Postupné odstraňování" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Uplatnit pravidla pro odstraňování starých zachycených stavů" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Uplatnit zásadu uchovávání" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Pokus o zachování neobsazeného prostoru, jak je nastaveno" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Pokus o zachování neobsazených {perc} i-uzlů, jak je nastaveno" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nyní" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nedaří se připojit (mount) {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent nenalezen. Ověřte, zda je nainstalovaný." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nedaří se odemknout soukromou část ssh klíče. Heslo je buď chybně zadané " "nebo není k dispozici plánovači cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Použití šifry {cipher} se na stroji {host} nezdařilo." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Vzdálené umístění existuje, ale není to složka." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Do vzdáleného umístění nelze zapisovat." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" "Vzdálené umístění nemá nastaveno oprávnění ke spouštění (tj. nelze do něho " "vstoupit)." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Vzdálené umístění se nedaří vytvořit." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Vzdálený stroj {host} nepodporuje {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Další pokyny naleznete v manuálové stránce aplikace (man backintime)" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kontrolní příkazy na stroji {host} vrátily neznámou chybu" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Na vzdáleném stroji {host} nejsou podporovány pevné odkazy (hardlink)" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Zkopírovat veřejnou část ssh klíče „{pubkey}“ na vzdálený stroj „{host}“." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Vyplňte heslo pro „{user}“." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Cílový souborový systém pro „{path}“ je typu NTFS a ten má známé " "nekompatibility se způsobem, jakým jsou soubory ukládány na unixových " "souborových systémech." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} není platnou složkou." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Vytváření následující složky se nezdařilo:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Přístup pro zápis může být omezen." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Cílový souborový systém pro „{path}“ je typu FAT a ten nepodporuje pevné " "odkazy (hardlink). Použijte namísto něj nějaký běžný linuxový souborový " "systém." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Cílový souborový systém pro „{path}“ je SMB síťové sdílení. Ověřte, že " "vzdálený SMB server podporuje symbolické odkazy (symlink), případně v " "„{expertOptions}“ zapněte „{copyLinks}“." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopírovat až cíle odkazů (obejde symbolické odkazy)" #: common/tools.py:504 msgid "Expert Options" msgstr "Pokročilé předvolby" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Cílový souborový systém pro {path} je sdílení připojené přes sshfs. To " "nepodporuje pevné odkazy (hardlink). Použijte namísto toho přímo režim „Na " "vzdáleném stroji“ (SSH)." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Vytvoření souboru v této složce se nezdařilo:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O aplikaci" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Vývojáři" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Překladatelé" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licence" #: qt/app.py:172 msgid "Shortcuts" msgstr "Zkratky" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Tato složka v nyní vybraném\n" "zachyceném stavu neexistuje." #: qt/app.py:257 msgid "Add to Include" msgstr "Přidat do seznamu zálohovaných" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Přidat do seznamu vynechaných" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Zdá se, že {app_name} je spuštěno poprvé, protože nebylo nalezeno žádné " "nastavení." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Naimportovat existující nastavení (ze složky cíle zálohování nebo jiného " "počítače)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Pokud se nachází na vyjímatelném médiu, připojte ho a klikněte na OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Pořídit zachycený stav" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Pro zjištění změn souborů používat časy jejich úprav a velikost." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Pořídit zachycený stav (režim s kontrolními součty)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Pro zjištění změn souborů používat jejich kontrolní součty." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pozastavit pořizování zachyceného stavu" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Pokračovat v pořizování zachyceného stavu" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Ukončit toto pořizování zachyceného stavu" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Znovu načíst seznam zachycených stavů" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nazvat zachycený stav" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Odstranit zachycený stav" #: qt/app.py:505 msgid "View snapshot log" msgstr "Zobrazit záznam událostí při pořizování zachyceného stavu" #: qt/app.py:509 msgid "View last log" msgstr "Zobrazit záznam nedávných událostí" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Spravovat profily…" #: qt/app.py:517 msgid "Shutdown" msgstr "Potom vypnout" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Po pořízení zachyceného stavu vypnout počítač." #: qt/app.py:521 msgid "Setup language…" msgstr "Nastavit jazyk…" #: qt/app.py:525 msgid "Exit" msgstr "Ukončit aplikaci" #: qt/app.py:529 msgid "User manual" msgstr "Uživatelská příručka" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Otevřít uživatelskou příručku v prohlížeči (lokálně, pokud je k dispozici - " "jinak z Internetu)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "manuálová stránka: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Zobrazí manuálovou stránku o Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "manuálová stránka: Soubor s nastaveními profilů" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Zobrazí manuálovou stránku o souboru s nastavováním profilů (backintime-" "config)" #: qt/app.py:547 msgid "Project website" msgstr "Webové stránky projektu" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Otevřít webové stránky Back in Time v prohlížeči" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Co je v aplikaci nového" #: qt/app.py:555 msgid "FAQ" msgstr "Často kladené dotazy (FAQ)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Otevřít Často kladené dotazy (FAQ) v prohlížeči" #: qt/app.py:559 msgid "Ask a question" msgstr "Položit dotaz" #: qt/app.py:563 msgid "Report a bug" msgstr "Nahlásit chybu / dát podnět" #: qt/app.py:566 msgid "Translation" msgstr "Překlad" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Znovu zobrazí pozvání k účastni na překládání." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Přechod na jiné šifrování (z EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Znovu zobrazit zprávu o odebrání EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Obnovit" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Obnovit označené soubory či složky do jejich původních umístění." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Obnovit do…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Obnovit označené soubory či složky do nového umístění." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Obnovit právě zobrazenou složku a veškerý její obsah do původního umístění." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Obnovit právě zobrazenou složku a veškerý její obsah do nového umístění." #: qt/app.py:601 msgid "Up" msgstr "Přejít do nadřazené složky" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Zobrazovat skryté soubory" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Porovnat zachycené stavy…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kandidát na vydání" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Znovu zobrazit zprávu ohledně tohoto kandidáta na vydání." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Záloha" #: qt/app.py:692 msgid "&Restore" msgstr "&Obnovení" #: qt/app.py:698 msgid "&Help" msgstr "&Nápověda" #: qt/app.py:743 msgid "Icons only" msgstr "Pouze ikony" #: qt/app.py:746 msgid "Text only" msgstr "Pouze text" #: qt/app.py:749 msgid "Text below icons" msgstr "Text pod ikonami" #: qt/app.py:752 msgid "Text beside icon" msgstr "Text vedle ikon" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Pokud toto okno zavřete, pak aplikace Back In Time nebude moci po dokončení " "pořízení zachyceného stavu vypnout počítač." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Opravdu chcete okno zavřít?" #: qt/app.py:1072 msgid "Working:" msgstr "Zpracovává se:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Dokončeno, záloha není potřebná" #: qt/app.py:1129 msgid "Working" msgstr "Zpracovává se" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Chyba" #: qt/app.py:1161 msgid "Sent" msgstr "Odesláno" #: qt/app.py:1162 msgid "Speed" msgstr "Rychlost" #: qt/app.py:1163 msgid "ETA" msgstr "Odhad. zbývající čas" #: qt/app.py:1225 msgid "Global" msgstr "Globální" #: qt/app.py:1226 msgid "Root" msgstr "Kořen" #: qt/app.py:1227 msgid "Home" msgstr "Domovská složka" #: qt/app.py:1255 msgid "Backup directories" msgstr "Složky pro zálohu" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Název pro zachycený stav" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Opravdu chcete tento zachycený stav odstranit?" msgstr[1] "Opravdu chcete tyto zachycené stavy odstranit?" msgstr[2] "Opravdu chcete tyto zachycené stavy odstranit?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Stávající soubory, které by jinak byly odebrány nebo přepsány těmi ze zálohy,\n" "zachovat a jen připojit za jejich název „{suffix}“." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Novější verze souborů budou před zahájením obnovy přejmenovány přidáním " "předpony {suffix}. Až je už nebudete potřebovat, můžete je odstranit pomocí " "následujícího příkazu:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Obnovit pouze soubory které neexistují\n" "nebo jsou novější, než ty v cíli.\n" "(pomocí volby „rsync --update“)." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Odebrat novější prvky v původní složce." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Obnovit označené soubory nebo složky do původního umístění a smazat " "soubory/složky, které nejsou obsažené v zachyceném stavu. Buďte velmi " "opatrní, protože toto smaže soubory/složky, které byly vynechány během " "pořizování zachyceného stavu." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Opravdu chcete tento soubor obnovit do nové složky „{path}“?" msgstr[1] "Opravdu chcete tyto soubory obnovit do nové složky „{path}“?" msgstr[2] "Opravdu chcete tyto soubory obnovit do nové složky „{path}“?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Opravdu chcete tento soubor obnovit?" msgstr[1] "Opravdu chcete tyto soubory obnovit?" msgstr[2] "Opravdu chcete tyto soubory obnovit?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Opravdu chcete veškeré novější soubory v „{path}“ odebrat?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Opravdu chcete z původní složky odebrat veškeré novější soubory?" #: qt/app.py:1608 #, fuzzy, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Varování{BOLDEND}: smazání souborů v kořenové složce souborového " "systému může způsobit nefunkčnost celého operačního systému!!!" #: qt/app.py:1857 msgid "Snapshot" msgstr "Zachycený stav" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Obnovit {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Obnovit {path} do…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Dobrý den,\n" "už několikrát jste použili Back In Time v jazyce {language}.\n" "Překlad vámi nainstalované verze Back In Time do {language} je dokončen z {perc}. Bez ohledu na úroveň vašich technických znalostí můžete přispět k překladu a tím i do aplikace Back In Time jako takové.\n" "Pokud chcete přispět, navštivte prosím {translation_platform_url}. Ohledně další pomoci a dotazů pak {back_in_time_project_website}.\n" "Omlouváme se za vyrušení a tato zpráva už nebude zobrazována. Tento dialog je ale kdykoli k dispozici prostřednictvím nabídky Nápověda.\n" "Kolektiv vývojářů Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "překladatelská platforma" #: qt/app.py:2076 msgid "Website" msgstr "Webové stránky" #: qt/app.py:2090 msgid "Your translation" msgstr "Váš překlad" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Ve Fediverse na Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-mail na {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "E-mailová konference {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} na webových stránkách projektu." #: qt/app.py:2118 msgid "Open an issue" msgstr "Otevřít problém" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativně je možné použít jiný vámi zvolený kanál." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Tato verze Back In Time je teprve kandidátem na vydání a je určena hlavně pro testování stability při přípravě příštího oficiálního vydání.\n" "Nejsou sbírány žádné informace o uživateli či telemetrie. Nicméně, kolektiv vývojářů Back In Time velmi zajímá vědět, zda je kandidát na vydání používán a zda má smysl pokračovat v poskytování takovýchto verzí před vydáním.\n" "Proto prosíme o krátkou zpětnou vazbu zda jste si tuto verzi vyzkoušeli, i když jste se nesetkali s žádnými problémy. I rychlé testovací spuštění na pár minut by hodně pomohlo.\n" "K dispozici jsou následující možnosti kontaktování:\n" "{contact_list}\n" "V této verzi tato zpráva už nebude znovu zobrazována, ale je možné se k ní kdykoli dostat prostřednictvím nabídky nápovědy.\n" "Děkujeme za vaši podporu a pomoc se zlepšováním Back In Time!\n" "Váš kolektiv vývojářů Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Nastavení jazyka se projeví až po příštím spuštění Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Vytváření profilu s EncFS bude odebráno v příštím dílčím vydání (1.7), " "naplánovaném na rok 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Není doporučeno nadále tento režim v profilech používat." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "zprávě" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Podpora pro EncFS je ukončována kvůli zranitelnostem zabezpečení." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "Další podrobnosti, včetně možných alternativ, viz {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Následující profil(y) využívají šifrování prostřednictvím EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Náhrada je plánována, ale není možné zaručit, že bude do té doby hotová." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Uživatelé jsou zváni k této diskuzi. Aktualizované podrobnosti ohledně " "dalších kroků jsou k dispozici v {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Tato zpráva už nebude zobrazována. Tento dialog je ale kdykoli k dispozici " "prostřednictvím nabídky Nápověda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Kolektiv vývojářů Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Nastavení jazyka" #: qt/languagedialog.py:97 msgid "System default" msgstr "Systémový výchozí" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Použít jazyk operačního systému." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Přeloženo: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Zobrazení nedávných událostí" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Zobrazení událostí při pořizování zachyceného stavu" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Zachycené stavy:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtr:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Vše" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Změny" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Chyby" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informace" msgstr[1] "Informace" msgstr[2] "Informace" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "nezdary rsync přenosů (experimentální)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Chyba (Error), [I] Informace, [C] Změna (Change)" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekódovat popisy umístění" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Spravovat profily" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Přejmenovat" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Přidat" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Odebrat" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Obecné" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Zahrnout" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Zahrnout soubory a složky" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Přidat soubor" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Přidat složku" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Vynechat" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Pro informaci{ENDBOLD}: V režimu „Na stroji v síti (v šifrované " "podobě)“ funguje pouze jedna nebo dvě hvězdičky (např. {example2}). Ostatní " "typy zástupných vyjádření a vzorů budou ignorovány (např. {example1}) Názvy " "souborů se totiž v tomto režimu kvůli EncFS šifrování nedají předvídat." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Vynechat zástupně vyjádřené, soubory a složky" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Přidat výchozí" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Vynechat soubory větší než:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Vynechat soubory větší než hodnota v {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "V případě, že není používán „Úplný rsync režim“, bude se toto týkat pouze " "nových souborů, protože pro nástroj rsync je toto předvolba přenosu, nikoli " "vynechání. Takže, velké soubory, které byly zazálohovány už dříve, v " "zachycených stavech zůstanou, i když od té doby byly změněny." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Odebírání a uchovávání" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Př&edvolby" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Pokročilé předvolby" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Obnovit nastavení" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Upravit uživatelsky definované akce" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nový profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Přejmenovat profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Opravdu chcete profil „{name}“ smazat?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Důrazně doporučeno{ENDBOLD}: (Veškerá doporučení už obsažena.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Důrazně doporučeno{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Zástupné vyjádření vynechaného" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Vynechat soubor" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Vynechat složku" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Zahrnout soubor" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„{path}“ je symbolický odkaz. Odkazovaný cíl nebude zazálohován, dokud jeho umístění výslovně nezahrnete.\n" "Zahrnout tedy cíl symbolického odkazu namísto odkazu samotného?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Zahrnout složku" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Vypnuto protože tento vzor není funkční v režimu „Na vzdáleném stroji (v " "šifrované podobě)“." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Automatické zálohování" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Den:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Den v týdnu:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Čas:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "V hodiny:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "po hodině" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minut:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Spouštět Back In Time při připojení jednotky k počítači (s tím, že četnost " "záloh se neřídí těmito odpo/připojeními, ale nastaveným intervalem mezi " "zálohami). Budete vyzváni k zadání hesla pro sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Spouštět aplikaci Back In Time opakovaně. Užitečné pokud počítač není " "zapínán pravidelně." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Co:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Zaznamenávat ladící zprávy" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Zapisuje ladící zprávy do systémového záznamu událostí prostřednictvím " "„--debug“." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Upozornění: Použijte pouze dočasně pro diagnostiku, protože vytváří velké " "množství výstupu." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Vypnuto" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Při každém startu/restartu počítače" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Každou {n} minutu" msgstr[1] "Každé {n} minuty" msgstr[2] "Každých {n} minut" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Každou hodinu" msgstr[1] "Každé {n} hodiny" msgstr[2] "Každých {n} hodin" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Každou {n} hodinu" msgstr[1] "Každé {n} hodiny" msgstr[2] "Každých {n} hodin" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Uživatelsky určené časy" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Každý den" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Opakovaně (jako anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Při připojení (flash)disku (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Každý týden" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Každý měsíc" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Každý rok" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hodin" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dnů" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Týdnů" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Měsíců" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Uživatelsky určené časy mohou být pouze čárkou oddělovaný seznam hodin " "(například 8,12,18,23) nebo (např.) */3 pro pravidelné zálohy každé 3 " "hodiny." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Stroj:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Uživatel:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Připojit k cíli prostřednictvím této proxy (známé také jako jump host). " "Podrobnosti viz „-J“ v dokumentaci příkazu „ssh“ nebo „ProxyJump“ v " "manuálové stránce „ssh_config“." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Výstraha:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Tyto předvolby jsou pro pokročilá nastavení. Měňte je pouze pokud jste si " "plně vědomi jejich důsledků." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Spouštět nástroj rsync s parametrem „{cmd}“:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "když jako naplánovaná úloha (cron)" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "při zálohování na vzdálený stroj" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "při ručně spuštěném pořízení zachyceného stavu" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Pokud chcete zapnout tuto možnost, nainstalujte „nocache“." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "při ukládání záloh přímo na zálohovaném počítači" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" "U naplánovaných úloh (cron) zahazovat výstup (stdout) (přesměrováním do " "/dev/null)." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Pokud je nainstalován (a nastaven) MTA, cron automaticky pošle e-mail s " "přiloženým výstupem z naplánovaných úloh." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" "U naplánovaných úloh (cron) zahazovat chybový výstup (stderr) (přesměrováním" " do /dev/null)." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Pokud je nainstalován (a nastaven) MTA, cron automaticky pošle e-mail s " "přiloženými chybami naplánovaných úloh." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Omezit využití přenosové kapacity, zabrané nástrojem rsync, na:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Zálohovat včetně seznamů řízení přístupu (ACL)" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Zálohovat včetně rozšířených atributů (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "V případě odkazů na soubory/složky, nacházející se mimo zálohovanou složku, " "zazálohovat přímo je a nikoli jen odkaz (funguje pouze s absolutními odkazy)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Nepřekračovat (přípojnými body) do dalších souborových systémů" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Je třeba, aby předvolby byly obklopeny uvozovkami, např. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Vložte dodatečné parametry pro rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Předpona kterou spouštět před každým příkazem na vzdáleném stroji." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Proměnné je třeba zbavit jejich významu pomocí zpětného lomítka (příklad: " "\\$NECO). Toto se nedotýká nástroje rsync. Předponu pro rsync tedy přidáte " "pomocí „{example_value}“ s {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "výchozí" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Před příkazy přes SSH přidávat" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Zkontrolujte zda je vzdálený stroj dostupný na síti" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Varování: pokud vypnuto a vzdálený stroj není dostupný, může toto vést k " "některým podivným chybám." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Ověřit zda vzdálený stroj podporuje všechny nezbytné příkazy." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Varování: pokud vypnuto a vzdálený stroj nepodporuje veškeré nezbytné " "příkazy, může toto vést k některým podivným chybám." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(výchozí: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "vypnuto" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "zapnuto" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Ukládání záloh:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kam ukládat zachycené stavy" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Nastavení pro SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Umístění:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šifra:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Soukromá část klíče:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Zvolte existující soubor se soukromým klíčem (obvykle nazvaný „id_ed25519“, " "ve starších případech „id_rsa“)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Vytvořit nový SSH klíč bez hesla (není možné pokud je už vybrán soubor se " "soukromým klíčem)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Heslo pro" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Uložit heslo do klíčenky desktopového prostředí" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Uložit heslo pro potřeby plánovače Cron (slabina v zabezpečení: správce " "systému si heslo může přečíst)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Pokročilé" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Úplný popis umístění zachyceného stavu:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Nezvolili jste soukromý klíč pro SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Přejete si vytvořit novou dvojici veřejného/soukromého klíče (bez hesla?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Soubor „{file}“ se soukromou částí klíče neexistuje." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Přejete si zkopírovat veřejnou část vašeho SSH klíče na vzdálený stroj a " "umožnit tak přihlašování bez hesla?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Nepodvrženost stroje „{host}“ se nepodařilo ověřit." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Otisk {keytype} klíče je:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Zkontrolujte tento otisk! Přejete si ho přidat do souboru „known_hosts“?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Opravdu změnit složku se zachycenými stavy?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "V umístění {path} se nepodařilo vytvořit nový SSH klíč." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "" "Zobrazovat oznámení (prostřednictvím centra oznámení desktopového prostředí)" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Nepořizovat zachycené stavy při provozu na akumulátor" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Údaje o stavu napájení nejsou ze systému k dispozici" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Pořizovat pouze jeden zachycený stav naráz" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Pořizování ostatních zachycených stavů bude blokováno do dokončení toho " "právě probíhajícího. Toto je globální předvolba, takže se bude týkat všech " "profilů tohoto uživatele. Zapíná se ale pro každého uživatele zvlášť." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Zazálohovat soubory, které by byly při procesu obnovování nahrazeny" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Novější verze souborů budou před zahájením obnovy přejmenovány přidáním " "předpony {suffix}. Až je už nebudete potřebovat, můžete je odstranit pomocí " "příkazu {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" "Pokračovat i v případě výskytu chyb (zachovat i neúplné zachycené stavy)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" "Zda se soubory, určené k zálohování změnily zjišťovat pomocí jejich " "kontrolního součtu (přesnější)" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Pořídit nový zachycený stav i v případě, že nedošlo k žádným změnám." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Podrobnost zaznamenávání událostí (log):" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nic" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Následující pravidla jsou zpracovávána od začátku seznamu směrem k jeho " "konci. Pozdější pravidla přebíjí ta dřívější a nejsou jimi omezována. " "Ohledně podrobností a ukázek viz {manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "uživatelská příručka" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Otevřít uživatelskou příručku v prohlížeči." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Ponechávat nejnovější zachycené stavy." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Poslední nebo nejnovější zachycený stav je uchováván v každém případě." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Toto chování není možné změnit." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Neodstraňovat ty zachycené stavy, které uživatel nějak nazval." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Zachycené stavy, které byly nějak nazvány, krom obvyklého časového razítka " "byl dán název, budou za všech okolností zachovávány a nebudou odebrány." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Let" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Odstranit zachycené stavy starší než" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Celé dny. Stávající den je ignorován." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Týdny v kalendáři s pondělím coby prvním dnem. Stávající týden je ignorován." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 měsíční periody. Stávající měsíc je ignorován." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Zásada uchovávání" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Na vzdáleném stroji spustit na pozadí." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Procedura inteligentního odebírání bude spuštěna přímo na vzdáleném stroji, " "nikoli lokálně. Na vzdáleném stroji je třeba, aby byly nainstalovány a k " "dispozici příkazy „bash“, „screen“ a „flock“." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Pokud vybráno, Back In Time nejprve vyzkouší vzdálený stroj." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dny jsou počítány ode dneška." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Ponechat všechny zachycené stavy za uplynulých" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dnů." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Ponechat poslední zachycený stav co den za uplynulých" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "Týdny jsou počítány od toho stávajícího. Týdny začínají v pondělí." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Ponechat poslední zachycený stav co týden za uplynulých" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "týdnů." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Měsíce jsou počítány jako kalendářní a začíná se stávajícím měsícem." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Ponechat poslední zachycený stav co měsíc za uplynulých" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "měsíců." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Roky jsou počítány jako kalendářní a začíná se stávajícím rokem." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Ponechat poslední zachycený stav z každého roku" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "za všechna leta." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… pokud volného místa zbývá méně než" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "" "… pokud z počtu složek a souborů, které lze na souborovém systému vytvořit " "(inode), zbývá méně než" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Odebrat nejstarší zachycené stavy pokud…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Dotaz" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: „{profile_name}“" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Zobrazit záznam nedávných událostí" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Spustit {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Zpracování…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Odesláno:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Rychlost:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Odhad. zbývající čas:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Zachycené stavy" #: qt/qttools.py:506 msgid "Today" msgstr "Dnes" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Včera" #: qt/qttools.py:522 msgid "This week" msgstr "Tento týden" #: qt/qttools.py:529 msgid "Last week" msgstr "Minulý týden" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Toto NENÍ zachycený stav, ale pohled přímo do stávajících souborů na tomto " "počítači" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Minulá kontrola {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Naimportovat nastavení" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nebylo nalezeno žádné nastavení" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Naimportovat" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Vyberte složku se zachycenými stavy ze které má být naimportován soubor s " "nastaveními. Popis umístění může vypadat jako: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Pokud se složka nachází na externí nebo síťové jednotce – je třeba ji předem" " ručně připojit." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Zobrazit kompletní záznam událostí" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Předvolby ohledně porovnávání zachycených stavů" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Příkaz:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametry:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Jako parametry umístění použijte %1 a %2" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Nastavte příkaz pro zjišťování rozdílů nebo klikněte na Storno." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Příkaz „{cmd}“ se nepodařilo v systému najít. Zkuste něco jiného nebo " "klikněte na Storno." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nenastaveny žádné parametry pro příkaz diff. Náhradně bude použita výchozí " "hodnota „{params}“." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Pouze odlišující se zachycené stavy" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Vypsat pouze zachycené stavy, shodné s:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Hloubková kontrola (přesnější, ale pomalejší)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Smazat" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Vybrat vše" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Porovnat" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Přejít na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Předvolby" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Porovnávat zachycený stav s ním samotným nedává smysl." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Opravdu chcete „{file}“ vymazat ze zachyceného stavu „{snapshot_id}“?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Opravdu chcete „{file}“ vymazat z(e) {count} zachycených stavů?" #: qt/snapshotsdialog.py:406 #, fuzzy msgid "WARNING: This cannot be revoked." msgstr "VAROVÁNí: Toto nelze vzít zpět!" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Vynechat {path} z budoucích zachycených stavů?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Podsložky nemohou být součástí toho, co se zálohuje." backintime-1.5.4/common/po/da.po000066400000000000000000001747771477034762000165220ustar00rootroot00000000000000# Danish translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 18:59+0000\n" "Last-Translator: asjo \n" "Language-Team: Danish \n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Advarsel" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hovedprofil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokal (EncFS krypteret)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS krypteret)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privat nøgle" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalt krypteret" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Kryptering" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH krypteret" #: common/config.py:296 msgid "Default" msgstr "Standard" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Snapshots mappe er ugyldig." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Mindst en mappe skal vælges til backup." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Mappe: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Denne mappe kan ikke inkluderes i sikkerhedskopien, da den er del af " "sikkerhedskopiens destination." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Kunne ikke skrive ny crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron kører ikke, selvom crontab-kommandoen er tilgængelig. Planlagte backup-" "job vil ikke blive kørt. Cron kan være installeret, men ikke aktiveret. Prøv" " kommandoen “systemctl enable cron” eller kontakt supportkanalerne for din " "GNU/Linux-distribution." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Kunne ikke installere Udev regel for profil {profile_id}. DBus Service " "'{dbus_interface}' var ikke tilgængelig" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Metoden udev virker ikke med indstilling {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Fandt ikke UUID for {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Kunne ikke gemme konfiguration" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Kunne ikke læse konfiguration" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" findes allerede." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Den sidste profil kan ikke slettes." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Kan ikke tilslutte '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Opsætning for krypteret mappe ikke fundet." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Lav en ny krypteret mappe?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Annullér" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Bekræft venligst adgangskode." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Kodeord passer ikke." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Tag et tilstands-billede" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kan ikke fjerne {mountprocess} fra {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} ikke fundet. Installér venligst (f.eks. med \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Tilsluttelsespunkt {mntpoint} er ikke tomt." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Indtast adgangskode for {mode} profil \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "MISLYKKEDES" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Gendan tilladelser" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Færdig" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Venter med backup under batteridrift" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Kan ikke finde tilstands-billede-mappen." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Hvis den er på et flytbar drev, tilslut venligst drevet." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Venter %s sekund." msgstr[1] "Venter %s sekunder." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Kunne ikke tage tilstands-billede {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Hav venligst tålmodighed. Færdigører…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Kan ikke oprette mappe." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Gemmer konfigurationsfil…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Gemmer tilladelser…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Fandt efterladt tilstandsbillede {snapshot_id} som kan fortsættes med." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Sletter efterladt {snapshot_id}-mappe fra seneste kørsel" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Kan ikke fjerne mappe" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Tag et tilstands-billede" #: common/snapshots.py:1430 msgid "Success" msgstr "Succes" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Delvist overført på grund af fejl" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Delvis overførsel da nogle filer fra kilden er forduftet (se 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' afsluttede med slutværdien {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Kig i 'man rsync' for flere detaljer" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "Negative rsync slutværdier er signalnumre, se 'kill -l' og 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ingen ændringer, så et nyt tilstands-billede er ikke nødvendigt" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Kan ikke omdøbe {new_path} til {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Smart sletning" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Brug regler til at fjerne gamle tilstands-billeder" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Brug bevaringspolitik" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Prøv at holde minimum fri plads" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Prøver at holde mindst {perc} inoder fri" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nu" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Kan ikke tilslutte {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "Kan ikke finde ssh-agent. Sørg venligst for at den er installeret." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Kunne ikke fjerne låsen på ssh privat nøgle. Forkert kodeord elle kodeordet " "er ikke tilgængelig for cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Chiffer {cipher} fungerede ikke for {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Stien findes i den anden ende, men er ikke en mappe." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Stien i den anden ende er ikke skrivbar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Stien i den anden ende er ikke eksekverbar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Kan ikke oprette fjernmappe." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Den anden maskine {host} understøtter ikke {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Se 'man backintime' for yderligere instruktioner" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Check-kommandoerne på vært {host} gav en ukendt fejl" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Den anden maskine {host} understøtter ikke hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopiér offentlig ssh-nøgle \"{pubkey}\" til vært \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Indtast venligst et kodeord for \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Destinationsfilsystem for {path} er formatteret med NTFS, som ikke er fuldt " "kompatibelt med UNIX-lignede filsystemer." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} er ikke en gyldig mappe." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Oprettelse af følgende mappe fejlede:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Skriveadgang kan være begrænset." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Destinationsfilsystem for {path} er formatteret med FAT, som ikke kan " "håndtere hard-links. Brug venligst et understøttet GNU/Linux-filsystem." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Destinationsfilsystem for {path} er delt via SMB. Undersøg venligst om SMB " "serveren understøtter symlinks eller aktiver {copyLinks} i {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopier links (følg symbolske links)" #: common/tools.py:504 msgid "Expert Options" msgstr "Avancerede indstillinger" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Destinationsfilsystemet for {path} er delt via ssfhs. Sshfs understøtter " "ikke hardlinks. Benyt venligst 'SSH' mode i stedet." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Filoprettelse fejlede i mappe:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Om" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Forfattere" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Oversættelser" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licens" #: qt/app.py:172 msgid "Shortcuts" msgstr "Genveje" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Denne mappe findes ikke\n" "i det valgte tilstands-billede." #: qt/app.py:257 msgid "Add to Include" msgstr "Tilføj til Inkludér" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Tilføj til Spring over" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} synes at køre for den første gang, da ingen konfiguration blev " "fundet." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importer en eksisterende konfiguration (fra en backup destinationsmappe " "eller anden computer)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Hvis den er på et flytbar drev, indsæt venligst drevet og tryk OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Tag et tilstands-billede" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Brug ændringstid og størrelse til at opdage filændringer." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Opret et tilstands-billede (checksum modus)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Brug checksummer til at opdage filændringer." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Sæt tilstands-afbildning på pause" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Genoptag tilstands-afbildning" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stop tilstands-afbildning" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Opdatér tilstands-billede-liste" #: qt/app.py:497 msgid "Name snapshot" msgstr "Navngiv tilstands-billede" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Fjern tilstands-billede" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vis tilstands-billede-log" #: qt/app.py:509 msgid "View last log" msgstr "Vis seneste log" #: qt/app.py:513 msgid "Manage profiles…" msgstr "hovedprofil…" #: qt/app.py:517 msgid "Shutdown" msgstr "Luk ned" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Luk ned når tilstands-billedet er færdiggjort." #: qt/app.py:521 msgid "Setup language…" msgstr "Sæt sprog op…" #: qt/app.py:525 msgid "Exit" msgstr "Afslut" #: qt/app.py:529 msgid "User manual" msgstr "Brugervejledning" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Åbn brugervejledning i browser (lokal hvis tilgængelig, ellers på nettet)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man-side: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Viser man-side om Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man-side: Profilkonfigurationsfil" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "Viser man-side om profilkonfigurationsfil (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projektets hjemmeside" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Åbn Back In Time hjemmeside i browser" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Ændringslog" #: qt/app.py:555 msgid "FAQ" msgstr "OSS" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Åbn Ofte Stillede Spørgsmål (OSS) i browser" #: qt/app.py:559 msgid "Ask a question" msgstr "Stil et spørgsmål" #: qt/app.py:563 msgid "Report a bug" msgstr "Rapporter en fejl" #: qt/app.py:566 msgid "Translation" msgstr "Oversættelse" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Vis beskeden om deltagelse i oversættelse igen." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Krypteringsovergang (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Vis besked fjernelse af EncFS igen." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Gendan" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Gendan de valgte filer eller mapper på det oprindelige sted." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Gendan …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Gendan de valgte filer eller mapper på et nyt sted." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "Gendan den viste mappe og al dens indhold på det oprindelige sted." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Gendan den viste mappe og al dens indhold på et nyt sted." #: qt/app.py:601 msgid "Up" msgstr "Op" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Vis skjulte filer" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Tag et tilstands-billede…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "kandidat til udgivelse" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Vis beskeden om denne udgivelseskandidat igen." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Sikkerhedskopiér" #: qt/app.py:692 msgid "&Restore" msgstr "&Gendan" #: qt/app.py:698 msgid "&Help" msgstr "&Hjælp" #: qt/app.py:743 msgid "Icons only" msgstr "Alene ikoner" #: qt/app.py:746 msgid "Text only" msgstr "Alene tekst" #: qt/app.py:749 msgid "Text below icons" msgstr "Tekst under ikoner" #: qt/app.py:752 msgid "Text beside icon" msgstr "Tekst ved siden af ikon" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Hvis du lukker dette vindue så kan Back In Time ikke lukke din maskine ned " "når tilstands-billedet er færdigt." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Er du sikker på at du ønsker at lukke det?" #: qt/app.py:1072 msgid "Working:" msgstr "Arbejder:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Færdig, ingen sikkerhedskopiering nødvendig" #: qt/app.py:1129 msgid "Working" msgstr "Arbejder" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Fejl" #: qt/app.py:1161 msgid "Sent" msgstr "Sendt" #: qt/app.py:1162 msgid "Speed" msgstr "Hastighed" #: qt/app.py:1163 msgid "ETA" msgstr "Forventet afslutning" #: qt/app.py:1225 msgid "Global" msgstr "Globalt" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Hjemmemappe" #: qt/app.py:1255 msgid "Backup directories" msgstr "Sikkerhedskopi-mapper" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Tilstands-billede-navn" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Er du sikker på du ønsker at fjerne tilstands-billedet?" msgstr[1] "Er du sikker på du ønsker at fjerne tilstands-billederne?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Opret sikkerhedskopier med {suffix} tilføjet\n" "før lokale elementer overskrives." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Nyere version af filer vil blive omdøbt med {suffix} tilføjet før " "genddannelse. Hvis du ikke har brug for dem længere, kan de fjernes med " "denne kommando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Gendan alene elementer som ikke findes eller\n" "som er nyere end dem der findes.\n" "Bruger \"rsync --update\" parameteren." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Fjern nyere elementer i oprindelsesmappen." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Gendan valgte filer eller mapper på den oprindelige plads og slet filer " "eller mapper som ikke er i tilstands-billedet. Vær ekstremt forsigtig for " "dette vil slette filer og mapper som blev sprunget over da tilstands-" "billedet blev dannet." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Er du sikker på at du vil gendanne dette element i den nye mappe?" msgstr[1] "" "Er du sikker på at du vil gendanne disse elementer i den nye mappe?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Er du sikker på at du vil gendanne dette element?" msgstr[1] "Er du sikker på at du vil gendanne disse elementer?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Er du sikker på du vil slette alle nyere filer i {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Er du sikker på du vil slette alle nyere filer i din oprindelige mappe?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}ADVARSEL{BOLDEND}: Hvis du sletter filer i filsystemets rod risikerer " "du at ødelægge hele dit system." #: qt/app.py:1857 msgid "Snapshot" msgstr "Tilstands-billede" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Gendan {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Gendan {path} …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hej\n" "Du har nu brugt Back In Time på {language} et par gange nu.\n" "Oversættelsen af din version af Back In Time i {language} er {perc} færdig oversat. Ligegyldigt af niveau kan du hjælpe med oversættelsen og derved Back In Time.\n" "Besøg venligst {translation_platform_url} hvis du ønsker at kontribuere. For yderlige hjælp eller spørgsmål, besøg venligst {back_in_time_project_website}.\n" "Vi undskylder forstyrrelsen, denne besked vil ikke blive vist igen. Denne dialog box er tilgængelig til enhver tid i 'hjælp' menuen.\n" "Dit Back In Time Team" #: qt/app.py:2071 msgid "translation platform" msgstr "oversættelses platform" #: qt/app.py:2076 msgid "Website" msgstr "Websted" #: qt/app.py:2090 msgid "Your translation" msgstr "Din oversættelse" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "I fødiverset på Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email til {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Emailliste {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} på projektets hjemmeside." #: qt/app.py:2118 msgid "Open an issue" msgstr "Opret en fejlrapport" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Eller du kan benytte en anden mulighed du foretrækker." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Denne udgave af Back In Time er en udgivelseskandidat og er primært tiltænkt stabilitetstest som forberedelse til næste udgivelse.\n" "Ingen brugerdata eller telemetri opsamles. Men, Back In Time-holdet er meget interesseret i at vide om udgivelseskandidaten bliver brugt og om det er værd at fortsætte med at stille sådanne før-udgivelses versioner til rådighed.\n" "Derfor beder holdet dig om kort at tilkendegive om du har prøvet denne udgave, også hvis du ikke oplevede nogle problemer. Selv en hurtig testkørsel på et par minutter hjælper os.\n" "De følgende kontaktmåder findes:\n" "{contact_list}\n" "I denne udgave vises denne besked ikke igen, men du kan altid se den igen i hjælpemenuen.\n" "Tak for din støtte og for at hjælpe os med at gøre Back In Time bedre!\n" "Dit Back In Time-hold" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Sprogopsætningen ændres først efter genstart af Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "EncFS profiloprettelse bliver fjernet i den næste mindre udgivelse (1.7), " "planlagt i 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Det er ikke længere anbefalet at bruge den tilstand i en profil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "whitepaper" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "Understøttelse af EncFS bliver fjernet på grund at sikkerhedsproblemer." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "For yderligere detaljer, inklusive mulige alternativer, se venligst dette " "{whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Følgende profil(er) bruger kryptering med EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "En erstatning er planlagt, men kan ikke garanteres at være der til tiden." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Brugere er velkomne til at bidrage til diskussionen. Opdaterede detaljer om " "de næste trin er tilgængelige i dette {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Denne besked vil ikke blive vist igen. Dialogboksen er tilgænglig på ethvert" " tidspunkt via hjælp-menuen." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Dit Back In Time Hold" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Sæt sprog op" #: qt/languagedialog.py:97 msgid "System default" msgstr "Systemstandard" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Brug styresystemets sprog." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Oversat: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Se Sidste Log" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Se Snapshot Log" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Tilstands-billeder:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alles" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Ændringer" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Fejl" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Information" msgstr[1] "Informationer" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync overførelsesfejl (eksperimentalt)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Fejl, [I] Information, [C] Ændre" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "afkod paths" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Håndtér profiler" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Redigér" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Tilføj" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Fjern" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Generelt" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkludér" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Inkludér filer og mapper" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Tilføj fil" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Tilføj mappe" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Ekskludér" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: I 'SSH krypteret' tilstand, er kun enkelt eller dobbelt" " stjerne funktionelt (f.eks. {example2}). Andre type wildcards eller mønstre" " vil blive ignoreret (f.eks. {example1}). Filnavne er uforudseelige i denne " "tilstand pga. kryptering med EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Ekskludéringmønstre, filer eller mapper" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Tilføj standard" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Ekskludér filer større end:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Ekskludér filer større end værdi i {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Med 'Full rsync mode' slået fra påvirker dette kun nye filer da dette er en " "overførselsesparameter for rsync, ikke en ekskluderingsparameter. Så store " "filer der tidligere er overført forbliver i tilstands-billederne selv hvis " "de er ændret." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Fjer&rn & Opbevaring" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "I&ndstillinger" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "A&vancerede indstillinger" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Gendan opsætning" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Redigér bruger-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Ny profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Omdøb profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Er du sikker på at du vil slette profilen \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Kraftigt anbefalet{ENDBOLD}: (Alle anbefalinger er allerede " "inkluderet.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Kraftigt anbefalet{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Ekskludér mønster" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Ekskludér fil" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Ekskludér mappe" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkludér fil" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" er et symbolsk link. Det linket peger på vil ikke blive sikkerhedskopieret med mindre du også inkluderer den sti.\n" "Vil du inkludere det som linket peger på i stedet?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Inkludér mappe" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Deaktiver fordi dette mønster ikke fungerer i tilstand 'SSH krypteret'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Planlæg" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dag:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Ugedag:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tid:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Timer:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "hver time" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutter:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Kør Back In Time så snart drevet tilsluttes (kun en gang hver X'te dag). Du " "bliver spurgt om dit sudo kodeord." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Kør Back In Time med jævne mellemrum. Dette er praktisk hvis computeren ikke" " er tændt på faste tidspunkter." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Hver:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Aktiver logning af debug beskeder" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Skriver debugniveau-beskeder ind i system log via \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Advarsel: Brug kun dette midlertidigt til fejlfinding, da det genererer en " "stor mængde output." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Deaktiveret" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Ved hver opstart/genstart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Hver {n} minut" msgstr[1] "Hver {n} minutter" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Hver time" msgstr[1] "Hver {n} timer" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Hver {n} time" msgstr[1] "Hver {n} timer" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Angiv interval" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Hver dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Gentag (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Når drev bliver tilsluttet (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Hver uge" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Hver måned" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Hvert år" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Time(r)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(e)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Uge(r)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Måned(er)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Tilpassede timer kan kun være en kommasepareret liste af timer (for eksempel" " 8,12,18,23) eller */3 for periodisk sikkerhedskopiering hver tredje time." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Vært:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Bruger:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Forbind til destinationsvært via denne proxy (også kendt som en jump host). " "Se \"-J\" i \"ssh\"-kommandoens dokumentation eller \"ProxyJump\" i " "\"ssh_config\" man side for detaljer." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Advarsel:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Disse valgmuligheder er til avanceret opsætning. Lad dem være hvis du ikke " "er fuldstændig klar over hvad konsekvenserne er." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Kør 'rsync' med '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "som et cronjob" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "på en fjernvært" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "når et manuelt tilstands-billede dannes" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Installér venlist 'nocache' for at kunne vælge denne mulighed." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "på lokal maskine" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Send stdout til /dev/null i cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron vil automatisk sende en email med vedhæftet output fra cronjobs this " "der er en MTA installeret." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Send stderr til /dev/null i cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron vil automatisk sende en email med vedhæftet fejl af cronjobs hvis en " "MTA er installeret." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Begræns rsync's båndbreddeforbrug:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Behold ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Behold udvidede attributter (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopier usikre links (virker kun med absolutte links)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Begræns til ét filsystem" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Værdier skal i citationstegn, for eksempel {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Indsæt yderligere parametre til rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Præfiks til at køre før hver kommando på fjernvært." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabler skal escapes med \\$FOO. Dette vil ikke berøre rsync. For at " "tilføje præfiks til rsync, brug \"{example_value}\" med " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standard" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Foranstil alle SSH kommandoer" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Undersøg om fjernvært er på nettet" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Advarsel: hvis dette er slået fra og fjernværten ikke er tilgængelig, " "risikerer du at få nogle besynderlige fejl." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Undersøg om fjernværten understøtter alle nødvendige kommandoer." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Advarsel: hvis dette er slået fra og fjernværten ikke understøtter alle " "nødvendige kommandoer risikerer du at få nogle besynderlige fejl." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(standard: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "slået fra" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "slået til" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Tilstand:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Hvor skal tilstands-billeder gemmes" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH Indstillinger" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Sti:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Kryptering:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privat SSH nøgle:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Vælg en eksisterende privat nøgle-fil (normalt navngivet \"id_ed25519\" og i" " ældre opsætninger \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Opret en ny SSH-nøgle uden kodeord (ikke tilladt hvis en privat nøgle-fil " "allerede er valgt)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Kodeord" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Gem kodeord i nøglering" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Husk kodeord for cron (sikkerhedsproblem: root kan læse kodeordet)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avanceret" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Fuld sti til tilstands-billeder:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Du har ikke valgt en privat nøglefil til SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Vil du danne et nyt offentligt/private kodeordsløst nøglepar?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Den private nøglefil \"{file}\" mangler." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Vil du kopiere din offentlige SSH-nøgle til fjernværten for at gøre login " "uden kodeord mulig?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autenticiteten af værten {host} kan ikke etableres." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} nøgle fingeraftryk er:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verificér venligst dette fingeraftryk. Vil du tilføje det til din " "'known_hosts' fil?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Er du sikker på du ønsker at skifte tilstands-billede-mappe ?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Oprettelsen af ny SSH nøgle i {path} mislykkedes." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Aktivér bekendtgørelser" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "De-aktivér tilstands-billeder ved batteri-drift" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Strømstatus ikke tilgængelig fra system" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Dan kun et tilstands-billede af gangen" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andre tilstands-billeder vil være blokeret indtil det nuværende er " "færdiggjort. Dette er en global indstilling. Så det påvirker alle profiler " "for denne bruger. Men du bliver nød til at aktivere det for alle andre " "brugere også." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Sikkerhedskopiering erstattede filer ved genddannelse" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Nyere version af filer vil blive omdøbt med {suffix} tilføjet før " "genddannelse. Hvis du ikke har brug for dem længere, kan de fjernes med " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Fortsæt ved fejl (behold ufuldstændige tilstands-billeder)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Brug checksummer til at finde ændringer" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Dan et nyt tilstands-billede uanset om der var ændringer eller ej." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Logniveau:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ingen" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "De følgende regler håndteres fra top til bund. Senere regler tager præcedens" " over tidligere og er ikke begrænset af disse. Detaljer og eksempler findes " "i {manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "brugervejledning" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Åbn brugervejledning i browser." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Behold det nyeste tilstands-billede." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Det sidste eller friskeste tilstands-billede beholdes under alle " "omstændigher." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Denne opførsel kan ikke ændres." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Behold navngivne tilstands-billeder." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Tilstandsbilleder som, udover det sædvanlige tidsstempel, har fået tilddelt " "et navn slettes under ingen omstændigher og vil ikke blive fjernet." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "År" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Fjern tilstands-billede ældre end" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Hele dage. Dags dato ignoreres." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Kalenderuger med mandag som første dag. Nuværende uge ignoreres." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 måneders perioder. Nuværende måned ignoreres." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Opbevaringspolitik" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Kør i bagrunden på fjernværten." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Smart-sletningsfunktionen kører direkte på fjernmaskinen, ikke lokalt. " "Kommandoerne \"bash\", \"screen\" and \"flock\" er påkrævet på " "fjernmaskinen." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Hvis dette er valgt begynder Back In Time med at teste fjernmaskinen." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dagene tælles fra i dag." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Behold alle tilstands-billeder for de seneste" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dag(e)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Behold det sidste tilstands-billede for hver dag for det sidste" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Ugernes tælles startende fra den nuværende uge. Uger starter på mandage." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Behold det seneste tilstands-billede for hver uge for de seneste" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Uge(r)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Månederne tælles som kalendermåneder fra nuværende måned." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Behold det seneste tilstands-billede for hver måned for de seneste" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "måned(er)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Årene tælles som kalenderår fra i år." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Behold det seneste tilstands-billeder for hvert år de seneste" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "alle år." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... fri plads er mindre end" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... frie inodes er mindre end" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Fjern ældste tilstands-billeder hvis …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Spørgsmål" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Se Sidste Log" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Kør {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Arbejder…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Sendt:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hastighed:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Tilstands-billeder" #: qt/qttools.py:506 msgid "Today" msgstr "I dag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "I går" #: qt/qttools.py:522 msgid "This week" msgstr "Denne uge" #: qt/qttools.py:529 msgid "Last week" msgstr "Sidste uge" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Dette er IKKE et snapshot men et nutidigt syn af dine lokale filer" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Sidste check {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importeer konfiguration" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Ingen opsætning fundet" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Import" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Vælg tilstands-billede-mappen hvorfra konfigurationsfilen skal importeres. " "Stien kan se sådan ud: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Hvis mappen er placeret på en eksternt eller flytbart drev, skal det først " "tilsluttes manuelt." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Vis Fulde Log" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Valgmuligheder om sammenligning af tilstands-billeder" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Kommando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametre:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Brug %1 og %2 som sti-parametre" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Venligst sæt en diff-kommando eller tryk Annuller." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Kommandoen \"{cmd}\" blev ikke fundet på dette system. Venligst prøv noget " "andet eller tryk Annuller." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Ingen parametre sat for diff-kommandoen. Bruger standardværdi \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Kun tilstands-billeder der er forskellige" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Vis kun tilstands-billeder der er ens med:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Grundig sammenligning (mere præcis, men langsom)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Slet" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Vælg alle" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Sammenlign" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gå til" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Indstillinger" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Du kan ikke sammenligne et tilstands-billede med sig selv." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Er du sikker på at du vil slette {file} i tilstands-billedet {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Vil du virkelig slette {file} i {count} tilstands-billeder?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ADVARSEL: Dette kan ikke tilbagekaldes." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Ekskludér {path} fra tilstands-billeder fremover?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Uundermapperne kan ikke inkluderes in backup'en." backintime-1.5.4/common/po/de.po000066400000000000000000002035431477034762000165060ustar00rootroot00000000000000# German translation of Back In Time # Copyright (C) 2008-2009 Oprea Dan # This file is distributed under the same license as the Back In Time package. # msgid "" msgstr "" "Project-Id-Version: Back In Time 0.9.5\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-06 14:37+0000\n" "Last-Translator: buhtz \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Warnung" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hauptprofil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokal (EncFS-verschlüsselt)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-verschlüsselt)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Privater SSH Schlüssel" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokal verschlüsselt" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Verschlüsselung" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH verschlüsselt" #: common/config.py:296 msgid "Default" msgstr "Standard" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: »{name}«" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Schnappschuss-Verzeichnis ist ungültig." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Für das Backup muss mindestens ein Verzeichnis ausgewählt werden." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Verzeichnis: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Dieses Verzeichnis kann nicht in die Sicherung aufgenommen werden, da es " "Teil des Zielverzeichnisses ist." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Schreiben einer neuen crontab ist fehlgeschlagen." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron läuft nicht, obwohl der Befehl crontab verfügbar ist. Geplante " "Sicherungs-Aufgaben werden nicht ausgeführt. Cron könnte installiert, aber " "nicht aktiviert sein. Versuche den Befehl »systemctl enable cron« oder " "konsultiere die Support-Kanäle deiner GNU/Linux-Distribution." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Udev-Regel für Profil {profile_id} konnte nicht erstellt werden. DBus-Dienst" " »{dbus_interface}« war nicht verfügbar" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev-Zeitplan funktioniert nicht mit dem Modus {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "UUID für »{path}« konnte nicht gefunden werden" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Speichern der Konfiguration ist fehlgeschlagen" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Laden der Konfiguration ist fehlgeschlagen" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil »{name}« bereits vorhanden." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Das letzte Profil kann nicht entfernt werden." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "»{command}« kann nicht eingehängt werden" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "" "Einstellungen für das verschlüsselte Verzeichnis wurden nicht gefunden." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Soll ein neues verschlüsseltes Verzeichnis erstellt werden?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Abbruch" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Passwort bitte bestätigen." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Passwort stimmt nicht überein." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Schnappschuss erstellen" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kann {mountprocess} nicht von {mountpoint} aushängen." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} nicht gefunden. Bitte installieren (z.B. mit »{installcommand}«)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Einhängepunkt {mntpoint} ist nicht leer." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Passwort für {mode} Profil »{profile}« eingeben:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FEHLGESCHLAGEN" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Berechtigungen wiederherstellen" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Fertig" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Aufschieben der Sicherung im Akkubetrieb" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Schnappschuss-Verzeichnis wurde nicht gefunden." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Wenn es auf einem Wechsellaufwerk ist, bitte dieses verbinden." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Warte %s Sekunde." msgstr[1] "Warte %s Sekunden." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Schnappschuss {snapshot_id} konnte nicht erstellt werden." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Bitte Geduld haben. Abschluss läuft…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Verzeichnis kann nicht erstellt werden." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Konfigurationsdatei wird gespeichert …" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Zugriffsrechte werden gespeichert …" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Übrig gebliebener Schnappschuss »{snapshot_id}« gefunden, der fortgesetzt " "werden kann." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Vom letzten Durchgang übriggebliebener Schnappschuss »{snapshot_id}« wird " "entfernt" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Verzeichnis kann nicht entfernt werden" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Schnappschuss wird erstellt" #: common/snapshots.py:1430 msgid "Success" msgstr "Erfolgreich" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Teilübertragung aufgrund eines Fehlers" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Partieller Transfer aufgrund von verschwundenen Quelldateien (siehe 'man " "rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' beendet mit Code {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Siehe 'man rsync' für weitere Details" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negative Rückgabewerte von rsync sind Signalnummern. Siehe 'kill -l' und " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Keine Änderungen, es ist kein neuer Schnappschuss notwendig" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Umbenennen von {new_path} in {path} fehlgeschlagen." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Cleveres Löschen" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Wende Regeln, zum Entfernen alter Snapshots an" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Wende Aufbewahrungs-Richtlinien an" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Versuche das Minimum an freiem Speicher freizuhalten" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Es wird versucht mindestens {perc} freie Inodes zu behalten" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Jetzt" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs} kann nicht eingebunden werden" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "ssh-agent nicht gefunden. Bitte sicherstellen, dass er installiert ist." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Privater SSH-Schlüssel konnte nicht entsperrt werden. Passwort falsch oder " "für cron nicht verfügbar." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Verschlüsselungsverfahren {cipher} für {host} fehlgeschlagen." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" "Der Pfad existiert auf dem entfernten Rechner, ist aber kein Verzeichnis." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Der Pfad auf dem entfernten Rechner ist nicht beschreibbar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Der Pfad auf dem entfernten Rechner ist nicht ausführbar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Erstellen des Pfades auf dem entfernten Rechner ist fehlgeschlagen." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Der entfernte Rechner {host} unterstützt {command} nicht" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Weitere Anweisungen unter »man backintime«" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Überprüfung der Befehle auf dem Rechner {host} gab unbekannten Fehler zurück" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Der entfernte Rechner {host} unterstützt keine Hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Den öffentlichen SSH-Schlüssel »{pubkey}« zum entfernten Rechner »{host}« " "kopieren." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Bitte Passwort für »{user}« eingeben." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Das Zielateisystem für {path} ist mit NTFS formatiert, das bekannte " "Inkompatibilitäten mit Unix-ähnlichen Dateisysteme aufweist." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "Der Pfad {path} ist kein gültiges Verzeichnis." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Erstellen des folgenden Verzeichnisses ist fehlgeschlagen:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Schreibzugriff könnte eingeschränkt sein." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Das Zieldateisystem für {path} ist mit FAT formatiert, welches Hardlinks " "nicht unterstützt. Bitte benutzen Sie ein natives GNU/Linux-Dateisystem." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Das Zieldateisystem für {path} ist eine eingehängte SMB-Freigabe. Bitte " "stellen Sie sicher, dass der entfernte SMB-Server Symlinks unterstützt oder " "aktivieren Sie »{copyLinks}« in »{expertOptions}«." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Verknüpfungen kopieren (symbolische Verknüpfungen zurückverfolgen)" #: common/tools.py:504 msgid "Expert Options" msgstr "Experten-Einstellungen" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Das Zieldateisystem für {path} ist eine eingehängte sshfs-Freigabe. Sshfs " "unterstützt keine Hardlinks. Bitte benutzen Sie stattdessen den Modus »SSH«." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Erzeugen einer Datei in diesem Verzeichnis fehlgeschlagen:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Über" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autoren" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Übersetzungen" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lizenz" #: qt/app.py:172 msgid "Shortcuts" msgstr "Verknüpfungen" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Dieses Verzeichnis ist im aktuell ausgewählten\n" "Schnappschuss nicht vorhanden." #: qt/app.py:257 msgid "Add to Include" msgstr "Hinzufügen zum Einschließen" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Hinzufügen zum Ausschließen" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} scheint zum ersten Mal gestartet zu werden, da keine " "Konfiguration gefunden wurde." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Bestehende Konfiguration importieren (von einem Sicherungs-Verzeichnis oder " "einem anderen Computer)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Wenn er auf einem Wechsellaufwerk ist, bitte dieses verbinden und dann OK " "drücken." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Schnappschuss erstellen" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Nutzt Änderungszeit und Größe um geänderte Dateien zu erkennen." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Schnappschuss erstellen (Prüfsummen Modus)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Prüfsumme benutzen, um Änderungen von Dateien zu erkennen." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Schnappschuss anhalten" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Schnappschuss fortsetzen" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Schnappschuss stoppen" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Liste der Schnappschüsse auffrischen" #: qt/app.py:497 msgid "Name snapshot" msgstr "Schnappschuss benennen" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Schnappschuss entfernen" #: qt/app.py:505 msgid "View snapshot log" msgstr "Schnappschussprotokoll ansehen" #: qt/app.py:509 msgid "View last log" msgstr "Letztes Protokoll ansehen" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Profile verwalten…" #: qt/app.py:517 msgid "Shutdown" msgstr "Herunterfahren" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Rechner herunterfahren, nachdem der Schnappschuss erstellt wurde." #: qt/app.py:521 msgid "Setup language…" msgstr "Sprache einstellen…" #: qt/app.py:525 msgid "Exit" msgstr "Beenden" #: qt/app.py:529 msgid "User manual" msgstr "Benutzerhandbuch" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Öffnet Benutzerhandbuch im Browser (wenn verfügbar lokal, anderseits online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Manpage: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Zeigt Manpage über Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "Manpage: Profile-Konfigurationsdatei" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "Zeigt Manpage zu Profil-Konfigurationsdatei (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projektwebsite" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Öffnet Back In Time Website im Browser" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Änderungsprotokoll" #: qt/app.py:555 msgid "FAQ" msgstr "Häufige Fragen (FAQ)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Öffnet Häufig gestellte Fragen (FAQ) im Browser" #: qt/app.py:559 msgid "Ask a question" msgstr "Eine Frage stellen" #: qt/app.py:563 msgid "Report a bug" msgstr "Fehler melden" #: qt/app.py:566 msgid "Translation" msgstr "Übersetzung" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Zeigt die Meldung über die Teilnahme an der Übersetzung erneut an." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Umstellung der Verschlüsselung (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Zeigt die Meldung über das Entfernen von EncFS erneut an." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Wiederherstellen" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Ausgewählte Dateien oder Verzeichnisse am Originalort wiederherstellen." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Wiederherstellen zu …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" "Ausgewählte Dateien oder Verzeichnisse an einem neuen Ort wiederherstellen." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Stellt das aktuell angezeigte Verzeichnis und seinen gesamten Inhalt am " "ursprünglichen Zielort wieder her." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Stellt das aktuell angezeigte Verzeichnis und seinen gesamten Inhalt an " "einem neuen Zielort wieder her." #: qt/app.py:601 msgid "Up" msgstr "Hoch" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Versteckte Dateien anzeigen" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Schnappschüsse vergleichen…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Release Candidate" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Zeigt die Meldung über den Release Candidate erneut an." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Wiederherstellen" #: qt/app.py:698 msgid "&Help" msgstr "&Hilfe" #: qt/app.py:743 msgid "Icons only" msgstr "Nur Icons" #: qt/app.py:746 msgid "Text only" msgstr "Nur Text" #: qt/app.py:749 msgid "Text below icons" msgstr "Text unter Icons" #: qt/app.py:752 msgid "Text beside icon" msgstr "Text neben Icons" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Wenn Sie das Fenster schließen, kann Back In Time den Rechner nicht " "herunterfahren wenn die Sicherung beendet ist." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Möchten Sie es wirklich schließen?" #: qt/app.py:1072 msgid "Working:" msgstr "In Bearbeitung:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Fertig, keine Sicherung notwendig" #: qt/app.py:1129 msgid "Working" msgstr "In Bearbeitung" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Fehler" #: qt/app.py:1161 msgid "Sent" msgstr "Gesendet" #: qt/app.py:1162 msgid "Speed" msgstr "Geschwindigkeit" #: qt/app.py:1163 msgid "ETA" msgstr "Verbleibend" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Wurzelverzeichnis" #: qt/app.py:1227 msgid "Home" msgstr "Persönlicher Ordner" #: qt/app.py:1255 msgid "Backup directories" msgstr "Sicherungs-Verzeichnisse" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Schnappschussname" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Sind Sie sicher, dass Sie den Schnappschuss löschen wollen?" msgstr[1] "Sind Sie sicher, dass Sie diese Schnappschüsse löschen wollen?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Lokale Elemente vor dem Überschreiben oder\n" "Entfernen zur Sicherung mit angehängten {suffix} speichern." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Vor dem Wiederherstellen werden neuere Dateiversionen mit einem angehängten " "{suffix} umbenannt. Wenn sie nicht mehr benötigt werden, können sie mit dem " "folgenden Befehl entfernt werden:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Nur Elemente wiederherstellen, die im Zielordner nicht existieren\n" "oder in der Sicherung neuer sind als im Zielordner.\n" "Das nutzt die Option »rsync --update«." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Neuere Elemente im Original-Verzeichnis entfernen." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Ausgewählte Dateien oder Verzeichnisse am ursprünglichen Ort " "wiederherstellen und Dateien/Verzeichnisse löschen, die nicht in dem " "Schnappschuss enthalten sind. Seien Sie sehr vorsichtig, denn damit werden " "Dateien und Verzeichnisse gelöscht, die während des Erstellen des " "Schnappschusses ausgeschlossen waren." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Wollen Sie dieses Element wirklich in dem neuen Verzeichnis {path} " "wiederherstellen?" msgstr[1] "" "Wollen Sie diese Elemente wirklich in dem neuen Verzeichnis {path} " "wiederherstellen?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Möchten Sie dieses Element wirklich wiederherstellen?" msgstr[1] "Möchten Sie diese Elemente wirklich wiederherstellen?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Sind Sie sicher, dass Sie alle neueren Dateien in {path} entfernen wollen?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Sind Sie sicher, dass Sie alle neueren Dateien in dem Ursprungs-Verzeichnis " "löschen möchten?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Warnung{BOLDEND}: Das Löschen von Dateien im Wurzelverzeichnis kann " "das komplette System zerstören." #: qt/app.py:1857 msgid "Snapshot" msgstr "Schnappschuss" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Stelle {path} wieder her" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Stelle {path} wieder nach …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hallo\n" "Sie haben Back In Time in der Sprache {language} nun schon einige Male genutzt.\n" "Die Übersetzung Ihrer installierten Version von Back In Time in {language} ist zu {perc} vollständig. Unabhängig von Ihren technischen Kenntnissen können Sie selbst zur Übersetzung und damit zu Back In Time beitragen.\n" "Bitte besuchen Sie die {translation_platform_url}, wenn Sie dazu beitragen möchten. Für weitere Hilfe und Fragen, besuchen Sie bitte die {back_in_time_project_website}.\n" "Wir entschuldigen uns für die Unterbrechung. Diese Meldung wird nicht noch einmal angezeigt, ist aber jederzeit über das Hilfe-Menü verfügbar.\n" "Ihr Back In Time-Team" #: qt/app.py:2071 msgid "translation platform" msgstr "Übersetzungsplattform" #: qt/app.py:2076 msgid "Website" msgstr "Internetseite" #: qt/app.py:2090 msgid "Your translation" msgstr "Ihre Übersetzung" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Im Fediverse auf Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email an {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Mailingliste {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} auf der Projekt-Website." #: qt/app.py:2118 msgid "Open an issue" msgstr "Öffne ein Ticket" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativ kannst du einen anderen Kanal deiner Wahl verwendet." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Diese Version von Back In Time ist ein Release Candidate und dient hauptsächlich dem Testen der Stabilität zur Vorbereitung auf die nächste offizielle Version.\n" "Benutzerdaten oder Telemetrie werden nicht gesammelt. Das Back In Time-Team ist jedoch sehr daran interessiert zu erfahren, ob der Release Candidate verwendet wird und ob es sich lohnt, solche Vorabversionen weiterhin anzubieten.\n" "Daher bittet das Team um ein kurzes Feedback, ob du diese Version getestet hast, auch wenn du keine Probleme festgestellt hast. Selbst ein kurzer Testlauf von nur wenigen Minuten würde uns sehr helfen.\n" "Die folgenden Kontaktmöglichkeiten stehen zur Verfügung:\n" "{contact_list}\n" "Diese Nachricht wird, in dieser Version, nicht erneut angezeigt. Sie kann jedoch jederzeit über das Hilfe-Menü aufgerufen werden.\n" "Vielen Dank für deine Unterstützung und dafür, dass du uns hilfst, Back In Time zu verbessern!\n" "Dein Back In Time Team" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Die Spracheinstellungen wirken erst, nach dem Back In Time neu gestartet " "wurde." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Die Erstellung von EncFS-Profilen wird in der nächsten Nebenversion (1.7), " "die für 2026 geplant ist, entfernt." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Es wird nicht empfohlen, diesen Modus weiterhin für ein Profil zu verwenden." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "Whitepaper" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "Die Unterstützung für EncFS wird, aufgrund von sicherheitsrelevanter " "Schwachstellen, eingestellt." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Für weitere Details, einschließlich möglicher Alternativen, bitte dieses " "{whitepaper} lesen." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" "Folgendes Profil bzw. folgende Profile nutzen Verschlüsselung mit EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Ein Ersatz ist geplant, jedoch ohne Garantie, dass er rechtzeitig verfügbar " "sein wird." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Nutzer sind eingeladen, an dieser Diskussionen teilzunehmen. Aktualisierte " "Details zu den nächste Schritte sind in diesem {whitepaper} verfügbar." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Die Nachricht wird nicht wieder angezeigt, ist aber jederzeit über das " "Hilfe-Menu abrufbar." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Dein Back In Time Team" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Sprache einstellen" #: qt/languagedialog.py:97 msgid "System default" msgstr "Standardeinstellung des Systems" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Nutze Sprache des Betriebssystems." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Übersetzt: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Ansicht letztes Protokoll" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Ansicht Schnappschussprotokoll" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Schnappschüsse:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alles" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Änderungen" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Fehler" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Information" msgstr[1] "Informationen" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync Übertragungsfehler (experimentell)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Fehler, [I] Information, [C] Änderung" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "Pfade entschlüsseln" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Profile verwalten" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Bearbeiten" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Hinzufügen" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Entfernen" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Allgemein" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Einbeziehen" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Dateien und Verzeichnisse einbeziehen" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Datei hinzufügen" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Verzeichnis hinzufügen" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "Aus&schließen" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: Im Modus 'SSH verschlüsselt', funktionieren nur " "einzelne oder doppelte Sternchen (z.B. {example2}). Andere Arten von " "Platzhaltern und Mustern werden ignoriert (z.B. {example1}). Aufgrund der " "Verschlüsselung durch EncFS, sind Dateinamen in diesem Modus nicht " "vorhersehbar." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Muster, Dateien oder Verzeichnisse ausschließen" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Standardeinstellungen hinzufügen" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Dateien ausschließen, die größer sind als:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Dateien ausschließen, die größer sind als {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Wenn »Voller rsync-Modus« deaktiviert ist, wird das nur neue Dateien " "betreffen, weil das für rsync eine Transferoption und keine Ausschlussoption" " ist. Das bedeutet, dass größere Dateien, die bereits zuvor gesichert " "wurden, auch in neuen Schnappschüssen gesichert werden, selbst wenn sie " "verändert wurden." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Löschen & Aufbewahren" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Optionen" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "E&xperten-Einstellungen" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Konfiguration wiederherstellen" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "User-callback bearbeiten" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Neues Profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Profil umbenennen" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Sind Sie sicher, dass Sie das Profil »{name}« löschen wollen?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Ausdrücklich empfohlen{ENDBOLD}: (All Empfehlungen bereits " "eingeschlossen.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Ausdrücklich empfohlen{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Ausschlussmuster" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Datei ausschließen" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Verzeichnis ausschließen" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Datei einbeziehen" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "»{path}« ist ein symbolischer Link (Symlink). Das verknüpfte Ziel wird nicht gesichert, wenn Sie es nicht ebenfalls hinzufügen.\n" "Möchten Sie stattdessen das Ziel des Links hinzufügen?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Verzeichnis einbeziehen" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Deaktiviert, da dieses Muster im Modus »SSH verschlüsselt« nicht " "funktionsfähig ist." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Zeitplan" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Tag:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Wochentag:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Uhrzeit:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Stunden:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "nach der vollen Stunde" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuten:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "»Back In Time« starten, sobald das Laufwerk angeschlossen wurde (nur einmal " "alle X Tage). Sie werden nach Ihrem sudo-Passwort gefragt werden." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "»Back In Time« wiederholt starten. Das ist nützlich, wenn der Rechner nicht " "immer eingeschaltet ist." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Alle:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Protokollierung von Debug-Nachrichten aktivieren" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Schreibt Debug-Nachrichten in das Systemprotokoll (nutzt »--debug« Option)." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Vorsicht: Nur vorübergehend zur Diagnose einsetzen, da eine große Menge an " "Ausgaben erzeugt wird." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Deaktiviert" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Bei jedem Hochfahren/Neustart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Jede Minute" msgstr[1] "Alle {n} Minuten" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Jede Stunde" msgstr[1] "Alle {n} Stunden" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Jede Stunde" msgstr[1] "Alle {n} Stunden" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Benutzerdefinierte Stunden" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Täglich" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Wiederholend (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Sobald das Laufwerk angeschlossen wird (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Wöchentlich" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Monatlich" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Jährlich" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Stunde(n)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Tag(e)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Woche(n)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Monat(e)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Benutzerdefinierte Stunden, bitte als Kommata getrennte Stundenliste " "schreiben (z.B. 8,12,18,23) oder */3 für wiederholte Sicherungen alle 3 " "Stunden." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "User:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Verbindet sich mit dem Zielhost über diesen Proxy (auch bekannt als Jump-" "Host). Für Details siehe \"-J\" in der Dokumentation des \"ssh\"-Befehls " "oder \"ProxyJump\" in der \"ssh_config\" man page." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Vorsicht:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Diese Optionen dienen der fortgeschrittenen Konfiguration. Nur ändern, wenn " "die Auswirkungen vollständig bekannt sind." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Starte »rsync« mit »{cmd}«:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "als cron-job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "auf entfernten Rechnern" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "wenn ein Schnappschuss manuell erstellt wird" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Bitte 'nocache' installieren, um diese Option freizuschalten." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "auf dem lokalen Rechner" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Leitet stdout in cronjobs nach /dev/null um." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Wenn ein MTA installiert ist, sendet Cron eine automatische E-Mail mit dem " "angehängten Ausgabeprotokoll der Cronjobs." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Leitet stderr in cronjobs nach /dev/null um." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Wenn ein MTA installiert ist, sendet Cron eine automatische E-Mail mit dem " "angehängten Fehlerprotokoll der Cronjobs." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Beschränke Nutzung der Bandbreite durch rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACLs bewahren" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Erweiterte Attribute (xattr) bewahren" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Unsichere Verknüpfungen kopieren (funktioniert nur mit absoluten " "Verknüpfungen)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Auf ein Dateisystem beschränken" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Optionen müssen in Anführungszeichen stehen z.B.: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Weitere Optionen zu rsync hinzufügen" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" "Präfix der vor jedem Befehl auf dem entfernten Rechner ausgeführt wird." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variablen müssen mit \\$FOO maskiert werden. Das betrifft nicht rsync. Um " "einen Präfix für rsync hinzuzufügen muss »{example_value}« mit " "{rsync_options_value} genutzt werden." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "Standard" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Präfix zum SSH-Befehl hinzufügen" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Überprüfen, ob der entfernte Rechner am Netz ist" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Warnung: Wenn dies deaktiviert ist und der entfernte Rechner nicht verfügbar" " ist, kann es zu einigen verwirrenden Fehlern kommen." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Prüfen, ob der entfernte Rechner alle erforderlichen Befehle unterstützt." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Warnung: Wenn dies deaktiviert ist und der entfernte Rechner nicht alle " "erforderlichen Befehle unterstützt, kann es zu einigen verwirrenden Fehlern " "kommen." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(Standard: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "deaktiviert" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "aktiviert" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modus:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Wo Schnappschüsse gespeichert werden" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-Einstellungen" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Pfad:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Chiffre:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privater Schlüssel:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Wählt eine existierende private Schüsseldatei (üblicherweise als " "»id_ed25519« benannt, oder »id_rsa« auf älteren Systemen)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Erzeugt einen neuen SSH Schlüssel ohne Passwort (nur wenn noch keine private" " Schlüsseldatei ausgewählt wurde)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Passwort" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Passwort im Schlüsselbund speichern" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Passwort für Cron zwischenspeichern (Sicherheitsproblem: Systemverwalter " "»root« kann das Passwort lesen)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Erweitert" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Vollständiger Schnappschusspfad:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Sie haben keine Datei für einen privaten SSH Schlüssel ausgewählt." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Möchten Sie ein neues öffentlich/privates und passwortloses Schlüsselpaar " "erstellen?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Die private Schlüsseldatei »{file}« ist nicht vorhanden." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Möchten Sie Ihren öffentlichen SSH-Schlüssel auf den entfernten Rechner " "kopieren, um die passwortlose Anmeldung zu aktivieren?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Die Echtheit des Rechners {host} kann nicht festgestellt werden." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} Fingerabdruck des Schlüssels ist:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Bitte überprüfen Sie diesen Fingerabdruck. Möchten Sie ihn zu Ihrer " "'known_hosts' Datei hinzufügen?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "" "Sind Sie sicher, dass Sie das Schnappschuss-Verzeichnis ändern wollen?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Erstellen eines neuen SSH-Schlüssels in {path} ist fehlgeschlagen." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Benachrichtigungen aktivieren" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Schnappschüsse im Akkubetrieb deaktivieren" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Energiestatus des Systems nicht verfügbar" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Nur einen Schnappschuss zur selben Zeit ausführen" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andere Schnappschüsse werden blockiert, bis der aktuelle Schnappschuss " "fertiggestellt ist. Das ist eine globale Option, die alle Profile dieses " "Benutzers betreffen wird. Die Option muss aber auch für alle anderen " "Benutzer aktiviert werden." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Beim Wiederherstellen Dateien ersetzen" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Vor dem Wiederherstellen werden neuere Dateiversionen mit einem angehängten " "{suffix} umbenannt. Wenn sie nicht mehr benötigt werden, können Sie sie mit " "{cmd} entfernen" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Bei Fehlern fortfahren (unvollständige Schnappschüsse behalten)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Prüfsumme benutzen, um Änderungen zu erkennen" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Neuen Schnappschuss unabhängig von Änderungen erstellen." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Protokollierungsstufe:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nichts" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Die nachfolgenden Regeln werden von oben nach unten abgearbeitet. Spätere " "Regeln überschreiben frühere und sind nicht an diese gebunden. Siehe das " "{manual} für Details und Beispiele." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "Benutzerhandbuch" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Öffnet Benutzerhandbuch im Browser." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Behalte den neusten Schnappschuss." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Der letzte bzw. frisches Schnappschuss wird unter allen Umständen behalten." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Das Verhalten ist unveränderlich." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Behalte benannte Schnappschüsse." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Schnappschüsse, die zusätzlich zum üblichen Zeitstempel einen Namen erhalten" " haben, werden unter allen Umständen aufbewahrt und werden nicht entfernt." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Jahr(e)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Entferne Schnappschüsse älter als" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Vollständige Tage. Aktueller Tag wird ignoriert." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Kalenderwochen beginnend mit Montag. Aktuelle Woche wird ignoriert." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 Monats Periode. Aktueller Monat wird ignoriert." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Aufbewahrungs-Richtlinien" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Auf entferntem Rechner im Hintergrund ausführen." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Das Clevere-Löschen wird direkt auf dem entfernten System ausgeführt, nicht " "lokal. Die Befehle \"bash\", \"screen\" und \"flock\" müssen auf dem " "entfernten System installiert und verfügbar sein." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Wenn ausgewählt, wird Back In Time zunächst das entfernte System prüfen." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Die Tage werden gezählt, beginnend mit den aktuellen Tag." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Alle Schnappschüsse behalten, der letzten" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Tag(e)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Behalte den letzten Schnappschuss jeden Tages, für die letzten" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Wochenzählung beginnt in der aktuell laufenden Woche. Wochenbeginn ist " "Montag." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Behalte den letzten Schnappschuss jeder Woche, für die letzten" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Woche(n)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Gezählt werden Kalendermonate, beginnend mit dem aktuellen Monat." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Behalte den letzten Schnappschuss jedes Monats, für die letzten" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "Monat(e)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Gezählt werden Kalenderjahre, beginnend mit dem aktuellen Jahr." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Behalte den letzten Schnappschuss jedes Jahres, für" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "alle Jahre." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… freier Speicher kleiner ist als" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… weniger Inodes frei sind als" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Entferne die ältesten Schnappschüsse wenn …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Frage" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Letztes Protokoll ansehen" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Starte {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "In Bearbeitung…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Gesendet:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Geschwindigkeit:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Schnappschüsse" #: qt/qttools.py:506 msgid "Today" msgstr "Heute" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Gestern" #: qt/qttools.py:522 msgid "This week" msgstr "Diese Woche" #: qt/qttools.py:529 msgid "Last week" msgstr "Letzte Woche" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Das hier ist KEIN Schnappschuss, aber eine aktuellen Ansicht Ihrer lokalen " "Daten" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Letzte Überprüfung {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Konfiguration importieren" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Keine Konfiguration gefunden" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importieren" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Wähle das Schnappschuss-Verzeichnis, aus dem die Konfiguration zu " "importieren ist. Der Pfad könnte so aussehen: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Befindet sich das Verzeichnis auf einem externen oder entfernten Laufwerk, " "muss dieses vorher manuell eingehängt werden." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Komplettes Protokoll anzeigen" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Optionen zum Vergleichen von Schnappschüssen" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Befehl:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parameter:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Verwende %1 und %2 als Pfadparameter" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Bitte diff Befehl festlegen oder Abbrechen drücken." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Der Befehl »{cmd}« wurde auf dem System nicht gefunden. Bitte etwas anderes " "versuchen oder Abbrechen drücken." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Keine Parameter für den diff Befehl vorhanden. Nutze die Standardwerte " "»{params}«." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Nur sich unterscheidende Schnappschüsse" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Nur Schnappschüsse auflisten, die gleich sind mit:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Gründliche Prüfung (genauer, aber langsamer)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Löschen" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Alles auswählen" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Vergleiche" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gehen zu" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Optionen" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Sie können einen Schnappschuss nicht mit sich selbst vergleichen." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Soll in dem Schnappschuss »{snapshot_id}« die Datei »{file}« wirklich " "gelöscht werden?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" "Soll in {count} Schnappschüssen die Datei »{file}« wirklich gelöscht werden?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "WARNUNG: Das kann nicht rückgängig gemacht werden." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "»{path}« von zukünftigen Schnappschüssen ausschließen?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Das Unterverzeichnis kann nicht in die Sicherung einbezogen werden." backintime-1.5.4/common/po/el.po000066400000000000000000002454601477034762000165220ustar00rootroot00000000000000# Greek translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-17 19:43+0000\n" "Last-Translator: djemos \n" "Language-Team: Greek \n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Προειδοποίηση" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Κύριο Προφίλ" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Τοπικό (EncFS κρυπτογραφημένο)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS κρυπτογραφημένο)" #: common/config.py:278 msgid "Local" msgstr "Τοπικό" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Ιδιωτικό κλειδί SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Τοπικά κρυπτογραφημένο" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Κρυπτογράφηση" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH κρυπτογραφημένο" #: common/config.py:296 msgid "Default" msgstr "Προεπιλογή" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Προφίλ: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Ο φάκελος στιγμιοτύπων δεν είναι έγκυρος." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Πρέπει να επιλεχτεί τουλάχιστον ένας φάκελος για αντίγραφα ασφαλείας." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Κατάλογος: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Αυτός ο κατάλογος δεν μπορεί να συμπεριληφθεί στο αντίγραφο ασφαλείας, καθώς" " αποτελεί μέρος του ίδιου του προορισμού δημιουργίας αντιγράφων ασφαλείας." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Αποτυχία εγγραφής καινούργιου crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Το Cron δεν εκτελείται παρά το γεγονός ότι η εντολή crontab είναι διαθέσιμη." " Οι προγραμματισμένες εργασίες δημιουργίας αντιγράφων ασφαλείας δεν θα " "εκτελεστούν. Το Cron μπορεί να είναι εγκατεστημένο αλλά να μην είναι " "ενεργοποιημένο. Δοκιμάστε την εντολή \"systemctl enable cron\" ή " "συμβουλευτείτε τα κανάλια υποστήριξης της GNU/Linux διανομής σας." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Αποτυχία εγκατάστασης κανόνα Udev για το προφίλ {profile_id}. Η υπηρεσία " "DBus '{dbus_interface}' δεν ήταν διαθέσιμη" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Ο χρονοπρογραμματισμός με Udev δεν δουλεύει με τη λειτουργία {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Δεν βρέθηκε το UUID για το {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Αποτυχία αποθήκευσης της παραμετροποίησης" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Αποτυχία φόρτωσης της παραμετροποίησης" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Το προφίλ \"{name}\" υπάρχει ήδη." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Το τελευταίο προφίλ δεν μπορεί να αφαιρεθεί." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Αδυναμία προσάρτησης '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Η παραμετροποίηση για κρυπτογραφημένο φάκελο δεν βρέθηκε." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Δημιουργία νέου κρυπτογραφημένου φακέλου;" #: common/encfstools.py:146 msgid "Cancel" msgstr "Ακύρωση" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Παρακαλώ επιβεβαιώστε τον κωδικό." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Ο κωδικός δεν ταιριάζει." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Λήψη στιγμιότυπου" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Αδυναμία αποπροσάρτησης {mountprocess} από το {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Δεν βρέθηκε το {command}. Παρακαλώ εγκαταστήστε το (π.χ. μέσω " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Το σημείο προσάρτησης {mntpoint} δεν είναι κενό." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Καταχώρηση κωδικού για {mode} προφίλ \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "ΑΠΟΤΥΧΙΑ" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Επαναφορά δικαιωμάτων" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Ολοκληρώθηκε" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Αναβολή του backup όσο το σύστημα βρίσκεται σε μπαταρία" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Αδυναμία δημιουργίας φακέλου στιγμιοτύπων." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Εάν βρίσκεται σε αφαιρούμενη συσκευή, παρακαλώ συνδέστε την." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Αναμονή %s δευτερόλεπτο." msgstr[1] "Αναμονή %s δευτερόλεπτα." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Αποτυχία λήψης στιγμιότυπου {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Παρακαλώ για την υπομονή σας. Ολοκληρώνεται…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Αδυναμία δημιουργίας φακέλου." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Αποθήκευση αρχείου ρυθμίσεων…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Αποθήκευση δικαιωμάτων…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Βρέθηκε παλαιότερο στιγμιότυπο {snapshot_id} το οποίο μπορεί να συνεχιστεί." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Αφαίρεση του εναπομείναντα φακέλου {snapshot_id} της τελευταίας εκτέλεσης" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Αδυναμία αφαίρεσης καταλόγου" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Λήψη στιγμιότυπου" #: common/snapshots.py:1430 msgid "Success" msgstr "Επιτυχία" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Μερική μεταφορά λόγω σφάλματος" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Μερική μεταφορά λόγω εξαφανισμένων αρχείων πηγής (δείτε 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "Η διεργασία 'rsync' τελείωσε με κωδικό {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Δείτε το 'man rsync' για περισσότερες λεπτομέρειες" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Οι αρνητικοί αριθμοί ως κωδικοί εξόδου του rsync είναι αριθμοί σήματος, " "δείτε 'kill -l' και 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Δεν άλλαξε τίποτα, δεν είναι απαραίτητη η λήψη νέου στιγμιότυπου" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Αδυναμία μετονομασίας {new_path} σε {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Έξυπνη αφαίρεση" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Εφαρμόστε κανόνες για να αφαιρέσετε παλιά στιγμιότυπα" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Εφαρμόστε πολιτική διατήρησης" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Προσπάθεια διατήρησης ελάχιστου ελεύθερου χώρου" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "" "Προσπαάθεια διατήρησης ελάχιστου ποσοστού {perc} ελεύθερων συστημάτων " "αρχείου (inodes)" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Τώρα" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Αδυναμία προσάρτησης {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "το ssh-agent δε βρέθηκε. Παρακαλώ βεβαιωθείτε ότι είναι εγκατεστημένο." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Δεν ήταν δυνατό το ξεκλείδωμα του ιδιωτικού κλειδιού SSH. Λάθος κωδικός ή " "δεν υπάρχει διαθέσιμος κωδικός για cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Το κρυπτογράφημα {cipher} απέτυχε για τον {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Η απομακρυσμένη διαδρομή υπάρχει αλλά δεν είναι φάκελος." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Η απομακρυσμένη διαδρομή δεν είναι εγγράψιμη." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Η απομακρυσμένη διαδρομή δεν είναι εκτελέσιμη." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Αδυναμία δημιουργίας απομακρυσμένης διαδρομής." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" "Ο απομακρυσμένος διακομιστής {host} δεν υποστηρίζει την εντολή {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Βλέπε 'man backintime' για περισσότερες οδηγίες" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Οι εντολές ελέγχου στον διακομιστή {host} επέστρεψαν ένα άγνωστο σφάλμα" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "O απομακρυσμένος διακομιστής {host} δεν υποστηρίζει hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Αντιγράψτε το δημόσιο κλειδί SSH \"{pubkey}\" στον απομακρυσμένο διακομιστή " "\"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Παρακαλώ επιβεβαιώστε τον κωδικό του \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Το σύστημα αρχείων του προορισμού για το {path} είναι μορφοποιημένο με NTFS," " το οποίο είναι ασύμβατο με συστήματα αρχείων προορισμού Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} δεν είναι έγκυρος κατάλογος." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Η δημιουργία του ακόλουθου καταλόγου απέτυχε:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Τα δικαιώματα εγγραφής μπορεί να είναι περιορισμένα." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Το σύστημα αρχείων του προορισμού για το {path} είναι μορφοποιημένο με FAT " "το οποίο δεν υποστηρίζει hard-links. Παρακαλώ χρησιμοποιήστε ένα εγγενές " "σύστημα αρχείων GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Το σύστημα αρχείων προορισμού για το {path} είναι ένα κοινόχρηστο στοιχείο " "που προσαρτάται μέσω SMB. Βεβαιωθείτε ότι ο απομακρυσμένος διακομιστής SMB " "υποστηρίζει συμβολικούς συνδέσμους ή ενεργοποιήστε το \"{copyLinks}\" στο " "\"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Αντιγραφή συνδέσμων (αφαίρεση αναφοράς των συμβολικών συνδέσμων)" #: common/tools.py:504 msgid "Expert Options" msgstr "Προχωρημένες Ρυθμίσεις" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Το σύστημα αρχείων προορισμού για το {path} είναι ένα κοινόχρηστο στοιχείο " "που προσαρτάται μέσω sshfs. Το Sshfs δεν υποστηρίζει σκληρούς συνδέσμους. " "Χρησιμοποιήστε τη λειτουργία \"SSH\"." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Αδυναμία δημιουργίας φακέλου στον κατάλογο:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Σχετικά" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Δικαιούχοι" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Μεταφράσεις" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Άδεια Χρήσης" #: qt/app.py:172 msgid "Shortcuts" msgstr "Συντομεύσεις" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Αυτός ο κατάλογος δεν υπάρχει\n" "στο τρέχον επιλεγμένο στιγμιότυπο." #: qt/app.py:257 msgid "Add to Include" msgstr "Προσθήκη στα Περιλαμβανόμενα" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Προσθήκη στα Αποκλειόμενα" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} φαίνεται να εκτελείται για πρώτη φορά χωρίς να εντοπίζεται " "παραμετροποίηση." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Εισαγωγή υπάρχουσας παραμετροποίησης (από κατάλογο ανάκτησης ή από άλλο " "υπολογιστή);" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Εάν βρίσκεται σε αφαιρούμενη συσκευή, παρακαλώ συνδέστε την και στην " "συνέχεια πατήστε ΟΚ." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Λήψη στιγμιοτύπου" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Χρήση ώρας τροποποίησης και μεγέθους, για ανίχνευση αλλαγής αρχείου." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Λήψη στιγμιοτύπου (κατάσταση checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Χρήση των checksum για ανίχνευση αλλαγών αρχείου." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Παύση της διαδικασίας στιγμιοτύπου" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Συνέχιση διαδικασίας στιγμιοτύπου" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Διακοπή διαδικασίας στιγμιοτύπου" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Ανανέωση λίστας στιγμιοτύπου" #: qt/app.py:497 msgid "Name snapshot" msgstr "Ονομασία στιγμιότυπου" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Αφαίρεση στιγμιότυπου" #: qt/app.py:505 msgid "View snapshot log" msgstr "Πρόβαλε το αρχείο καταγραφής στιγμιότυπου" #: qt/app.py:509 msgid "View last log" msgstr "Προβολή τελευταίας καταγραφής" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Διαχείριση προφιλ…" #: qt/app.py:517 msgid "Shutdown" msgstr "Τερματισμός" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "" "Τερματισμός λειτουργίας συστήματος μετά την ολοκλήρωση του στιγμιοτύπου." #: qt/app.py:521 msgid "Setup language…" msgstr "Καθορισμός γλώσσας…" #: qt/app.py:525 msgid "Exit" msgstr "Έξοδος" #: qt/app.py:529 msgid "User manual" msgstr "Εγχειρίδιο χρήστη" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Ανοίξτε το εγχειρίδιο χρήστη στο πρόγραμμα περιήγησης (τοπικό εάν είναι " "διαθέσιμο διαφορετικά στο διαδίκτυο)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man page: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Εμφανίζει τη σελίδα χρήστη σχετικά με το Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man page: Αρχείο διαμόρφωσης προφίλ" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Εμφανίζει τη σελίδα χρήστη σχετικά με το αρχείο διαμόρφωσης προφίλ " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Ιστοσελίδα του έργου" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Ανοίξτε τον ιστότοπο Back In Time στο πρόγραμμα περιήγησης" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Αρχείο αλλαγών" #: qt/app.py:555 msgid "FAQ" msgstr "Συχνές Ερωτήσεις" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Ανοίξτε τις Συχνές Ερωτήσεις (FAQ) στο πρόγραμμα περιήγησης" #: qt/app.py:559 msgid "Ask a question" msgstr "Κάνε μια ερώτηση" #: qt/app.py:563 msgid "Report a bug" msgstr "Αναφορά προβλήματος" #: qt/app.py:566 msgid "Translation" msgstr "Μετάφραση" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Εμφανίζει ξανά το μήνυμα σχετικά με τη συμμετοχή στη μετάφραση." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Μετάβαση κρυπτογράφησης (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Εμφανίζει ξανά το μήνυμα σχετικά με την αφαίρεση του EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Επαναφορά" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Επανέφερε τα επιλεγμένα αρχεία ή φακέλους στον αρχικό τους προορισμό." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Επαναφορά στο…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Επανέφερε τα επιλεγμένα αρχεία ή φακέλους σε ένα νέο προορισμό." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Επαναφορά του τρέχοντος εμφανιζόμενου φακέλου και όλων των περιεχομένων του," " στον αρχικό προορισμό." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Επανέφερε τον τρέχοντα εμφανιζόμενο φάκελο και όλα τα περιεχόμενα του σε ένα" " νέο προορισμό." #: qt/app.py:601 msgid "Up" msgstr "Επάνω" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Προβολή κρυφών αρχείων" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Σύγκριση στιγμιοτύπων…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Απελευθέρωση υποψηφίου" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Εμφανίζει ξανά το μήνυμα για αυτόν τον υποψήφιο έκδοσης." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Eπαναφορά" #: qt/app.py:698 msgid "&Help" msgstr "&Βοήθεια" #: qt/app.py:743 msgid "Icons only" msgstr "Μόνο εικονίδια" #: qt/app.py:746 msgid "Text only" msgstr "Κείμενο μόνο" #: qt/app.py:749 msgid "Text below icons" msgstr "Κείμενο κάτω από τα εικονίδια" #: qt/app.py:752 msgid "Text beside icon" msgstr "Κείμενο δίπλα στο εικονίδιο" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Αν κλείσετε αυτό το παράθυρο το Back In Time δεν θα μπορεί να τερματίσει το " "σύστημά σας όταν ολοκληρωθεί το στιγμιότυπο." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Είστε σίγουροι ότι θέλετε να το κλείσετε;" #: qt/app.py:1072 msgid "Working:" msgstr "Εργασία:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Ολοκληρώθηκε, δεν χρειάζεται backup" #: qt/app.py:1129 msgid "Working" msgstr "Εργασία" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Σφάλμα" #: qt/app.py:1161 msgid "Sent" msgstr "Στάλθηκαν" #: qt/app.py:1162 msgid "Speed" msgstr "Ταχύτητα" #: qt/app.py:1163 msgid "ETA" msgstr "Αναμενόμενος χρόνος" #: qt/app.py:1225 msgid "Global" msgstr "Γενικά" #: qt/app.py:1226 msgid "Root" msgstr "Ρίζα" #: qt/app.py:1227 msgid "Home" msgstr "Οικία" #: qt/app.py:1255 msgid "Backup directories" msgstr "Φάκελοι ανάκτησης" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Όνομα στιγμιότυπου" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Είστε σίγουροι ότι θέλετε να διαγράψετε το παρακάτω στιγμιότυπο;" msgstr[1] "Είστε σίγουροι ότι θέλετε να διαγράψετε τα παρακάτω στιγμιότυπα;" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Δημιουργία αντιγράφων backup με επίθεμα {suffix}\n" "πριν την αντικατάσταση ή αφαίρεση τοπικών στοιχείων." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Οι νεότερες εκδόσεις αρχείων θα μετονομαστούν με επίθεμα {suffix} πριν " "επανέλθουν. Αν δεν τα χρειάζεστε πια, μπορείτε να τα αφαιρέσετε με την " "ακόλουθη εντολή:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Αποκατάσταση μόνο στοιχείων που δεν υπάρχουν ή\n" "είναι νεότερα από αυτά στον προορισμό.\n" "Χρησιμοποιώντας την επιλογή \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Αφαίρεσε νέα στοιχεία από τον αρχικό φάκελο." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Επαναφέρετε επιλεγμένα αρχεία ή καταλόγους στον αρχικό προορισμό και " "διαγράψτε αρχεία ή καταλόγους που δεν βρίσκονται στο στιγμιότυπο. Να είστε " "εξαιρετικά προσεκτικοί γιατί αυτό θα διαγράψει αρχεία και καταλόγους που " "εξαιρέθηκαν κατά τη λήψη του στιγμιότυπου." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Είστε σίγουροι ότι θέλετε να επαναφέρετε αυτό το στοιχείο μέσα στον νέο " "φάκελο;" msgstr[1] "" "Είστε σίγουροι ότι θέλετε να επαναφέρετε αυτά τα στοιχεία μέσα στον νέο " "φάκελο;" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "" "Είστε σίγουροι ότι θέλετε να διαγράψετε το {file} από {count} στιγμιότυπα;" msgstr[1] "" "Είστε σίγουροι ότι θέλετε να διαγράψετε τα {file} από {count} στιγμιότυπα;" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Είστε σίγουρος για μεταφορά όλων των νεότερων αρχείων στο {path};" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Είστε σίγουροι ότι θέλετε να διαγράψετε όλα τα νέα αρχεία από τον αρχικό σας" " κατάλογο;" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Προσοχή{BOLDEND}: Διαγράφοντας αρχεία από το ριζικό φάκελλο μπορεί να " "έχει ως αποτέλεσμα την κατάρρευση του συστήματος." #: qt/app.py:1857 msgid "Snapshot" msgstr "Στιγμιότυπο" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Επαναφορά {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Επαναφορά {path} στο…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Γειά\n" "Μέχρι στιγμής έχεις χρησιμοποιήσει μερικές φορές την {language} γλώσσα\n" "Η μετάφραση της εγκατεστημένης έκδοσης του Back In Time στα {language} είναι {perc} ολοκληρωμένη. Ανεξάρτητα απο το τεχνικό σου επίπεδο, μπορείς να συνεισφέρεις στην μετάφραση και κατ' επέκταση στο ίδιο το Back In Time.\n" "Παρακαλώ επισκέψου το {translation_platform_url} εαν επιθμείς να συνεισφέρεις. Για περαιτέρω βοήθεια και ερωτήσεις , παρακαλώ επισκέψου το {back_in_time_project_website}.\n" "Μας συγχωρείς για την διακοπή, και αυτό το μήνυμα δεν θα εμφανιστεί ξανά. Αυτή η ενημέρωση είναι διαθέσιμη οπότε θελήσεις μέσα απο το μενού help.\n" "H ομάδα του Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "πλατφόρμα μετάφρασης" #: qt/app.py:2076 msgid "Website" msgstr "Ιστοσελίδα" #: qt/app.py:2090 msgid "Your translation" msgstr "Η μετάφρασή σου" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Στο Fediverse στο Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email στο {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Mailing list {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} στην ιστοσελίδα του έργου." #: qt/app.py:2118 msgid "Open an issue" msgstr "Άνοιξε ένα ζήτημα" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" "Εναλλακτικά, μπορείς να χρησιμοποιήσεις εναλλακτικό κανάλι επικοινωνίας της " "επιλογής σου." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Αυτή είναι μια έκδοση συνεισφοράς του Back In Time και ο πρωταρχικός της σκοπός είναι να δοκιμαστεί η σταθερότητά της κατά το στάδιο προετοιμασίας της επόμενης επίσημης έκδοσης.\n" "Δεν συλλέγονται προσωπικά δεδομένα ή δεδομένα τηλεμετρίας. Ωστόσο η ομάδα του Back In Time ενδιαφέρεται να γνωρίζει εάν αυτή η έκδοση συνεισφοράς χρησιμοποιείται και αν αξίζει να συνεχίσει να προσφέρει αυτές τις εκδόσεις πριν την επίσημη κυκλοφορία.\n" "Συνεπώς, η ομάδα ευγενικά επιθυμεί να σας ζητήσει την ανατροφοδότησή σας σε οτιδήποτε έχετε δοκιμάσει από την συγκεκριμένη έκδοση, ακόμα και αν δεν παρουσιάστηκαν ιδιαίτερα ζητήματα. Ακόμα και ένα γρήγορο τέστ μερικών λεπτών θα ήταν πολύτιμο για εμάς. \n" "Οι ακόλουθοι τρόποι επικοινωνίας είναι διαθέσιμοι:\n" "{contact_list}\n" "Στην συγκεκριμένη έκδοση, αυτό το μήνυμα δεν θα εμφανιστεί εκ νέου όμως θα είναι προσβάσιμο μέσω του μενού βοήθειας.\n" "Σας ευχαριστούμε για την υποστήριξη και για την βοήθεια να εξελίξουμε το Back In Time!\n" "Η δική σου ομάδα του Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Η επιλογή γλώσσας ενεργοποιείται έπειτα από επανεκκίνηση του Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Η δημιουργία προφίλ EncFS θα καταργηθεί στην επόμενη δευτερεύουσα έκδοση " "(1.7), που έχει προγραμματιστεί για το 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Δεν συνιστάται η χρήση αυτής της λειτουργίας για προφίλ επιπλέον." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "λευκή βίβλος" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Η υποστήριξη για το EncFS διακόπτεται λόγω τρωτών σημείων ασφαλείας." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Για περισσότερες λεπτομέρειες, συμπεριλαμβανομένων πιθανών εναλλακτικών " "λύσεων, ανατρέξτε σε αυτό το {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Τα ακόλουθα προφίλ χρησιμοποιούν κρυπτογράφηση με EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Σχεδιάζεται μια αντικατάσταση, αλλά δεν μπορούμε να εγγυηθούμε ότι θα φτάσει" " έγκαιρα." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Οι χρήστες καλούνται να συμμετάσχουν σε αυτή τη συζήτηση. Ενημερωμένες " "λεπτομέρειες για τα επόμενα βήματα είναι διαθέσιμες σε αυτό το {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Αυτό το μήνυμα δεν θα εμφανιστεί ξανά. Αυτός ο διάλογος είναι διαθέσιμος " "οποτεδήποτε μέσω του μενού βοήθειας." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Η δική σου ομάδα του Your Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Γλώσσα εγκατάστασης" #: qt/languagedialog.py:97 msgid "System default" msgstr "Προεπιλογή συστήματος" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Χρήση της γλώσσας του λειτουργικού συστήματος." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Μεταφρασμένο: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Προβολή Τελευταίου αρχείου καταγραφής" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Προβολή αρχείου καταγραφής στιγμιότυπου" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Προφίλ:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Λήψη στιγμιοτύπου:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Φίλτρο:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Όλα" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Αλλαγές" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Σφάλματα" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Πληροφορία" msgstr[1] "Πληροφορίες" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "αποτυχίες μεταφοράς rsync (πειραματικό)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Σφάλμα, [I] Πληροφορία, [C] Αλλαγή" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "αποκωδικοποίηση μονοπατιών" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Διαχείριση προφίλ" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Επεξεργασία" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Προσθήκη" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Αφαίρεση" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Γενικά" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Συμπεριλαμβάνει" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Συμπεριλαμβάνει αρχεία και καταλόγους" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Πρόσθεσε αρχείο" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Προσθήκη καταλόγου" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Εξαίρεση" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Πληροφορίες{ENDBOLD}: Στη κατάσταση λειτουργίας 'SSH encrypted', " "λειτουργούν μόνο μονοί ή διπλοί αστερίσκοι (π.χ. {example2}). Άλλοι τύποι " "χαρακτήρων μπαλαντέρ και μοτίβων θα αγνοηθούν (π.χ. {example1}). Τα ονόματα " "αρχείων είναι απρόβλεπτα σε αυτήν τη λειτουργία λόγω κρυπτογράφησης από το " "EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Εξαιρέστε μοτίβα, αρχεία ή καταλόγους" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Προσθήκη προεπιλογής" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Εξαίρεση αρχείων μεγαλύτερα από:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Εξαίρεση αρχείων μεγαλύτερα από {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Με απενεργοποιημένη τη λειτουργία \"Πλήρης συγχρονισμός\", αυτό θα επηρεάσει" " μόνο τα νέα αρχεία, καθώς για το rsync, αυτή είναι μια επιλογή μεταφοράς " "και όχι μια επιλογή εξαίρεσης. Επομένως, τα μεγάλα αρχεία για τα οποία έχουν" " δημιουργηθεί αντίγραφα ασφαλείας στο παρελθόν θα παραμείνουν στα " "στιγμιότυπα ακόμα κι αν έχουν τροποποιηθεί." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Κατάργηση & Διατήρηση" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Επιλογές" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Επιλογές E&expert" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Επαναφορά παραμετροποίησης" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Επεξεργασία επανάκλησης χρήστη" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Νέο προφίλ" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Μετονομασία προφίλ" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Είστε βέβαιοι ότι θέλετε να διαγράψετε το προφίλ \"{name}\";" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Συνιστάται ανεπιφύλακτα{ENDBOLD}: (Όλες οι προτάσεις έχουν ήδη " "συμπεριληφθεί.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Συνιστάται ανεπιφύλακτα{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Εξαίρεσε μοτίβο" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Εξαίρεση αρχείου" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Εξαίρεση καταλόγου" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Συμπερίληψη αρχείου" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "Το \"{path}\" είναι ένας συμβολικός σύνδεσμος. Στο συνδεδεμένο στόχος δεν θα δημιουργηθεί αντίγραφο ασφαλείας μέχρι να τον συμπεριλάβετε επίσης.\n" "Θα θέλατε να συμπεριλάβετε τον στόχο συμβολικού συνδέσμου;" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Συμπερίληψη καταλόγου" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Απενεργοποιήθηκε επειδή αυτό το μοτίβο δεν λειτουργεί στη λειτουργία 'SSH " "encrypted'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Προγραμματισμός" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Ημέρα:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Καθημερινές:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Ώρα:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Ώρα(ες):" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "μετά την ώρα" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Λεπτά:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Εκτελέστε το Back In Time μόλις συνδεθεί η μονάδα δίσκου (μόνο μία φορά κάθε" " X ημέρες). Θα σας ζητηθεί ο κωδικός πρόσβασης sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Τρέξτε το Back In Time επανειλημμένα. Αυτό είναι χρήσιμο εάν ο υπολογιστής " "δεν λειτουργεί τακτικά." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Κάθε:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Ενεργοποίηση καταγραφής μηνυμάτων εντοπισμού σφαλμάτων" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Γράφει μηνύματα σε επίπεδο εντοπισμού σφαλμάτων στο αρχείο καταγραφής " "συστήματος μέσω \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Προσοχή: Χρησιμοποιήστε το μόνο προσωρινά για διαγνωστικά, καθώς παράγει " "μεγάλη ποσότητα εξόδου." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Απενεργοποιημένο" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Σε κάθε εκκίνηση/επανεκκίνηση" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Κάθε {n} λεπτό" msgstr[1] "Κάθε {n} λεπτά" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Κάθε ώρα" msgstr[1] "Κάθε {n} ώρες" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Κάθε {n} ώρα" msgstr[1] "Κάθε {n} ώρες" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Ώρες που μπορείτε να τις προσαρμόσετε" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Καθημερινά" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Επανειλημμένως" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Όταν συνδέεται δίσκος (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Κάθε εβδομάδα" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Κάθε μήνα" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Κάθε χρόνο" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Ώρα(ες)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Ημέρα(ες)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Εβδομάδα(ες)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Μήνας(ες)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Οι προσαρμοσμένες ώρες μπορούν να είναι μόνο μια λίστα ωρών διαχωρισμένων με" " κόμματα (π.χ. 8,12,18,23) ή */3 για περιοδικά αντίγραφα ασφαλείας κάθε 3 " "ώρες." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Χρήστης:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Συνδεθείτε στον κεντρικό υπολογιστή προορισμού μέσω αυτού του διακομιστή " "μεσολάβησης (γνωστός και ως κεντρικός υπολογιστής μετάβασης). Δείτε το " "\"-J\" στην τεκμηρίωση της εντολής \"ssh\" ή το \"ProxyJump\" στη σελίδα man" " \"ssh_config\" για λεπτομέρειες." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Προσοχή:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Αυτές οι επιλογές είναι για προηγμένες διαμορφώσεις. Τροποποιήστε μόνο εάν " "έχετε πλήρη επίγνωση των συνεπειών τους." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Τρέξε 'rsync' με '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "ως cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "σε απομακρυσμένο κεντρικό υπολογιστή" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "όταν παίρνετε ένα χειροκίνητο στιγμιότυπο" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Εγκαταστήστε το 'nocache' για να ενεργοποιήσετε αυτήν την επιλογή." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "στην τοπική μηχανή" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Ανακατευθύνετε το stdout στο /dev/null στα cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Το Cron θα στείλει αυτόματα ένα email με συνημμένη έξοδο cronjobs εάν " "εγκατασταθεί ένα MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Ανακατεύθυνση stderr στο /dev/null στα cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Το Cron θα στείλει αυτόματα ένα email με συνημμένα σφάλματα cronjobs εάν " "εγκατασταθεί ένα MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/δευτερόλεπτο" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Περιορισμός χρήσης εύρους ζώνης rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Διατηρήστε το ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Διατήρηση εκτεταμένων χαρακτηριστικών (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Αντιγραφή μη ασφαλών συνδέσμων (λειτουργεί μόνο με απόλυτους συνδέσμους)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Περιορισμός σε ένα σύστημα αρχείων" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Οι επιλογές πρέπει να αναφέρονται π.χ. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Επικολλήστε πρόσθετες επιλογές για συγχρονισμό" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" "Πρόθεμα για εκτέλεση πριν από κάθε εντολή στον απομακρυσμένο κεντρικό " "υπολογιστή." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Οι μεταβλητές πρέπει να διαφεύγουν με \\$FOO. Αυτό δεν αγγίζει τον " "συγχρονισμό. Επομένως, για να προσθέσετε ένα πρόθεμα για rsync " "χρησιμοποιήστε το \"{example_value}\" με το {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "προεπιλογή" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Προσθήκη προθέματος σε εντολές SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Ελέγξτε εάν ο απομακρυσμένος κεντρικός υπολογιστής είναι συνδεδεμένος" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Προειδοποίηση: Εάν είναι απενεργοποιημένο και ο απομακρυσμένος κεντρικός " "υπολογιστής δεν είναι διαθέσιμος, αυτό θα μπορούσε να οδηγήσει σε κάποια " "περίεργα σφάλματα." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Ελέγξτε εάν ο απομακρυσμένος κεντρικός υπολογιστής υποστηρίζει όλες τις " "απαραίτητες εντολές." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Προειδοποίηση: Εάν είναι απενεργοποιημένο και ο απομακρυσμένος κεντρικός " "υπολογιστής δεν υποστηρίζει όλες τις απαραίτητες εντολές, αυτό θα μπορούσε " "να οδηγήσει σε κάποια περίεργα σφάλματα." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(προεπιλογή: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "ανενεργό" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "ενεργό" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Λειτουργία:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Που να αποθηκεύσουμε στιγμιότυπα" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Ρυθμίσεις SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Διαδρομή:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Κρυπτοαλγόριθμος:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Ιδιωτικό κλειδί:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Διάλεξε ένα υπάρχων αρχείο ιδιωτικού κλειδιού (συνήθως ονομάζεται " "\"id_ed25519 και σε παλαιότερες εγκαταστάσεις \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Δημιούργησε ένα νέο κλειδί SSH χωρίς κωδικό (δεν επιτρέπεται εάν ήδη υπάρχει" " ένα αρχείο ιδιωτικού κλειδιού)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Κωδικός" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Αποθήκευση κωδικού στην Κλειδοθήκη" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Αποθηκεύστε προσωρινά τον κωδικό πρόσβασης για το Cron (πρόβλημα ασφαλείας: " "ο root μπορεί να διαβάσει τον κωδικό πρόσβασης)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Προηγμένος" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Πλήρης διαδρομή στιγμιότυπου:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Δεν επιλέξατε ένα αρχείο ιδιωτικού κλειδιού για το SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Θα θέλατε να δημιουργήσετε ένα νέο ζευγάρι ιδιωτικού/δημόσιου κλειδιού χωρίς" " κωδικό;" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Το αρχείο ιδιωτικού κλειδιού \"{file}\" δεν υπάρχει." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Θέλετε να αντιγράψετε το δημόσιο κλειδί SSH στον απομακρυσμένο κεντρικό " "υπολογιστή για να ενεργοποιήσετε τη σύνδεση χωρίς κωδικό πρόσβασης;" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" "Η αυθεντικότητα του απομακρυσμένου υπολογιστή {host} δεν μπορεί να " "εξακριβωθεί." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Το αποτύπωμα κλειδιου {keytype} είναι:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Παρακαλώ εξακριβώστε το αποτύπωμα. Θα θέλατε να το προσθέσετε στο αρχείο " "'known_hosts';" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Είστε σίγουροι ότι θέλετε να αλλάξετε τον φάκελο στιγμιότυπων;" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Αποτυχία δημιουργίας νέου κλειδιού SSH στο {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Ενεργοποίησε τις ειδοποιήσεις" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Απενεργοποίησε τα στιγμιότυπα όντας σε λειτουργία με μπαταρία" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Η κατάσταση ενέργειας δεν είναι διαθέσιμη από το σύστημα" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Εκτέλεσε μόνο ένα στιγμιότυπο κάθε φορά" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Άλλα στιγμιότυπα θα αποκλειστούν μέχρι να ολοκληρωθεί το τρέχον στιγμιότυπο." " Αυτή είναι μια καθολική επιλογή. Επομένως, θα επηρεάσει όλα τα προφίλ αυτού" " του χρήστη. Αλλά πρέπει να το ενεργοποιήσετε και για όλους τους άλλους " "χρήστες." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Το αντίγραφο ασφαλείας αντικατέστησε αρχεία κατά την επαναφορά" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Οι νεότερες εκδόσεις αρχείων θα μετονομαστούν με επίθεμα {suffix} πριν " "επανέλθουν. Αν δεν τα χρειάζεστε πια, μπορείτε να τα αφαιρέσετε με {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Συνέχισε παρά τα λάθη (κράτησε ημιτελή στιγμιότυπα)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Χρησιμοποίησε checksum για να εντοπίσεις αλλαγές" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Δημιούργησε ενα νέο στιγμιότυπο είτε υπάρχουν αλλαγές είτε όχι." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Επίπεδο καταγραφής:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Κανένα" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Οι παρακάτω κανόνες επεξεργάζονται από πάνω προς τα κάτω. Οι μεταγενέστεροι " "κανόνες υπερισχύουν των προγενέστερων και δεν περιορίζονται από αυτούς. " "Δείτε το {manual} για λεπτομέρειες και παραδείγματα." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "εγχειρίδιο χρήσης" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Άνοιξε το εγχειρίδιο χρήσης στον φυλλομετρητή." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Κράτησε το πιο πρόσφατο στιγμιότυπο." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Το τελευταίο ή πιο φρέσκο στιγμιότυπο διατηρείται υπό οποιεσδήποτε συνθήκες." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Αυτή η συμπεριφορά δεν δύναται να αλλάξει." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Κράτησε επώνυμα στιγμιότυπα." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Τα στιγμιότυπα στα οποία έχει δοθεί ένα όνομα, εκτός από τη συνηθισμένη " "χρονική σήμανση, θα διατηρηθούν υπό οποιεσδήποτε συνθήκες και δεν θα " "αφαιρεθούν." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Έτος(η)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Αφαίρεση στιγμιότυπων παλαιότερων από" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Ολόκληρες ημέρες. Η τρέχουσα ημέρα αγνοείται." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Ημερολογιακές εβδομάδες με πρώτη μέρα τη Δευτέρα. Η τρέχουσα εβδομάδα " "αγνοείται." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "περίοδοι 12 μηνών. Ο τρέχων μήνας αγνοείται." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Πολιτική διατήρησης" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Εκτέλεση στο παρασκήνιο σε απομακρυσμένο κεντρικό υπολογιστή." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Η διαδικασία έξυπνης αφαίρεσης θα εκτελεστεί απευθείας στο απομακρυσμένο " "μηχάνημα, όχι τοπικά. Οι εντολές \"bash\", \"screen\" και \"flock\" πρέπει " "να είναι εγκατεστημένες και διαθέσιμες στο απομακρυσμένο μηχάνημα." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Εάν επιλεγεί, το Back In Time θα ελέγξει πρώτα τον απομακρυσμένο κεντρικό " "υπολογιστή." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Οι ημέρες μετρούνται από σήμερα." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Κράτησε ολα τα στιγμιότυπα από την τελευταία" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Ημέρα(ες)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Κράτησε το τελευταίο στιγμιότυπο για κάθε μέρα από την τελευταία" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Οι εβδομάδες υπολογίζονται ξεκινώντας από την τρέχουσα εβδομάδα λειτουργίας." " Μια εβδομάδα ξεκινά τη Δευτέρα." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Κράτησε το τελευταίο στιγμιότυπο για κάθε εβδομάδα από την τελευταία" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Εβδομάδα(ες)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Οι μήνες μετρούνται για ημερολογιακοί μήνες αρχίζοντας από τον τρέχον μήνα." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" "Κράτησε το τελευταίο στιγμιότυπο για κάθε μήνα από τον(τους) τελευταίο(ους)" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "Μήνας(ες)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Τα έτη μετρούνται ως ημερολογιακά έτη αρχίζοντας από το τρέχον έτος." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Κράτησε το τελευταίο στιγμιότυπο για κάθε έτος για" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "όλα τα έτη." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... ο ελεύθερος χώρος είναι μικρότερος από" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... τα ελεύθερα inodes είναι λιγότερα από" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Αφαίρεσε τα παλαιότερα στιγμιότυπα εάν …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Ερώτηση" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Προφίλ: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Προβολή τελευταίου αρχείου καταγραφής" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Εκκίνησε {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Εργάζεται…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Απεσταλμένα:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Ταχύτητα:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ΕΧΑ:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Στιγμιότυπα" #: qt/qttools.py:506 msgid "Today" msgstr "Σήμερα" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Εχθές" #: qt/qttools.py:522 msgid "This week" msgstr "Αυτή την εβδομάδα" #: qt/qttools.py:529 msgid "Last week" msgstr "Προηγούμενη εβδομάδα" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Αυτό ΔΕΝ είναι ένα στιγμιότυπο αλλά μια ζωντανή προβολή των τοπικών σας " "αρχείων" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Τελευταίος έλεγχος {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Εισαγωγή διαμόρφωσης" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Δεν βρέθηκαν ρυθμίσεις παραμέτρων" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Εισαγωγή" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Επιλέξτε τον κατάλογο στιγμιότυπων από τον οποίο πρέπει να εισαχθεί το " "αρχείο διαμόρφωσης. Η διαδρομή μπορεί να μοιάζει με: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Εάν ο κατάλογος βρίσκεται σε εξωτερική ή απομακρυσμένη μονάδα δίσκου, πρέπει" " να τοποθετηθεί χειροκίνητα εκ των προτέρων." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Εμφάνιση πλήρους αρχείου καταγραφής" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Επιλογές για σύγκριση στιγμιότυπων" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Εντολή:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Παράμετροι:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Χρησιμοποιήστε το %1 και το %2 για τις παραμέτρους διαδρομής" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Παρακαλώ ορίστε μια εντολή diff ή πατήστε Ακύρωση." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Η εντολή \"{cmd}\" δεν βρέθηκε σε αυτό το σύστημα. Παρακαλώ δοκιμάστε κάτι " "άλλο ή πατήστε Ακύρωση." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Δεν έχουν οριστεί παράμετροι για την εντολή diff. Χρησιμοποιείται η " "προεπιλεγμένη τιμή \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Συγκρινόμενα στιγμιότυπα μόνο" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Πρόβαλε μόνο τα στιγμιότυπα που είναι ίσα με:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Έλεγχος σε βάθος (πιο ακριβής, αλλά αργός)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Διαγραφή" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Επιλογή Όλων" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Σύγκριση" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Πήγαινε στο" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Επιλογές" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Δεν μπορείτε να συγκρίνετε ένα στιγμιότυπο με τον εαυτό του." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Θέλετε σίγουρα να διαγράψετε το αρχείο {file} που υπάρχει στο στιγμιότυπο " "{snapshot_id};" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" "Είστε σίγουροι ότι θέλετε να διαγράψετε το {file} από {count} στιγμιότυπα;" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ΠΡΟΣΟΧΗ: Αυτό δεν μπορεί να αναιρεθεί." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Εξαίρεση {path} από μελλοντικά στιγμιότυπα;" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "" #~ "Ο υποφάκελος του αντιγράφου δεν μπορεί να εμπεριέχεται στον φάκελλο " #~ "ανάκτησης." backintime-1.5.4/common/po/eo.po000066400000000000000000001667241477034762000165320ustar00rootroot00000000000000# Esperanto translation for backintime # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-16 05:39+0000\n" "Last-Translator: Adolfo Jayme Barrientos \n" "Language-Team: Esperanto \n" "Language: eo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Averto" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Ĉefa profilo" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Loka (EncFS-kriptita)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-kriptita)" #: common/config.py:278 msgid "Local" msgstr "Loka" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "privata ŝlosilo de ssh" #: common/config.py:283 msgid "Local encrypted" msgstr "Kriptita loke" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "kriptante" #: common/config.py:289 msgid "SSH encrypted" msgstr "kriptita SSH" #: common/config.py:296 msgid "Default" msgstr "defaŭlto" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profilo: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Dosiero por ekrankopio ne estas valida!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Restaŭri {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Savkopi-subdosierujon ne eblis inkluzivi." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Malsukcesis skribi novan crontab-on." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron ne rulas malgraŭ la ekzisto de la komando \"crontab\". La planitaj " "savkopi-loboroj ne rulos. Cron eble estas instalita, sed ne ŝaltita. Provu " "la komandon \"systemctl enable cron\" aŭ konsulti la subtenaĵoj de via " "GNU/Linux distribuo." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Ne povis instali udev-regulo por profilo {profile_id}. DBus-servo " "{dbus_interface} ne estis havebla" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "udev-planado ne funkcias je reĝimo {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Ne povas trovi UUID por {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Malsukcesis savi agordon" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Malsukcesis meti agordo" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profilo \"{name}\" jam ekzistas." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Ĉi tio ne povas esti nuligita." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Ne povas surmeti '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Agordo por ĉifritaj dosierujoj ne trovis." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Krei novan kriptan dosieron?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Ĉesi" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Bonvolu konfirmi pasvorton." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Pasvorto ne kongruas." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Krei momentaĵon" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Ne povas demeti {mountprocess} disde {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} ne estas trovita. Bonvolu instali ĝin ekz. per " "\"{installcommand}\"" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Surmetingo {mntpoint} ne estas malplena." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Entajpi pasvorton por {mode} profilo \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "Malpravis" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaŭri permesojn" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Farite" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Atendas baterion antaŭ komenci savkopii" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Ne povas trovi momentaĵ-dosierujon." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Se ĝi estas je demetebla disko, bonvolu konekti ĝin kaj post tio premi OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Atendi %s sekundon." msgstr[1] "Atendi %s sekundojn." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Malsukcesas krei momentaĵon {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Ne povas krei dosieron" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Konservante agordan dosieron…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Savante permesojn…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Trovis {snapshot_id}, kiun eblas plukreas." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Forigante {snapshot_id} dosierujon de lasta momentaĵkreo" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Ne povas forigi dosieron" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Faras ekrankopion" #: common/snapshots.py:1430 msgid "Success" msgstr "Sukceso" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Parta transmeto pro eraro" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Parta transmeto, ĉar la fontaj dosieroj malaperis (vidu 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' finas kun elira kodo {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Vidu 'man rsync' por pli multe da detaloj" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negativaj eliraj kodoj de rsync estas signalkodoj, vidu 'kill -l' kaj 'man " "kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nenio estas ŝanĝita, nova momentaĵo ne estas necesa" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Ne povas renomi {new_path} al {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Inteligenta forigo" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Malnovaj momentaĵoj estas forigitaj" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Provas konservi la minimumo da neokupita diskospaco" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Provante konservi minimume {perc} da malplenaj indeksnodoj" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nun" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Ne povas surmeti {sshfs}" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "Ne trovas ssh-agent. Bonvolu certiĝi, ke ĝin estas instalita." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Ne povas malŝlosi privata ŝlosilo de ssh. Neĝusta pasvorto aŭ pasvorto ne " "ricevebla por cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Ĉifro {cipher} malsukcesas por {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Fora vojo ekzistas, sed ne estas dosierujo." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Fora vojo ne estas skribebla." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Fora vojo ne estas plenumebla." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Ne povis krei foran vojon." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Foriga gastiganto {host} ne subtenas {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Vidu al 'man backintime' por pli multe da instrukcioj" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kontrolkomando en gastiganto {host} revenigis nekonatan eraron" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Fora gastiganto {host} ne subtenas senperan ligilon" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopii publika ssh-ŝloliso \"{pubkey}\" al la fora gastiganto \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Bonvolu enigi pasvorton por uzanto \"{user}\"." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Celdosiersistemo por {path} estas formita kun FAT, kio ne subtenas senperajn" " ligilojn. Bonvolu uzi indiĝenan Linuksan dosiersistemo." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Fora vojo ekzistas, sed ne estas dosierujo." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Celdosiersistemo por {path} estas formita kun FAT, kio ne subtenas senperajn" " ligilojn. Bonvolu uzi indiĝenan Linuksan dosiersistemo." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Celdosiersistemo por {path} estas muntita retdividejo je SMB. Bonvolu " "certiĝi, ke la fora SMB servilo subtenas simbolajn ligilojn, aŭ aktivigi " "{copyLinks} en {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopii lingilojn (forigi simbolajn lingilojn)" #: common/tools.py:504 msgid "Expert Options" msgstr "Spertaj Agordoj" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Celdosiersistemo por {path} estas muntita retdividejo je sshfs. sshfs ne " "subtenas senperajn ligilojn. Bonvolu uzi la 'SSH' reĝimo anstataŭe." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Pri" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Aŭtoroj" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Tradukoj" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Permesilo" #: qt/app.py:172 msgid "Shortcuts" msgstr "Klavkombinoj" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Tio dosierujo ne ekzistas\n" "en la nuntempe selektita momentaĵo." #: qt/app.py:257 msgid "Add to Include" msgstr "Aldoni al la inkluzivitoj" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Aldoni al la ekskluzivitoj" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "Ŝajnas, ke {app_name} rulas unue, ĉar agordo ne estas trovita." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Ĉu importi ekzistantan agordon (de savkopi-celdosierujo aŭ alia komputilo)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Se ĝi estas je demetebla disko, bonvolu konekti ĝin kaj post tio premi OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Fari momentaĵon" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Uzi tempon kaj grandon de modifo por detektado de dosierŝanĝoj." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Krei momentaĵon (kontrolsumreĝimo)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Uzi kontrolsumojn por detektado de dosierŝanĝoj." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Paŭzi momentaĵkreon" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Malpaŭzi momentaĵkreon" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Ĉesi momentaĵkreon" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Aktualigi liston da momentaĵoj" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nomi momentaĵon" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Forigi momentaĵon" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vidi momentaĵprotokolon" #: qt/app.py:509 msgid "View last log" msgstr "Vidi lastan protokolon" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Administri profilojn…" #: qt/app.py:517 msgid "Shutdown" msgstr "Sistemfermo" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Malŝati sistemon post fini momentaĵkreon." #: qt/app.py:521 msgid "Setup language…" msgstr "Agordi lingvon…" #: qt/app.py:525 msgid "Exit" msgstr "Eliri" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Agorddosiero por profiloj" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Ŝanĝoprotokolo" #: qt/app.py:555 msgid "FAQ" msgstr "Oftaj demandoj" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Demandi" #: qt/app.py:563 msgid "Report a bug" msgstr "Raporti cimon" #: qt/app.py:566 msgid "Translation" msgstr "Traduko" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Vidigas la mesaĝon pri partopreni je la tradukoj ree." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Ŝanĝi la kriptadon (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Vidigas ree la mesaĝon pri la fortigado de EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaŭri" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Restaŭri la selektitajn dosierojn aŭ dosierujojn al originala celo." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaŭri al …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Restaŭri la selektitajn dosierojn aŭ dosierujojn al nova celo." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaŭri la nuntempe vidigitajn dosierujojn kaj ĉiojn de ilia enhavo al " "originala celo." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaŭri la nuntempe vidigitajn dosierujojn kaj ĉiojn de ilia enhavo al nova" " celo." #: qt/app.py:601 msgid "Up" msgstr "Supren" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Montri kaŝitajn dosierojn" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Kompari momentaĵojn…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Vidigas ree la mesaĝon pri la fortigado de EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Savkopio" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaŭri" #: qt/app.py:698 msgid "&Help" msgstr "&Helpo" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Se vi fermi tiun fenestron, Back in Time ne eblos malŝalti vian sistemon." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Ĉu vi vere volas fermi ĝin?" #: qt/app.py:1072 msgid "Working:" msgstr "Faranta:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Farita, savkopio ne estas bezonata" #: qt/app.py:1129 msgid "Working" msgstr "Laborante" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Eraro" #: qt/app.py:1161 msgid "Sent" msgstr "Sendita" #: qt/app.py:1162 msgid "Speed" msgstr "Rapideco" #: qt/app.py:1163 msgid "ETA" msgstr "Restanta" #: qt/app.py:1225 msgid "Global" msgstr "Tutmonda" #: qt/app.py:1226 msgid "Root" msgstr "Ĉefuzanto" #: qt/app.py:1227 msgid "Home" msgstr "Hejmo" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Savkopiodosierujoj" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nomo de momentaĵo" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Ĉu vi certas ke vi volas forigi tion momentaĵon?" msgstr[1] "Ĉu vi certas ke vi volas forigi tiojn momentaĵojn?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Krei kopioj de savkopioj kun vosta {suffix}\n" "antaŭ anstataŭigi aŭ forigi lokajn elementojn." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Pli novaj versioj de dosieroj estos renomata je vosta {suffix} antaŭ " "restaŭri. Se vi ne plu bezonas ilin, vi povas forigi ilin je la sekvanta " "komando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Sole restaŭri elementojn, kiuj ne ekzistas aŭ\n" "estas pli novaj ol tiuj, kiuj estas je la celon.\n" "Tio uzas la \"rsync --update\" opcion." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Forigi pli novaj elementoj en la originala dosierujo." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaŭri selektajn dosierojn aŭ dosierujon al la originala celon kaj forigi " "dosierojn aŭ dosierujojn, kiuj ne estas en la momentaĵo. Estu treege zorga, " "ĉar tio forigos dosierojn kaj dosierujon, kiuj estis ekskluzivitaj kiam la " "momentaĵo estis kreita." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Ĉu vi vere volas restaŭri ĉi tiun dosier(uj)on al la nova dosierujo\n" "{path}?" msgstr[1] "" "Ĉu vi vere volas restaŭri ĉi tiujn dosier(uj)ojn al la nova dosierujo\n" "{path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ĉu vi vere volas restaŭri ĉi tiun dosieron?" msgstr[1] "Ĉu vi vere volas restaŭri ĉi tiujn dosierojn?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Ĉu vi certas ke vi volas forigi ĉiujn pli novajn dosierojn en {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Ĉu vi estas certa, ke vi volas forigi ĉiujn pli novajn dosierojn en la " "originala dosierujo?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}AVERTO{BOLDEND}: Forigi dosierojn en la radika dosierujo povas rompi " "vian tutan sistemon." #: qt/app.py:1857 msgid "Snapshot" msgstr "Momentaĵo" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaŭri {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaŭri {path} al …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Saluton\n" "Vi estas uzinta Back In Time en {language} kelkfoje nun.\n" "La {language}-traduko de la instalita versio estas {perc} kompleta. Sendistinge de via nivelo de komputil-kono, vi povas kontribui al la traduko kaj tiumaniere al Back In Time mem.\n" "Bonvolu viziti la {translation_platform_url} se vi deziras kontribui. Por plua helpo kaj demandoj, bonvolu viziti la {back_in_time_project_website}.\n" "Ni pardonpetas pri la interrompo, kaj ĉi tiu mesaĝo ne plu aperos. Ĉi tio dialogo estos ĉiam disponebla en la helpmenuo.\n" "Via Back In Time teamo" #: qt/app.py:2071 msgid "translation platform" msgstr "tradukplatformon" #: qt/app.py:2076 msgid "Website" msgstr "Retejo" #: qt/app.py:2090 msgid "Your translation" msgstr "Via traduko" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "La lingoagordoj ne efikas antaŭ restarti Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Post ne longe EncFS ne estos subtenata. Ne estas rekomendita uzi tio ĉi " "reĝimo por profilo plue." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "dokumento" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "La sekvanta(j) profilo(j) uzi ĉifrado je EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ĉi tiu mesaĝo ne plu aperos. Ĉi tio dialogo estos ĉiam disponebla en la " "helpmenuo." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Via Back In Time teamo" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Agordi lingvon" #: qt/languagedialog.py:97 msgid "System default" msgstr "Defaŭlto de la sistemo" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Uzi la lingvon de la operaciumo." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Tradukita: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Vidaĵo je lastaj protokoloj" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Vidaĵo je momentaĵoj" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profilo:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Momentaĵoj:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtrilo:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Ĉiuj" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Ŝanĝoj" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Eraroj" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informoj" msgstr[1] "Informoj" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Transmetpaneo je rsync (eksperimenta)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Eraro, [I] Informoj, [C] Ŝanĝo" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "Malĉifri vojojn" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Administri profilojn" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Redakti" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Aldoni" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Forigi" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Ĝenerale" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkluzivi" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Inkluzivi dosierojn kaj dosierujojn" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Aldoni dosieron" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Aldoni dosierujon" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Ekskluzivi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informo:{ENDBOLD}: Je 'kriptita SSH' reĝimo, sole unuoblaj kaj duoblaj" " asteriskoj funkcii (ekz. {example2}). Aliaj tipoj de ĵokeroj kaj ŝablonoj " "estos ignoritaj (ekz. {example1}). Nomoj de dosieroj estas neantaŭvideblaj " "je tio reĝimo pro la kriptado de EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Ekskluzivi ŝablonojn, dosierojn aŭ dosierujojn" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Aldoni defaŭlton" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Ekskluzivi dosierojn pli grandajn ol:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Ekskluzivi dosierojn pli grandajn ol {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Se 'Tuta rsync reĝimo' estas malvalidigita, tio sole influos novajn " "doiserojn, ĉar por rsync tio estas transmetopcio, ne ekskluzivopcio. Do " "grandaj dosieroj, kiujn estis savkopiita antaŭe, restos en momentaĵoj, eĉ se" " ili ŝanĝis." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opcioj" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Specialaj Opcioj" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaŭri agordon" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Redakti user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nova profilo" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renomi profilon" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Ĉu vi certas ke vi volas forigi la profilon \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Treege rekomenditoj{ENDBOLD}: (Ĉiuj rekomendoj estas inkluzivitaj " "jam.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Treege rekomenditoj{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Ekskludi ŝablonon" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Ekskludi dosieron" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Ekskludi dosierujon" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkludi dosieron" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" estas simbola ligilo. La ligita celo ne estos savkopiata ĝis vi inkludi ĝin ankaŭ.\n" "Ĉu vi volas inkludi la simbole ligitan celon anstataŭ?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Inkludi dosierujon" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Malŝaltita, ĉar tio ŝablono ne funkcias je 'kriptita SSH' reĝimo." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Horaro" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Tago:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Labortago:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Horoj:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Ruli Back In Time tuj kiam la disko estas konektita (sole unu fojon en X tagoj).\n" "Vi estos demandata je via sudo-pasvorton." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Ruli Back In Time ripetfoje. Tio estas utila se la komputilo ne rulas " "regule." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Ĉiuj:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Ŝalti protokoli de sencimig-mesaĝoj" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Skribas mesaĝoj kun sencimig-nivelo en sistem-protokolo per \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Singardo: Sole uzu tion kelktempe pro diagnozo, ĉar ĝin generas larĝan " "kvanton de eligo." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Malŝaltita" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Je ĉiu startigo/restartigo" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Je ĉiu minuto" msgstr[1] "Je ĉiuj {n} minutoj" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Ĉiu horon" msgstr[1] "Ĉiu {n} horojn" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Ĉiu horoj" msgstr[1] "Ĉiu {n} horojn" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Uzdefinitaj horoj" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Ĉiutage" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Ripete (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Kiam diskingo estas kontektate (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Ĉiusemajne" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Ĉiumonate" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Ĉiujare" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Horo(j)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Tago(j)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semajno(j)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Monato(j)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Uzdefinitaj horoj sole eblas esti perkome disigita listo (ekz. 8,12,18,23) " "aŭ io kiel */3 por periodaj savkopioj je ĉiu 3 horoj." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH-prokurilo" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Gastiganto:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Pordo:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Uzanto:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Konekti al la celgastiganto per tio prokurilo (ankaŭ konita kiel \"jump " "host\" aŭ \"salt-gastiganto\"). Por pli multe da detaloj, vidu \"-J\" en la " "dokumentado de la komando \"ssh\" au \"ProxyJump\" en la dokumentado je la " "programo \"man\"." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Demando" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Startas 'rsync' je '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "kiel cron laboro" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "je la fora gastiganto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "kiam fari manan momentaĵon" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Bonvolu instali 'nocache' por ŝalti tion opcion)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "je loka komputilo" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Alidirekti stdout al /dev/null en cron laboro." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron aŭtomate sendos retpoŝto kun la aldonita eligo de la cron laboroj, se " "MTA estas instalita." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Alidirekti stderr al /dev/null en cron laboro." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron aŭtomate sendos retpoŝto kun la aldonita erar-eligo de la cron laboroj," " se MTA estas instalita." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Trafiklimigi rsync-on:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Konservi ACL-ojn" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Konservi etenditajn atributojn (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopii danĝerajn ligilojn (sole funkcias je absolutaj ligiloj)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Limigi al unu dosiersistemo" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opcioj devas esti citita ekz. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Aldoni pluajn opciojn al rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefikso antaŭ ĉiuj komandoj en la fora gastiganto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabloj devas eskapita je \\$FOO. Tio ne afektas rsync. Do por aldoni " "prefikso al rsync, uzi \"{example_value}\" je {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "Defaŭlto" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Aldoni prefikso al SSH-komandoj" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Kontroli, ke la fora gastiganto estas konektita" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Averto: se malvalidigita kaj la fora gastiganto ne estas disponebla, tio " "eblas igi kelkaj da bizaraj eraroj." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Kontroli, ke la fora gastiganto subtenas ĉiujn necesajn komandojn." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Averto: Se malvalidigita kaj la fora gastiganto ne subtenas ĉiujn necesajn " "komandojn, tio eblas igi kelkaj da bizaraj eraroj." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(defaŭlto: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "malŝaltita" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "ŝaltita" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Maniero:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kien savi la momentaĵojn" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Agordo de SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Vojo:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Ĉifro:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privata Ŝlosilo:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Elekti ekzistantan dosieron je privata ŝlosilo (normale nomita \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Krei novan SSH-ŝlosilon sen pasvorto (ne permesita se privata ŝlosilo estas " "jam elektita)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Pasvorto" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Savi pasvorton je ŝlosilaro" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Kaŝmemorigi pasvorton por cron (Sekureca problemo: ĉefuzanto eblas legi " "pasvorton)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Progresinta" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Plena momentaĵvojo:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Vi ne elektis privata-ŝlosil-dosieron por SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Ĉu vi volas generi novan paron de publika/privatan ŝlosilojn sen pasvorto?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Private ŝlosila dosiero {file} ne ekzistas." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Ĉu vi volas kopii vian publikan SSH-ŝlosilon al la fora gastiganto por " "ebligi ensaluton sen pasvorto?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "La aŭtenteco de la gastiganto {host} ne estis konstatebla." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} ŝlosilfingropremo estas:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Bonvolu konfirmi tion fingropremon! Ĉu vi volas aldoni ĝin al via " "'known_hosts' dosiero?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Ĉu vi certas ke vi volas ŝanĝi la momentaĵdosierujon?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Malsukcesi krei novan SSH-ŝlosilon en {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Aktivigi sciigojn" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Malvalidigi momentaĵkreado kiam ruli je baterio" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Kurentstato ne estas havebla de la sistemo" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Ne ruli plurajn momentaĵojn samtempe" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Aliaj momentaĵoj estos ŝtopita ĝis la aktuala momentaĵo estas kreita. Tio " "estas malloka opcio. Do ĝi afekcias ĉiujn profilojn por tiu uzanto. Sed vi " "devas ankaŭ aktivigi tion por ĉiujn aliaj uzanto." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Anstataŭigi dosierojn dum restaŭri" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Pli novaj versioj de dosieroj estos renomata je vosta {suffix} antaŭ " "restaŭri. Se vi ne plu bezonas ilin, vi povas forigi ilin je {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Kontinui je eraroj (savi nekompletajn momentaĵojn)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Uzi kontrolsumo por detekti ŝanĝojn" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Krei novan momentaĵon eĉ se nenio ŝanĝis." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivelo de protokoli:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Neniu" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Ne forigi nomitajn momentaĵojn." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Ne forigi nomitajn momentaĵojn." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Jaro(j)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Forigi momentaĵon" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Ruli fone je la foriga gastiganto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Savi ĉiujn momentaĵojn de la lasta(j)" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "tago(j)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Savi unu momentaĵon por tago je la lasta(j)" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Savi unu momentaĵon por semajno je la lasta(j)" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semajno(j)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Savi unu momentaĵon por monato je la lasta(j)" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "monato(j)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Savi ĉiujn momentaĵojn de la lasta(j)" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "ĉiuj jaroj." #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Se neokupita loko estas malpli ol:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Se neokupita indeksnodo estas malpli ol:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Malnovaj momentaĵoj estas forigitaj" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Demando" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profilo: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Vidi lastan protokolon" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Komencu {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Laborante…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Sendita:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Rapideco:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Restanta:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Momentaĵoj" #: qt/qttools.py:506 msgid "Today" msgstr "Hodiaŭ" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Hieraŭ" #: qt/qttools.py:522 msgid "This week" msgstr "Nuna semajno" #: qt/qttools.py:529 msgid "Last week" msgstr "Lasta semajno" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Tio Ne estas momentaĵo, sed liva vivo de viaj lokaj dosieroj" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Lasta kontrolo {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importi agordon" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Ne trovas agordon" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importi" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Elekti la momentaĵ-dosierujon de kie la agord-dosiero devus importota. La " "vojo eble aspektas tiel: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Se la dosierujo estas je ekstera aŭ fora disko, ĝi devas esti mane surmetita" " antaŭe." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Vidigi tutan protokolon" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opcioj de kompari momentaĵojn" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Komando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametroj:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Uzi %1 kaj %1 por vojparametroj" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Bonvolu agordi diff-komandon aŭ premi \"Ĉesi\"." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Ne eblas trovi la komandon \"{cmd}\" je tio sistemo. Bonvolu provi ian alion" " aŭ premi \"Ĉesi\"." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Neniom da parametroj agordita por la diff-komando. Uzi defaŭltan valoron " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Sole malsamaj momentaĵoj" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Sole listigi momentaĵojn samajn al:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Kompleta kontrolo (pli precize, sed pli malrapide)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Forigi" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Elekti ĉion" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Kompari" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Iri al" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcioj" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Vi ne povas kompari momentaĵon je ĝin mem." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Ĉu vi vere volas forigi {file} en momentaĵo {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ĉu vi vere volas forigi {file} en {count} momentaĵoj?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "AVERTO: Ĉi tio ne povas esti nuligita." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Ekskluzivi {path} de estontaj momentaĵoj?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Savkopi-subdosierujon ne eblis inkluzivi." backintime-1.5.4/common/po/es.po000066400000000000000000002001631477034762000165200ustar00rootroot00000000000000# Spanish translation of Backintime. # Copyright (C) 2008-2009 Oprea Dan # This file is distributed under the same license as the Backintime package. # Francisco M. Garcia Claramonte , 2008-2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-20 07:55+0000\n" "Last-Translator: Adolfo Jayme Barrientos \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Aviso" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Perfil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (cifrado EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (cifrado EncFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Clave privada SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Cifrado localmente" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Cifrado" #: common/config.py:289 msgid "SSH encrypted" msgstr "Cifrado SSH" #: common/config.py:296 msgid "Default" msgstr "Predeterminado" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Perfil: «{name}»" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "El directorio de instantáneas no es válido." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Debe seleccionarse al menos un directorio para la copia de respaldo." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Directorio: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Este directorio no puede incluirse en la copia de respaldo porque forma " "parte del destino de la copia misma." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Error al escribir nuevo crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron no se está ejecutando pese a que la orden crontab está disponible. Los " "trabajos de copia de respaldo programados no se ejecutarán. Cron podría " "estar instalado pero no activado. Pruebe la orden «systemctl enable cron» o " "consulte los canales de asistencia de su distribución GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "No se pudo instalar la regla Udev para el perfil {profile_id}. El servicio " "DBus «{dbus_interface}» no está disponible" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "La programación de Udev no funciona con el modo {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "No se pudo encontrar el UUID de «{path}»" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Error al guardar la configuración" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Se produjo un fallo al cargar la configuración" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "El perfil «{name}» ya existe." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "No puede eliminar el último perfil." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "No se pudo montar «{command}»" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "No se encuentra la configuración del directorio cifrado." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "¿Quiere crear un directorio cifrado nuevo?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Cancelar" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Confirme la contraseña." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "La contraseña no coincide." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Tomar instantánea" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "No se puede desmontar {mountprocess} de {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "No se encontró la orden {command} . Instálela (por ejemplo, mediante " "«{installcommand}»)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "El punto de montaje {mntpoint} no está vacío." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Introduzca la contraseña para el perfil {mode} «{profile}»:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "Falló" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaurar permisos" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Finalizado" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Aplazando la copia de respaldo mientras se usa la batería" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "No se puede encontrar el directorio de las instantáneas." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Si está en una unidad extraíble, conéctela." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Esperando %s segundo." msgstr[1] "Esperando %s segundos." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Error al tomar la instantánea {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Aguarde un momento. Finalizando…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "No se puede crear el directorio." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Guardando archivo de configuración…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Guardando permisos…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Se ha encontrado la instantánea sobrante {snapshot_id} que puede continuar." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Eliminación de los restos {snapshot_id} directorio de la última ejecución" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "No se puede eliminar la carpeta" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Tomar instantánea" #: common/snapshots.py:1430 msgid "Success" msgstr "Exitoso" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "La transferencia fue parcial por un error" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferencia parcial debido a la desaparición de archivos fuente (consulte " "«man rsync»)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "«rsync» finalizó con el código de salida {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Consulte «man rsync» para más detalles" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Los códigos de salida negativos de rsync son números de señales; consulte " "«kill -l» y «man kill»" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nada ha cambiado; no es necesaria una nueva instantánea" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "No se puede renombrar {new_path} a {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Eliminación inteligente" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Aplicar las reglas para eliminar las instantáneas antiguas" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Aplicar política de retención" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Intentar mantener el espacio libre mínimo" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Intentando conservar un mínimo de {perc} de inodos libres" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Ahora" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "No se puede montar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent no se encuentra. Asegúrese de que está instalado." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "No se pudo desbloquear la clave privada SSH. Contraseña incorrecta o " "contraseña inaccesible para cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "El cifrado {cipher} falló para {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "La ruta remota existe pero no es un directorio." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "La ruta remota no admite escritura." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "La ruta remota no es ejecutable." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "No se ha podido crear la ruta remota." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "El anfitrión remoto {host} no admite {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Consulte «man backintime» para obtener instrucciones adicionales" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Las órdenes de comprobación en el anfitrión {host} devolvieron un error " "desconocido" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "El anfitrión remoto {host} no admite enlaces duros" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copiar clave pública SSH «{pubkey}» en el anfitrión remoto «{host}»." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Introduzca una contraseña para «{user}»." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "El sistema de archivos de destino para {path} está formateado con NTFS, que " "tiene incompatibilidades conocidas con los sistemas de archivos de estilo " "Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} no es un directorio válido." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "No se pudo crear el directorio siguiente:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "El acceso de escritura puede estar restringido." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "El sistema de archivos de destino para {path} está formateado con FAT que no" " admite enlaces físicos. Use un sistema de archivos nativo de GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "El sistema de archivos de destino para {path} es un recurso compartido " "montado a través de SMB. Asegúrese de que el servidor SMB remoto admite " "enlaces simbólicos o active «{copyLinks}» en «{expertOptions}»." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copiar enlaces (desreferenciar enlaces simbólicos)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opciones avanzadas" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "El sistema de archivos de destino para {path} es un recurso compartido " "montado a través de sshfs. Sshfs no admite enlaces duros. Use el modo «SSH» " "en su lugar." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "La creación del archivo falló en este directorio:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Acerca de" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autores" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traducciones" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licencia" #: qt/app.py:172 msgid "Shortcuts" msgstr "Atajos" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Este directorio no existe\n" "en la instantánea seleccionada." #: qt/app.py:257 msgid "Add to Include" msgstr "Agregar a incluir" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Añadir a Excluidos" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} parece estar ejecutándose por primera vez ya que no se encuentra " "ninguna configuración." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "¿Quiere importar una configuración existente (desde un directorio de destino" " de copia de respaldo u otro equipo)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Si está en una unidad extraíble, conéctela y pulse Aceptar." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Tomar una instantánea" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Utiliza el tiempo de modificación y el tamaño para detectar cambios en los " "archivos." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Tomar una instantánea (en modo suma de verificación)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Utiliza sumas de verificación para detectar cambios en los archivos." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausar el proceso de instantánea" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Reanudar el proceso de instantáneas" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Parar el proceso de instantánea" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Actualizar lista de instantáneas" #: qt/app.py:497 msgid "Name snapshot" msgstr "Renombrar instantánea" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Eliminar instantánea" #: qt/app.py:505 msgid "View snapshot log" msgstr "Ver registro de instantánea" #: qt/app.py:509 msgid "View last log" msgstr "Ver último registro" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Perfil principal…" #: qt/app.py:517 msgid "Shutdown" msgstr "Apagar" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Apagar el sistema al terminar instantánea." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurar idioma…" #: qt/app.py:525 msgid "Exit" msgstr "Salir" #: qt/app.py:529 msgid "User manual" msgstr "Manual de utilización" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Abrir el manual de usuario en el navegador (localmente si está disponbile, " "si no en línea)" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Página man: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Muestra la página de manual sobre Back In Time (backintime)" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Página man: Archivo de configuración de perfiles" #: qt/app.py:543 #, fuzzy msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Mostrar la página man sobre Archivo de configuración de perfiles " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Sitio web del proyecto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Abrir en el navegador el sitio web de Back In Time" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Novedades" #: qt/app.py:555 msgid "FAQ" msgstr "Preguntas frecuentes" #: qt/app.py:557 #, fuzzy msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Abrir en el navegador las preguntas más frecuentes" #: qt/app.py:559 msgid "Ask a question" msgstr "Hacer preguntas" #: qt/app.py:563 msgid "Report a bug" msgstr "Informar de un problema" #: qt/app.py:566 msgid "Translation" msgstr "Traducción" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" "Muestra nuevamente el mensaje sobre la participación en la traducción." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transición de cifrado (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Muestra nuevamente el mensaje sobre la eliminación de EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurar" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Restaurar los archivos o carpetas seleccionadas a su destino original." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurar en…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Restaurar los archivos o carpetas seleccionados a un nuevo destino." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaura el directorio mostrado actualmente y todo su contenido al destino " "original." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaura el directorio mostrado actualmente y todo su contenido a un destino" " nuevo." #: qt/app.py:601 msgid "Up" msgstr "Arriba" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Mostrar archivos ocultos" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Comparar instantáneas…" #: qt/app.py:637 qt/app.py:2152 #, fuzzy msgid "Release Candidate" msgstr "Candidata para publicación" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "" "Muestra nuevamente el mensaje sobre esta versión candidata para publicación." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Copia de respaldo" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurar" #: qt/app.py:698 msgid "&Help" msgstr "&Ayuda" #: qt/app.py:743 msgid "Icons only" msgstr "Solamente iconos" #: qt/app.py:746 msgid "Text only" msgstr "Solamente texto" #: qt/app.py:749 msgid "Text below icons" msgstr "Texto bajo los iconos" #: qt/app.py:752 msgid "Text beside icon" msgstr "Texto junto a los iconos" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Si cierra la ventana, Back In Time no podrá apagar el sistema cuando se " "finalice la copia de respaldo." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "¿De verdad quiere cerrarla?" #: qt/app.py:1072 msgid "Working:" msgstr "Trabajando:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Hecho; no se necesita una copia de respaldo" #: qt/app.py:1129 msgid "Working" msgstr "En curso" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Error" #: qt/app.py:1161 msgid "Sent" msgstr "Enviado" #: qt/app.py:1162 msgid "Speed" msgstr "Velocidad" #: qt/app.py:1163 msgid "ETA" msgstr "Restante" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Administrador" #: qt/app.py:1227 msgid "Home" msgstr "Carpeta personal" #: qt/app.py:1255 msgid "Backup directories" msgstr "Directorios de copia de respaldo" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nombre de la instantánea" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "¿Confirma que quiere eliminar esta instantánea?" msgstr[1] "¿Confirma que quiere eliminar estas instantáneas?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Crear copias de respaldo con {suffix} al final\n" "antes de sobrescribir o eliminar elementos locales." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Las versiones más recientes de los archivos se restaurarán con la " "terminación {suffix}. Si ya no los necesita, puede eliminarlos con esta " "orden:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Solo restaura elementos que no existen o\n" "que son más recientes que los del destino.\n" "Se utiliza la opción «rsync --update»." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Eliminar los elementos más nuevos del directorio original." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaura los archivos o carpetas seleccionados al destino original y elimina" " los archivos o carpetas que no estén en la instantánea. Tenga mucho cuidado" " porque esto eliminará archivos y carpetas que se excluyeron durante la toma" " de la instantánea." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "¿Realmente quiere restaurar este elemento en el directorio nuevo?" msgstr[1] "" "¿Realmente quiere restaurar estos elementos en el directorio nuevo?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "¿Realmente quiere restaurar este elemento?" msgstr[1] "¿Realmente quiere restaurar estos elementos?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "¿Confirma que quiere eliminar todos los archivos más recientes en {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "¿Confirma que quiere eliminar todos los archivos más recientes del " "directorio original?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Atención{BOLDEND}: eliminar archivos en la raíz del sistema de " "archivos podría hacer que todo el sistema deje de funcionar." #: qt/app.py:1857 msgid "Snapshot" msgstr "Instantánea" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurar {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurar {path} en…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hola\n" "Ya has utilizado Back In Time en el idioma {language} unas cuantas veces.\n" "La traducción de su versión instalada de Back In Time al {language} está {perc} completa. Independientemente de su nivel de conocimientos técnicos, puede contribuir a la traducción y, por tanto, al propio Back In Time.\n" "Visite {translation_platform_url} si desea contribuir. Para más ayuda y preguntas, visite el {back_in_time_project_website}.\n" "Le pedimos disculpas por la interrupción, y este mensaje no se volverá a mostrar. Este diálogo está disponible en cualquier momento a través del menú de ayuda.\n" "Su equipo Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plataforma de traducciones" #: qt/app.py:2076 msgid "Website" msgstr "Sitio web" #: qt/app.py:2090 msgid "Your translation" msgstr "La traducción" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "En el Fediverso en Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Envíe un correo a {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Lista de correo {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} en la página web del proyecto." #: qt/app.py:2118 #, fuzzy msgid "Open an issue" msgstr "Abrir una incidencia" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "De forma alternativa, puede usar otro canal de su elección." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "La configuración de idioma solo surte efecto después de reiniciar Back In " "Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "La creación de perfiles EncFS se eliminará en la siguiente versión menor " "(1.7), programada para 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Ya no se recomienda utilizar ese modo para un perfil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "artículo" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS dejará de admitirse a causa de vulnerabilidades de seguridad." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Para conocer más detalles, incluyendo posibles alternativas, consulte este " "{whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "El siguiente perfil o perfiles utilizan cifrado con EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Hay un reemplazo programado, pero no hay garantía de que esté disponible a " "tiempo." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Los usuarios están invitados a participar en la discusión. Los detalles " "actualizados sobre los siguientes pasos están disponibles en {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Este mensaje no se volverá a mostrar. Este cuadro de diálogo está disponible" " en cualquier momento a través del menú de ayuda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "El equipo de Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Configurar el idioma" #: qt/languagedialog.py:97 msgid "System default" msgstr "Predeterminado del sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Utilizar el idioma del sistema operativo." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traducido: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Ver el último registro" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Ver registro de instantáneas" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Perfil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Instantáneas:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtrar:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Todo" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Cambios" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Errores" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Información" msgstr[1] "Informaciones" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Fallos en las transferencias rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Error, [I] Información, [C] Cambiar" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "descodificar rutas" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gestionar perfiles" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editar" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Añadir" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Quitar" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&General" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Incluir" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Incluir archivos y carpetas" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Añadir archivo" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Añadir directorio" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Excluir" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Información{ENDBOLD}: en el modo «Cifrado con SSH», solo funcionan los" " asteriscos simples o dobles (por ejemplo, {example2}). Se ignorarán otros " "tipos de comodines y patrones (por ejemplo, {example1}). Los nombres de " "archivo son impredecibles en este modo debido al cifrado de EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Excluir patrones, archivos o carpetas" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Agregar valor predeterminado" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Excluir archivos mayores que:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Excluir archivos mayores que el valor en {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Con el «modo rsync completo» desactivado, solo se impactarán los archivos " "nuevos, dado que, para rsync, esta es una opción de transferencia, no de " "exclusión. Por tanto, los archivos grandes que se hayan respaldado " "previamente se conservarán en las instantáneas, aunque se hayan modificado." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Elimina&r & retención" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opciones" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "A&justes avanzados" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restablecer configuración" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editar user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Perfil nuevo" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Cambiar nombre de perfil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "¿Confirma que quiere eliminar el perfil «{name}»?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Muy recomendable{ENDBOLD}: (Todas las recomendaciones ya incluidas.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Muy recomendable{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Excluir patrón" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Excluir archivo" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Excluir directorio" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Incluir archivo" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "«{path}» es un enlace simbólico. El destino enlazado no se incluirá en la copia de respaldo hasta que lo incluya también.\n" "¿Quiere incluir el destino del enlace simbólico en su lugar?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Incluir directorio" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Se desactivó porque este patrón no es funcional en el modo «Cifrado con " "SSH»." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Tareas programadas" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Día:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Día laborable:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tiempo:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Horas:" #: qt/manageprofiles/schedulewidget.py:86 #, fuzzy msgid "after the hour" msgstr "después de cada hora en punto" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutos:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Ejecute Back In Time en cuanto se conecte la unidad (sólo una vez cada X " "días). Se le pedirá su contraseña de sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Ejecuta Back In Time repetidamente. Esto es útil si el equipo no se está " "ejecutando regularmente." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Cada:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Activar el registro de mensajes de depuración" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Escribe mensajes de nivel de depuración en el registro del sistema mediante " "«--debug»." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Precaución: utilícelo solo temporalmente para diagnósticos, ya que genera " "una gran cantidad de salida." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Desactivado" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "En cada arranque/reinicio" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Cada {n} minuto" msgstr[1] "Cada {n} minutos" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Cada hora" msgstr[1] "Cada {n} horas" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Cada {n} hora" msgstr[1] "Cada {n} horas" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Horario personalizado" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Todos los días" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetidamente (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Cuando la unidad se conecta (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Semanalmente" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Mensualmente" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Anualmente" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hora(s)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Día(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semana(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mes(es)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Las horas personalizadas solo pueden ser una lista de horas separadas por " "comas (por ejemplo, 8,12,18,23) o */3 para copias de respaldo periódicas " "cada 3 horas." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Anfitrión:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Puerto:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usuario:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Conéctese al anfitrión de destino a través de este proxy (también conocido " "como anfitrión de salto). Consulte «-J» en la documentación de la orden " "«ssh» o «ProxyJump» en la página de manual «ssh_config» para obtener más " "detalles." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Precaución:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Estas opciones son para configuraciones avanzadas. Modifíquelas solamente si" " es plenamente consciente de las implicaciones." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Ejecutar «rsync» con «{cmd}»:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "como tarea cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "en un anfitrión remoto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "al tomar una instantánea manualmente" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Instale «nocache» para activar esta opción." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "en un equipo local" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirigir stdout a /dev/null en cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron enviará automáticamente un correo electrónico con la salida adjunta de " "cronjobs si hay un MTA instalado." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirigir stderr a /dev/null en cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron enviará automáticamente un correo electrónico con errores adjuntos de " "cronjobs si hay un MTA instalado." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "kB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limita el uso del ancho de banda de rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preservar ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preservar atributos extendidos (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Copiar vínculos incompletos (funciona solo con vínculos absolutos)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Restringir a un sistema de archivos" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Las opciones deben entrecomillarse, por ejemplo {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Pegar opciones adicionales a rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefijo para ejecutar antes de cada orden en el anfitrión remoto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Las variables deben codificarse con \\$FOO. Esto no afecta a rsync. Para " "añadir un prefijo a rsync utilice «{example_value}» con " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "predeterminado" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Añadir prefijo a órdenes SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Comprobar si el host remoto está en línea" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Advertencia: Si se desactiva y el host remoto no está disponible, esto " "podría dar lugar a algunos errores extraños." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Comprobar si el anfitrión remoto admite todas las órdenes necesarias." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Atención: si se desactiva y el anfitrión remoto no admite todas las órdenes " "necesarias, podrían producirse algunos errores extraños." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(predeterminado: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "desactivado" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "activado" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modo:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Dónde guardar las instantáneas" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Configuración de SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Ruta:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifrado:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Clave privada:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Elija un archivo de clave privada existente (normalmente llamado " "\"id_ed25519\", o \"id_rsa\" en configuraciones más antiguas)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Genera una nueva clave SSH sin contraseña (solo si aún no se ha seleccionado" " ningún archivo de clave privada)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Contraseña" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Guardar la contraseña en el llavero" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Prealmacenar contraseña para Cron (problema de seguridad: el superusuario " "puede leer la contraseña)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avanzado" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Ruta completa de la instantánea:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "No ha elegido un archivo de clave privada para SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "¿Desea generar un nuevo par de claves pública/privada sin contraseña?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "El archivo de clave privada «{file}» no existe." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "¿Le gustaría copiar su clave pública SSH en el anfitrión remoto para acceder" " sin contraseña?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "No se puede establecer la autenticidad del anfitrión {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "La huella digital de la clave {keytype} es:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verifique esta huella digital. ¿Quiere agregarla a su archivo «known_hosts»?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "¿Confirma que quiere cambiar el directorio de instantáneas?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Error al crear una nueva clave SSH en {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Activar notificaciones" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Desactivar instantáneas cuando se esté con batería" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "El estado de la energía no está disponible en el sistema" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Ejecutar solo una instantánea a la vez" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Las demás instantáneas se bloquearán hasta que finalice la instantánea " "actual. Esta es una opción global. Así que afectará a todos los perfiles de " "este usuario. Pero es necesario activar esto para todos los demás usuarios, " "también." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Respaldar los archivos reemplazados al restaurar" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Las versiones más recientes de los archivos se renombrarán con {suffix} al " "final antes de restaurarlos. Si ya no los necesita, puede eliminarlos con " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuar si hay errores (mantener imágenes incompletas)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Utilizar la suma de verificación (checksum) para detectar cambios" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Tome una nueva instantánea tanto si ha habido cambios como si no." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivel del registro:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ninguno" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Las reglas siguientes se procesan de arriba a abajo. Las últimas reglas " "sobreescriben las anteriores y no están restringidas por estas. Vea el " "{manual} para más detalles y ejemplos." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual de utilización" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Abrir el manual de utilización en el navegador." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Mantener la instantánea más reciente." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "La instantánea más reciente se conserva en cualquier circunstancia." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Ese comportamiento no se puede cambiar." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Conservar las instantáneas con nombre." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Las instantáneas que han recibido un nombre, además de la marca temporal " "habitual, se conservarán bajo cualquier circunstancia y no se eliminarán." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Año(s)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Eliminar las instantáneas anteriores a" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Días completos. El día actual se ignora." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Semanas de calendario empezando el lunes. La semana actual se ignora." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Periodos de 12 meses. El mes actual se ignora." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Directiva de retención" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Ejecutar en segundo plano en el anfitrión remoto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "El procedimiento de borrado inteligente se ejecutará directamente en la " "máquina remota, no localmente. Las órdenes «bash», «screen» y «flock» deben " "estar instaladas y disponibles en la máquina remota." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Se se marca, Back In Time comprobará primero la máquina remota." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Los días se empiezan a contar desde hoy." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Mantener todas las instantáneas hasta la última" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "día(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Conservar la última instantánea de cada día para los últimos" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Las semanas se empiezan a contar desde la semana actual. La semana empieza " "en lunes." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Conservar la última instantánea de cada semana para las últimas" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semana(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Los meses se empiezan a contar desde el mes actual." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Conservar la última instantánea de cada mes para los últimos" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mes(es)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Los años se cuenta como años de calendario desde el año actual." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Conservar la última instantánea de cada año para" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "todos los años." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... el espacio libre es inferior a" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... el número de inodos libres es inferior a" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Eliminar las instantáneas más antiguas si …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pregunta" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Perfil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Ver último registro" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Iniciar {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Trabajando…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Enviado:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocidad:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Tiempo restante estimado:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Instantáneas" #: qt/qttools.py:506 msgid "Today" msgstr "Hoy" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ayer" #: qt/qttools.py:522 msgid "This week" msgstr "Esta semana" #: qt/qttools.py:529 msgid "Last week" msgstr "Semana pasada" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Esto NO es una instantánea, sino una vista en directo de sus archivos " "locales" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Última comprobación {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importar configuración" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "No se ha encontrado ninguna configuración" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Seleccione la carpeta de instantáneas desde la que debe importarse el " "archivo de configuración. La ruta puede tener el siguiente aspecto " "{samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Si la carpeta se encuentra en una unidad externa o remota, debe montarse " "previamente de forma manual." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Mostrar registro completo" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opciones sobre la comparación de instantáneas" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parámetros:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Usar %1 y %2 para los parámetros de ruta" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Establezca una orden diff o pulse Cancelar." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "La orden «{cmd}» no se encuentra en este sistema. Intente otra cosa o pulse " "Cancelar." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "No hay parámetros establecidos para la orden diff. Se usará el valor " "predeterminado «{params}»." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Solo instantáneas diferentes" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Enumere solo instantáneas que sean iguales a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Comprobación rigurosa (más precisa, pero lenta)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Eliminar" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Seleccionar todo" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparar" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ir a" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opciones" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "No se puede comparar una misma instantánea." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "¿Realmente quiere eliminar {file} en la instantánea {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "¿Realmente quiere eliminar {file} en {count} instantáneas?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ADVERTENCIA: no se puede revocar." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "¿Excluir {path} de futuras instantáneas?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Las subcarpetas no pueden ser incluidas en la copia de seguridad." backintime-1.5.4/common/po/et.po000066400000000000000000002010571477034762000165240ustar00rootroot00000000000000# Estonian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-07 05:28+0000\n" "Last-Translator: Priit Jõerüüt \n" "Language-Team: Estonian \n" "Language: et\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Hoiatus" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Peamine profiil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Kohalik (krüptitud EncFS abil)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (krüptitud EncFS abil)" #: common/config.py:278 msgid "Local" msgstr "Kohalik" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privaatvõti" #: common/config.py:283 msgid "Local encrypted" msgstr "Kohalik krüptituna" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Krüptimine" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH krüptituna" #: common/config.py:296 msgid "Default" msgstr "Vaikimisi" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profiil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Hetktõmmiste kaust ei ole korrektne." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Varukoopia tegemiseks pead valima vähemalt ühe kausta." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Kaust: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Seda kausta ei saa kaasata varukoopiasse, kuna ta on osa varunduse " "sihtkaustast endast." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Uue crontabi loomine ei õnnestunud." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Kuigi käsk „crontab“ on saadaval, siis „cron“ ei ole töös ning seega " "ajastatud varukoopiate tegemine ei toimi. Võib-olla „cron“ on küll " "paigaldatud, aga pole sisse lülitatud. Proovi, kas käsust „systemctl enable " "cron“ on abi või pöördu abipalvega oma Linuxi versiooni tugitiimi poole." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Profiili „{profile_id}“ jaoks Udev'i reegli paigaldamine ei õnnestunud. " "DBus'i teenus „{dbus_interface}“ polnud kasutatav" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "{mode}-režiimis udev'i kasutamine ajastamiseks ei toimi" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "„{path}“ asukoha jaoks ei suuda tuvastada UUID-d" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Seadistuste salvestamine ei õnnestu" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Seadistuste laadimine ei õnnestu" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profiil „{name}“ on juba olemas." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Viimase profiili eemaldamine pole võimalik." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Haakimine pole võimalik: „{command}“" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Krüptitud kausta seadistusi ei õnnestu leida." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Kas loome uue krüptitud kausta?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Katkesta" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Palun korda salasõna." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Salasõnad ei klapi omavahel." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Tee hetktõmmis" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "„{mountprocess}“ lahtihaakimine asukohast „{mountpoint}“ ei õnnestu." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "„{command}“ käsku ei leidu. Palun paigalda ta (näiteks nii: " "„{installcommand}“)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "„{mntpoint}“ haakepunkt pole vaba." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Sisesta salasõna valitud profiili jaoks „{mode} - {profile}“:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "EBAÕNNESTUS" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Taasta õigused" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Valmis" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Viivitame varukoopia tegemist seni, kuni arvuti on akutoitel" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Ei õnnestu leida hetktõmmiste kausta." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Kui ta asub eemaldataval andmekandjal, siis palun ühenda see." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Ootame %s sekundi." msgstr[1] "Ootame %s sekundit." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Hetktõmmise nr {snapshot_id} tegemine ei õnnestunud." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Palun oota rahulikult. Lõpetame toimingut…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Ei saa luua kausta." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Salvestame seadistuste faili…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Salvestame õigusi…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Leidsime varasema hetktõmmise nr {snapshot_id}, mida saad täiendada." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Eemaldame varasemast ülejäänud hetktõmmise nr {snapshot_id} kausta" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Ei saa eemaldada kausta" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Teeme hetktõmmist" #: common/snapshots.py:1430 msgid "Success" msgstr "Õnnestus" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Vea tõttu on andmed vaid osaliselt kopeeritud" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Algsete failide kadumise tõttu on andmed vaid osaliselt kopeeritud " "(abiteabeks vaata „man rsync“)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "„rsync“ lõpetas töö veateatega {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Lisateavet leiad „man rsync“ käsuga" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Miinusmärgiga rsynci veateated on süsteemisignaalide numbrid, lisateavet " "leiad „kill -l“ ja „man kill“ käskudest" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Mitte midagi pole muutunud, uue hetktõmmise tegemine pole vajalik" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Asukoha „{path}“ uueks nimeks ei saa määrata „{new_path}“." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Nutikas eemaldamine" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Kehtesta vanade hetktõmmiste eemaldamise reeglid" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Kehtesta säilitamise reeglid" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Üritame jätta vabaks minimaalselt nõutava andmeruumi mahu" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Proovime jätta {perc} indekssõlmedest vabaks" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nüüd" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs} haakimine ei õnnestu" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "Programmi ssh-agent ei leidu. Palun kontrolli, et ta oleks paigaldatud." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Ssh privaatvõtme lukust lahtivõtmine ei õnnestunud. Salasõna oli kas vale " "või polnud croni jaoks leitav." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{cipher} šifti kasutamine hostis {host} ei õnnestunud." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Välisseadmes on asukoht olemas, kuid tegemist pole kaustaga." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Välisseadmes leiduv asukoht pole kirjutatav." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Välisseadmes leiduv asukoht pole käivitatav." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Ei saa luua välisseadmes asuvat kausta." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Väline seade „{host}“ ei toeta käsku „{command}“" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Lisateavet leiad käsuga „man backintime“" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kontrollkäsud hostis {host} andsid tulemuseks tundmatu vea" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Väline seade „{host}“ ei toeta püsilinke" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopeeri avalik ssh võti „{pubkey}“ välisesse seadmesse „{host}“." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Palun sisesta kasutaja „{user}“ salasõna." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Failisüsteem, mille asukohta „{path}“ tahad luua varukoopiat, on NTFS-" "vormingus ning teadaolevalt ei ühildu ta Unixi-stiilis failisüsteemidega." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} pole korrektne kausta." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Järgneva kausta loomine ei õnnestunud:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Kirjutusõigused võivad olla piiratud." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Failisüsteem, kuhu asukohta „{path}“ tahad luua varukoopiat, on FAT-" "vormingus ega toeta püsilinke. Palun kasuta mõnda Linuxile mõeldud " "failisüsteemi." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Failisüsteem, kuhu asukohta „{path}“ tahad luua varukoopiat, on SMB-põhisel " "andmekandjal. Palun kontrolli, et see SMB server toetab sümbollinkide " "kasutamist või seadistuste alajoatusest „{expertOptions}“ lülita sisse " "„{copyLinks}“." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopeeri lingid (eemalda sümbollinkide seosed)" #: common/tools.py:504 msgid "Expert Options" msgstr "Lisaseadistused asjatundjatele" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Failisüsteem, kuhu asukohta „{path}“ tahad luua varukoopiat, on haagitud " "sshfs abil. Kahjuks sshfs ei toeta püsilinke. Palun kasuta selle asemel SSH " "töörežiimi." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Faili loomine siia kausta ei õnnestunud:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Rakenduse teave" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autorid" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Tõlked" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Litsents" #: qt/app.py:172 msgid "Shortcuts" msgstr "Otseteed" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Seda kausta pole praegu\n" "valitud hetktõmmises olemas." #: qt/app.py:257 msgid "Add to Include" msgstr "Lisa kaasatavaks" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Lisa välistatavaks" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Kuna varasemat seadistust ei leidu, siis tundub, et {app_name} on kasutusel " "esimest korda." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Kas impordime olemasolevad seadistused (kas varukoopia sihtkaustast või " "muust arvutist)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Kui ta asub eemaldataval andmekandjal, siis palun ühenda see ja vajuta " "Sobib." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Tee hetktõmmis" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Muutuste tuvastamiseks kasuta muutmise aega ja faili suurust." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Tee hetktõmmis (kontrollsummadega)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Muutuste tuvastamiseks kasuta kontrollsummasid." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Peata hetktõmmise tegemine" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Jätka hetktõmmise tegemist" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Lõpeta hetktõmmise tegemine" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Uuenda hetktõmmiste loendit" #: qt/app.py:497 msgid "Name snapshot" msgstr "Anna hetktõmmisele nimi" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Eemalda hetktõmmis" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vaata hetktõmmiste logi" #: qt/app.py:509 msgid "View last log" msgstr "Vaata viimast logi" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Halda profiile…" #: qt/app.py:517 msgid "Shutdown" msgstr "Lülita välja" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Kui hetktõmmise tegemine on lõppenud, siis pane arvuti kinni." #: qt/app.py:521 msgid "Setup language…" msgstr "Seadista rakenduse keelt…" #: qt/app.py:525 msgid "Exit" msgstr "Välju" #: qt/app.py:529 msgid "User manual" msgstr "Kasutusjuhend" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Ava kasutusjuhend veebibrauseris (kui olemas, siis kohalikust arvutist, " "vastasel juhul võrgust)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "juhend käsureal: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Kuvab Back In Time'i juhendi käsureal (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "juhend käsureal: Profiilide seadistuste fail" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Kuvab Back In Time'i profiilide seadistuste faili juhendi käsureal " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projekti veebisait" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Ava Back In Time'i veebisait brauseriga" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Muudatuste logi" #: qt/app.py:555 msgid "FAQ" msgstr "KKK" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Ava korduma kippuvad küsimused (KKK) brauseriga" #: qt/app.py:559 msgid "Ask a question" msgstr "Esita küsimus" #: qt/app.py:563 msgid "Report a bug" msgstr "Teata veast" #: qt/app.py:566 msgid "Translation" msgstr "Tõlge" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Kuvab uuesti teate tõlkimises osalemise kohta." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Muudatused krüptimise kasutamisel (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Näitab uuesti teate EncFSi kasutusel eemaldamise kohta." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Taasta" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Taasta valitud failid või kaustad algupärasesse asukohta." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Taasta asukohta …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Taasta valitud failid või kaustad uude asukohta." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Taasta hetkel näidatud kaust koos kogu oma sisuga algupärasesse asukohta." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Taasta hetkel näidatud kaust koos kogu oma sisuga uude asukohta." #: qt/app.py:601 msgid "Up" msgstr "Üles" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Näita peidetud faile" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Võrdle hetktõmmiseid…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kandidaatversioon" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Näitab uuesti teadet kandidaatversiooni kohta." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Varukoopia" #: qt/app.py:692 msgid "&Restore" msgstr "Taa&sta" #: qt/app.py:698 msgid "&Help" msgstr "&Abi" #: qt/app.py:743 msgid "Icons only" msgstr "Ainult ikoonid" #: qt/app.py:746 msgid "Text only" msgstr "Ainult tekst" #: qt/app.py:749 msgid "Text below icons" msgstr "Tekst ikoonide all" #: qt/app.py:752 msgid "Text beside icon" msgstr "Tekst ikoonide kõrval" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Kui sa sulged selle akna, siis Back In Time ei suuda peale hetktõmmise " "tegemist sinu arvuti tööd lõpetada." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Kas sa oled kindel, et tahad selle sulgeda?" #: qt/app.py:1072 msgid "Working:" msgstr "Töötan:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Valmis, varukoopiat pole vaja teha" #: qt/app.py:1129 msgid "Working" msgstr "Töötan" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Viga" #: qt/app.py:1161 msgid "Sent" msgstr "Saadetud" #: qt/app.py:1162 msgid "Speed" msgstr "Kiirus" #: qt/app.py:1163 msgid "ETA" msgstr "Jäänud" #: qt/app.py:1225 msgid "Global" msgstr "Üleüldine" #: qt/app.py:1226 msgid "Root" msgstr "Juurkaust" #: qt/app.py:1227 msgid "Home" msgstr "Kodukaust" #: qt/app.py:1255 msgid "Backup directories" msgstr "Tagavarakoopia kaustad" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Hetktõmmise nimi" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Kas oled kindel, et soovid kustutada selle hetktõmmise?" msgstr[1] "Kas oled kindel, et soovid kustutada need hetktõmmised?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Enne kui kirjutad üle või kustutad kohalikud failid, kaustad ja muud objektid,\n" "tee koopiad, mille lõpus on „{suffix}“." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Enne taastamist teeme uuematest failidest koopia, mille lõpus on „{suffix}“." " Kui sa neid enam ei vaja, siis saad kõik korraga kustutada sellise käsuga:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Taasta ainult failid, kaustad ja muud objektid,\n" "mida pole olemas või on uuemad, kuid need, mis leiduvad siktkohas.\n" "Selleks kasutame „rsync --update“ võtit." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Eemalda algsest kaustast uuemad failid, kaustad ja muud objektid." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Taasta valitud failid ja kaustad algsesse asukohta ning kustuta failid ja " "kaustad, mis ei leidunud selles hetktõmmises. Kuna hetktõmmise tegemisel " "välistatud failid ja kaustad kuuluvad seetõttu kustutamisele, siis palun ole" " eriti ettevaatlik." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Kas sa oled kindel et soovid selle faili, kausta ja muu objekti taastada " "uude kausta?" msgstr[1] "" "Kas sa oled kindel et soovid need failid, kaustad ja muud objektid taastada " "uude kausta?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Kas sa oled kindel, et soovid taastada selle faili või kausta?" msgstr[1] "Kas sa oled kindel, et soovid taastada need failid või kaustad?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Kas sa oled kindel, et soovid eemaldada kõik uuemad failid asukohas " "„{path}“?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Kas sa oled kindel, et soovid eemaldada kõik uuemad failid oma algsest " "kaustast?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Hoiatus{BOLDEND}: failide kustutamine juurkaustast võib rikkuda kogu " "sinu arvuti failisüsteemi." #: qt/app.py:1857 msgid "Snapshot" msgstr "Hetktõmmis" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Taasta {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Taasta {path} asukohta …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Tere\n" "Sa oled nüüdseks juba kasutanud Back In Time'i {language} keeles mitmeid kordi.\n" "Sinu poolt paigaldatud Back In Time'i versiooni tõlge {language} keelde on {perc} valmis. Sõltumata sinu tehnilistest teadmistest, võid sa panustada tõlkesse ja seeläbi ka Back In Time'i enesesse.\n" "Kui soovid osaleda, siis palun külasta {translation_platform_url} veebilehte. Edasiseks toeks ja küsimusteks, palun vaata {back_in_time_project_website} lehte.\n" "Vabanda katkestuse pärast, ja seda sõnumit me ei näita enam uuesti. See dialoog on kättesaadav igal ajal läbi abimenüü.\n" "Sinu Back In Time meeskond" #: qt/app.py:2071 msgid "translation platform" msgstr "meie tõlkelahenduse" #: qt/app.py:2076 msgid "Website" msgstr "Veebisait" #: qt/app.py:2090 msgid "Your translation" msgstr "Sinu tõlge" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Födiversumis Mastodonis: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Saadad e-kirja {link_and_label} aadressile." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Saadad e-kirja postiloendisse {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} projekti veebisaidis." #: qt/app.py:2118 msgid "Open an issue" msgstr "Ava veateade" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Lisaks võid vaida ka mõne muu sinu eelistatud suhtluskanali." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "See Back In Time'i versioon on kandidaatversioon ning on eelkõige mõeldud stabiilsuse testimiseks enne lõpliku versiooni ilmumist.\n" "Me ei kogu kasutajate andmeid ega pruugi telemeetriat. Aga samas on Back In Time'i arendustiim on huvitatud teada saama, kas kandidaatversioonid leiavad üldse kasutust ning kas nende tegemine on üldse vajalik.\n" "Seetõttu tiim palun sult lühikest tagasisidet, kas sa oled seda versiooni testinud, seda ka siis kui phtegi probleemi ei tekkinud. Isegi kiire testkäivitus mõneks minutiks aitaks meid märgatavalt.\n" "Meiega saad ühendust võtta alljärgnevalt:\n" "{contact_list}\n" "Ntud sõnumit selles versioonis enam ei kuvata, aga on alati leitav abiteabe menüüst.\n" "Täname sind osalemise eest ning abi eest Back In Time'i parandamisel!\n" "Sinu Back In Time'i tiim" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Keelevalikud jõustuvad vaid Back In Time'i uuesti käivitamisel." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "EncFS profiili loomise võimalus eemaldatakse järgmisest versioonist (1.7), " "mis on plaanitud 2026. aastaks." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Pealegi me ei soovita selle režiimi kasutamist mitte üheski profiilis." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "dokumendist" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS tugi lõppeb temaga seotud turvavigade tõttu." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Lisateavet, sealhulgas alternatiivide kohta, leiad siit: {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Järgmised profiilid kasutavad krüptimist EncFSiga:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Me oleme kavandanud ka asenduse, aga pole kindel, et jõuame sellega valmis " "õigeks ajaks." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Kutsume kasutajaid osalema teemakohases arutelus. Uuendatud üksikasjad " "järgmiste sammude kohta on kirjas siin: {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Seda teadet me enam ei näita, aga sa võid ta alati abiteabe menüüst uuesti " "avada." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Sinu Back In Time'i tiim" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Seadista rakenduse keelt" #: qt/languagedialog.py:97 msgid "System default" msgstr "Süsteemi määratud keel" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Kasuta operatsioonisüsteemi keelevalikut." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Tõlkimise osakaal: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Viimane logivaade" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Hetktõmmiste logivaade" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profiil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Hetktõmmised:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Kõik" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Muutused" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Veateated" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Teave" msgstr[1] "Teave" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync-käsu kopeerimiste vead (katseline)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] viga, [I] teave, [C] muudatus" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekodeeri asukohad" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Halda profiile" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Muuda" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Lisa" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Eemalda" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "Ü&ldine" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Kaasa" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Kaasa failid ja kaustad" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Lisa fail" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Lisa kaust" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Jäta välja" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Lisateave{ENDBOLD}: Kui töörežiimiks on „SSH krüptituna“, siis " "toimivad vaid ühe- ja kahekordsed tärnid (näiteks: {example2}). Muud " "metamärgid ja mustrid ei ole kasutusel (näiteks: {example1}). Kuna kasutusel" " on krüptimine EncFSiga, siis selles režiimis on failide nimed " "ettearvamatud." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Jäta välja mustrid, failid või kaustad" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Lisa vaikimisi valikud" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Jäta välja failid, mis on suuremad, kui:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Jäta välja failid, mis on suuremad, kui {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Kui töörežiim „Täiemahuline sünkroniseerimine rsynci abil“ pole kasutusel, " "siis see eelistus mõjutab vaid uusi faile (tegemist on failide liigutamise " "eelistusega, mitte välistamise eelistusega). Seetõttu varem varundatud " "suured failid jäävad hetktõmmistesse ja siis, kui neid on hiljem muudetud." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Eemaldamine ja säilitamine" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Valikud" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Ek&sperdi valikud" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Taasta seadistused" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Muuda kasutajapoolset tagasikutset" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Uus profiil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Muuda profiili nime" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Oled kindel, et tahad kustuda profiili „{name}“?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Tungivalt soovitatav{ENDBOLD}: (Kõik soovitused on juba kaasatud.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Soovitame tungivalt{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Jäta välja mustri alusel" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Jäta välja fail" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Jäta välja kaust" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Kaasa fail" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„{path}“ on sümbollink. Lingi sihtkausta või -faili ei varundata seni, kuni sa pole teda kaasanud.\n" "Kas sa sooviksid selle asemel kaasata sihtkausta või -faili?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Kaasa kaust" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Kuna selline muster pole režiimis „SSH krüptituna“ funktsionaalne, siis " "eelistus on välja lülitatud." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Ajakava" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Päev:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Nädalapäev:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Aeg:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Tunnid:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "pärast tundi" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuteid:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Käivita Back In Time niipea, kui andmekandja on ühendatud (vaid üks kord X " "päeva jooksul). Käivitamisel küsime sudo salasõna." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Käivita Back In Time'i korduvalt. Sellest valikust on kasu, kui arvuti pole " "pidevalt sisse lülitatud." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Iga:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Kasuta silumisteadete logimist" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Selle eelistuse valimisel salvestame „--debug“ võtmega logisse " "silumisteateid." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Hoiatus: kuna see eelistus tekitab märgatava logimagu, siis kasuta seda vaid" " ajutiselt diagnostikaks või veaotsinguks." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Välja lülitatud" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Igal käivitamisel/taaskäivitamisel" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Iga {n} minuti järel" msgstr[1] "Iga {n} minuti järel" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Kord tunnis" msgstr[1] "Iga {n} tunni järel" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Iga {n} tunni järel" msgstr[1] "Iga {n} tunni järel" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Kohandatud tunnid" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Iga päev" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Korduvalt (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Kui andmekandja on ühendatud (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Iga nädal" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Iga kuu" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Iga aasta" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Tund/tunnid" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Päev(a)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Nädal(at)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Kuu(d)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Kui soovid enda poolt tunde täpsustada, siis kasuta komadega eraldatud " "loendit (näiteks 8,12,18,23) või */3 tüüpi märgistust (viimases näites " "tehakse varukoopia iga kolme tunni järel)." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH proksi" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Kasutaja:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Ühenduseks välise seadmega kasuta seda proksit (tuntud ka hüppeserverina). " "Vaata „ssh“ käsu juhendist „-J“ võtit või „man ssh_config“ juhendist " "„ProxyJump“ lõiku." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Hoiatus:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Need eelistused on mõeldud asjatundjatele ja keerukamate kasutusjuhtumite " "jaoks. Muuda neid ainult siis, kui täpselt tead, mida teed." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Käivita „rsync“ käsuga „{cmd}“:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "kasutades ajastamist croniga" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "välises seadmes" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "kui teed hetktõmmist käsitsi" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Selle eelistuse kasutamiseks palun paigalda „nocache“." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "kohalikus arvutis" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" "Croniga ajastatud tööde puhul suuna standardväljund nulli (stdout > " "/dev/null)." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Kui e-kirjade edastamine on seadistatud, siis cron saadab automaatselt " "kirja, mille manuseks on croni tehtud töö väljund." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" "Croniga ajastatud tööde puhul suuna standardviga nulli (stderr > /dev/null)." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Kui e-kirjade edastamine on seadistatud, siis cron saadab automaatselt " "kirja, mille manuseks on croni tehtud töös tekkinud vead." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Piira rsync'i ribalaiust:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Säilita pääsuloend (ACL)" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Säilita failide laiendatud metainfo (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopeeri ebaturvalised lingid (toimib vaid absoluutsete linkide puhul)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Piirdu ühe failisüsteemiga" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Lisatingimused peavad olema jutumärkide vahel, näiteks {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Lisa rsync-ile täiendavad suvandeid" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Välises seadmes käivita iga käsu ees see prefiks." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Muutujad peavad olema tähistatud $FOO paomärkidega. See ei käi rsynci kohta." " Seega, lisamaks rsyncile prefikseid kasuta „{example_value}“ koos " "„{rsync_options_value}“." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "vaikimisi" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Lisa SSH käsule eesliiteid" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Kontrolli, kas väline seade on võrgus" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Hoiatus: kui see eelistus on välja lülitatud ja väline seade pole võrgus, " "siis võib tekkida imelikke vigu." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Kontrolli, kas väline seade võimaldab kõikide vajalike käskude kasutamist." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Hoiatus: kui see eelistus on välja lülitatud ja väline ei toeta kõiki " "vajalikke käske, siis võib tekkida imelikke vigu." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(vaikimisi: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "pole kasutusel" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "kasutusel" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Töörežiim:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kuhu salvestame hetktõmmised" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH seadistused" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Asukoht:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šiffer:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privaatvõti:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Vali olemasolev privaatvõtme fail (tavaliselt nimega „id_ed25519“ kuid " "vanemates seadistustes pigem nimega „id_rsa“)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Loo uus ilma salasõnata ssh võti (see pole lubatud, kui privaatvõti on juba " "valitud)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Salasõna" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Salvesta salasõna tarkvaralises võtmerõngas" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Puhverda salasõna croni jaoks (See on ka turvaprobleem: juurkasutajal on " "võimalik salasõna lugeda)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Täiendavad seadistused" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Hetktõmmiste täpne asukoht:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Sa pole valinud ssh jaoks privaatvõtit." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Kas sa sooviksid luua uue salasõnata võtmepaari (privaatvõti/avalik võti)?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privaatvõtmefaili „{file}“ pole olemas." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Kas sa soovid kopeerida oma avaliku ssh võtme välisesse seadmesse ja sellega" " võtta kasutusele salasõnata sisselogimise?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Hosti „{host}“ autentsust pole võimalik tuvastada." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} võtme sõrmejälg on:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Palun kontrolli, et tegemist on õige sõrmejäljega. Kas sa sooviksid teda " "lisada ka „known_hosts“ faili?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Kas oled kindel, et soovid muuta hetktõmmiste kausta?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Uue SSH võtme loomine asukohta „{path}“ ei õnnestunud." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Luba teavitused" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Kui arvuti on akutoitel, siis ära tee hetktõmmiseid" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Toitesüsteemi oleks pole siin arvutis tuvastatav" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Tee korraga vaid üks hetktõmmis" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Muude hetktõmmiste tegemine on seni blokeeritud, kuni hetkel pooleli olev " "hetktõmmis on tehtud. See on rakenduse üldine eelistus ja seega mõjutab " "selle kasutaja kõiki profiile. Aga sa pead ta aktiveerima kõikide kasutajate" " puhul." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Taastamisel tee asendatud failidest varukoopia" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Enne taastamist muudetakse failide nimesid lisades neile suffiksi " "„{suffix}“. Kui sa neid faile enam ei vaja, siis võid nad eemaldada käsuga " "„{cmd}“" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Vigade puhul jätka tööd (säilita poolikud hetktõmmised)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Muutuste tuvastamiseks kasuta kontrollsummat" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" "Tee uus hetktõmmis hoolimata sellest, kas arvutis tekkis muutusi või mitte." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Logitase:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Määramata" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Järgnevaid reegleid töödeldakse suunaga ülevalt alla. Hilisemad reeglid " "alati asendavad varasemaid ega ole varasemaist kuidagi mõjutatud. " "Üksikasjade ja näidete teave leidub {manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "kasutusjuhendis" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Ava kasutusjuhend veebibrauseris." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Säilita viimane hetktõmmis." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "Viimane ja kõige värskem hetktõmmis säilib igal juhul." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Seda reeglit pole mitte kuidagi võimalik muuta." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Ära kustuta nimedega hetktõmmiseid." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Hetktõmmised, millel lisaks tavapärasele ajatemplile on eraldi nimi, jäävad " "kõikides olukordades alles ega kuulu kustutamisele." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Aasta(t)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Eemalda hetktõmmised, mis on vanemad kui" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Täispäevades ja tänane päev ei lähe arvesse." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Esmaspäevaga algavates kalendrinädalates ja see nädal ei lähe arvesse." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12-kuulistes ajavahemikes ja praegune kuu ei lähe arvesse." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Säilitamise reeglid" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Käivita välises seadmes taustal." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Nutikas kustutamine töötab otseselt välisseadmes, mitte kohaliku seadmes. " "Selleks peavad välisseadmes olema paigaldatud „bash“, „screen“ ja „flock“." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Kui valitud, siis Back In Time esmalt testib välisseadet." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Päevi loendame alates tänasest." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Säilita kõik hetktõmmised viimase" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "päeva kestel." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Säilita viimane hetktõmmis iga päeva kohta viimase" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "Nädalaid loendame alates sellest nädalast. Nädal algab esmaspäevaga." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Säilita viimane hetktõmmis iga nädala kohta viimase" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "nädala jooksul." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Kuid loendame kalendrikuudena alates sellest kuust." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Säilita viimane hetktõmmis iga kuu kohta viimase" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "kuu kestel." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Aastaid loendame kalendriaastatena alates sellest aastast." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Säilita viimane hetktõmmis iga aasta kohta" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "läbi aastate." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… kui vaba ruumi on vähem kui" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… kui vabu indekssõlmesid on vähem kui" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Eemalda vanimad hetktõmmised, kui…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Palun vasta küsimusele" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profiil: „{profile_name}“" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Vaata viimast logi" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Käivita {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Töötan…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Saadetud:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Kiirus:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Jäänud:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Hetktõmmised" #: qt/qttools.py:506 msgid "Today" msgstr "Täna" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Eile" #: qt/qttools.py:522 msgid "This week" msgstr "Sel nädalal" #: qt/qttools.py:529 msgid "Last week" msgstr "Eelmisel nädalal" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "See EI OLE hetktõmmis, vaid sinu kohaliku failisüsteemi failide tegelik " "vaade" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Viimati kontrollitud {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Impordi seadistused" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Seadistusi ei leidu" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Impordi" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Vali hetktõmmiste kaust, kust soovid seadistuste faili importida. Asukoht " "võiks olla midagi sellist: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Kui vastav kaust asub välisel andmekandjal või kaugseadmes, siis esmalt " "palun haagi ta käsitsi." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Näita tervet logi" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Hetktõmmiste võrdlemise valikud" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Käsk:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parameetrid:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Asukoha parameetritena kasuta „%1“ ja „%2“" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Palun seadista „diff“ käsk või vajuta „Katkesta“." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Käsku „{cmd}“ ei leidu selles seadmes. Palun proovi midagi muud või vajuta " "„Katkesta“." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Diff käsu parameetrid puuduvad. Kasutan vaikimisi väärtust „{params}“." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Vaid siis, kui hetktõmmised erinevad" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Näita vaid hetktõmmiseid, mis võrduvad järgnevaga:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Põhjalik kontroll (palju täpsem, aga ka aeglasem)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Kustuta" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Vali kõik" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Võrdle" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Mine" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Valikud" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Sa ei saa võrrelda hetktõmmist iseendaga." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Kas sa kindlasti soovid kustutada „{file}“ hetktõmmises nr {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" "Kas sa kindlasti soovid kustutada „{file}“ kokku {count}s hetktõmmises?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "HOIUATUS: seda tegevust ei saa tagasi pöörata." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Kas soovid välistada tulevastest hetktõmmistest asukoha „{path}“?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Neid alamkaustu ei saa kaasata varukoopiasse." backintime-1.5.4/common/po/eu.po000066400000000000000000001766631477034762000165430ustar00rootroot00000000000000# Basque translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-18 06:33+0000\n" "Last-Translator: buhtz \n" "Language-Team: Basque \n" "Language: eu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Abisua" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profil nagusia" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokala (EncFS zifratua)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS zifratua)" #: common/config.py:278 msgid "Local" msgstr "Lokala" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH giltz pribatu" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalki zifratua" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Zifraketa" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH zifratua" #: common/config.py:296 msgid "Default" msgstr "Lehenetsia" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profila: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Babeskopien karpeta ez da baliozkoa." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Gutxienez direktorio bat hautatu behar da babeskopia egiteko." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Direktorioa: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Karpeta hau ezin da babeskopian sartu babeskopiaren helburu beraren zatia " "baita." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Huts egin du crontab berria idazten." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron ez da exekutatzen crontab agindua eskuragarri egon arren. " "Programatutako babeskopia lanak ez dira exekutatuko. Baliteke Cron " "instalatuta egotea baina gaituta ez egotea. Saiatu \"systemctl enable cron\"" " komandoa edo kontsultatu zure GNU Linux banaketaren laguntza kanalak." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Ezin izan da Udev araua instalatu {profile_id} profilarentzat. " "'{dbus_interface}' DBus zerbitzua ez zegoen erabilgarri" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Programatutako Udev-a ez dabil {mode} moduarekin" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Ezin da UUID aurkitu \"{path}\"-erako" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Huts egin du ezarpenak gordetzen" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Huts egin du ezarpenak kargatzen" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "\"{name}\" profila badago honezkero." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Ezin da azken profila kendu." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "'{command}' ezin da muntatu" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Zifratutako karpetaren ezarpenak ez dira aurkitu." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Karpeta zifratu berri bat sortu?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Utzi" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Egiaztatu pasahitza mesedez." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Pasahitzak ez datoz bat." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Egin babeskopia" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Ezin da {mountprocess} desmuntatu {mountpoint}-tik." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} ez da aurkitu. Mesedez instalatu (adibidez \"{installcommand}\"ren" " bidez)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "{mntpoint} muntatze-puntua ez dago hutsik." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Idatzi {mode} \"{profile}\" profilaren pasahitza:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "HUTS EGIN DU" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Leheneratu baimenak" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Eginda" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Atzeratu babeskopia bateriaz dabilen bitartean" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Ezin da aurkitu babeskopien karpeta." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Unitate eramangarri batean badago konekta ezazu." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Itxaroten segundo %s ." msgstr[1] "Itxaroten %s segundo." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Huts egin du {snapshot_id} babeskopia egiten." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Mesedez, izan pazientzia. Amaitzen…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Ezin da karpeta sortu." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Gorde ezarpenen fitxategia…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Baimenak gordetzen…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "'{snapshot_id}' jarraitu daitekeen soberakina aurkitu da." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Azken exekuziotik '{snapshot_id}' karpeta soberakina kentzen" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Ezin da karpeta ezabatu" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Babeskopia egiten" #: common/snapshots.py:1430 msgid "Success" msgstr "Ongi" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transferentzia partziala errorea dela eta" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferentzia partziala desagertutako iturburu-fitxategiengatik (ikus 'man " "rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "\"rsync\" amaitu da irteera-kode honekin {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Ikus 'man rsync' xehetasun gehiagorako" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Rsync irteera kode negatiboak seinale zenbakiak dira, ikusi 'kill -l' eta " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ez dago aldaketarik. Ez da babeskopia berririk egin behar" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Ezin zaio {new_path}-(r)i {path} izena jarri." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Ezabatze adimenduna" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Aplikatu babeskopia zaharrak ezabatzeko arauak" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Aplikatu atxikipen politika" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Saiatu espazio minimoa mantentzen" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Saiatu gutxienez {perc} nodo libre mantentzen" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Orain" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Ezin da {sshfs} muntatu" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent ez da aurkitu. Ziurtatu instalatuta dagoela." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Ezin da SSH-ren gako pribatua desblokeatu. Okerreko pasahitza edo cron-" "entzat baliozkoa ez den pasahitza." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{cipher} zifraketak huts egin du {host}rentzat." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Urrutiko bide-izena badago baina ez da direktorio bat." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Urrutiko bide-izenak ez dauka idazteko baimenik." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Urrutiko bide-izena ez da exekutagarria." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Ezin da sortu urrutiko bide-izena." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Urruneko {host} ostalariak ez du {command} onartzen" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Begiratu 'man backintime' azalpenak ikusteko" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "{host} ostalariaren egiaztatzeko komandoek errore ezezaguna itzuli dute" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "{host} urrutiko ostalariak ez ditu esteka gogorrak onartzen" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopiatu \"{pubkey}\" ssh-gako publikoa \"{host}\" urrutiko ostalarira." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Sartu \"{user}\"-entzako pasahitza bat." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "'{path}'-(r)en helburuko fitxategi-sistemaren formatua NTFS da. NTFS ezaguna" " da Unix estikoko fitxategi-sistemekin konpatibilitate arazoak izatearren." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} ez da direktorio balido bat." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Ezin izan da hurrengo direktorioa sortu:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Baliteke idazteko sarbidea mugatuta egotea." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "'{path}'-(r)en helburuko fitxategi-sistemaren formatua FAT da eta ez du " "esteka gogorrik onartzen. Erabili Linux jatorriko fitxategi-sistema bat." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "'{path}'-(r)en helburuko fitxategi-sistema SMB-ez muntatutako partekatutako " "karpeta da. Egiaztatu urruneko SMB zerbitzariak esteka sinbolikoak onartzen " "dituela edo gaitu '{copyLinks}' '{expertOptions}'-en." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiatu estekak (erreferentzia kendu esteka sinbolikoei)" #: common/tools.py:504 msgid "Expert Options" msgstr "Aukera aurreratuak" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "'{path}'-(r)en helburuko fitxategi-sistema sshfs-ez muntatutako " "partekatutako karpeta da. sshfs-ek ez du esteka gogorrik onartzen. Erabili " "'SSH' haren ordez." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Ezin izan da fitxategia sortu direktorio honetan:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Honi buruz" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Egileak" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Itzulpenak" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lizentzia" #: qt/app.py:172 msgid "Shortcuts" msgstr "Lasterbideak" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Karpeta hau ez da existitzen\n" "une honetan hautatutako babeskopian." #: qt/app.py:257 msgid "Add to Include" msgstr "Gehitu sartu beharrekoetan" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Gehitu kanpoan utzi beharrekoetan" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} lehen aldiz exekutatzen ari dela dirudi, ez baita konfiguraziorik" " aurkitzen." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Lehendik dagoen konfigurazio bat inportatu (babeskopia batetik edo beste " "ordenagailu batetik)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Unitate eramangarri batean badago konekta ezazu eta sakatu Ados." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Egin babeskopia" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Erabili denbora eta tamaina aldaketak fitxategi-aldaketak hautemateko." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Egin babeskopia (kontrol baturarekin)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Erabili kontrol-batura aldaketak detektatzeko." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausatu babeskopia prozesua" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Laburtu babeskopia prozesua" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Gelditu babeskopia prozesua" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Freskatu babeskopien zerrenda" #: qt/app.py:497 msgid "Name snapshot" msgstr "Izendatu babeskopia" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Kendu babeskopia" #: qt/app.py:505 msgid "View snapshot log" msgstr "Ikusi babeskopiaren erregistroa" #: qt/app.py:509 msgid "View last log" msgstr "Ikusi azken erregistroa" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Kudeatu profilak…" #: qt/app.py:517 msgid "Shutdown" msgstr "Itzali" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Itzali sistema babeskopia bukatu ondoren." #: qt/app.py:521 msgid "Setup language…" msgstr "Konfiguratu hizkuntza…" #: qt/app.py:525 msgid "Exit" msgstr "Irten" #: qt/app.py:529 msgid "User manual" msgstr "Erabiltzailearen eskuliburua" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Ireki erabiltzailearen eskuliburua nabigatzailean (tokikoa eskuragarri " "badago bestela lineakoa)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man orria: Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Back In Time-ren man orria erakusten du (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man orria: profilen konfigurazio fitxategia" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Konfigurazio fitxategien gaineko man orria erakusten du (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Proiektuaren webgunea" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Ireki Back In Time-ren webgunea nabigatzailean" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Aldaketen egunkaria" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Ireki ohiko galderak (FAQ) nabigatzailean" #: qt/app.py:559 msgid "Ask a question" msgstr "Zerbait galdetu" #: qt/app.py:563 msgid "Report a bug" msgstr "Akats baten berri eman" #: qt/app.py:566 msgid "Translation" msgstr "Itzulpena" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Itzulpenean parte hartzeari buruzko mezua erakusten du berriro." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Enkriptazio-trantsizioa (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "EncFS kentzeari buruzko mezua erakusten du berriro." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Berreskuratu" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Leheneratu hautatutako fitxategiak eta karpetak jatorrizko kokalekura." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Leheneratu hona …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" "Leheneratu hautatutako fitxategiak eta karpetak kokaleku berri batera." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Leheneratu erakutsitako karpetak eta haien eduki guztia jatorrizko " "kokalekura." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Leheneratu une honetan erakusten den direktorioa eta bere eduki guztia " "kokaleku berri batera." #: qt/app.py:601 msgid "Up" msgstr "Gora" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Erakutsi ezkututko fitxategiak" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Konparatu babeskopiak…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Askatzeko bertsio hautagaia" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Bertsio hautagai honi buruzko mezua erakusten du berriro." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Babeskopia" #: qt/app.py:692 msgid "&Restore" msgstr "&Leheneratu" #: qt/app.py:698 msgid "&Help" msgstr "L&aguntza" #: qt/app.py:743 msgid "Icons only" msgstr "Ikonoak bakarrik" #: qt/app.py:746 msgid "Text only" msgstr "Testua bakarrik" #: qt/app.py:749 msgid "Text below icons" msgstr "Testua ikonoen azpian" #: qt/app.py:752 msgid "Text beside icon" msgstr "Testua ikonoen ondoan" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Leiho hau ixten baduzu Back In Time-k ezin izango du zure sistema itzali " "babeskopia bukatzean." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Ziur zaude itxi nahi duzula?" #: qt/app.py:1072 msgid "Working:" msgstr "Lanean:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Egina, ez da babeskopia egin behar" #: qt/app.py:1129 msgid "Working" msgstr "Lanean" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Errorea" #: qt/app.py:1161 msgid "Sent" msgstr "Bidalita" #: qt/app.py:1162 msgid "Speed" msgstr "Abiadura" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "Orokorra" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Hasiera" #: qt/app.py:1255 msgid "Backup directories" msgstr "Babeskopia direktorioak" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Babeskopiaren izena" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Seguru zaude babeskopia ezabatu nahi duzula?" msgstr[1] "Seguru zaude babeskopiak ezabatu nahi dituzula?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Egin babeskopia bukaerako '{suffix}'\n" "fitxategi lokalak gainidatzi edo ezabatu aurretik." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Fitxategien bertsio berriak berrizendatuko dira '{suffix}' kokapenarekin " "leheneratu baino lehen. Ez badituzu gehiago behar ezabatu ditzakezu honako " "aginduarekin:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Leheneratu soilik falta diren fitxategiak edo\n" "helburuko tokikoak baino berriagoak direnak.\n" "\"rsync --update\" aukera erabiliz." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Ezabatu jatorrizko karpetako fitxategirik berrienak." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Leheneratu hautatutako fitxategiak edo karpetak jatorrizko kokalekura eta " "ezabatu babeskopian ez dauden fitxategi edo karpetak. Kontu handiz egin, " "honek babeskopia egitean baztertutako fitxategi eta karpetak ezabatuko ditu." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Seguru zaude elementu hau karpeta berrian leheneratu nahi duzula?" msgstr[1] "" "Seguru zaude fitxategi hauek karpeta berrian leheneratu nahi dituzula?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ziur zaude fitxategi hau berreskuratu nahi duzula?" msgstr[1] "Ziur zaude fitxategi horiek berreskuratu nahi dituzula?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Ziur {path}-ko fitxategi berri guztiak kendu nahi dituzula?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Seguru zaude jatorrizko karpetatik berriagoak diren fitxategi guztiak " "ezabatu nahi dituzula?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}KONTUZ{BOLDEND}: fitxategi-sistemaren erroko fitxategiak ezabatzeak " "sistema osoa hondatu dezake." #: qt/app.py:1857 msgid "Snapshot" msgstr "Babeskopia" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Berreskuratu {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Leheneratu {path} hona…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Kaixo\n" "Dagoeneko hainbat aldiz erabili duzu Back In Time aplikazioa {language} hizkuntzan.\n" "Instalatuta duzun Back In Time-ren bertsioaren {language}-zko itzulpenaren {perc} eginda dago. Itzulpena egiten lagundu zenezake eta modu horretan Back In Time lagunduko duzu, jakintza teknikorik izan gabe.\n" "Bisitatu {translation_platform_url} ekarpenak egin nahi badituzu. Laguntza edo galderak badituzu, bisitatu {back_in_time_project_website}.\n" "Barkatu eragozpenak, mezu hau ez da berriro agertuko. Mezu hau berriz ikusi dezakezu laguntza menua erabiliz.\n" "Zure Back In Time taldea" #: qt/app.py:2071 msgid "translation platform" msgstr "Itzulpenetarako plataforma" #: qt/app.py:2076 msgid "Website" msgstr "Webgunea" #: qt/app.py:2090 msgid "Your translation" msgstr "Zure Itzulpena" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Fedibertsoko Mastodonen: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Mezu elektronikoa {link_and_label} helbidera." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Posta-zerrenda {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} proiektuaren webgunean." #: qt/app.py:2118 msgid "Open an issue" msgstr "Arazo baten berri eman" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Bestela, nahi duzun kanala erabil dezakezu." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Back In Time-ren bertsio hau hautagaia da eta hurrengo bertsio ofizialerako prestatzeko egonkortasun-probak egiteko da.\n" "Ez da erabiltzailearen daturik edo telemetriarik biltzen. Hala ere, Back In Time taldeari asko interesatzen zaio Release Candidate erabiltzen ari ote den eta ea merezi duen jakitea aurreko bertsioak ematen jarraitzea.\n" "Hori dela eta, taldeak iritzi labur bat eskatzen dizu bertsio hau probatu duzun ala ez jakiteko, nahiz eta arazorik ez aurkitu. Minutu gutxiko proba azkar batek ere asko lagunduko liguke.\n" "Harremanetarako aukera hauek daude eskuragarri:\n" "{contact_list}\n" "Bertsio honetan, mezu hau ez da berriro erakutsiko, baina edonoiz atzi dezakezu laguntza-menuaren bidez.\n" "Eskerrik asko zure laguntzagatik eta Back In Time hobetzen laguntzeagatik!\n" "Zure Back In Time taldea" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Hizkuntza-ezarpenek Back In Time berrabiarazi ondoren bakarrik izango dute " "eragina." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Encfs profila sortzea 2026rako programatutako hurrengo bertsio txikian (1.7)" " kenduko da." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Ez da gomendagarria modu hori erabiltzea profil baterako." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "orri zuria" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Encfs-en laguntza eten egin da segurtasun ahuleziak direla medio." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Xehetasun gehiago lortzeko, balizko alternatibak barne, ikus {whitepaper} " "hau." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Profil hau(ek) EncFS enkriptatzea erabiltzen dute:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Ordezkapen bat aurreikusten da, baina ezin da bermatu garaiz iritsiko denik." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Erabiltzaileak eztabaida honetara gonbidatuta daude. Hurrengo urratsetan " "eguneratutako xehetasunak eskuragarri daude {whitepaper} honetan." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Mezu hau ez da berriro erakutsiko. Elkarrizketa hau edozein unetan " "eskuragarri dago laguntza menuaren bidez." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Zure Back In &Time taldea" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Konfiguratu hizkuntza" #: qt/languagedialog.py:97 msgid "System default" msgstr "Sistemak lehenetsia" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Erabili sistema eragileen hizkuntza." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Itzulia: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Azken erregistroaren ikuspegia" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Babeskopiaren erregistro ikuspegia" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profila:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Babeskopiak:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Iragazi:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Guztiak" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Aldaketak" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Akatsak" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informazioa" msgstr[1] "Informazioak" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync transferentzia akatsak (esperimentala)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Errorea, [I] Informazioa, [C] Aldaketa" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekodetu bide-izenak" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Kudeatu profilak" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editatu" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Gehitu" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Kendu" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Orokorra" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Sartu" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Fitxategiak eta karpetak barne" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Gehitu fitxategia" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Gehitu direktorioa" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Kanpoan utzi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informazioa{ENDBOLD}:'SSH enkriptatutako' moduan, izartxo bakunak edo " "bikoitzak baino ez dute funtzionatzen (adibidez, {example2}). Beste komodin " "eta ereduei ez ikusi egingo zaie (adibidez, {example1}). Fitxategi-izenak ez" " dira aurreikusten modu honetan, EncFS-k enkriptatutakoaren ondorioz." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Baztertu txantiloi, fitxategi edo direktorio hauek" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Gehitu lehenetsia" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Utzi kanpoan hau baino handiagoak diren fitxategiak:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Utzi kanpoan {size_unit} baino handiagoak diren fitxategiak." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "'rsync osoko modua' desgaituta badago horrek fitxategi berriei soilik " "eragingo die zeren eta rsync-entzat hori transferentzia aukera bat da, ez " "baztertze aukera bat. Beraz babeskopia lehendik egina zituzten fitxategi " "handiak mantenduko dira irudian nahiz eta aldaketak jasan." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Ezabatu atxikipena" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Aukerak" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "A&ukera aurreratuak" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Leheneratu konfigurazioa" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editutatu erabiltzailearen atzeradeia" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Profil berria" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Berrizendatu profila" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Seguru zaude \"{name}\" profila ezabatu nahi duzula?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Oso gomendagarria{ENDBOLD}: (Gomendio guztiak dagoeneko sartuta.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Oso gomendagarria{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Baztertu txantiloia" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Baztertu fitxategia" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Baztertu direktorioa" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Sartu fitxategia" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" esteka sinboliko bat da. Estekatutako objektuaren babeskopia ez da egingo are eta bera ere gehitu arte.\n" "Nahi duzu gehitu esteka sinbolikoen helburu-objektuak?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Sartu direktorioa" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Desgaituta dago eredu hau ez delako funtzionala \"SSH enkriptatutako\" " "moduan." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Programaketa" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Eguna:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Asteguna:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Ordua:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Orduak:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "orduaren ondoren" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutuak:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Exekutatu Back In Time unitatea konektatu bezain pronto (X egunean behin " "bakarrik). Zure sudo pasahitza eskatuko zaizu." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Erabili Back In Time behin eta berriz. Egin bereziki ordenagailua ez badabil" " ongi." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Bakoitza:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Gaitu arazketa-mezuen erregistroa" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Arazketa-mailako mezuak idazten ditu sistemaren erregistroan \"--debug\" " "bidez." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Kontuz: diagnostikoetarako soilik erabili aldi baterako, irteera kopuru " "handia sortzen baitu." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Ezgaituta" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Abiatze/berrabiaratze guztietan" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "minutu {n}etik behin" msgstr[1] "{n} minututik behin" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Orduro" msgstr[1] "{n} orduro" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} orduero" msgstr[1] "{n} orduero" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Ordu pertsonalizatuak" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Egunero" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Behin eta berriz (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Unitatea konektatzean (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Astero" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Hilero" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Urtero" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Ordu" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Egun(ak)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "aste" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Hilabete" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Ordu pertsonalizazuak komaz banatutako ordu-zerrenda izan daiteke bakarrik " "(adib. 8,12,18,23) edo */3 hiru orduz behin babeskopia egiteko." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxya" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Ostalaria:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Ataka:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Erabiltzailea:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Konektatu xede-ostalarira proxy honen bidez (jauzi-ostalari gisa ere " "ezaguna). Ikus \"-J\" \"ssh\" komandoaren dokumentazioan edo \"ProxyJump\" " "\"ssh_config\" man orrialdean xehetasunetarako." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Kontuz:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Aukera hauek konfigurazio aurreratuetarako dira. Aldatu soilik haien " "ondorioez guztiz jabetzen bazara." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Exekutatu 'rsync' '{cmd}'-rekin:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "programatutako ataza bezala" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "urrutiko ostalarian" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "eskuzko babeskopia egitean" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Mesedez, instalatu 'nocache' aukera hau gaitzeko." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "ordenagailuan bertan" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Birzuzendu stdout /dev/null-era cronjob-etan." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron-ek automatikoki bidaliko du mezu elektroniko bat cronjob-en irteera " "erantsia MTA instalatuta badago." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Birzuzendu stderr /dev/null-era cronjob-etan." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron-ek automatikoki bidaliko du mezu elektroniko bat cronjob-en akatsak " "erantsita MTA instalatuta badago." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/seg" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Mugatu rsync-en banda-zabaleraren erabilera:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Mantendu ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Mantendu atributu hedatuak (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopiatu esteka inseguruak (egin bakarrik esteka absolutuekin)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Mugatu fitxategi-sistema batera" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Aukerak kakotxen artean idatzi, esate baterako {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Itsatsi aukera gehigarriak rsync-eri" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" "Urruneko ostalariaren komando bakoitzaren aurretik exekutatzeko aurrizkia." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Aldagaiak \\$FOO bidez alde egin behar dute. Honek ez dio eragiten rsync-i. " "Beraz rsync erabili dezan aurrizki bat gehitzeko erabili \"{example_value}\"" " {rsync_options_value}-rekin." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "lehenetsia" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Gehitu aurrizkia SSH komandoei" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Markatu urrutiko ostalaria linean badago" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Kontuz: desgaitzen baduzu eta urrutiko ostalaria ezin bada erabili, " "ustekabeko erroreak sor daitezke." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Probatu urrutiko ostalariak behar diren komando guztiak onartzen dituen." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Kontuz: desgaitzen baduzu eta urrutiko ostalariak behar diren komando " "guztiak onartzen ez baditu, ustekabeko erroreak sor daitezke ." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(default: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "ezgaituta" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "gaituta" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modua:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Non gorde babeskopiak" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH ezarpenak" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Bide-izena:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Zifratu:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Gako pribatua:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Aukeratu lehendik dagoen gako pribatuaren fitxategi bat (normalean " "\"id_ed25519\" izena du eta konfigurazio zaharretan \"id_rsa\" )." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Sortu SSH gako berri bat pasahitzik gabe (ez da onartzen gako pribatuaren " "fitxategi bat dagoeneko hautatuta badago)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Pasahitza" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Gorde pasahitza" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Cron-entzako cache-pasahitza (Segurtasun akatsa: root-ek pasahitza irakur " "dezake)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Aurreratua" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Babeskopiaren bide osoa:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Ez duzu gako pribatuko fitxategirik aukeratu SSHrako." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Nahi al duzu pasahitzik gabeko gako publiko/pribatu parea sortzea?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "\"{file}\" gako pribatuko fitxategirik ez dago." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Nahi al duzu kopiatzea zure SSH gako publikoa urrutiko ostalarira pasahitzik" " gabe sartu ahal izateko?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Ezin da egiaztatu \"{host}\" ostalariaren benetakotasuna." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} gakoaren hatz-marka hau da:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Egiaztatu hatz-marka! Nahi al duzu bera gehitzea zure 'known_hosts' " "fitxategira?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Ziur zaude aldatu nahi duzula babeskopien direktorioa?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Huts egin du {path} kokalekuan SSH gako berria sortzen." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Gaitu notifikazioak" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Ezgaitu babeskopiak egitea bateriaz funtzionatzean" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Energia egoera ez dago eskurtagarri sistemarentzat" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Egin babeskopia bat aldiko" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Beste babeskopiak blokeatuko dira oraingo babeskopia egiten den bitartean. " "Hau aukera globala da, beraz, erabiltzaile honen profil guztiei eragiten " "die. Baina beste erabiltzaileentzat aktibatu behar da ere." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Egin berreskurapenean ordeztutako fitxategien babeskopia" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Berriagoak diren fitxategiak berrizendatuko dira '{suffix}' kokapenarekin " "leheneratu baino lehen. Ez badituzu gehiago behar ezabatu ditzakezu " "'{cmd}'-rekin" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Jarraitu erroreak egon arren (mantendu babeskopia osatu gabea)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Erabili kontrol-batura aldaketak detektatzeko" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Egin babeskopia berria aldaketarik izan ote den kontuan izan gabe." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Erregistro maila:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ezer Ez" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Hurrengo arauak goitik behera prozesatzen dira. Azken arauek aurrekoak " "gainidazten dituzte eta ez dira haiek mugatuta. Ikusi {manual} -eko " "xehetasunak eta adibideak." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "erabiltzailearen eskuliburua" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Ireki erabiltzailearen eskuliburua nabigatzailean." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Mantendu duela gutxiko babeskopiak." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Azken irudia, freskoena alegia, zirkunstantzia guztietan mantentzen da." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Portaera hori ezin da aldatu." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Mantendu izena duten babeskopiak." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Ohiko denbora-zigiluaz gain, izena eman zaien babeskopia-irudiak ez dira " "ezabatuko." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "urtez" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Kendu hau baino zaharragoak diren babeskopiak" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Egun osoak. Uneko eguna ez da kontuan hartzen." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Egutegiko asteak astelehena lehen eguna dela. Uneko astea ez da kontuan " "hartzen." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 hilabeteko tarteak. Uneko hilabetea ez da kontuan hartzen." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Atxikipen politika" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Exekutatu urrutiko ostalariaren atzeko planoan." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Kentzeko prozedura adimenduna zuzenean urruneko makinan exekutatuko da, ez " "lokalean. \"bash\", \"screen\" eta \"flock\" komandoak instalatu eta " "eskuragarri egon behar dira urruneko makinan." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Hautatzen bada, Back In Time-k urruneko makina probatuko du lehenik." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Egunak gaur hasita kontatzen dira." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Mantendu babeskopia guztiak" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "eguna(k)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Mantendu eguneko babeskopia bana azkeneko" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Asteak kontatzen dira uneko astean hasita. Astea astelehenean hasten da." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Mantendu asteko babeskopia bana azkeneko" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "astea(k)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Hilabeteak egutegiko hilabete gisa kontatzen dira, uneko hilabetean hasita." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Mantendu hilabeteko babeskopia bana azkeneko" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "hilabeta(k)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Urteak egutegiko urte gisa kontatzen dira uneko urtean hasita." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Mantendu urteko babeskopia bana azkeneko" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "urte guztiak." #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "toki librea hau baino txikiagoa bada:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "... nodo libreak hauek baino gutxiago badira:" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Babeskopia zaharrenak ezabatu baldin eta …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Galdera" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profila: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Ikusi azken erregistroa" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Hasi {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Lanean…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Bidalita:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Abiadura:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Babeskopiak" #: qt/qttools.py:506 msgid "Today" msgstr "Gaur" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Atzo" #: qt/qttools.py:522 msgid "This week" msgstr "Aste honetan" #: qt/qttools.py:529 msgid "Last week" msgstr "Joan den astean" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Hau EZ da babeskopia bat zure fitxategi lokalen ikuspegia baizik" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Azken kontrola {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Inportatu konfigurazioa" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Ez da ezarpenik topatu" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Inportatu" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Hautatu konfigurazio fitxategia inportatu behar den babeskopien direktorioa." " Bidea honelakoa izan daiteke: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Direktorioa kanpoko edo urruneko disko batean badago, eskuz muntatu behar da" " aldez aurretik." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Erakutsi erregistro osoa" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Irudiak alderatzeko aukerak" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Komandoa:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametroak:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Erabili %1 eta %2 bide-izenen parametroetarako" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Ezarri diff komando bat edo sakatu Utzi." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "\"{cmd}\" komandoa ezin da aurkitu sistema honetan. Saiatu beste zerbait edo" " sakatu Utzi." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Ez da parametrorik ezarri diff komandorako. \"{params}\" balio lehenetsia " "erabiltzen." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Babeskopia desberdinak soilik" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Zerrendatu bakarrik berdinak diren babeskopiak hona:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Egiaztatze sakona (zehaztasun handiagoa, baina motela)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Ezabatu" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Hautatu denak" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Konparatu" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Joan hona" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Aukera" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Ezin duzu alderatu babeskopia bat bere buruarekin." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Ziur zaude \"{snapshot_id}\" babeskopiako \"{file}\" fitxategia ezabatu nahi" " duzula?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" "Ziur zaude {count} babeskopiako \"{file}\" fitxategia ezabatu nahi duzula?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "KONTUZ: Honek ez dauka atzera bueltarik." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Baztertu {path} hurrengo babeskopietan?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Azpikarpetak ezin dira babes kopian sartu." backintime-1.5.4/common/po/fa.po000066400000000000000000002256131477034762000165060ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the Back In Time package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Back In Time 1.3.4-dev\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 09:08+0000\n" "Last-Translator: Mahmood Rohani \n" "Language-Team: Persian \n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.10.2\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "هشدار" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "نمایه اصلی" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "محلی (رمزنگاری شده با EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (رمزنگاری شده با EncFS)" #: common/config.py:278 msgid "Local" msgstr "محلی" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "کلید خصوصی SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "رمزنگاری شده محلی" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "رمزنگاری" #: common/config.py:289 msgid "SSH encrypted" msgstr "رمزنگاری شده با SSH" #: common/config.py:296 msgid "Default" msgstr "پیشفرض" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "نمایه: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "پوشه برگرفت‌ها معتبر نیست." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "بابد حداقل یک مسیر برای پپشتیبان‌گیری انتخاب شود." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "پوشه: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "این پوشه چون خودش بخشی از مقصد پشتیبان‌گیری است نمی‌توان در پشتیبان قرار " "داد." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "نوشتن کرونتب جدید شکست خورد." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron با وجود در دسترس بودن دستور crontab اجرا نمی شود. کارهای پشتیبان برنامه" " ریزی شده اجرا نمی شوند. Cron ممکن است نصب شده باشد اما فعال نباشد. دستور " "\"systemctl enable cron\" را امتحان کنید یا با پشتیبانی توزیع گنو/لینوکس خود" " مشورت کنید." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "نتوانست قوانین Udev را برای نمایه {profile_id} نصب کند. سامانه دی‌باس(DBus) " "'{dbus_interface}' در دسترس نبود" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "برنامه‌ریزی udev با حالت {mode} کار نمی‌کند" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "UUID برای \"{path}\" پیدا نشد" #: common/configfile.py:101 msgid "Failed to save config" msgstr "ذخیره پیکربندی شکست خورد" #: common/configfile.py:137 msgid "Failed to load config" msgstr "بارگذاری پیکربندی شکست خورد" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "نمایه \"{name}\" از قبل وجود دارد." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "آخرین نمایه را نمیتوان پاک کرد." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "نمی‌توان '{command}' را متصل کرد" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "پیکربندی برای پوشه رمز‌گذاری‌شده پیدا نشد." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "آیا میخواهید یک پوشه رمز‌گذاری شده جدید بسازید؟" #: common/encfstools.py:146 msgid "Cancel" msgstr "لغو" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "لطفاً رمز عبور را تایید کنید." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "کلمه‌عبور مطابقت ندارد." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "گرفتن اسنپ‌شات" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "نمی‌توان {mountprocess} را از {mountpoint} جدا کرد." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command} پیدا نشد، لطفا آن را نصب کنید (مثلا با \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "مونت‌پوینت ‮{mntpoint} خالی نیست." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "برای نمایهٔ {mode} «{profile}» رمز وارد کنید:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "شکست خورد" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "بازگردانی دسترسی ها" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "تمام" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "به تعویق انداختن پشتیبان گیری در هنگام باتری" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "نمی‌توان پوشه برگرفت‌ها را پیدا کرد." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "اگر بر روی یک درایو قابل جابجایی است، لطفا آن را وصل کنید." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "برای %s ثانیه باید منتظر ماند." msgstr[1] "صبر برای %s ثانیه." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "گرفتن اسنپ‌شات {snapshot_id} شکست خورد." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "خواهشمند است شکیبا باشید. گام پایانی…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "نمی‌توان پوشه ساخت." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "درحال ذخیره فایل پیکر‌بندی…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "در حال ذخیره دسترسی‌ها…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "یک برگرفته باقی‌مانده ({snapshot_id}) پیدا شد که می‌تواند ادامه یابد." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "حذف کردن پوشه‌ای {snapshot_id} رها شده‌ از آخرین اجرا" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "نمیتوان پوشه را حذف کرد" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "در حال گرفتن اسنپ‌شات" #: common/snapshots.py:1430 msgid "Success" msgstr "موفق" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "انتقال جزئی به دلیل خطا" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "انتقال جزئی به دلیل فایل‌های منبع ناپدید شده (به \"man rsync\" مراجعه کنید)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' با کد خروج {exit_code} به پایان رسید" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "برای جزئیات بیشتر به \"man rsync\" مراجعه کنید" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "کدهای خروجی منفی rsync شماره سیگنال هستند، به \"kill -l\" و \"man kill\" " "مراجعه کنید" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "چیزی تغییر نیافت، اسنپ‌شات ضروری جدیدی نیست" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "نمی‌توان {new_path} را به {path} تغییر نام داد." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "حذف هوشمند" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "درحال پاک کردن برگرفته‌های قدیمی" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "اعمال کردن سیاست نگهداری" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "درحال تلاش برای نگهداری حداقل فضای آزاد" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "در حال تلاش برای نگهداری حداقل {perc} آزاد inodeها" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "الان" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "امکان سوار کردن {sshfs} وجود ندارد" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent پیدا نشد. لطفا از نصب بودن آن مطمئن شوید." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "کلید خصوصی پوستهٔ امن باز نشد. رمز عبور اشتباه است یا این‌که برای کرون " "رمزعبور موجود نیست." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "متن رمز {cipher} برای {host} شکست خورد." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "مسیر ریموت وجود دارد اما یک دایرکتوری نیست." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "مسیر ریموت قابل نوشتن نیست." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "مسیر ریموت قایل اجرا نیست." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "نمی‌توان پوشه ریموت ساخت." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "مسیر ریموت {host} دستور {command} را پشتیبانی نمیکند" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "برای دستورالعمل های بیشتر به \"man backintime\" مراجعه کنید" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "بررسی دستورات روی میزبان {host} خطای ناشناخته ای را نشان داد" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "میزبان ریموت {host} از هاردلینک‌ها پشتیبانی نمی کند" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "کپی کردن کلید عمومی \"SSH \"{pubkey} را به میزبان راه دور \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "لطفاً رمز عبور را برای \"{user}\" وارد کنید." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "فایل سیستم مقصد برای {path} با قالب NTFS فرمت شده است که دارای ناسازگاری‌های" " شناخته‌شده‌ای با سیستم‌ فایل‌های شبه یونیکس است." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} یک پوشه‌ی معتبر نیست." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "ایجاد پوشه‌ی زیر ناموفق بود:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "شاید نوشتن در دسترسی نباشد." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "فایل سیستم مقصد برای {path} با قالبFAT فرمت شده است که پیوندهای سخت را " "پشتیبانی نمیکند. لطفا یک فایل سیستم بومی لینوکس را به کار ببرید." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "سیستم فایل مقصد برای {path} یک اشتراک سوار شده از طریق SMB است. لطفا اطمینان" " حاصل کنید که سرور SMB راه دور از پیوند‌های نمادین پشتیبانی میکند یا گزینه " "\"{copyLinks}\" را در \"{expertOptions}\" فعال کنید." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "کپی کردن لینک ها(لینک‌های نمادین متفاوت)" #: common/tools.py:504 msgid "Expert Options" msgstr "گزینه های حرفه‌ای" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "فایل‌سیستم مقصد برای {path} یک اشتراک سوار شده از طریق SSHFS است. SSHFS از " "پیوندهای سخت پشتیبانی نمیکند. لطفا از حالت \"SSH\" استفاده کنید." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "ایجاد پرونده در این پوشه ناموفق بود:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "درباره" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "نویسندگان" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "مترجم‌ها" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "پروانه" #: qt/app.py:172 msgid "Shortcuts" msgstr "میانبرها" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "این پوشه\n" "در برگرفته انتخاب شده فعلی وجود ندارد." #: qt/app.py:257 msgid "Add to Include" msgstr "اضافه کردن به شامل‌ها" #: qt/app.py:259 msgid "Add to Exclude" msgstr "اضافه کردن به استثناها" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "به نظر می‌رسد که {app_name} برای اولین بار اجرا می‌شود زیرا هیچ پیکربندی‌ای " "یافت نشد." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "یک پیکربندی موجود را وارد میکنید (از یک پوشه‌ی مقصد پشتیبان یا از رایانه‌ای " "دیگر)؟" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "اگر روی یک درایو قابل جابجایی است، لطفا آن را وصل کنید و سپس روی \"تأیید\" " "کلیک کنید." #: qt/app.py:470 msgid "Take a snapshot" msgstr "گرفتن اسنپ‌شات" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "از زمان و اندازه اصلاح برای تشخیص تغییر فایل استفاده کنید." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "گرفتن اسنپ‌شات (حالت چک‌سام)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "از چک‌سام برای شناسایی تغییرات استفاده کن." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "توقف پروسه اسنپ‌شات" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "ادامه پروسه اسنپ‌شات" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "لغو پروسه اسنپ‌شات" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "تازه‌سازی فهرست اسنپ‌شات" #: qt/app.py:497 msgid "Name snapshot" msgstr "نام‌بردن اسنپ‌شات" #: qt/app.py:501 msgid "Remove snapshot" msgstr "حذف اسنپ‌شات" #: qt/app.py:505 msgid "View snapshot log" msgstr "مشاهده لاگ اسنپ‌شات" #: qt/app.py:509 msgid "View last log" msgstr "مشاهده آخرین لاگ" #: qt/app.py:513 msgid "Manage profiles…" msgstr "مدیریت نمایه‌ها…" #: qt/app.py:517 msgid "Shutdown" msgstr "خاموش" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "بعد از تمام شدن اسنپ‌شات سیستم را خاموش کن." #: qt/app.py:521 msgid "Setup language…" msgstr "زبان راه‌اندازی…" #: qt/app.py:525 msgid "Exit" msgstr "خروج" #: qt/app.py:529 msgid "User manual" msgstr "راهنمای کاربر" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "باز کردن راهنمای کاربر در مرورگر ( اگر موجود باشد محلی در غیر این صورت " "آنلاین)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Back In Time - صفحه‌ی راهنما" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "نمایش صفحه‌ راهنمای مربوط به Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "صفحه‌ راهنما: پرونده پیکربندی نمایه‌ها" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "نمایش صفحه‌ راهنمای مربوط به پرونده پیکربندی نمایه‌ها (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "وبگاه پروژه" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "باز کردن وبگاه Back In Time در مرورگر" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "لاگ تغییرات" #: qt/app.py:555 msgid "FAQ" msgstr "سوالات متداول" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "باز کردن سوالات متداول در مرورگر" #: qt/app.py:559 msgid "Ask a question" msgstr "سوال بپرس" #: qt/app.py:563 msgid "Report a bug" msgstr "گزارش اشکال" #: qt/app.py:566 msgid "Translation" msgstr "ترجمه" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "دوباره پیام درمورد مشارکت در ترجمه را نشان می‌دهد." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "تبدیل رمزگذاری (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "دوباره پیام در مورد پاک شدن EncFS نشان می‌دهد." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "بازگردانی" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "پرونده‌ها یا پوشه‌های انتخاب شده را به مقصد اصلی بازگردان." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "بازگردانی به …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "پرونده‌ها یا پوشه‌های انتخاب شده را به مقصد جدید بازگردان." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "پوشه نمایش داده شده فعلی و تمام محتویات آن را به مقصد اصلی بازگردان." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "پوشه نمایش داده شده فعلی و تمام محتویات آن را به یک مقصد جدید بازیابی کن." #: qt/app.py:601 msgid "Up" msgstr "بالا" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "نمایش فایل های مخفی" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "مقایسه اسنپ‌شات‌ها…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "نامزد انتشار" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "پیام مربوط به این نامزد انتشار را دوباره نمایش بده." #: qt/app.py:676 msgid "Back In &Time" msgstr "برگشت در زمان" #: qt/app.py:681 msgid "&Backup" msgstr "&پشتیبان‌گیری" #: qt/app.py:692 msgid "&Restore" msgstr "&بازگردانی" #: qt/app.py:698 msgid "&Help" msgstr "&کمک" #: qt/app.py:743 msgid "Icons only" msgstr "فقط نمادها" #: qt/app.py:746 msgid "Text only" msgstr "فقط متن" #: qt/app.py:749 msgid "Text below icons" msgstr "متن زیر نمادها" #: qt/app.py:752 msgid "Text beside icon" msgstr "متن کنار نماد" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "اگر شما این پنجره را ببندید، Back In Time دیگر قادر نیست که رایانه شما را " "بعد از تمام شدن اسنپ‌شات خاموش کند." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "آیا از بستن این مورد مطمئنید؟" #: qt/app.py:1072 msgid "Working:" msgstr "در حال انجام:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "تامام، پشتیبان‌گیری لازم نیست" #: qt/app.py:1129 msgid "Working" msgstr "درحال انجام" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "خطا" #: qt/app.py:1161 msgid "Sent" msgstr "فرستاده‌شده" #: qt/app.py:1162 msgid "Speed" msgstr "سرعت" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "جهانی" #: qt/app.py:1226 msgid "Root" msgstr "ریشه" #: qt/app.py:1227 msgid "Home" msgstr "خانه" #: qt/app.py:1255 msgid "Backup directories" msgstr "پوشه‌های پشتیبان" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "نام اسنپ‌شات" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "آیا از پاک کرد این اسنپ‌شات مطمئنید؟" msgstr[1] "آیا از پاک کردن این اسنپ‌شات‌ها مطمئنید؟" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "پشتیبان‌هایی با پسوند {suffix} را\n" "قبل از بازنوشتن یا حذف کردن عناصر محلی ایجاد کن." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "نسخه‌های جدیدتر از فایل‌ها با دنباله {suffix} قبل از بازگردانی تغییر نام " "داده خواهند شد. اگر دیگر به آن احتیاجی ندارید، میتوانید آن را با دستور زیر " "حذف کنید:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "تنها عناصری که وجود ندارند\n" "یا جدید‌تر از معادلشان در مقسد هستند را بازیابی کن.\n" "با استفاده از قابلیت \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "عناصر جدیدتر را در پوشه اصلی حذف کن." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "بازیابی پرونده‌ها یا پوشه‌های انتخاب‌شده به مقصد اصلی و حذف پرونده‌ها یا " "پوشه‌هایی که در برگرفته‌ها وجود ندارند. بسیار محتاط باشید، زیرا این عملیات " "پرونده‌ها و پوشه‌هایی را که در هنگام گرفتن برگرفته مستثنا شده بودند، حذف " "خواهد کرد." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "آیا واقعا می‌خواهید این عنصر را درون پوشه جدید بازیابی کنید؟" msgstr[1] "آیا واقعا می‌خواهید این عناصر را درون پوشه جدید بازیابی کنید؟" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "آیا از بازگرداندن این مورد مطمئنید؟" msgstr[1] "آیا از بازگرداندن این موارد مطمئنید؟" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "آیا شما مطمئنید که میخواهید تمامی فایل های جدیدتر را در {path} حذف کنید؟" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "آیا مطمئن هستید که میخواهید تمامی پرونده‌های جدیدتر را در پوشه اصلی خود حذف " "کنید؟" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}هشدار{BOLDEND}: حذف کردن پرونده‌ها در سامانه‌پرونده ریشه می‌تواند کل " "سامانه شما را خراب کند." #: qt/app.py:1857 msgid "Snapshot" msgstr "اسنپ‌شات" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "بازگرداندن {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "بازگرداندن {path} به …" # ignore-placeholder-compare #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "سلام\n" "شما تاکنون چندین بار از Back In Time به زبان {language} استفاده کرده‌اید.\n" "ترجمه‌ی نسخه‌ی نصب‌شده‌ی Back In Time به این زبان {perc}٪ تکمیل شده است. صرف‌نظر از میزان دانش فنی شما، می‌توانید در ترجمه و بهبود Back In Time مشارکت کنید.\n" "اگر مایل به همکاری هستید، لطفا به {translation_platform_url} مراجعه کنید. برای دریافت راهنمایی‌های بیشتر و طرح سوالات، می‌توانید به وبگاه پروژه {back_in_time_project_website} سر بزنید.\n" "از وقفه پیش‌آمده پوزش می‌طلبیم. این پیام دیگر نمایش داده نخواهد شد اما هر زمان از طریق منوی راهنما قابل دسترسی است.\n" "تیم Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "سکوی ترجمه" #: qt/app.py:2076 msgid "Website" msgstr "وبسایت" #: qt/app.py:2090 msgid "Your translation" msgstr "ترجمه شما" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "در فداییورس در ماستودون: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "ایمیل به {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "فهرست ایمیل: {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} در وبگاه پروژه." #: qt/app.py:2118 msgid "Open an issue" msgstr "باز کردن یک مشکل جدید" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "همچنین شما میتوانید از کانال دیگری از انتخاب خود استفاده کنید." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "این نسخه از Back In Time یک نامزد انتشار است و عمدتا برای آزمایش پایداری به‌منظور آماده‌سازی برای انتشار رسمی بعدی ارائه شده است.\n" "هیچ داده‌ی کاربری یا اطلاعات تله‌متری جمع‌آوری نمی‌شود. بااین‌حال، تیم Back In Time مشتاق است بداند آیا این نسخه‌ی آزمایشی در حال استفاده است و آیا ادامه‌ی انتشار چنین نسخه‌هایی ارزشمند خواهد بود.\n" "بنابراین، تیم ما از شما تقاضا دارد بازخوردی کوتاه ارائه دهید و اطلاع دهید که آیا این نسخه را آزمایش کرده‌اید، حتی اگر هیچ مشکلی مشاهده نکرده باشید. حتی یک اجرای آزمایشی چند دقیقه‌ای نیز کمک بزرگی برای ما خواهد بود.\n" "راه‌های ارتباطی زیر در دسترس هستند:\n" "{contact_list}\n" "در این نسخه، این پیام دیگر نمایش داده نخواهد شد اما هر زمان از طریق منوی راهنما قابل دسترسی خواهد بود.\n" "از حمایت شما سپاسگزاریم و خوشحالیم که در بهبود Back In Time کمک می‌کنید!\n" "تیم Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "تنظیمات زمان تنها بعد از خارج و وارد شدن از Back In Time تاثیر گذار هستند." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "ایجاد پروفایل EncFS در نسخه‌ی جزئی بعدی (1.7)، که برای سال 2026 برنامه‌ریزی " "شده است، حذف خواهد شد." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "استفاده از این حالت برای یک نمایه دیگر توصیه نمی‌شود." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "اوراق سفید" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "پشتیبانی از EncFS به دلیل آسیب‌پذیری‌های امنیتی متوقف می‌شود." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "برای جزئیات بیشتر، از جمله گزینه‌های جایگزین، لطفاً به این {whitepaper} " "مراجعه کنید." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "نمایه(های) زیر از رمزنگاری با EncFS استفاده می‌کنند:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "جایگزینی برنامه‌ریزی شده است، اما نمی‌توان تضمین کرد که به‌موقع آماده شود." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "از کاربران دعوت می‌شود تا در این بحث شرکت کنند. جزئیات به‌روز شده درباره‌ی " "مراحل بعدی در این {whitepaper} موجود است." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "این پیام دیگر نشان داده نخواهد شد. این دیالوگ در هر زمانی از طریق منوی " "راهنما قابل دستیابی است." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "از طرف تیم برگشت در زمان" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "انتخاب زبان" #: qt/languagedialog.py:97 msgid "System default" msgstr "پیش‌فرض سیستم" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "استفاده از زبان سیستم عامل." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "ترجمه شده: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "آخرین نمای لاگ" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "نمای لاگ اسنپ‌شات" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "نمایه:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "برگرفته‌ها:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "پالایش:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "همه" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "تغییرات" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "خطاها" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "اطلاعات" msgstr[1] "آگاهی" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "خطا‌های انتقال rsync‌ (آزمایشی)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] خطا، [I] اطلاعات، [C] تغییرات" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "رمزگشایی مسیرها" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "مدیریت نمایه‌ها" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "ویرایش" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "اضافه" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "حذف" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "کلی" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "شامل" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "پرونده‌ها و پوشه‌ها را شامل کن" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "اضافه کردن فایل" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "اضافه کردن پوشه" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "استثنا" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}اطلاعات{ENDBOLD}: در حالت 'SSH encrypted' فقط ستاره‌های تکی یا دوتایی " "قابل استفاده هستند (مثلاً {example2}). سایر انواع الگوها و کاراکترهای " "جایگزین نادیده گرفته خواهند شد (مثلاً {example1}). در این حالت، به دلیل " "رمزگذاری توسط EncFS، نام پرونده‌ها غیرقابل پیش‌بینی خواهند بود." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "الگوها، پرونده‌ها یا پوشه‌ها را استثنا کن" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "اضافه کردن پیش‌فرض" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "استثنا کردن پرونده‌های بزرگتر از:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "استثنا کردن پرونده‌ها با اندازه بزرگتر از {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "با غیرفعال بودن 'Full rsync mode'، این تنظیم فقط بر روی پرونده‌های جدید " "تأثیر خواهد گذاشت، زیرا در rsync این یک گزینه‌ی انتقال است، نه یک گزینه‌ی " "حذف. بنابراین، پرونده‌های بزرگی که قبلا پشتیبان‌گیری شده‌اند، حتی در صورت " "تغییر، در برگرفته‌ها باقی خواهند ماند." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "حذف و نگهداری" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&گزینه‌ها" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "گ&زینه‌های حرفه‌ای" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "بازگردانی پیکربندی" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "ویرایش user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "نمایه جدید" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "تغییر نام نمایه" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "آیا شما واقعا مطمئن هستید که میخواهید نمایه \"{name}\" را پاک کنید؟" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}به‌شدت توصیه می‌شود{ENDBOLD}: (همه‌ی توصیه‌ها از پیش اعمال شده‌اند.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}به‌شدت توصیه می‌شود{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "استثنا کردن الگو" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "استثنا کردن فایل" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "استثنا کردن پوشه" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "شامل کردن فایل" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" یک پیوند نمادین است. هدف پیوندداده‌شده پشتیبان‌گیری نمی‌شود مگر این که شما شاملش کنید.\n" "آیا مایلید که هدف پیوندهای نمادین را نیز شامل کنید؟" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "شامل کردن پوشه" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "غیرفعال شده زیرا این الگو در حالت 'SSH encrypted' قابل استفاده نیست." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "برنامه‌ریزی" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "روز:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "روز هفته:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "زمان:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "ساعت‌:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "بعد از ساعت" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "دقیقه‌ها:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "تا وقتی که درایو متصل است Back In Time را اجرا کن (فقط یکبار در هر X روز). " "از شما رمز عبور sudo پرسیده خواهد شد." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Back In Time را مکرر اجرا کن. این زمانی کاربردی است که رایانه معمولاً روشن " "نیست." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "هر:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "فعال‌سازی ثبت پیام‌های اشکال‌زدایی" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "پیام‌های سطح اشکال‌زدایی را از طریق \"--debug\" در لاگ سامانه ثبت کن." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "احتیاط: این گزینه را فقط به‌صورت موقت برای عیب‌یابی استفاده کنید، زیرا حجم " "زیادی از خروجی تولید می‌کند." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "غیرفعال" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "در هر بوت/ریبوت" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "هر {n} دقیقه یکبار" msgstr[1] "هر {n} دقیقه" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "هر ساعت" msgstr[1] "هر {n} ساعت" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "هر {n} ساعت یکبار" msgstr[1] "هر {n} ساعت" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "ساعت‌های سفارشی" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "هر روز" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "مکرر (آناکرون)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "وقتی درایو متصل شد (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "هر هفته" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "هر ماه" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "هر سال" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "ساعت(ها)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "روز" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "هفته" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "ماه" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "ساعت سفارشی فقط می‌تواند فهرستی از ساعت‌هایی باشد که با ویرگول انگلیسی از هم" " جدا شده باشد (مثل 8,12,18,23) و یا به صورت ‪*/3‬ برای پشتیبان‌گیری دوره‌ای " "هر سه ساعت نوشته شود." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "پروکسی SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "میزبان(هاست):" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "پورت:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "کاربر:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "اتصال به میزبان هدف از طریق این پروکسی (که به عنوان Jump Host نیز شناخته " "می‌شود). برای جزئیات بیشتر، به گزینه \"-J\" در مستندات دستور ssh یا " "\"ProxyJump\" در صفحه man ssh_config مراجعه کنید." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "احتیاط:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "این گزینه‌ها برای تنظیمات پیشرفته هستند. فقط در صورتی آن‌ها را تغییر دهید که" " به طور کامل از تأثیراتشان آگاه باشید." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "'rsunc' را با '{cmd}' اجرا کن:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "به عنوان کار کرون" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "برروی هاست ریموت" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "وقتی که درحال گرفتن اسنپ‌شات دستی است" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "برای فعال‌سایزی این گزینه لطفا 'nocache' را نصب کنید." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "برروی ماشین محلی" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "stdout را به /dev/null در کار‌های کرون منتقل کنید." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "اگر یک MTA نصب شده باشد، Cron به‌صورت خودکار ایمیلی حاوی خروجی وظایف " "زمان‌بندی‌شده ارسال خواهد کرد." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "stderr را به /dev/null در کار‌های کرون منتقل کنید." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "اگر یک MTA نصب شده باشد، Cron به‌صورت خودکار ایمیلی حاوی خروجی خطاهای وظایف " "زمان‌بندی‌شده ارسال خواهد کرد." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/ثانیه" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "استفاده rsync از پهنای باند را محدود کن:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "حفظ ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "حفظ ویژگی‌های گسترده (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "کپی پیوندهای ناامن (فقط با پیوندهای مطلق کار میکند)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "محدود کردن به یک پرونده سامانه" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "گزینه‌ها باید بین نویسه‌های نقل‌قول قرار بگیرند مثل {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "پیست گزینه های اضافه به rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "پیشوندی که قبل از اجرای هر دستور در میزبان راه دور اجرا می‌شود." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "متغیرها باید به‌صورت \\$FOO فرار داده شوند. این مقدار بر rsync تأثیر " "نمی‌گذارد، بنابراین برای افزودن یک پیشوند به rsync از \"{example_value}\" " "همراه با {rsync_options_value} استفاده کنید." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "پیشفرض" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "اضافه کردن پیشوند به دستورات SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "بررسی کن اگر هاست ریموت آنلاین هست" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "هشدار: اگر این گزینه غیرفعال باشد و میزبان راه دور در دسترس نباشد، ممکن است " "باعث بروز خطاهای غیرمنتظره شود." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "بررسی کن که آیا میزبان راه‌دور از تمامی دستورات ضروری پشتیبانی می‌کند یا " "خیر." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "هشدار: اگر این گزینه غیرفعال باشد و میزبان راه دور از تمام دستورات موردنیاز " "پشتیبانی نکند، ممکن است باعث بروز خطاهای غیرمنتظره شود." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "غیرفعال" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "فعال" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "حالت:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "کجا اسنپ‌شات‌ها ذخیره شود" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "تنظیمات SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "مسیر:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "متن رمز:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "کلید خصوصی:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "یک فایل کلید خصوصی موجود را انتخاب کنید (معمولاً با نام **\"id_ed25519\"** و" " در تنظیمات قدیمی‌تر **\"id_rsa\"**)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "یک کلید SSH جدید بدون رمز عبور بساز (اگر یک فایل کلید خصوصی درحال حاضر " "انتخاب شده باشد مجاز نیست)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "رمز عبور" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "رمز عبور را در دسته کلید ذخیره کنید" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "رمز عبور کش برای کرون (مشکل امنیتی: ریشه می‌تواند رمز عبور را بخواند)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "پیشرفته" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "مسیر کامل اسنپ‌شات:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "شما هیچ فایل کلید خصوصی برای SSH انتخاب نکردید." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "آیا مایلید یک جفت کلید عمومی/خصوصی جدید بدون رمز عبور ایجاد کنید؟" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "فایل کلید خصوصی \"{file}\" وجود ندارد." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "آیا مایلید کلید عمومی SSH خود را به میزبان راه دور کپی کنید تا ورود بدون رمز" " عبور فعال شود؟" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "اصالت میزبان {host} قابل تأیید نیست." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "اثر انگشت کلید {keytype} عبارت است از:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "لطفاً این اثر انگشت را تأیید کنید. آیا مایلید آن را به فایل 'known_hosts' " "خود اضافه کنید؟" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "آیا مطمئنید که می خواهید پوشه برگرفت‌ها را تغییر دهید؟" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "ایجاد کلید SSHجدید در {path} ناموفق بود." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "فعال کردن اعلان‌ها" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "غیرفعال کردن اسنپ‌شات‌ها در هنگام باتری" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "وضعیت باتری از طرف سیستم در دسترس نیست" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "فقط یک اسنپ‌شات در زمان اجرا کن" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "سایر برگرفت‌ها تا پایان برگرفت جاری مسدود خواهند شد. این یک گزینه‌ی کلی است،" " بنابراین بر تمام نمایه‌های این کاربر تأثیر می‌گذارد. با این حال، برای سایر " "کاربران نیز باید این گزینه را به‌صورت جداگانه فعال کنید." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "پشتیبان‌گیری از فایل‌های تغییر مکان یافته در هنگام بازگردانی" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "نسخه‌های جدیدتر پرونده‌ها پیش از بازیابی، با پسوند {suffix} تغییر نام خواهند" " یافت. اگر دیگر به آن‌ها نیازی ندارید، می‌توانید با استفاده از این دستور آن " "را حذف کنید.{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "ادامه دادن در هنگام خطا (اسنپ‌شات ناقص میمانند)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "از سرجمع برای شناسایی تغییرات استفاده کن" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "یک اسنپ‌شات جدید بگیر بدون در نظر گرفتن اینکه آیا تغییر داشته یا خیر." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "سطح لاگ:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "هیچکدام" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "قوانین زیر از بالا به پایین پردازش می‌شوند. قوانین بعدی، قوانین قبلی را " "جایگزین کرده و محدود به آن‌ها نیستند. برای جزئیات و مثال‌ها به {manual} " "مراجعه کنید." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "راهنمای کاربر" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "باز کردن راهنمای کاربر در مرورگر." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "آخرین برگرفت را نگه دار." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "آخرین یا جدیدترین برگرفت در هر شرایط نگه داشته می شود." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "رفتار نمی تواند تغییر کند." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "برگرفت‌های نامگذاری شده را حذف نکن." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "برگرفت‌های نام گذاری شده, به علاوه ی usual timestamp, در هر شراطی نگه داشته " "و حذف نمی شوند." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "سال(ها)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "حذف برگرفت قدیمی‌تر از" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "روزهای کامل. روز جاری نادیده گرفته می‌شود." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "هفته‌های تقویم با دوشنبه به عنوان اولین روز. هفته جاری نادیده گرفته می‌شود." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "دوره‌های ۱۲ ماهه. ماه جاری نادیده گرفته می‌شود." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "سیاست‌های نگهداری" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "در پس‌زمینه برروی میزبان راه‌دور اجرا کن." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "فرآیند حذف هوشمند مستقیما روی ماشین راه دور اجرا می‌شود، نه به‌صورت محلی. " "دستورات \"bash\"، \"screen\" و \"flock\" باید روی ماشین راه دور نصب و در " "دسترس باشند." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "اگر این گزینه انتخاب شود، Back In Time ابتدا ماشین راه دور را آزمایش خواهد " "کرد." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "روزها از امروز شمرده می‌شوند." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "تمامی اسنپ‌شات ها را تا آخر نگهدار" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "روز‌(ها)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "آخرین برگرفت به ازای هر روز را به عنوان آخری نگه دار" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "هفته‌ها از هفته جاری که در حال اجرا است شروع می‌شوند. هفته از روز دوشنبه " "آغاز می‌شود." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "آخرین برگرفت را برای هر هفته به عنوان آخری نگه دار" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "هفته(ها)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "ماه‌ها به‌عنوان ماه‌های تقویمی از ماه جاری شمرده می‌شوند." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "آخرین برگرفت به ازای هر ماه را به عنوان آخری نگه دار" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "ماه(ها)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "سال‌ها به‌عنوان سال‌های تقویمی از سال جاری شمرده می‌شوند." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "آخرین برگرفت به ازای هر سال را به عنوان آخری نگه دار" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "تمام سال ها." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... فضای آزاد کمتر باشد از" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... در صورتی که تعداد inode آزاد کمتر باشد از" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "حذف برگرفت‌های قدیمی‌تر اگر …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "سوال" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "نمایه: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "آخرین لاگ را ببین" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "اجرای {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "درحال کار…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "فرستاده‌شده:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "سرعت:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "زمان تخمینی:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "اسنپ‌شات‌ها" #: qt/qttools.py:506 msgid "Today" msgstr "امروز" #: qt/qttools.py:513 msgid "Yesterday" msgstr "دیروز" #: qt/qttools.py:522 msgid "This week" msgstr "این هفته" #: qt/qttools.py:529 msgid "Last week" msgstr "آخرین هفته" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "این یک اسنپ‌شات نیست ولی یک نمای زنده از پرونده‌های محلی شماست" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "آخرین بررسی {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "وارد کردن پیکربندی" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "هیچ پیکربندی‌ پیدا نشد" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "وارد کردن" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "دایرکتوری برگرفت که باید فایل پیکربندی را از آن وارد کنید انتخاب کنید. مسیر " "ممکن است به صورت زیر باشد: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "اگر دایرکتوری بر روی یک درایو خارجی یا راه دور قرار دارد، باید پیش از آن " "به‌صورت دستی سوار شود." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "لاگ را کامل نشان بده" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "گزینه‌هایی در مورد مقایسه عکس‌های فوری" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "دستور:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "پارامتر ها:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "از ۱٪ و ۲٪ برای پارامترهای مسیر استفاده کن" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "لطفا دستور diff را تنظیم کنید یا روی لغو کلیک کنید." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "دستور \"{cmd}\" در این سامانه یافت نشد. لطفا دستور دیگری امتحان کنید یا روی " "لغو کلیک کنید." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "هیچ پارامتری برای دستور diff تنظیم نشده است. از مقدار پیش‌فرض \"{params}\" " "استفاده می‌شود." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "فقط اسنپ‌شات‌ها را مقایسه کن" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "فقط برگرفت‌هایی را که فهرست کن که برابر هستند با:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "بررسی ژرفناک (بیشتر دقیق، ولی کند)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "پاک کردن" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "انتخاب همه" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "مقایسه" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "برو به" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "گزینه‌ها" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "شما نمی‌توانید یک اسنپ‌شات را با خودش مقایسه کنید." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "آیا شما واقعا می‌خواهید \"{file}\" را در اسنپ‌شات \"{snapshot_id}\" پاک کنید؟" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "آیا واقعا می‌خواهید \"{file}\" را در {count} اسنپ‌شات پاک کنید؟" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "هشدار: این عمل قابل بازگشت نیست." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "می‌خواهید که \"{path}\" را از اسنپ‌شات‌های آینده مستثنی کنید؟" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "زیر پوشه پشتیبان را نمی‌توان اضافه کرد." backintime-1.5.4/common/po/fi.po000066400000000000000000001770511477034762000165200ustar00rootroot00000000000000# Finnish translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-13 12:15+0000\n" "Last-Translator: piijuska \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Varoitus" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Pääprofiili" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Paikallinen (EncFS salattu)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS salattu)" #: common/config.py:278 msgid "Local" msgstr "Paikallinen" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "yksityinen SSH-avain" #: common/config.py:283 msgid "Local encrypted" msgstr "Paikallinen salattu" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Salaus" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH-salattu" #: common/config.py:296 msgid "Default" msgstr "Oletus" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profiili: ”{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Tilannevedosten hakemisto ei ole kelvollinen." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Vähintään yksi hakemisto on valittava varmuuskopiointia varten." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Hakemisto: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Tätä hakemistoa ei voi sisällyttää varmuuskopioon, koska se on osa itse " "varmuuskopion kohdetta." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Uuden crontabin kirjoittaminen epäonnistui." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron ei ole käynnissä, vaikka komento 'crontab' on käytettävissä. " "Ajoitettuja varmuuskopiointitöitä ei suoriteta. Cron saattaa olla " "asennettuna, mutta ei käytössä. Kokeile komentoa 'systemctl enable cron' tai" " ota yhteyttä GNU/Linux-jakelun tukikanaviin." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Profiilille {profile_id} ei voitu asentaa udev-sääntöä. DBus-palvelu " "”{dbus_interface}” ei ole käytettävissä" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udevin ajoittaminen ei toimi tilassa {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Kohteelle ”{path}” ei löytynyt UUID:tä" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Määrityksen tallentaminen epäonnistui" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Määrityksen lataaminen epäonnistui" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profiili ”{name}” on jo olemassa." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Tätä ei voi kumota." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Ei voi liittää '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Salatun hakemiston määritystä ei löytynyt." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Luodaanko uusi salattu hakemisto?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Peru" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Ole hyvä ja vahvista salasana." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Salasanat eivät täsmää." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ota otos" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Ei voi irrottaa {mountprocess} kohteesta {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Komentoa \"{command}\" ei löytynyt. Ole hyvä ja asenna se (esim. " "\"{installcommand}\" kautta)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Liitospiste {mntpoint} ei ole tyhjä." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Syötä salasana {mode} profiilille \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "EPÄONNISTUI" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Palauta käyttöoikeudet" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Valmis" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Viivästetään varmuuskopiointia akkukäytön ajan" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Tilannevedosten hakemistoa ei löydy." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Jos se on irrotettavassa asemassa, liitä se." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Odotetaan %s sekunti." msgstr[1] "Odotetaan %s sekuntia." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Otoksen {snapshot_id} luominen epäonnistui." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Ole kärsivällinen; viimeistellään…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Hakemistoa ei voi luoda." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Tallennetaan määritystiedostoa…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Tallennetaan käyttöoikeuksia…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Löytyi jäljelle jäänyt tilannevedos {snapshot_id}, jota voidaan jatkaa." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Poistetaan jäljelle jäänyt {snapshot_id}-hakemisto viimeisestä suorituksesta" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Ei voi poistaa hakemistoa" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Otetaan otosta" #: common/snapshots.py:1430 msgid "Success" msgstr "Onnistui" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Osittain siirretty johtuen virheestä" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Osittain siirretty johtuen puuttuvista lähdetiedostoista ( kts. 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' päättyi paluukoodilla {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Katso lisätietoja: 'man rsync'" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negatiiviset rsync-poistumiskoodit ovat signaalinumeroita, katso 'kill -l' " "ja 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Mikään ei ole muuttunut: uusi otos ei ole tarpeen" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Ei voi uudelleennimetä {new_path} {path}:ksi." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Älykäs poisto" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Sovella säännöt poistaaksesi vanhat tilannevedokset" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Sovella säilytyskäytäntö" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Yritetään pitää vapaa vähimmäistila" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Yritetään pitää vähintään {perc} inodeja vapaana" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nyt" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Ei voi liittää {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agentia ei löytynyt. Varmista, että se on asennettu." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Yksityisen SSH-avaimen lukitusta ei voida avata. Salasana on väärin tai ei " "käytettävissä cronia varten." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Salausalgoritmi {cipher} epäonnistui kohteeseen {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Etäsijainti on olemassa muttei kansio." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Etäsijaintiin ei voi kirjoittaa." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Etäsijainti ei ole ohjelmatiedosto." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Etäsijaintia ei voitu luoda." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Etäkone {host} ei tue komentoa {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Lisätietoa: ”man backintime”" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Check-komennot palvelimella {host} antoivat tuntemattoman virheen" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Etäkone {host} ei tue kovia linkkejä" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopioi julkinen ssh-avain \"{pubkey}\" palvelimelle \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Ole hyvä ja syötä käyttäjän \"{user}\" salasana." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Kohdetiedostojärjestelmä kohteelle {path} on alustettu NTFS:llä, jolla on " "tunnettuja yhteensopimattomuuksia UNIX-tyylisten tiedostojärjestelmien " "kanssa." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} ei ole kelvollinen hakemisto." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Seuraavan hakemiston luominen epäonnistui:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Kirjoitusoikeutta saatetaan rajoittaa." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Kohdetiedostojärjestelmä kohteelle {path} on alustettu FATilla, joka ei tue " "kiintolinkkejä. Käytä alkuperäistä GNU/Linux-tiedostojärjestelmää." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Kohdetiedostojärjestelmä kohteelle {path} on SMB:n kautta liitetty jako. " "Varmista, että SMB-etäpalvelin tukee symbolisia linkkejä tai aktivoi " "\"{copyLinks}\" kohdassa \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopioi linkit (ratkaise symboliset linkit)" #: common/tools.py:504 msgid "Expert Options" msgstr "Asiantuntija-asetukset" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Kohdetiedostojärjestelmä kohteelle {path} on sshfs:n kautta liitetty jako. " "Sshfs ei tue kiinteitä linkkejä. Käytä sen sijaan tilaa \"SSH\"." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Tiedoston luominen epäonnistui tässä hakemistossa:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Tietoa" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Tekijät" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Käännökset" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lisenssi" #: qt/app.py:172 msgid "Shortcuts" msgstr "Pikanäppäimet" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Tätä hakemistoa ei ole olemassa nykyisessä\n" "valitussa tilannevedoksessa." #: qt/app.py:257 msgid "Add to Include" msgstr "Lisää mukaan otettaviin" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Lisää pois jätettäviin" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} näyttää käynnistettävän ensimmäistä kertaa, koska asetuksia ei " "löytynyt." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Tuodaanko olemassa oleva kokoonpano (varmuuskopion kohdehakemistosta tai " "toisesta tietokoneesta)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Jos kansio on siirrettävällä asemalla, kytke se ja napsauta OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ota otos" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Käytä muokkausajankohtaa ja kokoa tiedoston muokkauksen havaitsemiseen." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ota otos tarkistussummin" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Havaitse muutokset tarkistussummista." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Keskeytä otosprosessi" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Jatka otosprosessia" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Pysäytä otosprosessi" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Virkistä otosluettelo" #: qt/app.py:497 msgid "Name snapshot" msgstr "Ota otos" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Poista otos" #: qt/app.py:505 msgid "View snapshot log" msgstr "Näytä otosloki" #: qt/app.py:509 msgid "View last log" msgstr "Näytä viimeisin loki" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Hallinnoi profiileja…" #: qt/app.py:517 msgid "Shutdown" msgstr "Sammuta" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Sammuta järjestelmän otoksen valmistuttua." #: qt/app.py:521 msgid "Setup language…" msgstr "Asennuskieli…" #: qt/app.py:525 msgid "Exit" msgstr "Lopeta" #: qt/app.py:529 msgid "User manual" msgstr "Käyttöopas" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Avaa käyttöopas selaimessa (paikallinen jos saatavilla muuten verkossa)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "'man'-sivu: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Näyttää 'man'-sivun Back In Time (backintime) :stä" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "'man'-sivu: Profiilien konfigurointitiedosto" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Näyttää 'man'-sivun profiilien konfigurointitiedostosta (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projektin verkkosivusto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Avaa Back In Time -verkkosivusto selaimessa" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Muutosloki" #: qt/app.py:555 msgid "FAQ" msgstr "UKK" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Avaa Usein kysytyt kysymykset (UKK) selaimessa" #: qt/app.py:559 msgid "Ask a question" msgstr "Esitä kysymys" #: qt/app.py:563 msgid "Report a bug" msgstr "Ilmoita ohjelmavirheestä" #: qt/app.py:566 msgid "Translation" msgstr "Käännökset" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Näytä viesti kääntämiseen osallistumisesta uudelleen." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Encryption Transition (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Näyttää viestin EncFS:n poistosta uudelleen." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Palauta" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Palauta valitut tiedostot tai hakemistot alkuperäiseen kohteeseen." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Palauta kohteeseen…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Palauta valitut tiedostot tai hakemistot uuteen kohteeseen." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Palauta tällä hetkellä näytettävä hakemisto ja kaikki sen sisältö " "alkuperäiseen kohteeseen." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Palauta näytettävä hakemisto ja kaikki sen sisältö uuteen kohteeseen." #: qt/app.py:601 msgid "Up" msgstr "Ylös" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Näytä piilotiedostot" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Vertaa otoksia…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Julkaisuehdokas" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Näyttää viestin tästä julkaisuehdokkaasta uudelleen." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Varmuuskopio" #: qt/app.py:692 msgid "&Restore" msgstr "&Palauta" #: qt/app.py:698 msgid "&Help" msgstr "&Ohje" #: qt/app.py:743 msgid "Icons only" msgstr "Vain kuvakkeet" #: qt/app.py:746 msgid "Text only" msgstr "Vain teksti" #: qt/app.py:749 msgid "Text below icons" msgstr "Teksti kuvakkeiden alla" #: qt/app.py:752 msgid "Text beside icon" msgstr "Teksti kuvakkeen vieressä" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Jos suljet tämän ikkunan, Back In Time ei voi sammuttaa järjestelmää otoksen" " valmistuttua." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Haluatko varmasti sulkea sen?" #: qt/app.py:1072 msgid "Working:" msgstr "Käsitellään:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Valmis, varmuuskopiota ei tarvittu" #: qt/app.py:1129 msgid "Working" msgstr "Käsitellään" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Virhe" #: qt/app.py:1161 msgid "Sent" msgstr "Lähetetty" #: qt/app.py:1162 msgid "Speed" msgstr "Nopeus" #: qt/app.py:1163 msgid "ETA" msgstr "Jäljellä" #: qt/app.py:1225 msgid "Global" msgstr "Yleisasetukset" #: qt/app.py:1226 msgid "Root" msgstr "Juuri" #: qt/app.py:1227 msgid "Home" msgstr "Koti" #: qt/app.py:1255 msgid "Backup directories" msgstr "Varmuuskopiohakemistot" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Otoksen nimi" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Oletko varma että haluat poistaa tämän otoksen?" msgstr[1] "Oletko varma että haluat poistaa nämä otokset?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Varmuuskopioi paikalliset tiedostot ennen korvaamista\n" "tai poistamista ”{suffix}”-päätteelle." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Tiedostojen uudempien versioiden nimiin lisätään ”{suffix}” ennen " "palauttamista. Ellei niitä enää tarvita, ne voi poistaa tällä komennolla:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Palauta vain tiedostot, jotka puuttuvat tai\n" "ovat uudempia kuin kohteessa.\n" "Käytetään ”rsync --update” -asetusta." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Poista uudemmat elementit alkuperäisestä hakemistosta." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Palauta valitut tiedostot tai hakemistot alkuperäiseen kohteeseen ja poista " "tiedostot tai hakemistot, jotka eivät ole tilannekuvassa. Ole varovainen, " "koska tämä poistaa tiedostot ja hakemistot, jotka jätettiin pois " "tilannekuvan ottamisen aikana." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Haluatko todella palauttaa tämän elementin uuteen hakemistoon?" msgstr[1] "Haluatko todella palauttaa nämä elementit uuteen hakemistoon?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Haluatko varmasti palauttaa tämän tiedoston?" msgstr[1] "Haluatko varmasti palauttaa nämä tiedostot?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Haluatko varmasti poistaa kansion ”{path}” kaikki uudemmat tiedostot?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Oletko varma, että haluat poistaa kaikki uudemmat tiedostot alkuperäisestä " "hakemistosta?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Varoitus{BOLDEND}: Tiedostojen poistaminen tiedostojärjestelmän " "juuressa, voi rikkoa koko järjestelmän." #: qt/app.py:1857 msgid "Snapshot" msgstr "Otokset" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Palauta {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Palauta {path} kohteeseen…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hei,\n" "Olet käyttänyt Back In Time -sovellusta kielellä: {language} jo jonkin aikaa.\n" "Ohjelmaversiosi käännös kielelle {language} on {perc} valmis. Riippumatta teknisestä osaamisestasi voit osallistua käännöksen ja sitä kautta myös Back In Time -ohjelman kehitykseen itsekin.\n" "Siirry osoitteeseen {translation_platform_url} jos haluat osallistua. Lisätietoja saat myös osoitteesta: {back_in_time_project_website}.\n" "Pyydämme anteeksi keskeytystä eikä tätä ilmoitusta näytetä uudestaan. Tämä viesti on saatavilla koska tahansa help -menun kautta.\n" "Sinun Back In Time Team" #: qt/app.py:2071 msgid "translation platform" msgstr "Käännökset" #: qt/app.py:2076 msgid "Website" msgstr "Sivusto" #: qt/app.py:2090 msgid "Your translation" msgstr "Käännökset" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Fediversumissa Mastodonissa: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Lähetä sähköpostia osoitteeseen {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Postituslista {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} projektin verkkosivustolla." #: qt/app.py:2118 msgid "Open an issue" msgstr "Avaa vikalippu" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Vaihtoehtoisesti voit käyttää toista valitsemaasi kanavaa." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Tämä Back In Time -versio on Julkaisuehdokas, ja se on tarkoitettu ensisijaisesti vakauden testaamiseen seuraavaa virallista julkaisua varten.\n" "Käyttäjätietoja tai telemetriaa ei kerätä. Back In Time -joukkue on kuitenkin hyvin kiinnostunut tietämään, käytetäänkö Julkaisuehdokasta ja kannattaako tällaisten julkaisua edeltävien versioiden tarjoamista jatkaa.\n" "Siksi joukkue pyytää ystävällisesti lyhyttä palautetta siitä, oletko testannut tätä versiota, vaikka et olisi kohdannut mitään ongelmia. Jopa muutaman minuutin mittainen nopea testiajo auttaisi meitä paljon.\n" "Käytettävissä ovat seuraavat yhteydenottovaihtoehdot:\n" "{contact_list}\n" "Tässä versiossa tätä viestiä ei enää näytetä, mutta se on käytettävissä milloin tahansa ohjevalikon kautta.\n" "Kiitos tuestasi ja siitä, että autat meitä parantamaan Back In Timea!\n" "Back In Time -joukkueesi" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Kielivalinta astuu voimaan uudelleenkäynnistyksen jälkeen." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "EncFS-profiilin luominen poistetaan seuraavassa pienessä julkaisussa (1.7), " "joka on suunniteltu vuodelle 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Tämän tilan käyttöä profiilille ei enää suositella." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "valkopaperi" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS:n tuki lopetetaan tietoturva-aukkojen vuoksi." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Lisätietoja, mukaan lukien mahdolliset vaihtoehdot, on tässä " "{whitepaper}:ssa." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Seuraavat profiilit käyttävät salausta EncFS:n kanssa:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "Vaihtoa suunnitellaan, mutta ei voida taata, että se saapuu ajoissa." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Käyttäjiä pyydetään liittymään tähän keskusteluun. Päivitetyt tiedot " "seuraavista vaiheista ovat saatavilla tässä {whitepaper}:ssa." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Tätä viestiä ei näytetä uudelleen. Tämä valintaikkuna on käytettävissä " "milloin tahansa ohjevalikon kautta." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Back In Time -joukkueesi" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Asennuskieli" #: qt/languagedialog.py:97 msgid "System default" msgstr "Järjestelmän oletus" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Käytä järjestelmän kielivalintaa." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Käännetty: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Viimeisin lokinäkymä" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Otoslokinäkymä" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profiili:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Otokset:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Suodatin:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Kaikki" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Muutokset" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Virheet" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Tieto" msgstr[1] "Tiedot" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync-siirtoviat (kokeellinen)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Virhe, [I] Tietoa, [C] Muutokset" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekoodaa polut" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Hallinnoi profiileja" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Muokkaa" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Lisää" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Poista" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Yleisasetukset" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Ota mukaan" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Sisällytä tiedostot ja hakemistot" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Lisää tiedosto" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Lisää hakemisto" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Jätä pois" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Tieto{ENDBOLD}: SSH-salatussa tilassa vain yksi- tai tuplatähti " "toimivat (esim. {example2}). Muut jokerimerkit ja -kuviot ohitetaan (esim. " "{example1}). Tiedostojen nimet ovat arvaamattomia tässä tilassa EncFS-" "salauksen vuoksi." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Sulje pois kuvioita, tiedostoja tai hakemistoja" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Lisää oletukset" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Jätä pois tätä suuremmat tiedostot:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Jätä pois tätä suuremmat tiedostot: {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Kun \"Täysi rsync -tila\" on poistettu käytöstä, tämä vaikuttaa vain uusiin " "tiedostoihin, koska rsyncissä tämä on siirtovaihtoehto, ei " "poissulkemisvaihtoehto. Siksi suuret tiedostot, jotka on varmuuskopioitu " "aiemmin, säilyvät tilannevedoksissa, vaikka niitä olisi muokattu." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Poista & säilyttäminen" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Valinnat" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "A&siantuntija-asetukset" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Palauta määritys" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Muokkaa käyttäjäkutsua" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Uusi profiili" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Muuta profiilin nimeä" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Haluatko varmasti poistaa profiilin ”{name}”?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Erittäin suositeltavaa{ENDBOLD}: (Kaikki suositukset sisältyvät jo.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Erityisesti suositellaan{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Jätä pois kuvio" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Jätä pois tiedosto" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Sulje pois hakemisto" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Ota mukaan tiedosto" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "”{path}” on symlinkki. Linkin kohdetta ei varmuuskopioida, ellei sitä oteta erikseen mukaan.\n" "Haluatko ottaa mukaan symlinkkien kohteet?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Sisällytä hakemisto" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Poistettu käytöstä, koska tämä kuvio ei toimi tilassa \"SSH-salattu\"." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Aikataulu" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Päivä:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Viikonpäivä:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Aika:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Tunnit:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "tunnin jälkeen" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuutit:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Suorita Back In Time heti, kun asema on kytketty (vain kerran X päivässä). " "Sinulta kysytään \"sudo\"-salasanaa." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Suorita BackInTime toistuvasti. Tästä on apua, ellei kone ole aina " "käynnissä." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Joka:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Ota viankorjausviestien lokiin kirjaaminen käyttöön" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Kirjoittaa viankorjaustason viestejä järjestelmälokiin komennon '--debug' " "myötä." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Huomio: Käytä tätä vain väliaikaisesti diagnostiikkaan, koska se tuottaa " "suuren määrän ulostuloa." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Ei käytössä" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Käynnistysten yhteydessä" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "{n} minuutin välein" msgstr[1] "{n} minuutin välein" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Tunnin välein" msgstr[1] "Joka {n} tunti" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} tunnin välein" msgstr[1] "{n} tunnin välein" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Mukautetut tunnit" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Päivittäin" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Toistuva (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Asemaa kytkettäessä (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Viikoittain" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Kuukausittain" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Joka vuosi" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Tunti/Tunnit" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Päivä(ä)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Viikko(a)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Kuukausi/Kuukaudet" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Mukautettujen tuntien on oltava pilkuin erotettu tuntiluettelo (esim. " "8,12,18,23) tai */3 varmuuskopioille kolmen tunnin välein." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Välipalvelin" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Konenimi:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Portti:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Käyttäjä:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Yhdistä kohdeisäntään tämän välityspalvelimen kautta (tunnetaan myös nimellä" " hyppyisäntä). Katso '-J' 'ssh'-komentodokumentaatiosta tai 'ProxyJump' " "'ssh_config'-'man'-sivulta yksityiskohtien saamista varten." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Huomio:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Nämä vaihtoehdot ovat edistyneille määrityksille. Muuta vain, jos olet " "täysin tietoinen niiden vaikutuksista." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Suorita rsync komennolla '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "cron-töissä" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "etäkoneilla" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "käyttäjän tehdessä itse otoksia" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Asenna \"nocache\" ottaaksesi tämän vaihtoehdon käyttöön." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "paikallisella koneella" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Ohjaa cron-töiden vakiotulosvirta /dev/nulliin." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron lähettää automaattisesti sähköpostin, jossa on liitteenä tulosteet " "cron-töistä, jos MTA on asennettu." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Ohjaa cron-töiden vakiovirhevirta /dev/nulliin." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron lähettää automaattisesti sähköpostin, joka sisältää liitteenä virheet " "cron-töistä, jos MTA on asennettu." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "kt/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Rajoita rsyncin kaistan käyttöä:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Säilytä ACL:t" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Säilytä lisämääritteet (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopioi turvattomat linkit (toimii vain absoluuttisille linkeille)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Rajaa yhdelle tiedostojärjestelmälle" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Valitsinten arvot tulee merkitä lainausmerkkeihin, esim. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Liitä lisävalinnat rsyncille" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Etuliite joka ajetaan ennen jokaista komentoa etäkoneella." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "\"esc\" on sovellettava muuttujiin \\$FOO:lla. Tämä ei koske rsynciin, joten" " jos haluat lisätä etuliitteen rsyncille, käytä \"{example_value}\" ja " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "oletus" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Lisää SSH-komentoihin etuliite" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Tarkista, onko etäkone verkossa" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Varoitus: Jos se on poistettu käytöstä ja etäisäntä ei ole käytettävissä, " "tämä voi aiheuttaa outoja virheitä." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Tarkista, tukeeko etäkone kaikkia vaadittuja komentoja." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Varoitus: Jos se on poistettu käytöstä ja etäisäntä ei tue kaikkia " "tarvittavia komentoja, tämä voisi aiheuttaa outoja virheitä." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(oletus: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "ei käytössä" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "käytössä" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Tila:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Mihin otokset tallennetaan" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-asetukset" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Sijainti:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Salausmenetelmä:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Yksityinen avain:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Valitse olemassa oleva yksityinen avaintiedosto (yleensä nimettyinä " "\"id_ed25519\", ja vanhemmissa asetuksissa \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Luo uusi SSH avain ilman salasanaa (vain jos yksityistä avainta ei ole jo " "valittu)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Salasana" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Tallenna salasana avainrenkaaseen" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Tallenna salasana välimuistiin cronia varten (tietoturvaongelma: root voi " "lukea salasanan)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Lisäasetukset" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Otoksen täydellinen sijainti:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Et valinnut yksityisen avaimen tiedostoa SSH:lle." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Haluatko luoda uuden salasanattoman julkisen/yksityisen avainparin?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Yksityistä avaintiedostoa ”{file}” ei ole olemassa." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Haluatko kopioida julkisen SSH-avaimesi etäisäntään salasanattoman " "sisäänkirjautumisen mahdollistamiseksi?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Koneen ”{host}” autenttisuutta ei voida todentaa." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Avaimen {keytype} sormenjälki on:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Tarkista tämä sormenjälki. Haluatko lisätä sen tiedostoosi \"known_hosts\"?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Oletko varma, että haluat muuttaa tilannevedoshakemistoa?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Uuden SSH-avaimen luominen {path}:ssa epäonnistui." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Käytä ilmoituksia" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Älä tee otoksia akkukäytössä" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Järjestelmä ei tarjoa virranhallintatietoja" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Tee vain yksi otos kerrallaan" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Muut otokset estetään, kunnes nykyinen on valmis. Tämä on yleisasetus, joten" " se vaikuttaa käyttäjän kaikkiin profiileihin. Muille käyttäjille asetus " "täytyy kuitenkin ottaa käyttön erikseen." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Varmuuskopioi palautettaessa korvatut tiedostot" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Tiedostojen uudemmat versiot nimetään uudelleen ja niiden lopussa on " "{suffix} ennen palauttamista. Jos et tarvitse niitä enää, voit poistaa ne " "komennolla '{cmd}'" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Jatka virheistä huolimatta (säilytä keskeneräiset otokset)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Havaitse muutokset tarkistussummista" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Tee uusi otos, vaikkei muutoksia olisi." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Lokitaso:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ei mitään" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Seuraavat säännöt käsitellään ylhäältä alas. Myöhemmät säännöt ohittavat " "aikaisemmat eivätkä ne rajoita niitä. Katso lisätietoja ja esimerkkejä " "oppaasta {manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "käyttöopas" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Avaa käyttöopas selaimessa." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Säilytä uusin tilannevedos." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "Viimeinen tai tuorein tilannevedos säilytetään kaikissa olosuhteissa." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Sitä käytöstä ei voi muuttaa." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Säilytä nimetyt tilannevedokset." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Tilannevedokset, joille on annettu nimi, tavallisen aikaleiman lisäksi, " "säilytetään kaikissa olosuhteissa, eikä niitä poisteta." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Vuosi(a)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Poista tilannevedokset, jotka ovat vanhempia kuin" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Täydelliset päivät. Nykyinen päivä on jätetty huomioimatta." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Kalenteriviikot, maanantaina ensimmäisenä päivänä. Nykyinen viikko on " "jätetty huomioimatta." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 kuukauden ajanjaksot. Nykyiset kuukaudet on jätetty huomioimatta." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Säilytyskäytäntö" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Suorita etäkoneessa taustalla." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Älykäs poistotoiminto suoritetaan suoraan etäkoneessa, ei paikallisesti. " "Komennot 'bash', 'screen' ja 'flock' on asennettava ja käytettävissä " "etäkoneessa." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Jos valittuna, Back In Time testaa ensin etäkonetta." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Päivät lasketaan tästä päivästä alkaen." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Säilytä kaikki otokset" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "viime päivältä (/päiviltä)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Säilytä kunkin päivän viimeinen tilannevedos viimeisenä" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Viikot lasketaan kuluvasta juoksuviikosta alkaen. Viikko alkaa maanantaina." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Säilytä kunkin viikon viimeinen tilannevedos viimeisenä" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "viime viikolta (/viikoilta)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Kuukaudet lasketaan kalenterikuukausiksi kuluvista kuukausista alkaen." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Säilytä kunkin kuukauden viimeinen tilannevedos viimeisenä" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "viime kuulta (/kuukausilta)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Vuodet lasketaan kalenterivuosiksi kuluvasta vuodesta alkaen." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Säilytä viimeinen tilannevedos jokaisesta vuodesta" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "kaikki vuodet." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… vapaa tila on vähemmän kuin" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… vapaat inodit ovat vähemmän kuin" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Poista vanhimmat tilannevedokset, jos…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Kysymys" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profiili: ”{profile_name}”" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Näytä viimeisin loki" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Käynnistä {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Käsitellään…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Lähetetty:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Nopeus:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Arvioitu saapumisaika (ETA):" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Otokset" #: qt/qttools.py:506 msgid "Today" msgstr "Tänään" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Eilen" #: qt/qttools.py:522 msgid "This week" msgstr "Tällä viikolla" #: qt/qttools.py:529 msgid "Last week" msgstr "Viime viikolla" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Tämä EI ole otos vaan elävä näkymä paikallisiin tiedostoihin" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Viimeksi tarkistettu {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Tuo kokoonpano" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Kokoonpanoa ei löytynyt" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Tuo" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Valitse tilannevedoshakemisto, josta kokoonpanotiedosto tuodaan. Polku voi " "näyttää tältä: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Jos hakemisto sijaitsee ulkoisella tai etäasemalla, se on liitettävä " "manuaalisesti etukäteen." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Näytä täysi loki" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Tilannevedosten vertailemisen kattavat vaihtoehdot" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Komento:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametrit:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Käytä sijaintiparametreina %1 ja %2" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Aseta komento 'diff' tai paina Peruuta." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Komentoa \"{cmd}\" ei löydy tästä järjestelmästä. Kokeile jotain muuta tai " "paina Peruuta." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "'diff'-komennolle ei ole asetettu parametreja. Käytetään oletusarvoa " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Suorita eroanalyysi vain tilannevedoksista" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Luettele vain otokset, jotka ovat samoja kuin:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Syvätarkistus (tarkempi, mutta hitaampi)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Poista" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Valitse kaikki" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Vertaa" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Siirry" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Valinnat" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Otosta ei voi verrata itseensä." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Haluatko poistaa tiedoston ”{file}” otoksesta ”{snapshot_id}”?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Haluatko varmasti poistaa tiedoston ”{file}” {count} otoksesta?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "Varoitus: Tätä ei voi kumota." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Jätetäänkö ”{path}” pois myöhemmistä otoksista?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Alihakemistoja ei voi sisällyttää varmuuskopioon." backintime-1.5.4/common/po/fo.po000066400000000000000000001403221477034762000165150ustar00rootroot00000000000000# Faroese translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-12 18:58+0000\n" "Last-Translator: robinkjeld \n" "Language-Team: Faroese \n" "Language: fo\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Ávaring" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profilur" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalt (EncFS brongla)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS brongla)" #: common/config.py:278 msgid "Local" msgstr "Lokalt" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privatur lykil" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalt brongla" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Kryptering" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH krypterað" #: common/config.py:296 msgid "Default" msgstr "Standard" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Umhvarv: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Løtumyndar mappa er ikki gildug." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Í minsta lagi ein mappa má vera vald til trygdaravrit." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Mappa {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "" #: common/configfile.py:101 msgid "Failed to save config" msgstr "" #: common/configfile.py:137 msgid "Failed to load config" msgstr "" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Umhvarv \"{name}\" finnst longu." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "" #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Ikki gjørligt at lata upp '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Uppseting fyri tí bronglaðu mappuna er ikki funnin." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Gera eina nýggja bronglaða mappu?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Ógilda" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Vinarliga vátta loyniorðið." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Loyniorðið er ikki líka." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Tak eina løtumynd" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Ógjørligt at avtaka {mountprocess} frá {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} ikki funnin. Vinarliga installera (t.d. við \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Mountpoint {mntpoint} ikki tómt." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Skriva inn loyniorð fyri {mode} profile \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "MISEYÐNA" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Goymi loyvi" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Liðugt" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Útseta trygaravrit ímeðan streymur ikki er tilsettur" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Kann ikki finna løtumyndar mappuna." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Um mappan er á einari eksternum harddiski, vinarliga set hann til." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Bíðar %s sekund." msgstr[1] "Bíðar %s sekund." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Kann ikki stovna skjáttuna" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Goymi samansetingarfíluna …" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Goymi loyvi .…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Kaann ikki taka burtur skjáttuna" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Tak eina løtumynd" #: common/snapshots.py:1430 msgid "Success" msgstr "" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Tak gamlar løtumyndir burtir" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Royn at halda minstamark av tøkum plássi" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Roynur at halda min {perc} tøkt inodes" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nú" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Ógjørligt at stovna {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent ikki funnin. Vinarliga kanna at hann er lagdur inn." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Ber ikki til at lesa ssh persónligur lykil. Skeivt loyniorð ella loyniorð " "ikki tøkt fyri cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Kann ikki stovna skjáttuna." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Fjar telda {host} stuðlar ikki undir {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Hygg eftir 'man backintime' fyri nærri boðum" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kanna kommando á fjarteldu {host} boðar frá ókendum feilboðum" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Fjartelda {host} stuðlar ikki undir hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Avrita almenna ssh-key \"{pubkey}\" til fjarteldu \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Vinarliga tøppa inn loyniorð fyri \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "" #: common/tools.py:504 msgid "Expert Options" msgstr "Framkomnir kostir" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Um forritið" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "" #: qt/app.py:172 msgid "Shortcuts" msgstr "Snarvegir" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" #: qt/app.py:257 msgid "Add to Include" msgstr "" #: qt/app.py:259 msgid "Add to Exclude" msgstr "" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" #: qt/app.py:470 msgid "Take a snapshot" msgstr "Tak eina løtumynd" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Hvar skullu støðumyndirnar goymast" #: qt/app.py:497 msgid "Name snapshot" msgstr "Tak eina løtumynd" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Tak støðumynd burtur" #: qt/app.py:505 msgid "View snapshot log" msgstr "Tak eina løtumynd" #: qt/app.py:509 msgid "View last log" msgstr "" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Høvuðsumhvarv…" #: qt/app.py:517 msgid "Shutdown" msgstr "" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "" #: qt/app.py:521 msgid "Setup language…" msgstr "" #: qt/app.py:525 msgid "Exit" msgstr "Far úr" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Goymi samansetingarfíluna" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "" #: qt/app.py:555 msgid "FAQ" msgstr "" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "" #: qt/app.py:563 msgid "Report a bug" msgstr "" #: qt/app.py:566 msgid "Translation" msgstr "" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Endurstovna" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Endurstovna…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" #: qt/app.py:601 msgid "Up" msgstr "Upp" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Vís fjaldar fílur" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Tak eina løtumynd…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "" #: qt/app.py:692 msgid "&Restore" msgstr "&Endurstovna" #: qt/app.py:698 msgid "&Help" msgstr "&Hjálp" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "Er tú viss/ur í at taka støðumyndina burtur" #: qt/app.py:1072 msgid "Working:" msgstr "Arbeiði:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Liðug, eingin trygdarriting neyðug" #: qt/app.py:1129 msgid "Working" msgstr "Arbeiði" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "" #: qt/app.py:1161 msgid "Sent" msgstr "" #: qt/app.py:1162 msgid "Speed" msgstr "" #: qt/app.py:1163 msgid "ETA" msgstr "" #: qt/app.py:1225 msgid "Global" msgstr "Heiltøkur" #: qt/app.py:1226 msgid "Root" msgstr "Rót" #: qt/app.py:1227 msgid "Home" msgstr "Heim" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Trygdarritingar-skjáttur" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Navn á støðumynd" #: qt/app.py:1398 #, fuzzy msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Er tú viss/ur í at taka støðumyndina burtur" msgstr[1] "Er tú viss/ur í at taka støðumyndina burtur" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Er tú viss/ur í at taka støðumyndina burtur" msgstr[1] "Er tú viss/ur í at taka støðumyndina burtur" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Er tú viss/ur í at taka støðumyndina burtur" msgstr[1] "Er tú viss/ur í at taka støðumyndina burtur" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Er tú viss/ur í at taka støðumyndina burtur" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" #: qt/app.py:1857 msgid "Snapshot" msgstr "Støðumyndir" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Endurstovna {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Endurstovna {path}…" # ignore-placeholder-compare #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hey\n" "Tú hevur nú brúkt Back In Time á føroyskum nakrar ferðir.\n" "Umsetingin av tínari innløgdu útgávu av Back In Time til føroyskt er {perc} liðug. Tú er vælkomin til at geva eitt íkast til umsetingina og harvið eisini til sjálvt forritið Back In Time, óansæð tínar tøkniligu førleikar.\n" "Vitjað endiliga {translation_platform_url} um tú hevur hug at geva títt íkast. Um tú hevur spurningar ella brúk fyri hjálp, kanst tú vitja {back_in_time_project_website}.\n" "Hesi boðini verða ikki víst aftur, og vit biða um umbering fyri órónna. Boðini kunnu finnast aftur undir hjálparvalmyndini.\n" "Vinarliga, Back In Time toymi" #: qt/app.py:2071 msgid "translation platform" msgstr "" #: qt/app.py:2076 msgid "Website" msgstr "Heimasíða" #: qt/app.py:2090 msgid "Your translation" msgstr "" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 msgid "System default" msgstr "" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Umhvarv:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Støðumyndir:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtur:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alt" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Broytingar" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Villur" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Upplýsingar" msgstr[1] "Upplýsingar" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "" #: qt/manageprofiles/__init__.py:67 #, fuzzy msgid "Manage profiles" msgstr "Høvuðsumhvarv" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Ritstjórna" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Alment" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Tak við" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Tak skjáttur við" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Legg fílu til" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Legg skjáttu til" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "Út&iloka" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Kostir" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Framkomnir kostir" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nýtt umhvarv" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Nýnevn umhvarv" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Er tú viss/ur í at strika umhvarvið \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Tak fílu við" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Tak skjáttur við" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Skrá" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Tími:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Hvønn:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Ógilda" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Við hvørjari byrjan/endurbyrjan" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Hvønn {n} minutt" msgstr[1] "Hvønn {n} minutt" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Hvønn {n} tími" msgstr[1] "Hvønn {n} tími" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Hvønn dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Hvørja viku" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Hvønn mánað" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Hvønn ár" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(ar)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Vika(ur)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Vertur:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Brúkari:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Hvar skullu støðumyndirnar goymast" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "SSH privatur lykil:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Framkomið" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Er tú viss/ur í at broyta støðumyndaskjáttu ?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Virkja kunningar" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Einki" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Tak støðumynd burtur." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Tak støðumynd burtur." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Ár" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Tak støðumynd burtur" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dag(ar)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Vika(ur)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Um tað tøka plássið er minni enn:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Um tað tøka plássið er minni enn:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Tak gamlar støðumyndir burtir" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Umhvarv: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Arbeiði…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Støðumyndir" #: qt/qttools.py:506 msgid "Today" msgstr "Í dag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Í gjár" #: qt/qttools.py:522 msgid "This week" msgstr "Henda vikan" #: qt/qttools.py:529 msgid "Last week" msgstr "Fyrra vikan" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 #, fuzzy msgid "Command:" msgstr "Stýriboð" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Far til" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Kostir" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Tú kannst ikki samanbera eina støðumynd við sær sjálvari." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "" backintime-1.5.4/common/po/fr.po000066400000000000000000002040071477034762000165210ustar00rootroot00000000000000# French translation of Back In Time. # Copyright (C) 2008-2009 Oprea Dan # This file is distributed under the same license as the Back In Time package. # # msgid "" msgstr "" "Project-Id-Version: Back In Time 0.8.8\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-17 10:49+0000\n" "Last-Translator: bubub \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Avertissement" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (chiffré avec EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (chiffré avec EncFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Clé privée SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Local chiffré" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Chiffrement" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH chiffré" #: common/config.py:296 msgid "Default" msgstr "Par défaut" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil : \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Le dossier des instantanés n'est pas valide." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Au moins un répertoire doit être sélectionné pour la sauvegarde." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Répertoire : {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Le répertoire ne peut pas être inclus dans la sauvegarde car il fait parti " "de la destination sauvegardée." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Échec d'écriture de la nouvelle crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron n'est pas lancé, bien que la commande crontab soit disponible. Les " "sauvegardes planifiées ne seront pas exécutées. Il se pourrait que Cron soit" " installé mais pas activé. Essayez la commande \"systemctl enable cron\" ou " "consultez les canaux de support de votre distribution GNU Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Échec d'installation de la règle udev pour le profil {profile_id}. Le " "service DBus '{dbus_interface}' n'était pas disponible" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "La planification udev ne fonctionne pas avec le mode {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Impossible de trouver l'UUID pour {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Échec de l'enregistrement de la configuration" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Échec du chargement de la configuration" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Le profil \"{name}\" existe déjà." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Le dernier profil ne peut pas être supprimé." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Échec de montage de '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "La configuration du dossier chiffré est introuvable." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Créer un nouveau répertoire chiffré ?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Annuler" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Veuillez confirmer le mot de passe." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Le mot de passe ne correspond pas." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Prendre un instantané" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Échec de démontage de {mountprocess} depuis {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} non trouvé. Veuillez l'installer (par exemple avec " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Le point de montage {mntpoint} n'est pas vide." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Entrez le mot de passe pour le profil {mode} \"{profile}\" :" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "ÉCHEC" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaurer les permissions" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Terminé" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Différer la sauvegarde lors du fonctionnement sur batterie" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Répertoire des instantanés inaccessible." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "" "S'il se trouve sur un disque externe, veuillez le connecter, puis cliquez " "sur OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Prochain essai dans %s seconde." msgstr[1] "Prochain essai dans %s secondes." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Échec de l'instantané {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Veuillez patienter, c'est bientôt fini…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Échec de création du répertoire." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Enregistrement du fichier de configuration…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Enregistrement des permissions…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "L'instantané {snapshot_id} a été interrompu et peut être poursuivi." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Suppression du répertoire résiduel {snapshot_id}, datant de la dernière " "exécution" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Échec de suppression du répertoire" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Création de l'instantané" #: common/snapshots.py:1430 msgid "Success" msgstr "Succès" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transfert partiel en raison d'une erreur" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transfert partiel dû à la disparition de fichiers source (voir 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' s'est terminé avec le code d'état {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Voir 'man rsync' pour plus de détails" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Les codes d'état négatifs de rsync sont des numéros de signal, voir 'kill " "-l' et 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Aucun changement, un nouvel instantané n'est pas nécessaire" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Échec de renommage de {new_path} en {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Suppression intelligente" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Appliquer les règles pour supprimer les anciens instantanés" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Appliquer la politique de conservation" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Tentative de conservation d'un minimum d'espace libre" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Tentative pour conserver un minimum de {perc} d'inodes libres" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Maintenant" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Échec de montage de {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent introuvable. Assurez-vous qu'il soit installé." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Impossible de déverrouiller la clé privée SSH. Mot de passe incorrect ou non" " disponible pour cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Le chiffrement {cipher} a échoué pour {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Le chemin d'accès distant existe mais n'est pas un répertoire." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Le chemin d'accès distant n'est pas accessible en écriture." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Le chemin d'accès distant n'est pas exécutable." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Impossible de créer le chemin distant." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "L'hôte distant {host} n'accepte pas {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Consultez 'man backintime' pour plus d'informations" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "La vérification des commandes sur l'hôte {host} a renvoyé une erreur " "inconnue" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "L'hôte distant {host} ne prend pas en charge les liens physiques" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copie de la clé SSH publique \"{pubkey}\" sur l'hôte distant \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Veuillez fournir un mot de passe pour \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Le système de fichiers de destination pour {path} est au format NTFS, qui a " "des incompatibilités avec les systèmes de fichiers de style Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "Le chemin {path} n'est pas un répertoire valable." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Échec de création du répertoire suivant :" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "L'accès en écriture peut être restreint." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Le système de fichiers de destination pour {path} est au format FAT, qui ne " "prend pas en charge les liens physiques. Veuillez utiliser un système de " "fichiers GNU/Linux natif." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Le système de fichiers de destination pour {path} est un partage SMB. " "Assurez-vous que le serveur SMB distant autorise les liens symboliques ou " "activez \"{copyLinks}\" dans \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copier les liens (résoudre les liens symboliques)" #: common/tools.py:504 msgid "Expert Options" msgstr "Options avancées" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Le système de fichiers de destination pour {path} est un partage sshfs, qui " "ne prend pas en charge les liens physiques. Veuillez utiliser le mode 'SSH' " "à la place." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Échec de création de fichier dans le répertoire suivant :" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "À propos" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Auteurs" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traductions" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licence" #: qt/app.py:172 msgid "Shortcuts" msgstr "Raccourcis" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ce répertoire n'existe pas\n" "dans l'instantané sélectionné." #: qt/app.py:257 msgid "Add to Include" msgstr "Ajouter aux inclusions" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Ajouter aux exclusions" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} semble s'exécuter pour la première fois car aucune configuration " "n'a été trouvée." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importer une configuration existante (à partir d'un dossier de sauvegarde ou" " d'un autre ordinateur) ?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "S'il se trouve sur un disque externe, veuillez le connecter puis cliquer sur" " OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Prendre un instantané" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Utiliser la date de modification et la taille pour détecter les changements " "des fichiers." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Prendre un instantané (mode somme de contrôle)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" "Utiliser les sommes de contrôle pour détecter les changements des fichiers." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Mettre en pause la prise de l'instantané" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Reprendre la prise de l'instantané" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Arrêter la prise de l'instantané" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Rafraîchir la liste des instantanés" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nommer l'instantané" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Supprimer l'instantané" #: qt/app.py:505 msgid "View snapshot log" msgstr "Voir le journal des instantanés" #: qt/app.py:509 msgid "View last log" msgstr "Afficher le dernier journal" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gérer les profils…" #: qt/app.py:517 msgid "Shutdown" msgstr "Arrêt" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Éteindre le système après la fin de l'instantané." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurer la langue…" #: qt/app.py:525 msgid "Exit" msgstr "Quitter" #: qt/app.py:529 msgid "User manual" msgstr "Manuel d'utilisation" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Ouvrir le manuel d'utilisation dans le navigateur (en local si disponible, " "sinon en ligne)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "manuel : Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Afficher le manuel de Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "manuel : fichier de configuration des profils" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Afficher le manuel du fichier de configuration des profils (backintime-" "config)" #: qt/app.py:547 msgid "Project website" msgstr "Site web du projet" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Ouvrir le site de Back In Time dans le navigateur" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Notes de version" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Ouvrir la Foire aux questions (FAQ) dans le navigateur" #: qt/app.py:559 msgid "Ask a question" msgstr "Poser une question" #: qt/app.py:563 msgid "Report a bug" msgstr "Signaler un bogue" #: qt/app.py:566 msgid "Translation" msgstr "Traduction" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" "Affiche à nouveau le message au sujet de la participation à la traduction." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transition de chiffrement (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Affiche à nouveau le message au sujet de la suppression d'EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurer" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Restaurer les fichiers ou répertoires sélectionnés à leur emplacement " "d'origine." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurer vers …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" "Restaurer les fichiers ou répertoires sélectionnés vers un nouvel " "emplacement." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaurer le répertoire affiché et tout son contenu à l'emplacement " "d'origine." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaurer le répertoire affiché et tout son contenu vers un nouvel " "emplacement." #: qt/app.py:601 msgid "Up" msgstr "Dossier parent" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Afficher les fichiers cachés" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Comparer des instantanés…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Version candidate" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Affiche à nouveau le message de cette version candidate." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Sauvegarde" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurer" #: qt/app.py:698 msgid "&Help" msgstr "&Aide" #: qt/app.py:743 msgid "Icons only" msgstr "Icônes uniquement" #: qt/app.py:746 msgid "Text only" msgstr "Texte uniquement" #: qt/app.py:749 msgid "Text below icons" msgstr "Texte sous les icônes" #: qt/app.py:752 msgid "Text beside icon" msgstr "Texte à côté des icônes" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Si vous fermez cette fenêtre, Back In Time ne sera pas en mesure d'arrêter " "votre système lorsque l'instantané sera terminé." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Voulez-vous vraiment la fermer ?" #: qt/app.py:1072 msgid "Working:" msgstr "En cours :" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Terminé, il n'y a rien à sauvegarder" #: qt/app.py:1129 msgid "Working" msgstr "En cours" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Erreur" #: qt/app.py:1161 msgid "Sent" msgstr "Envoyé" #: qt/app.py:1162 msgid "Speed" msgstr "Vitesse" #: qt/app.py:1163 msgid "ETA" msgstr "Temps restant estimé" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Répertoire racine" #: qt/app.py:1227 msgid "Home" msgstr "Répertoire personnel" #: qt/app.py:1255 msgid "Backup directories" msgstr "Répertoires sauvegardés" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nom de l'instantané" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Êtes-vous sûr(e) de vouloir supprimer cet instantané ?" msgstr[1] "Êtes-vous sûr(e) de vouloir supprimer ces instantanés ?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Créer des copies de sauvegarde avec le suffixe '{suffix}' \n" "avant d'écraser ou de supprimer les fichiers locaux." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Les versions les plus récentes des fichiers seront renommées avec le suffixe" " '{suffix}' avant la restauration. Si vous n'en avez plus besoin, vous " "pouvez les supprimer avec la commande suivante :" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Restaurer seulement les fichiers qui n'existent pas\n" " ou qui sont plus récents que ceux de la destination.\n" "Utilise l'option \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Supprimer du répertoire d'origine les éléments plus récents." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaurer les fichiers et répertoires sélectionnés vers leur emplacement " "d'origine et supprimer les fichiers et répertoires qui ne font pas partie de" " l'instantané. Soyez prudent : cette option va supprimer les fichiers et " "répertoires qui n'étaient pas inclus dans la sauvegarde." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Voulez-vous vraiment restaurer ce fichier dans le nouveau répertoire ?" msgstr[1] "" "Voulez-vous vraiment restaurer ces fichiers dans le nouveau répertoire ?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Voulez-vous vraiment restaurer ce fichier ?" msgstr[1] "Voulez-vous vraiment restaurer ces fichiers ?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Voulez-vous vraiment supprimer tous les fichiers les plus récents dans " "{path} ?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Voulez-vous vraiment supprimer les fichiers plus récents du répertoire " "d'origine ?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Attention{BOLDEND} : Supprimer des fichiers à la racine du système de " "fichiers pourrait endommager l'ensemble de votre système." #: qt/app.py:1857 msgid "Snapshot" msgstr "Instantané" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurer {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurer {path} vers…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Bonjour\n" "Vous avez utilisé Back In Time en {language} un certain nombre de fois.\n" "La traduction en {language}de la version de Back In Time que vous avez installée est désormais {perc} terminée. Quel que soit votre niveau de connaissances techniques, vous pouvez contribuer à la traduction et donc à Back In Time même.\n" "Veuillez visiter {translation_platform_url} si vous souhaitez y participer. Pour de plus amples informations et pour toute question, merci de visiter {back_in_time_project_website}.\n" "Nous nous excusons pour l'interruption, ce message n'apparaîtra plus. Ce dialogue est accessible à tout moment via le menu Aide.\n" "L'équipe Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plateforme de traduction" #: qt/app.py:2076 msgid "Website" msgstr "Site Web" #: qt/app.py:2090 msgid "Your translation" msgstr "Votre traduction" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Dans le Fediverse chez Mastodon : {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Envoyer un courriel à {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Liste de diffusion {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} sur le site web du projet." #: qt/app.py:2118 msgid "Open an issue" msgstr "Ouvrir une discussion" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Ou aussi, par tout moyen à votre convenance." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Cette version de Back In Time est une version candidate, dont l'objectif principal est de vérifier la stabilité, en vue de la prochaine version officielle.\n" "Il n'y a pas de collecte des données d'utilisation ni de télémétrie. Cependant, l'équipe de Back In Time aimerait beaucoup savoir si cette version candidate est utilisée, et s'il y a un intérêt à poursuivre la diffusion de telles versions candidates.\n" "L'équipe vous demande donc un retour rapide de votre part, pour savoir si vous avez testé cette version, et ce même si vous n'avez pas identifié de problème. Même un retour sur un rapide essai de quelques minutes serait d'une aide importante.\n" "Vous pouvez faire un retour de plusieurs manières :\n" "{contact_list}\n" "Ce message peut être affiché à tout moment via le menu d'aide.\n" "Merci pour votre soutien et pour l'aide apportée à l'amélioration de Back In Time !\n" "Votre équipe Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Le changement de langue ne prend effet qu'après le redémarrage de Back In " "Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "La création du profil EncFS sera supprimée lors de la prochaine version " "mineure (1.7), programmée en 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Il n'est désormais plus recommandé d'utiliser ce mode pour un profil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "livre blanc" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "La prise en charge de EncFS est arrêté pour des raisons de vulnérabilités de" " la sécurité." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Pour plus de détails, incluant des alternatives potentielles, referez-vous, " "s'il vous plaît, à ce {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Les profils suivants sont chiffrés avec EncFS :" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Un remplacement est planifié, mais il n'est pas garanti qu'il arrivera à " "temps." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Les utilisateurs sont invités à rejoindre cette discussion. Les détails mise" " à jour pour les prochaines étapes sont disponibles dans ce {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ce message ne sera plus affiché. Cette boîte de dialogue est disponible à " "tout moment via le menu d'aide." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Votre équipe Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Configurer la langue" #: qt/languagedialog.py:97 msgid "System default" msgstr "Par défaut" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Utiliser la langue du système." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traduit à : {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Voir le dernier journal" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Voir le journal des instantanés" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil :" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Instantanés :" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtre :" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tous" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Modifications" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Erreurs" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Information" msgstr[1] "Informations" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Échecs de transfert rsync (expérimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Erreur, [I] Information, [C] Modification" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "décoder les chemins" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gérer les profils" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Modifier" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Ajouter" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Retirer" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Général" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inclure" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Inclure les fichiers et répertoires" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Ajouter un fichier" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Ajouter un répertoire" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Exclure" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD} : En mode 'SSH chiffré', seuls les astérisques simples " "ou doubles sont fonctionnels (par exemple {example2}). Les autres types de " "jokers et de motifs seront ignorés (par exemple {example1}). Les noms de " "fichiers sont imprévisibles dans ce mode en raison du chiffrement par EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Exclure les motifs, fichiers ou répertoires" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Ajouter par défaut" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Exclure les fichiers plus gros que :" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Exclure les fichiers plus gros que la valeur en {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Avec 'Full rsync mode' désactivé, seuls les nouveaux fichiers seront " "affectés car du point de vue de rsync c'est une option de transfert et non " "d'exclusion. Les gros fichiers transférés précédemment resteront donc dans " "l'instantané même s'ils ont été modifiés." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Suppression et Conservation" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Options" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "O&ptions avancées" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaurer la configuration" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Éditer le script de rappel (callback)" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nouveau profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renommer le profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Êtes-vous sûr(e) de vouloir supprimer le profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Fortement recommandé{ENDBOLD} : (Toutes les recommandations sont déjà " "incluses.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Fortement recommandé{ENDBOLD} : {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Exclure selon un modèle" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Exclure un fichier" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Exclure un répertoire" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inclure le fichier" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" est un lien symbolique. La cible du lien ne sera pas sauvegardée tant que vous ne l'aurez pas inclue également.\n" "Voulez-vous plutôt inclure la cible du lien ?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Inclure un répertoire" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Désactivé car ce motif n'est pas fonctionnel en mode \"SSH chiffré\"." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Planification" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Jour :" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Jour de la semaine :" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Heure :" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Heures :" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "de chaque heure" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutes :" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Exécutez Back In Time dès que le lecteur est connecté (seulement une fois " "tous les X jours). Vous serez invité à saisir votre mot de passe super-" "utilisateur." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Exécuter BackInTime à plusieurs reprises. Ce réglage est utile si " "l'ordinateur n'est pas allumé régulièrement." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Tous les :" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Activer l'enregistrement des messages de débogage" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Écrit des messages de niveau débogage dans le journal du système via \"--" "debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Attention : n'utilisez cette fonction que temporairement pour des " "diagnostics, car elle génère une grande quantité de données." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Désactivée" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "À chaque démarrage/re-démarrage" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Chaque minute" msgstr[1] "Toutes les {n} minutes" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Chaque heure" msgstr[1] "Toutes les {n} heures" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Chaque heure" msgstr[1] "Toutes les {n} heures" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Horaires personnalisées" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Tous les jours" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "À plusieurs reprises (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Quand le disque est connecté (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Chaque semaine" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Chaque mois" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Chaque année" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Heure(s)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Jour(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semaine(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mois" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Les heures personnalisées doivent être séparées par une virgule (ex : " "8,12,18,23) ou */3 pour les sauvegardes périodiques toutes les 3 heures." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Hôte :" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port :" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Utilisateur :" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Connectez-vous à l'hôte cible via ce mandataire (proxy, aussi appelé jump " "host). Voir l'option \"-J\" dans la documentation de la commande ssh ou " "\"ProxyJump\" dans celle de \"ssh_config\" pour les détails." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Attention :" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Modifiez ces options uniquement si vous savez réellement ce que vous faites." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Exécuter 'rsync' avec '{cmd}' :" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "comme une tâche cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "sur un serveur distant" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "lors d'un instantané manuel" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Veuillez installer 'nocache' pour activer cette option." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "sur la machine locale" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Rediriger stdout vers /dev/null dans les tâches cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron enverra automatiquement un email avec les résultats des cronjobs en " "pièce jointe si un MTA est installé." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Rediriger stderr vers /dev/null dans les tâches cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron enverra automatiquement un email avec les erreurs attachées des " "cronjobs si un MTA est installé." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "Ko/sec" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limiter l'utilisation de bande passante par rsync :" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Conserver les autorisations" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Conserver les attributs étendus (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Copier les liens non sécurisés (fonctionne seulement avec les liens absolus)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Limiter à un système de fichier" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" "Les arguments doivent être entourés de guillemets, par exemple : {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Passer des options supplémentaires à rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Préfixe à exécuter avant chaque commande sur l'hôte distant." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Les variables doivent être échappées avec \\$FOO. Cela n'affecte pas rsync. " "Donc, pour ajouter un préfixe à rsync, utilisez \"{example_value}\" avec " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "par défaut" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Ajouter un préfixe aux commandes SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Vérifier si l'hôte distant est en ligne" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Attention : si désactivé et si l'hôte distant n'est pas disponible, cela " "pourrait conduire à d'étranges erreurs." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Vérifier si l'hôte distant accepte toutes les commandes nécessaires." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Attention : si désactivé et que l'hôte distant ne prend pas en charge toutes" " les commandes nécessaires, cela pourrait entraîner des erreurs étranges." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(par défaut : {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "désactivé" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "activé" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mode :" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Dossier pour les sauvegardes" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Réglages SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Chemin :" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Type de chiffrement :" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Clé privée :" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Choisissez un fichier de clé privée (normalement nommé \"id_ed25519\", ou " "\"id_rsa\" pour de vieilles configurations)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Créer une nouvelle clé SSH sans mot de passe (non autorisé si un fichier de " "clé privée est déjà sélectionné)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Mot de passe" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Enregistrer le Mot de passe dans le trousseau" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Mot de passe en cache pour Cron (note de sécurité : root peut lire le mot de" " passe)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avancées" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Chemin d'accès complet de l'instantané :" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Vous n'avez pas sélectionné de fichier de clé privée pour SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Voulez-vous générer une nouvelle paire de clés publique/privée sans mot de " "passe ?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Le fichier de clé privée {file} n'existe pas." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Voulez-vous copier votre clé publique SSH sur l'hôte distant pour activer " "l'identification sans mot de passe ?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "L'authenticité de l'hôte {host} ne peut être établie." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "L'empreinte de la clé {keytype} est :" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Veuillez vérifier cette empreinte. Souhaitez-vous l'ajouter à votre fichier " "'known_hosts' ?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Voulez-vous vraiment changer le répertoire des instantanés ?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Échec de la création de la nouvelle clé SSH dans {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Activer les notifications" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Désactiver les sauvegardes automatiques en mode batterie" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Impossible d'obtenir l'état de l'alimentation du système" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Exécuter un seul instantané à la fois" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Les autres instantanés seront bloqués jusqu'à ce que l'instantané en cours " "soit terminé. Ceci une option globale. Elle affectera donc tous les profils " "de cet utilisateur. Vous devez cependant l'activer pour tous les autres " "utilisateurs." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Sauvegarder les fichiers remplacés lors de la restauration" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Les versions plus récentes des fichiers seront renommées avec le préfixe " "'{suffix}' avant la restauration. Si vous n'en avez pas besoin, vous pouvez " "les supprimer avec '{cmd}'" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuer en cas d'erreur (conserver les instantanés incomplets)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Utiliser la somme de contrôle pour détecter les changements" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Prendre un instantané qu'il y ait eu des modifications ou non." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Niveau de journalisation :" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Aucun" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Les règles suivantes sont traitées du haut vers le bas. Chaque règle est " "prioritaire sur celles qui précèdent et n'est pas contrainte par elles. Voir" " le {manual} pour les détails et des exemples." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manuel d'utilisation" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Ouvrir le manuel d'utilisation dans le navigateur." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Conserver l'instantané le plus récent." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Le dernier instantané, c'est à dire le plus récent, est conservé dans tous " "les cas." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Ce comportement ne peut pas être modifié." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Conserver les instantanés nommés." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Les instantanés portant un nom, en plus de l'horodatage habituel, seront " "conservés dans tous les cas." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Année(s)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Supprimer les instantanés plus vieux que" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Jours entiers, en ignorant le jour actuel." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Semaines calendaires, démarrant au lundi, en ignorant la semaine actuelle." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Période de 12 mois, en ignorant le mois actuel ." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Politique de conservation" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Exécuter en tâche de fond sur l'hôte distant." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "La procédure de retrait intelligente va être exécutée directement sur la " "machine distante, et non en local. Les commandes \"bash\", \"screen\" et " "\"flock\" doivent être disponibles sur la machine distante." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Si activé, Back In Time va d'abord test la machine distante." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Les jours sont comptés à partir d'aujourd'hui." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Garder tous les instantanés depuis les derniers" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "jour(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Conserver le dernier instantané de chaque jour pour les derniers" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Les semaines sont comptées depuis la semaine actuelle, avec un début de " "semaine au lundi." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Garder le instantané de chaque semaine pour les dernières" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semaine(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Les mois sont comptés de manière calendaire, en partant du mois actuel." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Garder le dernier instantané de chaque mois pour les derniers" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mois." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" "Les années sont comptées de manière calendaires, à partir de l'année " "actuelle." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Garder le dernier instantané de chaque année, pour les dernières" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "toujours." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... si l'espace libre est inférieur à" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... si le pourcentage d'inodes libres est inférieur à" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Supprimer les anciens instantanés si…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Question" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil : {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Voir la dernière entrée du journal" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Démarrer {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "En cours…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Envoyé :" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Vitesse :" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA :" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Instantanés" #: qt/qttools.py:506 msgid "Today" msgstr "Aujourd'hui" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Hier" #: qt/qttools.py:522 msgid "This week" msgstr "Cette semaine" #: qt/qttools.py:529 msgid "Last week" msgstr "La semaine dernière" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Ceci n'est PAS un instantané (sauvegarde) mais une vue de l'état actuel de " "vos fichiers locaux" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Dernière vérification {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importer la configuration" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Aucune configuration trouvée" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importer" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Sélectionnez le répertoire d'instantanés d'où doit être importé le fichier " "de configuration. Le chemin d'accès peut ressembler à : {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Si le dossier est situé sur un disque externe ou distant, il doit d'abord " "être monté." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Afficher le journal complet" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Options de la comparaison d'instantanés" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Commande :" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Paramètres :" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Utiliser %1 et %2 pour les paramètres de chemin" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Veuillez définir une commande diff ou appuyez sur Annuler." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "La commande \"{cmd}\" est introuvable sur ce système. Veuillez essayer autre" " chose ou appuyer sur Annuler." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Aucun paramètre n'a été défini pour la commande diff. Utilisation de la " "valeur par défaut \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Instantanés différents seulement" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Lister uniquement les instantanés égaux à :" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Vérification approfondie (plus précise, mais lente)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Supprimer" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Tout sélectionner" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparer" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Atteindre" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Options" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Vous ne pouvez pas comparer un instantané à lui même." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Voulez-vous vraiment supprimer {file} dans l'instantané {snapshot_id} ?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Voulez-vous vraiment supprimer {file} dans les {count} instantanés ?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "AVERTISSEMENT : Ceci ne peut être révoqué." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Exclure {path} des futurs instantanés ?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Les sous-dossiers ne peuvent pas être inclus dans la sauvegarde." backintime-1.5.4/common/po/gl.po000066400000000000000000002007311477034762000165140ustar00rootroot00000000000000# Galician translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-16 15:38+0000\n" "Last-Translator: mbouzada \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Advertencia" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Perfil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (EncFS cifrado)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS cifrado)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Chave SSH privada" #: common/config.py:283 msgid "Local encrypted" msgstr "Cifrado local" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Cifrado" #: common/config.py:289 msgid "SSH encrypted" msgstr "Cifrado SSH" #: common/config.py:296 msgid "Default" msgstr "Predeterminado" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Perfil: «{name}»" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "O directorio de instantáneas non é válido." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" "Debe seleccionarse polo menos un directorio para a copia de seguranza." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Directorio: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Non é posíbel incluír este directorio na copia de seguranza por mor de que é" " parte do destino da copia." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Produciuse un fallo escribindo no novo crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron non se está a executar aínda que está dispoñíbel a orde crontab. Os " "traballos de copia de seguranza programados non se executarán. É posible que" " Cron estea instalado pero non activado. Probe a executar «systemctl enable " "cron» ou consulte a axuda da súa distribución GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Non foi posíbel instalar a regra de Udev para o perfil {profile_id}. O " "servizo DBus «{dbus_interface}» non estaba dispoñíbel" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "A programación de udev non funciona co modo {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Non foi posíbel atopar o UUID de «{path}»" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Produciuse un erro ao gardar a configuración" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Produciuse un erro ao cargar a configuración" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "O perfil «{name}» xa existe." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Non é posíbel revogar o último perfil." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Non é posíbel montar «{command}»" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Non se atopou a configuración do directorio cifrado." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Quere crear un novo directorio cifrado?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Cancelar" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Confirme o contrasinal." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "O contrasinal non coincide." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Facer unha instantánea" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Non é posíbel desmontar {mountprocess} de {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "Non se atopou {command}. Instáleo, por exemplo con {installcommand}" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "O punto de montaxe {mntpoint} non está libre." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Introduza o contrasinal do perfil de {mode} ({profile}):" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FALLOU" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaurar os permisos" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Feito" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Adiando a copia de seguranza mentres se usa a batería" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Non é posíbel atopar o directorio de instantáneas." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Se está nunha unidade extraíbel, conéctea." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Agardando %s segundo." msgstr[1] "Agardando %s segundos." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Produciuse un fallo ao facer a instantánea {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Teña paciencia. Finalizando…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Non é posíbel crear o directorio." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Gardando o ficheiro de configuración…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Gardando os permisos…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Atopáronse restos da instantánea {snapshot_id} cos que se pode continuar." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Retirando o directorio {snapshot_id} sobrante da última execución" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Non é posíbel retirar o directorio" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Facer instantánea" #: common/snapshots.py:1430 msgid "Success" msgstr "Satisfactorio" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transferencia incompleta por mor dun fallo" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferencia incompleta por desapareceren os ficheiros orixinais (véxase " "«man rsync»)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "«rsync» rematou co código {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Véxase «man rsync» para obter máis información" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Se rsync devolve un código negativo, iso é o código dun sinal. Véxanse as " "ordes «kill -l» e «man kill»" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Non se precisa unha instantánea nova porque non houbo cambios" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Non é posíbel cambiar o nome de {new_path} a {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Remoción intelixente" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Aplicar regras para eliminar instantáneas antigas" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Aplicar a directiva de retención" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Tentar preservar o espazo libre mínimo" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Tentando manter un mínimo de {perc} inodos libres" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Agora" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Non é posíbel montar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "Non se atopou ssh-agent. Asegúrese de que está instalado." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Non foi posíbel desbloquear a chave ssh privada. O contrasinal é incorrecto " "ou non está dispoñíbel para cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Fallou o cifrado {cipher} para {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "A ruta remota existe mais non é un cartafol." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "A ruta remota non permite a escritura." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "A ruta remota non é executábel." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Non foi posíbel crear a ruta remota." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "O servidor remoto {host} non admite {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Vexa «man backintime» para obter máis instrucións" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "As ordes de comprobación no servidor {host} devolveron un fallo descoñecido" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "O servidor remoto {host} non admite ligazóns duras" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copiar a chave ssh pública «{pubkey}» ao servidor remoto «{host}»." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Introduza o contrasinal de «{user}»." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "O sistema de ficheiros de destino de {path} está formatado con NTFS, que ten" " incompatibilidades coñecidas cos sistemas de ficheiros de estilo Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} non é un directorio válido." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Produciuse un fallo ao crear o seguinte directorio:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "O acceso para escritura pode estar restrinxido." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "O sistema de ficheiros de destino para {path} está formatado con FAT, o cal " "non admite ligazóns fortes. Use un sistema de ficheiros nativo de GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "O sistema de ficheiros de destino para {path} é un recurso compartido " "montado mediante SMB. Asegúrese de que o servidor SMB remoto admite ligazóns" " simbólicas ou active «{copyLinks}» en «{expertOptions}»." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copiar as ligazóns (desbotar as ligazóns simbólicas)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opcións avanzadas" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "O sistema de ficheiros de destino para {path} é un recurso compartido " "montado mediante sshfs. Sshfs non admite ligazóns fortes. En troques use o " "modo «SSH»." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Produciuse un fallo ao crear o ficheiro neste directorio:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Sobre" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autores" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traducións" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenza" #: qt/app.py:172 msgid "Shortcuts" msgstr "Atallos" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Este directorio non existe\n" "na actual instantánea seleccionada." #: qt/app.py:257 msgid "Add to Include" msgstr "Engadir á lista de inclusión" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Engadir á lista de exclusión" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Semella que é a primeira vez que se executa {app_name} xa que non se atopou " "ningunha configuración." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importar unha configuración existente (dende un directorio de destino de " "copia de seguranza ou doutro computador)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Se está nunha unidade extraíbel, conéctea e prema en Aceptar." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Facer unha instantánea" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Usar a data de modificación e o tamaño para atopar ficheiros modificados." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Facer unha instantánea (con suma de comprobación)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Usar a suma de comprobación para detectar cambios." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausar o proceso de instantánea" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Continuar co proceso de instantánea" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Cancelar o proceso de instantánea" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Actualizar a lista de instantáneas" #: qt/app.py:497 msgid "Name snapshot" msgstr "Renomear a instantánea" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Retirar a instantánea" #: qt/app.py:505 msgid "View snapshot log" msgstr "Ver o rexistro de instantáneas" #: qt/app.py:509 msgid "View last log" msgstr "Ver o último rexistro" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Xestionar perfís…" #: qt/app.py:517 msgid "Shutdown" msgstr "Apagar" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Apagar o sistema ao rematar a instantánea." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurar o idioma…" #: qt/app.py:525 msgid "Exit" msgstr "Saír" #: qt/app.py:529 msgid "User manual" msgstr "Manual de usuario" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Abrir o manual de usuario no navegador (local se está dispoñíbel, senón, en " "liña)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "páxina de inicio: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Amosar a páxina de inicio sobre Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "páxina de inicio: Ficheiro de configuración dos perfís" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Amosar a páxina de inicio sobre o ficheiro de configuración de perfís " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Sitio web do proxecto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Abrir o sitio web de Back In Time no navegador" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Rexistro de cambios" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ (preguntas frecuentes)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Abrir as preguntas frecuentes (FAQ) no navegador" #: qt/app.py:559 msgid "Ask a question" msgstr "Faga unha pregunta" #: qt/app.py:563 msgid "Report a bug" msgstr "Informar dun fallo" #: qt/app.py:566 msgid "Translation" msgstr "Tradución" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Amosa de novo a mensaxe sobre colaborar na tradución." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transición do cifrado (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Amosa de novo a mensaxe sobre a retirada de EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurar" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Restaurar os ficheiros ou directorios seleccionados no seu destino orixinal." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurar en…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Restaurar os ficheiros ou directorios seleccionados nun novo destino." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaurar o directorio amosado actualmente e todo o seu contido ao destino " "orixinal." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaurar o directorio amosado actualmente e todo o seu contido a un novo " "destino." #: qt/app.py:601 msgid "Up" msgstr "Subir" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Amosar os ficheiros agochados" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Comparar instantáneas…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Versión candidata" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Amosa de novo a mensaxe sobre esta versión candidata." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Copia de seguranza" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurar" #: qt/app.py:698 msgid "&Help" msgstr "A&xuda" #: qt/app.py:743 msgid "Icons only" msgstr "Só iconas" #: qt/app.py:746 msgid "Text only" msgstr "Só texto" #: qt/app.py:749 msgid "Text below icons" msgstr "Texto baixo as iconas" #: qt/app.py:752 msgid "Text beside icon" msgstr "Texto a carón das iconas" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Se pecha esta xanela Back In Time non poderá apagar o seu sistema cando " "remate a instantánea." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Confirma que quere pechala?" #: qt/app.py:1072 msgid "Working:" msgstr "En proceso:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Rematado, non foi necesario facer unha copia de seguranza" #: qt/app.py:1129 msgid "Working" msgstr "En proceso" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Erro" #: qt/app.py:1161 msgid "Sent" msgstr "Enviada" #: qt/app.py:1162 msgid "Speed" msgstr "Velocidade" #: qt/app.py:1163 msgid "ETA" msgstr "Tempo restante estimado" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Raíz" #: qt/app.py:1227 msgid "Home" msgstr "Inicio" #: qt/app.py:1255 msgid "Backup directories" msgstr "Directorios de copia de seguranza" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nome da instantánea" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Confirma que quere eliminar esta instantánea?" msgstr[1] "Confirma que quere eliminar estas instantáneas?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Crear copias de seguranza cun {suffix} ao final antes\n" "de substituír ou retirar elementos locais." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "As versións máis recentes dos ficheiros renomearanse cun {suffix} ao final " "antes de restauralos. Se xa non os precisa, pode eliminalos coa seguinte " "orde:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Restaurar só os ficheiros que non existan ou\n" "que sexan máis recentes que os do destino.\n" "Empregando a opción «rsync --update»." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Retirar os ficheiros máis recentes do directorio orixinal." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaurar os ficheiros ou directorios seleccionados ao destino orixinal e " "eliminar os ficheiros ou directorios que non estean na instantánea. Vaia " "amodo, xa que isto eliminará os ficheiros e directorios excluídos ao facer a" " instantánea." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Confirma que quere restaurar este elemento no novo directorio?" msgstr[1] "Confirma que quere restaurar estes elementos no novodirectorio?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Confirma que quere restaurar este elemento?" msgstr[1] "Confirma que quere restaurar estes elementos?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Confirma que quere eliminar os ficheiros máis recentes de {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Confirma que quere retirar todos os ficheiros recentes do directorio " "orixinal?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Advertencia{BOLDEND}: a eliminación de ficheiros na raíz do sistema de" " ficheiros pode estragar todo o sistema." #: qt/app.py:1857 msgid "Snapshot" msgstr "Instantánea" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurar {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurar {path} en…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Ola!\n" "Xa utilizou Back In Time en {language} varias veces.\n" "A tradución ao {language} da versión de Back In Time que ten instalada está completa só ao {perc}. Independentemente dos seus coñecementos técnicos, pode colaborar na tradución e, polo tanto, co propio Back In Time.\n" "Se quere colaborar, visite {translation_platform_url}. Para obter máis axuda ou resposta ás posíbeis preguntas, visite {back_in_time_project_website}.\n" "Descúlpenos a interrupción, esta mensaxe non volverá ser amosada. Pode abrir de novo este diálogo en calquera momento no menú de axuda.\n" "O equipo de Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plataforma de tradución" #: qt/app.py:2076 msgid "Website" msgstr "Sitio web" #: qt/app.py:2090 msgid "Your translation" msgstr "A súa tradución" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "No Fediverso en Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Enviar correo a {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Lista de correo {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} no sitio web do proxecto." #: qt/app.py:2118 msgid "Open an issue" msgstr "Abrir unha incidencia" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Tamén pode empregar outra canle da súa elección." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Esta versión de Back In Time é unha edición candidata e está pensada principalmente para probas de estabilidade en preparación para a próxima edición oficial.\n" "Non se recollen datos de usuario nin telemetría. Porén, o equipo de Back In Time está moi interesado en saber se se está a utilizar a edición candidata e se paga a pena seguir fornecendo estas edicións preliminares.\n" "Polo tanto, o equipo pídelle amablemente un breve comentario sobre se probou esta versión, aínda que non teña atopado ningún incidente. Incluso unha proba rápida duns minutos axudaríanos moito.\n" "Ten ao seu dispor as seguintes opcións de contacto:\n" "{contact_list}\n" "Nesta versión, esta mensaxe non volverá amosarse, mais pódese acceder en calquera momento a través do menú de axuda.\n" "Grazas polo seu apoio e por axudarnos a mellorar Back In Time!\n" "O equipo de Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Os axustes de idioma só teñen efecto após reiniciar Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "A creación de perfís EncFS eliminarase na próxima versión menor (1.7), " "prevista para o 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Ademais, non se recomenda utilizar ese modo para un perfil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "documento técnico" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "A compatibilidade con EncFS está a ser descontinuado por mor de " "vulnerabilidades da seguranza." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Para obter máis detalles, incluíndo potenciais alternativas, consulte este " "{whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Os seguinte (ou seguintes) perfís usan cifrado con EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Está previsto un substituto, mais non se pode garantir que chegue a tempo." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Os usuarios están convidados a unirse a esta discusión. Os detalles " "actualizados sobre os próximos pasos están dispoñibles neste {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Esta mensaxe non volverá ser amosada. Este diálogo está dispoñíbel en " "calquera momento a través do menú de axuda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "O equipo de Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Configurar o idioma" #: qt/languagedialog.py:97 msgid "System default" msgstr "Predeterminado do sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Empregar o idioma do sistema operativo." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traducido: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Vista do último rexistro" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Vista do rexistro de instantáneas" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Perfil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Instantáneas:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtro:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Todo" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Cambios" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Erros" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Información" msgstr[1] "Informacións" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Fallos nas transferencia de rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Erro, [I] Información, [C] Cambio" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "descodificar rutas" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Xestionar perfís" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editar" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Engadir" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Retirar" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Xeral" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Incluír" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Incluír os ficheiros e os directorios" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Engadir ficheiro" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Engadir directorio" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Excluír" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Información{ENDBOLD}: no modo «Cifrado SSH», só funcionan os " "asteriscos simples ou dobres (p. ex., {example2}). Ignoraranse outros tipos " "de comodíns e patróns (p. ex., {example1}). Os nomes de ficheiros son " "imprevisíbeis neste modo por mor do cifrado de EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Excluír os patróns, ficheiros ou directorios" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Engadir predeterminado" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Excluír ficheiros maiores de:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Excluír os ficheiros máis grandes que o valor en {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Co «Modo rsync completo» desactivado isto só afectará aos novos ficheiros " "porque para rsync é unha opción de transferencia, non de exclusión. Por iso," " os ficheiros grandes que se copiaron antes permanecerán nas copias, mesmo " "se tiveron cambios." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Retirada e retención" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opcións" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "O&pcións avanzadas" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaurar a configuración" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editar a devolución de chamada do usuario" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Perfil novo" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renomear o perfil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Confirma que quere eliminar o perfil «{name}»?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Moi recomendado{ENDBOLD}: (Todas as recomendacións xa incluídas.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Moi recomendado{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Excluír o patrón" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Excluír o ficheiro" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Excluír o directorio" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Incluír o ficheiro" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "«{path}» é unha ligazón simbólica. Non se fará unha copia de seguranza do destino ligado ata que tamén o inclúa.\n" "Quere incluír, en troques, o destino da ligazón simbólica?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Incluír o directorio" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Foi desactivado porque este patrón non funciona no modo «SSH cifrado»." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Programar" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Día:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Día da semana:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tempo:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Horas:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "após a hora" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutos:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Executar Back In Time cando se conecte a unidade (só unha vez cada X días). " "Pediráselle o seu contrasinal para sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Executar Back In Time repetidamente. Útil se o computador non ten un " "funcionamento regular." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Cada:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Activar o rexistro de mensaxes de depuración" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Escribe mensaxes de nivel de depuración no rexistro do sistema mediante " "«--debug»." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Precaución: úseo só ocasionalmente para diagnósticos, xa que xera unha gran " "cantidade de resultados." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Desactivado" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "En todos os arranques" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Cada {n} minuto" msgstr[1] "Cada {n} minutos" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Cada hora" msgstr[1] "Cada {n} horas" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Cada {n} hora" msgstr[1] "Cada {n} horas" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Horas personalizadas" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Todos os días" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetidamente (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Cando a unidade se conecte (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Todas as semanas" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Todos os meses" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Todos os anos" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hora(s)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Día(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semana(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mes(es)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "As horas personalizadas só poden ser unha lista de horas separadas por comas" " (p. ex.: 8,12,18,23) ou */3 para copias periódicas cada 3 horas." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Servidor:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Porto:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usuario:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Conéctese ao servidor de destino a través deste proxy (tamén coñecido como " "servidor de salto). Consulte «-J» na documentación da orde «ssh» ou " "«ProxyJump» na páxina de man «ssh_config» para obter máis detalles." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Precaución:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Estas opcións son para configuracións avanzadas. Modifíqueas só se é " "plenamente consciente das implicacións." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Executar «rsync» con «{cmd}»:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "como un traballo de cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "nun servidor remoto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "ao facer unha instantánea manual" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Instale «nocache» para activar esta opción." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na máquina local" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirixir stdout a /dev/null en cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron enviará automaticamente un correo coa saída adxunta de cronjobs se hai " "un MTA instalado." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirixir stderr a /dev/null en cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron enviará automaticamente un correo con erros de cronjobs adxuntos se hai" " un MTA instalado." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limitar o uso do largo de banda de rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preservar ACL (listas de control de acceso)" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preservar os atributos estendidos (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Copiar as ligazóns non seguras (funciona só con ligazóns absolutas)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Restrinxir a un sistema de ficheiros" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "As opcións deben levar comiñas p.e. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Pegar as opcións adicionais a rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefixo a executar antes de cada orde no servidor remoto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "As variábeis deben escaparse con \\$FOO. Isto non afecta a rsync. Polo " "tanto, para engadir un prefixo para rsync, use «{example_value}» con " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "predeterminado" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Engadir prefixo ás ordes de SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Comprobar se o servidor remoto está en liña" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Advertencia: se está desactivado e o servidor remoto non estiver dispoñíbel," " poderíanse producir erros estraños." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Comprobar se o servidor remoto acepta todas as ordes necesarias." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Advertencia: se está desactivado e o servidor remoto non admite as ordes " "necesarias, poderíanse producir erros estraños." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(predeterminado: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "desactivado" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "activado" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modo:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Onde gardar as instantáneas" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Axustes SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Ruta:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifrado:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Chave privada:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Escolla un ficheiro de chave privada existente (normalmente chamado " "«id_ed25519» e en configuracións máis antigas «id_rsa»)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Crear unha nova chave SSH sen contrasinal (non permitido se xa foi " "seleccionado un ficheiro de chave privada)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Contrasinal" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Gardar o contrasinal no chaveiro" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Gardar o contrasinal de Cron na memoria tobo (problema de seguranza: root " "pode ler o contrasinal)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avanzado" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Ruta completa á instantánea:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Non escolleu un ficheiro de chave privada para SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Gustaríalle xerar un par de chaves pública/privada sen contrasinal?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Non existe o ficheiro coa chave privada «{file}»." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Quere copiar a súa chave SSH ao servidor remoto para activar o acceso sen " "contrasinal?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Non é posíbel estabelecer a autenticidade do servidor {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "A pegada dixital da chave {keytype} é:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verifique esta pegada dixital! Quere engadila ao seu ficheiro «known_hosts»?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Confirma que quere cambiar o directorio de instantáneas?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Produciuse un fallo ao crear a nova chave SSH en {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Activar as notificacións" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Desactivar as instantáneas cando estea coa batería" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "O estado da alimentación non está dispoñíbel no sistema" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Executar só unha instantánea á vez" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "As outras instantáneas bloquearanse ata que remate de facerse a actual. Esta" " é unha opción global. Afectará a todos os perfís deste usuario. Mais tamén " "debe activar isto para o resto de usuarios." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Copia de seguranza dos ficheiros substituídos na restauración" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "As versións máis recentes dos ficheiros renomearanse cun {suffix} ao final " "antes de restauralos. Se xa non os precisa, pode eliminalos con {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuar con erros (manter instantáneas incompletas)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Usar a suma de comprobación para detectar cambios" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Facer unha nova instantánea aínda que non houbese cambios." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivel do rexistro:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ningún" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "As seguintes regras procesanse de arriba abaixo. As regras posteriores " "anulan as anteriores e non están restrinxidas por elas. Consulte o {manual} " "para obter máis detalles e exemplos." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual do usuario" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Abrir o manual de usuario no navegador." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Non eliminar a instantánea máis recente." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "A última ou máis recente das instantáneas conservase en todas as " "circunstancias." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Non é posíbel cambiar este comportamento." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Non eliminar as instantáneas con nome." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "As instantáneas ás que se lles deu un nome, ademais da marca de tempo " "habitual, conservaranse en todas as circunstancias e non se eliminarán." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Ano(s)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Retirar as instantáneas máis antigas que" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Días completos. O día actual ignorase." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Semanas naturais co luns como primeiro día. A semana actual ignorase." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Períodos de 12 meses. O mes actual ignórase." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Directiva de retención" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Executar en segundo plano no servidor remoto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "O procedemento de eliminación intelixente executarase directamente na " "máquina remota, non localmente. As ordes «bash», «screen» e «flock» deben " "estar instaladas e dispoñíbeis na máquina remota." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Se se selecciona, Back In Time probará primeiro a máquina remota." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Os días cóntanse a partir de hoxe." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Conservar todas as instantáneas dos últimos" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "día(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Conservar a última instantánea de cada día para o último día" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "As semanas cóntanse a partir da semana actual. Unha semana comeza o luns." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Conservar a última instantánea por semana para a última semana" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semana(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Os meses cóntanse como meses naturais a partir do mes en curso." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Conservar a última instantánea de cada mes para o último mes" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mes(es)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Os anos cóntanse como anos naturais a partir do ano en curso." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Conservar a última instantánea de cada ano para o último ano" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "todos os anos." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… o espazo libre é inferior a" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… os inodos libres son menos do" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Retirar as instantáneas antigas se…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pregunta" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Perfil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Ver o último rexistro" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Iniciar {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "En proceso…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Enviada:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocidade:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Tempo restante estimado:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Instantáneas" #: qt/qttools.py:506 msgid "Today" msgstr "Hoxe" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Onte" #: qt/qttools.py:522 msgid "This week" msgstr "Esta semana" #: qt/qttools.py:529 msgid "Last week" msgstr "A semana pasada" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Esta NON é unha instantánea senón unha vista actual dos ficheiros locais" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Última comprobación {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importar a configuración" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Non se atopou ningunha configuración" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Seleccione o directorio de instantáneas dende o que se debe importar o " "ficheiro de configuración. A ruta pode ter este aspecto: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Se o directorio está situado nunha unidade externa ou remota, debe montarse " "previamente de xeito manual." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Amosar o rexistro completo" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opcións para comparar instantáneas" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Orde:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parámetros:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Usar %1 e %2 como parámetros da ruta" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Defina unha orde diff ou prema en Cancelar." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Non é posíbel atopar a orde «{cmd}» neste sistema. Tente outra cousa ou " "prema en Cancelar." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Non se definiu ningún parámetro para a orde diff. Usando o valor " "predeterminado «{params}»." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Só instantáneas con diferenzas" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Listar só as instantáneas iguais a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Comprobación exhaustiva (máis precisa pero máis lenta)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Eliminar" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Seleccionar todo" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparar" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ir a" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcións" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Non é posíbel comparar unha instantánea con ela mesma." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Confirma que quere eliminar «{file}» na instantánea «{snapshot_id}»?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Confirma que quere eliminar «{file}» de {count} instantáneas?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ADVERTENCIA: isto non se pode revogar." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Excluír {path} de instantáneas futuras?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Non é posíbel incluír os subdirectorios na copia de seguranza." backintime-1.5.4/common/po/he.po000066400000000000000000002104321477034762000165050ustar00rootroot00000000000000# Hebrew translation for backintime # Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2008. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-16 15:38+0000\n" "Last-Translator: Yaron Shahrabani \n" "Language-Team: Hebrew \n" "Language: he\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "אזהרה" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "פרופיל ראשי" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "מקומי (בהצפנת EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (בהצפנת EncFS)" #: common/config.py:278 msgid "Local" msgstr "מקומי" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "מפתח SSH פרטי" #: common/config.py:283 msgid "Local encrypted" msgstr "בהצפנה מקומית" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "הצפנה" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH מוצפן" #: common/config.py:296 msgid "Default" msgstr "ברירת מחדל" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "פרופיל: „{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "תיקיית תמונות מצב אינה תקנית." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "יש לבחור לפחות תיקייה אחת לגיבוי." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "תיקייה: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "אי אפשר לכלול את התיקייה בגיבוי כיוון שהיא חלק מיעד הגיבוי עצמו." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "כתיבת crontab חדש נכשלה." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron לא פעיל למרות שהפקודה crontab זמינה. משימות גיבוי מתוזמנות לא תרוצנה. " "כנראה ש־Cron מותקן אבל לא מופעל. כדאי לנסות להריץ את הפקודה „systemctl " "enable cron” או להיוועץ בערוצי התמיכה של הפצת הגנו/לינוקס שלך." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "לא ניתן להתקין כלל Udev לפרופיל {profile_id}. שירות ה־D-Bus‏ " "‚{dbus_interface}’ לא היה זמין" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "תזמון udev לא עובד עם המצב {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "לא ניתן למצוא מזהה ייחודי ל־{path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "שמירת ההגדרות נכשלה" #: common/configfile.py:137 msgid "Failed to load config" msgstr "טעינת ההגדרות נכשלה" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "הפרופיל „{name}” כבר קיים." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "אי אפשר להסיר את הפרופיל האחרון." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "אי אפשר לעגן את ‚{command}’" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "לא נמצאו הגדרות לתיקייה מוצפנת." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "ליצור תיקייה מוצפנת חדשה?" #: common/encfstools.py:146 msgid "Cancel" msgstr "ביטול" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "נא לאשר את הסיסמה." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "הסיסמאות לא תואמות." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "שמירת תמונת מצב" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "לא ניתן לנתק את העיגון {mountprocess} מ־{mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "פקודה {command} לא נמצאה. אפשר להתקין את הפקודה (בעזרת \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "נקודת העיגון {mntpoint} לא ריקה." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "הכנס סיסמא בשביל {mode} משתמש \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "נכשל" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "שחזור הרשאות" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "בוצע" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "הגיבוי מושהה בעת שימוש בסוללה" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "לא ניתן למצוא את תיקיית תמונות המצב." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "אם היא נמצאת על כונן נשלף יש לחבר אותו." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "בהמתנה של שנייה אחת." msgstr[1] "בהמתנה של %s שניות." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "שמירת תמונת המצב {snapshot_id} נכשלה." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "נא להתאזר בסבלנות. התהליך מסתיים…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "לא ניתן ליצור את התיקייה." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "קובץ ההגדרות נשמר…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "הרשאות נשמרות…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "נמצאו שאריות של תמונת מצב {snapshot_id} שאפשר להמשיך." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "התיקייה {snapshot_id} שנשארה מהריצה האחרונה נמחקת" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "לא ניתן להסיר תיקייה" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "תמונת מצב נשמרת" #: common/snapshots.py:1430 msgid "Success" msgstr "הצלחה" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "שגיאה: בוצעה העברה חלקית בלבד" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "העברה חלקית עקב קובצי מקור שנעלמו (ר׳ ‚man rsync’)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "‚rsync’ הסתיים עם קוד היציאה {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "קרא את 'man rsync' לפרטים נוספים" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "קודים שליליים ביציאה של rsync הם מספרי אותות, ר׳ ‚kill -l’ ו־‚man kill’" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "דבר לא השתנה, לא צריך תמונת מצב חדשה" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "לא ניתן לשנות את השם {new_path} ל־{path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "הסרה חכמה" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "החלת כללים להסרת תמונות מצב ישנות" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "החלת מדיניות שימור" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "מתבצע ניסיון לשמור על מקום פנוי מזערי" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "מתבצע ניסיון לשמור לפחות {perc} מה־inodes פנויים" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "עכשיו" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "לא ניתן לעגן את {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent לא נמצא. נא לוודא שהוא מותקן." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "לא ניתן לשחרר את נעילת מפתח ה־ssh הפרטי. הסיסמה שגויה או שהסיסמה לא זמינה " "ל־cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "מצפין {cipher} נכשל עבור המשתמש {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "הנתיב המרוחק קיים אך הוא לא תיקייה." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "לא ניתן לכתוב לנתיב המרוחק." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "הנתיב המרוחק לא ניתן להפעלה." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "לא ניתן ליצור את הנתיב המרוחק." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "מארח מרוחק {host} לא תומך בפקודה {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "קרא את 'man backintime' להוראות נוספות" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "פקודות הבדיקה שרצו על {host} החזירו שגיאה לא ידועה" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "המארח המרוחק {host} לא תומך בקישורים קשיחים" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "העתקת מפתח ה־SSH הציבורי „{pubkey}” למארח המרוחק „{host}”." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "נא למלא סיסמה למשתמש „{user}”." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "מערכת הקבצים המיועדת ל־{path} מפורמטת ל־NTFS, שידועה בחוסר התאימות שלה " "למערכות קבצים תואמות יוניקס." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} אינה תיקייה תקפה." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "יצירת התיקייה הבאה נכשלה:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "גישת הכתיבה כנראה מוגבלת." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "מערכת הקבצים המיועדת ל־{path} מפורמטת ל־FAT שבה אין תמיכה בקישורים קשיחים. " "נא להשתמש במערכת קבצים טבעית של גנו/לינוקס." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "מערכת היעד עבור {path} היא שיתוף SMB מעוגן. נא לוודא ששרת ה־SMB המרוחק תומך " "בקישורים סמליים או להפעיל את„ {copyLinks}” תחת „{expertOptions}”." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "העתקת קישורים (ביטול הפניה של קישורים סמליים)" #: common/tools.py:504 msgid "Expert Options" msgstr "אפשרויות מתקדמות" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "מערכת הקבצים המיועדת עבור {path} היא שיתוף בעיגון sshfs. ב־sshfs אין תמיכה " "בקישורים קשיחים. נא להשתמש במצב „SSH” במקום." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "יצירת קבצים בתיקייה הזאת נכשלה:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "על אודות" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "יוצרים" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "תרגומים" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "רישיון" #: qt/app.py:172 msgid "Shortcuts" msgstr "קיצורים" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "התיקייה הזאת לא קיימת\n" "בתמונת המצב הנוכחית שנבחרה." #: qt/app.py:257 msgid "Add to Include" msgstr "הוספה להכללה" #: qt/app.py:259 msgid "Add to Exclude" msgstr "הוספה להחרגה" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "נראה כי {app_name} עולה לראשונה כיוון שלא נמצאו הגדרות." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "לייבא הגדרות קיימות (מתיקיית יעד גיבוי או ממחשב אחר)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "אם היא נמצאת על כונן נשלף יש לחבר אותו וללחוץ על אישור." #: qt/app.py:470 msgid "Take a snapshot" msgstr "שמירת תמונת מצב" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "להשתמש בזמן השינוי ובגודל לזיהוי שינויים בקובץ." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "שמירת תמונת מצב (עם סיכומי ביקורת)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "להשתמש בסיכומי ביקורת לאיתור שינויים." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "השהיית שמירת תמונת מצב" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "המשך שמירת תמונת מצב" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "עצירת שמירת תמונת מצב" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "רענון רשימת תמונות המצב" #: qt/app.py:497 msgid "Name snapshot" msgstr "מתן שם לתמונת מצב" #: qt/app.py:501 msgid "Remove snapshot" msgstr "הסרת תמונת מצב" #: qt/app.py:505 msgid "View snapshot log" msgstr "הצגת יומן תמונות מצב" #: qt/app.py:509 msgid "View last log" msgstr "הצגת היומן האחרון" #: qt/app.py:513 msgid "Manage profiles…" msgstr "ניהול פרופילים…" #: qt/app.py:517 msgid "Shutdown" msgstr "כיבוי" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "לכבות את המערכת אחרי ששמירת תמונת המצב הסתיימה." #: qt/app.py:521 msgid "Setup language…" msgstr "הגדרות שפה…" #: qt/app.py:525 msgid "Exit" msgstr "יציאה" #: qt/app.py:529 msgid "User manual" msgstr "מדריך למשתמשים" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "פתיחת מדריך המשתמש בדפדפן (מקומי אם זמין או מקוון אם לא)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "עמוד ה־man‏: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "הצגת עמוד man על Back In Time ‏(backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "עמוד man: קובץ הגדרת פרופילים" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "הצגת עמוד man על קובץ הגדרת פרופילים (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "אתר המיזם" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "פתיחת אתר Back In Time בדפדפן" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "יומן שינויים" #: qt/app.py:555 msgid "FAQ" msgstr "שאלות ותשובות" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "פתיחת שאלות נפוצות (שו״ת) בדפדפן" #: qt/app.py:559 msgid "Ask a question" msgstr "פרסום שאלה" #: qt/app.py:563 msgid "Report a bug" msgstr "דיווח על תקלה" #: qt/app.py:566 msgid "Translation" msgstr "תרגום" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "הצגת ההודעה בנוגע להשתתפות בתרגום שוב." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "תעבורה מוצפנת (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "הצגת ההודעה על הסרת EncFS שוב." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "שחזור" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "שחזור הקבצים או התיקיות הנבחרים ליעד המקורי." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "שחזור אל…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "שחזור הקבצים או התיקיות הנבחרים ליעד חדש." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "שחזור התיקייה שמופיעה ואת כל התוכן שלה ליעד המקורי." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "שחזור התיקייה שמופיע ואת כל התוכן שלה ליעד חדש." #: qt/app.py:601 msgid "Up" msgstr "למעלה" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "הצגת קבצים נסתרים" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "השוואת תמונות מצב…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "מועמדת להוצאה לאור" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "הצגת ההודעה על המועמדת להוצאה לאור שוב." #: qt/app.py:676 msgid "Back In &Time" msgstr "&חזרה בזמן" #: qt/app.py:681 msgid "&Backup" msgstr "&גיבוי" #: qt/app.py:692 msgid "&Restore" msgstr "&שחזור" #: qt/app.py:698 msgid "&Help" msgstr "ע&זרה" #: qt/app.py:743 msgid "Icons only" msgstr "סמלים בלבד" #: qt/app.py:746 msgid "Text only" msgstr "טקסט בלבד" #: qt/app.py:749 msgid "Text below icons" msgstr "טקסט מתחת לסמלים" #: qt/app.py:752 msgid "Text beside icon" msgstr "טקסט ליד הסמלים" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "סגירת החלון תגרום לכך של־Back In Time לא תהיה אפשרות לכבות את המערכת שלך עם " "סיום שמירת תמונת המצב." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "לסגור אותו?" #: qt/app.py:1072 msgid "Working:" msgstr "בעבודה:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "הסתיים, לא נדרש גיבוי" #: qt/app.py:1129 msgid "Working" msgstr "בעבודה" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "שגיאה" #: qt/app.py:1161 msgid "Sent" msgstr "נשלח" #: qt/app.py:1162 msgid "Speed" msgstr "מהירות" #: qt/app.py:1163 msgid "ETA" msgstr "זמן משוערך" #: qt/app.py:1225 msgid "Global" msgstr "כללי" #: qt/app.py:1226 msgid "Root" msgstr "תיקיית העל" #: qt/app.py:1227 msgid "Home" msgstr "תיקיית הבית" #: qt/app.py:1255 msgid "Backup directories" msgstr "תיקיות גיבוי" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "שם תמונת המצב" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "להסיר את תמונת המצב?" msgstr[1] "להסיר את תמונות המצב?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "ליצור עותקי גיבוי עם {suffix} כסיומת.\n" "בטרם שכתוב או הסרה של רכיבים מקומיים." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "לגרסאות חדשות יותר של הקבצים יתווסף {suffix} לסוף השם לפני האחסון. אם אין " "בהם צורך עוד אפשר להסיר אותם עם הפקודה הבאה:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "לשחזר רק קבצים שלא נמצאים או\n" "שהם חדשים יותר מאלו ביעד.\n" "באמצעות האפשרות „rsync --update”." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "הסרת רכיבים חדשים יותר בתיקייה המקורית." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "שחזור הקבצים או התיקיות הנבחרי ליעדם המקורי ולמחוק קבצים ותיקיות שאינם " "בתמונת המצב. חובה לנקוט במשנה זהירות כיוון שהפעולה הזאת תמחק קבצים ותיקיות " "שהוחרגו במהלך הכנת תמונת המצב." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "לשחזר את הרכיב הזה לתיקייה החדשה?" msgstr[1] "לשחזר את הרכיבים האלה לתיקייה החדשה?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "לשחזר את הרכיב הזה?" msgstr[1] "לשחזר את הרכיבים האלה?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "להסיר את כל הקבצים החדשים יותר תחת {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "להסיר את כל הקבצים החדשים בתיקיית המקור שלך?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}אזהרה{BOLDEND}: מחיקת קבצים בשורש מערכת הקבצים יכולה לשבש את כל המערכת" " שלך." #: qt/app.py:1857 msgid "Snapshot" msgstr "תמונת מצב" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "שחזור {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "לשחזר את {path} אל…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "שלום\n" "השתמשת ב־Back In Time ב{language} מספר פעמים עד כה.\n" "מלאכת התרגום של הגרסה שהתקנת של Back In Time ל{language} הושלמה ב־{perc} אחוז. בלי קשר לרמת הידע הטכני שלך, אפשר לתרום למלאכת התרגום ובכך לתרום ל־Back In Time עצמה.\n" "נא לגשת אל {translation_platform_url} כדי לעזור. לעזרה ושאלות נוספות, נא לבקר ב־{back_in_time_project_website}.\n" "אנחנו מתנצלים על ההפרעה, וההודעה הזאת לא תופיע שוב. החלונית הזאת זמינה בכל עת דרך תפריט העזרה.\n" "צוות Back In Time לרשותכם" #: qt/app.py:2071 msgid "translation platform" msgstr "פלטפורמת תרגום" #: qt/app.py:2076 msgid "Website" msgstr "אתר" #: qt/app.py:2090 msgid "Your translation" msgstr "התרגום שלך" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "בפדיברס דרך מסטודון: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "דוא״ל אל {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "רשימת הדיוור {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} באתר המיזם." #: qt/app.py:2118 msgid "Open an issue" msgstr "לפתוח דיווח תקלה" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "לחלופין, אפשר להשתמש בכל ערוץ אחר לשיקולך." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "הגרסה הזאת של Back In Time היא מועמדת להוצאה לאור ומיועדת בעיקר לבדיקות יציבות ולהכנה למהדורה הרשמית הבאה.\n" "לא נאספים נתוני משתמש או מדדים. עם זאת, צוות Back In Time מאוד ישמח לדעת מה אופן השימוש במהדורה שמיועדת להוצאה לאור והאם שווה להמשיך לספק גרסאות טרום הוצאה לאור שכאלה.\n" "לכן, הצוות מבקש בצורה נעימה לקבל משוב קצר על האם בדקת את הגרסה הזאת, אפילו אם לא נתקלת בתקלות כלשהן. אפילו בדיקה זריזה שתרוץ במשך מספר דקות תעזור לנו מאוד.\n" "אלו האפשרויות הזמינות ליצירת קשר:\n" "{contact_list}\n" "בגרסה הזאת, ההודעה הזאת לא תופיע שוב אבל אפשר לגשת אליה בכל עת דרך תפריט העזרה.\n" "תודה על התמיכה ועל הסיוע במאמצים לשיפור Back In Time!\n" "צוות Back In Time לרשותך" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "הגדרות השפה ייכנסו לתוקף רק לאחר הפעלת Back In Time מחדש." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "יצירת פרופילי EncFS תוסר בגרסה המזערית הבאה (1.7), צפויה לצאת לאור ב־2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "לא מומלץ להשתמש במצב הזה לפרופיל עוד." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "תיעוד" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "התמיכה ב־EncFS הופסקה עקב חולשות אבטחה." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "לפרטים נוספים, כולל חלופות אפשריות, ניתן לקרוא את ה{whitepaper} הזה." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "הפרופילים הבאים משתמשים בהצפנה עם EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "מתוכננת החלפה, אבל לא ניתן להבטיח שהיא תגיע בזמן." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "משתמשים מוזמנים להצטרף לדיון הזה. הפרטים העדכניים על הצעדים הבאים זמינים " "ב{whitepaper} הזה." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "ההודעה הזאת לא תופיע שוב. החלונית הזאת זמינה בכל עת דרך תפריט העזרה." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "צוות Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "הגדרת שפה" #: qt/languagedialog.py:97 msgid "System default" msgstr "ברירת מחדל המערכת" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "להשתמש בשפת מערכת ההפעלה." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "תורגמו: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "תצוגת היומן האחרון" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "תצוגת יומן תמונות מצב" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "פרופיל:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "תמונות מצב:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "סינון:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "הכול" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "שינויים" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "שגיאות" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "פרטים" msgstr[1] "פרטים" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "כשלי העברה דרך rsync (ניסיוניים)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] שגיאה, [I] מידע, [C] שינוי" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "פענוח נתיבים" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "ניהול פרופילים" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "עריכה" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "הוספה" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "הסרה" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&כללי" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "לכלול" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "לכלול קבצים ותיקיות" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "הוספת קובץ" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "הוספת תיקייה" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "לה&חריג" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}פרטים{ENDBOLD}: במצב ‚הצפנתSSH”, רק כוכבית אחת או שתיים משחקות תפקיד " "(למשל: {example2}). סוגים אחרים של תווי הכללה ותבניות לא משחקים תפקיד (למשל:" " {example1}). שמות הקבצים אינם צפויים במצב הזה עקב הצפנה עם EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "החרגת תבניות, קבצים או תיקיות" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "הוספת ברירת מחדל" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "החרגת קבצים שגדולים מאשר:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "החרגת קבצים שגדולים מהערך {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "כש‚מצב rsync מלא’ כבוי, זה ישפיע רק על קבצים מאחר של־rsync זאת אפשרות העברה," " לא אפשרות החרגה. לכן, קבצים גדולים שגובו בעבר יישארו בתמונות מצב אפילו אם " "נערכו." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "ה&סרה ושימור" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&אפשרויות" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "אפשרויות &מומחים" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "שחזור הגדרות" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "עריכת משוב משתמש" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "פרופיל חדש" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "שינוי שם לפרופיל" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "למחוק את הפרופיל „{name}”?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}מומלץ בחום{ENDBOLD}: (כל ההמלצות כבר נכללו.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}מומלץ בחום{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "הכללת תבנית" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "הכללת קובץ" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "החרגת תיקייה" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "לכלול קובץ" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„‎{path}” הוא קישור סמלי. היעד המקושר לא יגובה עד שיוכלל גם הוא.\n" "לכלול את יעד הקישור הסמלי במקום?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "לכלול תיקייה" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "מושבת כי התבנית הזאת לא שמישה במצב ‚SSH מוצפן’." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "תזמון" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "יום:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "יום בשבוע:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "שעה:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "שעות:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "אחרי השעה" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "דקות:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "להריץ את Back In Time עם חיבור הכונן (פעם אחת כל X ימים). תופיע בקשה לסיסמת " "העל שלך (sudo)." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "הרצת Back In Time באופן מחזורי. שימוש אם המחשב לא דולק קבוע." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "כל:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "הפעלת תיעוד של הודעות ניפוי שגיאות" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "כתיבת הודעות ברמת ניפוי שגיאות ליומן המערכת דרך „‎--debug”." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "אזהרה: להשתמש בזה באופן זמני לאבחון, כיוון שזה מייצר המון פלט." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "מושבת" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "בכל טעינה/הפעלה מחדש של מערכת" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "כל דקה" msgstr[1] "כל {n} דקות" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "כל שעה" msgstr[1] "כל {n} שעות" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "כל שעה" msgstr[1] "כל {n} שעות" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "שעות מותאמות אישית" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "כל יום" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "במחזוריות (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "כאשר כונן מתחבר (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "כל שבוע" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "כל חודש" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "כל שנה" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "שעה/ות" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "יום/ימים" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "שבוע/ות" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "חודש/ים" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "שעות מותאמות אישית יכול להיות רק רשימת של שעות מופרדת בפסיקים (למשל: " "8,12,18,23) או ‎*/3 לגיבויים במחזורים של 3 שעות." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "מתווך SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "מארח:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "פתחה:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "משתמש:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "להתחבר למארח היעד דרך המתווך הזה (ידוע גם בשם מארח קפיצה/jump host). אפשר " "לקרוא על „‎-J” בתיעוד פקודת „ssh” או „ProxyJump” במדריך למשתמש " "ב־„ssh_config” לפרטים נוספים." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "אזהרה:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "אלו אפשרויות מתקדמות. אפשר לשנות אותן רק אם ברור לך לחלוטין מה תהיינה " "ההשלכות לכך." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "הרצת ‚rsync’ עם ‚{cmd}’:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "כמשימת cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "במארח המרוחק" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "בעת שמירת תמונת מצב ידנית" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "נא להתקין ‚nocache’ כדי להפעיל את האפשרות הזאת." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "במכונה המקומית" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "הפניית stdout ל־‎/dev/null במשימות ה־cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "Cron ישלח הודעות בדוא״ל בצירוף הפלט של משימות ה־cron אם MTA מותקן." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "הפניית stderr ל־‎/dev/null במשימות ה־cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "Cron ישלח הודעות בדוא״ל בצירוף השגיאות של משימות ה־cron אם MTA מותקן." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "ק״ב/שנייה" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "הגבלת ניצולת רוחב הפס של rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "שימור הרשאות ובעלות" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "שימור מאפיינים מורחבים (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "העתקת קישורים בלתי מהימנים (עובד רק עם קישורים מוחלטים)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "הגבלה למערכת קבצים אחת" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "חובה לשים אפשרויות במירכאות, למשל: ‎{example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "הדבקת אפשרויות נוספות ל־rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "קידומת להרצה לפני כל פקודה במארח המרוחק." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "יש למלט משתנים עם \\$FOO. זה לא נוגע ל־rsync. אז כדי להוסיף קידומת ל־rsync " "יש להשתמש ב־„{example_value}” יחד עם {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "ברירת מחדל" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "הוספת קידומת לפקודות SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "לבדוק אם המארח המרוחק מחובר" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "אזהרה: אם האפשרות מושבתת והמארח המרוחק לא זמין, עלולות להתרחש כל מיני שגיאות" " מוזרות." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "לבדוק האם המארח המרוחק תומך בכל הפקודות הנחוצות." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "אזהרה: אם האפשרות מושבתת והמארח המרוחק לא תומך בכל הפקודות הנחוצות, עלולות " "להתרחש שגיאות מוזרות." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(ברירת מחדל: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "מושבת" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "מופעל" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "מצב:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "איפה לשמור גיבויים" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "הגדרות SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "נתיב:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "צופן:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "מפתח פרטי:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "נא לבחור קובץ מפתח פרטי קיים (בדרך כלל נקרא „id_ed25519” או במערכות ישנות " "יותר „id_rsa”)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "יצירת מפתח SSH חדש ללא סיסמה (אסור אם כבר נבחר מפתח פרטי)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "סיסמה" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "שמירת הסיסמה לצרור המפתחות" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "שמירת סיסמה ל־Cron במטמון (סיבות אבטחה: משתמש על - root יכול לקרוא סיסמה)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "הגדרות מתקדמות" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "נתיב תמונת מצב מלא:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "לא בחרת קובץ מפתח פרטי ל־SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "לייצר צמד מפתחות ציבורי/פרטי ללא סיסמה?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "קובץ המפתח הפרטי „{file}” לא קיים." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "להעתיק את מפתח ה־SSH הציבורי שלך למארח המרוחק כדי לאפשר כניסה ללא סיסמה?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "אי אפשר לאמת את האמינות של {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "טביעת אצבע מפתח ה־{keytype} היא:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "נא לאמת את טביעת האצבע הזאת. להוסיף אותה לקובץ ה־‚known_hosts’ שלך?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "להחליף את תיקיית תמונות המצב?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "יצירת מפתח SSH חדש תחת {path} נכשלה." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "אפשר הודעות" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "השבת גיבויים כאשר על בטרייה" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "מצב הכוח אינו זמין מהמערכת" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "להריץ שמירה של תמונת מצב אחת כל פעם" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "תמונות מצב אחרות תיחסמנה עד שתמונת המצב הנוכחית תסתיים. זאת אפשרות גללית. " "לכן היא תשפיע על כל הפרופילים למשתמש הזה. אבל צריך להפעיל את זה גם לכל השאר " "המשתמשים." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "גיבוי הקבצים המוחלפים בשחזור" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "לשם של גרסאות חדשות יותר של הקבצים יתווסף {suffix} טרם השחזור. אם אין בהם " "יותר צורך אפשר להסיר אותם בעזרת {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "להמשיך כשיש שגיאות (לשמור על תמונות מצב חלקיות)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "להשתמש בסכומי בדיקה לאיתור שינויים" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "לשמור תמונת מצב גם אם לא נערכו שינויים." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "רמת פירוט יומן:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "ללא" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "הכללים הבאים עובדו מלמעלה למטה. הכללים המאוחרים יותר דורסים את הקודמים והם " "לא מגבילים אותם. אפשר לעיין ב{manual} לפרטים נוספים ולדוגמאות." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "מדריך למשתמשים" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "פתיחת מדריך למשתמשים בדפדפן." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "להשאיר את תמונת המצב העדכנית ביותר." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "תמונת המצב האחרונה או העדכנית ביותר נשמרת ללא תלות בתנאים." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "אי אפשר לשנות את ההתנהגות הזאת." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "להשאיר תמונות מצב עם שם." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "תמונת מצב שקיבלה שם, בנוסף לחותמת הזמן הרגילה, תישמר בכל אופן ולא תוסר." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "שנה/ים" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "להסיר תמונות מצב מלפני" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "ימים מלאים. היום הנוכחי לא מחושב." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "שבועות קלנדריים עם יום שני בתור יום תחילת השבוע. השבוע הנוכחי לא מחושב." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "תקופות של 12 חודשים. החודש הנוכחי לא נכלל." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "מדיניות שימור" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "הרצה ברקע במארח המרוחק." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "תהליך ההסרה החכמה ירוץ ישירות במכונה המרוחקת, לא מקומית. הפקודות „bash”,‏ " "„screen” ו־„flock” חייבות להיות מותקנות וזמינות במכונה המרוחקת." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "אם האפשרות נבחרה, Back In Time תבדוק תחילה את המכונה המרוחקת." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "הימים מחושבים החל מהיום." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "לשמור את כל תמונות המצב האחרונות במשך" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "יום/ימים." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "לשמור את תמונת המצב האחרונה בכל יום למשך" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "השבועות מחושבים החל מהשבוע הנוכחי. שבוע מתחיל ביום שני." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "לשמור תמונת המצב האחרונה בכל שבוע למשך" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "שבוע/שבועות." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "החודשים מחושבים כחודשים קלנדריים החל מהחודש הנוכחי." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "לשמור תמונת מצב אחת מכל חודש למשך" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "חודש/חודשים." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "השנים מחושבות כשנים קלנדריות החל מהשנה הנוכחית." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "לשמור את תמונת המצב האחרונה מכל שנה למשך" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "כל השנים." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "…המקום הפנוי קטן מ־" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "…כמות ה־inodes הפנויה קטנה מ־" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "להסיר את תמונות המצב הישנות ביותר אם…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "שאלה" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "פרופיל: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "הצגת היומן האחרון" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "הפעלת {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "בעבודה…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "נשלחו:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "מהירות:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "זמן משוער לסיום:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "גיבויים" #: qt/qttools.py:506 msgid "Today" msgstr "היום" #: qt/qttools.py:513 msgid "Yesterday" msgstr "אתמול" #: qt/qttools.py:522 msgid "This week" msgstr "השבוע" #: qt/qttools.py:529 msgid "Last week" msgstr "שבוע שעבר" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "זה לא גיבוי אלא מבט עכשוי על הקבצים המקומיים שלך" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "בדיקה אחרונה {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "ייבוא הגדרות" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "לא נמצאו הגדרות" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "ייבוא" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "נא לבחור את תיקיית תמונות המצב ממנה ייובא קובץ ההגדרות. הנתיב אמור להיראות " "כך: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "אם התיקייה נמצאת בכונן חיצוני או מרוחק, יש לעגן אותה ידנית תחילה." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "הצגת היומן המלא" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "אפשרויות להשוואת תמונות מצב" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "פקודה:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "משתנים:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "להשתמש ב־%1 וב־%2 כמשתני נתיב" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "נא להגדיר פקודת diff או לבטל." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "הפקודה „{cmd}” לא נמצאה במערכת הזאת. נא לנסות משהו אחר או ללחוץ על ביטול." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "לא מוגדרים משתנים לפקודת diff (הבדלים). נעשה שימוש בערך ברירת המחדל " "„{params}”." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "תמונות מצב עם שינויים בלבד" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "להציג רק תמונות מצב שזהות ל־:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "בדיקה עמוקה (מדויקת יותר, אך אטית)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "מחיקה" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "בחירה בהכול" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "השוואה" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "מעבר אל" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "אפשרויות" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "לא ניתן להשוות תמונת מצב לעצמה." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "למחוק את {file} בתמונת המצב {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "למחוק את {file} ב־{count} תמונות מצב?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "אזהרה: אי אפשר לשלול את זה." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "להחריג את {path} מתמונות מצב עתידיות?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "אי אפשר לכלול את תת־התיקיות בגיבוי." backintime-1.5.4/common/po/hr.po000066400000000000000000001460111477034762000165230ustar00rootroot00000000000000# Croatian translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-14 00:32+0000\n" "Last-Translator: MarvinDarwin \n" "Language-Team: Croatian \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Upozorenje" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Glavni profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalno (EncFS šifriranje)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS šifriranje)" #: common/config.py:278 msgid "Local" msgstr "Lokalno" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Privatni ključ za SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalno šifrirano" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Šifriranje" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH šifrirano" #: common/config.py:296 msgid "Default" msgstr "Zadano" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Mapa snimki nije valjana !" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Za sigurnosnu kopiju treba se odabrati barem jedna mapa." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Povrati {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Mapa se ne može sigurnosno kopirati." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nije moguće stvoriti novi crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Naredba crontab je dostupna, ali Cron nije pokrenut. Zakazano sigurnosno " "kopiranje neće se pokrenuti. Moguće je da je Cron instaliran, ali nije " "omogućen. Pokušajte unijeti naredbu \"systemctl enable cron\" ili se " "obratite kanalima podrške GNU/Linux distribucije koju upotrebljavate." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Instalacija Udev pravila za profil {profile_id} nije uspjela. DBus usluga " "'{dbus_interface}' nije dostupna" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nije moguće pronaći UUID za {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Spremanje konfiguracije neuspješno" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Učitavanje konfiguracije neuspješno" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" već postoji." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Posljednji profil ne može se ukloniti." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nemoguće postaviti naredbu '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Konfiguracija za šifriranu mapu nije pronađena." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Stvori novu šifriranu mapu?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Otkaži" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Molim Vas da potvrdite lozinku." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Lozinka se ne podudara." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Uzmi snimku" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Naredba {command} nije pronađena. Molimo instalirajte je (primjerice pomoću " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Unesite lozinku za {mode} profile \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NEUSPJEŠNO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Spremi dopuštenje" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Završeno" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Odgoda sigurnosnog kopiranja za vrijeme punjenja" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Nije moguće napraviti mapu" #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Nije moguće pronaći mapu snimki.\n" "Ako je na izmjenjivom disku, molimo, spojite ga i pritisnite OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čekanje %s sekunda." msgstr[1] "Čekanje %s sekundi." msgstr[2] "Čekanje %s sekundi." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Neuspjelo uzimanje snimke {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Molimo vas za strpljenje. Završavamo…" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Nije moguće napraviti mapu" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Spremi datoteku postavki …" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Spremi dopuštenje …" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Neuspjelo uzimanje snimke {snapshot_id}." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Nije moguće ukloniti mapu" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Uzmi snimku" #: common/snapshots.py:1430 msgid "Success" msgstr "Uspjeh" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Prijenos djelomičan jer je došlo do pogreške" #: common/snapshots.py:1434 #, fuzzy msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Prijenos djelomičan jer su izvorne datoteke nestale (vidi 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' završen uz izlazni kod {exit_code}" #: common/snapshots.py:1451 #, fuzzy msgid "See 'man rsync' for more details" msgstr "Vidi 'man rsync' za više detalja" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ništa se nije promijenilo, nema potrebe za novim snimaka" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Nemoguće preimenovati {new_path} u {path}." #: common/snapshots.py:1855 #, fuzzy msgid "Smart removal" msgstr "Smart uklanjanje" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Ukloni stare snimke" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Pokušaj sačuvati min slobodno mjesta" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Pokušaj sačuvati min {perc} slobodno mjesta" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Sada" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nije moguće postaviti {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent nije pronađen. Molimo provjerite je li instaliran." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nije moguće otključati ssh privatni ključ. Lozinka je pogrešna ili nije " "dostupna za cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 #, fuzzy msgid "Remote path exists but is not a directory." msgstr "Udaljeni put postoji, ali nije mapa." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nije moguće napraviti mapu." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Vidi 'man backintime' za daljnje upute" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" #: common/sshtools.py:1193 #, fuzzy, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Molim Vas unesite lozinku za korisnika \"{user}\"" #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} nije valjana mapa." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Neuspješno stvaranje sljedeće mape:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Pristup za pisanje možda je ograničen." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "" #: common/tools.py:504 msgid "Expert Options" msgstr "Stručne opcije" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Neuspješno stvaranje datoteke u sljedećoj mapi:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O programu" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autori" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Prijevodi" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenca" #: qt/app.py:172 msgid "Shortcuts" msgstr "Prečaci" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ova mapa ne postoji\n" "u odabranoj snimci." #: qt/app.py:257 msgid "Add to Include" msgstr "Dodaj u uključeno" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Dodaj u isključeno" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Nije pronađena nikakva konfiguracija, čini se da je {app_name} pokrenut prvi" " put." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Nije moguće pronaći mapu snimki.\n" "Ako je na izmjenjivom disku, molimo, spojite ga i pritisnite OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Uzmi snimku" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pauziraj snimanje" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Nastavi snimanje" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Prekini snimanje" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Osvježi popis snimki" #: qt/app.py:497 msgid "Name snapshot" msgstr "Uzmi snimku" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Ukloni Snimku" #: qt/app.py:505 msgid "View snapshot log" msgstr "Prikaži Zapis Snimke" #: qt/app.py:509 msgid "View last log" msgstr "Prikaži Zadnji Zapis" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Glavni profil…" #: qt/app.py:517 msgid "Shutdown" msgstr "Isključi računalo" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Isključi sustav kad snimanje završi." #: qt/app.py:521 msgid "Setup language…" msgstr "Jezik…" #: qt/app.py:525 msgid "Exit" msgstr "Izlaz" #: qt/app.py:529 msgid "User manual" msgstr "Korisnički priručnik" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Otvori korisnički priručnik u pregledniku (po mogućnosti lokalno, u " "suprotnom na internetu)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Spremi datoteku postavki" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "Web-mjesto projekta" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Otvori web-stranicu projekta Back In Time u pregledniku" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Zapisnik promjena" #: qt/app.py:555 msgid "FAQ" msgstr "Česta pitanja" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Otvori česta pitanja u pregledniku" #: qt/app.py:559 msgid "Ask a question" msgstr "Postavi pitanje" #: qt/app.py:563 msgid "Report a bug" msgstr "Prijavi pogrešku" #: qt/app.py:566 msgid "Translation" msgstr "Prevođenje" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Ponovno prikazuje poruku o sudjelovanju u procesu prevođenja." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Povrati" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Vrati odabrane datoteke ili mape na izvorno odredište." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Povrati…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Vrati odabrane datoteke ili mape na novo odredište." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Vrati trenutno prikazanu mapu i sav njezin sadržaj na izvorno odredište." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Vrati trenutno prikazanu mapu i sav njezin sadržaj na novo odredište." #: qt/app.py:601 msgid "Up" msgstr "Gore" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Prikaži skrivene datoteke" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Uzmi snimku…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 #, fuzzy msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 #, fuzzy msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Povrati" #: qt/app.py:698 msgid "&Help" msgstr "Po&moć" #: qt/app.py:743 msgid "Icons only" msgstr "Samo ikone" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "Jeste li sigurni da želite ukloniti snimku" #: qt/app.py:1072 msgid "Working:" msgstr "Radim:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Završeno, nije potrebna rezerva" #: qt/app.py:1129 msgid "Working" msgstr "Radim" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "" #: qt/app.py:1161 msgid "Sent" msgstr "" #: qt/app.py:1162 msgid "Speed" msgstr "" #: qt/app.py:1163 msgid "ETA" msgstr "" #: qt/app.py:1225 msgid "Global" msgstr "Globalno" #: qt/app.py:1226 msgid "Root" msgstr "Korijen" #: qt/app.py:1227 msgid "Home" msgstr "Početak" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Mape rezerve" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Ime Snimke" #: qt/app.py:1398 #, fuzzy msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Jeste li sigurni da želite ukloniti snimku" msgstr[1] "Jeste li sigurni da želite ukloniti snimku" msgstr[2] "Jeste li sigurni da želite ukloniti snimku" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Neuspjelo uzimanje snimke {snapshot_id} !!!" msgstr[1] "Neuspjelo uzimanje snimke {snapshot_id} !!!" msgstr[2] "Neuspjelo uzimanje snimke {snapshot_id} !!!" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Jeste li sigurni da želite ukloniti snimku" msgstr[1] "Jeste li sigurni da želite ukloniti snimku" msgstr[2] "Jeste li sigurni da želite ukloniti snimku" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Jeste li sigurni da želite ukloniti snimku" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" #: qt/app.py:1857 msgid "Snapshot" msgstr "Snimke" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Povrati {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Povrati {path}…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Pozdrav\n" "Već ste više puta upotrebljavali Back In Time na sljedećem jeziku: {language}.\n" "Prijevod vaše inačice programa Back In Time na {language} dovršen je {perc}. Bez obzira na tehničke sposobnosti koje imate, možete se pridružiti projektu prevođenja te tako doprinositi programu Back In Time.\n" "Ako želite sudjelovati, posjetite {translation_platform_url}. Za dodatna pitanja i pomoć posjetite {back_in_time_project_website}.\n" "Ispričavamo se što smo Vas prekinuli, ova se poruka više neće prikazivati. Ubuduće je možete pronaći na izborniku za pomoć.\n" "Tim programa Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "" #: qt/app.py:2076 msgid "Website" msgstr "Web stranica" #: qt/app.py:2090 msgid "Your translation" msgstr "" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 msgid "System default" msgstr "" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Snimke:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Sve" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Promjene" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Grješke" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Informacije" msgstr[1] "Informacije" msgstr[2] "Informacije" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Grješka, [I] Informacije, [C] Promjeni" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Glavni profil" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Uredi" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Općenito" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Uključi" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Ukljući mape i datoteke" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dodaj datoteku" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Dodaj mapu" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Isključi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Iskljući sljedove, datoteke ili mape" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Isključi datoteku:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Op&cije" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Stručne opcije" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Novi profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Preimenuj profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Jeste li sigurni da želite obrisati profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "Visoko preporučeno" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Isključi slijed" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Isključi datoteku" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Isključi mapu" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Uključi datoteku" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Uključi mapu" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Raspored" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Sat:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Svakih:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Onemogućeno" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Pri svakom paljenju/podizanju" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Svakih {n} minuta" msgstr[1] "Svakih {n} minuta" msgstr[2] "Svakih {n} minuta" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" msgstr[2] "" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Svakih {n} sati" msgstr[1] "Svakih {n} sati" msgstr[2] "Svakih {n} sati" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Svaki dan" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Svaki tjedan" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Svaki mjesec" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Svake godine" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dan(a)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Tjedan(a)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Domaćin:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Korisnik:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Sačuvaj ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Gdje sačuvati snimke" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Napredno" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Jeste li sigurni da želite promjeniti mapu snimki?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Omogući obavijesti" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Onesposobi snimke tijekom rada na bateriji" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Stanje energije nije dostupno od sustava" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Nastavi ne grješkama (zadrži nepotpune snimke)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Razina Zapisa:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nijedno" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Nemoj uklanjati imenovane snimke." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Nemoj uklanjati imenovane snimke." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Godina" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Ukloni Snimku" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dan(a)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Tjedan(a)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Ako je slobodan prostor manji od:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Ako je slobodan prostor manji od:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Ukloni stare snimke" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Prikaži Zadnji Zapis" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Radim…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snimke" #: qt/qttools.py:506 msgid "Today" msgstr "Danas" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Jučer" #: qt/qttools.py:522 msgid "This week" msgstr "Ovaj tjedan" #: qt/qttools.py:529 msgid "Last week" msgstr "Prošli tjedan" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 #, fuzzy msgid "Command:" msgstr "Naredba" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Dubinska provjera (preciznije, ali sporije)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Idi Na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcije" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nije moguće usporediti snimku s njom samom." #: qt/snapshotsdialog.py:396 #, fuzzy, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Neuspjelo uzimanje snimke {snapshot_id} !!!" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Podmape se ne mogu sigurnosno kopirati." backintime-1.5.4/common/po/hu.po000066400000000000000000002064641477034762000165370ustar00rootroot00000000000000# Hungarian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # # FIRST AUTHOR , 2009. # Kósa Lajos , 2013. msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-12 18:58+0000\n" "Last-Translator: buhtz \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Figyelmeztetés" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Fő profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Helyi (EncFS-sel titkosított)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-sel titkosított)" #: common/config.py:278 msgid "Local" msgstr "Helyi" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH személyes kulcs" #: common/config.py:283 msgid "Local encrypted" msgstr "Helyi titkosított" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Titkosítás" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH-val titkosított" #: common/config.py:296 msgid "Default" msgstr "Alapértelmezett" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: „{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "A pillanatképek könyvtára nem érvényes." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Legalább egy könyvtárat ki kell választani a biztonsági mentéshez." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Könyvtár: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Ez a könyvtár nem szerepelhet a biztonsági mentésben, mivel magának a " "biztonsági mentési célnak a része." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nem sikerült az új crontab írása." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "A Cron nem fut, annak ellenére hogy a crontab parancs elérhető. Az ütemezett" " biztonsági mentési feladatok nem fognak futni. Lehet, hogy a Cron telepítve" " van, de nincs engedélyezve. Próbálja meg a „systemctl enable cron” " "parancsot, vagy keresse fel a GNU/Linux disztribúciója támogatási " "csatornáit." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Nem sikerült telepíteni az Udev-szabályt a(z) {profile_id} profilnál. A(z) " "„{dbus_interface}” DBus-szolgáltatás nem volt elérhető" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Az udev ütemezése nem működik a(z) {mode} móddal" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nem található a(z) „{path}” UUID-ja" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nem sikerült elmenteni a beállításokat" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nem sikerült betölteni a beállításokat" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "A(z) „{name}” profil már létezik." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Az utolsó profilt nem lehet eltávolítani." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nem lehet csatolni a(z) „{command}” parancsot" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "A titkosított könyvtár beállítása nem található." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Létrehoz egy új titkosított könyvtárat?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Mégse" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Erősítse meg a jelszót." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "A jelszó nem egyezik." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Pillanatkép készítése" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" "Nem lehet leválasztani a(z) {mountprocess} folyamatot a(z) {mountpoint} " "csatolási pontról." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "A(z) {command} nem található. Telepítse (például ezzel: „{installcommand}”)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "A(z) {mntpoint} csatolási pont nem üres." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Adja meg a(z) „{profile}” {mode} profil jelszavát:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "SIKERTELEN" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Jogosultságok helyreállítása" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Kész" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Biztonsági mentés elhalasztása akkumulátorról való működésnél" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Nem található a pillanatképek könyvtára." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Ha cserélhető meghajtón van, akkor helyezze be." #: common/snapshots.py:849 #, fuzzy, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "%s másodperc várakozás." msgstr[1] "%s másodperc várakozás." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Nem sikerült a(z) {snapshot_id} pillanatkép készítése." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Legyen türelemmel. Véglegesítés…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Nem lehet létrehozni a könyvtárat." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Beállítófájl mentése…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Jogosultságok mentése…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Található egy maradvány {snapshot_id} pillanatkép, amely folytatható." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "A maradvány {snapshot_id} könyvtár eltávolítása a legutóbbi futtatásból" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Nem lehet eltávolítani a könyvtárat" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Pillanatkép készítése" #: common/snapshots.py:1430 msgid "Success" msgstr "Sikeres" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Részleges átvitel egy hiba miatt" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Részleges átvitel az eltűnt forrásfájlok miatt (lásd: „man rsync”)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "Az „rsync” a(z) {exit_code} számú hibakóddal fejeződött be" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Nézze meg a „man rsync” kézikönyvet a további részletekért" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "A negatív rsync kilépési kódok szignálszámok, nézze meg a „kill -l” és a " "„man kill” parancsokat" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Semmi sem változott, nincs szükség új pillanatképre" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Nem lehet átnevezni a(z) {new_path} útvonalat erre: {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Intelligens eltávolítás" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Szabályok alkalmazása a régi pillanatképek eltávolításához" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Megtartási szabály alkalmazása" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Kísérlet a legkisebb szabad hely megtartására" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Kísérlet legalább {perc} szabad inode megtartására" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Most" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nem lehet csatolni: {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "Az „ssh-agent” nem található. Győződjön meg arról, hogy telepítve van." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nem sikerült feloldani az SSH személyes kulcsát. Hibás a jelszó vagy a " "jelszó nem érhető el a cron számára." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "A(z) {cipher} titkosító meghiúsult a(z) {host} kiszolgálónál." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "A távoli útvonal létezik, de nem könyvtár." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "A távoli útvonal nem írható." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "A távoli útvonal nem futtatható." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nem sikerült létrehozni a távoli útvonalat." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "A(z) {host} távoli kiszolgáló nem támogatja a(z) {command} parancsot" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Nézze meg a „man backintime” parancsot a további utasításokért" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "A parancsok ellenőrzése a(z) {host} kiszolgálón ismeretlen hibát adott " "vissza" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" "A(z) {host} távoli kiszolgáló nem támogatja a rögzített hivatkozásokat" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "A(z) „{pubkey}” nyilvános SSH-kulcs másolása a(z) „{host}” távoli " "kiszolgálóra." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Adja meg „{user}” felhasználó jelszavát." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "A(z) {path} útvonal célfájlrendszere NTFS-re van formázva, amely nem " "kompatibilis a Unix-stílusú fájlrendszerekkel." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "A(z) {path} nem érvényes könyvtár." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "A következő könyvtár létrehozása nem sikerült:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Az írási hozzáférés korlátozott lehet." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "A(z) {path} útvonal célfájlrendszere FAT-tal van formázva, amely nem " "támogatja a rögzített hivatkozásokat. Használjon natív GNU/Linux " "fájlrendszert." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "A(z) {path} útvonal célfájlrendszere egy SMB csatolású megosztás. Győződjön " "meg arról, hogy a távoli SMB-kiszolgáló támogatja-e a szimbolikus " "hivatkozásokat vagy kapcsolja be a „{copyLinks}” lehetőséget az " "„{expertOptions}” alatt." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Hivatkozások másolása (szimbolikus hivatkozások megszüntetése)" #: common/tools.py:504 msgid "Expert Options" msgstr "Szakértői beállítások" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "A(z) {path} útvonal célfájlrendszere egy sshfs csatolású megosztás. Az sshfs" " nem támogatja a rögzített hivatkozásokat. Használja inkább az „SSH” módot." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "A fájl létrehozása ebben a könyvtárban nem sikerült:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Névjegy" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Szerzők" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Fordítások" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenc" #: qt/app.py:172 msgid "Shortcuts" msgstr "Gyorsbillentyűk" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ez a könyvtár nem létezik a jelenleg\n" "kiválasztott pillanatképben." #: qt/app.py:257 msgid "Add to Include" msgstr "Hozzáadás a felvettekhez" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Hozzáadás a kizártakhoz" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Úgy tűnik, hogy a(z) {app_name} először lett elindítva, mivel nem található " "beállítás hozzá." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importál egy meglévő beállítást (egy biztonsági mentés célkönyvtárából vagy " "egy másik számítógépről)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Ha cserélhető meghajtón van, akkor helyezze be, és nyomja meg az OK gombot." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Pillanatkép készítése" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "A módosítás ideje és a méret használata a fájlváltoztatások felismeréséhez." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Pillanatkép készítése (ellenőrzőösszeg mód)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Ellenőrzőösszegek használata a fájlváltoztatások felismeréséhez." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pillanatkép folyamatának szüneteltetése" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Pillanatkép folyamatának folytatása" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Pillanatkép folyamatának leállítása" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Pillanatképek listájának frissítése" #: qt/app.py:497 msgid "Name snapshot" msgstr "Pillanatkép elnevezése" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Pillanatkép eltávolítása" #: qt/app.py:505 msgid "View snapshot log" msgstr "Pillanatkép naplójának megtekintése" #: qt/app.py:509 msgid "View last log" msgstr "Utolsó napló megtekintése" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Profilok kezelése…" #: qt/app.py:517 msgid "Shutdown" msgstr "Leállítás" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "A rendszer leállítása a pillanatkép befejezése után." #: qt/app.py:521 msgid "Setup language…" msgstr "Nyelv beállítása…" #: qt/app.py:525 msgid "Exit" msgstr "Kilépés" #: qt/app.py:529 msgid "User manual" msgstr "Felhasználói kézikönyv" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Felhasználói kézikönyv megnyitása a böngészőben (helyileg, ha elérhető, " "egyébként az internetről)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "kézikönyvoldal: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Megjeleníti a Back In Time (backintime) kézikönyvoldalát" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "kézikönyvoldal: Profilok beállítófájlja" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Megjeleníti a profilok beállítófájljával kapcsolatos kézikönyvoldalt " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projekt webhelye" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "A Back In Time webhelyének megnyitása a böngészőben" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Változásnapló" #: qt/app.py:555 msgid "FAQ" msgstr "GYIK" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Gyakran ismételt kérdések (GYIK) megnyitása a böngészőben" #: qt/app.py:559 msgid "Ask a question" msgstr "Kérdés feltevése" #: qt/app.py:563 msgid "Report a bug" msgstr "Hiba jelentése" #: qt/app.py:566 msgid "Translation" msgstr "Fordítás" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" "Ismét megjeleníti a fordításban való részvétellel kapcsolatos üzenetet." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Titkosítási átmenet (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Ismét megjeleníti az EncFS eltávolításával kapcsolatos üzenetet." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Helyreállítás" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "A kijelölt fájlok vagy könyvtárak helyreállítása az eredeti célhelyre." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Helyreállítás ide…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "A kijelölt fájlok vagy könyvtárak helyreállítása egy új célhelyre." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "A jelenleg megjelenített könyvtár és annak teljes tartalmának helyreállítása" " az eredeti célhelyre." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "A jelenleg megjelenített könyvtár és annak teljes tartalmának helyreállítása" " egy új célhelyre." #: qt/app.py:601 msgid "Up" msgstr "Fel" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Rejtett fájlok megjelenítése" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Pillanatképek összehasonlítása…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kiadásra jelölt" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Ismét megjeleníti az ezzel a kiadásra jelölttel kapcsolatos üzenetet." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Biztonsági mentés" #: qt/app.py:692 msgid "&Restore" msgstr "&Helyreállítás" #: qt/app.py:698 msgid "&Help" msgstr "&Súgó" #: qt/app.py:743 msgid "Icons only" msgstr "Csak ikonok" #: qt/app.py:746 msgid "Text only" msgstr "Csak szöveg" #: qt/app.py:749 msgid "Text below icons" msgstr "Szöveg az ikonok alatt" #: qt/app.py:752 msgid "Text beside icon" msgstr "Szöveg az ikon mellett" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ha bezárja ezt az ablakot, akkor a Back In Time nem lesz képes leállítani a " "rendszert a pillanatkép befejezése után." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Valóban be szeretné zárni?" #: qt/app.py:1072 msgid "Working:" msgstr "Munkavégzés:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Kész, nincs szükség biztonsági mentésre" #: qt/app.py:1129 msgid "Working" msgstr "Munkavégzés" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Hiba" #: qt/app.py:1161 msgid "Sent" msgstr "Elküldve" #: qt/app.py:1162 msgid "Speed" msgstr "Sebesség" #: qt/app.py:1163 msgid "ETA" msgstr "Becsült hátralévő idő" #: qt/app.py:1225 msgid "Global" msgstr "Globális" #: qt/app.py:1226 msgid "Root" msgstr "Gyökér" #: qt/app.py:1227 msgid "Home" msgstr "Saját mappa" #: qt/app.py:1255 msgid "Backup directories" msgstr "Biztonsági mentés könyvtárai" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Pillanatkép neve" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Biztosan el szeretné távolítani ezt a pillanatképet?" msgstr[1] "Biztosan el szeretné távolítani ezeket a pillanatképeket?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Biztonsági mentés másolatok létrehozása {suffix}\n" "végződéssel a helyi elemek felülírása vagy eltávolítása előtt." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "A fájlok újabb verziói átnevezésre kerülnek {suffix} végződéssel a " "helyreállítás előtt. Ha már nincs rájuk többé szüksége, akkor az alábbi " "paranccsal eltávolíthatja azokat:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Csak azon elemek helyreállítása, amelyek nem\n" "léteznek, vagy újabbak a célhelyen lévőknél.\n" "Az „rsync --update” kapcsoló használata." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Újabb elemek eltávolítása az eredeti könyvtárból." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "A kijelölt fájlok vagy könyvtárak helyreállítása az eredeti célhelyre, " "valamint a pillanatképben nem szereplő fájlok vagy könyvtárak törlése. " "Legyen rendkívül óvatos, mert ez törölni fogja azokat a fájlokat és " "könyvtárakat, amelyek a pillanatkép készítésekor ki voltak zárva." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Valóban helyre szeretné állítani ezt az elemet az új könyvtárba?" msgstr[1] "" "Valóban helyre szeretné állítani ezeket az elemeket az új könyvtárba?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Valóban helyre szeretné állítani ezt az elemet?" msgstr[1] "Valóban helyre szeretné állítani ezeket az elemeket?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Biztosan el szeretné távolítani a(z) {path} mappában lévő összes újabb " "fájlt?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Biztosan el szeretné távolítani az eredeti könyvtárban lévő összes újabb " "fájlt?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Figyelmeztetés:{BOLDEND} a fájlrendszer gyökerében lévő fájlok törlése" " tönkreteheti az egész rendszert." #: qt/app.py:1857 msgid "Snapshot" msgstr "Pillanatkép" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "{path} helyreállítása" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "{path} helyreállítása ide…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Üdvözöljük!\n" "Ön már többször használta a Back In Time programot {language} nyelven.\n" "A Back In Time telepített verziójának {language} nyelvre történő fordítása {perc} készültségű. Függetlenül attól, hogy milyen szintű műszaki ismeretekkel rendelkezik, hozzájárulhat a fordításhoz, és így magához a Back In Time-hoz is.\n" "Látogasson el a {translation_platform_url} oldalra, ha szeretne közreműködni. A további segítségért és kérdésekért látogasson el a {back_in_time_project_website} weboldalra.\n" "Elnézést kérünk a zavarásért. Ez az üzenet nem fog többé megjelenni. Ez a párbeszédablak később is bármikor elérhető a súgó menüben.\n" "A Back In Time csapata" #: qt/app.py:2071 msgid "translation platform" msgstr "fordítási platform" #: qt/app.py:2076 msgid "Website" msgstr "Webhely" #: qt/app.py:2090 msgid "Your translation" msgstr "Az Ön fordítása" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "A mastodoni födiverzumban: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-mail küldése: {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Levelezőlista: {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} a projekt webhelyén." #: qt/app.py:2118 msgid "Open an issue" msgstr "Nyisson hibajegyet" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" "Alternatívaként egy másik, Ön által választott csatornát is használhat." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "A Back In Time ezen verziója kiadásra jelölt, és elsősorban a következő hivatalos kiadásra való felkészülés során végzett stabilitástesztekre szolgál.\n" "Nem gyűjt felhasználói adatokat vagy telemetriát. A Back In Time csapatát azonban nagyon érdekli, hogy a kiadásra jelölt verzió használatban van-e, és érdemes-e folytatni az ilyen kiadás előtti verziók biztosítását.\n" "Ezért a csapat rövid visszajelzést kér arról, hogy tesztelte-e ezt a verziót, még akkor is, ha nem találkozott semmilyen problémával. Már egy gyors, néhány perces próbahasználat is sokat segítene nekünk.\n" "A következő kapcsolatfelvételi lehetőségek állnak rendelkezésre:\n" "{contact_list}\n" "Ebben a verzióban ez az üzenet nem jelenik meg újra, de bármikor elérhető a súgó menüből.\n" "Köszönjük a támogatását és azt, hogy segít nekünk a Back In Time fejlesztésében!\n" "Az Ön Back In Time csapata" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "A nyelvi beállítások csak a Back In Time újraindítása után lépnek érvénybe." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Az EncFS-profil létrehozása eltávolításra kerül a következő, 2026-ra " "tervezett kisebb kiadásban (1.7)." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Nem ajánlott ezt a módot továbbra is használni egy profilhoz." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "dokumentum" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Az EncFS támogatása a biztonsági sebezhetőségek miatt megszűnik." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "További részletekért, beleértve a lehetséges alternatívákat, ez a " "{whitepaper} ad tájékoztatást." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "A következő profilok használnak EncFS-sel történő titkosítást:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "A helyettesítése tervben van, de nem garantálható, hogy időben megérkezik." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Arra kérjük a felhasználókat, hogy csatlakozzanak ehhez a beszélgetéshez. A " "következő lépések frissített részleteiről ez a {whitepaper} ad " "tájékoztatást." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ez az üzenet többé nem jelenik meg. Ez a párbeszédablak bármikor elérhető a " "súgó menüből." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Az Ön Back In Time csapata" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Nyelv beállítása" #: qt/languagedialog.py:97 msgid "System default" msgstr "Rendszer alapértelmezettje" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Az operációs rendszer nyelvének használata." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Lefordítva: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Utolsó napló megtekintése" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Pillanatkép naplójának megtekintése" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Pillanatképek:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Szűrő:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Összes" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Változtatások" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Hibák" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Információ" msgstr[1] "Információk" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync átviteli hibák (kísérleti)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] hiba, [I] információ, [C] változtatás" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "útvonalak visszafejtése" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Profilok kezelése" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Szerkesztés" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Hozzáadás" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Eltávolítás" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "Á<alános" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Felvétel" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Fájlok és könyvtárak felvétele" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Fájl hozzáadása" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Könyvtár hozzáadása" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Kizárás" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Információ{ENDBOLD}: az „SSH-val titkosított” módban csak az egy- vagy" " kettős csillagok működnek (például: {example2}). A többi típusú " "helyettesítő karakter és minta figyelmen kívül lesz hagyva (például: " "{example1}). A fájlnevek ebben a módban kiszámíthatatlanok az EncFS általi " "titkosítás miatt." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Minták, fájlok vagy könyvtárak kizárása" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Alapértelmezett hozzáadása" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Ennél nagyobb fájlok kizárása:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "A {size_unit} értékénél nagyobb fájlok kizárása." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "A letiltott „Teljes rsync mód” használatával ennek csak az új fájlokra van " "hatása, mert az rsync esetén ez egy átviteli kapcsoló, nem kizáró kapcsoló. " "Tehát a korábban biztonsági mentésre került nagy fájlok megmaradnak a " "pillanatképekben, akkor is ha módosultak." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Eltávolítás és megtartás" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Beállítások" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "S&zakértői beállítások" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Beállítások helyreállítása" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Felhasználó-visszahívás szerkesztése" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Új profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Profil átnevezése" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Biztosan törölni szeretné a(z) „{name}” profilt?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Erősen ajánlott{ENDBOLD}: (Már tartalmazza az összes ajánlást.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Erősen ajánlott{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Minta kizárása" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Fájl kizárása" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Könyvtár kizárása" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Fájl felvétele" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "A(z) „{path}” útvonal egy szimbolikus hivatkozás. A hivatkozott cél nem kerül biztonsági mentésre, amíg azt is fel nem veszi.\n" "Szeretné a szimbolikus hivatkozás célját felvenni helyette?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Könyvtár felvétele" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Letiltva, mert ez a minta nem működik „SSH-val titkosított” módban." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Ütemezés" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Nap:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Hét napja:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Idő:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Óra:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "óra után" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Perc:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "A Back In Time futtatása, amint a meghajtó csatlakoztatásra kerül (X naponta" " csak egyszer). Kérni fogja a sudo jelszót." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "A Back In Time futtatása ismételten. Ez akkor hasznos, ha a számítógép nincs" " rendszeresen bekapcsolva." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Minden:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Hibakeresési üzenetek naplózásának engedélyezése" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Hibakeresés szintű üzeneteket ír a rendszernaplóba a „--debug” kapcsolón " "keresztül." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Vigyázat: ezt csak átmenetileg használja diagnosztikára, mivel nagy " "mennyiségű kimenetet állít elő." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Letiltva" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Minden indításkor vagy újraindításkor" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "{n} percenként" msgstr[1] "{n} percenként" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Óránként" msgstr[1] "{n} óránként" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} óránként" msgstr[1] "{n} óránként" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Egyéni órák" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Naponta" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Ismételten (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Ha meghajtó kerül csatlakoztatásra (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Hetente" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Havonta" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Évente" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Óra" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Nap" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Hét" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Hónap" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Az egyéni órák csak az órák vesszővel elválasztott listája lehet (például " "8,12,18,23) vagy */3 a háromóránkénti rendszeres biztonsági mentésekhez." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Kiszolgáló:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Felhasználó:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Kapcsolódás a célállomáshoz ezen a proxyn (más néven ugrókiszolgálón) " "keresztül. A részletekért nézze meg a „-J” kapcsolót az „ssh” parancs " "dokumentációjában vagy a „ProxyJump” beállítást az „ssh_config” " "kézikönyvoldalán." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Vigyázat:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Ezek a beállítások haladó szintű beállításokhoz valók. Csak akkor módosítsa," " ha teljes mértékben tisztában van azok következményeivel." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Az „rsync” futtatása a(z) „{cmd}” paranccsal:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "cron-feladatként" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "távoli kiszolgálón" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "kézi pillanatkép készítésekor" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Telepítse a „nocache” programot ezen beállítás engedélyezéséhez." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "helyi gépen" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" "A szabványos kimenet átirányítása a /dev/null helyre a cron-feladatokban." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "A cron automatikusan e-mailt küld csatolva a cron-feladat kimenetével, ha " "van MTA telepítve." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" "A szabványos hibakimenet átirányítása a /dev/null helyre a cron-" "feladatokban." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "A cron automatikusan e-mailt küld csatolva a cron-feladat hibáival, ha van " "MTA telepítve." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/mp" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Az rsync sávszélesség-használatának korlátozása:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACL megőrzése" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Kiterjesztett attribútumok (xattr) megőrzése" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Nem biztonságos hivatkozások másolása (csak abszolút hivatkozásokkal " "működik)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Korlátozás egyetlen fájlrendszerre" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "A kapcsolókat idézőjelek közé kell tenni, például: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "További kapcsolók beillesztése az rsync-be" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Minden parancs előtt futtatandó előtag a távoli kiszolgálón." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "A változókat el kell fedni a \\$FOO visszafelé mutató perjelekkel. Ez nem " "érinti az rsync parancsot. Tehát az rsync számára történő előtag-" "hozzáadáshoz használjon „{example_value}” kapcsolókat {rsync_options_value} " "értékkel." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "alapértelmezett" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Előtag hozzáadása az SSH-parancsokhoz" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Annak ellenőrzése, hogy a távoli kiszolgáló elérhető-e" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Figyelmeztetés: ha le van tiltva és a távoli kiszolgáló nem érhető el, akkor" " ez néhány furcsa hibához vezethet." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Annak ellenőrzése, hogy a távoli kiszolgáló támogatja-e az összes szükséges " "parancsot." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Figyelmeztetés: ha le van tiltva és a távoli kiszolgáló nem támogatja az " "összes szükséges parancsot, akkor ez néhány furcsa hibához vezethet." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(alapértelmezett: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "letiltva" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "engedélyezve" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mód:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Hová mentse a pillanatképeket" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-beállítások" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Útvonal:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Titkosító:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Személyes kulcs:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Meglévő személyes kulcsfájl kiválasztása (általában „id_ed25519”, régebbi " "beállításoknál „id_rsa” néven)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Új SSH-kulcs létrehozása jelszó nélkül (nem engedélyezett, ha egy személyes " "kulcsfájl már ki van választva)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Jelszó" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Jelszó mentése a kulcstartóba" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Jelszó gyorsítótárazása a Cron számára (biztonsági probléma: a rendszergazda" " elolvashatja a jelszót)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Speciális" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Teljes pillanatkép útvonala:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Nem választott ki személyes kulcsfájlt az SSH-hoz." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Szeretne egy új, jelszómentes nyilvános és személyes kulcspárt előállítani?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "A(z) „{file}” személyes kulcsfájl nem létezik." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Szeretné a nyilvános SSH-kulcsát a távoli kiszolgálóra másolni a " "jelszómentes bejelentkezés engedélyezéséhez?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "A(z) {host} kiszolgáló hitelességét nem lehet megállapítani." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "A(z) {keytype}-kulcs ujjlenyomata:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Ellenőrizze ezt az ujjlenyomatot! Szeretné hozzáadni a „known_hosts” " "fájlhoz?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Biztosan meg szeretné változtatni a pillanatképek könyvtárát?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Nem sikerült létrehozni új SSH-kulcsot a(z) {path} mappában." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Értesítések engedélyezése" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Pillanatképek letiltása akkumulátorról való működésnél" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Az energiaellátás állapota nem érhető el a rendszerről" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Egyszerre csak egy pillanatkép futtatása" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "A többi pillanatkép tiltva lesz, amíg az aktuális pillanatkép elkészül. Ez " "egy globális beállítás. Tehát ezen felhasználó összes profiljára hatással " "lesz. De ezt az összes többi felhasználónál is be kell kapcsolnia." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Lecserélt fájlok biztonsági mentése a helyreállításkor" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "A fájlok újabb verziói átnevezésre kerülnek {suffix} végződéssel a " "helyreállítás előtt. Ha már nincs rájuk többé szüksége, akkor a(z) {cmd} " "paranccsal eltávolíthatja azokat" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Folytatás hibák esetén (befejezetlen pillanatképek megtartása)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Ellenőrzőösszeg használata a változtatások felismeréséhez" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" "Új pillanatkép készítése, függetlenül attól, hogy voltak-e változtatások " "vagy sem." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Naplózási szint:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nincs" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "A következő szabályok felülről lefelé kerülnek feldolgozásra. A későbbi " "szabályok felülírják a korábbiakat, és nem korlátozzák azokat. Részleteket " "és példákat a {manual} tartalmaz." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "felhasználói kézikönyv" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Felhasználói kézikönyv megnyitása a böngészőben." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "A legfrissebb pillanatkép megtartása." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "A legutóbbi vagy legfrissebb pillanatkép minden körülmények között " "megtartásra kerül." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Ezt a viselkedést nem lehet megváltoztatni." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Elnevezett pillanatképek megtartása." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Azok a pillanatképek, amelyeknek a szokásos időbélyegen kívül nevet is " "adtak, minden körülmények között megtartásra kerülnek, és nem lesznek " "eltávolítva." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Év" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Az ennél régebbi pillanatképek eltávolítása" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Teljes napok. A jelenlegi nap figyelmen kívül van hagyva." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Hétfővel, mint első nappal kezdődő naptári hetek. A jelenlegi hét figyelmen " "kívül van hagyva." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 hónapos időszakok. A jelenlegi hónap figyelmen kívül van hagyva." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Megtartási irányelv" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Futtatás a háttérben a távoli kiszolgálón." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Az intelligens eltávolítási eljárás közvetlenül a távoli gépen fog futni, " "nem helyileg. A „bash”, „screen” és „flock” parancsoknak telepítve kell " "lenniük a távoli gépen, és elérhetőnek kell lenniük." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Ha ki van választva, akkor a Back in Time először leteszteli a távoli gépet." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "A napok a mai naptól kezdve számítanak." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Az összes pillanatkép megtartása a legutóbbi" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "napról." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Minden egyes nap utolsó pillanatképének megtartása a legutóbbi" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "A hetek a jelenlegi héttől kezdve számítanak. Egy hét hétfőn kezdődik." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Minden egyes hét utolsó pillanatképének megtartása a legutóbbi" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "hétről." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "A hónapok a jelenlegi hónappal kezdődő naptári hónappal kezdve számítanak." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Minden egyes hónap utolsó pillanatképének megtartása a legutóbbi" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "hónapról." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Az évek a jelenlegi évvel kezdődő naptári évekkel kezdve számítanak." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Minden egyes év utolsó pillanatképének megtartása a legutóbbi" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "teljes évről." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… a szabad hely kevesebb mint" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… a szabad inode-ok száma kevesebb mint" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "A legrégebbi pillanatképek eltávolítása, ha …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Kérdés" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Utolsó napló megtekintése" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "{appname} indítása" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Munkavégzés…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Elküldve:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Sebesség:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Becsült hátralévő idő:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Pillanatképek" #: qt/qttools.py:506 msgid "Today" msgstr "Ma" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Tegnap" #: qt/qttools.py:522 msgid "This week" msgstr "Ez a hét" #: qt/qttools.py:529 msgid "Last week" msgstr "Múlt hét" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Ez NEM pillanatkép, hanem a helyi fájlok élő nézete" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Utolsó ellenőrzés {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Beállítások importálása" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nem találhatók beállítások" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importálás" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Válassza ki a pillanatkép könyvtárát, ahonnan a beállítófájlt importálni " "kell. Az útvonal így nézhet ki: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Ha a könyvtár külső vagy távoli meghajtón található, akkor azt előzetesen " "kézileg kell csatolni." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Teljes napló megjelenítése" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Pillanatképek összehasonlítására vonatkozó beállítások" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Parancs:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Paraméterek:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Használjon %1 és %2 helykitöltőket az útvonal paramétereihez" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Állítson be egy diff parancsot, vagy nyomja meg a Mégse gombot." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "A(z) „{cmd}” parancs nem található ezen a rendszeren. Próbálkozzon valami " "mással, vagy nyomja meg a Mégse gombot." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nincsenek paraméterek beállítva a diff parancshoz. Az alapértelmezett " "„{params}” érték használata." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Csak eltérő pillanatképek" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Csak ezzel azonos pillanatképek felsorolása:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Alapos ellenőrzés (pontosabb, de lassú)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Törlés" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Összes kijelölése" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Összehasonlítás" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ugrás ide" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Beállítások" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nem lehet összehasonlítani egy pillanatképet önmagával." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Valóban törölni szeretné a(z) „{file}” fájlt a(z) „{snapshot_id}” " "pillanatképből?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Valóban törölni szeretné a(z) „{file}” fájlt {count} pillanatképből?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "FIGYELMEZTETÉS: ezt nem lehet visszavonni." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Kizárja a(z) „{path}” útvonalat a jövőbeli pillanatképekből?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "A biztonsági mentés almappáját nem lehet felvenni." backintime-1.5.4/common/po/id.po000066400000000000000000001750561477034762000165210ustar00rootroot00000000000000# Indonesian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-21 12:46+0000\n" "Last-Translator: buhtz \n" "Language-Team: Indonesian \n" "Language: id\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Peringatan" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profil utama" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokal (terenkripsi EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (terenkripsi EncFS)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Kunci privat SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Terenkripsi lokal" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Enkripsi" #: common/config.py:289 msgid "SSH encrypted" msgstr "Terenkripsi SSH" #: common/config.py:296 msgid "Default" msgstr "Baku" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Direktori snapshot tidak valid." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Setidaknya satu direktori harus dipilih untuk cadangan." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Direktori: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Direktori ini tidak bisa disertakan dalam cadangan karena itu adalah bagian " "dari tujuan cadangan itu sendiri." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Gagal menulis crontab baru." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron tidak berjalan meskipun perintah crontab tersedia. Pekerjaan cadangan " "terjadwal tidak akan dijalankan. Cron mungkin sudah terpasang tetapi belum " "diaktifkan. Cobalah perintah systemctl enable cron atau konsultasikan dengan" " saluran dukungan distribusi GNU/Linux Anda." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Tidak bisa memasang aturan Udev untuk profil {profile_id}. Layanan DBus " "'{dbus_interface}' tidak tersedia" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Penjadwalan Udev tidak berfungsi dengan mode {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Tidak bisa menemukan UUID untuk {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Gagal menyimpan konfigurasi" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Gagal memuat konfigurasi" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" sudah ada." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Profil terakhir tidak dapat dihapus." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Tidak bisa mengait '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Konfigurasi untuk direktori yang terenkripsi tidak ditemukan." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Buat direktori terenkripsi baru?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Batal" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Silakan konfirmasikan kata sandi." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Kata sandi tidak cocok." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ambil snapshot" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Tidak bisa melepas kait {mountprocess} dari {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} tidak ditemukan. Silakan pasang (mis. melalui " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Titik kait {mntpoint} tidak kosong." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Masukkan kata sandi untuk profil {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "GAGAL" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Pulihkan izin" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Selesai" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Tunda pencadangan saat memakai baterai" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Tak bisa temukan direktori snapshot." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Jika itu ada pada drive lepas pasang harap tancapkan." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Menunggu %s detik." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Gagal mengambil snapshot {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Harap sabar. Sedang menyelesaikan…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Tak bisa membuat direktori." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Menyimpan berkas konfigurasi…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Menyimpan izin…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Ditemukan sisa snapshot {snapshot_id} yang dapat dilanjutkan." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Menghapus sisa direktori {snapshot_id} dari proses sebelumnya" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Tak bisa membuang direktori" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Mengambil snapshot" #: common/snapshots.py:1430 msgid "Success" msgstr "Sukses" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transfer sebagian karena kesalahan" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transfer sebagian karena berkas sumber yang menghilang (lihat 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' berakhir dengan kode keluar {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Lihat 'man rsync' untuk lebih jelasnya" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Kode keluar rsync negatif adalah nomor sinyal, lihat 'kill -l' dan 'man " "kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Tidak ada yang berubah, tidak perlu membuat snapshot baru" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Tidak bisa mengubah nama {new_path} ke {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Penghapusan cerdas" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Terapkan aturan untuk membuang snapshot lama" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Terapkan kebijakan retensi" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Mencoba menjaga ruang kosong minimum" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Mencoba menjaga min {perc} inode bebas" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Sekarang" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Tidak bisa mengait {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent tidak ditemukan. Pastikan sudah terpasang." #: common/sshtools.py:470 #, fuzzy msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Tidak dapat membuka kunci kunci privat SSH. Kata sandi salah atau tidak " "tersedia untuk cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cipher {cipher} gagal untuk {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Path remote ada tapi sayangnya bukan sebuah direktori." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Path remote tidak bisa ditulisi." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Path remove tidak bisa dieksekusi." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Tak bisa membuat path remote." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Host {host} remote tak mendukung {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Lihat 'man backintime' untuk instruksi lebih lanjut" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Pemeriksaan perintah pada host {host} mengembalikan kesalahan yang tak " "dikenal" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Host {host} remote tidak mendukung hardlink" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Salin ssh-key publik \"{pubkey}\" ke host remote \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Mohon masukkan kata sandi untuk \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Sistem berkas tujuan untuk {path} diformat dengan NTFS, yang diketahui " "memiliki inkompatibilitas dengan sistem berkas gaya Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} bukan direktori yang valid." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Pembuatan direktori berikut gagal:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Akses tulis mungkin dibatasi." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Sistem berkas tujuan untuk {path} diformat FAT yang tidak mendukung hard-" "link. Silakan gunakan sistem berkas GNU/Linux yang native." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Sistem berkas tujuan untuk {path} adalah share yang dikait lewat SMB. " "Pastikan server SMB remote mendukung symlink atau aktifkan {copyLinks} dalam" " {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Salin link (dereference link simbolik)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opsi Pakar" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Sistem berkas tujuan untuk {path} adalah share yang dikait lewat sshfs. " "sshfs tidak mendukung hard-link. Harap gunakan mode \"SSH\" sebagai " "pengganti." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Pembuatan berkas gagal di direktori ini:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Tentang" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Penulis" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Terjemahan" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lisensi" #: qt/app.py:172 msgid "Shortcuts" msgstr "Pintasan" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Direktori ini tidak ada\n" "dalam snapshot yang sedang dipilih." #: qt/app.py:257 msgid "Add to Include" msgstr "Tambah ke Disertakan" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Tambah ke Pengecualian" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} tampaknya dijalankan untuk pertama kali karena tidak ditemukan " "konfigurasi." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Impor konfigurasi yang ada (dari direktori target cadangan atau komputer " "lain)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Jika folder tersebut ada pada drive lepas pasang harap tancapkan lalu tekan " "OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ambil snapshot" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Gunakan waktu & ukuran modifikasi untuk deteksi perubahan berkas." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ambil snapshot (mode checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Gunakan checksum untuk deteksi perubahan berkas." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Istirahatkan proses snapshot" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Lanjutkan proses snapshot" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Hentikan proses snapshot" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Segarkan daftar snapshot" #: qt/app.py:497 msgid "Name snapshot" msgstr "Namai snapshot" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Buang snapshot" #: qt/app.py:505 msgid "View snapshot log" msgstr "Lihat catatan log snapshot" #: qt/app.py:509 msgid "View last log" msgstr "Lihat catatan log terakhir" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Kelola profil…" #: qt/app.py:517 msgid "Shutdown" msgstr "Matikan" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Matikan sistem setelah snapshot selesai." #: qt/app.py:521 msgid "Setup language…" msgstr "Siapkan bahasa…" #: qt/app.py:525 msgid "Exit" msgstr "Keluar" #: qt/app.py:529 msgid "User manual" msgstr "Manual pengguna" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Buka manual pengguna dalam peramban (lokal bila tersedia dan daring bila " "tidak)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "halaman man: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Menampilkan halaman man tentang Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "halaman man: Berkas konfigurasi profil" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Menampilkan halaman man tentang berkas konfig profil (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Situs web proyek" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Buka situs web Back In Time dalam peramban" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Log Perubahan" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Buka Pertanyaan Sering Muncul (FAQ) dalam peramban" #: qt/app.py:559 msgid "Ask a question" msgstr "Ajukan pertanyaan" #: qt/app.py:563 msgid "Report a bug" msgstr "Laporkan bug" #: qt/app.py:566 msgid "Translation" msgstr "Terjemahan" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Menampilkan lagi pesan tentang partisipasi dalam penerjemahan." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transisi Enkripsi (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Menampilkan lagi pesan tentang penghapusan EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Pulihkan" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Pulihkan berkas atau direktori yang dipilih ke tujuan asli." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Pulihkan ke …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Pulihkan berkas atau direktori yang dipilih ke sebuah tujuan baru." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Pulihkan direktori yang saat ini ditampilkan dan semua isinya ke tujuan " "asli." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Pulihkan direktori yang saat ini ditampilkan dan semua isinya ke tujuan " "baru." #: qt/app.py:601 msgid "Up" msgstr "Naik" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Tampilkan berkas tersembunyi" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Bandingkan snapshot…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kandidat Rilis" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Menampilkan lagi pesan tentang Kandidat Rilis ini." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Pulihkan" #: qt/app.py:698 msgid "&Help" msgstr "B&antuan" #: qt/app.py:743 msgid "Icons only" msgstr "Hanya ikon" #: qt/app.py:746 msgid "Text only" msgstr "Hanya teks" #: qt/app.py:749 msgid "Text below icons" msgstr "Teks di bawah ikon" #: qt/app.py:752 msgid "Text beside icon" msgstr "Teks di samping ikon" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Jika Anda menutup jendela ini, Back In Time tidak akan mampu mematikan " "sistem Anda ketika snapshot selesai dibuat." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Anda yakin ingin menutupnya?" #: qt/app.py:1072 msgid "Working:" msgstr "Sedang Bekerja:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Selesai, backup tidak diperlukan" #: qt/app.py:1129 msgid "Working" msgstr "Sedang Bekerja" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Kesalahan" #: qt/app.py:1161 msgid "Sent" msgstr "Terkirim" #: qt/app.py:1162 msgid "Speed" msgstr "Kecepatan" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Home" #: qt/app.py:1255 msgid "Backup directories" msgstr "Cadangkan direktori" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nama Snapshot" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Yakin hendak membuang snapshot ini?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Buat salinan cadangan dengan {suffix} di belakang\n" "sebelum menimpa atau menghapus elemen lokal." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Versi lebih baru dari berkas akan diubah nama dengan tambahan {suffix} di " "belakang sebelum memulihkan. Jika Anda tidak memerlukannya lagi Anda dapat " "menghapusnya dengan perintah berikut:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Hanya pulihkan berkas yang tidak ada atau\n" "lebih baru dari yang ada di tujuan.\n" "Memakai opsi \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Buang elemen yang lebih baru di direktori asli." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Memulihkan berkas atau direktori yang dipilih ke tujuan asli dan menghapus " "berkas atau direktori yang tidak ada dalam snapshot. Mesti sangat berhati-" "hati karena ini akan menghapus berkas dan direktori yang dikecualikan pada " "saat pengambilan snapshot." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Yakin ingin memulihkan elemen ini ke dalam direktori baru?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Yakin ingin memulihkan elemen ini?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Yakin ingin membuang semua berkas yang lebih baru dalam {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Yakin ingin membuang semua berkas yang lebih baru dalam direktori asli?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Peringatan{BOLDEND}: Menghapus berkas dalam sistem berkas root dapat " "merusak seluruh sistem Anda." #: qt/app.py:1857 msgid "Snapshot" msgstr "Snapshot" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Pulihkan {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Pulihkan {path} ke …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Halo\n" "Kini Anda sudah menggunakan Back In Time dalam bahasa {language} beberapa kali.\n" "Penerjemahan ke dalam {language} dari versi Back In Time yang terpasang telah {perc} selesai. Terlepas dari tingkat keahlian teknismu, Anda bisa berkontribusi dalam penerjemahan maupun Back In Time itu sendiri.\n" "Bila ingin terlibat, silakan kunjungi {translation_platform_url}. Untuk bantuan dan pertanyaan lebih lanjut, silakan kunjungi {back_in_time_project_website}.\n" "Maaf atas gangguannya, dan pesan ini tidak akan ditampilkan lagi. Dialog ini tersedia kapan saja melalui menu bantuan.\n" "Tim Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "platform penerjemahan" #: qt/app.py:2076 msgid "Website" msgstr "Situs Web" #: qt/app.py:2090 msgid "Your translation" msgstr "Terjemahan Anda" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Dalam Fediverse pada Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email ke {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Milis {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} di laman web proyek." #: qt/app.py:2118 msgid "Open an issue" msgstr "Buat laporan masalah" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Atau, Anda dapat menggunakan saluran lain sesuai keinginan Anda." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Versi Back In Time ini adalah Kandidat Rilis dan terutama ditujukan untuk pengujian stabilitas sebagai persiapan untuk rilis resmi berikutnya.\n" "Tidak ada data pengguna atau telemetri yang dikumpulkan. Namun, tim Back In Time sangat tertarik untuk mengetahui apakah Kandidat Rilis ini digunakan dan apakah layak untuk terus menyediakan versi pra-rilis seperti ini.\n" "Oleh karena itu, tim dengan hormat meminta umpan balik singkat tentang apakah Anda telah menguji versi ini, bahkan jika Anda tidak menemukan masalah apa pun. Uji coba cepat selama beberapa menit pun akan sangat membantu kami.\n" "Opsi kontak berikut tersedia:\n" "{contact_list}\n" "Dalam versi ini, pesan ini tidak akan ditampilkan lagi tetapi dapat diakses kapan saja melalui menu bantuan.\n" "Terima kasih atas dukungan Anda dan telah membantu kami meningkatkan Back In Time!\n" "Tim Back In Time Anda" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Pengaturan bahasa hanya berlaku setelah memulai ulang Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Penciptaan profil EncFS akan dihapus dalam rilis minor selanjutnya (1.7), " "yang dijadwalkan pada 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Tidak disarankan lagi untuk memakai mode itu bagi suatu profil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "whitepaper" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Dukungan bagi EncFS dihentikan karena kerentanan keamanan." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Untuk rincian lebih lanjut, termasuk alternatif-alternatif potensial, harap " "mengacu ke {whitepaper} ini." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Profil berikut memakai enkripsi dengan EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Suatu pengganti ada direncanakan, tapi tidak bisa menjamin akan hadir pada " "waktunya." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Pengguna diundang bergabung ke diskusi ini. Rincian terbarui tentang " "langkah-langkah selanjutnya tersedia pada {whitepaper} ini." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Pesan ini tidak akan ditampilkan lagi. Dialog ini tersedia kapan pun melalui" " menu bantuan." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Tim Back In Time Anda" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Siapkan bahasa" #: qt/languagedialog.py:97 msgid "System default" msgstr "Baku sistem" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Gunakan bahasa sistem operasi." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Diterjemahkan: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Tampilan Log Terakhir" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Tampilan Log Snapshot" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Snapshot:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Semua" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Perubahan" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Kesalahan" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informasi" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "kegagalan transfer rsync (eksperimen)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Kesalahan, [I] Informasi, [C] Ubah" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekode path" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Kelola profil" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Sunting" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Tambah" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Buang" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Umum" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Sertakan" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Sertakan berkas dan direktori" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Tambah berkas" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Tambah direktori" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "K&ecualikan" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: Dalam mode 'SSH terenkripsi', hanya asterisk tunggal " "atau ganda yang berfungsi (mis. {example2}). Tipe wildcard dan pola lain " "akan diabaikan (mis. {example1}). Nama berkas itu tidak dapat ditebak dalam " "mode ini karena enkripsi oleh EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Kecualikan pola, berkas, atau direktori" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Tambahkan baku" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Abaikan berkas yang lebih dari:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Abaikan berkas yang lebih dari {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Dengan 'Mode rsync lengkap' dimatikan, ini hanya akan mempengaruhi berkas-" "berkas baru karena untuk rsync ini merupakan pilihan transfer, bukan opsi " "pengabaian. Maka berkas-berkas besar yang telah dicadangkan sebelumnya akan " "tetap berada dalam snapshot-snapshot bahkan setelah mereka berubah." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Hapus & &Retensi" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opsi" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Opsi &Pakar" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Pulihkan Konfigurasi" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Sunting user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Profil baru" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Ubah nama profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Yakin ingin menghapus profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Sangat disarankan{ENDBOLD}: (Semua saran telah disertakan.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Sangat disarankan{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Abaikan pola" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Abaikan berkas" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Abaikan direktori" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Sertakan berkas" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" adalah sebuah symlink. Tujuan yang ditaut tidak akan dicadangkan hingga Anda juga menyertakannya.\n" "Apakah Anda ingin menyertakan tujuan yang di-symlink sebagai pengganti?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Sertakan direktori" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Dinonaktifkan karena pola ini tidak berfungsi dalam mode 'SSH terenkripsi'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Jadwal" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Hari:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Hari kerja:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Waktu:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Jam:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "setelah jam" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Menit:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Jalankan Back In Time segera setelah drive terhubung (hanya sekali setiap X " "hari). Anda akan ditanya untuk kata sandi sudo Anda." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Jalankan Back In Time secara berulang. Ini berguna bila komputer tidak " "dijalankan secara berkala." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Setiap:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Fungsikan pencatatan log dari pesan-pesan debug" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Menulis pesan-pesan level debug ke dalam log sistem melalui \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Waspada: Hanya gunakan ini sementara untuk diagnostik, karena itu " "menghasilkan keluaran yang sangat banyak." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Dinonaktifkan" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Pada setiap boot/reboot" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Setiap {n} menit" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Setiap {n} jam" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Setiap {n} jam" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Waktu khusus" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Setiap hari" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Berulang (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Ketika drive tersambung (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Setiap minggu" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Setiap bulan" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Setiap tahun" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Jam" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Hari" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Minggu" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Bulan" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Jam ubahan hanya dapat berupa daftar jam yang dipisah koma (contoh: " "8,12,18,23) atau */3 untuk backup terjadwal setiap 3 jam." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proksi SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Pengguna:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Menyambung ke host target melalui proksi ini (juga dikenal sebagai jump " "host). Lihat \"-J\" dalam dokumentasi perintah \"ssh\" atau \"ProxyJump\" " "dalam halaman man \"ssh_config\" untuk rinciannya." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Peringatan:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Opsi-opsi ini untuk konfigurasi lanjutan. Ubah hanya jika Anda benar-benar " "memahami dampaknya." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Jalankan 'rsync' dengan '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "sebagai cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "pada host jarak jauh" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "ketika mengambil snapshot manual" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Mohon pasang 'nocache' untuk mengaktifkan opsi ini." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "pada mesin lokal" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Arahkan ulang stdout ke /dev/null dalam cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron akan secara otomatis mengirim suatu surel dengan keluaran cronjob yang " "dilampirkan bila suatu MTA terpasang." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Arahkan ulang stderr ke /dev/null dalam cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron akan secara otomatis mengirim suatu email dengan kesalahan cronjob yang" " dilampirkan bila suatu MTA terpasang." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/detik" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Batasi penggunaan bandwidth rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Pertahankan ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Pertahankan atribut tambahan (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Salin tautan yang tidak aman (hanya bisa untuk tautan absolut)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Batasi ke satu sistem berkas" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opsi harus diapit tanda kutip mis.: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Tempelkan opsi tambahan ke rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefiks yang dijalankan sebelum setiap perintah pada host jarak jauh." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabel perlu di-escape dengan \\$FOO. Ini tidak menyentuh rsync. Jadi " "untuk menambah awalan bagi rsync gunakan \"{example_value}\" dengan " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "baku" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Tambahkan prefiks ke perintah-perintah SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Periksa apakah host jarak jauh sedang daring" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Peringatan: jika dimatikan dan host jarak jauh tidak tersedia, ini dapat " "menyebabkan kesalahan yang aneh." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Periksa apakah host jarak jauh mendukung semua perintah yang diperlukan." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Peringatan: jika dimatikan dan host jarak jauh tidak mendukung semua " "perintah yang dibutuhkan, ini dapat menyebabkan beberapa kesalahan aneh." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(baku: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "dinonaktifkan" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "difungsikan" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mode:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Lokasi penyimpanan snapshot" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Pengaturan SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Path:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cipher:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Kunci Privat:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Pilih berkas kunci privat yang sudah ada (umumnya dinamai \"id_ed25519\" dan" " dalam penyiapan lama \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Buat kunci SSH baru tanpa kata sandi (tidak diizinkan jika kunci privat " "sudah dipilih)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Kata Sandi" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Simpan Kata Sandi ke Ring Kunci" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Singgahkan Kata Sandi untuk Cron (Masalah keamanan: root dapat membaca kata " "sandi)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Tingkat Lanjut" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Path snapshot lengkap:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Anda tidak memilih suatu berkas kunci privat bagi SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Apakah Anda ingin membuat pasangan baru kunci publik/privat tanpa kata " "sandi?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Berkas kunci privat \"{file}\" tidak ada." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Apakah Anda ingin menyalin kunci publik SSH Anda ke host jarak jauh untuk " "mengaktifkan login tanpa kata sandi?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Keaslian host \"{host}\" tidak dapat diyakinkan." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Sidik jari kunci {keytype} adalah:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Mohon memeriksa sidik jari ini. Apakah Anda ingin menambahkannya ke dalam " "berkas 'known_hosts' Anda?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Yakin ingin mengubah direktori snapshot?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Gagal membuat kunci SSH baru dalam {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Fungsikan pemberitahuan" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Matikan snapshot ketika menggunakan baterai" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Status daya tidak tersedia dari sistem" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Jalankan hanya satu snapshot pada suatu saat" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Snapshot-snapshot lain akan diblok hingga snapshot yang sekarang berjalan " "selesai. Ini adalah pilihan global. Jadi ini akan mempengaruhi semua profil " "untuk pengguna ini. Tetapi Anda harus mengaktifkan ini untuk pengguna " "lainnya juga." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Backup menggantikan berkas-berkas saat pemulihan" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Versi lebih baru dari berkas akan diubah nama dengan tambahan {suffix} di " "belakang sebelum memulihkan. Jika Anda tidak memerlukannya lagi Anda dapat " "menghapusnya dengan {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" "Lanjukan saat ada kesalahan (simpan snapshot-snapshot yang tidak lengkap)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Gunakan checksum untuk mendeteksi perubahan" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ambil snapshot baru walaupun ada perubahan atau tidak." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Level Log:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nihil" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Aturan-aturan berikut diproses dari puncak ke dasar. Aturan-aturan yang " "belakangan menimpa yang sebelumnya dan tidak dibatasi oleh mereka. Lihat " "{manual} untuk rincian dan contoh." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual pengguna" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Buka manual pengguna dalam peramban." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Simpan snapshot terkini." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Snapshot terakhir atau paling baru dipertahankan di bawah semua keadaan." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Perilaku itu tidak bisa diubah." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Simpan snapshot yang dinamai." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Snapshot yang diberi nama, selain memiliki stempel waktu biasa, akan " "dipertahankan di bawah semua keadaan dan tidak akan dihapus." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Tahun" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Buang snapshot yang lebih lama dari" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Hari penuh. Hari kini diabaikan." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Minggu kalender dengan Senin sebagai hari pertama. Minggu kini diabaikan." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Periode 12 bulan. Bulan kini diabaikan." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Kebijakan retensi" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Jalankan di latar belakang pada host jarak jauh." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Prosedur penghapusan cerdas akan dijalankan langsung pada mesin jarak jauh, " "bukan secara lokal. Perintah 'bash', 'screen', dan 'flock' harus diinstal " "dan tersedia pada mesin jarak jauh." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Jika dipilih, Back In Time akan terlebih dahulu menguji mesin jarak jauh." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Hari-hari dihitung mulai dari hari ini." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Simpan semua snapshot selama" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "hari terakhir." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Simpan snapshot terakhir untuk setiap hari selama" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Minggu-minggu dihitung mulai dari minggu kini yang sedang berjalan. Suatu " "minggu mulai pada hari Senin." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Simpan snapshot terakhir untuk setiap minggu selama" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "minggu terakhir." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Bulan-bulan dihitung sebagai bulan kalender mulai dari bulan kini." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Simpan snapshot terakhir untuk setiap bulan selama" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "bulan terakhir." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Tahun-tahun dihitung sebagai tahun kalender mulai dari tahun kini." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Simpan snapshot terakhir untuk setiap tahun selama" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "semua tahun." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... ruang kosong kurang dari" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... inode bebas kurang dari" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Membuang snapshot paling lama bila …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pertanyaan" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Lihat Catatan Log Terakhir" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Mulai {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Sedang Bekerja…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Terkirim:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Kecepatan:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snapshot" #: qt/qttools.py:506 msgid "Today" msgstr "Hari ini" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Kemarin" #: qt/qttools.py:522 msgid "This week" msgstr "Minggu ini" #: qt/qttools.py:529 msgid "Last week" msgstr "Minggu lalu" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Ini BUKAN sebuah snapshot melainkan tampilan langsung dari berkas-berkas " "lokal Anda" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Pemeriksaan terakhir {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Impor konfigurasi" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Konfigurasi tidak ditemukan" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Impor" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Pilih direktori snapshot tempat asal berkas konfigurasi mesti diimpor. Path-" "nya mungkin seperti ini: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Bila direktori terletak pada drive eksternal atau jarak jauh, itu mesti " "dikait secara manual sebelumnya." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Tampilkan log lengkap" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opsi tentang membandingkan snapshot" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Perintah:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parameter:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Gunakan %1 dan %2 untuk parameter path" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Harap atur suatu perintah diff atau tekan Batal." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Perintah \"{cmd}\" tidak bisa ditemukan pada sistem ini. Harap coba yang " "lain atau tekan Batal." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Tidak ada parameter yang diatur untuk perintah diff. Memakai nilai baku " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Hanya snapshot yang berbeda" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Hanya cantumkan daftar snapshot yang sama dengan:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Pemeriksaan mendalam (lebih akurat, tetapi lambat)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Hapus" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Pilih Semua" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Bandingkan" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Pergi Ke" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opsi" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Anda tidak bisa membandingkan sebuah snapshot dengan dirinya sendiri." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Apakah Anda yakin ingin menghapus \"{file}\" dalam snapshot " "\"{snapshot_id}\"?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Apakah Anda yakin ingin menghapus \"{file}\" dalam {count} snapshot?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "PERINGATAN: Ini tidak dapat dicabut." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Jangan ikutkan \"{path}\" dari snapshot mendatang?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Sub direktori tidak dapat disertakan dalam cadangan." backintime-1.5.4/common/po/ie.po000066400000000000000000001336701477034762000165160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the "Back In Time" package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \"Back In Time\" \"1.5.2-dev\"\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-01-26 18:37+0000\n" "Last-Translator: Mithridates \n" "Language-Team: Occidental \n" "Language: ie\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.9.2\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Avise" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Chef-profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (ciffrat con EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (ciffrat con ENcFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Privat clave SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Local, ciffrat" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Ciffration" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH, ciffrat" #: common/config.py:296 msgid "Default" msgstr "Predefinit" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: «{name}»" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Restituer {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Ne posset inscrir nov crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Ne posset trovar UUID por {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Ne posset salvar config" #: common/configfile.py:137 msgid "Failed to load config" msgstr "" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" ja existe." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Li ultim profil ne posse esser removet." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Ne posset montar '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "" #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "" #: common/encfstools.py:146 msgid "Cancel" msgstr "Anullar" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Ples confirmar li passaparol." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command} ne trovar. Ples installar it (p.ex. per \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NE SUCCESSAT" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restituer permissiones" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Finit" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Atendent %s second." msgstr[1] "Atendent %s secondes." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Ne successat crear un fólder." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Salvant permissiones…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Ne successat creat un fólder" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "" #: common/snapshots.py:1430 msgid "Success" msgstr "Successe" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' finit con code de exeada {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Usar 'man rsync' por plu detallies" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Ne posset renominar {new_path} a {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Provant mantener un minimum de líber spacie" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nu" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Ne posset montar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent ne trovat. Ples confirmar que it es installat." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cipher {cipher} fallit por {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Usar 'man backintime' por plu detallies" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Ples inscrir un passaparol por \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "" #: common/tools.py:504 msgid "Expert Options" msgstr "Expert Optiones" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Pri" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autores" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traductores" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licentie" #: qt/app.py:172 msgid "Shortcuts" msgstr "Rapid-tastes" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" #: qt/app.py:257 msgid "Add to Include" msgstr "Adjunter a Inclusion" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Adjunter a Exclusion" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" #: qt/app.py:470 msgid "Take a snapshot" msgstr "" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "" #: qt/app.py:497 msgid "Name snapshot" msgstr "" #: qt/app.py:501 msgid "Remove snapshot" msgstr "" #: qt/app.py:505 msgid "View snapshot log" msgstr "" #: qt/app.py:509 msgid "View last log" msgstr "" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gerer profiles…" #: qt/app.py:517 msgid "Shutdown" msgstr "" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "" #: qt/app.py:521 msgid "Setup language…" msgstr "Configurar li lingue…" #: qt/app.py:525 msgid "Exit" msgstr "Surtir" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "" #: qt/app.py:555 msgid "FAQ" msgstr "" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Questionar" #: qt/app.py:563 msgid "Report a bug" msgstr "" #: qt/app.py:566 msgid "Translation" msgstr "Traduction" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restituer" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restituer a …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" #: qt/app.py:601 msgid "Up" msgstr "Al superiori" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "&Archivar" #: qt/app.py:692 msgid "&Restore" msgstr "&Restituer" #: qt/app.py:698 msgid "&Help" msgstr "Au&xilie" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Vole tu vermen cluder it?" #: qt/app.py:1072 msgid "Working:" msgstr "Laborant:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "" #: qt/app.py:1129 msgid "Working" msgstr "Laborant" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Errore" #: qt/app.py:1161 msgid "Sent" msgstr "Misset" #: qt/app.py:1162 msgid "Speed" msgstr "Rapiditá" #: qt/app.py:1163 msgid "ETA" msgstr "" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "" #: qt/app.py:1227 msgid "Home" msgstr "Hem" #: qt/app.py:1255 msgid "Backup directories" msgstr "" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" #: qt/app.py:1857 msgid "Snapshot" msgstr "" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restituer {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2071 msgid "translation platform" msgstr "platform de traduction" #: qt/app.py:2076 msgid "Website" msgstr "Websitu" #: qt/app.py:2090 msgid "Your translation" msgstr "Vor traduction" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Lingue" #: qt/languagedialog.py:97 msgid "System default" msgstr "Del sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traductet: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtre:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Omni" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Modificationes" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Errores" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "" msgstr[1] "" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gerer profiles" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Adjunter" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Remover" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&General" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Includer" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Includer un fólder" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Adjunter un file" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Adjunter un fólder" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Excluder" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Parametres" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nov profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renominar li profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Excluder un mustre" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Excluder un file" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Excluder un fólder" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Includer un file" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Includer un fólder" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Plan" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Die:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Die de semane:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Hores:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Chascun:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Ínactiv" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Chascun die" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Chascun semane" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Chascun mensu" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Chascun annu" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "hor(es)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "die(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "semane(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mensu(s)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Portu:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usator:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Question" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "Ko/sec" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "predefinit" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(predefinit: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "ínactiv" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "activ" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mode:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Parametres de SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Rute:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Ciffre:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privat clave:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Contrasigne" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avansat" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Null" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "annu(s)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "die(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semane(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mensu(s)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Question" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Lansar {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "" #: qt/qttools.py:506 msgid "Today" msgstr "Hodíe" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Yer" #: qt/qttools.py:522 msgid "This week" msgstr "Ho-semane" #: qt/qttools.py:529 msgid "Last week" msgstr "Ultim semane" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comande:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametres:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Remover" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Selecter omni" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparar" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ear a" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Parametres" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "" backintime-1.5.4/common/po/is.po000066400000000000000000001571741477034762000165410ustar00rootroot00000000000000# Sveinn í Felli , 2023. msgid "" msgstr "" "Project-Id-Version: Icelandic (Back In Time)\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-01-03 03:42+0000\n" "Last-Translator: sveinki \n" "Language-Team: Icelandic \n" "Language: is\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.9.2\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Aðvörun" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Aðalsnið" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Staðvært (EncFS-dulritað)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-dulritað)" #: common/config.py:278 msgid "Local" msgstr "Staðvært" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH-einkalykill" #: common/config.py:283 msgid "Local encrypted" msgstr "Staðvært dulritað" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Dulritun" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH dulritað" #: common/config.py:296 msgid "Default" msgstr "Sjálfgefið" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Snið: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Mappa fyrir skyndiafrit er ekki gild." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Að minnsta kosti ein mappa verður að vera undir öryggisafrit." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Endurheimta {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Mappan getur ekki verið innifalin í öryggisafritinu." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Mistókst að skrifa nýtt crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Gat ekki installað Udev reglu fyrir prófíl {profile_id}. DBus þjónusta " "'{dbus_interface}' var ekki í boði" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Áætlað udev virkar ekki með hamnum {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Gat ekki fundið UUID fyrir {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Mistókst að vista stillingaskrá" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Mistókst að hlaða inn stillingaskrá" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Sniðið \"{name}\" er þegar til staðar." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Ekki er hægt að fjarlægja síðasta sniðið." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Get ekki tengt '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Grunnstillingar fyrir dulritaða möppu fundust ekki." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Búa til nýja dulritaða möppu?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Hætta við" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Staðfestu lykilorðið." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Lykilorðin samsvara ekki." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Taka skyndiafrit" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Get ekki aftengt {mountprocess} úr {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} fannst ekki. Endilega settu það upp (t.d. með " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Tengipunktur {mntpoint} er ekki laus." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Settu inn lykilorð fyrir {mode}-notkunarsniðið \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "MISTÓKST" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Endurheimta heimildir" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Búið" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Fresta afritun þegar rafhlöður eru í notkun" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Finn ekki möppu fyrir skyndiafrit." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Ef hún er á útskiptanlegu drifi, skaltu tengja það og ýta síðan á 'Í lagi'." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Bið %s sekúndu." msgstr[1] "Bið %s sekúndur." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Mistókst að taka skyndiafritið {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Sýndu þolinmæði. Er að klára.…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Get ekki búið til möppu." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Vista stillingaskrá…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Vista aðgangsheimildir…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Fann leifar af skyndiafritinu {snapshot_id} sem hægt er að halda áfram með." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Fjarlægi leifar af möppunni {snapshot_id} frá síðustu keyrslu" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Get ekki fjarlægt möppu" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Taka skyndiafrit" #: common/snapshots.py:1430 msgid "Success" msgstr "Tókst" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Einungis hluti skráaflutnings vegna villu" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Einungis hluti skráaflutnings vegna horfinna upprunaskráa (skoðaðu 'man " "rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' hætti með stöðvunarkóðanum {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Skoðaðu 'man rsync' til að sjá frekari upplýsingar" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Engar breytingar, engin þörf fyrir nýtt skyndiafrit" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Gat ekki endurnefnt {new_path} sem {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Snjöll fjarlæging" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Fjarlægja gömul skyndiafrit" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Reyna að halda í lágmarksmagn af lausu plássi" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Reyna að halda a.m.k. {perc} af lausum i-hnútum (inodes)" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Núna" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Get ekki tengt {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent fannst ekki. Gakktu úr skugga um að það sé uppsett." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Tókst ekki að aflæsa ssh-einkalykli. Rangt lykilorð eða að lykilorð er ekki " "tiltækt fyrir cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Dulritunaraðferðin {cipher} tókst ekki fyrir {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Fjartengd slóð er til, en er ekki mappa." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Fjartengd slóð er ekki skrifanleg." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Fjartengd slóð er ekki keyranleg." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Tókst ekki að útbúa fjartengda slóð." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Fjartengda vélin {host} styður ekki {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Skoðaðu 'man backintime' til að sjá frekari leiðbeiningar" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Fjartengda vélin {host} styður ekki harðtengi (hardlinks)" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Afritaðu ssh-dreifilykil \"{pubkey}\" yfir á fjartengdu vélina \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Settu inn lykilorð fyrir \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Markskráakerfi fyrir {path} er í NTFS-sniði, sem þekkt er fyrir ósamhæfni " "við Unix-ættuð skráakerfi." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} er ekki gild mappa." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Gerð eftirfarandi möppu mistókst:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Skrifaðgangur gæti verið takmarkaður." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Markskráakerfi fyrir {path} er á FAT-sniði sem virkar ekki með hörðum-" "tenglum. Notaðu frekar upprunalegt GNU/Linux skráakerfi." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Markskráakerfi fyrir {path} er SMB-tengd sameign. Gakktu úr skugga um að " "fjartengdi SMB-þjónninn styðji tákntengi (symlink) eða virkjaðu {copyLinks} " "í {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Afrita tengla (afbyggja tákntengi - dereference symbolic links)" #: common/tools.py:504 msgid "Expert Options" msgstr "Ítarlegri valkostir" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Markskráakerfi fyrir {path} er í sshfs-tengd sameign. SSHFS styður ekki " "harða-tengla. Notaðu frekar 'SSH'." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Mistókst að útbúa skrá í þessari möppu:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Um forritið" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Höfundar" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Þýðingar" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Notkunarleyfi" #: qt/app.py:172 msgid "Shortcuts" msgstr "Flýtilyklar" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Þessi mappa er ekki til\n" "í valda skyndiafritinu." #: qt/app.py:257 msgid "Add to Include" msgstr "Bæta við meðfylgjandi" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Bæta við útilokun" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Það lítur út fyrir að {app_name} sé að keyra í fyrsta skipti þar sem engar " "grunnstillingar fundust." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Flytja inn fyrirliggjandi grunnstillingar (úr markmöppu öryggisafritunar eða" " annarri tölvu)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Ef hún er á útskiptanlegu drifi, skaltu tengja það og ýta síðan á 'Í lagi'." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Taka skyndiafrit" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Nota breytingartíma og stærð til að skynja breytingar á skrám." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Taka skyndiafrit (í gátsummuham)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Nota gátsummu til að skynja breytingar á skrám." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Gera hlé á vinnslu skyndiafrits" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Halda áfram með vinnslu skyndiafrits" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stöðva vinnslu skyndiafrits" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Endurlesa lista yfir skyndiafrit" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nefndu skyndiafrit" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Fjarlægja skyndiafrit" #: qt/app.py:505 msgid "View snapshot log" msgstr "Skoða atvikaskrá skyndiafrita" #: qt/app.py:509 msgid "View last log" msgstr "Skoða síðustu atvikaskrá" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Sýsla með notkunarsnið…" #: qt/app.py:517 msgid "Shutdown" msgstr "Slökkva" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Slökkva á kerfi þegar skyndiafritun lýkur." #: qt/app.py:521 msgid "Setup language…" msgstr "Setja upp tungumál…" #: qt/app.py:525 msgid "Exit" msgstr "Hætta" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time öryggisafritun" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Stillingaskrá notkunarsniða" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Breytingasaga" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ / Algengar spurningar" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Spyrja spurninga" #: qt/app.py:563 msgid "Report a bug" msgstr "Tilkynna um villu" #: qt/app.py:566 msgid "Translation" msgstr "Þýðingar" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Birtir aftur skilaboðin um þátttöku í þýðingum." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Encryption Transition (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Birtir aftur skilaboðin um fjarlægingu EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Endurheimta" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Endurheimta valdar skrár eða möppur á upprunalega staðsetningu." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Endurheimta í …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Endurheimta valdar skrár eða möppur á nýja staðsetningu." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Endurheimta sýnda möppu og allt innihald hennar á upprunalega staðsetningu." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Endurheimta sýnda möppu og allt innihald hennar á nýja staðsetningu." #: qt/app.py:601 msgid "Up" msgstr "Upp" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Sýna faldar skrár" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Bera saman skyndiafrit…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Útgáfukandídat" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Birtir aftur skilaboðin um þennan útgáfukandídat." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time öryggisafritun" #: qt/app.py:681 msgid "&Backup" msgstr "&Öryggisafrit" #: qt/app.py:692 msgid "&Restore" msgstr "Endu&rheimta" #: qt/app.py:698 msgid "&Help" msgstr "&Hjálp" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ef þú lokar þessum glugga, mun Back In Time ekki geta slökkt á kerfinu þegar" " skyndiafritun lýkur." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Viltu örugglega loka þessu?" #: qt/app.py:1072 msgid "Working:" msgstr "Að vinna:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Búið, engin öryggisafritun nauðsynleg" #: qt/app.py:1129 msgid "Working" msgstr "Að vinna" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Villa" #: qt/app.py:1161 msgid "Sent" msgstr "Sent" #: qt/app.py:1162 msgid "Speed" msgstr "Hraði" #: qt/app.py:1163 msgid "ETA" msgstr "Áætluð lok" #: qt/app.py:1225 msgid "Global" msgstr "Víðvært" #: qt/app.py:1226 msgid "Root" msgstr "Kerfisstjóri (root)" #: qt/app.py:1227 msgid "Home" msgstr "Einkamappa (Home)" #: qt/app.py:1255 msgid "Backup directories" msgstr "Öryggisafritunarmöppur" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Heiti skyndiafrits" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Ertu viss um að þú viljir fjarlægja þetta skyndiafrit?" msgstr[1] "Ertu viss um að þú viljir fjarlægja þessi skyndiafrit?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Fjarlægja nýjar skrár í upprunalegri möppu." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Ertu viss um að þú viljir endurheimta þetta atriði í nýju möppuna?" msgstr[1] "Ertu viss um að þú viljir endurheimta þessi atriði í nýju möppuna?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ertu viss um að þú viljir endurheimta þetta atriði ?" msgstr[1] "Ertu viss um að þú viljir endurheimta þessi atriði?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Ertu viss um að þú viljir fjarlægja allar nýrri skrár í {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Ertu viss um að þú viljir fjarlægja allar nýrri skrár í upprunalegri möppu?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Aðvörun{BOLDEND}: Eyðing skráa á rót skráarkerfis gæti skemmt " "varanlega allt kerfið þitt." #: qt/app.py:1857 msgid "Snapshot" msgstr "Skyndiafrit" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Endurheimta {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Endurheimta {path} í …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hæ\n" "Þú hefur núna notað Back In Time með {language}-viðmótinu nokkrum sinnum.\n" "Þýðingarnar á uppsettu útgáfunni á Back In Time fyrir {language} eru {perc} kláraðar. Sama á hvaða stigi þú ert varðandi tækniþekkingu, þá geturðu alveg lagt af mörkum við þýðingarnar og þannig einnig til Back In Time.\n" "Þú ættir að skoða {translation_platform_url} ef þig langar til að vera með. Til að fá frekari aðstoð og svör við spurningum ættirðu að heimsækja {back_in_time_project_website}.\n" "Við biðjums velvirðingar á trufluninni, þessi skilaboð munu ekki birtast aftur. Hægt er að skoða þessi skilaboð aftur hvenær sem er úr hjálparvalmyndinni.\n" "Back In Time teymið" #: qt/app.py:2071 msgid "translation platform" msgstr "þýðingakerfið" #: qt/app.py:2076 msgid "Website" msgstr "Vefsvæði" #: qt/app.py:2090 msgid "Your translation" msgstr "Þýðing þín" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Senda tölvupóst til {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Póstlisti {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} á vefsvæði verkefnisins." #: qt/app.py:2118 msgid "Open an issue" msgstr "Opna verkbeiðni" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" "Einnig gætirðu sent inn spurningar á aðra samskiptaleið sem þér líkar." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Breytingar á tungumálastillingum munu öðlast gildi þegar þú skráir þig næst " "inn." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Back In Time teymið þitt" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Setja upp tungumál" #: qt/languagedialog.py:97 msgid "System default" msgstr "Sjálfgefið í kerfinu" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Nota tungumál stýrikerfis." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Þýtt: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Síðasta virka sýn atvikaskráningar" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Sýn á atvikaskrá skyndiafrita" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Notkunarsnið:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Skyndiafrit:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Sía:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Allt" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Breytingar" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Villur" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Upplýsingar" msgstr[1] "Upplýsingar" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Villa, [I] Upplýsingar, [C] Breyta" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "afkóða slóðir" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Sýsla með notkunarsnið" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Breyta" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Bæta við" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Fjarlægja" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Almennt" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "Ta&ka með" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Hafa með skrár og möppur" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Bæta við skrá" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Bæta við möppu" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Undanskilja" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Undanskilja mynstur, skrár eða möppur" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Bæta við sjálfgefnu" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Hunsa skrár stærri en:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Hunsa skrár stærri en gildi í {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Valk&ostir" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Ítarlegri &valkostir" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Endurheimta stillingaskrá" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nýtt snið" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Endurnefna snið" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Ertu viss um að þú viljir eyða sniðinu \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Sérstaklega mælt með{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Útilokunarmynstur" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Undanskilja skrá" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Undanskilja möppu" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Hafa með skrá" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Hafa með möppu" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Vinnuáætlun" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dagur:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Vikudagur:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tími:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Klukkustundir:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Hverjar:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Virkja atvikaskráningu villuleitarskilaboða" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Óvirkt" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Við hverja ræsingu/endurræsingu" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Á {n} mínútu fresti" msgstr[1] "Á {n} mínútna fresti" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Á klukkustundar fresti" msgstr[1] "Á {n} klukkustunda fresti" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} klukkustundar fresti" msgstr[1] "Á {n} klukkustunda fresti" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Sérsniðnar klukkustundir" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Hvern dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Endurtekið (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Þegar drif er tengt (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Vikulega" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Mánaðarlega" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Árlega" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "klukkustund(ir)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "dag(a)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "viku(r)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "mánuð(ir)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH-milliþjónn" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Miðlari:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Gátt:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Notandi:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Varúð:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Keyra 'rsync' með '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "sem cron-verk" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "á fjartengdri vél" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "við að taka handvirkt skyndiafrit" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Settu upp 'nocache' til að geta notað þennan valkost." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "á staðværri vél" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Endurbeina stdout í /dev/null í cron-verkum." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Endurbeina stderr í /dev/null í cron-verkum." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Takmarka notkun rsync á bandbreidd:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Varðveita ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Varðveita ítarleg eigindi (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Afrita ótrygga tengla (virkar aðeins með algilda tengla)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Takmarka við eitt skráakerfi" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Líma viðbótarvalkosti inn í rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "sjálfgefið" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Bæta forskeyti við SSH-skipanir" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Athuga hvort fjartengd vél er á netinu" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Athuga hvort fjartengd vél styðji allar nauðsynlegar skipanir." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(sjálfgefið: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "óvirkt" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "virkt" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Hamur:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Hvar á að vista skyndiafrit" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH stillingar" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Slóð:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Dulritunaraðferð (cipher):" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Einkalykill:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Lykilorð" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Vista lykilorð í lyklakippu" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Nánar" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Heildarslóð skyndiafrita:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Þú valdir enga skrá með einkalykli fyrir SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Einkalykilsskráin \"{file}\" er ekki til." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Ekki tókst að sannreyna auðkenni hýsilvélarinnar {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Fingrafar {keytype} dulritunarlykils er:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Yfirfarðu þetta fingrafar. Myndirðu vilja bæta því í 'known_hosts' skrána " "þina?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Ertu viss um að þú viljir skipta um möppu undir skyndiafrit?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Mistókst að búa til nýjan SSH-lykil í {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Virkja tilkynningar" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Koma í veg fyrir skyndiafritun þegar rafhlaða er í notkun" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Staða rafhlöðu er ekki tiltæk frá kerfinu" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Keyra aðeins eitt skyndiafrit í einu" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Öryggisafrit skipti út skrám við endurheimtingu" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Halda áfram við villur (geyma ókláruð skyndiafrit)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Nota gátsummu til að skynja breytingar" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Taka skyndiafrit sama hvort nokkuð hafi breyst eða ekki." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Stig atvikaskráningar:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ekkert" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Geyma nefnd skyndiafrit." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Geyma nefnd skyndiafrit." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "ár" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Fjarlægja skyndiafrit" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Keyra í bakgrunni á fjartengdri vél." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Geyma öll skyndiafrit síðustu" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dag(a)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Geyma eitt skyndiafrit á dag síðustu" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Geyma eitt skyndiafrit á viku síðustu" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "viku(r)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Geyma eitt skyndiafrit á mánuði síðustu" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mánuði(r)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Geyma öll skyndiafrit síðustu" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Ef laust pláss er minna en:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Ef lausir i-hnútar (inodes) eru færri en:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Fjarlægja gömul skyndiafrit" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Spurning" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Snið: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Skoða síðasta annál" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Ræsa {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Í vinnslu…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Sent:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hraði:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Áætluð lok:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Skyndiafrit" #: qt/qttools.py:506 msgid "Today" msgstr "Í dag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Í gær" #: qt/qttools.py:522 msgid "This week" msgstr "Í þessari viku" #: qt/qttools.py:529 msgid "Last week" msgstr "Í síðustu viku" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Síðasta athugun {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Flytja inn grunnstillingar" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Engin stillingaskrá fannst" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Flytja inn" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Birta fullan annál" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Valkostir við samanburð skyndiafrita" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Skipun:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Viðföng:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Notaðu %1 og %2 fyrir viðföng slóðar" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Veldu aðra diff-skipun eða ýttu á að hætta við." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Skipunin \"{cmd}\" finnst ekki á þessu kerfi. Prófaðu eitthvað annað eða " "ýttu á að hætta við." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Taka skyndiafrit mismunar" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Telja aðeins upp skyndiafrit sem jafngilda:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Ítarleg yfirferð (nákvæmari, en hægvirkt)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Eyða" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Velja allt" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Bera saman" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Fara í" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Valkostir" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Þú getur ekki borið skyndiafrit saman við sjálft sig." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Ertu viss um að þú viljir eyða {file} í skyndiafritinu {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ertu viss um að þú viljir eyða {file} í {count} skyndiafritum?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "AÐVÖRUN: Þetta er ekki hægt að afturkalla." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Útiloka {path} framvegis frá skyndiafritun?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Undirmöppurnar geta ekki verið innifaldar í öryggisafritinu." backintime-1.5.4/common/po/it.po000066400000000000000000002005301477034762000165230ustar00rootroot00000000000000# Italian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 09:08+0000\n" "Last-Translator: smart2128 \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Attenzione" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profilo principale" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Locale (cifratura EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (cifratura EncFS)" #: common/config.py:278 msgid "Local" msgstr "Locale" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Chiave privata SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Locale cifrato" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Cifratura" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH con cifratura" #: common/config.py:296 msgid "Default" msgstr "Predefinito" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profilo: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Cartella delle istantanee non valida." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Selezionare almeno una cartella per il backup." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Cartella: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "La cartella non può essere inclusa nel backup poiché fa parte della " "destinazione del backup stesso." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Impossibile scrivere il nuovo crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron non è in esecuzione nonostante il comando crontab sia disponibile. I " "backup pianificati non saranno eseguiti. Cron potrebbe essere installato, ma" " non abilitato. Prova ad eseguire il comando \"systemctl enable cron\" o " "richiedi assistenza tramite i canali di supporto della tua distribuzione " "GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Impossibile installare la regola di Udev per il profilo {profile_id}. Il " "servizio DBus '{dbus_interface}' non era disponibile" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "La pianificazione udev non funziona con la modalità {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Impossibile trovare UUID per \"{path}\"" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Salvataggio della configurazione fallito" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Impossibile caricare la configurazione" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Il profilo \"{name}\" esiste già." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "L'ultimo profilo non può essere rimosso." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Impossibile montare '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Configurazione per la cartella cifrata non trovata." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Vuoi creare una nuova cartella cifrata?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Annulla" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Conferma la password." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "La password non corrisponde." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Crea istantanea" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Impossibile smontare {mountprocess} da {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} non trovato. Si prega di installarlo (usando ad es. " "{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Il punto di montaggio {mntpoint} non è vuoto." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Inserire la password per il profilo {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FALLITO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Ripristina permessi" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Fatto" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Backup posticipato durante funzionamento a batteria" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Impossibile trovare la cartella delle istantanee." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Se è su un disco rimovibile, collegalo." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Aspettando %s secondo." msgstr[1] "Aspettando %s secondi." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Creazione dell'istantanea {snapshot_id} fallita." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Un po' di pazienza. Si sta terminando…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Impossibile creare la cartella." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Salvataggio file di configurazione…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Salvataggio permessi…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Trovato lo snapshot {snapshot_id} rimanente che può essere continuato." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Rimozione della cartella {snapshot_id} rimanente dall'ultima esecuzione" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Impossibile rimuovere la cartella" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Generazione dell'istantanea" #: common/snapshots.py:1430 msgid "Success" msgstr "Successo" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Trasferimento parziale a causa di un errore" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Trasferimento parziale perché i file di origine sono spariti (vedi 'man " "rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' terminato con codice di uscita {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Vedi 'man rsync' per ulteriori dettagli" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "I codici di ritorno negativi di rsync sono numeri di segnale, vedi 'kill -l'" " e 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nulla è cambiato, nessuna nuova istantanea necessaria" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Non posso rinominare {new_path} in {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Rimozione intelligente" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Applica le regole per rimuovere le vecchie istantanee" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Applica la politica di conservazione" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Tentativo di mantenere lo spazio libero minimo" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Tentativo di mantenere almeno il {perc} di inode liberi" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Adesso" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Impossibile montare {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent non trovato. Accertati che sia installato." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Non ho potuto sbloccare la chiave privata ssh. Password errata o non " "disponibile per cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cifratura {cipher} fallita per {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Il percorso remoto esiste ma non è una cartella." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Il percorso remoto non è scrivibile." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Il percorso remoto non è eseguibile." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Non ho potuto creare il percorso remoto." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "L'host remoto {host} non supporta {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Guarda 'man backintime' per ulteriori istruzioni" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Il controllo dei comandi sull'host {host} ha restituito un errore " "sconosciuto" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "L'host remoto {host} non supporta gli hard link" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copia la chiave ssh pubblica \"{pubkey}\" sull'host remoto \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Inserire la password per \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Il filesystem di destinazione per '{path}' è formattato con NTFS, che ha " "delle incompatibilità note con i filesystem derivati da Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} non è una cartella valida." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "La creazione della seguente cartella non è riuscita:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "L'accesso in scrittura potrebbe essere limitato." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Il filesystem di destinazione per '{path}' è formattato con FAT che non " "supporta hard link. Utilizza un filesystem GNU/Linux nativo." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Il filesystem di destinazione per {path} è una condivisione montata tramite " "SMB. Assicurati che il server SMB remoto supporti i collegamenti simbolici o" " attiva \"{copyLinks}\" in \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copia collegamenti (segue i collegamenti simbolici)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opzioni per esperti" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Il filesystem di destinazione per {path} è una condivisione montata tramite " "sshfs. Sshfs non supporta gli hard link. Utilizza invece la modalità " "\"SSH\"." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "La creazione del file in questa cartella non è riuscita:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Informazioni" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autori" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traduzioni" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenza" #: qt/app.py:172 msgid "Shortcuts" msgstr "Collegamenti" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Questa cartella non esiste\n" "nell'istantanea attualmente selezionata." #: qt/app.py:257 msgid "Add to Include" msgstr "Aggiungi alle inclusioni" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Aggiungi alle esclusioni" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} sembra essere stato avviato per la prima volta in quanto non è " "stata trovata una configurazione." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Vuoi importare una configurazione esistente (da una cartella di destinazione" " del backup o da un altro computer)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Se si trova su un disco rimovibile, collegarlo e premere OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Crea un'istantanea" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Usa la dimensione e l'ora di modifica dei file per riconoscere i file " "cambiati." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Crea un'istantanea (usando i checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Usa il checksum per rilevare i cambiamenti." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Metti in pausa il processo di istantanea" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Riprendi il processo di istantanea" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Interrompi il processo di istantanea" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Aggiorna lista istantanee" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nome Istantanea" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Rimuovi istantanea" #: qt/app.py:505 msgid "View snapshot log" msgstr "Visualizza registro istantanea" #: qt/app.py:509 msgid "View last log" msgstr "Visualizza ultimo registro" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gestione profili…" #: qt/app.py:517 msgid "Shutdown" msgstr "Spegnimento" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Arresta il sistema quando l'istantanea è terminata." #: qt/app.py:521 msgid "Setup language…" msgstr "Imposta lingua…" #: qt/app.py:525 msgid "Exit" msgstr "Esci" #: qt/app.py:529 msgid "User manual" msgstr "Manuale utente" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Apri il manuale utente nel browser (locale se disponibile, altrimenti in " "linea)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "pagina del manuale: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Visualizza la pagina di manuale di Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "pagina del manuale: file di configurazione dei profili" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Visualizza la pagina di manuale relativa al file di configurazione dei " "profili (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Sito web del progetto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Apri il sito web di Back In Time nel browser" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Registro dei cambiamenti" #: qt/app.py:555 msgid "FAQ" msgstr "Domande frequenti" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Apri le domande frequenti (FAQ) nel browser" #: qt/app.py:559 msgid "Ask a question" msgstr "Fai una domanda" #: qt/app.py:563 msgid "Report a bug" msgstr "Segnala un bug" #: qt/app.py:566 msgid "Translation" msgstr "Traduzione" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Mostra nuovamente il messaggio sulla partecipazione alla traduzione." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transizione della cifratura (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Mostra nuovamente il messaggio sulla rimozione della cifratura EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Ripristina" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Ripristina i file o le cartelle selezionati nella destinazione originale." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Ripristina su…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" "Ripristina i file o le cartelle selezionati in una nuova destinazione." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Ripristina la cartella attualmente mostrata e tutto il suo contenuto nella " "destinazione originale." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Ripristina la cartella attualmente mostrata e tutto il suo contenuto in una " "nuova destinazione." #: qt/app.py:601 msgid "Up" msgstr "Su" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Mostra i file nascosti" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Confronta istantanee…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Release Candidate" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" "Mostra nuovamente il messaggio su questa versione candidata al rilascio." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Ripristina" #: qt/app.py:698 msgid "&Help" msgstr "&Aiuto" #: qt/app.py:743 msgid "Icons only" msgstr "Solo le icone" #: qt/app.py:746 msgid "Text only" msgstr "Solo il testo" #: qt/app.py:749 msgid "Text below icons" msgstr "Testo sotto le icone" #: qt/app.py:752 msgid "Text beside icon" msgstr "Testo accanto alle icone" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Se chiudi questa finestra Back In Time non sarà in grado di arrestare il " "sistema al termine dell'istantanea." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Vuoi veramente chiuderla?" #: qt/app.py:1072 msgid "Working:" msgstr "Lavoro in corso:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Fatto, nessun backup necessario" #: qt/app.py:1129 msgid "Working" msgstr "Lavoro in corso" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Errore" #: qt/app.py:1161 msgid "Sent" msgstr "Inviati" #: qt/app.py:1162 msgid "Speed" msgstr "Velocità" #: qt/app.py:1163 msgid "ETA" msgstr "Tempo rimanente stimato" #: qt/app.py:1225 msgid "Global" msgstr "Globale" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Home" #: qt/app.py:1255 msgid "Backup directories" msgstr "Cartelle di backup" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nome istantanea" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Sei sicuro di voler rimuovere questa istantanea?" msgstr[1] "Sei sicuro di voler rimuovere queste istantanee?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Crea copie di backup aggiungendo {suffix}\n" "prima di sovrascrivere o rimuovere elementi locali." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Le nuove versioni dei file saranno rinominate con il suffisso {suffix} prima" " del ripristino. Se non ne hai più bisogno, puoi rimuoverle con il comando " "seguente:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Ripristina solo gli elementi che non esistono o\n" "sono più recenti di quelli di destinazione.\n" "Utilizza l'opzione \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Rimuovi gli elementi più recenti nella cartella originale." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Ripristina i file o le cartelle selezionati nella destinazione originale ed " "elimina i file e le cartelle che non sono nell'istantanea. Fai molta " "attenzione perché questo eliminerà i file e le cartelle che sono stati " "esclusi durante l'acquisizione dell'istantanea." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Vuoi veramente ripristinare questo elemento nella nuova cartella?" msgstr[1] "Vuoi veramente ripristinare questi elementi nella nuova cartella?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Vuoi veramente ripristinare questo elemento?" msgstr[1] "Vuoi veramente ripristinare questi elementi?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Sei sicuro di voler rimuovere tutti i file più recenti in '{path}'?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Sei sicuro di voler rimuovere tutti i file più recenti nella tua cartella " "originale?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Attenzione{BOLDEND}: Cancellare i file nella radice del filesystem " "potrebbe danneggiare l'intero sistema." #: qt/app.py:1857 msgid "Snapshot" msgstr "Istantanea" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Ripristina {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Ripristina {path} su…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Ciao\n" "Hai usato Back In Time in lingua {language} un po' di volte.\n" "La traduzione della versione di Back In Time installata in {language} è completa al {perc}. Indipendentemente dal tuo livello tecnico, puoi contribuire alla traduzione e migliorare così Back In Time.\n" "Visita {translation_platform_url} per contribuire. Per avere altre informazioni, puoi visitare {back_in_time_project_website}.\n" "Ci scusiamo per l'interruzione, questo messaggio non sarà mostrato nuovamente, ma rimane disponibile per consultazione nel menu Aiuto.\n" "La squadra di Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "piattaforma di traduzione" #: qt/app.py:2076 msgid "Website" msgstr "Sito web" #: qt/app.py:2090 msgid "Your translation" msgstr "La tua traduzione" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Nel Fediverso su Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email a {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Mailing list {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} sul sito web del progetto." #: qt/app.py:2118 msgid "Open an issue" msgstr "Apri una segnalazione" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "In alternativa, puoi usare un altro canale a tua scelta." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Questa versione di Back In Time è una Release Candidate ed è principalmente destinata ai test di stabilità in preparazione della prossima versione ufficiale.\n" "Non vengono raccolti dati utente o telemetria. Tuttavia, la squadra di Back In Time è molto interessata a sapere se la Release Candidate è in uso e se vale la pena continuare a fornire tali versioni pre-rilascio.\n" "Pertanto, la squadra chiede gentilmente un breve riscontro sul fatto che tu abbia testato questa versione, anche se non hai sperimentato alcun problema. Anche un rapido test di pochi minuti ci aiuterebbe molto.\n" "Sono disponibili le seguenti opzioni di contatto:\n" "{contact_list}\n" "In questa versione, questo messaggio non sarà più visualizzato, ma è possibile accedervi in qualsiasi momento tramite il menu di aiuto.\n" "Grazie per il tuo supporto e per averci aiutato a migliorare Back In Time!\n" "La tua squadra di Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Le impostazioni della lingua avranno effetto solo dopo aver riavviato Back " "In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "La creazione del profilo EncFS sarà rimossa nella prossima versione minore " "(1.7), pianificata per il 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Si sconsiglia di usare ulteriormente questa modalità per un profilo." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "documento" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "Supporto per EncFS è stato interrotto a causa di vulnerabilità di sicurezza." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Per ulteriori dettagli, incluse le potenziali alternative, fai riferimento a" " questo {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "I seguenti profili usano la cifratura con EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "una sostituzione è pianificata, ma non possiamo garantire che arrivi in " "tempo." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Gli utenti sono invitati a partecipare alla discussione. I dettagli " "aggiornati sui prossimi passi sono disponibili in questo {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Questo messaggio non sarà più visualizzato. Questa finestra di dialogo è " "visualizzabile in ogni momento tramite il menù di aiuto." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Il tuo team Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Imposta lingua" #: qt/languagedialog.py:97 msgid "System default" msgstr "Default del sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Usa la lingua del sistema operativo." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Tradotto: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Visualizzazione Ultimo Registro" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visualizza il registro dell'istantanea" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profilo:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Istantanee:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtro:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tutti" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Cambiamenti" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Errori" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informazione" msgstr[1] "Informazioni" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "errori trasferimento rsync (sperimentale)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Errore, [I] Informazione, [C] Cambiamento" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "decodifica i percorsi" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gestione profili" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Modifica" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Aggiungi" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Rimuovi" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Generale" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Includi" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Includi file e cartelle" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Aggiungi file" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Aggiungi cartella" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Escludi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: nella modalità 'SSH cifrato' funzionano solo gli " "asterischi singoli e doppi (es. {example2}). Gli altri tipi di caratteri " "jolly e pattern saranno ignorati (es. {example1}). In questa modalità i nomi" " di file non sono prevedibili a causa della cifratura di EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Escludi pattern, file o cartelle" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Aggiungi predefiniti" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Escludi file più grandi di:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Escludi file più grandi del valore in {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Se la 'Modalità rsync completo' è disabilitata, questo avrà effetto solo sui" " nuovi file, perché rsync la tratta come un'opzione di trasferimento, non di" " esclusione. Per questo motivo i file già sottoposti a backup in precedenza " "rimarranno nelle istantanee anche se sono stati modificati." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Rimozione e conservazione" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opzioni" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Op&zioni per esperti" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Ripristina configurazione" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Modifica callback utente" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nuovo profilo" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Rinomina profilo" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Sei sicuro di voler eliminare il profilo \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Fortemente raccomandato{ENDBOLD}: (Tutte le raccomandazioni già " "incluse.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Fortemente raccomandato{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Pattern di esclusione" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Escludi file" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Escludi cartella" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Includi file" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" è un link simbolico. La destinazione del link non sarà copiata nel backup se non la includerai esplicitamente.\n" "Vuoi piuttosto includere la destinazione del link simbolico?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Includi cartella" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Disabilitato perché questo pattern non è funzionante in modalità 'SSH " "cifrato'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Pianificazione" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Giorno:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Giorno della settimana:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tempo:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Ore:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "dopo l'ora" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuti:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Avvia Back In Time non appena il dispositivo viene collegato (solo una volta" " ogni X giorni). Ti verrà richiesta la password di sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Avvia Back In Time ripetutamente. È utile se il computer non viene avviato " "regolarmente." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Ogni:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Abilita registrazione dei messaggi di debug" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Scrive i messaggi di debug nel registro di sistema tramite \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Attenzione: da usare solo temporaneamente per diagnostica, in quanto genera " "una grande quantità di messaggi." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Disabilitato" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Ad ogni avvio/riavvio" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Ogni minuto" msgstr[1] "Ogni {n} minuti" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Ogni ora" msgstr[1] "Ogni {n} ore" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Ogni {n} ora" msgstr[1] "Ogni {n} ore" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Orario personalizzato" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Ogni giorno" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Ripetutamente (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Quando il drive viene connesso (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Ogni settimana" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Ogni mese" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Ogni anno" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Ora(e)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Giorno(i)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Settimana(e)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mese(i)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "L'orario personalizzato può essere solo un elenco di ore separate da virgola" " (es. 8,12,18,23) oppure */3 per backup periodici ogni 3 ore." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Porta:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Utente:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Connetti all'host destinazione attraverso questo proxy (conosciuto anche " "come jump host). Per i dettagli, consulta \"-J\" nella documentazione del " "comando \"ssh\" o \"ProxyJump\" nella pagina del manuale." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Attenzione:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Queste opzioni sono pensate per le configurazioni avanzate. Modificale solo " "sei pienamente consapevole delle loro implicazioni." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Esegui 'rsync' con '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "come cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "sull'host remoto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "quando si crea un'istantanea manuale" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Installa 'nocache' per abilitare questa opzione." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "sulla macchina locale" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirigi stdout verso /dev/null nei cronjob." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron invierà automaticamente una email con allegato il registro dei cronjob " "se un MTA è installato." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirigi stderr verso /dev/null nei cronjob." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron invierà automaticamente una email con allegato il registro errori dei " "cronjob se un MTA è installato." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limita la banda utilizzata da rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preserva ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preserva attributi estesi (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Copia collegamenti non sicuri (funziona solo con collegamenti assoluti)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Limita a un file system" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Le opzioni devono essere racchiuse tra virgolette, es. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Passa opzioni aggiuntive a rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefisso da eseguire prima di ciascun comando sull'host remoto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Le variabili necessitano di escaping con \\$FOO. Questo non riguarda rsync. " "Quindi per aggiungere un prefisso per rsync usa \"{example_value}\" con " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "default" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Aggiungi prefisso ai comandi SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Controlla se l'host remoto è online" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Attenzione: se disabilitato e l'host remoto non è disponibile, questo " "potrebbe portare ad alcuni errori strani." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Controlla se l'host remoto supporta tutti i comandi necessari." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Attenzione: se disabilitato e l'host remoto non supporta tutti i comandi " "necessari, questo potrebbe portare ad alcuni strani errori." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(predefinito: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "disabilitato" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "abilitato" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modalità:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Dove salvare le istantanee" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Impostazioni di SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Percorso:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifratura:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Chiave privata:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Seleziona un file di chiave privata esistente (di solito chiamato " "\"id_ed25519\" e nelle vecchie installazioni \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Crea una nuova chiave SSH senza password (non permesso se è già stato " "selezionato un file di chiave privata)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Password" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Salva la password nel gestore delle password" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Salva la password per Cron (problema di sicurezza: l'utente root può leggere" " la password)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avanzate" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Percorso completo per le istantanee:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Non hai scelto un file di chiave privata per SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Vorresti generare una nuova coppia di chiavi pubblica/privata senza " "password?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Il file chiave privata \"{file}\" non esiste." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Vuoi copiare la tua chiave SSH pubblica sull'host remoto per abilitare il " "login senza password?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "L'autenticità dell'host \"{host}\" non può essere stabilita." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "L'impronta digitale della chiave {keytype} è:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Si prega di verificare questa impronta digitale. Vorresti aggiungerla al tuo" " file 'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Sei sicuro di voler cambiare la cartella delle istantanee?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Impossibile creare una nuova chiave SSH in {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Attiva le notifiche" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Disabilita le istantanee quando usi la batteria" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Impossibile stabilire la modalità di alimentazione" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Esegui solo un'istantanea alla volta" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Le altre istantanee saranno bloccate finché l'istantanea attuale non sarà " "completata. Questa è un'opzione globale, pertanto avrà effetto su tutti i " "profili di questo utente. Tuttavia devi attivare quest'opzione anche per gli" " altri utenti." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Esegui il backup dei file sostituiti durante il ripristino" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Le nuove versioni dei file saranno rinominate con il suffisso {suffix} prima" " del ripristino. Se non ne hai più bisogno, puoi rimuoverle con {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continua in caso di errore (mantiene un'istantanea incompleta)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Usa il checksum per riconoscere i cambiamenti" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" "Crea un'istantanea anche se non ci sono modifiche rispetto alla precedente." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Livello di log:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nulla" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Le regole seguenti sono elaborate dall'alto in basso. Le regole successive " "scavalcano le regole precedenti e non sono vincolate da esse. Vedi il " "{manual} per dettagli ed esempi." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manuale utente" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Apri il manuale utente nel browser." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Mantieni l'istantanea più recente." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "L'ultima o la più recente istantanea è mantenuta in ogni caso." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Il comportamento non può essere modificato." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Mantieni le istantanee con un nome." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Le istantanee che, in aggiunta alla consueta marca temporale, hanno ricevuto" " un nome saranno mantenute in ogni caso e non saranno rimosse." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Anno(i)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Rimuovi le istantanee più vecchie di" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Giorni interi. Il giorno attuale è ignorato." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Settimane di calendario con lunedì come primo giorno. La settimana attuale è" " ignorata." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Periodi di 12 mesi. Il mese attuale è ignorato." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Politica di conservazione" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Esegui in sottofondo sull'host remoto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "La procedura di rimozione intelligente sarà eseguita direttamente nella " "macchina remota, non localmente. I comandi \"bash\", \"screen\" e \"flock\" " "devono essere installati e disponibili sulla macchina remota." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Se selezionato, Back In Time effettuerà innanzi tutto un test della macchina" " remota." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "I giorni sono contati a partire da oggi." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Mantieni tutte le istantanee degli ultimi" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "giorno/i." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Mantieni l'ultima istantanea al giorno per gli ultimi" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Le settimane sono contate a partire dalla settimana attuale in corso. Una " "settimana inizia il lunedì." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Mantieni l'ultima istantanea per ogni settimana per le ultime" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "settimana/e." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "I mesi sono contati come mesi di calendario a partire dal mese attuale." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Mantieni l'ultima istantanea per ogni mese per gli ultimi" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mese/i." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" "Gli anni sono contati come anni di calendario a partire dall'anno attuale." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Mantieni l'ultima istantanea per ogni anno per" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "tutti gli anni." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… lo spazio libero è inferiore a" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… gli inode liberi sono inferiori a" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Rimuovi le vecchie istantanee se…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Domanda" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profilo: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Visualizza ultimo log" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Avvia {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Lavoro in corso…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Inviati:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocità:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Istantanee" #: qt/qttools.py:506 msgid "Today" msgstr "Oggi" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ieri" #: qt/qttools.py:522 msgid "This week" msgstr "Questa settimana" #: qt/qttools.py:529 msgid "Last week" msgstr "Scorsa settimana" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Questa NON è un'istantanea, bensì una vista attuale dei tuoi file locali" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Ultimo controllo {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importa configurazione" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Configurazione non trovata" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importa" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Seleziona la cartella delle istantanee da cui importare la configurazione. " "Il percorso potrebbe somigliare a: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Se la cartella si trova su un disco esterno o remoto, deve essere prima " "montato manualmente." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Mostra il registro completo" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opzioni relative al confronto tra istantanee" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Usa %1 e %2 come parametri del percorso" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Si prega di impostare un comando diff o premere Annulla." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Il comando \"{cmd}\" non è stato trovato nel sistema. Si prega di provarne " "un altro o premere Annulla." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nessun parametro impostato per il comando diff. Uso il valore predefinito " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Solo istantanee diverse" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Mostra solo istantanee uguali a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Controllo approfondito (più accurato ma più lento)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Elimina" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Seleziona tutte" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Confronta" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Vai a" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opzioni" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Non è possibile confrontare un'istantanea con se stessa." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Vuoi veramente cancellare \"{file}\" nell'istantanea \"{snapshot_id}\"?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Vuoi veramente cancellare \"{file}\" in {count} istantanee?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ATTENZIONE: Questa operazione è irreversibile." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Escludere \"{path}\" dalle istantanee future?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Le sotto-cartelle non possono essere incluse nel backup." backintime-1.5.4/common/po/ja.po000066400000000000000000002105701477034762000165060ustar00rootroot00000000000000# Japanese translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-22 07:06+0000\n" "Last-Translator: sybahd \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "警告" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "メインプロファイル" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "ローカル (EncFS暗号化)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS暗号化)" #: common/config.py:278 msgid "Local" msgstr "ローカル" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH 秘密鍵" #: common/config.py:283 msgid "Local encrypted" msgstr "ローカル暗号化" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "暗号" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH暗号化" #: common/config.py:296 msgid "Default" msgstr "標準設定" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "プロファイル: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "スナップショットフォルダが無効です。" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "最低でも一個のディレクトリをバックアップのために指定してください。" #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "ディレクトリ: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "このディレクトリはバックアップ先の一部であるため、バックアップに含めることはできません。" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "新しい crontab の書き込みに失敗しました。" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron が稼働していないため crontab コマンドが使えません。 したがってバックアップは行われません。 Cron " "はインストールされているようですが、サービスとして起動されてない可能性があります。 \"systemctl enable cron\" " "を使って起動してみてください、また、 GNU/Linux ディストーションへサポートを依頼するのもよいでしょう。" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "プロファイル {profile_id} の Udev ルールをインストールできませんでした。 DBus サービス 「{dbus_interface}」 " "が有効ではありません" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "{mode} モード では、udev スケジュールは使用できません" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "{path} には該当の UUID がありませんでした" #: common/configfile.py:101 msgid "Failed to save config" msgstr "設定を保存できませんでした" #: common/configfile.py:137 msgid "Failed to load config" msgstr "設定を読み込めませんでした" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "プロファイル \"{name}\" はすでに存在しています。" #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "最後に残ったプロファイルを削除することはできません。" #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "{command} をマウントできません" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "フォルダの暗号化に関する設定がみつかりません。" #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "新しい暗号化されたフォルダを作成しますか?" #: common/encfstools.py:146 msgid "Cancel" msgstr "取消" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "パスワードを確認してください。" #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "パスワードが一致しません。" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "スナップショット取得" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "{mountprocess} を {mountpoint} からアンマウントできません。" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command} は見つかりません。例を参考にインストールしてください。例\"{installcommand}\"" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "マウントポイント {mntpoint} が空ではありません。" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "{mode}プロファイル \"{profile}\" のパスワードを入力してください:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "失敗" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "パーミッションを復元" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "完了" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "バッテリー動作のときは延期する" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "スナップショットフォルダが見つかりません。" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "もしリムーバブルドライブ上にあるのなら、それを接続してからOKを押してください。" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "%s 秒待機中。" #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "スナップショット {snapshot_id} の取得に失敗しました。" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "最終処理を行っています、少々お持ちください…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "フォルダを作成できません。" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "設定ファイルの保存…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "パーミッションを保存…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "以前に作成した継続使用できるスナップショット {snapshot_id} がありました。" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "前回の作業で作成した {snapshot_id} フォルダを削除しています" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "フォルダを削除できません" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "スナップショットの取得" #: common/snapshots.py:1430 msgid "Success" msgstr "成功" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "エラーによる部分的な転送" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "ソースファイルの消失による部分的な転送 (man rsync を参照)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' は終了コード {exit_code} で終了しました" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "詳細は'man rsync'を参照" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "ネガティブの rsync 終了コードはシグナル番号です、'kill -l' および 'man kill' を参照してください" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "変更箇所がないので新しいスナップショットは必要ありません" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "{path} を {new_path} に変更できません。" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "おまかせ削除" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "古いスナップショットにルールを適用" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "保持期間条件を適用する" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "最小限のフリースペースの確保を試みる" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "最低限でも{perc}分のフリーなinodeを確保中です" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "現在" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs} をマウントできません" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agentが見つかりません。インストールされているか確認してください。" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "ssh の秘密鍵を解除できませんでした。パスワードが間違っているか、cron で使用できないパスワードです。" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "暗号アルゴリズム {cipher} は {host} で失敗しました。" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "リモートパスは存在するが、ディレクトリではない。" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "リモートパスは書き込みできません。" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "リモートパスは実行可能ではありません。" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "フォルダを作成できません。" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "リモートホスト {host} は {command} をサポートしていない" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "詳しくは 'man backintime' を参照してください" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "ホスト {host} のコマンド群をチェックしたところ、不明なエラーを返しました" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "リモートホスト {host} がハードリンクをサポートしていません" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "公開鍵 \"{pubkey}\" をリモートホスト \"{host}\" にコピーしてください。" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "ユーザ \"{user}\" のパスワードを入力してください。" #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "{path} の保存先ファイルシステムは NTFS でフォーマットされていて、これはUnix-" "styleのファイルシステムと非互換であることが知られています。" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} は有効なディレクトリではありません。" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "以下のディレクトリの作成に失敗しました:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "書き込み権限が限定されているようです。" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "{path} の保存先ファイルシステムは、ハードリンクをサポートしない FAT でフォーマットされています。ネイティブの GNU/Linux " "ファイルシステムを使用してください。" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "{path} の保存先ファイルシステム は SMB マウントされた共有です。 " "リモートSMBサーバーがシンボリックリンクをサポートしているか確認してください、または {expertOptions} で {copyLinks} " "を有効化してください。" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "リンクをコピーする(シンボリックリンクの参照解除)" #: common/tools.py:504 msgid "Expert Options" msgstr "上級者向けオプション" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "{path} の保存先ファイルシステムは sshfs の共有マウントです。 sshfs はハードリンクをサポートしていません 。代わりにモード " "'SSH' を使用してください。" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "以下のディレクトリへのファイル作成が失敗しました:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "バージョン情報" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "開発者" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "翻訳" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "ライセンス" #: qt/app.py:172 msgid "Shortcuts" msgstr "ショートカット" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "現在選択されているスナップショットには\n" "このフォルダはありません。" #: qt/app.py:257 msgid "Add to Include" msgstr "含むフォルダを指定" #: qt/app.py:259 msgid "Add to Exclude" msgstr "除外するフォルダを指定" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "{app_name} は今回始めて起動されたため、設定ファイルがみつかりません。" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "すでに存在する設定ファイルを流用しますか (バックアップ先や他のコンピュータから)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "もしファイルがリムーバブルドライブ上にあるのなら、それを接続してからOKを押してください。" #: qt/app.py:470 msgid "Take a snapshot" msgstr "スナップショットの取得" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "ファイルの変更検出には、変更時間とサイズを使用します。" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "スナップショット取得(チェックサムモード)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "変更の検出にチェックサムを使用する。" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "スナップショットの作成を一時停止する" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "スナップショットの作成を再開する" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "スナップショットの作成を停止する" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "スナップショットリストの更新" #: qt/app.py:497 msgid "Name snapshot" msgstr "スナップショットに名前をつける" #: qt/app.py:501 msgid "Remove snapshot" msgstr "スナップショットの削除" #: qt/app.py:505 msgid "View snapshot log" msgstr "スナップショットログの表示" #: qt/app.py:509 msgid "View last log" msgstr "最近のログを表示" #: qt/app.py:513 msgid "Manage profiles…" msgstr "プロファイルの管理…" #: qt/app.py:517 msgid "Shutdown" msgstr "電源を切る" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "スナップショットの作成終了後に電源を切る。" #: qt/app.py:521 msgid "Setup language…" msgstr "言語設定…" #: qt/app.py:525 msgid "Exit" msgstr "終了" #: qt/app.py:529 msgid "User manual" msgstr "ユーザーマニュアル" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "ブラウザでユーザーマニュアルを開く (ローカルになければオンラインで)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man ページ: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Back In Time (backintime)の man ページを表示する" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man ページ: 設定ファイルのプロファイル" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "設定ファイル (backintime-config) のプロファイルに関する man ページを表示する" #: qt/app.py:547 msgid "Project website" msgstr "開発元サイト" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Back In Time の開発サイトをブラウザで開く" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "変更履歴" #: qt/app.py:555 msgid "FAQ" msgstr "よくある質問" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "よくある質問 (FAQ) をブラウザで開く" #: qt/app.py:559 msgid "Ask a question" msgstr "質問する" #: qt/app.py:563 msgid "Report a bug" msgstr "バグを報告する" #: qt/app.py:566 msgid "Translation" msgstr "翻訳" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "翻訳への参加に関するメッセージを再度表示。" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "暗号化の移行 (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "EncFS 削除に関するメッセージを再度表示。" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "復元" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "選択されたファイルやフォルダを元の場所に復元。" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "復元…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "選択されたファイルやフォルダを新しい場所に復元。" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "現在表示されているフォルダとそれに含まれるファイルを元の場所に復元。" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "現在表示されているフォルダとそれに含まれるファイルを新しい場所に復元。" #: qt/app.py:601 msgid "Up" msgstr "上のフォルダへ" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "不可視ファイルを表示" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "スナップショットを比較…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "リリース候補版" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "リリース候補版についてのメッセージを再度表示。" #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "バックアップ(&B)" #: qt/app.py:692 msgid "&Restore" msgstr "復元(&R)" #: qt/app.py:698 msgid "&Help" msgstr "ヘルプ(&H)" #: qt/app.py:743 msgid "Icons only" msgstr "アイコンのみ" #: qt/app.py:746 msgid "Text only" msgstr "テキストのみ" #: qt/app.py:749 msgid "Text below icons" msgstr "テキストをアイコンの下に" #: qt/app.py:752 msgid "Text beside icon" msgstr "テキストをアイコンの横に" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "このウインドウを閉じると Back In Time はスナップショットの作成終了時に電源を切ることができなくなります。" #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "本当に閉じますか?" #: qt/app.py:1072 msgid "Working:" msgstr "作業中:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "完了、バックアップの必要はありませんでした" #: qt/app.py:1129 msgid "Working" msgstr "作業中" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "エラー" #: qt/app.py:1161 msgid "Sent" msgstr "送信済" #: qt/app.py:1162 msgid "Speed" msgstr "速度" #: qt/app.py:1163 msgid "ETA" msgstr "予定完了時間" #: qt/app.py:1225 msgid "Global" msgstr "全体" #: qt/app.py:1226 msgid "Root" msgstr "ルート" #: qt/app.py:1227 msgid "Home" msgstr "ホーム" #: qt/app.py:1255 msgid "Backup directories" msgstr "バックアップ元のフォルダ" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "スナップショット名" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "スナップショットを削除してもよろしいですか?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "ローカルファイルを上書きまたは削除する前に\n" "末尾に {suffix} を付けたバックアップコピーを作成する。" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "復元をする際に、より新しいファイルがある場合は拡張子 {suffix} がファイル名に付与されます。もし不要の場合は以下のコマンドで削除してください :" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "ファイルが存在しないか\n" "より新しい場合にのみ復元します。\n" "\"rsync --update\" のオプションを使用します。" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "元のフォルダ内の新しいファイルを削除する。" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "選択したファイルやディレクトリを元の保存先に復元し " "スナップショットに含まれないファイルやフォルダを削除します。これによってスナップショット作成時に除外されたファイルやディレクトリが " "削除されるので、十分注意してください。" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "本当に新しいディレクトリに復元しますか?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "本当にファイルを復元してよろしいですか?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "{path} にあるより新しいファイルを削除してもよろしいですか?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "元のディレクトリの『より新しいファイル』を削除してもよろしいですか?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "{BOLD}警告{BOLDEND}:ファイルシステムルートのファイルを削除すると、システム全体が壊れる可能性があります。" #: qt/app.py:1857 msgid "Snapshot" msgstr "スナップショット" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "{path} を復元" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "{path} を復元…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "こんにちは\n" "これまでに Back In Time {language} 版をご利用いただいた皆様へ。\n" "インストールいただいた Back In Time {language} 版のバージョンでは、{perc} まで翻訳が完了しています。技術的な知見の有無に関わらず、翻訳にご協力いただくことで Back In Time に貢献いただくことが可能です。\n" "ご協力いただける場合は {translation_platform_url} をご覧ください。その他のヘルプやご質問は {back_in_time_project_website} をご覧ください。\n" "突然のメッセージを失礼致しました。このメッセージは今後表示されませんが、ヘルプメニューからいつでもご覧いただけます。\n" "Back In Time チーム一同" #: qt/app.py:2071 msgid "translation platform" msgstr "翻訳プラットフォーム" #: qt/app.py:2076 msgid "Website" msgstr "ウェブサイト" #: qt/app.py:2090 msgid "Your translation" msgstr "翻訳へのご協力のお願い" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Mastodon にある Fediverse で: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email はこちら: {link_and_label}。" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "メーリングリスト {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "開発サイトに {link_and_label}。" #: qt/app.py:2118 msgid "Open an issue" msgstr "議題を伝える" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "その他に、好みのチャンネルを選択することもできます。" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "このバーションの Back In Time は公開予定版で次の公式リリースに向けて安定性のテストに使用されます。\n" "個人情報等のユーザーデータは送信されません、しかしながら、 Back In Time チームは公開予定版が使用されているかどうかや、このようなプレリリース版を提供することに意味があるのかどうか知りたいと思っています。\n" "それ故に、もし何も問題なくてもフィードバックをくださることをお願いしたいのです。 たった数分間のテストランでも十分に有益な情報となり得ます。\n" "以下は送信要領です:\n" "{contact_list}\n" "このバージョンではメッセージは再度表示されません、が、ヘルプメニューからいつでもアクセスできます。\n" "Back In Time をご愛用いただき、多大なる支援を頂いて誠に感謝申し上げます。\n" "Back In Time チーム一同" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "言語設定は、Back In Time を再起動した後に有効になります。" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "EncFS のプロファイル作成は次のマイナーリリース (1.7、2026年予定) では割愛されます。" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "そのモードのプロファイルを使用することは、なおさら推奨されなくなりました。" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "ホワイトペーパー" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS のサポートはセキュリティの脆弱性により廃止されました。" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "詳細と可能性のある代替品については、以下を参照してください {whitepaper}。" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "次のプロファイルが EncFS暗号化を使用しています:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "代替品は計画されていますが、次のリリースに間に合うかどうかは保証できません。" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "ユーザーディスカッションへの参加は歓迎です。 最新情報はこの {whitepaper} の次のステップにあります。" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "このメッセージは再度表示されません。 このダイアログはヘルプメニューからいつでもアクセスできます。" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Back In Time チームより" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "言語設定" #: qt/languagedialog.py:97 msgid "System default" msgstr "標準設定" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "オペレーティングシステムの言語を使用する。" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "翻訳済み: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "最終ログを表示" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "スナップショットログを表示" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "プロファイル:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "スナップショット:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "フィルタ:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "全て" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "変更点" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "エラー" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "情報" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync 転送の失敗 (実験的)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] エラー、 [I] インフォメーション、 [C] 変更点" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "復号先" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "プロファイルの管理" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "編集" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "追加" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "削除" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "一般(&G)" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "追加リスト(&I)" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "追加するファイルとフォルダ" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "ファイルを追加" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "フォルダを追加" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "除外リスト(&E)" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD} 情報 {ENDBOLD}: SSH 暗号化 モードでは、単一または二重のアスタリスクしか使用できません (例 {example2} )。 " "他のワイルドカードやパターンは全て無視されます (例 {example1})。 このモードでは EncFS の仕様によりファイル名は予測できません。" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "除外するファイルやフォルダのパターン" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "標準設定に追加" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "これより大きいファイルは除外する:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "({size_unit}単位で)この値よりも大きいファイルは除外する。" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "'Full rsync mode' " "が無効化されている場合、プログラムは新しく作られたファイルだけを取り扱います、これは転送オプションで除外オプションではありません。 " "したがって、以前バックアップされた大きなファイルは変更されていても適用されません。" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "削除と保持の条件(&R)" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "オプション(&O)" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "上級者向けオプション(&X)" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "設定の復元" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "ユーザーコールバックの編集" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "新規プロファイル" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "プロファイルをリネーム" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "プロファイル ”{name}” を本当に削除しますか?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}強くおすすめします{ENDBOLD}: (すべてのオススメは既に除外されています)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}強くおすすめします{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "除外するパターン" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "除外するファイル" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "除外するフォルダ" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "含めるファイル" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "{path} はシンボリックリンクです このリンクにある本体は指定しない限りバックアップされません\n" "シンボリックリンクの代わりに本体を指定しますか?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "追加するフォルダ" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "このパターンは 'SSH 暗号化' モードでは機能しないため、無効化されました。" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "スケジュール" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "日:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "曜日:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "時間:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "時間:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "毎正時後" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "分:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "ドライブが接続されたら Back In Time を実行 (ただし X日に一回)。 sudo のパスワードを求められます。" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "Back In Time を繰り返し実行する。コンピュータを定期的に起動していない場合に便利です。" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "毎:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "デバッグメッセージのログを有効化" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "デバッグレベルメッセージを \"--debug\" 経由でシステムログに書き込む。" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "注意: これは非常に大量の出力を発生させるので、臨時の診断に使用してください。" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "無効" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "起動/再起動毎に" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "{n} 分毎" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "毎{n}時間ごと" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} 時間毎" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "カスタム時間" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "毎日" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "繰り返し (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "ドライブが接続されたとき(udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "毎週" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "毎月" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "毎年" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "時間" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "日" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "週" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "カ月" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "カスタム時間には、カンマ区切りの時間リスト(例:8,12,18,23)または */3 3時間ごとの定期バックアップのみを指定できます。" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH プロキシ" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "ホスト:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "ポート:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "ユーザ:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "プロキシ経由で目的のホストに接続します (踏み台サーバとも呼ばれます)。 \"ssh\" の \"-J\" オプションまたは " "\"ssh_config\" の \"ProxyJump\" について書いてある man または解説ページをご覧ください。" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "注意:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "これらのオプションは高度な設定です。編集する際にはこれらの相関性について十分配慮してください。" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "'{cmd}' をつけて 'rsync' を実行:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "cron として実行" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "リモートホスト上で" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "手動でスナップショットを作成時" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "'nocache'をインストールしてこのオプションを有効にしてください。" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "ローカルマシン上で" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "cronジョブの標準出力を/dev/nullにリダイレクトする。" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "もし MTA がインストールされていれば、Cron は自動的に出力をメール送信します。" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "cronジョブの標準エラーを/dev/nullにリダイレクトする。" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "もし MTA がインストールされていれば、Cron は自動的にエラーをメール送信します。" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/秒" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "rsync の帯域幅使用量を制限する:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACL を保存" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "拡張属性を維持(xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "危険なリンクをコピー(絶対リンクに対してのみ動作)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "一つのファイルシステムに制限する" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "オプションは必ず引用符で囲むこと 例:{example} 。" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "rsync に追加オプションを貼り付ける" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "外部ホストでコマンドを実行する際に使う接頭辞。" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "変数はバックスラッシュでスケープ (e.g. \\$FOO) しなければなりません。rsync で使う接頭辞を追加するには " "{example_value} を {rsync_options_value} と一緒に使います。" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "標準設定" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "SSHコマンドにプレフィックスを追加する" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "リモートホストがオンラインかどうか確認する" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "警告: これを無効化するとリモートホストが利用できない場合に奇妙なエラーが出ます。" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "リモートホストが必要なコマンドをすべてサポートしているか確認する。" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "警告: これを無効にした場合、リモートホストが必要なコマンドをすべてサポートしていないと奇妙なエラーが発生する可能性があります。" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(標準設定: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "無効" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "有効" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "モード:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "スナップショットの保存場所" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH 設定" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "パス:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "暗号化方法:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "秘密鍵:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "すでにある秘密鍵を使用する (通常 \"id_rsa\"というファイル名)。" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "新しい SSH鍵をパスワードなしで作成する (すでに秘密鍵を選択済みの場合は実行できません)。" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "パスワード" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "パスワードを鍵束に保存" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "パスワードを cron に渡す (セキュリティ上の問題: 管理者にパスワードを知られます)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "上級設定" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "スナップショットのフルパス:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "SSH 用の秘密鍵ファイルを選択していません。" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "新しいパスワードなしの公開鍵/秘密鍵ペアを生成しますか?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "秘密鍵ファイル \"{file}\" は存在しません。" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "公開 SSH 鍵をリモートホストにコピーして、パスワード不要のログインを可能にしますか?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "ホスト {host} の信頼性を確立できません。" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} 鍵のフィンガープリントは:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "フィンガープリントを確認してください。’known_hosts’ ファイルに追加しますか?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "本当にスナップショットのフォルダを変更してもよろしいですか?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "{path} において新しい SSH鍵の作成に失敗しました。" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "通知を有効にする" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "バッテリ駆動の際はスナップショット取得を無効化" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "システムから電源情報が得られません" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "一度に作成するスナップショットの数をひとつに限定して実行する" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "他のスナップショット作業は現在のものが終了するまで保留されます。これはすべてのプロファイルに適用されます。逆に言えば、その条件が満たされないとこのオプションを使うことができません。" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "復元時に置換されたファイルをバックアップする" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "復元時により新しいファイルがある場合は拡張子{suffix} 付きでファイル名変更されます。もし不要の場合は以下のコマンドで削除してください : " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "エラー発生時に継続 (不完全なスナップショットを維持)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "変更の検出にチェックサムを使用" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "変更の有無に関わらず、新しいスナップショットを取得する。" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "ログレベル:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "なし" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "次のルールは上から順番に実行されます。 新しいルールが前のルールの如何に関わらず常に上書きします。 {manual} に解説と例があります。" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "ユーザーマニュアル" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "ユーザーマニュアルをブラウザで開く。" #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "最近のスナップショットを保持する。" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "最新のスナップショットはどんな状況でも保存されます。" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "そのふるまい(仕様)は変更できません。" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "名前付きスナップショットを保存する。" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "名前をつけられたスナップショットはどのような状況でも削除しない。" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "年" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "次の期間より古いスナップショットを削除する" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "今日を除く日数。" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "週は月曜に始まります。今週を除く週数です。" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "今月を除く12ヶ月毎を一年とします。" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "保存ルール" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "リモートホスト上のバックグラウンドで実行する。" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "おまかせ削除機能はリモートマシン上で直接で動作します、ローカルマシンではありません。 リモートマシンに \"bash\" \"screen\" " "\"flock\" のコマンドがインストールされていて使用可能か確認してください。" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "これをチェックすると、Back In Time は最初リモートマシンでテストを行います。" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "今日を入れた日数です。" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "すべてのスナップショットを保存する日数" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "日。" #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "日毎のスナップショットを保存する日数" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "今週を入れた週数、週のはじめは月曜です。" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "週毎のスナップショットを保存する期間" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "週間。" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "今月を含めた月数。" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "月毎のスナップショットを保存する期間" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "カ月。" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "今年を含めた年数。" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "年毎のスナップショットを保存する日数" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "全ての年。" #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "...空き容量がこの値未満:" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "...freeな inode がこの値未満:" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "このような場合に最も古いスナップショットを削除 …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "質問" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "プロファイル: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "最近のログを閲覧" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "{appname} を開始する" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "作業中…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "送信:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "速度:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "完了予想時間:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "スナップショット" #: qt/qttools.py:506 msgid "Today" msgstr "今日" #: qt/qttools.py:513 msgid "Yesterday" msgstr "昨日" #: qt/qttools.py:522 msgid "This week" msgstr "今週" #: qt/qttools.py:529 msgid "Last week" msgstr "先週" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "スナップショットではなく、ローカルファイルのライブビューです" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "最終チェック {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "設定をインポート" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "設定が見つかりません" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "インポート" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "設定ファイルがインポートされるべきスナップショットがあるフォルダを指定してください。 パスはこのように表示されるはずです:{samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "もし、ディレクトリが外部記憶やリモートマシン上にある場合は、必ず使用前に手動でマウントしてください。" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "すべてのログを見る" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "スナップショットの比較についてのオプション" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "コマンド:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "パラメータ:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "パスのパラメータに %1 と %2 を使う" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "diff コマンドをセットしてください、またはキャンセルボタンを押してください。" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "この {cmd} コマンドはシステムにありません。 別の方法を試すかキャンセルボタンを押してください。" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "diff コマンドに渡すパラメータがありません。 デフォルトの値 {params} を使用します。" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "スナップショットの差分のみ" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "等しいスナップショットだけをリストアップする:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "詳細な違いを検証 (より正確ですが遅いです)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "削除" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "全て選択" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "比較" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "移動" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "オプション" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "同一スナップショットは比較できません。" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "スナップショット {snapshot_id} の {file} を本当に削除してもよろしいですか?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "{count}個のスナップショットから {file} を本当に削除したいですか?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "警告: これを取り消すことはできません。" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "今後のスナップショットから {path} を除外しますか?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "バックアップ先をバックアップ元のサブフォルダにすることはできません。" backintime-1.5.4/common/po/ko.po000066400000000000000000002011541477034762000165230ustar00rootroot00000000000000# Korean translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 15:41+0000\n" "Last-Translator: darkcircle \n" "Language-Team: Korean \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "경고" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "메인 프로파일" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "로컬 (EncFS 암호화)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS 암호화)" #: common/config.py:278 msgid "Local" msgstr "로컬" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH 개인 키" #: common/config.py:283 msgid "Local encrypted" msgstr "로컬 암호화" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "암호화" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH 암호화" #: common/config.py:296 msgid "Default" msgstr "기본" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "프로필: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "스냅샷 폴더가 올바르지 않습니다." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "백업을 위해서는 적어도 하나의 디렉토리가 선택되어야 합니다." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "디렉터리: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "이 디렉터리는 백업 저장소 자체의 일부이므로 백업 대상에 넣어둘 수 없습니다." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "새로운 크론탭 작성에 실패했습니다." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "크론탭(crontab) 명령어가 가능하지만 크론(Cron)이 작동하지 않습니다. 스케쥴 백업이 작동하지 않을 것입니다. 크론(Cron)이" " 설치 되어있을 수도 있지만 활성화가 안되어있을 수 도 있습니다. 다음 명령어 \"systemctl enable cron\"를 시도하거나" " 당신의 GNU/Linux 배포판에 도움을 요청해보세요." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "{profile_id} 프로필에 Udev 규칙을 설치할 수 없습니다. DBus 서비스 '{dbus_interface}'을(를) 사용할 수" " 없습니다" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "udev 일정이 {mode} 모드로 동작하지 않습니다" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "{path}의 UUID를 찾을 수 없습니다" #: common/configfile.py:101 msgid "Failed to save config" msgstr "설정 저장에 실패했습니다" #: common/configfile.py:137 msgid "Failed to load config" msgstr "설정 불러오기에 실패했습니다" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "\"{name}\" 프로필이 이미 있습니다." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "마지막 프로필은 제거할 수 없습니다." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "'{command}' 명령을 마운트할 수 없습니다" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "암호화 디렉터리 설정을 찾을 수 없습니다." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "새 암호화 폴더를 만드시겠습니까?" #: common/encfstools.py:146 msgid "Cancel" msgstr "취소" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "암호를 확인하십시오." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "암호가 일치하지 않습니다." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "스냅샷 생성하기" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "{mountpoint}(에)서 {mountprocess}을(를) 마운트 해제할 수 없습니다." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "{command}을(를) 찾을 수 없습니다. {installcommand} 명령으로 설치하십시오" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "{mntpoint} 마운트 지점이 비어 있지 않습니다." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "\"{profile}\" {mode} 프로파일의 암호를 입력하십시오:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "실패" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "권한 복원" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "완료" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "배터리를 사용하는 동안 백업 연기" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "스냅샷 디렉터리를 찾을 수 없습니다." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "이동식 드라이브에 있다면 우선 연결하십시오." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "%s초 기다립니다." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "{snapshot_id} 스냅샷을 생성하지 못했습니다." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "잠시만 기다려주세요. 마무리 중…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "디렉터리를 만들 수 없습니다." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "구성 파일 저장 중…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "권한 저장 중…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "계속할 수 있는 남은 {snapshot_id} 스냅샷을 찾았습니다." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "마지막 실행에서 남은 {snapshot_id} 디렉터리 제거 중" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "디렉터리를 제거할 수 없습니다" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "스냅샷 생성" #: common/snapshots.py:1430 msgid "Success" msgstr "성공" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "오류 때문에 일부만 전송했습니다" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "사라진 소스 파일로 인한 부분 전송('man rsync' 참조)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync'가 종료 코드 {exit_code}로 종료되었습니다" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "자세한 내용은 'man rsync'를 참조하세요" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "rsync 음수 종료 코드는 시그널 번호입니다. 'kill -l' 및 'man kill'을 참조하세요" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "아무것도 변경되지 않았으며 새 스냅샷이 필요하지 않습니다" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "{new_path} 경로 이름을 {path} 경로 이름으로 바꿀 수 없습니다." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "똑똑한 제거" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "오래된 스냅샷을 제거할 규칙 적용" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "보호 정책 적용 중" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "최소 여유 공간을 유지하려고 합니다" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "최소 {perc}개의 사용 가능한 아이노드를 유지하려고 합니다" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "현재" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs}을(를) 마운트할 수 없습니다" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent가 없습니다. 설치 여부를 확인하십시오." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "SSH 개인 키를 잠금 해제할 수 없습니다. 잘못된 암호거나 cron 암호를 사용할 수 없습니다." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{host}의 {cipher} 암호화에 실패했습니다." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "원격 경로가 존재하지만 디렉터리가 아닙니다." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "원격 경로에 쓸 수 없습니다." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "원격 경로를 실행할 수 없습니다." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "원격 경로를 생성할 수 없습니다." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "원격 호스트 {host}은(는) {command}을(를) 지원하지 않습니다" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "자세한 지침은 'man backintime'을 참조하세요" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "호스트 {host}의 확인 명령이 알 수 없는 오류를 반환했습니다" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "원격 호스트 {host}은(는) 하드링크를 지원하지 않습니다" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "\"{pubkey}\" 공개 SSH 키를 \"{host}\" 원격 호스트에 복사합니다." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "\"{user}\" 암호를 입력하십시오." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "{path}의 대상 파일 시스템은 유닉스 방식 파일 시스템과 호환성이 없다고 알려진 NTFS 형식으로 초기화했습니다." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path}은(는) 적절한 디렉터리가 아닙니다." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "해당 디렉토리 생성에 실패:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "쓰기 권한이 제한되어있습니다." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "{path}의 대상 파일 시스템은 하드 링크를 지원하지 않는 FAT 형식으로 포맷했습니다. GNU/Linux 자체 파일 시스템을 " "사용하십시오." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "{path}의 대상 파일 시스템은 SMB 형식 공유 마운트입니다. 원격 SMB 서버가 심볼릭 링크를 지원하는지 확인하거나 " "\"{expertOptions}\"에서 \"{copyLinks}\"를 활성화하십시오." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "링크 복사 (심볼릭 링크 역참조)" #: common/tools.py:504 msgid "Expert Options" msgstr "전문가 설정" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "{path}의 대상 파일 시스템은 SSHFS 공유 마운트 입니다. SSHFS는 하드 링크를 지원하지 않습니다. 대신 \"SSH\" 모드를" " 사용하십시오." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "디렉토리에서 파일 생성에 실패:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "정보" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "저자" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "번역" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "라이센스" #: qt/app.py:172 msgid "Shortcuts" msgstr "바로 가기" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "현재 선택한 스냅샷에\n" "이 디렉터리가 없습니다." #: qt/app.py:257 msgid "Add to Include" msgstr "포함할 항목 추가" #: qt/app.py:259 msgid "Add to Exclude" msgstr "제외할 항목 추가" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "{app_name}을 어떤 설정 없이 처음 실행하는 것 같습니다." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "(백업 대상 디렉터리 또는 다른 컴퓨터에서) 기존 설정을 가져오시겠습니까?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "이동식 드라이브에 있는 경우 연결한 다음 확인을 누르십시오." #: qt/app.py:470 msgid "Take a snapshot" msgstr "스냅샷 생성" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "파일 변경 감지를 위해 수정 시간 및 크기를 사용합니다." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "체크섬을 포함한 스냅샷 생성하기" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "파일 변경 감지에 체크섬을 사용합니다." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "스냅샷 생성 일시 중지" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "스냅샷 생성 재시작" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "스냅샷 생성 중지" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "스냅샷 목록 새로 고침" #: qt/app.py:497 msgid "Name snapshot" msgstr "스냅샷 이름 변경" #: qt/app.py:501 msgid "Remove snapshot" msgstr "스냅샷 제거" #: qt/app.py:505 msgid "View snapshot log" msgstr "스냅샷 로그 보기" #: qt/app.py:509 msgid "View last log" msgstr "마지막 로그 보기" #: qt/app.py:513 msgid "Manage profiles…" msgstr "프로필 관리…" #: qt/app.py:517 msgid "Shutdown" msgstr "끄기" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "스냅샷이 끝난 후 시스템 종료하기." #: qt/app.py:521 msgid "Setup language…" msgstr "언어 설정…" #: qt/app.py:525 msgid "Exit" msgstr "끝내기" #: qt/app.py:529 msgid "User manual" msgstr "사용자 메뉴얼" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "사용자 메뉴얼을 브라우저에서 열기(로컬이 안되면 온라인으로)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "맨 페이지: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Back In Time (backintime) 맨 페이지를 표시합니다" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "맨 페이지: 프로필 설정 파일" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "프로파일 설정(backintime-config)에 대한 man 페이지 열기" #: qt/app.py:547 msgid "Project website" msgstr "프로젝트 사이트" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "브라우저에서 Back In Time 웹사이트 열기" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "변경 내역" #: qt/app.py:555 msgid "FAQ" msgstr "자주 묻는 질문" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "브라우저에서 자주 묻는 질문들 (FAQ) 열기" #: qt/app.py:559 msgid "Ask a question" msgstr "질문하기" #: qt/app.py:563 msgid "Report a bug" msgstr "버그 신고" #: qt/app.py:566 msgid "Translation" msgstr "번역" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "번역 참여에 대한 메세지를 다시 보기." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transition 암호화 (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "EncFS 제거에 대한 메시지를 다시 보기." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "복원" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "선택한 파일이나 디렉터리를 원래 대상으로 복원합니다." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "다음 위치에 복원 …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "선택한 파일 또는 디렉터리를 새로운 대상으로 복원합니다." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "현재 표시한 디렉터리와 해당 디렉터리의 모든 내용을 원래 대상으로 복원합니다." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "현재 나타난 디렉터리와 해당 디렉터리의 모든 내용을 새 대상으로 복원합니다." #: qt/app.py:601 msgid "Up" msgstr "위로" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "숨겨진 파일 표시" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "스냅샷 비교…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "배포 후보" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "배포 후보에 대한 메시지 다시 보기." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "백업" #: qt/app.py:692 msgid "&Restore" msgstr "복원" #: qt/app.py:698 msgid "&Help" msgstr "도움말" #: qt/app.py:743 msgid "Icons only" msgstr "아이콘만" #: qt/app.py:746 msgid "Text only" msgstr "글자만" #: qt/app.py:749 msgid "Text below icons" msgstr "아이콘 밑 글자" #: qt/app.py:752 msgid "Text beside icon" msgstr "아이콘 옆 글자" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "이 창을 닫으면 스냅샷을 마쳤을 때 Back In Time에서 시스템을 끌 수 없습니다." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "정말로 닫으시겠습니까?" #: qt/app.py:1072 msgid "Working:" msgstr "진행 중:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "완료했습니다. 백업이 필요하지 않습니다" #: qt/app.py:1129 msgid "Working" msgstr "진행 중" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "오류" #: qt/app.py:1161 msgid "Sent" msgstr "전송" #: qt/app.py:1162 msgid "Speed" msgstr "속도" #: qt/app.py:1163 msgid "ETA" msgstr "예상 소요 시간" #: qt/app.py:1225 msgid "Global" msgstr "전역" #: qt/app.py:1226 msgid "Root" msgstr "루트" #: qt/app.py:1227 msgid "Home" msgstr "홈" #: qt/app.py:1255 msgid "Backup directories" msgstr "백업 디렉터리" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "스냅샷 이름" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "정말 이 스냅샷(들)을 제거하시겠습니까?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "로컬 요소를 덮어쓰거나 제거하기 전에\n" "뒤에 오는 {suffix}를 사용하여 백업 복사본을 만듭니다." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "파일 최신 버전은 복원하기 전 {suffix}를 붙여 이름을 바꿉니다. 해당 파일이 더이상 필요하지 않으면 다음 명령으로 제거할 수 " "있습니다:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "백업 대상 위치에 없거나\n" "해당 위치보다 최신인 항목만 복원합니다.\n" "\"rsync --update\" 옵션을 사용하십시오." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "원본 디렉터리에서 최신 요소를 제거합니다." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "선택한 파일 또는 디렉터리를 원래 대상으로 복원하고 스냅샷에 없는 파일 또는 디렉터리는 삭제합니다. 스냅샷을 취할 때 제외한 파일 및 " "디렉터리도 삭제하므로 취급에 신중을 기하십시오." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "이 항목을 새 디렉터리에 복원하시겠습니까?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "정말로 이 항목을 복원하시겠습니까?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "{path}에 있는 모든 최신 파일을 제거하시겠습니까?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "정말로 원본 디렉터리에서 모든 최신 파일을 제거하시겠습니까?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "{BOLD}경고{BOLDEND}: 파일 시스템 루트에서 파일을 삭제하면 전체 시스템이 망가질 수 있습니다." #: qt/app.py:1857 msgid "Snapshot" msgstr "스냅샷" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "{path} 복원" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "{path}를 다음 위치에 복원 …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "안녕하세요\n" "지금까지 여러분은 {language} 언어로 Back In Time을 몇 번 사용해 보셨습니다.\n" "설치된 Back In Time 버전의 {language} 번역이 {perc} 가량 끝났습니다. 여러분의 기술 전문 지식 수준에 관계없이 귀하는 번역에 기여하여 Back In Time 자체에 기여할 수 있습니다.\n" "기여하고 싶다면 {translation_platform_url}를 방문하세요. 추가 지원 및 질문이 있다면 {back_in_time_project_website}를 방문하세요.\n" "불편을 끼쳐드려 죄송하며 이 메시지는 다시 표시되지 않습니다. 이 대화 상자는 도움말 메뉴를 통해 언제든지 살펴보실 수 있습니다.\n" "여러분의 Back In Time 팀" #: qt/app.py:2071 msgid "translation platform" msgstr "번역 플랫폼" #: qt/app.py:2076 msgid "Website" msgstr "웹사이트" #: qt/app.py:2090 msgid "Your translation" msgstr "귀하의 번역" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Mastodon에서 보기: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "{link_and_label}에 전자메일 보내기." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "{link_and_label} 메일링 리스트" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "프로젝트 웹사이트의 {link_and_label}." #: qt/app.py:2118 msgid "Open an issue" msgstr "문제 보고 열기" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "대신, 다른 채널을 활용하여 연락할 수 있습니다." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "이번 Back In Time 버전은 출시 후보작으로 다음 정식 출시 버전의 준비를 위한 안정화 시험이 주 목적입니다.\n" "사용자 데이터 또는 원격 데이터는 수집하지 않습니다. 그러나, Back In Time 팀에서는 출시 후보작의 사용 여부와 출시 이전 버전의 계속적 제공 가치 여부를 확인하고 싶습니다.\n" "따라서, 팀에서는 어떤 문제를 경험해보지 못했다 하더라도 이 버전의 시험 여부에 대한 간단한 고견을 듣고자 합니다. 몇 분동안의 간단한 시험 실행만으로도 저희에겐 큰 도움이 됩니다.\n" "다음과 같은 방식으로 연락할 수 있습니다:\n" "{contact_list}\n" "이 버전에서, 이 메시지는 더이상 나타나지 않지만 도움말 메뉴에서 언제든 살펴보실 수 있습니다.\n" "Back In Time 개선을 지원해주시는 여러분께 감사합니다!\n" "여러분의 Back In Time 팀" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "언어 설정은 Back In Time을 다시 시작한 후에만 적용됩니다." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "EncFS 프로파일 생성은 차기 마이너 릴리스(1.7)에서 2026년에 제거합니다." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "프로파일에서의 이 모드 사용은 더 이상 추천하지 않습니다." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "백서" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS 지원은 보안 취약성 문제로 더이상 진행하지 않습니다." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "잠재적 대안책이 담긴 더 자세한 내용은, {whitepaper}을(를) 참고하십시오." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "다음 프로파일에서 EncFS 암호화를 사용합니다:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "대체를 계획했으나, 제 시간의 처리여부는 보증할 수 없습니다." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "이 논의에 사용자를 초대합니다. 다음 단계의 업데이트 세부 사항은 {whitepaper}에 들어있습니다." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "이 메시지는 다시 나타나지 않습니다. 이 대화상자는 도움말 메뉴 항목에서 언제든 열어보실 수 있습니다." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "여러분의 Back In Time 팀" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "언어 설정" #: qt/languagedialog.py:97 msgid "System default" msgstr "시스템 기본값" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "운영 체제의 언어를 사용합니다." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "{percent} 번역됨" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "마지막 로그 보기" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "스냅샷 로그 보기" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "프로필:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "스냅샷:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "필터:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "모두" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "변경" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "오류" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "정보" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync 전송 실패 (시험용)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] 오류, [I] 정보, [C] 변경" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "경로 디코딩" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "프로필 관리" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "편집" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "추가" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "삭제" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "일반(&G)" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "포함(&I)" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "파일 및 디렉터리 포함" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "파일 추가" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "디렉터리 추가" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "제외(&E)" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}정보{ENDBOLD}: 'SSH 암호화' 모드에서, 단일, 이중 애스터리스크만 동작합니다 (예: {example2}). 다른 " "형식의 와일드카드와 패턴은 무시합니다 (예: {example1}). 이 모드에서 파일 이름은 EncFS로 암호화하기 때문에 예측할 수 " "없습니다." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "파일 또는 디렉터리 제외 패턴" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "기본값 추가" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "크기가 큰 파일 제외:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "{size_unit} 단위의 값보다 큰 파일을 제외합니다." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "'전체 rsync 모드'를 해제하면, 제외옵션이 아닌 전송 옵션이기 때문에 rsync에서 현재 파일부터 영향을 줍니다. 따라서 이미 앞서" " 백업한 파일은 수정 작업을 진행했다 하더라도 스냅샷은 그대로 남습니다." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "제거(&R) 및 보유" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "옵션(&O)" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "고급 설정" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "설정 복구" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "user-callback 편집" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "새로운 프로파일" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "프로파일명을 변경" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "정말 \"{name}\" 프로파일을 삭제하시겠습니까?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}강력 추천{ENDBOLD}: (모든 추천 항목이 이미 들어있습니다.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}강력 추천{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "제외 패턴" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "제외 파일" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "제외 디렉터리" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "파일 포함" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" 경로는 심볼릭 링크입니다. 포함하기 전까지는 백업하지 않습니다.\n" "백업에 심볼릭 링크를 추가하시겠습니까?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "디렉터리 포함" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "이 패턴은 'SSH 암호화' 모드에서 동작하지 않기 때문에 사용할 수 없습니다." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "일정" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "일:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "요일:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "시간:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "시간:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "한시간 후" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "분:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "드라이브를 연결하면 Back In Time을 실행합니다(매 X일에 한번씩). sudo 암호 입력이 필요합니다." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "반복적으로 Back In Time을 실행합니다. 컴퓨터를 비정기적으로 사용할 때 쓸만합니다." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "매:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "디버깅 메시지 기록 활성" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "디버깅 수준 메시지를 \"--debug\" 옵션으로 시스템 로그에 기록합니다." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "위험: 엄청난 양의 출력 내용을 만들어내므로 진단 목적으로 잠시 동안만 사용하십시오." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "비활성화됨" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "부팅/재부팅 할 때 마다" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "매 {n}분 마다" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "{n}시간마다" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "매 {n}시간마다" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "시간 주기 설정" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "매일" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "반복 (아나크론)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "드라이브를 연결했을 때(udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "매주" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "매월" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "매년" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "시간" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "일" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "주" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "월" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "개별 설정 시간은 쉼표로 구분한 시간 값(예: 8, 12, 18, 23)이거나 3시간당 주기 백업일 경우 */3 과 같은 형식의 " "값입니다." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH 프록시" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "호스트:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "포트:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "사용자:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "이 프록시로 대상 호스트에 연결합니다 (호스트 건너뛰기). \"ssh\" 명령 문서에서 \"-J\" 옵션 또는 \"ssh_config\"" " 설명서 페이지의 \"ProxyJump\" 옵션의 자세한 내용을 참고하십시오." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "위험:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "이 옵션은 고급 설정 항목입니다. 구현 동작을 완전히 이해할 경우에만 설정 값을 수정하십시오." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "'{cmd}' 명령으로 'rsync' 실행:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "크론 작업으로 실행" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "원격 호스트에서" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "사용자정의 스냅샷을 찍을때" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "이 옵션을 사용하려면 'nocache'를 설치하십시오." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "로컬 머신에서" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "크론 작업의 표준 출력을 /dev/null로 보냄." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "MTA를 설치했다면 크론 작업 출력 내용을 첨부한 전자메일을 크론에서 자동으로 보냅니다." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "크론 작업의 오류 출력을 /dev/null로 보냄." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "MTA를 설치했다면 크론 작업 오류 내용을 첨부한 전자메일을 크론에서 자동으로 보냅니다." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sec" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "rsync 대역폭 사용량 제한:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACL 설정값 보존" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "확장 속성 (xattr) 보존" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "불안전한 링크 복사(절대 링크인 경우만 동작)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "하나의 파일 시스템으로 제한" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "옵션은 따옴표 안에 넣어야 합니다. 예. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "rsync에 추가 옵션 넣기" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "원격 호스트의 모든 명령 앞에 붙여 실행할 접두부입니다." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "변수는 \\$FOO 처럼 이스케이핑해야 합니다. rsync를 건드리지는 않습니다. rsync 접두부를 추가하려면 " "\"{example_value}\"와(과) {rsync_options_value}을(를) 사용하십시오." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "기본값" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "SSH 명령에 접두 옵션 추가" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "원격 호스트가 접근 가능한지 확인" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "경고: 이 옵션이 꺼져있고 원격 호스트를 사용할 수 없다면 이상한 오류를 유발할 수 있습니다." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "원격 호스트에서 필요한 모든 명령을 지원하는지 확인합니다." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "경고: 이 옵션이 꺼져 있고 원격 호스트에서 필요한 모든 명령을 지원하지 않으면, 이상한 오류를 유발할 수 있습니다." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(기본값: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "비활성" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "활성" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "모드:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "스냅샷을 저장할 위치" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH 설정" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "경로:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "암호:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "개인 키:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "기존 개인 키 파일을 선택하십시오(보통 \"id_ed25519\" 파일이며, 오래된 설정에는 \"id_rsa\" 이름으로 설정함)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "암호 없는 새 SSH 키를 만듭니다(개인 키 파일을 이미 선택했을 경우 허용하지 않음)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "암호" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "키 모음에 암호 저장" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "크론 캐시 암호(보안 문제: 루트 계정에서 암호를 볼 수 있음)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "고급 설정" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "전체 스냅샷 경로:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "SSH용 개인 키를 선택하지 않았습니다." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "새 암호 없이 공용/개인키 쌍을 만드시겠습니까?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "\"{file}\" 개인키 파일이 없습니다." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "원격 호스트에 암호 없는 로그인을 사용할 공개 SSH 키를 복사하시겠습니까?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "{host} 호스트의 인증 과정을 처리할 수 없습니다." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} 키 지문:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "이 지문키를 검증하세요. 'known_hosts' 파일에 추가하시겠습니까?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "정말 스냅샷 디렉터리를 바꾸시겠습니까?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "{path}에 새 SSH 키 생성 실패." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "알림 사용하기" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "배터리 사용중에는 스냅샷을 찍을 수 없습니다" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "시스템의 전원 상태를 알 수 없습니다" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "동시에 하나의 스냅샷 동작만 수행" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "현재 스냅샷을 처리할 때까지 다른 스냅샷 처리를 차단합니다. 이 동작은 전역 옵션입니다. 이 사용자의 모든 프로파일에 영향을 줍니다. " "다만, 다른 사용자에게도 이 옵션을 설정해야합니다." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "복원시 대체 파일 백업" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "최신 버전 파일은 복원하기 전 뒤에 {suffix}를 붙인 이름으로 바뀝니다. 더 이상 필요하지 않으면 {cmd}을(를) 사용하여 제거할" " 수 있습니다" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "오류가 있어도 진행(미완 스냅샷 유지)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "체크섬을 이용해 변경사항 찾기" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "변경 사항과 관계없이 새로운 스냅샷 생성." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "로깅 수준:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "없음" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "다음 규칙을 상단에서 하단으로 순서대로 처리합니다. 이전 규칙은 나중에 다른 규칙으로 덮어쓸 수 있으며 이전 규칙에 얽매이지 않습니다. " "자세한 내용과 예제는 {manual}을(를) 살펴보십시오." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "사용자 설명서" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "브라우저에 사용자 설명서를 엽니다." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "가장 최근 스냅샷 유지." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "어떤 상황에든 최신 스냅샷을 유지합니다." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "이 동작은 바꿀 수 없습니다." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "이름이 붙은 스냅샷 유지." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "이름이 붙었거나, 타임스탬프를 매긴 스냅샷은 어떤 경우에든 유지하며 제거하지 않습니다." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "년" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "다음보다 오래된 스냅샷 제거" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "오늘을 무시한 만 경과일자." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "월요일을 달력의 주 첫날로 간주합니다. 이번 주는 무시합니다." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12월 간격. 이번 달은 무시합니다." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "유지 정책" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "원격 호스트의 백그라운드에서 실행합니다." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "똑똑한 제거 과정은 로컬이 아닌 원격 머신에서 직접 실행합니다. \"bash\", \"screen\", \"flock\" 명령을 설치하여" " 원격 머신에서 사용할 수 있어야 합니다." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "이 항목을 선택하면, Back In Time에서 원격 머신을 우선 시험합니다." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "오늘부터 날짜를 셉니다." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "모든 최신 스냅샷 유지" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "일." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "일별 최신 스냅샷을 최신 스냅샷으로 유지" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "현재 실행 주 부터 경과 주 수를 셉니다. 한 주의 시작은 월요일입니다." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "주별 최신 스냅샷을 최신 스냅샷으로 유지" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "주." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "월은 현재 월부터 달력 월을 세듯 셉니다." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "월별 최신 스냅샷을 최신 스냅샷으로 유지" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "달." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "금년부터 시작하여 달력의 연도를 세듯 연 수를 셉니다." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "각 연도별 마지막 스냅샷 유지 기간" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "매년." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… 여유 공간이 다음보다 적은 경우" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… 여유 inode 갯수가 다음보다 적은 경우" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "오래된 스냅샷 제거 조건 …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "질문" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "프로필: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "마지막 로그 보기" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "{appname} 시작" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "진행 중…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "전송:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "속도:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "남은시간:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "스냅샷" #: qt/qttools.py:506 msgid "Today" msgstr "오늘" #: qt/qttools.py:513 msgid "Yesterday" msgstr "어제" #: qt/qttools.py:522 msgid "This week" msgstr "어번 주" #: qt/qttools.py:529 msgid "Last week" msgstr "지난 주" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "이것은 스냅샷이 아니라 로컬 파일의 실시간 보기입니다" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "마지막 확인 시간 {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "설정 가져오기" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "설정 없음" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "가져오기" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "설정 파일을 가져올 스냅샷 디렉터리를 선택하십시오. 경로는 {samplePath}와(과) 같습니다" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "디렉터리가 외장 드라이브나 원격 드라이브에 있다면, 우선 직접 마운트해야 합니다." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "전체 로그 보기" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "스냅샷 비교 관련 옵션" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "명령:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "매개변수:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "경로 매개변수로 %1와(과) %2을(를) 사용" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "diff 명령을 설정하거나 취소를 누르십시오." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "\"{cmd}\" 명령을 시스템에서 찾을 수 없습니다. 다른 명령을 시도해보거나 취소를 누르십시오." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "diff 명령의 매개변수를 설정하지 않았습니다. \"{params}\" 기본 값을 사용합니다." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "스냅샷 비교만 진행" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "다음 조건에 동일한 스냅샷만 조회:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "자세히 확인(느리지만 정확함)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "삭제" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "전체 선택" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "비교" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "이동하기" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "옵션" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "스냅샷을 자신과 비교할 수 없습니다." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "정말로 {snapshot_id} 스냅샷에서 {file} 파일을 삭제하시겠습니까?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "정말로 {count}개의 스냅샷에서 {file} 파일을 삭제하시겠습니까?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "경고: 이 동작은 취소할 수 없습니다." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "앞으로의 스냅샷에서 {path} 경로를 제외하시겠습니까?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "해당 하위 폴더는 백업에 포함 될 수 없습니다." backintime-1.5.4/common/po/lt.po000066400000000000000000001641101477034762000165310ustar00rootroot00000000000000# Lithuanian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2024-07-22 12:37+0000\n" "Last-Translator: buhtz \n" "Language-Team: Lithuanian \n" "Language: lt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n" "X-Generator: Weblate 5.6.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Įspėjimas" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Pagrindinis profilis" #: common/config.py:266 #, fuzzy msgid "Local (EncFS encrypted)" msgstr "užšifruotas" #: common/config.py:267 #, fuzzy msgid "SSH (EncFS encrypted)" msgstr "Užšifruotas su SSH" #: common/config.py:278 msgid "Local" msgstr "Vietinis" #: common/config.py:280 msgid "SSH" msgstr "" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privatus raktas" #: common/config.py:283 #, fuzzy msgid "Local encrypted" msgstr "užšifruotas" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Užšifravimas" #: common/config.py:289 msgid "SSH encrypted" msgstr "Užšifruotas su SSH" #: common/config.py:296 msgid "Default" msgstr "Numatytasis" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profilis: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Momentinių kopijų aplankas negalioja!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Atstatyti {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nepavyko įrašyti naujo crontab failo." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Nepavyko įdiegti Udev taisyklės profiliui {profile_id}.DBus " "Service'{dbus_interface}', buvo nepasiekiamas" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Suplanuoti udev neveikia naudojant režimą {mode}" #: common/config.py:1582 #, fuzzy, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nepavyko rasti UUID adresui \"{path}\"" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nepavyko išsaugoti konfiguracijos" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nepavyko įkelti konfiguracijos" #: common/configfile.py:684 common/configfile.py:783 #, fuzzy, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profilis \"{name}\" jau egzistuoja." #: common/configfile.py:729 #, fuzzy msgid "The last profile cannot be removed." msgstr "Tai negali būti atšaukta." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Neįmanoma įrengti '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Konfiguracija užšifruotam aplankui nerasta." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Sukurti naują užšifruotą aplanką?" #: common/encfstools.py:146 msgid "Cancel" msgstr "" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Prašome patvirtinti slaptažodį." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Išsaugoti momentinę nuotrauką" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NEPAVYKO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Atstatyti prieigas" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Atlikta" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Atsarginės kopijos kūrimas atidedamas, kol naudojamas akumuliatorius" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Nepavyko sukurti aplanko" #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Nepavyko rasti momentinių nuotraukų aplanko.\n" "Jei jis yra keičiamame diske, prijunkite jį ir paspauskite OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Laukti %s sekundes." msgstr[1] "Laukti %s sekundžių." msgstr[2] "Laukti %s sekundžių." #: common/snapshots.py:914 #, fuzzy, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Nepavyko išsaugoti momentinės kopijos {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Nepavyko sukurti aplanko" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Išsaugomas konfigūracijos failas…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Prieigos yra išsaugomos…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Rastas likęs {snapshot_id}, kurį galima tęsti." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Šalinamas atlikęs {snapshot_id} aplankas iš praeitos operacijos" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Nepavyko pašalinti aplanko" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Padaryti momentinę nuotrauką" #: common/snapshots.py:1430 msgid "Success" msgstr "" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Niekas nepakito, įrašyti naujos momentinės kopijos neprivaloma" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Neįmanoma pervadinti {new_path} į {path}" #: common/snapshots.py:1855 #, fuzzy msgid "Smart removal" msgstr "Išmanus pašalinimas" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Senų momentinių kopijų pašalinimas" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Bandyti" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Bandoma išlaikyti mažiausiai {perc} laisvų inodų" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Dabar" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Neįmanoma įrengti {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 #, fuzzy msgid "Remote path is not executable." msgstr "„Shebang“ vartotojo atgalinio iškvietimo scenarijuje nėra vykdomas." #: common/sshtools.py:721 #, fuzzy msgid "Couldn't create remote path." msgstr "Nepavyko sukurti aplanko." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, fuzzy, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Kopijuoti viešą SSH raktą \"{pubkey}\" į nuotolinį pagrindinį kompiuterį " "\"{host}\"" #: common/sshtools.py:1193 #, fuzzy, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Prašome įvesti slaptažodį vartotojui \"{user}\"" #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Paskirties failų sistema, skirta {path}, suformatuota naudojant FAT, kuri " "nepalaiko kietųjų nuorodų. Prašome naudoti savąją Linux failų sistemą." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Paskirties failų sistema, skirta {path}, suformatuota naudojant FAT, kuri " "nepalaiko kietųjų nuorodų. Prašome naudoti savąją Linux failų sistemą." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Paskirties{path} failų sistema yra SMB resursas. Įsitikinkite, kad SMB " "serveris palaiko simbolines sąsajas, arba {expertOptions} įjunkite " "{copyLinks}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopijuoti nuorodas (atsieti simbolines nuorodas)" #: common/tools.py:504 msgid "Expert Options" msgstr "Parinktys ekspertams" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Paskirties failų sistema, skirta {path}, yra sshfs prijungta dalis. sshfs " "nepalaiko kietųjų nuorodų. Vietoj to naudokite režimą „SSH“." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Apie" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autoriai" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Vertimai" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenzija" #: qt/app.py:172 msgid "Shortcuts" msgstr "Nuorodos" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Šis aplankas neegzistuoja\n" "pasirinktoje momentinėje kopijoje." #: qt/app.py:257 msgid "Add to Include" msgstr "Pridėti prie įtraukti" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Pridėti, prie neįtraukti" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Nepavyko rasti momentinių nuotraukų aplanko.\n" "Jei jis yra keičiamame diske, prijunkite jį ir paspauskite OK." #: qt/app.py:470 #, fuzzy msgid "Take a snapshot" msgstr "Išsaugoti momentinę nuotrauką" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 #, fuzzy msgid "Take a snapshot (checksum mode)" msgstr "Išsaugoti momentinę kopiją su kontroline suma" #: qt/app.py:477 #, fuzzy msgid "Use checksums for file change detection." msgstr "Pasikeitimų aptikimui naudoti kontrolines sumas." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pristabdyti momentinės kopijos procesą" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Pratęsti momentinės kopijos procesą" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stabdyti momentinės kopijos procesą" #: qt/app.py:493 #, fuzzy msgid "Refresh snapshot list" msgstr "Atnaujinti momentinių kopijų sąrašą" #: qt/app.py:497 #, fuzzy msgid "Name snapshot" msgstr "Išsaugoti momentinę nuotrauką" #: qt/app.py:501 #, fuzzy msgid "Remove snapshot" msgstr "Pašalinti momentinę kopiją" #: qt/app.py:505 #, fuzzy msgid "View snapshot log" msgstr "Peržiūrėti momentinių kopijų žurnalą" #: qt/app.py:509 #, fuzzy msgid "View last log" msgstr "Peržiūrėti paskutinį įrašą žurnale" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Pagrindinis profilis…" #: qt/app.py:517 msgid "Shutdown" msgstr "Išjungti" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Išjungti sistemą, kai momentinė kopija baigs veikti." #: qt/app.py:521 msgid "Setup language…" msgstr "" #: qt/app.py:525 msgid "Exit" msgstr "Išeiti" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Išsaugomas konfigūracijos failas" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Pakeitimų sąrašas" #: qt/app.py:555 msgid "FAQ" msgstr "D.U.K." #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Užduokite klausimą" #: qt/app.py:563 msgid "Report a bug" msgstr "Pranešti apie klaidą" #: qt/app.py:566 #, fuzzy msgid "Translation" msgstr "Vertimai" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Atstatyti" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "" "Atkurkite pasirinktus failus arba aplankus į pradinę paskirties vietą." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 #, fuzzy msgid "Restore to …" msgstr "Atkurti į …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Atkurkite pasirinktus failus arba aplankus į naują paskirties vietą." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Atkurkite pasirinktus failus arba aplankus į originalią paskirties vietą." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Atkurkite šiuo metu rodomą aplanką ir visą jo turinį į naują paskirties " "vietą." #: qt/app.py:601 msgid "Up" msgstr "Aukštyn" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Rodyti paslėptus failus" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Išsaugoti momentinę nuotrauką…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "" #: qt/app.py:692 msgid "&Restore" msgstr "&Atstatyti" #: qt/app.py:698 msgid "&Help" msgstr "&Pagalba" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 #, fuzzy msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Jeigu uždarysite šį langą, „Back In Time“ negalės išjungti Jūsų kompiuterio pasibaigus momentinės kopijos kūrimui.\n" "Ar tikrai norite uždaryti?" #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "Ar tikrai norite atkurti failus" #: qt/app.py:1072 msgid "Working:" msgstr "Dirbu:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Atlikta, atsarginė kopija nebūtina" #: qt/app.py:1129 msgid "Working" msgstr "Dirbama" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Klaida" #: qt/app.py:1161 msgid "Sent" msgstr "Išsiųsta" #: qt/app.py:1162 msgid "Speed" msgstr "Greitis" #: qt/app.py:1163 msgid "ETA" msgstr "Numatomas atvykimo laikas" #: qt/app.py:1225 msgid "Global" msgstr "Globalus" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Pradžia" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Atsarginių kopijų aplankai" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Momentinės kopijos pavadinimas" #: qt/app.py:1398 #, fuzzy msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Ar jūs tikrai norite pašalinti momentinę kopiją" msgstr[1] "Ar jūs tikrai norite pašalinti momentinę kopiją" msgstr[2] "Ar jūs tikrai norite pašalinti momentinę kopiją" #: qt/app.py:1496 #, fuzzy, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Sukurkite atsargines kopijas su pabaiga {suffix} prieš tai\n" "vietinių failų perrašymas arba pašalinimas." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Prieš atkuriant, naujesnės failų versijos bus pervardytos su pabaiga {suffix}.\n" "Jei jums jų nebereikia, galite juos pašalinti naudodami {cmd}" #: qt/app.py:1520 #, fuzzy msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Atkurkite tik tuos failus, kurių nėra arba\n" "yra naujesnės nei paskirties vietos.\n" "Naudojant parinktį „rsync --update“." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Pašalinkite naujesnius failus iš pradinio aplanko." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Atkurti pasirinktus failus ar aplankus į pradinį taikinį ir\n" "ištrinti failus/aplankus, kurių nėra momentinėje kopijoje.\n" "Tai ištrins failus/aplankus, kurie nebuvo įtraukti į kopiją jos kūrimo metu.\n" "Būkite labai atsargūs!!!" #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Ar tikrai norite atkurti failus\n" "į naują aplanką {path}" msgstr[1] "" "Ar tikrai norite atkurti failus\n" "į naują aplanką {path}" msgstr[2] "" "Ar tikrai norite atkurti failus\n" "į naują aplanką {path}" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ar tikrai norite atkurti failus" msgstr[1] "Ar tikrai norite atkurti failus" msgstr[2] "Ar tikrai norite atkurti failus" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Ar tikrai norite pašalinti visus naujesnius failus iš {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Ar tikrai norite pašalinti visus naujesnius failus iš pradinio aplanko?" #: qt/app.py:1608 #, fuzzy, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "ĮSPĖJIMAS: Failų, esančių failų sistemos šaknyje trynimas gali sugadinti " "jūsų visą operacinę sistemą!!!" #: qt/app.py:1857 msgid "Snapshot" msgstr "Momentinė kopija" #: qt/app.py:1896 #, fuzzy, python-brace-format msgid "Restore {path}" msgstr "Atstatyti {path}" #: qt/app.py:1898 #, fuzzy, python-brace-format msgid "Restore {path} to …" msgstr "Atstatyti {path} į …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Sveiki\n" "Jau kelis kartus naudojotės Back In Time {language} kalba.\n" "Jūsų įdiegtos Back In Time versijos vertimas į {language} yra {perc} baigtas. Nepaisant jūsų įgūdžių lygio galite prisidėti prie vertimo, taip prisidėdami prie pačio Back In Time.\n" "Kviečiame apsilankyti {translation_platform_url} jei norite prisidėti. Jei jums reikalinga pagalba ar turite klausimų, prašome apsilankyti {back_in_time_project_website}.\n" "Atsiprašome už sutrukdymą, ši žinutė daugiau rodoma nebus. Ši informacija pasiekiama bet kuriuo laiku pagalbos meniu.\n" "Jūsų Back In Time komanda" #: qt/app.py:2071 #, fuzzy msgid "translation platform" msgstr "Vertimai" #: qt/app.py:2076 msgid "Website" msgstr "Interneto svetainė" #: qt/app.py:2090 #, fuzzy msgid "Your translation" msgstr "Vertimai" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 #, fuzzy msgid "System default" msgstr "numatytasis" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Paskutinio \"log\" vaizdas" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Momentinės kopijos žurnalo vaizdas" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 #, fuzzy msgid "Profile:" msgstr "Profilis" #: qt/logviewdialog.py:78 #, fuzzy msgid "Snapshots:" msgstr "Momentinės kopijos" #: qt/logviewdialog.py:93 #, fuzzy msgid "Filter:" msgstr "Filtras" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Visi" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Pakeitimai" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Kaidos" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Informacija" msgstr[1] "Informacija" msgstr[2] "Informacija" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Klaida, [I] Informacija, [C] Pakeisti" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "iškoduoti adresus" #: qt/manageprofiles/__init__.py:67 #, fuzzy msgid "Manage profiles" msgstr "Pagrindinis profilis" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Keisti" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Pridėti" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Ištrinti" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Bendri" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Įtraukti" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Įtraukti failus bei aplankus" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Pridėti failą" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Pridėti aplanką" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "Išs&kirti" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Išskirkite šablonus, failus ar aplankus" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Pridėti numatytąjį" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Išskirti failus, didesnius, nei:" #: qt/manageprofiles/__init__.py:233 #, fuzzy, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Išskirti failus, didesnius, nei: " #: qt/manageprofiles/__init__.py:235 #, fuzzy msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Išskirkite failus, didesnius nei %(prefix)s.\n" "Išjungus „Visas rsync režimas“, tai turės įtakos tik naujiems failams\n" "nes rsync tai yra perdavimo parinktis, o ne išimtis.\n" "Taigi dideli failai, kurių atsarginės kopijos buvo sukurtos anksčiau, liks momentinėse nuotraukose\n" "net jei jie pasikeitė." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Pa&rinktys" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Parinktys &ekspertams" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Atkurti Config" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Redaguoti naudotojo-galinį iškvietimą" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Naujas profilis" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Pervadinti profilį" #: qt/manageprofiles/__init__.py:333 #, fuzzy, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Ar jūs tikrai norite ištrinti profilį \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "Labai patariama" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Išskirti šabloną" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Išskirti failą" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Išskirti aplanką" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Įtraukti failą" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„{path}“ yra simbolis. Susieto tikslo atsarginė kopija nebus sukurta, kol neįtrauksite ir jos.\n" "Ar vietoj to norėtumėte įtraukti simbolio nuorodą?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Įtraukti aplanką" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Tvarkaraštis" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Savaitės diena:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Valandos:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Paleisti „Back In Time“ iš karto po disko prijungimo (tik kas X dienų)\n" "Bus prašoma įvesti Jūsų sudo slaptažodį." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Pakartotinai paleiskite Back In Time. Tai naudinga, jei kompiuteris neveikia" " reguliariai." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Kiekvienas:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Išjungta" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Po kiekvieno operacinės sistemos paleidimo/perkrovimo" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Kas {n} minutes" msgstr[1] "Kas {n} minutes" msgstr[2] "Kas {n} minutes" #: qt/manageprofiles/schedulewidget.py:150 #, fuzzy, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Kas valandą" msgstr[1] "Kas valandą" msgstr[2] "Kas valandą" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Kas {n} valandos" msgstr[1] "Kas {n} valandos" msgstr[2] "Kas {n} valandos" #: qt/manageprofiles/schedulewidget.py:159 #, fuzzy msgid "Custom hours" msgstr "Pasirinktinos valandos" #: qt/manageprofiles/schedulewidget.py:160 #, fuzzy msgid "Every day" msgstr "Kasdien" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Pakartotinai (anachronistiškai)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Kai tvarkyklė yra prijungta (udev)" #: qt/manageprofiles/schedulewidget.py:163 #, fuzzy msgid "Every week" msgstr "Kas savaitę" #: qt/manageprofiles/schedulewidget.py:164 #, fuzzy msgid "Every month" msgstr "Kas mėnesį" #: qt/manageprofiles/schedulewidget.py:165 #, fuzzy msgid "Every year" msgstr "Kasmet" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Valandą (-as)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Diena (os/ų)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Savaitė (ės/čių)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mėnesį (-ius)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Tinkintos valandos gali būti tik kableliais atskirtas valandų sąrašas (pvz.," " 8,12,18,23) arba */3, kai atsarginės kopijos daromos kas 3 valandas." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Pagrindinis kompiuteris:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Prievadas:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Naudotojas:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Klausimas" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Paleiskite „rsync“ su „{cmd}“:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "kaip cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "nuotoliniame pagrindiniame kompiuteryje" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "darant momentinę kopiją rankiniu būdu" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Norėdami įjungti šią parinktį, įdiekite 'nocache')" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "vietiniame kompiuteryje" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Nukreipkite stdout į /dev/null cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Nukreipkite stderr į /dev/null cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 #, fuzzy msgid "Limit rsync bandwidth usage:" msgstr "Apriboti rsync pralaidumo naudojimą" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Išsaugoti ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Išsaugoti išplestinius atributus (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopijuoti nesaugias nuorodas (veikia tik su absoliučiomis nuorodomis)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, fuzzy, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" "Įklijuoti papildomas parinktis į rsyncOptions turi būti cituojamos pvz. " "{example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Įklijuokite papildomas parinktis į rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, fuzzy, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Priešdėlis paleisti prieš kiekvieną komandą nuotoliniame pagrindiniame kompiuteryje.\n" "Kintamieji turi būti pakeisti naudojant \\$FOO.\n" "Tai neliečia rsync. Taigi, norėdami pridėti priešdėlį\n" "rsync naudokite „%(cbRsyncOptions)s“ su\n" "%(rsync_options_value)s\n" "\n" "%(default)s: %(def_value)s" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "numatytasis" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Pridėkite priešdėlį prie SSH komandų" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Patikrinkite, ar nuotolinis kompiuteris yra prisijungęs" #: qt/manageprofiles/tab_expert_options.py:337 #, fuzzy msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Įspėjimas: jei išjungta ir nuotolinis kompiuteris\n" "nepasiekiamas, tai gali sukelti \n" "keistas klaidas." #: qt/manageprofiles/tab_expert_options.py:341 #, fuzzy msgid "Check if remote host supports all necessary commands." msgstr "" "Patikrinkite, ar nuotolinis kompiuteris palaiko visas reikalingas komandas" #: qt/manageprofiles/tab_expert_options.py:344 #, fuzzy msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Įspėjimas: jei išjungta ir nuotolinis kompiuteris\n" "nepalaiko visų reikalingų komandų,\n" "tai gali sukelti keistų klaidų." #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "numatytasis" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "išjungta" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "įjungta" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Būsena:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kur išsaugoti momentines kopijas" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH nustatymai" #: qt/manageprofiles/tab_general.py:130 #, fuzzy msgid "Path:" msgstr "Adresas" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šifras:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privatus Raktas:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Pasirinkite esamą privataus rakto failą (pagal nutylėjimą užvadintą " "\"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 #, fuzzy msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Sukurti naują SSH raktą be slaptažodžio (negalima, jei privataus rakto " "failas jau pasirinktas)" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Slaptažodis" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Išsaugoti slaptažodį" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Išsaugoti Cron slaptažodį (Saugumo spraga: root gali matyti slaptažodį)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Išplėstiniai parametrai" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Visas momentinės kopijos kelias:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 #, fuzzy msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Jūs nepasirinkote SSH privataus rakto failo.\n" "Ar norėtumėte sugeneruoti naują viešojo / privataus raktų porą be slaptažodžių?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privataus rakto failas \"{file}\" neegzistuoja." #: qt/manageprofiles/tab_general.py:491 #, fuzzy msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Ar norite nukopijuoti viešąjį SSH raktą į\n" "nuotolinio kompiuterio, kad įgalintumėte prisijungimą be slaptažodžio?" #: qt/manageprofiles/tab_general.py:525 #, fuzzy, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" "{host} autentiškumo nustatyti nepavyko.\n" "\n" "{keytype} rakto kontrolinis kodas yra:" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 #, fuzzy msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Patvirtinkite šį piršto atspaudą! Ar norėtumėte pridėti jį prie failo " "\"known_hosts\"?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Ar tikrai norite pakeisti momentinių kopijų aplanką?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Nepavyko sukurti naujo SSH rakto {path}" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Įgalinti pranešimus" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Išjunkite momentines kopijas, kai naudojate akumuliatorių" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Maitinimo būsena nepasiekiama iš sistemos" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Vienu metu paleisti tik vieną momentinę kopiją" #: qt/manageprofiles/tab_options.py:53 #, fuzzy msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Kitos momentinės kopijos bus blokuojamos, kol bus padaryta dabartinė momentinė kopija.\n" "Tai bendrasis variantas. Taigi tai turės įtakos visiems šio vartotojo profiliams.\n" "Bet jūs turite tai suaktyvinti ir visiems kitiems vartotojams." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Atkūrimo metu sukurkite pakeistų failų atsarginę kopiją" #: qt/manageprofiles/tab_options.py:64 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Prieš atkuriant, naujesnės failų versijos bus pervardytos su pabaiga {suffix}.\n" "Jei jums jų nebereikia, galite juos pašalinti naudodami {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Tęskite klaidas (išsaugokite neišsamias momentines kopijas)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Pasikeitimų aptikimui naudoti kontrolines sumas" #: qt/manageprofiles/tab_options.py:83 #, fuzzy msgid "Take a new snapshot whether there were changes or not." msgstr "" "Padarykite naują momentinę kopiją, nepaisant ar buvo pakeitimų, ar ne." #: qt/manageprofiles/tab_options.py:90 #, fuzzy msgid "Log Level:" msgstr "Žurnalo lygis" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Tuščia" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Nešalinti momentinių kopijų, turinčių pavadinimus." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Nešalinti momentinių kopijų, turinčių pavadinimus." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Metai (-ų)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Pašalinti momentinę kopiją" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 #, fuzzy msgid "Run in background on remote host." msgstr "Vykdykite nuotolinio pagrindinio kompiuterio fone." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Išsaugokite visas momentines kopijas paskutinei" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Diena(os)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Paskutinį kartą išsaugokite vieną momentinę kpiją per dieną" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Paskutinį kartą išsaugokite vieną momentinę kopiją per savaitę" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Savaitė(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Paskutinį kartą išsaugokite vieną momentinę kopiją per mėnesį" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "Mėnesis(iai)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Išsaugokite visas momentines kopijas paskutinei" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Jei laisvos vietos mažiau nei" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Jei laisvų inodų mažiau nei" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Senų momentinių kopijų pašalinimas" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Klausimas" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profilis: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Peržiūrėti paskutinį įrašą žurnale" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Paleisti {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Dirbama…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Išsiųsta:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Greitis:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Momentinės kopijos" #: qt/qttools.py:506 msgid "Today" msgstr "Šiandien" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Vakar" #: qt/qttools.py:522 msgid "This week" msgstr "Šią savaitę" #: qt/qttools.py:529 msgid "Last week" msgstr "Praeitą savaitę" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Tai NE momentinė kopija, o tiesioginis vietinių failų vaizdas" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Paskutinis patikrinimas {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Konfigūracija nerasta" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Parodyti visą žurnalą" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 #, fuzzy msgid "Command:" msgstr "Komanda" #: qt/snapshotsdialog.py:54 #, fuzzy msgid "Parameters:" msgstr "Parametrai" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "naudoti %1 ir %2 kaip kelio parametrus" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Tik skirti skirtingus momentinius vaizdus" #: qt/snapshotsdialog.py:134 #, fuzzy msgid "List only snapshots that are equal to:" msgstr "Išvardykite tik tokias momentines nuotraukas kaip: " #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Gilus apžiūrėjimas (tikslesnis, bet lėtesnis)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Ištrint" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Pasirinkti viską" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Eiti į" #: qt/snapshotsdialog.py:196 #, fuzzy msgid "Options" msgstr "&Parinktys" #: qt/snapshotsdialog.py:353 #, fuzzy msgid "You can't compare a snapshot to itself." msgstr "Jūs negalite palyginti momentinės kopijos su ja pačia." #: qt/snapshotsdialog.py:396 #, fuzzy, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "Ar tikrai norite ištrinti \"{file}\" momentinėje nuotraukoje " "\"{snapshot_id}\"?" #: qt/snapshotsdialog.py:402 #, fuzzy, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ar tikrai norite ištrinti „{file}“ iš {count} momentinių nuotraukų?" #: qt/snapshotsdialog.py:406 #, fuzzy msgid "WARNING: This cannot be revoked." msgstr "Tai negali būti atšaukta!" #: qt/snapshotsdialog.py:424 #, fuzzy, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Ištraukti \"{path}\" iš momentinių nuotraukų ateityje?" backintime-1.5.4/common/po/messages.pot000066400000000000000000001273761477034762000201220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the "Back In Time" package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: \"Back In Time\" \"1.5.4-rc2\"\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "" #: common/config.py:278 msgid "Local" msgstr "" #: common/config.py:280 msgid "SSH" msgstr "" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "" #: common/config.py:283 msgid "Local encrypted" msgstr "" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "" #: common/config.py:289 msgid "SSH encrypted" msgstr "" #: common/config.py:296 msgid "Default" msgstr "" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "" #: common/configfile.py:101 msgid "Failed to save config" msgstr "" #: common/configfile.py:137 msgid "Failed to load config" msgstr "" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "" #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "" #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "" #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "" #: common/encfstools.py:146 msgid "Cancel" msgstr "" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "" #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "" msgstr[1] "" #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "" #: common/snapshots.py:1430 msgid "Success" msgstr "" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "" #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "" #: common/tools.py:504 msgid "Expert Options" msgstr "" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "" #: qt/app.py:172 msgid "Shortcuts" msgstr "" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" #: qt/app.py:257 msgid "Add to Include" msgstr "" #: qt/app.py:259 msgid "Add to Exclude" msgstr "" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" #: qt/app.py:470 msgid "Take a snapshot" msgstr "" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "" #: qt/app.py:497 msgid "Name snapshot" msgstr "" #: qt/app.py:501 msgid "Remove snapshot" msgstr "" #: qt/app.py:505 msgid "View snapshot log" msgstr "" #: qt/app.py:509 msgid "View last log" msgstr "" #: qt/app.py:513 msgid "Manage profiles…" msgstr "" #: qt/app.py:517 msgid "Shutdown" msgstr "" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "" #: qt/app.py:521 msgid "Setup language…" msgstr "" #: qt/app.py:525 msgid "Exit" msgstr "" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "" #: qt/app.py:555 msgid "FAQ" msgstr "" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "" #: qt/app.py:563 msgid "Report a bug" msgstr "" #: qt/app.py:566 msgid "Translation" msgstr "" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" #: qt/app.py:601 msgid "Up" msgstr "" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "" #: qt/app.py:692 msgid "&Restore" msgstr "" #: qt/app.py:698 msgid "&Help" msgstr "" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "" #: qt/app.py:1072 msgid "Working:" msgstr "" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "" #: qt/app.py:1129 msgid "Working" msgstr "" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "" #: qt/app.py:1161 msgid "Sent" msgstr "" #: qt/app.py:1162 msgid "Speed" msgstr "" #: qt/app.py:1163 msgid "ETA" msgstr "" #: qt/app.py:1225 msgid "Global" msgstr "" #: qt/app.py:1226 msgid "Root" msgstr "" #: qt/app.py:1227 msgid "Home" msgstr "" #: qt/app.py:1255 msgid "Backup directories" msgstr "" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete " "files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "" msgstr[1] "" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" #: qt/app.py:1857 msgid "Snapshot" msgstr "" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is " "{perc} complete. Regardless of your level of technical expertise, you can " "contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For " "further assistance and questions, please visit the " "{back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. " "This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2071 msgid "translation platform" msgstr "" #: qt/app.py:2076 msgid "Website" msgstr "" #: qt/app.py:2090 msgid "Your translation" msgstr "" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily " "intended for stability testing in preparation for the next official " "release.\n" "No user data or telemetry is collected. However, the Back In Time team is " "very interested in knowing if the Release Candidate is being used and if it " "is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have " "tested this version, even if you didn’t encounter any issues. Even a quick " "test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed " "anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on " "time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps " "are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 msgid "System default" msgstr "" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "" msgstr[1] "" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you " "include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days). " "You will be prompted for your sudo password." msgstr "" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "" msgstr[1] "" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of " "their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an " "MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an " "MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "" #: qt/qttools.py:506 msgid "Today" msgstr "" #: qt/qttools.py:513 msgid "Yesterday" msgstr "" #: qt/qttools.py:522 msgid "This week" msgstr "" #: qt/qttools.py:529 msgid "Last week" msgstr "" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "" "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "" backintime-1.5.4/common/po/nb.po000066400000000000000000001664231477034762000165220ustar00rootroot00000000000000# Norwegian Bokmal translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-13 07:57+0000\n" "Last-Translator: trench \n" "Language-Team: Norwegian Bokmål \n" "Language: nb\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Advarsel" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hovedprofil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalt (EncFS-kryptert)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-kryptert)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "privat SSH-nøkkel" #: common/config.py:283 msgid "Local encrypted" msgstr "kryptert lokalt" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Kryptering" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH kryptert" #: common/config.py:296 msgid "Default" msgstr "Standardverdi" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Mappen for øyeblikksbilde er ugyldig." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Minst én katalog må velges for sikkerhetskopiering." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Gjenopprett {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Du kan ikke inkludere undermapper av sikkerhetskopi-mappen." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Klarte ikke å skrive ny crontab." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron kjører ikke til tross for at crontab-kommandoen er tilgjengelig. " "Planlagte sikkerhetskopieringsjobber kjøres ikke. Cron kan være installert, " "men ikke aktivert. Prøv kommandoen \"systemctl enable cron\" eller konsulter" " støttekanalene til din GNU/Linux-distribusjon." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Klarte ikke å installere regel for Udev for profilen {profile_id}. DBus-" "tjenesten '{dbus_interface}' var ikke tilgjengelig" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Timeplan udev virker ikke med modusen {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Kunne ikke finne UUID for {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Kunne ikke skrive konfigurasjons-fil" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Kunne ikke laste konfigurasjon-sfil" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" finnes allerede." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Den siste eksistererende profilen kan ikke fjernes." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Kan ikke montere '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Fant ikke konfigurasjon for kryptert mappe." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Lage en ny kryptert mappe?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Avbryt" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Vennligst bekreft passordet." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Passordene stemmer ikke overens." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ta øyeblikksbilde" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kan ikke avmontere {mountprocess} fra {mountpoint}." #: common/mount.py:709 #, fuzzy, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Finner ikke {command}. Vennligst installer den, for eksempel via " "«{installcommand}»" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Monteringspunket {mntpoint} er ikke tomt." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Skriv inn passord for {mode} profil «{profile}»:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FEILET" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Gjenopprett tillatelser" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Ferdig" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Batteridrift utsetter backup" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Kan ikke opprette mappe." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Kan ikke finne øyeblikksbilde-mappe.\n" "Hvis den er på en ekstern disk må du koble denne til, og deretter trykke OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Venter %s sekund." msgstr[1] "Venter %s sekunder." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Øyeblikksbilde feilet {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Vær tålmodig. Fullfører …" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Kan ikke opprette mappe" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Lagrer konfigurasjonsfil…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Lagrer tillatelser…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Fant resten {snapshot_id} som kan fortsettes." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Fjerner reste-mappen {snapshot_id} fra forrige kjøring" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Mappen kan ikke slettes" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Tar øyeblikksbilde" #: common/snapshots.py:1430 msgid "Success" msgstr "Suksess" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Delvis overføring på grunn av feil" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Ufullstendig overføring grunnet tap av kildefiler (se 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' avsluttet med kode {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Se 'man rsync' for flere detaljer" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "Negative rsync-returkoder er signalnumre. Se 'kill -l' og 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ingenting er endret, så nytt øyeblikksbilde er ikke nødvendig" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Kan ikke endre navn fra {new_path} til {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Smart sletting" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Slett gamle øyeblikksbilder" #: common/snapshots.py:1921 #, fuzzy msgid "Apply retention policy" msgstr "Bruk retningslinjer for oppbevaring" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Forsøk å bevare min ledig plass" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Forsøker å bevare minst {perc} ledige inodes" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nå" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Kan ikke montere {sshfs}" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "Fant ingen SSH-agent. Vennligst se til at den er installert." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Klarte ikke å låse opp den private SSH-nøkkelen. Enten er passordet feil, " "eller så er ikke passordet tilgjengelig for cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Chiffer {cipher} feilet for {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Fjern-katalogbanen finnes, men er ikke en mappe." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Fjern-katalogbanen er ikke skrivbar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Fjern-katalogbanen er ikke kjørbar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Kan ikke opprette ekstern bane." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Ekstern vert {host} støtter ikke {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Slå opp 'man backintime' for videre instruksjoner" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kommandosjekk på verten {host} returnerte en ukjent feil" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Fjern-verten {host} støtter ikke harde lenker" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopier offentlig ssh nøkkel \"{pubkey}\" til den andre verten «{host}»." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Vennligst skriv inn passord for «{user}»." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Målfilsystem for {path} er formatert med FAT som ikke støtter hardlenker. " "Bruk heller et filsystem tilpasset Linux." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Fjern-katalogbanen finnes, men er ikke en mappe." #: common/tools.py:446 #, fuzzy msgid "Creation of following directory failed:" msgstr "Opprettelsen av følgende katalog mislyktes:" #: common/tools.py:448 common/tools.py:544 #, fuzzy msgid "Write access may be restricted." msgstr "Skrivetilgang kan være begrenset." #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Målfilsystem for {path} er formatert med FAT som ikke støtter hardlenker. " "Bruk heller et filsystem tilpasset Linux." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Målfilsystemet for {path} er et delt nettverksområde av typen SMB. Se til at" " målfilsystemet støtter symbolske lenker (symlinks), eller aktivér " "{copyLinks} i {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopier symbolske lenker som filer (og fjern lenkereferansen)" #: common/tools.py:504 msgid "Expert Options" msgstr "Avanserte innstillinger" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Målfilsystemet for {path} er delt sshfs-montert område, men sshfs støtter " "ikke harde lenker. Vennligst bruk «SSH»-modus i stedet." #: common/tools.py:542 #, fuzzy msgid "File creation failed in this directory:" msgstr "Filoppretting mislyktes i denne katalogen:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Om" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Forfattere" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Oversettelser" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lisens" #: qt/app.py:172 msgid "Shortcuts" msgstr "Snarveier" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Mappen finnes ikke\n" "i det valgte øyeblikksbildet." #: qt/app.py:257 msgid "Add to Include" msgstr "Legg til for å inkludere" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Legg til for å ekskludere" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "{app_name} virker å kjøre for første gang, da intet oppsett finnes." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Vil du importere en eksisterende konfigurasjon (fra en " "sikkerhetskopimålkatalog eller en annen datamaskin)?" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Kan ikke finne øyeblikksbilde-mappe.\n" "Hvis den er på en ekstern disk må du koble denne til, og deretter trykke OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ta et øyeblikksbilde" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Bruk endringstid og størrelse for å spore fil-endringer." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ta et øyeblikksbilde (sjekksum-modus)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Bruk sjekksummer for å spore filendringer." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Sett øyeblikksbilde-prosessen på pause" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Fortsett øyeblikksbilde-prosessen" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stopp øyeblikksbilde-prosessen" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Oppdaterer listen over øyeblikksbilder" #: qt/app.py:497 msgid "Name snapshot" msgstr "Gi navn til øyeblikksbilde" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Fjern øyeblikksbilde" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vis logg for øyeblikksbilde" #: qt/app.py:509 msgid "View last log" msgstr "Vis siste logg" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Administrer profiler…" #: qt/app.py:517 msgid "Shutdown" msgstr "Skru av" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Skrur av systemet etter at øyeblikksbildet er ferdig." #: qt/app.py:521 msgid "Setup language…" msgstr "Velg språk…" #: qt/app.py:525 msgid "Exit" msgstr "Avslutt" #: qt/app.py:529 #, fuzzy msgid "User manual" msgstr "Brukerhåndbok" #: qt/app.py:531 #, fuzzy msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Åpne brukerhåndboken i nettleseren (lokal hvis tilgjengelig ellers på " "nettet)" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "man-side: Tilbake i tid" #: qt/app.py:537 #, fuzzy msgid "Displays man page about Back In Time (backintime)" msgstr "Viser man-side om Back In Time (backintime)" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Profilens konfigurasjonsfil" #: qt/app.py:543 #, fuzzy msgid "Displays man page about profiles config file (backintime-config)" msgstr "Viser man-side om profilens konfigurasjonsfil (backintime-config)" #: qt/app.py:547 #, fuzzy msgid "Project website" msgstr "Prosjektets nettside" #: qt/app.py:550 #, fuzzy msgid "Open Back In Time website in browser" msgstr "Åpne Back In Time-nettstedet i nettleseren" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Endringslogg" #: qt/app.py:555 msgid "FAQ" msgstr "Ofte stilte spørsmål" #: qt/app.py:557 #, fuzzy msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Åpne Vanlige spørsmål (FAQ) i nettleseren" #: qt/app.py:559 msgid "Ask a question" msgstr "Still et spørsmål" #: qt/app.py:563 msgid "Report a bug" msgstr "Rapporter en feil" #: qt/app.py:566 msgid "Translation" msgstr "Oversettelse" #: qt/app.py:568 #, fuzzy msgid "Shows the message about participation in translation again." msgstr "Viser meldingen om deltakelse i oversettelsen igjen." #: qt/app.py:572 #, fuzzy msgid "Encryption Transition (EncFS)" msgstr "Krypteringsovergang (EncFS)" #: qt/app.py:574 #, fuzzy msgid "Shows the message about EncFS removal again." msgstr "Viser meldingen om fjerning av EncFS igjen." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Gjennopprett" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Gjenopprett valgte filer og mapper til opprinnelig sted." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Gjennopprett til …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Gjenopprett valgte filer og mapper til et nytt sted." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Gjenopprett de viste mappene og alt deres innhold til det opprinnelige " "stedet." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Gjenopprett de viste mappene og alt deres innhold til et nytt sted." #: qt/app.py:601 msgid "Up" msgstr "Opp" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Vis skjulte filer" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Sammenlign øyeblikksbilder…" #: qt/app.py:637 qt/app.py:2152 #, fuzzy msgid "Release Candidate" msgstr "Utgivelseskandidat" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Viser meldingen om denne utgivelseskandidaten igjen." #: qt/app.py:676 #, fuzzy msgid "Back In &Time" msgstr "Tilbake i &Tid" #: qt/app.py:681 msgid "&Backup" msgstr "&Sikkerhetskopi" #: qt/app.py:692 msgid "&Restore" msgstr "&Gjennopprett" #: qt/app.py:698 msgid "&Help" msgstr "&Hjelp" #: qt/app.py:743 #, fuzzy msgid "Icons only" msgstr "Bare ikoner" #: qt/app.py:746 #, fuzzy msgid "Text only" msgstr "Kun tekst" #: qt/app.py:749 #, fuzzy msgid "Text below icons" msgstr "Tekst under ikonene" #: qt/app.py:752 #, fuzzy msgid "Text beside icon" msgstr "Tekst ved siden av ikonet" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Hvis du lukker dette vinduet vil ikke Back In Time være i stand til å skru " "av systemet når øyeblikksbildet er ferdig." #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "Er du sikker på at du vil gjenopprette dette elementet?" #: qt/app.py:1072 msgid "Working:" msgstr "Arbeider:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Ferdig, sikkerhetskopiering trengs ikke" #: qt/app.py:1129 msgid "Working" msgstr "Arbeider" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Feil" #: qt/app.py:1161 msgid "Sent" msgstr "Sendt" #: qt/app.py:1162 msgid "Speed" msgstr "Hastighet" #: qt/app.py:1163 msgid "ETA" msgstr "Forventet ferdig" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Rot" #: qt/app.py:1227 msgid "Home" msgstr "Hjem" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Øyeblikksbilde mapper" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Navn på øyeblikksbilde" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Er du sikker på at du vil fjerne dette øyeblikksbildet?" msgstr[1] "Er du sikker på at du vil fjerne disse øyeblikksbildene?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Lag en sikkerhetskopi med endelse {suffix}\n" "før lokale elementer blir fjernet eller overskrevet." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Nyere versjoner av filer vil få nytt navn med endelsen {suffix} før de blir gjenopprettet.\n" "Hvis du ikke trenger dem lengre kan du fjerne dem med {cmd}" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Gjenopprett kun elementer som enten ikke eksisterer\n" "eller er nyere enn de eksisterende elementene.\n" "Bruker \"rsync --update\"-opsjonen." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Fjern elementer som er nyere i den originale mappen." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Gjenopprett valgte filer og mapper til det originale stedet og\n" "slett filer og mapper som ikke er inkuldert i øyeblikksbildet.\n" "Vær veldig forsiktig, fordi dette vil\n" "slette alle filene og mappene som var\n" "ekskludert da øyeblikksbildet ble tatt." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Er du sikker på at du vil gjenopprette dette elementet til den nye mappen\n" "{path}?" msgstr[1] "" "Er du sikker på at du vil gjenopprette disse elementene til den nye mappen\n" "{path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Er du sikker på at du vil gjenopprette dette elementet?" msgstr[1] "Er du sikker på at du vil gjenopprette disse elementene?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Er du sikker på at du vil fjerne alle nyere filer i {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Er du sikker på at du vil fjerne alle nyere filer i den originale mappen?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}ADVARSEL{BOLDEND}: Å slette filer i root-filsystemet kan ødelegge hele" " systemet ditt." #: qt/app.py:1857 msgid "Snapshot" msgstr "Øyeblikksbilde" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Gjenopprett {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Gjennopprett {path} til …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hei!\n" "Du har brukt Back In Time med {language} språkdrakt noen ganger allerede.\n" "Oversettelsen til {language} for din installerte versjon av Back In Time er {perc} ferdig. Uavhengig av din tekniske kompetanse kan du bidra med oversettelse og dermed også til Back In Time.\n" "Det er fint om du besøker {translation_platform_url} hvis du har lyst til å bidra. For mer hjelp og spørsmål, besøk {back_in_time_project_website}.\n" "Vi beklager forstyrrelsen, og denne meldingen vil ikke dukke opp igjen. Denne dialogen er tilgjengelig når som helst via hjelpemenyen.\n" "Hilsen Back In Time-laget ditt" #: qt/app.py:2071 msgid "translation platform" msgstr "oversettelses-plattform" #: qt/app.py:2076 msgid "Website" msgstr "Nettside" #: qt/app.py:2090 msgid "Your translation" msgstr "Din oversettelse" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Språkinnstillingene trer først i kraft etter en omstart av Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Innstalleringsspråk" #: qt/languagedialog.py:97 msgid "System default" msgstr "Standardverdi for systemet" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Bruk samme språk som operativsystemet." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Oversatt: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Se seneste logg" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Se logg for øyeblikksbilde" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Øyeblikksbilder:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alt" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Endringer" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Feil" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Informasjon" msgstr[1] "Informasjon" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Feil, [I] Informasjon, [C] Endring" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dokode stier" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Administrer profiler" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Rediger" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Legg til" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Fjern" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Generelt" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkluder" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Inkluder filer og mapper" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Legg til fil" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Legg til katalog" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Ekskludér" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Ekskluderingsmønstre, filer og mapper" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Legg til standardmønstre" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Ekskluder filer som er større enn:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Utelukk filer som har større verdi enn {size_unit}." #: qt/manageprofiles/__init__.py:235 #, fuzzy msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Ekskluder filer som er større enn verdien i %(prefix)s.\n" "Med 'Full rsync mode' avslått vil dette bare gjelde nye filer\n" "siden dette for rsync er en overførings-opsjon, ikke en ekskluderings-opsjon.\n" "Det betyr at store filer som har blitt sikkerhetskopiert forblir i øyeblikksbildet\n" "selv om de har endret seg." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Alternativer" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "E&kspert-innstillinger" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Gjenopprett konfigurasjon" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Endre user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Ny profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Omdøp profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Er du sikker på at du vil slette profilen \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "Svært anbefalt" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Utelukk mønster" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Ekskluder fil" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Ekskludér katalog" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkluder fil" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" er en symbolsk lenke. Det vil ikke bli tatt sikkerhetskopi av målet for lenken inntil du inkluderer dette også.\n" "Ønsker du å inkludere målet for den symbolske lenken istedenfor?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Inkludér katalog" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Timeplan" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Ukedag:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Timer:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Kjør Back In Time så snart lagringsenheten koble til (kun en gang hver X dager)).\n" "Du vil bli spurt om ditt sudo-passord." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Kjør Back In Time gjentakende. Dette er nyttig hvis datamaskinen ikke kjører" " hele tiden." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Hver:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Deaktivert" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "For hver start/omstart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Hvert minutt" msgstr[1] "Hvert {n}. minutt" #: qt/manageprofiles/schedulewidget.py:150 #, fuzzy, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Hver time" msgstr[1] "Hver time" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Hver time" msgstr[1] "Hver {n}. time" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Velg timer" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Hver dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Gjentakende (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Når lagringsenheten kobles til (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Hver uke" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Hver måned" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Hvert år" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Time(r)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(er)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Uke(r)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Måned(er)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Egendefinerte timer kan kun være en kommaseparert liste med timer (for " "eksempel 2,4,6,18,22) eller */3 for periodisk sikkerhetskopiering hver 3. " "time." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Tjener:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Bruker:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Vær varsom:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Kjør 'rsync' med '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "som cron-jobb" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "på ekstern vert" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "når en lager et øyeblikksbilde manuelt" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Vennligst installer 'nocache' for å slå på denne opsjonen)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "på lokal maskin" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Rediriger stdout til /dev/null i cron-jobber." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Rediriger stderr til /dev/null i cron-jobber." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Begrens båndbredden for rsync til:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Behold ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Behold utvidede attributter (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopier usikre lenker (virker kun på absolutte lenker)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opsjoner må settes i gåseøyne, for eksempel {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Lim inn tilleggsopsjoner til rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, fuzzy, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Prefiks å kjøre før hver kommando på ekstern vert.\n" "Variabler må starte med en \"rømningskarakter\", en bakoverstrek, for eksempel \\$FOO.\n" "Dette berører ikke rsync. For å legge til en et prefiks for\n" "rsync bruker du \"%(cbRsyncOptions)s\" med\n" "%(rsync_options_value)s\n" "\n" "%(default)s: %(def_value)s" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standard" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Legg til et prefiks for SSH-kommandoer" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Sjekk om ekstern vert er oppe" #: qt/manageprofiles/tab_expert_options.py:337 #, fuzzy msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Advarsel: Hvis denne opsjonen er avslått samtidig som ekstern vert\n" "ikke er tilgjengelig kan det oppstå en del\n" "merkelige feil." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Sjekk om ekstern vert har støtte for alle nødvendige kommandoer." #: qt/manageprofiles/tab_expert_options.py:344 #, fuzzy msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Advarsel: hvis opsjonen er avslått og den eksterne verten\n" "ikke støtter alle de nødvendige kommandoene\n" "kan det oppstå en del merkelige feil." #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "standard" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "avslått" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "påslått" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modus:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Hvor lagre øyeblikksbilder" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-innstillinger" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Sti:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Chiffer:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privat SSH-nøkkel:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "Velg en eksisterende privat nøkkel (normalt kalt \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Lag en ny SSH-nøkkel uten passord (ikke tillatt hvis en privat nøkkel " "allerede er valgt)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Passord" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Lagre passord til nøkkelringen" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Legg passordet i hurtigminne for cron (sikkerhetsutfordring: root-bruker kan" " lese passordet)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avansert" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Fullstendig øyeblikksbilde-bane:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 #, fuzzy msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Du valgte ikke en privat SSH-nøkkel.\n" "Ønsker du å lage et nytt passord-løst nøkkelpar (offentlig/privat nøkkelpar)?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privatnøkkel-fil \"{file}\" finnes ikke." #: qt/manageprofiles/tab_general.py:491 #, fuzzy msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Ønsker du å kopiere din offentlige SSH-nøkkel til den\n" "eksterne verten slik at du kan bruke passordløs innlogging?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Ektheten til vert {host} kan ikke fastslås." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 #, fuzzy msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Vennligst verifiser dette fingeravtrykket! Ønsker du å legge det til i din " "'known_hosts'-fil?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Er du sikker på at vil bytte mappe for øyeblikksbilder?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Fikk ikke til å lage nye SSH-nøkler i {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Slå på meldinger" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Slå av funksjonen snapshot ved bateridrift" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Batteristatus er ikke tilgjengelig fra systemet" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Ta kun ett øyeblikksbilde om gangen" #: qt/manageprofiles/tab_options.py:53 #, fuzzy msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andre øyeblikksbilder vil bli blokkert inntil det nåværende er ferdig.\n" "Dette er en global opsjon, så det vil gjelde for alle profiler til denne brukeren.\n" "Opsjonen må fortsatt aktiveres for andre brukere." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Ta sikkerhetskopi av filer som blir overskrevet av gjenoppretting" #: qt/manageprofiles/tab_options.py:64 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Nyere versjoner av filer vil få nytt navn med endelsen {suffix} før de blir gjenopprettet.\n" "Hvis du ikke trenger dem lengre kan du fjerne dem med {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "" "Fortsett når feil oppstår (behold øyeblikksbilder som ikke er komplette)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Bruk sjekksum for å oppdage endringer" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ta et nytt øyeblikksbilde enten det har vært endringer eller ikke." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Logg-nivå:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ingen" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Ikke fjern navngitte øyeblikksbilder." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Ikke fjern navngitte øyeblikksbilder." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "År" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Fjern øyeblikksbilde" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Kjør i bakgrunnen på den eksterne verten." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Behold alle øyeblikksbilder tatt de siste" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dag(ene)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Behold ett øyeblikksbilde pr dag for de siste" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Behold ett øyeblikksbilde pr uke for de siste" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "uke(ene)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Behold ett øyeblikksbilde pr måned for de siste" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "måned(ene)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Behold alle øyeblikksbilder tatt de siste" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Hvis det er mindre ledig plass enn" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… ledige inoder er færre enn" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Slett eldste øyeblikksbilde hvis …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Spørsmål" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Vis siste logg" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Start {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Arbeider…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Sendt:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hastighet:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Øyeblikksbilder" #: qt/qttools.py:506 msgid "Today" msgstr "Idag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Igår" #: qt/qttools.py:522 msgid "This week" msgstr "Denne uken" #: qt/qttools.py:529 msgid "Last week" msgstr "Forrige uke" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Dette er IKKE et øyeblikksbilde, men en sanntidsvisning av dine lokale filer" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Sist sjekket {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Fant ingen konfigurasjon" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Vis hele loggen" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opsjoner for å sammenligne øyeblikksbilder" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Kommando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametre:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Bruk %1 and %2 for path parameters" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Kun øyeblikksbilder med forskjeller" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Liste med kun like øyeblikksbilder til:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Dypsjekk (mer nøyktig, men tregt)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Slett" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Velg alle" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Sammenlign" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gå Til" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Alternativer" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Du kan ikke sammenlikne et øyeblikksbilde med seg selv." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Ønsker du virkelig å slette {file} i øyeblikksbildet {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ønsker du virkelig å slette {file} i {count} øyeblikksbilder?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ADVARSEL: Dette kan ikke gjøres om." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Utelukk {path} fra fremtidige øyeblikksbilder?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Du kan ikke inkludere undermapper av sikkerhetskopi-mappen." backintime-1.5.4/common/po/nl.po000066400000000000000000001724601477034762000165320ustar00rootroot00000000000000# Dutch translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2024-10-02 06:42+0000\n" "Last-Translator: reneald \n" "Language-Team: Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.7.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Let op" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hoofdprofiel" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokaal (EncFS-versleuteld)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-versleuteld)" #: common/config.py:278 msgid "Local" msgstr "Lokaal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH private sleutel" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokaal versleuteld" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Versleuteling" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH-versleuteld" #: common/config.py:296 msgid "Default" msgstr "Standaard" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profiel: “{name}”" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Momentopname-folder is ongeldig!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "{path} terugzetten" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Back-up-submap kan niet worden opgenomen." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Kon geen nieuwe crontab schrijven." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron is niet actief, hoewel het commando crontab beschikbaar is. Geplande " "back-uptaken worden niet uitgevoerd. Mogelijk is cron geïnstalleerd, maar " "niet geactiveerd. Probeer het commando \"systemctl enable cron\" of " "raadpleeg de ondersteuningskanalen van uw GNU/Linux-distributie." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Kon udev-regel voor profiel {profile_id} niet installeren. DBus-dienst " "'{dbus_interface}' was niet beschikbaar" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Methode udev werkt niet bij modus {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "" "Kon UUID (Universeel Unieke IDentificatiecode) voor \"{path}\" niet vinden" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Kon configuratie niet opslaan" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Kon configuratie niet laden" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profiel \"{name}\" bestaat al." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Het laatste profiel kan niet worden verwijderd." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Kan '{command}' niet aankoppelen" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Configuratie voor versleutelde map niet gevonden." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Een nieuwe versleutelde map aanmaken?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Annuleren" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Bevestig het wachtwoord." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Wachtwoord komt niet overeen." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Momentopname maken" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kan {mountprocess} niet ontkoppelen van {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} niet gevonden. Installeer het a.u.b. (bijv. via " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Koppelpunt {mntpoint} niet leeg." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Voer het wachtwoord in voor {mode} profiel \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "MISLUKT" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Rechten herstellen" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Voltooid" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Back-up uitstellen indien op batterij" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Kan momentopnamemap niet vinden." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Als deze op een verwijderbaar medium staat, gelieve dit aan te sluiten en op" " OK te drukken." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Wacht %s seconde." msgstr[1] "Wacht %s seconden." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Kon momentopname {snapshot_id} niet maken." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Even geduld. Afronden…" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Kan map niet aanmaken" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Configuratiebestand opslaan…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Rechten opslaan…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Restant van '{snapshot_id}' gevonden waarmee voortgegaan kan worden." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Resterende map '{snapshot_id}' van de laatste keer verwijderen" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Kan map niet verwijderen" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Momentopname wordt gemaakt" #: common/snapshots.py:1430 msgid "Success" msgstr "Succes" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Gedeeltelijke overdracht vanwege een fout" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Gedeeltelijke overdracht vanwege verdwenen bronbestanden (zie 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' eindigde met exitcode {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Zie 'man rsync' voor meer informatie" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negatieve rsync-exitcodes zijn signaalnummers, zie 'kill -l' en 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Er is niets veranderd, geen nieuwe momentopname nodig" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Kan {new_path} niet hernoemen naar {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Slim verwijderen" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Oude momentopnames verwijderen" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Een minimum aan vrije ruimte proberen te behouden" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Een minimum van {perc} vrije inodes proberen te behouden" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nu" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Kan {sshfs} niet aankoppelen" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent niet gevonden. Zorg ervoor dat het is geïnstalleerd." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Kon SSH-privésleutel niet ontgrendelen. Het wachtwoord is ongeldig of is " "niet beschikbaar voor cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Versleutelingsmethode {cipher} mislukt voor {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Extern pad bestaat maar is geen map." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Extern pad is niet beschrijfbaar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Extern pad is niet uitvoerbaar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Kon extern pad niet aanmaken." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Externe host {host} ondersteunt {command} niet" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Raadpleeg 'man backintime' voor verdere instructies" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Controlecommando's op host {host} gaven onbekende foutmelding" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Externe host {host} ondersteunt geen harde koppelingen" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "De openbare SSH-sleutel \"{pubkey}\" kopiëren naar externe host \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Voer het wachtwoord in voor \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Het doelbestandssysteem van ‘{path}’ is geformatteerd als NTFS, dat geen " "harde koppeling, hard-links, ondersteunt. Gebruik in plaats daarvan een " "authentiek Linux-bestandssysteem." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Extern pad bestaat maar is geen map." #: common/tools.py:446 #, fuzzy msgid "Creation of following directory failed:" msgstr "Kon volgende map niet aanmaken:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Het doelbestandssysteem van ‘{path}’ is geformatteerd als FAT, dat geen " "harde koppeling, hard-links, ondersteunt. Gebruik in plaats daarvan een " "authentiek Linux-bestandssysteem." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Het doelbestandssysteem van ‘{path}’ is een met SMB aangekoppelde " "netwerkopslag. Zorg ervoor dat de externe SMB-server symbolische koppelingen" " ondersteunt of activeer ‘{copyLinks}’ in ‘{expertOptions}’." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Koppelingen kopiëren (symbolische koppelingen derefereren)" #: common/tools.py:504 msgid "Expert Options" msgstr "Geavanceerde opties" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Doelbestandssysteem voor '{path}' is een met sshfs aangekoppelde " "netwerkopslag. sshfs ondersteunt geen harde koppelingen. Gebruik in plaats " "daarvan de modus 'SSH'." #: common/tools.py:542 #, fuzzy msgid "File creation failed in this directory:" msgstr "Kon geen bestand aanmaken in deze map:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Info" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Auteurs" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Vertalingen" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licentie" #: qt/app.py:172 msgid "Shortcuts" msgstr "Sneltoetsen" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Deze map bestaat niet\n" "in de momenteel geselecteerde momentopname." #: qt/app.py:257 msgid "Add to Include" msgstr "Toevoegen aan Opnemen" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Toevoegen aan Uitsluiten" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Het lijkt erop dat {app_name} voor de eerste keer wordt uitgevoerd, omdat er" " geen configuratie is gevonden." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Een bestaande configuratie importeren (vanuit een back-updoelmap of een " "andere computer)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Als deze op een verwijderbaar medium staat, gelieve dit aan te sluiten en op" " OK te drukken." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Een momentopname maken" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Modificatietijd en grootte gebruiken voor detectie van bestandswijzigingen." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Momentopname maken (modus controlegetal)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Controlegetallen gebruiken voor het opsporen van bestandswijzigingen." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Maken van momentopname pauzeren" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Maken van momentopname hervatten" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Maken van momentopname stoppen" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Momentopnamelijst vernieuwen" #: qt/app.py:497 msgid "Name snapshot" msgstr "Momentopname benoemen" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Momentopname verwijderen" #: qt/app.py:505 msgid "View snapshot log" msgstr "Momentopnamelogboek bekijken" #: qt/app.py:509 msgid "View last log" msgstr "Laatste logboek bekijken" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Profielen beheren…" #: qt/app.py:517 msgid "Shutdown" msgstr "Uitschakelen" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Computer uitschakelen wanneer de momentopname voltooid is." #: qt/app.py:521 msgid "Setup language…" msgstr "Taal instellen…" #: qt/app.py:525 msgid "Exit" msgstr "Afsluiten" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Profielconfiguratiebestand" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Wijzigingslogboek" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Een vraag stellen" #: qt/app.py:563 msgid "Report a bug" msgstr "Een fout melden" #: qt/app.py:566 msgid "Translation" msgstr "Vertaling" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Toont het bericht over deelname aan vertaling opnieuw." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Versleutelingsovergang (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Toont opnieuw het bericht over het verwijderen van EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Herstellen" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "" "De geselecteerde bestanden of mappen naar de oorspronkelijke bestemming " "herstellen." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Herstellen naar …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "" "De geselecteerde bestanden of mappen naar een nieuw bestemming herstellen." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "De momenteel weergegeven map en alle inhoud ervan naar de oorspronkelijke " "bestemming herstellen." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "De momenteel weergegeven map en alle inhoud ervan naar een nieuwe bestemming" " herstellen." #: qt/app.py:601 msgid "Up" msgstr "Omhoog" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Verborgen bestanden tonen" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Momentopnames vergelijken…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Toont opnieuw het bericht over het verwijderen van EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Back-up" #: qt/app.py:692 msgid "&Restore" msgstr "Te&rugzetten" #: qt/app.py:698 msgid "&Help" msgstr "&Hulp" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Als u dit venster sluit, zal Back In Time de computer niet uit kunnen " "schakelen wanneer de momentopname voltooid is." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Weet u zeker dat u het wilt sluiten?" #: qt/app.py:1072 msgid "Working:" msgstr "Bezig:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Klaar, geen back-up nodig" #: qt/app.py:1129 msgid "Working" msgstr "Bezig" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Fout" #: qt/app.py:1161 msgid "Sent" msgstr "Verzonden" #: qt/app.py:1162 msgid "Speed" msgstr "Snelheid" #: qt/app.py:1163 msgid "ETA" msgstr "Geschatte afhandelingstijd" #: qt/app.py:1225 msgid "Global" msgstr "Algemeen" #: qt/app.py:1226 msgid "Root" msgstr "Hoofdmap" #: qt/app.py:1227 msgid "Home" msgstr "Persoonlijke map" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Back-upmappen" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Naam momentopname" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Weet u zeker dat u deze momentopname wilt verwijderen?" msgstr[1] "Weet u zeker dat u deze momentopnames wilt verwijderen?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Back-ups met achtervoegsel {suffix} maken, voordat\n" "lokale elementen overschreven of verwijderd worden." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Nieuwere versies van bestanden worden hernoemd met achtervoegsel {suffix} " "voordat ze worden teruggezet. Als u ze niet meer nodig heeft kunt u ze " "verwijderen met het volgende commando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Alleen elementen terugzetten die niet bestaan of\n" "nieuwer zijn dan die in de bestemming.\n" "De optie \"rsync --update\" wordt gebruikt." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Nieuwere elementen in oorspronkelijke map verwijderen." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Geselecteerde bestanden of mappen naar de oorspronkelijke bestemming " "herstellen en bestanden/mappen die niet in de momentopname voorkomen, " "verwijderen. Wees hier uiterst voorzichtig mee. Hierdoor worden " "bestanden/mappen verwijderd die waren uitgesloten tijdens het maken van de " "momentopname." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Weet u zeker dat u dit element wilt herstellen naar de nieuwe map\n" "{path}?" msgstr[1] "" "Weet u zeker dat u deze elementen wilt herstellen naar de nieuwe map\n" "{path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Weet u zeker dat u dit element wilt herstellen?" msgstr[1] "Weet u zeker dat u deze elementen wilt herstellen?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Weet u zeker dat u alle nieuwere bestanden in {path} wilt verwijderen?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Weet u zeker dat u alle nieuwere bestanden in uw oorspronkelijke map wilt " "verwijderen?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Let op:{BOLDEND} Het verwijderen van bestanden uit de hoofdmap van het" " bestandssysteem kan uw hele systeem ruïneren." #: qt/app.py:1857 msgid "Snapshot" msgstr "Momentopname" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "{path} terugzetten" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "{path} terugzetten naar …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hallo\n" "U heeft Back In Time nu al een paar keer gebruikt in het {language}.\n" "De vertaling van de geïnstalleerde versie van Back In Time in het {language} is {perc} voltooid. Ongeacht uw niveau van technische expertise kunt u een bijdrage leveren aan de vertaling en daarmee aan Back In Time zelf.\n" "Bezoek {translation_platform_url} als u een bijdrage wilt leveren. Voor verdere hulp en vragen kunt u de {back_in_time_project_website} bezoeken.\n" "Onze excuses voor de onderbreking. Dit bericht zal niet opnieuw worden weergegeven. Dit dialoogvenster is op elk moment beschikbaar via het hulpmenu.\n" "Uw Back In Time-team" #: qt/app.py:2071 msgid "translation platform" msgstr "vertaalplatform" #: qt/app.py:2076 msgid "Website" msgstr "Website" #: qt/app.py:2090 msgid "Your translation" msgstr "Uw vertaling" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "De taalinstellingen worden pas van kracht na het herstarten van Back In " "Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Ondersteuning voor EncFS zal in de nabije toekomst worden stopgezet. Het " "wordt niet aanbevolen om die modus nog verder te gebruiken voor een profiel." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "witboek" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "De/het volgende profiel(en) gebruik(t)(en) versleuteling met EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Dit bericht zal niet meer worden weergegeven. Dit dialoogvenster is op elk " "moment beschikbaar via het hulpmenu." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Uw Back In Time-team" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Taal instellen" #: qt/languagedialog.py:97 msgid "System default" msgstr "Systeemstandaard" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "De taal van het besturingssysteem gebruiken." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Vertaald: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Laatste logboekweergave" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Weergave momentopnamelogboek" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profiel:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Momentopnames:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alles" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Wijzigingen" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Fouten" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informatie" msgstr[1] "Informatie" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "fouten in de rsync-overdracht (experimenteel)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Fout, [I] Informatie, [C] Wijziging" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "paden decoderen" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Profielen beheren" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Bewerken" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Toevoegen" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Verwijderen" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Algemeen" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Opnemen" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Bestanden en mappen opnemen" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Bestand toevoegen" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Map toevoegen" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Uitsluiten" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: in de modus 'SSH-versleuteld' zijn alleen enkele of " "dubbele sterretjes functioneel (bijvoorbeeld {example2}). Andere soorten " "jokertekens en patronen worden genegeerd (bijvoorbeeld {example1}). " "Bestandsnamen zijn in deze modus onvoorspelbaar vanwege de versleuteling " "door EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Patronen, bestanden of mappen uitsluiten" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Standaard toevoegen" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Bestanden uitsluiten die groter zijn dan:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Bestanden uitsluiten die groter zijn dan de waarde in {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Als 'Volledige rsync-modus' is uitgeschakeld, heeft dit alleen invloed op " "nieuwe bestanden, omdat dit voor rsync een overdrachtsoptie is en geen " "uitsluitingsoptie. Daarom zullen grote bestanden waarvan eerder een back-up " "is gemaakt, blijven bestaan in momentopnames, zelfs als ze zijn gewijzigd." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "O&pties" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Geavanceerde opties" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Configuratie herstellen" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "user-callback bewerken" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nieuw profiel" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Profiel hernoemen" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Weet u zeker dat u het profiel \"{name}\" wilt verwijderen ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Aanbevolen{ENDBOLD}: (Alle aanbevelingen zijn al inbegrepen.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Sterk aanbevolen{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Patroon uitsluiten" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Bestand uitsluiten" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Map uitsluiten" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Bestand opnemen" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" is een symbolische koppeling. Van het gekoppelde doel wordt geen back-up gemaakt totdat u het ook opneemt.\n" "Wilt u eerder het doel van de symbolische koppeling opnemen?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Map opnemen" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Geblokkeerd omdat dit patroon niet gebruikt kan worden bij 'SSH " "versleuteld'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Planning" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dag:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Dag van de week:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tijd:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Uren:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Back In Time uitvoeren zodra de schijf is aangesloten (slechts één keer per X dagen).\n" "Er zal om uw beheerderswachtwoord gevraagd worden." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Back In Time herhaaldelijk uitvoeren. Dit is handig wanneer de computer niet" " regelmatig wordt gebruikt." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Elk(e):" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Het loggen van foutopsporingsberichten inschakelen" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Schrijft berichten van debug-gehalte naar het systeemlogboek via \"--" "debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Let op: gebruik dit alleen tijdelijk voor diagnostische doeleinden, omdat " "het een grote hoeveelheid uitvoer genereert." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Uitgeschakeld" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Bij elke opstart/herstart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Elke minuut" msgstr[1] "Elke {n} minuten" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Elk uur" msgstr[1] "Elke {n} uur" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Elk uur" msgstr[1] "Elke {n} uur" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Aangepaste tijdstippen" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Dagelijks" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Herhaaldelijk (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Zodra de schijf is aangesloten (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Wekelijks" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Maandelijks" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Jaarlijks" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Uur/Uren" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(en)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Week/Weken" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Maand(en)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Aangepaste uren kunnen alleen een door komma's gescheiden lijst met uren " "zijn (bijv. 8,12,18,23) of */3 voor periodieke back-ups om de 3 uur." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH-Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Poort:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Gebruiker:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Via deze proxy verbinding maken met de doelhost (ook wel jumphost genoemd). " "Zie \"-J\" in de documentatie bij het \"ssh\"-commando of \"ProxyJump\" in " "de manpagina van \"ssh_config\" voor details." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Vraag" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "'rsync' uitvoeren met '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "als crontaak" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "op externe host" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "bij het maken van een handmatige momentopname" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Installeer 'nocache' om deze optie in te schakelen)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "op de lokale machine" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "stdout omleiden naar /dev/null in crontaken." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron zal automatisch een e-mail sturen met in bijlage de uitvoer van " "crontaken als er een MTA is geïnstalleerd." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "stderr omleiden naar /dev/null in crontaken." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron zal automatisch een e-mail sturen met in bijlage de foutmeldingen van " "crontaken als er een MTA is geïnstalleerd." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Het bandbreedtegebruik van rsync beperken:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACL behouden" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Uitgebreide attributen (xattr) behouden" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Onveilige koppelingen kopiëren (werkt alleen met absolute koppelingen)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Beperken tot één bestandssysteem" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opties moeten tussen aanhalingstekens staan, bijvoorbeeld {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Extra opties aan rsync toevoegen" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" "Voorvoegsel dat vóór elk commando op de externe host moet worden uitgevoerd." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabelen moeten worden gemaskeerd met \\$FOO. Dit heeft geen betrekking op" " rsync. Dus om een voorvoegsel voor rsync toe te voegen gebruikt u " "\"{example_value}\" met {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standaard" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Voorvoegsel aan SSH-commando's toevoegen" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Controleren of de externe host online is" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Let op: als dit is uitgeschakeld en de externe host niet beschikbaar is, kan" " dit leiden tot rare fouten." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Controleren of de externe host alle benodigde commando's ondersteunt." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Let op: als dit uitgeschakeld is en de externe host ondersteunt niet alle " "benodigde commando's, kan dit leiden tot rare fouten." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(standaard: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "uitgeschakeld" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "ingeschakeld" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modus:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Waar wilt u de momentopnames opslaan" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-instellingen" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Pad:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Versleutelingsmethode:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privésleutel:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "Kies een bestaand privésleutelbestand (normaal met de naam \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Een nieuwe SSH-sleutel zonder wachtwoord aanmaken (niet toegestaan als er al" " een privésleutelbestand is geselecteerd)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Wachtwoord" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Wachtwoord toevoegen aan sleutelbos" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Wachtwoord in cache opslaan voor Cron (Beveiligingsprobleem: beheerder kan " "wachtwoord lezen)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Geavanceerd" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Volledig momentopnamepad:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "U heeft geen privésleutelbestand voor SSH gekozen." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Wilt u een nieuw publiek/privé sleutelpaar genereren zonder wachtwoord?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privésleutelbestand \"{file}\" bestaat niet." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Wilt u uw openbare SSH-sleutel naar de externe host kopiëren om inloggen " "zonder wachtwoord mogelijk te maken?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "De authenticiteit van host {host} kan niet worden vastgesteld." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} sleutelvingerafdruk is:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Controleer deze vingerafdruk. Wilt u deze toevoegen aan uw bestand " "'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Weet u zeker dat u de momentopnamemap wilt wijzigen?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Aanmaken nieuwe SSH-sleutel in {path} mislukt." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Meldingen activeren" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Momentopnames uitschakelen bij batterijgebruik" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Voedingsstatus niet beschikbaar via systeem" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Slechts één momentopname tegelijk uitvoeren" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andere momentopnames worden geblokkeerd totdat de huidige momentopname is " "voltooid. Dit is een globale optie. Ze heeft dus invloed op alle profielen " "van deze gebruiker. Maar u moet dit ook voor alle andere gebruikers " "activeren." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Back-up maken van vervangen bestanden bij terugzetten" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Nieuwere versies van bestanden worden hernoemd met achtervoegsel {suffix} " "voordat ze worden teruggezet. Als u ze niet meer nodig heeft kunt u ze " "verwijderen met {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Doorgaan bij fouten (onvolledige momentopnames bewaren)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Controlegetal gebruiken om wijzigingen te detecteren" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Een nieuwe momentopname maken, of er nu wijzigingen waren of niet." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Logboekniveau:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Geen" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Genoemde momentopnames niet verwijderen." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Genoemde momentopnames niet verwijderen." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Jaar" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Momentopname verwijderen" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Op de achtergrond uitvoeren op externe host." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Alle momentopnames bewaren van de laatste" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dag(en)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Eén momentopname per dag bewaren van de laatste" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Eén momentopname per week bewaren van de laatste" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "week/weken." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Eén momentopname per maand bewaren van de laatste" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "maand(en)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Alle momentopnames bewaren van de laatste" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Als de vrije ruimte kleiner is dan:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Als er minder inodes vrij zijn dan:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Oude momentopnames verwijderen" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Vraag" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profiel: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Laatste logboek bekijken" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "{appname} starten" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Bezig…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Verzonden:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Snelheid:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Geschatte afhandelingstijd:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Momentopnames" #: qt/qttools.py:506 msgid "Today" msgstr "Vandaag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Gisteren" #: qt/qttools.py:522 msgid "This week" msgstr "Deze week" #: qt/qttools.py:529 msgid "Last week" msgstr "Vorige week" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Dit is GEEN momentopname maar een actuele weergave van uw lokale bestanden" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Laatste controle {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Configuratie importeren" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Geen configuratie gevonden" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importeren" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Selecteer de momentopnamemap waaruit het configuratiebestand moet worden " "geïmporteerd. Het pad kan er als volgt uitzien: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Als de map zich op een externe host of externe schijf bevindt, moet deze " "vooraf handmatig worden aangekoppeld." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Volledig logboek tonen" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opties voor het vergelijken van momentopnames" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Commando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parameters:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "%1 en %2 voor padparameters gebruiken" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Stel een diff-commando in of druk op Annuleren." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Het commando \"{cmd}\" kan niet worden gevonden op dit systeem. Probeer iets" " anders of druk op Annuleren." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Er zijn geen parameters ingesteld voor het diff-commando. Standaardwaarde " "\"{params}\" wordt gebruikt." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Alleen momentopnames die verschillen" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Alleen momentopnames tonen die gelijk zijn aan:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Diepgaande controle (nauwkeuriger, maar langzaam)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Wissen" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Alles selecteren" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Vergelijken" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gaan naar" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opties" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "U kunt een momentopname niet met zichzelf vergelijken." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Wilt u {file} in momentopname {snapshot_id} echt verwijderen?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Wilt u {file} in {count} momentopnames echt verwijderen?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "LET OP: dit kan niet worden teruggedraaid." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "{path} uitsluiten van toekomstige momentopnames?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Back-up-submap kan niet worden opgenomen." backintime-1.5.4/common/po/nn.po000066400000000000000000001677541477034762000165460ustar00rootroot00000000000000# Norwegian Nynorsk translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-15 02:28+0000\n" "Last-Translator: vidarlo \n" "Language-Team: Norwegian Nynorsk \n" "Language: nn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Åtvaring" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hovudprofil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokal (EncFS-kryptert)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-kryptert)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privatlykjel" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokal kryptert" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Kryptering" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH-kryptert" #: common/config.py:296 msgid "Default" msgstr "Standardverdi" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Mappa for augneblinksbileta er ugyldig." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Minst ei mappe må veljast for sikkerhetskopiering." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Mappe: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Du kan ikkje inkludere undermapper av sikkerheitskopierings-mappa." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Klara ikkje å skriva ny crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron køyrer ikkje sjølv om crontab-kommandoen er tilgjengeleg. Planlagde " "sikkerheitskoperingsjobbar vil ikkje køyre. Cron kan vere installert, men " "ikkje aktivert. Prøv kommandoen \"systemctl enable cron\", eller sjekk " "tilgjengelege støttekanaler for GNU/Linux-distribusjonen din." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Kunne ikkje installere Udev-regel for profilen {profile_id}. DBus-tenesta " "{dbus_interface} var ikkje tilgjengeleg" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Timeplan udev verker ikkje med modusen {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Kunne ikkje finne UUID for {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Kunne ikkje lagre oppsett" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Kunne ikkje laste oppsett" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profilen \"{name}\" finst allereie." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Den siste profilen kan ikkje fjernast." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Kan ikkje montere '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Fann ikkje konfigurasjon for kryptert mappe." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Lage ei ny kryptert mappe?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Avbryt" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Ver venleg å stadfesta passordet." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Passordene stemmer ikkje overeins." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ta augneblinksbilete" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kan ikkje avmontere {mountprocess} frå {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Fann ikkje {command}. Ver venleg å installere den ved hjelp av t.d. " "{installcommand}" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Monteringspunktet {mntpoint} er ikkje tomt." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Oppgje passord for {mode}-profilen \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FEILA" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Gjennopprett tillatelsar" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Fullført" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Ventar med sikkerhetskopi medan på batteri" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Fann ikkje mappe for augeblinksbilete." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Dersom ho er på ei ekstern lagringseining, plugg eininga i og trykk OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Ventar %s sekund." msgstr[1] "Ventar %s sekund." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Klarte ikkje å ta augneblinksbilete {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Ver venleg vent. Ferdigstiller…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Klarer ikkje å laga mappa." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Lagre oppsettsfila…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Lagre løyve …" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Fann påbegynt {snapshot_id} som kan fortsettjast på." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Fjernar reste-mappa {snapshot_id} frå førre køyring" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Kan ikkje fjerna mappa" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Ta augneblinksbilete" #: common/snapshots.py:1430 msgid "Success" msgstr "Suksess" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Delvis overføring grunna feil" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Ufullstendig overføring grunna tap av kjeldefiler (sjå 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' avslutta med kode {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Sjå 'man rsync' for fleire detaljar" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negative rsync-sluttkodar er signalnummer. Sjå 'kill -l' og 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ingenting endra, nytt augeblinksbilete ikkje påkrevd" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Kan ikkje omdøype {new_path} til {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Smart-sletting" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Bruk regel for å fjerne gamle augneblinksbilete" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Bruk bevaringsrutine" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Prøver å oppretthalde minimum ledig plass" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Prøver å halde minimum {perc} ledige inodar" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "No" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Kan ikkje montere {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "Fann ikkje ssh-agent. Sjekk at det er installert." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Kunne ikkje låse opp privat ssh-nøkkel. Feil passord eller passord ikkje " "tilgjengeleg for cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Kryptoalgoritmen {cipher} feila for {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Fjern sti finst, men er ikkje ei mappe." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Fjern sti er ikkje skrivbar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Fjern sti er ikkje køyrbar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Klarer ikkje å laga mappa på det andre systemet." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Maskina {host} støttar ikkje {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Les 'man backintime' for viare instruksar" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Testkommando på maskina {host} returnerte ukjend feil" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Maskina {host} støttar ikkje hardlenker" #: common/sshtools.py:1191 #, fuzzy, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopier offentleg ssh-nøkkel \"{pubkey}\" til maskina \"{host}\"" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Oppgi passord for \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Målfilsystem for {path} er formatert med NTFS, som ikkje er kompatibelt med " "Unix-filsystem." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} er ikkje ei gyldig mappe." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Kunne ikkje lage følgjande mappe:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Skrivetilgang kan vere avgrensa." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Målfilsystem for {path} er formatert med FAT som ikkje støttar harde " "lenkjer. Bruk heller eit filsystem tilpassa GNU/Linux." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Målfilsystemet for {path} er eit delt nettverksområde av typen SMB. Sjå til " "at målfilsystemet støttar symbolske lenkjer (symlinks), eller aktiver " "{copyLinks} i {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopier symbolske lenkjer som filer (og fjern lenkjereferansen)" #: common/tools.py:504 msgid "Expert Options" msgstr "Avanserte innstillingar" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Målfilsystemet for {path} er eit delt nettverksområde montert med sshfs, men" " sshfs støttar ikkje harde lenkjer. Ver venleg og bruka modus 'SSH' i staden" " for." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Oppretting av filer i denne katalogen feila:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Om" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Forfattarar" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Omsetjingar" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lisens" #: qt/app.py:172 msgid "Shortcuts" msgstr "Snarvegar" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Denne mappa finst ikkje\n" "i det valde augenblinksbiletet." #: qt/app.py:257 msgid "Add to Include" msgstr "Legg til for å inkludere" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Legg til for å ekskludere" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} ser ut til å køyre for første gong ettersom ingen konfigrasjon " "vart funnen." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importer eksisterande konfigurasjon frå ein sikkerheitskopi eller anna " "datamaskin?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Dersom ho er på ei ekstern lagringseining, plugg eininga i og trykk OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Taka eit augneblinksbilete" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Bruk tidspunkt for endring og størrelse for å detektere endringar i filer." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ta eit augneblinksbilete (sjekksum-modus)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Bruk sjekksummar for å oppdage endringar." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Set augneblinksbilete-prosessen på pause" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Taka opp att augneblinksbilete-prosessen" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stansa augneblinksbilete-prosessen" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Oppdater lista over augneblinksbilete" #: qt/app.py:497 msgid "Name snapshot" msgstr "Namngjeva augneblinksbilete" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Fjern augneblinksbilete" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vis logg for augneblinksbilete" #: qt/app.py:509 msgid "View last log" msgstr "Vis siste logg" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Administrer profilar…" #: qt/app.py:517 msgid "Shutdown" msgstr "Slå av" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Slår av systemet etter at augneblinksbilete er ferdig." #: qt/app.py:521 msgid "Setup language…" msgstr "Sett opp språk…" #: qt/app.py:525 msgid "Exit" msgstr "Avslutt" #: qt/app.py:529 msgid "User manual" msgstr "Brukarhandbok" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Opne brukarhandboka i nettlesaren (lokal om tilgjengeleg, elles på nett)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man-side: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Viser man-sida om Back In time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man-side: profilen si konfig-fil" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "Viser man-side om profil-konfigfil (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Prosjektet si nettside" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Opne Back In Time-nettsida i nettlesaren" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Endringslogg" #: qt/app.py:555 msgid "FAQ" msgstr "Vanlege spørsmål" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Opne ofte stilte spørsmål (FAQ) i nettlesaren" #: qt/app.py:559 msgid "Ask a question" msgstr "Still eit spørsmål" #: qt/app.py:563 msgid "Report a bug" msgstr "Rapporter ein feil" #: qt/app.py:566 msgid "Translation" msgstr "Oversetning" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Viser beskjed om å delta i oversettjinga igjen." #: qt/app.py:572 #, fuzzy msgid "Encryption Transition (EncFS)" msgstr "Kryptert transisjon (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Vis melding om fjerning av EncFS igjen." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Før tilbake" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Gjenopprett valde filer og mapper til opphavleg stad." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Før tilbake til …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Gjenopprett valde filer og mapper til ein ny stad." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "Gjenopprett den viste mappa med alt innhald til opphavleg stad." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Gjenopprett den viste mappa og alt innhald til ein ny stad." #: qt/app.py:601 msgid "Up" msgstr "Opp" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Vis gøymde filer" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Jamstill augneblinksbilete…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "sleppkandidat" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Viser melding om sleppkandidat igjen." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Sikkerheitskopier" #: qt/app.py:692 msgid "&Restore" msgstr "Før &tilbake" #: qt/app.py:698 msgid "&Help" msgstr "&Hjelp" #: qt/app.py:743 msgid "Icons only" msgstr "Kun ikon" #: qt/app.py:746 msgid "Text only" msgstr "Kun tekst" #: qt/app.py:749 msgid "Text below icons" msgstr "Tekst under ikon" #: qt/app.py:752 msgid "Text beside icon" msgstr "Tekst ved sidan av ikon" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Om du lukkar vindauget vil ikkje Back In Time kunne skru av maskina di når " "augeblinksbiletet er ferdig." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Vil du verkeleg lukke dette?" #: qt/app.py:1072 msgid "Working:" msgstr "Arbeider:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Ferdig, trong ikkje tryggleikskopiera" #: qt/app.py:1129 msgid "Working" msgstr "Arbeider" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Feil" #: qt/app.py:1161 msgid "Sent" msgstr "Sendt" #: qt/app.py:1162 msgid "Speed" msgstr "Hastigheit" #: qt/app.py:1163 msgid "ETA" msgstr "Forventa avslutta" #: qt/app.py:1225 msgid "Global" msgstr "Globalt" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Heim" #: qt/app.py:1255 msgid "Backup directories" msgstr "Sikkerheitskopieringsmapper" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Biletnamn" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Vil du verkeleg fjerna dette augneblinksbiletet?" msgstr[1] "Vil du verkeleg fjerna desse augneblinksbileta?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Sikkerheitskopier med {suffix} lagt til på slutten\n" "før overskriving eller fjerning av lokale element." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Nyare versjonar av filene vil verte omdøypte med etterfølgjande {suffix} før" " gjenoppretting. Om du ikkje treng dei meir kan du slette dei med følgjande " "kommando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Berre gjennopprett element som ikkje eksisterer eller\n" "er nyare enn dei som er i destinasjonen.\n" "Ved å bruka rsync --update opsjon." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Fjern nyare element i kjeldemappe." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Gjennopprett valde filer eller mapper til kjeldedestinasjon og slett filer " "og mapper som ikkje er i augneblinksbiletet. Ver varsam; dette vil slette " "filer og mapper som var eksluderte i augneblinksbiltetet." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Vil du verkeleg gjennoppretta dette elementet inn i den nye mappa {path}?" msgstr[1] "" "Vil du verkeleg gjennopprette desse elementa inn i den nye mappa {path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Vil du verkeleg gjennoppretta dette elementet?" msgstr[1] "Vil du verkeleg gjennoppretta desse elementa?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Er du sikker du vil fjerna alle nye filer i {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Er du sikker på at du vil fjerna alle nyare filer i den originale mappa?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Åtvaring{BOLDEND}: Sletting av filer i rota av filsystemet kan " "øydeleggje heile systemet ditt." #: qt/app.py:1857 msgid "Snapshot" msgstr "snapshot" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Gjennoppretta {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Gjennopprett {path} til …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hei\n" "Du har bruka Back In Time på {language} nokre gonger no.\n" "Utgåva du har no er {perc} sett om til {language}. Same kor mykje teknisk kunnskap du har, kan du vera med på å setja om og dimed òg hjelpa Back In Time.\n" "Gå til {translation_platform_url} om du til vera med på dette. Sjå {back_in_time_project_website} for opplysing og spørsmål.\n" "Me orsakar avbrotet og kjem ikkje til å syna denne førespurnaden att. Dette vindauget finn du når som helst frå hjelp-menyen.\n" "Helsing laget for Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "Oversetjingsplattform" #: qt/app.py:2076 msgid "Website" msgstr "Nettstad" #: qt/app.py:2090 msgid "Your translation" msgstr "Di oversetjing" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "I fødiverset på Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-post til {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "E-postliste {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} på prosjektet si nettside." #: qt/app.py:2118 msgid "Open an issue" msgstr "Rapporter eit problem" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativt kan du bruke ein anna valfri kanal." #: qt/app.py:2124 #, fuzzy, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Denne versjonen av Back in Time er ein kandidat for publisering. Den er primært tenkt for testing før neste offisielle versjon.\n" "Ingen brukardata eller loggar vert samla inn, men Back In Time-laget er veldig interesserte i om slike kandidatar vert nytta, og om det er verdt å fortsettje med dei. Difor ber vi om ei kort tilbakemelding på om du testar denne versjonen, sjølv om du ikkje opplever problem. Sjølv enkle testar på eit par minutt hjelper oss mykje.\n" "Følgjande kontaktmogelegheiter finst:\n" "{contact_list}\n" "Denne beskjeden vil ikkje verte vist igjen i denne versjonen, men finst tilgjengeleg i hjelpe-menyen.\n" "Helsing oss bak Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Språk instillingane vert aktivert etter omstart av Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Oppretting av EncFS-profilar vil verte fjerna i neste utgåve (1.7), planlagt" " for 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Det er ikkje anbefalt å bruke den moden for profilar lengre." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "rapporten" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Støtta for EncFS vert fjerna på grunn av tryggleiksproblem." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "For meir detaljar, inkludert mogelege alternativ, sjå denne {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Følgjande profil(ar) nyttar kryptering med EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Ei erstatning er planlagd, men det kan ikkje garanterast at den er klar i " "tide." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Brukarar er velkomne til å ta del i diskusjonen. Oppdaterte detaljar om dei " "neste stega er tilgjengelege i denne {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Denne meldinga vil ikkje verte vist igjen. Den er tilgjengeleg når som helst" " i hjelpe-menyen." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Back In Time-laget" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Oppsettspråk" #: qt/languagedialog.py:97 msgid "System default" msgstr "System standard" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Bruk operativsystemets språk." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Omsett: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Visning av siste logg" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visning av snapshot logg" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Augneblinksbilete:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alle" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Endringar" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Feil" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Informasjon" msgstr[1] "Informasjon" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync overføringsfeil (eksperimentell)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Feil, [I] Informasjon, [C] Endring" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "Dekoder stiar" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Handter profilar" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Endra" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Legg til" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Fjern" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Generell" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkluder" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Inkluder filer og mapper" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Legg til fil" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Legg til mappe" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Ekskluder" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Ekskluder mønster, filer eller mapper" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Legg til default" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Ekskluder filer større enn:" #: qt/manageprofiles/__init__.py:233 #, fuzzy, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Ekskluder filer større enn: " #: qt/manageprofiles/__init__.py:235 #, fuzzy msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Ekskluder filer høgare enn verdien %(prefix)s.\n" "Med 'full rsync modus' avslått vil kun nye filer bli handsama\n" "fordi rsync handterer dette som eit overførings val, ikkje ei ekskludering.\n" "Så store filer som har blitt tatt backup av før blir i snapshot\n" "sjølv om dei har blitt endra." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opsjonar" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "E&kspert val" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Gjennopprett konfigurasjon" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Rediger user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Ny profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Gje profilen nytt namn" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Vil du verkeleg sletta profilen \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "Sterkt tilrådd" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Ekskluder mønster" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Ekskluder fil" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Ekskluder mappe" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkluder fil" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" er ein symlink. Det lenka målet vil ikkje bli tatt backup av med mindre du inkluderer det og.\n" "Har du lyst til å inkludera symlinkmålet i staden?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Inkluder mappe" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Timeplan" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Vekedag:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Timar:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Køyr Back In Time så kjapt som mogleg når eininga vert kopla til (berre ein gong kvar X dag(ar)).\n" "Du vil bli avkrevd ditt sudo passord." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Repeter køyring av Back In Time. Dette er nyttig viss datamaskina ikkje " "køyrer regelmessig." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Kvar:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Slått av" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Ved kvar start/omstart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Kvart {n}. minutt" msgstr[1] "Kvart {n}. minutt" #: qt/manageprofiles/schedulewidget.py:150 #, fuzzy, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Kvar time" msgstr[1] "Kvar time" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Kvar {n}. time" msgstr[1] "Kvar {n}. time" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Eigendefinert tidsplan" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Kvar dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetert (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Når eining vert tilkopla (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Kvar veka" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Kvar månad" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Kvart år" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Time(-ar)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(ar)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Veke(r)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Månad(ar)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Eigendefinerte timar kan berre vera ei kommaseparert lista med timar (t.d. " "8,12,18,23) eller */3 for periodisk backup kvar 3. time." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Vert:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Brukar:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Spørsmål" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Køyr 'rsync' med '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "Som cron jobb" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "på fjern vert" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "Medan eit manuelt snapshot vert tatt" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Ver gild å installer 'nocache' for å aktivera dette valet)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "På lokal maskin" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Omdiriger stdout til /dev/null i kronjobbar." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Omdiriger stderr til /dev/null i kronjobbar." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 #, fuzzy msgid "Limit rsync bandwidth usage:" msgstr "Avgrensa rsync båndbreddebruk" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Hald på ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Hald på utvida attributtar (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopier utrygge lenkjer (verkar berre ved direkte lenkjer" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Valet må vera sitert t.d. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Lim inn ytterlegare val til rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variablar må ha kontrollsekvensen \\$FOO. Dette påverkar ikkje rsync. For å " "legge til prefiks for rsync, bruk \"{example_value}\" med " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standardverdi" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Legg til prefiks til ssh kommandoer" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Sjekk om nettverksvert er på nettet" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Åtvaring: dersom deaktivert og nettverksverten ikkje er tilgjengeleg kan det" " føre til rare feil." #: qt/manageprofiles/tab_expert_options.py:341 #, fuzzy msgid "Check if remote host supports all necessary commands." msgstr "Sjekk om nettverksvert støttar alle naudsynte kommandoar" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Åtvaring: Om avskrudd og nettverksverten ikkje støttar alle påkrevde " "kommandoar kan dette føre til rare feil." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(standardverdi: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "deaktivert" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "aktivert" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modus:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kvar vil du lagra snapshot" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH innstillingar" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Sti:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Chiffer:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privat lykjel:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Vel ei eksisterande privatnykelfil (normalt namngitt \"id_ed25519\" eller " "\"id_rsa\" i eldre oppsett)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Lag ein ny SSH-nykel utan passord (ikkje tillete om ei privatnykelfil " "allereie er vald)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Passord" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Lagra passord til lykjelring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Cache passord for Cron (Tryggleiksproblem: root kan lesa passord)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avansert" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Full sti til augneblinksbilete:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Du valde ikkje privatnykelfil for SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Har du lyst til å lage eit nytt offentleg/privat nykelpar?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privatlykkjelfil \"{file}\" eksisterer ikkje." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Har du lyst til å kopiera din offentlege SSH lykjel til nettverksverten for " "å aktivere passordlaus pålogging?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autentiseringa av verten {host} er ikkje mogleg." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype}-nykelen sitt fingeravtrykk er:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verifiser dette fingeravtrykket. Vil du legge det til di 'known_hosts' fil?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Vil du verkeleg endra augneblinksbilete-mappa?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Ny SSH lykjel i {path} kunne ikkje lagast" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Aktiver notifikasjonar" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Deaktiver snapshot når batteri er i bruk" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Straumstatus ikkje tilgjengeleg frå systemet" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Køyr kun eit snapshot i slengen" #: qt/manageprofiles/tab_options.py:53 #, fuzzy msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andre snapshot blir blokkerte intil der aktive snapshot er ferdig\n" "Dette er eit globalt val. Så det vil påverka alle profilar for denne brukaren.\n" "Du må aktivera dette for alle andre brukarar og." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Backup endrar filer under gjennoppretting" #: qt/manageprofiles/tab_options.py:64 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Nyare versjonar av filene vil verte omdøypte med etterfølgjande {suffix} før gjenoppretting.\n" "Om du ikkje treng dei meir kan du slette dei med {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Fortsett ved feil (hald på ufullstendige snapshot)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Bruk sjekksum for å oppdaga endringar" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ta eit nytt snapshot uansett om det har vore endringar eller ei." #: qt/manageprofiles/tab_options.py:90 #, fuzzy msgid "Log Level:" msgstr "Loggnivå" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ingen" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Ikkje fjern namngitte snapshot." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Ikkje fjern namngitte snapshot." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "År" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Fjern augneblinksbilete" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Kalenderveker med mondag som fyrste dag. Gjeldande veke er ignorert." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12-månaders periode. Gjeldande månad er ignorert." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Tilbakehaldsretningslinje" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Køyr i bakgrunnen på nettverksvert." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Smart fjerning vil køyre på nettverkstenaren, ikkje lokalt. Kommandoane " "\"bash\", \"screen\" og \"flock\" må vere installerte og tilgjengeleg på " "nettverkstenaren." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Om valt vil Back In Time fyrst teste nettverkstenaren." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dagane er talde frå og med i dag." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Hald på snapshots dei siste" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dag(ar)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Hald på eit augneblinksbilete per dag for dei siste" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "Vekene er talde frå og med denne veka. Ei veke startar på måndag." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Hald på eit augneblinksbilete per veka for dei siste" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Veke(r)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Månedane er talde som kalendermånader frå og med inneverande månad." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Hald på eit augneblinksbilete per månad for dei siste" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "Månad(ar)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Hald på snapshots dei siste" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Viss ledig plass er mindre enn" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Viss ledige inodes er mindre enn" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Fjern gamle augneblinksbilete" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Spørsmål" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Sjå siste logg" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Start {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Arbeider…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Sendt:" #: qt/qtsystrayicon.py:198 #, fuzzy msgid "Speed:" msgstr "Hastigheit" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Augneblinksbilete" #: qt/qttools.py:506 msgid "Today" msgstr "I dag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "I går" #: qt/qttools.py:522 msgid "This week" msgstr "Denne veka" #: qt/qttools.py:529 msgid "Last week" msgstr "Førre veke" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Dette er IKKJE eit snapshot, det er ei notids visning av dine lokale filer" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Sist sjekka {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Ingen konfigurasjon funne" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Dersom mappa er på ein ekstern eller fjerntilkopla disk, må den monterast " "manuelt først." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Vis full logg" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Val om å samanlikna snapshot" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Kommando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametrar:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Bruk %1 og %2 for sti parametrar" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Sett ein diff-kommando eller trykk avbryt." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Berre forskjellige snapshot" #: qt/snapshotsdialog.py:134 #, fuzzy msgid "List only snapshots that are equal to:" msgstr "List opp like snapshot til: " #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Djupsjekk (Meir eksakt, men treigare)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Slett" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Vel alle" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Samanlikna" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gå til" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Alternativa" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Du kan ikkje samanlikna eit snapshot med seg sjølv." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Vil du verkeleg sletta {file} i dette snapshot{snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Vil du verkeleg sletta {file} i {count} snapshot?" #: qt/snapshotsdialog.py:406 #, fuzzy msgid "WARNING: This cannot be revoked." msgstr "Dette kan ikkje gjerast om!" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Ekskluder {path} frå nye snapshot?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Du kan ikkje inkludere undermapper av sikkerheitskopierings-mappa." backintime-1.5.4/common/po/pl.po000066400000000000000000002015101477034762000165210ustar00rootroot00000000000000# Polish translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-06 14:37+0000\n" "Last-Translator: Merik \n" "Language-Team: Polish \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Ostrzeżenie" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profil główny" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalny (zaszyfrowane EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (zaszyfrowane EncFS)" #: common/config.py:278 msgid "Local" msgstr "Lokalny" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Klucz prywatny SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Zaszyfrowany lokalnie" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Szyfrowanie" #: common/config.py:289 msgid "SSH encrypted" msgstr "Zaszyfrowany SSH" #: common/config.py:296 msgid "Default" msgstr "Domyślny" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: „{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Katalog migawek jest nieprawidłowy." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" "Należy wybrać co najmniej jeden katalog do utworzenia kopii zapasowej." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Katalog: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Tego katalogu nie można uwzględnić w kopii zapasowej, ponieważ jest on " "częścią miejsca docelowego kopii zapasowej." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nie udało się zapisać nowej tablicy zadań (crontab)." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron nie działa pomimo dostępnego polecenia crontab. Zaplanowane zadania " "tworzenia kopii zapasowych nie będą działać. Cron może być zainstalowany, " "ale nie jest włączony. Wypróbuj polecenie „systemctl enable cron” lub " "uzyskaj pomoc na kanałach wsparcia dystrybucji GNU Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Nie udało się zainstalować reguły udev dla profilu {profile_id}. Usługa DBus" " „{dbus_interface}” nie była dostępna" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Harmonogram udev nie działa z trybem {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nie udało się odnaleźć UUID dla {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nie udało się zapisać konfiguracji" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nie udało się wczytać konfiguracji" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil „{name}” już istnieje." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Ostatniego profilu nie można usunąć." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nie można zamontować „{command}”" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Nie znaleziono konfiguracji dla zaszyfrowanego katalogu." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Czy stworzyć nowy zaszyfrowany katalog?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Anuluj" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Prosimy potwierdzić hasło." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Hasło nie pasuje." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Utwórz migawkę" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Nie można odmontować {mountprocess} z {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Nie znaleziono {command}. Zainstaluj to (np. poprzez „{installcommand}”)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Punkt montowania {mntpoint} nie jest pusty." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Wpisz hasło do profilu „{profile}” {mode}:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NIEPOWODZENIE" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Przywracanie uprawnień" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Gotowe" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Kopia zapasowa przełożona z powodu pracy na baterii" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Nie można znaleźć katalogu migawek." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Jeśli jest na dysku wymiennym, podłącz go." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Pozostała %s sekunda." msgstr[1] "Pozostały %s sekundy." msgstr[2] "Pozostało %s sekund." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Nie udało się wykonać migawki {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Prosimy o cierpliwość. Finalizowanie…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Nie można utworzyć katalogu." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Zapisywanie pliku konfiguracyjnego…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Zapisywanie uprawnień…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Znaleziono pozostała migawkę {snapshot_id}, która może być kontynuowana." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Usuwanie pozostałości katalogu {snapshot_id} z ostatniego wykonania" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Nie mogę usunąć katalogu" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Utwórz migawkę" #: common/snapshots.py:1430 msgid "Success" msgstr "Sukces" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transfer częściowy z powodu błędu" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transfer częściowy z powodu zaginionych plików źródłowych (patrz „man " "rsync”)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "„rsync” zakończył się kodem wyjścia {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Więcej informacji można znaleźć w „man rsync”" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negatywne kody wyjściowe rsync to liczby sygnałów, patrz „kill -l” i „man " "kill”" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nic się nie zmieniło, nie ma potrzeby tworzenia nowej migawki" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Nie można zmienić nazwy z {new_path} na {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Inteligentne usuwanie" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Zastosuj reguły, aby usunąć stare migawki" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Zastosuj zasady przechowywania" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Próba utrzymamia minimum wolnego miejsca" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Próba utrzymania minimum {perc} wolnych i-węzłów" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Teraz" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nie można zamontować {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "Nie znaleziono programu ssh-agent. Upewnij się, że jest zainstalowany." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nie można odblokować klucza prywatnego SSH. Hasło niewłaściwe lub " "niedostępne dla cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Szyfr {cipher} nie powiódł się dla {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Zdalna ścieżka istnieje, ale nie jest katalogiem." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Ścieżka zdalna nie jest zapisywalna." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Ścieżka zdalna nie jest wykonywalna." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nie można utworzyć zdalnej ścieżki." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Zdalny host {host} nie obsługuje {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Dalsze instrukcje znajdziesz w „man backintime”" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Polecenia sprawdzania na hoście {host} zwróciły nieznany błąd" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Zdalny host {host} nie obsługuje dowiązań twardych" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Skopiuj klucz publiczny SSH „{pubkey}” do zdalnego hosta „{host}”." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Wpisz hasło dla „{user}”." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Docelowy system plików dla {path} jest sformatowany za pomocą NTFS, w którym" " występują znane niezgodności z systemami plików w stylu uniksowym." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} nie jest prawidłowym katalogiem." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Utworzenie następującego katalogu nie powiodło się:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Dostęp do zapisu może być ograniczony." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Docelowy system plików dla {path} jest sformatowany za pomocą FAT, który nie" " wspiera dowiązań twardych. Użyj natywnego systemu plików GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Docelowy system plików dla {path} to udział zamontowany za pomocą SMB. " "Upewnij się, że zdalny serwer SMB wspiera dowiązania symboliczne lub aktywuj" " „{copyLinks}” w „{expertOptions}”." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiowanie dowiązań (odwołanie dowiązań symbolicznych)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opcje zaawansowane" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Docelowy system plików dla {path} to udział zamontowany za pomocą sshfs, " "który nie wspiera dowiązań twardych. Użyj trybu „SSH”." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Tworzenie pliku w tym katalogu nie powiodło się:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O programie" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autorzy" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Tłumaczenia" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licencja" #: qt/app.py:172 msgid "Shortcuts" msgstr "Skróty" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ten katalog nie istnieje\n" "w obecnie wybranej migawce." #: qt/app.py:257 msgid "Add to Include" msgstr "Dodaj do uwzględnionych" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Dodaj do wykluczonych" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Wygląda na to, że {app_name} działa po raz pierwszy, ponieważ nie znaleziono" " żadnej konfiguracji." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Zaimportować istniejącą konfigurację (z katalogu docelowego kopii zapasowej " "lub innego komputera)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Jeśli jest na dysku wymiennym, podłącz go, a następnie naciśnij OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Utwórz migawkę" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Użyj czasu i rozmiaru modyfikacji do wykrywania zmian w pliku." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Wykonaj migawkę (sprawdzanie sumy kontrolnej)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Używaj sum kontrolnych do wykrywania zmian plików." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Wstrzymaj wykonywanie migawki" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Wznów wykonywanie migawki" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Zakończ wykonywanie migawki" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Odśwież listę migawek" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nazwa migawki" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Usuń migawkę" #: qt/app.py:505 msgid "View snapshot log" msgstr "Zobacz dziennik migawki" #: qt/app.py:509 msgid "View last log" msgstr "Podgląd ostatniego dziennika" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Zarządzaj profilami…" #: qt/app.py:517 msgid "Shutdown" msgstr "Zamknięcie" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Zamknij system po wykonaniu migawki." #: qt/app.py:521 msgid "Setup language…" msgstr "Ustaw język…" #: qt/app.py:525 msgid "Exit" msgstr "Wyjście" #: qt/app.py:529 msgid "User manual" msgstr "Instrukcja obsługi" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Otwórz instrukcję obsługi w przeglądarce (lokalnie, jeśli jest dostępna, w " "przeciwnym razie online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man page: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Wyświetla man page dotyczącą Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man page: Plik konfiguracyjny profili" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Wyświetla man page dotyczącą pliku konfiguracyjnego profili (backintime-" "config)" #: qt/app.py:547 msgid "Project website" msgstr "Strona internetowa projektu" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Otwórz witrynę Back In Time w przeglądarce" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Lista zmian" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Otwórz często zadawane pytania (FAQ) w przeglądarce" #: qt/app.py:559 msgid "Ask a question" msgstr "Zadaj pytanie" #: qt/app.py:563 msgid "Report a bug" msgstr "Zgłoś błąd" #: qt/app.py:566 msgid "Translation" msgstr "Tłumaczenie" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Ponownie pokazuje komunikat o uczestnictwie w tłumaczeniu." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Przejście szyfrowania (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Ponownie pokazuje komunikat o usuwaniu EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Przywróć" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Przywróć wybrane pliki lub katalogi do pierwotnego miejsca docelowego." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Przywróć do…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Przywróć wybrane pliki lub katalogi do nowego miejsca docelowego." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Przywróć aktualnie wyświetlany katalog i całą jego zawartość do pierwotnego " "miejsca docelowego." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Przywróć aktualnie wyświetlany katalog i całą jego zawartość do nowego " "miejsca docelowego." #: qt/app.py:601 msgid "Up" msgstr "Do góry" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Pokaż ukryte pliki" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Porównaj migawki…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Wydanie kandydujące" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Wyświetla ponownie komunikat o wydaniu kandydującym." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Kopia zapasowa" #: qt/app.py:692 msgid "&Restore" msgstr "&Przywróć" #: qt/app.py:698 msgid "&Help" msgstr "P&omoc" #: qt/app.py:743 msgid "Icons only" msgstr "Tylko ikony" #: qt/app.py:746 msgid "Text only" msgstr "Tylko tekst" #: qt/app.py:749 msgid "Text below icons" msgstr "Tekst pod ikonami" #: qt/app.py:752 msgid "Text beside icon" msgstr "Tekst obok ikony" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Jeśli zamkniesz to okno, Back In Time nie będzie mógł zamknąć systemu po " "zakończeniu tworzenia migawki." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Czy naprawdę chcesz to zamknąć?" #: qt/app.py:1072 msgid "Working:" msgstr "Działanie:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Gotowe, archiwizacja niepotrzebna" #: qt/app.py:1129 msgid "Working" msgstr "Działanie" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Błąd" #: qt/app.py:1161 msgid "Sent" msgstr "Wysłane" #: qt/app.py:1162 msgid "Speed" msgstr "Prędkość" #: qt/app.py:1163 msgid "ETA" msgstr "Do końca" #: qt/app.py:1225 msgid "Global" msgstr "Globalne" #: qt/app.py:1226 msgid "Root" msgstr "Systemowy" #: qt/app.py:1227 msgid "Home" msgstr "Domowy" #: qt/app.py:1255 msgid "Backup directories" msgstr "Katalogi kopii zapasowej" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nazwa migawki" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Czy na pewno usunąć migawkę?" msgstr[1] "Czy na pewno usunąć migawki?" msgstr[2] "Czy na pewno usunąć migawki?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Utwórz kopie zapasowe z końcowym {suffix}\n" "przed nadpisaniem lub usunięciem elementów lokalnych." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Przed przywróceniem nazwy nowszych wersji plików zostaną zmienione " "z końcowym {suffix}. Jeśli już ich nie potrzebujesz, możesz je usunąć za " "pomocą następującego polecenia:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Przywróć tylko te elementy, które nie istnieją lub\n" "są nowsze niż te w miejscu docelowym.\n" "Korzystanie z opcji „rsync --update”." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Usuń nowsze elementy z pierwotnego katalogu." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Przywróć wybrane pliki lub katalogi do pierwotnego miejsca docelowego i usuń" " pliki lub katalogi, których nie ma w migawce. Zachowaj szczególną " "ostrożność, ponieważ spowoduje to usunięcie plików i katalogów wykluczonych " "podczas wykonywania migawki." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Czy na pewno chcesz przywrócić ten element do nowego katalogu?" msgstr[1] "Czy na pewno chcesz przywrócić te elementy do nowego katalogu?" msgstr[2] "Czy na pewno chcesz przywrócić te elementy do nowego katalogu?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Czy na pewno chcesz przywrócić ten element?" msgstr[1] "Czy na pewno chcesz przywrócić te elementy?" msgstr[2] "Czy na pewno chcesz przywrócić te elementy?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Czy na pewno chcesz usunąć wszystkie nowsze pliki z {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Czy na pewno chcesz usunąć wszystkie nowsze pliki z pierwotnego katalogu?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Ostrzeżenie{BOLDEND}: usunięcie plików z katalogu głównego systemu " "plików może spowodować uszkodzenie całego systemu." #: qt/app.py:1857 msgid "Snapshot" msgstr "Migawka" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Przywróć {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Przywróć {path} do…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Witaj!\n" "Back In Time w języku {language} został użyty już kilka razy.\n" "Tłumaczenie zainstalowanej wersji Back In Time na język {language} jest kompletne w {perc}. Możesz pomóc w ulepszeniu tłumaczeń, a poprzez to w ulepszaniu samego Back In Time bez posiadania żadnej wiedzy technicznej.\n" "Odwiedź {translation_platform_url}, jeśli chcesz pomóc. W celu uzyskania odpowiedzi na pytania lub dalszych wskazówek odwiedź {back_in_time_project_website}.\n" "Przepraszamy za utrudniania, ten komunikat nie pojawi się sam ponownie, ale będzie dostępny w menu pomocy.\n" "Zespół Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "platformę do tłumaczenia" #: qt/app.py:2076 msgid "Website" msgstr "Strona WWW" #: qt/app.py:2090 msgid "Your translation" msgstr "Twoje tłumaczenia" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "W Fediverse w Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-mail do {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Lista mailingowa {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} na stronie internetowej projektu." #: qt/app.py:2118 msgid "Open an issue" msgstr "Otwórz zagadnienie" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Możesz również użyć innego wybranego kanału." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Ta wersja Back In Time jest wydaniem kandydującym i jest przeznaczona głównie do testów stabilności w przygotowaniu do kolejnej oficjalnej wersji.\n" "Nie są gromadzone żadne dane użytkowników ani dane telemetryczne. Jednak zespół Back In Time jest bardzo zainteresowany tym, czy wydanie kandydujące jest używane i czy warto nadal udostępniać takie wersje przedpremierowe.\n" "Dlatego zespół uprzejmie prosi użytkowników o krótką opinię na temat tego, czy ta wersja była przez nich testowana, nawet jeśli nie napotkali żadnych problemów. Zaledwie krótki test trwający kilka minut bardzo by nam pomógł.\n" "Dostępne są następujące opcje kontaktu:\n" "{contact_list}\n" "W tej wersji ten komunikat nie zostanie ponownie wyświetlony, ale można uzyskać do niego dostęp w dowolnym momencie za pośrednictwem menu pomocy.\n" "Dziękujemy za wsparcie i pomoc w ulepszaniu Back In Time!\n" "Twój zespół Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Ustawienia języka zaczną obowiązywać dopiero po ponownym uruchomieniu " "programu Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Tworzenie profili EncFS zostanie usunięte w następnej wersji pomniejszej " "(1.7), zaplanowanej na 2026 rok." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Ponadto nie zaleca się używania tego trybu w profilu." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "białej księdze" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "Wsparcie dla systemu EncFS zostanie zakończone ze względu na luki w " "zabezpieczeniach." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Więcej szczegółów, w tym potencjalne zamienniki, można znaleźć w " "{whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Poniższe profile używają szyfrowania z EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Planowane jest zastępstwo, lecz nie można zagwarantować, że dotrze ono na " "czas." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Użytkownicy są zaproszeni do wzięcia udziału w dyskusji. Zaktualizowane " "szczegóły dotyczące kolejnych kroków są dostępne w {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ten komunikat nie zostanie wyświetlony ponownie. To okno dialogowe jest " "dostępne w dowolnym momencie za pośrednictwem menu pomocy." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Zespół Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Ustaw język" #: qt/languagedialog.py:97 msgid "System default" msgstr "Domyślne systemowe" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Użyj języka systemu operacyjnego." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Przetłumaczono: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Ostatni widok dziennika" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Widok dziennika migawki" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Migawki:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtr:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "wszystkie" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "zmiany" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "błędy" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informacja" msgstr[1] "Informacje" msgstr[2] "Informacji" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "błędy transferu rsync (eksperymentalne)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] błąd, [I] informacja, [C] zmiana" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekoduj ścieżki" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Zarządzaj profilami" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Edycja" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Dodaj" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Usuń" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Ogólne" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Dołącz" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Dołącz pliki i katalogi" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dodaj plik" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Dodaj katalog" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Wyklucz" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informacje{ENDBOLD}: w trybie „Zaszyfrowany SSH” działają tylko " "pojedyncze lub podwójne gwiazdki (np. {example2}). Inne typy symboli " "wieloznacznych i wzorców będą ignorowane (np. {example1}). W tym trybie " "nazwy plików są nieprzewidywalne ze względu na szyfrowanie przez EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Wyklucz wzorce, pliki lub katalogi" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Dodaj domyślne" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Wyklucz pliki większe niż:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Wyklucz pliki większe niż wartość w {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Po wyłączeniu „Pełnego trybu rsync” będzie to miało wpływ tylko na nowe " "pliki, ponieważ w przypadku rsync jest to opcja przesyłania, a nie opcja " "wykluczenia. Dlatego też duże pliki, których kopie zapasowe utworzono " "wcześniej, pozostaną w migawkach, nawet jeśli zostaną zmodyfikowane." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Usuń i &przechowuj" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Ustawienia" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Opcje e&ksportu" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Przywróć konfigurację" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Edytuj user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nowy profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Zmień nazwę profilu" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Na pewno chcesz usunąć profil „{name}”?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Wysoce zalecane{ENDBOLD}: (Wszystkie rekomendacje są już " "uwzględnione.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Wysoce zalecane{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Wzór wykluczenia" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Wyklucz plik" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Wyklucz katalog" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Dołącz plik" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„{path}” jest dowiązaniem symbolicznym. Kopia zapasowa połączonego celu nie zostanie utworzona, dopóki go również nie dołączysz.\n" "Czy zamiast tego chcesz dołączyć cel dowiązania symbolicznego?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Uwzględnij katalog" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Wyłączone, ponieważ ten wzorzec nie działa w trybie „Zaszyfrowany SSH”." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Harmonogram" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dzień:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Dzień powszedni:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Czas:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Godziny:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "po godzinie" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuty:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Uruchamiaj Back In Time zaraz po podłączeniu napędu (tylko raz na X dni). " "Zostanie wyświetlony monit o podanie hasła sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Uruchamiaj Back In Time wielokrotnie. Jest to przydatne, jeśli komputer nie " "działa regularnie." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Co:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Włącz rejestrowanie komunikatów debugowania" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Zapisuje komunikaty poziomu debugowania w dzienniku systemowym poprzez " "„--debug”." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Uwaga: używaj tego tylko tymczasowo do diagnostyki, ponieważ generuje to " "dużą ilość danych wyjściowych." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Nieaktywny" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Przy każdym uruchomieniu / restarcie" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Co {n} minutę" msgstr[1] "Co {n} minuty" msgstr[2] "Co {n} minut" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Co godzinę" msgstr[1] "Co {n} godziny" msgstr[2] "Co {n} godzin" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Co {n} godzinę" msgstr[1] "Co {n} godziny" msgstr[2] "Co {n} godzin" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Własny harmonogram" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Codziennie" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Wielokrotnie (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Po podłączeniu dysku (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Co tydzień" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Co miesiąc" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Co rok" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "godzin" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "dni" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "tygodni" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "miesięcy" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Godziny niestandardowe mogą być jedynie listą godzin oddzielonych " "przecinkami (np. 8,12,18,23) lub */3 w przypadku okresowych kopii zapasowych" " co 3 godziny." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Serwer proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Użytkownik:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Połącz się z hostem docelowym za pośrednictwem tego serwera proxy (znanego " "również jako host przeskoku). Aby uzyskać szczegółowe informacje, zobacz " "„-J” w dokumentacji polecenia „ssh” lub „ProxyJump” na stronie podręcznika " "„ssh_config”." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Uwaga:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Te opcje są przeznaczone do zaawansowanych konfiguracji. Modyfikuj tylko " "wtedy, gdy masz pełną świadomość ich konsekwencji." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Uruchamiaj „rsync” z „{cmd}”:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "jako zadanie crona" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "na zdalnym hoście" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "podczas wykonywania ręcznej migawki" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Zainstaluj „nocache”, aby włączyć tę opcję." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na lokalnej maszynie" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Przekieruj stdout z zadań crona do /dev/null." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron automatycznie wyśle wiadomość e-mail z załączonymi wynikami zadań cron," " jeśli jest zainstalowany MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Przekieruj stderr z zadań crona do /dev/null." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron automatycznie wyśle wiadomość e-mail z załączonymi błędami zadań cron, " "jeśli jest zainstalowany MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Ograniczenie przepustowości rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Zachowaj ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Zachowaj rozszerzone atrybuty (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Kopiowanie niebezpiecznych dowiązań (działa tylko z dowiązaniami " "bezwzględnymi)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Ogranicz do jednego systemu plików" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opcje muszą być ujęte w cudzysłów, np. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Dodatkowe opcje dla rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefiks uruchamiany przed każdym poleceniem na zdalnym hoście." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Zmienne wymagają ucieczki za pomocą \\$FOO. Nie dotyczy to rsync. Aby dodać " "przedrostek dla rsync, użyj „{example_value}” z {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "domyślnie" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Dodaj prefiks do poleceń SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Sprawdź, czy zdalny host jest dostępny" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Ostrzeżenie: jeśli opcja jest wyłączona, a zdalny host nie jest dostępny, " "może to prowadzić do dziwnych błędów." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Sprawdź, czy zdalny host obsługuje wszystkie niezbędne polecenia." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Ostrzeżenie: jeśli opcja jest wyłączona, a zdalny host nie obsługuje " "wszystkich niezbędnych poleceń, może to prowadzić do dziwnych błędów." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(domyślnie: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "wyłączone" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "włączone" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Tryb:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Gdzie zapisać migawki" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Ustawienia SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Ścieżka:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Szyfr:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Klucz prywatny:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Wybierz istniejący plik klucza prywatnego (zwykle o nazwie „id_ed25519”, " "a w starszych konfiguracjach „id_rsa”)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Utwórz nowy klucz SSH bez hasła (niedozwolone, jeśli plik klucza prywatnego " "jest już wybrany)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Hasło" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Zapisz hasło w portfelu" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Hasło pamięci podręcznej dla cron (problem bezpieczeństwa: root może " "odczytać hasło)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Zaawansowane" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Pełna ścieżka migawki:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Nie wybrano pliku klucza prywatnego dla SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Czy chcesz wygenerować nową parę kluczy publiczny/prywatny bez hasła?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Plik klucza prywatnego „{file}” nie istnieje." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Czy chcesz skopiować swój publiczny klucz SSH na zdalny host, aby umożliwić " "logowanie bez hasła?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Nie można ustalić autentyczności hosta {host}." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Odcisk palca klucza {keytype} to:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Zweryfikuj ten odcisk palca. Czy chcesz dodać go do swojego pliku " "„known_hosts”?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Czy na pewno chcesz zmienić katalog migawek?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Nie udało się utworzyć nowego klucza SSH w {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Włącz powiadomienia" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Wyłącz migawki podczas zasilania z baterii" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Status zasilania niedostępny w systemie" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Uruchamiaj tylko jedną migawkę na raz" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Inne migawki zostaną zablokowane do czasu wykonania bieżącej migawki. Jest " "to opcja globalna, więc będzie miała wpływ na wszystkie profile tego " "użytkownika. Ale musisz aktywować tę opcję także dla wszystkich innych " "użytkowników." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Kopia zapasowa zastąpionych plików podczas przywracania" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Przed przywróceniem nazwy nowszych wersji plików zostaną zmienione " "z końcowym {suffix}. Jeśli już ich nie potrzebujesz, możesz je usunąć za " "pomocą {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Kontynuuj przy błędach (pozwól na niekompletne migawki)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Używaj sum kontrolnych do wykrywania zmian" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" "Zrób nową migawkę, niezależnie od tego, czy nastąpiły zmiany, czy nie." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Poziom dziennika:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Brak" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Następujące reguły są przetwarzane od góry do dołu. Późniejsze reguły " "zastępują wcześniejsze i nie są przez nie ograniczone. Zobacz {manual}, aby " "uzyskać szczegóły i przykłady." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "instrukcja obsługi" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Otwórz instrukcję obsługi w przeglądarce." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Zachowaj najnowszą migawkę." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "W każdych okolicznościach zachowywana jest ostatnia i najświeższa migawka." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Tego zachowania nie da się zmienić." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Zachowaj nazwane migawki." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Migawki, którym oprócz zwykłego znacznika czasu nadano nazwę, będą " "przechowywane w każdych okolicznościach i nie zostaną usunięte." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "lat" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Usuń migawki starsze niż" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Pełne dni. Bieżący dzień jest ignorowany." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Tygodnie kalendarzowe z poniedziałkiem jako pierwszym dniem. Bieżący tydzień" " jest ignorowany." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Okresy 12 miesięcy. Bieżący miesiąc jest ignorowany." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Polityka przechowywania" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Uruchom w tle na zdalnym hoście." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Procedura inteligentnego usuwania zostanie uruchomiona bezpośrednio na " "komputerze zdalnym, a nie lokalnie. Polecenia „bash”, „screen” i „flock” " "muszą być zainstalowane i dostępne na maszynie zdalnej." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Jeśli opcja jest zaznaczona, Back In Time najpierw przetestuje komputer " "zdalny." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dni liczone są od dzisiaj." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Zachowaj wszystkie migawki na koniec" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dzień/dni." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Zachowaj ostatnią migawkę każdego dnia jako ostatnią" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Tygodnie są liczone od bieżącego tygodnia. Tydzień zaczyna się w " "poniedziałek." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Zachowaj ostatnią migawkę z każdego tygodnia jako ostatnią" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "tygodni(e)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Miesiące liczone są jako miesiące kalendarzowe, począwszy od miesiąca " "bieżącego." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Zachowaj ostatnią migawkę dla każdego miesiąca jako ostatnią" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "miesiąc/miesięcy." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Lata liczone są jako lata kalendarzowe, począwszy od roku bieżącego." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Zachowaj ostatnią migawkę z każdego roku" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "wszystkie lata." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "…wolnej przestrzeni jest mniej niż" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "…wolnych i-węzłów jest mniej niż" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Usuń najstarsze migawki, jeśli…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pytanie" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Podgląd ostatniego dziennika" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Uruchom {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Działanie…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Wysłane:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Prędkość:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Czas do końca:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Migawki" #: qt/qttools.py:506 msgid "Today" msgstr "Dziś" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Wczoraj" #: qt/qttools.py:522 msgid "This week" msgstr "Ten tydzień" #: qt/qttools.py:529 msgid "Last week" msgstr "Poprzedni tydzień" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "To NIE jest migawka, ale podgląd na żywo lokalnych plików" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Ostatnie sprawdzenie {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importuj konfigurację" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nie znaleziono konfiguracji" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importuj" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Wybierz katalog migawek, z którego ma zostać zaimportowany plik " "konfiguracyjny. Ścieżka może wyglądać następująco: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Jeśli katalog znajduje się na dysku zewnętrznym lub zdalnym, należy go " "wcześniej zamontować ręcznie." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Pokaż pełny dziennik" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opcje porównywania migawek" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Polecenie:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametry:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Użyj %1 i %2 dla ścieżki parametrów" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Ustaw polecenie diff lub naciśnij przycisk Anuluj." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "W tym systemie nie można znaleźć polecenia „{cmd}”. Spróbuj czegoś innego " "lub naciśnij Anuluj." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Dla polecenia diff nie ustawiono żadnych parametrów. Używanie wartości " "domyślnej „{params}”." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Tylko migawki różniące się" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Wyświetlaj tylko migawki równe:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Szczegółowa analiza (dokładniejsza, ale bardziej czasochłonna)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Usuń" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Wybierz wszystko" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Porównaj" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Idź do" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcje" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nie możesz porównywać migawki samej ze sobą." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Czy na pewno chcesz usunąć {file} w migawce {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Czy na pewno chcesz usunąć {file} z {count} migawek?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "OSTRZEŻENIE: nie można tego cofnąć." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Wykluczyć {path} z przyszłych migawek?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Podkatalogi nie mogą zostać uwzględnione w kopii zapasowej." backintime-1.5.4/common/po/pt.po000066400000000000000000002005201477034762000165310ustar00rootroot00000000000000# Portuguese translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-17 15:14+0000\n" "Last-Translator: buhtz \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Aviso" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Perfil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Encriptado localmente (EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH encriptado com EncFS" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Chave privada SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Encriptado localmente" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Encriptação" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH encriptado" #: common/config.py:296 msgid "Default" msgstr "Padrão" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Perfil: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "A pasta de snapshots não é válida!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Diretório: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Este diretório não pode ser incluído no backup pois faz parte do próprio " "destino do backup." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Não foi possível escrever o novo crontab." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "O Cron não está a ser executado apesar do comando crontab estar disponível. " "As tarefas de cópia de segurança agendadas não serão executadas. O Cron pode" " estar instalado, mas não ativado. Experimente o comando “systemctl enable " "cron” ou consulte os canais de suporte da sua distribuição GNU Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Não foi possível instalar a regra Udev para o perfil {profile_id}. O serviço" " DBus '{dbus_interface}' não estava disponível" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "O agendamento do udev não funciona com o modo {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Não foi possível encontrar o UUID para {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Não foi possível guardar a configuração" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Não foi possível carregar a configuração" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "O perfil \"{name}\" já existe." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "O último perfil não pode ser removido." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Não é possível montar '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Configuração para pasta encriptada não encontrada." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Criar uma nova pasta encriptada?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Cancelar" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Por favor, confirme a palavra-passe." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "A palavra-passe não coincide." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Tirar snapshot" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Não é possível desmontar {mountprocess} de {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} não encontrado. Por favor, instale-o (por exemplo, " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Ponto de montagem {mntpoint} não está vazio." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Colocar a password do perfil {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FALHOU" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaurar permissões" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Concluído" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Adiando a cópia de segurança enquanto a bateria está em uso" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Não é possível encontrar a pasta dos snapshots." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Se estiver numa unidade removível, por favor, ligue-a e depois pressione OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "A aguardar %s segundo." msgstr[1] "A aguardar %s segundos." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Falha ao tirar snapshot {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Por favor aguarde. Finalizando…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Não é possível criar a pasta." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "A guardar o ficheiro de configuração…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "A guardar permissões…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Encontrado snapshot pendente {snapshot_id} que pode ser continuado." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "A remover a pasta pendente {snapshot_id} da última execução" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Não é possível remover a pasta" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "A tirar snapshot" #: common/snapshots.py:1430 msgid "Success" msgstr "Sucesso" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transferência parcial devido a erro" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferência parcial devido a ficheiros de origem desaparecidos (consulte " "'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' terminou com o código de saída {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Consulte 'man rsync' para mais detalhes" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Códigos de saída negativos do rsync são números de sinais, consulte 'kill " "-l' e 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nada foi alterado, não é necessário um novo snapshot" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Não é possível renomear {new_path} para {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Remoção inteligente" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "A remover snapshots antigos" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "A tentar manter o espaço livre mínimo" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Tentando manter um mínimo de {perc} inodes livres" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Agora" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Não é possível montar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "\"ssh-agent\" não encontrado. Por favor, certifique-se de que está " "instalado." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Não foi possível desbloquear a chave privada SSH. Senha incorreta ou senha " "não disponível para cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cifra {cipher} falhou para {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "O caminho remoto existe mas não é um diretório." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "O caminho remoto não é gravável." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "O caminho remoto não é executável." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Não foi possível criar o caminho remoto." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "O host remoto {host} não suporta {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Consulte 'man backintime' para obter mais instruções" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Os comandos de verificação no host {host} retornaram um erro desconhecido" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "O host remoto {host} não suporta hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copiar a chave pública SSH \"{pubkey}\" para o host remoto \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Por favor, introduza a senha de\"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "O sistema de arquivos de destino para {path} está formatado com NTFS, que " "possui incompatibilidades conhecidas com o sistema de arquivos Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} não é um diretório válido." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "A criação do seguinte diretório falhou:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "A permissão de escrita pode estar restrita." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "O sistema de arquivos de destino para {path} está formatado com FAT, que não" " suporta hard-links. Por favor, utilize um sistema de arquivos nativo do " "Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "O caminho de arquivos de destino para {path} é uma partilha montada por SMB." " Certifique-se de que o servidor SMB remoto suporta links simbólicos ou " "ative {copyLinks} em {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copiar links (desreferenciar links simbólicos)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opções Avançadas" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "O sistema de ficheiros de destino para {path} é uma partilha montada por " "sshfs. O sshfs não suporta hard-links. Por favor, utilize o modo 'SSH'." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "A criação de arquivo falhou na pasta:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Sobre" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autores" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traduções" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licença" #: qt/app.py:172 msgid "Shortcuts" msgstr "Atalhos" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Esta pasta não existe\n" "no snapshot selecionado atualmente." #: qt/app.py:257 msgid "Add to Include" msgstr "Adicionar à Inclusão" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Adicionar à Exclusão" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} parece estar rodando pela primeira vez uma vez que não foi " "encontrada nenhuma configuração." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importar uma configuração existente (de um destino de backup ou outro " "computador)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Se estiver numa unidade removível, por favor, ligue-a e depois pressione OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Tirar uma snapshot" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Utilizar o tempo de modificação e o tamanho para deteção de alterações nos " "ficheiros." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Tirar uma snapshot (modo de verificação de checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Utilizar checksums para deteção de alterações nos arquivos." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausar o processo de snapshot" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Continuar o processo de snapshot" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Parar o processo de snapshot" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Atualizar lista de snapshots" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nomear snapshot" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Remover snapshot" #: qt/app.py:505 msgid "View snapshot log" msgstr "Ver registo do snapshot" #: qt/app.py:509 msgid "View last log" msgstr "Ver último registro" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gerenciar perfis…" #: qt/app.py:517 msgid "Shutdown" msgstr "Desligar" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Desligar o sistema após a conclusão do snapshot." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurar idioma…" #: qt/app.py:525 msgid "Exit" msgstr "Sair" #: qt/app.py:529 msgid "User manual" msgstr "Manual do Usuário" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Abrir o manual do usuário no navegador (local se disponível senão online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Manual: Voltando no tempo" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Exibe o manual sobre Voltar no Tempo (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "Manual: Arquivo de configuração de perfis" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "Exibe o manual de configuração de perfis (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Página do projeto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Abrir no navegador a página De Volta No Tempo" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Registo de alterações" #: qt/app.py:555 msgid "FAQ" msgstr "Perguntas frequentes" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Abrir as Perguntas Frequentes (FAQ) no navegador" #: qt/app.py:559 msgid "Ask a question" msgstr "Fazer uma pergunta" #: qt/app.py:563 msgid "Report a bug" msgstr "Reportar um erro" #: qt/app.py:566 msgid "Translation" msgstr "Tradução" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Mostra a mensagem sobre participação nas traduções novamente." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transição Encriptada (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Mostra a mensagem sobre a remoção EncFS novamente." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurar" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Restaurar os arquivos ou pastas selecionados para o destino original." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurar para …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Restaurar os arquivos ou pastas selecionados para um novo destino." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaurar a pasta atualmente exibida e todo o seu conteúdo para o destino " "original." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaurar a pasta atualmente exibida e todo o seu conteúdo para um novo " "destino." #: qt/app.py:601 msgid "Up" msgstr "Cima" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Mostrar arquivos ocultos" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Comparar capturas…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Candidato a Lançamento" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Mostra a mensagem sobre o Candidato a Lançamento novamente." #: qt/app.py:676 msgid "Back In &Time" msgstr "De Volta No &Tempo" #: qt/app.py:681 msgid "&Backup" msgstr "&Cópia de Segurança" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurar" #: qt/app.py:698 msgid "&Help" msgstr "&Ajuda" #: qt/app.py:743 msgid "Icons only" msgstr "Somente ícones" #: qt/app.py:746 msgid "Text only" msgstr "Somente texto" #: qt/app.py:749 msgid "Text below icons" msgstr "Texto abaixo dos ícones" #: qt/app.py:752 msgid "Text beside icon" msgstr "Texto ao lado do ícone" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Se fechar esta janela, o Back In Time não conseguirá desligar o seu sistema " "quando a captura estiver concluída." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Tem a certeza de que deseja fechar?" #: qt/app.py:1072 msgid "Working:" msgstr "Trabalhando:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Concluído, sem necessidade de cópia de segurança" #: qt/app.py:1129 msgid "Working" msgstr "Trabalhando" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Erro" #: qt/app.py:1161 msgid "Sent" msgstr "Enviado" #: qt/app.py:1162 msgid "Speed" msgstr "Velocidade" #: qt/app.py:1163 msgid "ETA" msgstr "ETA (tempo estimado)" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Raiz" #: qt/app.py:1227 msgid "Home" msgstr "Pasta Pessoal" #: qt/app.py:1255 msgid "Backup directories" msgstr "Diretórios de Cópia de Segurança" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nome da Captura" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Você tem certeza de que deseja remover esta captura?" msgstr[1] "Você tem certeza de que deseja remover estas capturas?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Criar cópias de segurança com sufixo {suffix}\n" "antes de substituir ou remover elementos locais." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "As versões mais recentes dos arquivos serão renomeadas com o sufixo {suffix}" " antes de serem restauradas. Se você não precisa delas, pode removê-las com " "o seguinte comando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Apenas restaurar elementos que não existem ou\n" "são mais recentes do que os existentes no destino.\n" "Utilizando a opção \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Remover elementos mais recentes na pasta original." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaurar os arquivos ou pastas selecionados para o destino original e " "apagar os arquivos ou pastas que não estão na captura. Tenha extremo " "cuidado, pois isto irá apagar arquivos e pastas que foram excluídos durante " "a criação da captura." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Você tem certeza de que deseja restaurar este elemento na nova pasta?" msgstr[1] "" "Você tem certeza de que deseja restaurar estes elementos na nova pasta?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Tem certeza de que deseja restaurar este elemento?" msgstr[1] "Tem certeza de que deseja restaurar estes elementos?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Você tem certeza de que deseja remover todos os arquivos mais recentes em " "{path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Você tem certeza de que deseja remover todos os arquivos mais recentes no " "seu diretório original?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Alerta{BOLDEND}: Apagar arquivos na raiz do sistema de arquivos pode " "danificar todo o sistema." #: qt/app.py:1857 msgid "Snapshot" msgstr "Captura" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurar {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurar {path} para…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Olá\n" "Já usou o Back In Time em {language} algumas vezes.\n" "A tradução para {language} da versão do Back In Time atualmente instalada está {perc} completa. Independentemente do seu nível de conhecimentos de técnicos, você poderá contribuir para a tradução e, portanto, para o próprio Back In Time.\n" "Visite {translation_platform_url} se quiser contribuir. Para obter mais ajuda ou para qualquer questão, visite {back_in_time_project_website}.\n" "Pedimos desculpa pala interrupção. Esta mensagem não voltará a ser mostrada. Este diálogo estará sempre disponível no menu de ajuda.\n" "Equipe do Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plataforma de tradução" #: qt/app.py:2076 msgid "Website" msgstr "Página web" #: qt/app.py:2090 msgid "Your translation" msgstr "A sua tradução" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "No Fediverso do Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email para {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Lista de email {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} do website do projeto." #: qt/app.py:2118 msgid "Open an issue" msgstr "Abrir um problema" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternadamente, você pode usar qualquer outro canal de sua escolha." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Esta versão do Back In Time é um Candidato a Lançamento e é focada em testes de estabilidade preparando para o próximo lançamento oficial.\n" "Nenhum dado ou telemetria será coletado. Porém, a equipe do Back In Time tem interesse em saber se o Candidato a Lançamento está sendo útil e é válido continuar a criar estas versões pré-candidatas.\n" "Sendo assim, a equipe pede educadamente por um breve retorno sobre os seus testes nesta versão, mesmo que você não encontre nenhum problema. Mesmo um rápido teste de poucos minutos poderá nos ajudar muito.\n" "As seguintes formas de contato estão disponíveis:\n" "{contact_list}\n" "Nesta versão, esta mensagem não será mais exibida porém poderá ser acessada a qualquer momento através do menu de ajuda.\n" "Muito obrigado pelo seu apoio em nos ajudar a melhorar o Back In Time!\n" "Equipe Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "As definições de linguagem serão aplicadas somente após de reiniciar o Back " "In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "A criação do perfil EncFS será removida na próxima atualização (1.7), " "agendada para 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Não é mais recomendado utilizar este modo para um perfil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "artigo técnico" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "O suporte para EncFS está sendo descontinuado devido a vulnerabilidades de " "segurança." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Para maiores detalhes, incluindo possíveis alternativas, por favor verifique" " este {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "O(s) seguinte(s) perfil(s) utilizam encriptação EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Uma substituição está planejada mas não podemos garantir que chegará em " "tempo." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Os usuários estão convidados a participar desta discussão. Detalhes sobre os" " próximos passos estão disponíveis neste {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Esta mensagem não será exibida novamente. O diálogo está disponível a " "qualquer tempo no menu de ajuda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Sua Equipe do Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Linguagem de configuração" #: qt/languagedialog.py:97 msgid "System default" msgstr "Predefinição do sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Usar a linguagem do sistema operacional." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traduzido: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Última Visualização do Registro" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visualização do Registro de Captura" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Perfil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Capturas de tela:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtro:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tudo" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Alterações" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Erros" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informação" msgstr[1] "Informações" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "falhas de transferências rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Erro, [I] Informação, [C] Alteração" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "caminhos descodificados" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gerir perfis" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editar" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Adicionar" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Remover" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Geral" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Incluir" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Incluir arquivos e pastas" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Adicionar um arquivo" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Adicionar pasta" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Excluir" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informação{ENDBOLD}: no modo \"encriptado por SSH\", apenas funcionam " "asteriscos simples ou duplos (exemplo, {example2}). Outros tipos de " "caracteres especiais e padrões serão ignorados (exemplo, {example1}). Os " "nomes de arquivos são imprevisíveis neste modo devido à encriptação por " "EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Excluir padrões, arquivos ou pastas" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Adicionar padrão" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Excluir arquivos maiores que:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Excluir arquivos maiores que o valor em {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Com o 'modo rsync completo' desativado, isto apenas afetará os novos " "arquivos, uma vez que para o rsync esta é uma opção de transferência, não " "uma opção de exclusão. Portanto, os arquivos grandes dos quais foram feitos " "backups anteriormente irão persistir nas capturas, mesmo que tenham sido " "modificados." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Remover & Retenção" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opções" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "O&pções Avançadas" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaurar Configuração" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editar o retorno do usuário" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Novo perfil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renomear perfil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Tem certeza que deseja remover este perfil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Altamente recomendado{ENDBOLD}: (Todas as recomendações já foram " "incluídas.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Altamente recomendado{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Excluir padrão" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Excluir arquivo" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Excluir diretório" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Incluir arquivo" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" é um link simbólico. Não será feito backup do destino selecionado até que o inclua também.\n" "Gostaria de incluir o destino do link simbólico?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Incluir pasta" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Desativado porque este padrão não funciona no modo 'SSH encriptado'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Agenda" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dia:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Dia da semana:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tempo:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Hora(s):" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "depois do horário" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutos:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Execute o Back In Time assim que a unidade estiver conectada (apenas uma vez" " a cada X dias). Será solicitada a sua senha sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Executar Back In Time repetidamente. Isto é útil se o computador não ficar " "ligado regularmente." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "A cada:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Ativar o registo de mensagens de debug" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Escreve mensagens de nível de debug no registo do sistema através de \"--" "debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Cuidado: Utilize-o apenas para diagnóstico temporário, pois gera uma grande " "quantidade de resultados." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Desativado" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "A cada início/reinício" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "A cada {n} minuto" msgstr[1] "A cada {n} minutos" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "A cada hora" msgstr[1] "A cada {n} horas" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "A cada {n} hora" msgstr[1] "A cada {n} horas" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Horário determinado" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Diariamente" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetidamente (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Quando o dispositivo for conectado (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Semanalmente" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Mensalmente" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Anualmente" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hora(s)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dia(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semana(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mês(es)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "As horas personalizadas só podem ser uma lista de horas separadas por " "vírgulas (exemplo 8,12,18,23) ou */3 para cópias de segurança a cada 3 " "horas." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Servidor:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Porta:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usuário:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Ligar ao servidor de destino através deste proxy (também conhecido com " "servidor de salto). Ver \"-J\" na documentação do comando \"ssh\" ou " "\"ProxyJump\" em \"ssh_config\" para maiores detalhes." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Cuidado:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Estas opções dão para configurações avançadas. Modifique somente o que você " "tiver conhecimento dos resultados." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Execute 'rsync' com '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "como cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "no servidor remoto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "ao tirar uma captura manual" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Por favor instale 'nocache' para ativar esta opção." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na máquina local" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirecione stdout para /dev/null em cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "O Cron enviará automaticamente um e-mail com a saída anexada dos cronjobs se" " estiver instalado um MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirecione stderr para /dev/null em cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "O Cron enviará automaticamente um e-mail com erros anexados de cronjobs se " "um MTA estiver instalado." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/seg" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limite a utilização da largura de banda rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preservar ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preservar atributos estendidos (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Copiar links inseguros (funciona apenas com links absolutos)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Restringir a um sistema de arquivos" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "As opções devem ser citadas, p. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Cole opções adicionais para rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefixo a ser executado antes de cada comando no servidor remoto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "As variáveis precisam de ser escapadas com \\$FOO. Isto não afeta o rsync. " "Assim, para adicionar um prefixo ao rsync, utilize \"{example_value}\" com " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "padrão" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Adicionar prefixo aos comandos SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Verificar se o servidor remoto está online" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Aviso: Se estiver desativado e o servidor remoto não estiver disponível, " "isto poderá levar a alguns erros estranhos." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Verifique se o servidor remoto suporta todos os comandos necessários." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Aviso: Se estiver desativado e o servidor remoto não suportar todos os " "comandos necessários, poderá levar a alguns erros estranhos." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(padrão: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "desativado" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "ativado" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modo:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Onde guardar as capturas" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Definições de SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Caminho:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifra:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Chave Privada:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Escolha um arquivo de chave privada existente (normalmente designado por " "\"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Crie uma nova chave SSH sem senha (não permitido se um ficheiro de chave " "privada já estiver selecionado)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Senha" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Guardar a Senha em um Keyring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Senha de Cache para Cron (problema de segurança: o root consegue ler a " "senha)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avançado" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Caminho completo da captura:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Não escolheu um arquivo de chave privada para o SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Gostaria de gerar um novo par de chaves pública/privada sem senha?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "O arquivo de chave privada \"{file}\" não existe." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Gostaria de copiar a sua chave SSH pública para o servidor remoto para " "permitir o login sem senha?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "A autenticidade do servidor {host} não pode ser verificada." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "A impressão digital da chave {keytype} é:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verifique esta impressão digital. Gostaria de adicioná-la ao seu arquivo " "'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Tem a certeza que deseja modificar este diretório de capturas?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Falha ao criar nova chave SSH em {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Ativar notificações" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Desativar capturas usar a bateria" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Estado de energia não disponível no sistema" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Execute uma captura de cada vez" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Outras capturas serão bloqueadas até que a captura atual esteja concluída. " "Esta é uma opção global. Portanto, isto afetará todos os perfis deste " "usuário. Mas você também precisará ativar isto para todos os outros " "usuários." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Cópia de segurança dos arquivos substituídos na restauração" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "As versões mais recentes dos arquivos serão renomeadas com o sufixo {suffix}" " antes de serem restauradas. Se você já não precisa delas, pode removê-las " "com {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuar com erros (manter capturas incompletas)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Use a soma de verificação para detectar mudanças" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Tire uma captura independentemente de haver alterações ou não." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nível de Registro:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nenhum" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "As seguintes regras foram processadas de cima para baixo. As últimas regras " "substituem as anteriores e não são limitadas por elas. Verifique o {manual} " "para detalhes e exemplos." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual do usuário" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Abrir o manual do usuário no navegador." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Manter a captura mais recente." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "A captura mais recente é mantida sob quaisquer circunstâncias." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "O comportamento não será alterado." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Manter as capturas nomeadas." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "As capturas que possuírem um nome dado em adição ao carimbo de data/hora " "padrão, serão mantidas sob quaisquer circunstâncias e não serão removidas." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Ano(s)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Remover capturas mais antigas que" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Dias completos. O dia atual será ignorado." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Semanas iniciadas com Segunda-feira. A semana atual sera ignorada." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Períodos de 12 meses. O mês atual será ignorado." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Política de retenção" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Executar em segundo plano no servidor remoto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "O procedimento de remoção inteligente irá rodar diretamente no servidor, não" " localmente. Os comandos \"bash\", \"screen\"e \"flock\" precisam estar " "instalados e disponíveis no servidor remoto." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Se selecionado, Back In Time primeiramente testará o servidor remoto." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dias contados começando a partir de hoje." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Mantenha todas as capturas pela última vez" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dia(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Mantenha uma captura para cada dia até o último" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "As semanas começam a ser contadas a partir da semana atual. A semana começa " "na Segunda-feira." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Mantenha uma captura por semana até a última" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semana(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Os meses são contados pelo calendário atual e iniciando a partir do mês " "atual." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Mantenha uma captura por mês até o último" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mês/meses." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Os anos são contados pelo calendário e a partir do ano atual." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Mantenha todas capturas a cada ano" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "todo os anos." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... o espaço livre é menor que" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "... os inodes livres forem inferiores a:" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Remover as capturas antigas se …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pergunta" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Perfil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Ver Último Registro" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Iniciar {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Trabalhando…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Enviado:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocidade:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Capturas" #: qt/qttools.py:506 msgid "Today" msgstr "Hoje" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ontem" #: qt/qttools.py:522 msgid "This week" msgstr "Esta semana" #: qt/qttools.py:529 msgid "Last week" msgstr "Semana passada" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Isto NÃO É uma captura, mas uma visualização em tempo real dos seus arquivos" " locais" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Última marcação {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importar configuração" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nenhuma configuração encontrada" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Selecione a pasta de captura a partir da qual o arquivo de configuração " "deverá ser importado. O caminho será parecer com: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Se a pasta estiver localizada numa unidade externa ou remota, terá de ser " "montada manualmente antes." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Mostrar registro completo" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opções sobre a comparação de capturas" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parâmetros:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Utilize %1 e %2 para os parâmetros do caminho" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Por favor, defina um comando diff ou pressione Cancelar." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "O comando \"{cmd}\" não pode ser encontrado neste sistema. Por favor, tente " "algo diferente ou aperte Cancelar." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nenhum parâmetro definido para o comando diff. Utilizando o valor padrão " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Apenas capturas diferentes" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Liste apenas capturas que sejam iguais a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Verificação profunda (mais precisa, mas lenta)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Eliminar" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Selecionar Todos" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparar" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ir para" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opções" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Você não pode comparar uma captura com ela mesma." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Você deseja realmente apagar {file} da captura {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Você deseja realmente apagar {file} das {count} capturas?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "AVISO: Isto não pode ser revogado." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Excluir {path} das futuras capturas?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "A subpasta de backup não pode ser incluída." backintime-1.5.4/common/po/pt_BR.po000066400000000000000000002007151477034762000171220ustar00rootroot00000000000000# Brazilian Portuguese translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-17 09:20+0000\n" "Last-Translator: buhtz \n" "Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Aviso" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Perfil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (criptografado com EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (criptografado com EncFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Chave privada SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Criptografia local" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Criptografia" #: common/config.py:289 msgid "SSH encrypted" msgstr "Criptografado via SSH" #: common/config.py:296 msgid "Default" msgstr "Padrão" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Perfil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Pasta de Snapshots inválida." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Pelo menos um diretório precisa ser selecionado para o backup." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Diretório: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Este diretório não pode ser incluído no backup pois faz parte do próprio " "destino do backup." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Falha ao escrever um novo crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron não está em execução, embora o comando crontab esteja disponível. Os " "backups agendados não serão executados. O cron pode estar instalado, mas não" " habilitado. Tente o comando 'systemctl enable cron' ou consulte os canais " "de suporte da sua distribuição GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Não foi possível instalar a regra Udev para o perfil {profile_id}. O serviço" " DBus '{dbus_interface}' não estava disponível" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Agendamento udev não funciona com o modo {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Não foi possível encontrar o UUID para {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Falha ao salvar a configuração" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Falha ao carregar a configuração" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "O perfil \"{name}\" já existe." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "O último perfil não pode ser removido." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Não foi possível montar '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Configuração para o diretório criptografado não encontrada." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Criar um novo diretório criptografado?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Cancelar" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Por favor, confirme a senha." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "A senha não corresponde." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Criar snapshot" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Incapaz de desmontar {mountprocess} de {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} não encontrado. Por favor, instale-o (ex. via \"{installcommand}\"" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Ponto de montagem {mntpoint} não está vazio." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Digite a senha para o perfil {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "FALHOU" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restaurar permissões" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Concluído" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Backup adiado devido ao uso de bateria" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Não foi possível encontrar o diretório de snapshots." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Se estiver em uma unidade removível, por favor, insira-o." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Aguardando %s segundo." msgstr[1] "Aguardando %s segundos." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Falha ao criar o snapshot {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Por favor, aguarde. Finalizando…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Não é possível criar a pasta." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Salvando o arquivo de configuração…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Salvando as permissões…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Foi encontrado o snapshot remanescente {snapshot_id} que pode ser " "continuado." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Removendo o diretório {snapshot_id} remanescente da última execução" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Não é possível remover o diretório" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Criando snapshot" #: common/snapshots.py:1430 msgid "Success" msgstr "Sucesso" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transferência parcial devido a um erro" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transferência parcial devido a arquivos de origem ausentes (consulte 'man " "rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "O 'rsync' terminou com o código de saída {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Veja 'man rsync' para mais detalhes" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Códigos de saída negativos do rsync são números de sinal, veja 'kill -l' e " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nada mudou, nenhum novo snapshot é necessário" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Não foi possível renomear {new_path} para {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Remoção Inteligente" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Aplicar regras para remover snapshots antigos" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Aplicar política de retenção" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Tentando manter o mínimo de espaço livre" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Tentando manter no mínimo {perc} de inodes livres" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Agora" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Não foi possível montar {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" "ssh-agent não encontrado. Por favor, certifique-se de que está instalado." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Não é possível desbloquear a chave privada ssh. A senha está errada ou não " "está disponível para o cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cifra {cipher} falhou para {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "O caminho remoto existe, mas não é um diretório." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "O caminho remoto não é gravável." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "O caminho remoto não é executável." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Não é possível criar o caminho remoto." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "O host remoto {host} não suporta {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Consulte 'man backintime' para instruções adicionais" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Verificação dos comandos no host {host} retornou um erro desconhecido" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "O host remoto {host} não suporta hardlinks" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Copiar chave ssh pública \"{pubkey}\" para o host remoto \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Por favor, digite a senha para \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "O sistema de arquivos de destino para '{path}' está formatado com NTFS, que " "possui incompatibilidades conhecidas com sistemas de arquivos estilo Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} não é um diretório válido." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "A criação do seguinte diretório falhou:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "O acesso de escrita pode estar restrito." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "O sistema de arquivos de destino para '{path}' está formatado com FAT, que " "não suporta hard-links. Por favor, utilize um sistema de arquivos nativo do " "GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "O sistema de arquivos de destino para '{path}' é um compartilhamento montado" " via SMB. Por favor, tenha certeza que o servidor SMB remoto suporta links " "simbólicos ou ative a opção '{copyLinks}' em '{expertOptions}'." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copiar links (desreferenciar links simbólicos)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opções avançadas" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "O sistema de arquivos de destino para '{path}' é um compartilhamento via " "sshfs. O sshfs não suporta hard-links. Por favor, utilize o modo \"SSH\" em " "vez disso." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "A criação de arquivo falhou neste diretório:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Sobre" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autores" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traduções" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licença" #: qt/app.py:172 msgid "Shortcuts" msgstr "Atalhos" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Esse diretório não existe\n" "no atual snapshot selecionado." #: qt/app.py:257 msgid "Add to Include" msgstr "Adicione à Lista de Inclusão" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Adicione à Lista de Exclusão" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} parece estar em execução pela primeira vez, pois nenhuma " "configuração foi encontrada." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importar uma configuração existente (de um diretório de destino de backup ou" " de outro computador)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Se estiver em uma unidade removível, por favor conecte-a e pressione OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Criar snapshot" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Usar horário de modificação e tamanho para detectar alterações nos arquivos." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Criar snapshot (modo checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Usar checksums para detectar alterações nos arquivos." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausar o processo de snapshot" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Retomar o processo de snapshot" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Parar processo de snapshot" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Atualizar lista de snapshots" #: qt/app.py:497 msgid "Name snapshot" msgstr "Nomear snapshot" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Remover snapshot" #: qt/app.py:505 msgid "View snapshot log" msgstr "Visualizar log do snapshot" #: qt/app.py:509 msgid "View last log" msgstr "Visualizar último log" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gerenciar perfis…" #: qt/app.py:517 msgid "Shutdown" msgstr "Desligar" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Desligar o sistema após o snapshot ser finalizado." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurar idioma…" #: qt/app.py:525 msgid "Exit" msgstr "Sair" #: qt/app.py:529 msgid "User manual" msgstr "Manual do usuário" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Abrir o manual do usuário no navegador (local, se disponível, caso contrário" " online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Página do manual: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Exibe a página do manual sobre o Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "Página do manual: Arquivo de configuração de perfis" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Exibe a página do manual sobre o arquivo de configuração de perfis " "(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Site do projeto" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Abrir o site do Back In Time no navegador" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Registro de alterações" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ (Perguntas Frequentes)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Abrir Perguntas Frequentes (FAQ) no navegador.\"" #: qt/app.py:559 msgid "Ask a question" msgstr "Fazer uma pergunta" #: qt/app.py:563 msgid "Report a bug" msgstr "Reportar um bug" #: qt/app.py:566 msgid "Translation" msgstr "Traduções" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Exibe novamente a mensagem sobre participação na tradução." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Transição de Criptografia (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Exibe novamente a mensagem sobre a remoção do EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurar" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Restaurar os arquivos ou diretórios selecionados para o destino original." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurar para …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "" "Restaurar os arquivos ou diretórios selecionados para um novo destino." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaurar o diretório exibido atualmente e todos os seus conteúdos para o " "destino original." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaurar o diretório exibido atualmente e todos os seus conteúdos para um " "novo destino." #: qt/app.py:601 msgid "Up" msgstr "Acima" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Exibir arquivos ocultos" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Comparar snapshots…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Versão Candidata a Lançamento" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Exibe a mensagem sobre esta versão candidata a lançamento novamente." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Backup" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurar" #: qt/app.py:698 msgid "&Help" msgstr "&Ajuda" #: qt/app.py:743 msgid "Icons only" msgstr "Apenas ícones" #: qt/app.py:746 msgid "Text only" msgstr "Apenas texto" #: qt/app.py:749 msgid "Text below icons" msgstr "Texto abaixo dos ícones" #: qt/app.py:752 msgid "Text beside icon" msgstr "Texto ao lado do ícone" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Se você fechar esta janela, o Back In Time não será capaz de desligar seu " "sistema quando o snapshot for finalizado." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Você realmente deseja fechar?" #: qt/app.py:1072 msgid "Working:" msgstr "Trabalhando:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Concluído, nenhum backup necessário" #: qt/app.py:1129 msgid "Working" msgstr "Trabalhando" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Erro" #: qt/app.py:1161 msgid "Sent" msgstr "Enviado" #: qt/app.py:1162 msgid "Speed" msgstr "Velocidade" #: qt/app.py:1163 msgid "ETA" msgstr "Tempo Estimado" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Raiz" #: qt/app.py:1227 msgid "Home" msgstr "Home" #: qt/app.py:1255 msgid "Backup directories" msgstr "Diretórios de backup" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nome do Snapshot" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Você tem certeza de que deseja remover esse snapshot?" msgstr[1] "Você tem certeza de que deseja remover esses snapshots?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Criar cópias de backup com o sufixo {suffix}\n" "antes de sobrescrever ou remover elementos locais." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Versões mais recentes dos arquivos serão renomeadas com o sufixo {suffix} " "antes da restauração. Se não precisar mais deles, poderá removê-los com o " "seguinte comando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Restaure apenas elementos que não existem ou\n" "que são mais recentes do que os do destino.\n" "Usando a opção \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Remover os elementos mais recentes do diretório original." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaure os arquivos ou diretórios selecionados para o destino original e " "exclua os arquivos ou diretórios que não estão no snapshot. Tenha extrema " "cautela, pois isso excluirá arquivos e diretórios que foram omitidos durante" " a criação do snapshot." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Você realmente deseja restaurar este elemento no novo diretório?" msgstr[1] "Você realmente deseja restaurar estes elementos no novo diretório?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Você realmente deseja restaurar este elemento?" msgstr[1] "Você realmente deseja restaurar estes elementos?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Você tem certeza de que deseja remover todos os arquivos mais recentes em " "{path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Você tem certeza de que deseja remover todos os arquivos mais novos em seu " "diretório original?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Atenção{BOLDEND}: Deletar arquivos no sistema de arquivos raiz pode " "quebrar todo o seu sistema." #: qt/app.py:1857 msgid "Snapshot" msgstr "Snapshot" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurar {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurar {path} para …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Olá\n" "Você tem usado o Back In Time no idioma {language} algumas vezes até agora.\n" "A tradução da sua versão instalada do Back In Time para o {language} está {perc} completa. Independentemente do seu nível de conhecimento técnico, você pode contribuir para a tradução e, para o Back In Time em si.\n" "Por favor, visite a {translation_platform_url} se desejar contribuir. Para assistência adicional e dúvidas, por favor acesse o projeto do {back_in_time_project_website}.\n" "Pedimos desculpas pela interrupção, e esta mensagem não será exibida novamente. Este diálogo está disponível a qualquer momento pelo menu de ajuda.\n" "Sua equipe Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "plataforma de tradução" #: qt/app.py:2076 msgid "Website" msgstr "através do site" #: qt/app.py:2090 msgid "Your translation" msgstr "Sua tradução" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "No Fediverse do Mastodon: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email para {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Lista de emails {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} no site do projeto." #: qt/app.py:2118 msgid "Open an issue" msgstr "Abra uma demanda" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativamente, você pode usar outro canal de sua escolha." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Esta versão do Back In Time é um Candidato de Lançamento e é destinada principalmente para testes de estabilidade em preparação para o próximo lançamento oficial.\n" "Nenhum dado do usuário ou telemetria é coletado. No entanto, a equipe do Back In Time está muito interessada em saber se o Candidato de Lançamento está sendo utilizado e se vale a pena continuar a fornecer essas versões de pré-lançamento.\n" "Portanto, a equipe solicita gentilmente um breve feedback sobre se você testou esta versão, mesmo que não tenha encontrado nenhum problema. Mesmo um teste rápido de alguns minutos nos ajudaria muito.\n" "As seguintes opções de contato estão disponíveis:\n" "{contact_list}\n" "Nesta versão, esta mensagem não será exibida novamente, mas pode ser acessada a qualquer momento pelo menu de ajuda.\n" "Obrigado pelo seu apoio e por nos ajudar a melhorar o Back In Time!\n" "Sua equipe do Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "As configurações de idioma só têm efeito após reiniciar o Back in Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "A criação de perfil EncFS será removida na próxima versão de lançamento " "(1.7), programada para 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Além disso, não é recomendado usar esse modo para um perfil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "artigo técnico" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" "O suporte para EncFS está sendo descontinuado devido a vulnerabilidades de " "segurança." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Para mais detalhes, incluindo possíveis alternativas, por favor consulte " "este {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Os seguintes perfis utilizam criptografia com EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Uma substituição está planejada, mas não é garantido que ela chegará a " "tempo." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Os usuários são convidados a juntarem-se a esta discussão. Detalhes " "atualizados dos próximos passos estão disponíveis neste {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Esta mensagem não será exibida novamente. Este dialog está disponível a " "qualquer momento através do menu de ajuda." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Sua Equipe Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Configurar idioma" #: qt/languagedialog.py:97 msgid "System default" msgstr "Padrão do sistema" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Use o idioma do sistema operacional." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Traduzido: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Visualização do Último Log" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visualização do Log do Snapshot" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Perfil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Snapshots:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtrar:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tudo" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Alterações" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Erros" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informação" msgstr[1] "Informações" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Falhas na transferência do rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Erro, [I] Informação, [C] Alteração" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "decodificar caminhos" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gerenciar perfis" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editar" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Adicionar" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Remover" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Geral" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Incluir" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Incluir arquivos e diretórios" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Adicionar arquivo" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Adicionar diretório" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Excluir" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: No modo 'SSH encrypted' (ssh criptografado), apenas um " "asterisco ou dois asteriscos são funcionais (p.ex {example2}). Outros tipos " "de wildcards e padrões serão ignorados (p.ex {example1}). Nome de arquivos " "são imprevisíveis nesse modo graças à encriptação por EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Excluir modelos, arquivos ou diretórios" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Adicionar padrão" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Excluir arquivos maiores que:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Exclua arquivos maiores que o valor em {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Com o 'modo rsync completo' desativado, isso afetará apenas os novos " "arquivos, pois para o rsync, esta é uma opção de transferência, não uma " "opção de exclusão. Portanto, arquivos grandes dos quais foi feito backup " "anteriormente persistirão nos snapshots, mesmo que tenham sido modificados." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Remover & Reter" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opções" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "O&pções Avançadas" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaurar Configuração" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editar user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Novo perfil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Renomear perfil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Você tem certeza que deseja excluir o perfil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Altamente recomendado{ENDBOLD}: (Todas as recomendações já inclusas.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Altamente recomendado{ENDBOLD}:{files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Excluir padrão" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Excluir arquivo" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Excluir diretório" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Incluir arquivo" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" é um symlink. O alvo conectado não será salvo até você incluí-lo também.\n" "Você gostaria de incluir o alvo do symlink em seu lugar?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Incluir diretório" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Desativado porque este padrão não funciona no modo 'SSH criptografado'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Agendar" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dia:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Dia da Semana:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tempo:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Horas:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "depois da hora" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minutos:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Executar o Back In Time assim que o dispositivo for conectado (apenas uma " "vez a cada X dias). Você será solicitado a fornecer sua senha sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Executar o Back In Time repetidamente. Isto é útil se o computador não é " "executado regularmente." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Todo:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Habilitar registro de mensagens de depuração" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Grava mensagens de nível de depuração no log do sistema via \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Cuidado: Use-o apenas temporariamente para diagnóstico por gerar um excesso " "de resultados." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Desabilitado" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Em cada início/reinício" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "A cada {n} minuto" msgstr[1] "A cada {n} minutos" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "A cada hora" msgstr[1] "A cada {n} horas" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "A cada {n} hora" msgstr[1] "A cada {n} horas" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Horas personalizadas" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Todo dia" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Repetidamente (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Quando o drive for conectado (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Toda semana" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Todo mês" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Todo ano" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hora(s)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dia(s)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Semana(s)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mês(es)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Horas personalizadas podem ser apenas uma lista de horários separados por " "vírgula (ex. 8,12,18,23) ou */3 para backups periódicos a cada 3 horas." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Host:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Porta:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Usuário:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Conecte ao host de destino por meio desse proxy (também conhecido como um " "host de salto) Veja \"-J\" na documentação do comando \"ssh\" ou " "\"ProxyJump\" na página \"ssh_config\" no manual para detalhes." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Cuidado:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Estas opções são para configurações avançadas. Modifique-as somente se " "estiver totalmente ciente de suas implicações." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Executar 'rsync' com '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "como uma tarefa cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "no host remoto" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "quando for criar um snapshot manual" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Por favor, instale 'nocache' para habilitar esta opção." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na máquina local" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirecionar o stdout para /dev/null nas tarefas cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "O Cron enviará automaticamente um e-mail com a saída anexada dos cronjobs se" " um MTA estiver instalado." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirecionar o stderr para /dev/null nas tarefas cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "O Cron enviará automaticamente um e-mail com erros anexados de cronjobs se " "um MTA estiver instalado." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/seg" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limite o uso da largura de banda rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Preservar ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Preservar atributos extendidos (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Copiar links inseguros (funciona apenas com links absolutos)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Restringir a um sistema de arquivos" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "As opções devem estar entre aspas, por exemplo: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Colar opções adicionais para o rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefixo para ser executado antes de cada comando no host remoto." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "As variáveis precisam ser escapadas com \\$FOO. Isso não afeta o rsync. " "Portanto, para adicionar um prefixo para rsync, use \"{example_value}\" com " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "padrão" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Adicionar prefixo aos comandos SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Verificar se host remoto está online" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Aviso: Se o host remoto estiver desabilitado e não disponível , isso pode " "levar a alguns erros estranhos." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Verifique se o host remoto suporta todos os comandos necessários." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Aviso: Se o host remoto estiver desabilitado e não suportar todos os " "comandos necessários, isso pode levar a erros esquisitos." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(padrão: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "desativado" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "ativado" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Modo:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Onde salvar os snapshots" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Configurações do SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Caminho:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifra:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Chave Privada:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Escolha um arquivo de chave privada existente (normalmente chamado de " "\"id_ed25519\" e em configurações antigas \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Criar uma nova chave SSH sem senha (não permitido se um arquivo de chave " "privada já está selecionado)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Senha" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Salvar a Senha no Chaveiro" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Armazenar a Senha para o Cron (Problema de segurança: o root poderá ler a " "senha)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avançado" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Caminho completo do snapshot:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" "Você não escolheu um arquivo de chave privada (private key) para o SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Você gostaria de gerar um novo par de chaves públicas/privadas sem senha?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Arquivo de chave privada \"{file}\" não existe." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Você gostaria de copiar sua chave pública SSH para o host remoto para " "habilitar o login sem senha?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "A autenticidade do host {host} não pôde ser estabelecida." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} chave de impressão digital é:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Por favor verifique essa impressão digital. Você gostaria de adicioná-la no " "seu arquivo 'known_hosts' (hosts conhecidos)?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Deseja realmente mudar o diretório de snapshots ?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Falha em criar nova chave SSH em {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Habilitar notificações" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Desativar snapshot quando estiver na bateria" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Status de energia não disponível no sistema" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Executar apenas um snapshot por vez" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Outros snapshots serão bloqueados até que o snapshot atual seja concluído. " "Esta é uma opção global. Portanto, isso afetará todos os perfis deste " "usuário. Mas também precisa ativar isso para todos os outros usuários." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Backup de arquivos substituídos na restauração" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Versões mais recentes de arquivos serão renomeadas com {suffix} à direita " "antes da restauração. Se não precisar mais deles, poderá removê-los com " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuar em caso de erros (manter snapshots incompletos)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Usar checksum para detectar alterações" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "" "Criar um novo snapshot independentemente de existir ou não alterações." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nível de Log:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nenhum" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "As seguintes regras são processadas de cima para baixo. Regras posteriores " "substituem as anteriores e não são restringidas por elas. Consulte o " "{manual} para mais detalhes e exemplos." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "manual de usuário" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Abrir o manual de usuário no navegador." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Manter o snapshot mais recente." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "O último ou mais recente snapshot é mantido sob todas as circunstancias." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Esse comportamento não pode ser mudado." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Manter os snapshots nomeados." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Os snapshots que receberam um nome, além do carimbo de data e hora usual, " "serão retidos sob todas as circunstancias e não serão removidos." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Ano(s)" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Remover snapshots mais antigos que" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Dias completos. o dia atual é ignorado." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Semanas do calendário com Segunda como primeiro dia. A semana atual é " "ignorada." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Períodos de 12 meses. O mês atual é ignorado." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Política de retenção" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Executar em segundo plano no host remoto." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "O procedimento de remoção inteligente será executado diretamente na máquina " "remota, não localmente. Os comandos \"bash\", \"screen\", e \"flock\" devem " "estar instalados e disponíveis na máquina remota." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Se selecionado, o Back In Time irá primeiramente testar a máquina remota." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Os dias são contados a partir de hoje." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Manter todos os snapshots pelos últimos" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dia(s)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Manter o último snapshot de cada dia dos últimos" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "As semanas são contadas a partir da semana atual. Uma semana começa na " "Segunda." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Manter o último snapshot de cada semana das últimas" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "semana(s)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Os meses são contados como meses do calendário começando pelo mês atual." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Manter o último snapshot de cada mês dos últimos" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mês(es)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" "Os anos são contados como anos do calendário começando pelo ano atual." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Manter o último snapshot de cada ano dos últimos" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "todos os anos." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "... o espaço livre é menor que" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "... os inodes livres são menores que" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Remover snapshots antigos se …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pergunta" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Perfil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Visualizar Último Log" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Inicializar {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Trabalhando…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Enviado:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Velocidade:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snapshots" #: qt/qttools.py:506 msgid "Today" msgstr "Hoje" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ontem" #: qt/qttools.py:522 msgid "This week" msgstr "Esta semana" #: qt/qttools.py:529 msgid "Last week" msgstr "Semana passada" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Isto NÃO é um snapshot, mas uma visualização do seus arquivos locais" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Última verificação {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Configuração de importação" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nenhum arquivo de configuração encontrado" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importar" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Selecione o diretório de snapshot do qual o arquivo de configuração deve ser" " importado. O caminho pode ser semelhante a: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Se o diretório estiver localizado em uma unidade externa ou remota, ela " "deverá ser montada manualmente antes." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Mostrar Log Completo" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opções sobre comparação de snapshots" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parâmetros:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Use %1 e %2 para os parâmetros de caminho" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Por favor, defina um comando diff ou pressione Cancelar." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "O comando \"{cmd}\" não pôde ser encontrado neste sistema. Por favor, tente " "outra coisa ou pressione Cancelar." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nenhum parâmetro definido para o comando diff. Usando o valor padrão " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Apenas snapshots diferentes" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Listar apenas snapshots iguais a:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Verificação profunda (mais preciso, mas lento)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Excluir" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Selecionar Tudo" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Comparar" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ir para" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opções" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Você não pode comparar um snapshot com ele mesmo." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Você realmente deseja apagar {file} no snapshot {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Você realmente deseja apagar {file} em {count} snapshots?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "Aviso: Isto não pode ser revogado." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Excluir {path} de snapshots futuros?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Sub-pasta backup não pode ser incluída." backintime-1.5.4/common/po/ro.po000066400000000000000000001740771477034762000165470ustar00rootroot00000000000000# Romanian translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2024-07-19 11:10+0000\n" "Last-Translator: espresso_nightingale \n" "Language-Team: Romanian \n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;\n" "X-Generator: Weblate 5.6.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Avertisment" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Profil principal" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Local (criptat EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (criptat EncFS)" #: common/config.py:278 msgid "Local" msgstr "Local" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Cheie privată SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Local criptat" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Criptare" #: common/config.py:289 msgid "SSH encrypted" msgstr "Criptat SSH" #: common/config.py:296 msgid "Default" msgstr "Implicit" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: „{name}”" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Dosarul de instantanee nu este valid!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Restaurează {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Sub-dosarul copiei de rezervă nu poate fi inclus." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nu s-a putut scrie un nou crontab." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron nu rulează deși comanda crontab este disponibilă. Sarcinile de copiere " "de rezervă programate nu vor rula. Cron ar putea fi instalat, dar nu este " "activat. Încercați comanda „systemctl enable cron” sau consultați canalele " "de asistență ale distribuției GNU Linux pe care o aveți." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Nu s-a putut instala regula Udev pentru profilul {profile_id}. Serviciul " "DBus „{dbus_interface}” nu a fost disponibil" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev-ul programului nu funcționează cu modul {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nu s-a putut găsi UUID-ul pentru {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nu s-a putut salva configurația" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nu s-a putut încărca configurația" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profilul „{name}” există deja." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Ultimul profil nu poate fi eliminat." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nu se poate monta „{command}”" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Nu s-a găsit configurația pentru dosarul criptat." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Creați un nou dosar criptat?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Anulează" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Confirmați parola." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Parola nu se potrivește." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ia instantaneu" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Nu se poate demonta {mountprocess} de la {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} nu a fost găsită. Instalați-o (de ex. prin „{installcommand}”)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Punctul de montare {mntpoint} nu este liber." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Introduceți parola pentru profilul {mode} „{profile}”:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "EȘUAT" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Restabilește permisiunile" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Terminat" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Se amână copierea de rezervă în timp ce se utilizează bateria" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Nu s-a putut găsi dosarul cu instantanee." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "Dacă se află pe o unitate detașabilă, conectați-o și apoi apăsați OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Se așteaptă %s secundă." msgstr[1] "Se așteaptă %s secunde." msgstr[2] "Se așteaptă %s de secunde." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Nu s-a putut realiza instantaneul {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Nu se poate crea dosarul" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Se salvează fișierul de configurație…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Se salvează permisiunile…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "A fost găsit {snapshot_id} rămas care poate fi continuat." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Se elimină dosarul {snapshot_id} rămas din ultima rulare" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Nu se poate elimina dosarul" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Se ia instantaneul" #: common/snapshots.py:1430 msgid "Success" msgstr "Succes" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Transfer parțial din cauza unei erori" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Transfer parțial din cauza fișierelor sursă dispărute (consultați „man " "rsync”)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "„rsync” s-a încheiat cu codul de ieșire {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Consultați „man rsync” pentru mai multe detalii" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Codurile de ieșire rsync negative sunt numere de semnal, consultați „kill " "-l” și „man kill”" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nimic nu s-a schimbat, nu este necesar un instantaneu nou" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Nu se poate redenumi {new_path} la {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Înlăturare inteligentă" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Se elimină instantaneele vechi" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Se încearcă păstrarea minimului de spațiu liber" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Se încearcă păstrarea a minim {perc} inode-uri libere" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Acum" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nu se poate monta {sshfs}" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent nu a fost găsit. Asigurați-vă că este instalat." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nu s-a putut debloca cheia privată ssh. Parolă greșită sau parola nu este " "disponibilă pentru cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Cifrul {cipher} a eșuat pentru {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Calea de la distanță există dar nu este un director." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Calea de la distanță nu este inscriptibilă." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Calea de la distanță nu este executabilă." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nu s-a putut crea calea de la distanță." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Gazda de la distanță {host} nu suportă {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Consultați „man backintime” pentru instrucțiuni suplimentare" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "Comenzile de verificare de pe gazda {host} au returnat o eroare necunoscută" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Gazda de la distanță {host} nu suportă legăturile tari" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Copiază cheia publică ssh „{pubkey}” la gazda de la distanță „{host}”." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Introduceți o parolă pentru „{user}”." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Sistemul de fișiere destinație pentru {path} este formatat cu FAT care nu " "suportă legăturile tari. Utilizați un sistem de fișiere nativ Linux." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Calea de la distanță există dar nu este un director." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Sistemul de fișiere destinație pentru {path} este formatat cu FAT care nu " "suportă legăturile tari. Utilizați un sistem de fișiere nativ Linux." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Sistemul de fișiere destinație pentru {path} este o partajare montată pe " "SMB. Asigurați-vă că serverul SMB de la distanță suportă legăturile " "simbolice sau activați {copyLinks} în {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Copiază legăturile (dereferențiază legăturile simbolice)" #: common/tools.py:504 msgid "Expert Options" msgstr "Opțiuni expert" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Sistemul de fișiere destinație pentru {path} este o partajare montată pe " "sshfs. Sshfs nu oferă suport pentru legăturile permanente (hard-link). " "Utilizați în schimb modul „SSH”." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Despre" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autori" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Traduceri" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licență" #: qt/app.py:172 msgid "Shortcuts" msgstr "Scurtături" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Acest dosar nu există\n" "în instantaneul selectat curent." #: qt/app.py:257 msgid "Add to Include" msgstr "Adaugă la includeri" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Adaugă la excluderi" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} pare să ruleze pentru prima dată întrucât nu s-a găsit nicio " "configurație." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importați o configurație existentă (dintr-un dosar țintă de copie de rezervă" " sau de pe un alt calculator)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Dacă se află pe o unitate detașabilă, conectați-o și apoi apăsați OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ia un instantaneu" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Utilizează timpul și dimensiunea modificării pentru detectarea modificărilor" " fișierelor." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ia un instantaneu (modul checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Utilizează checksum-uri pentru detectarea modificărilor fișierelor." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Suspendă procesul de instantaneu" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Reia procesul de instantaneu" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Oprește procesul de instantaneu" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Reîmprospătează lista de instantanee" #: qt/app.py:497 msgid "Name snapshot" msgstr "Denumește instantaneul" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Elimină instantaneul" #: qt/app.py:505 msgid "View snapshot log" msgstr "Vizualizează jurnalul instantaneului" #: qt/app.py:509 msgid "View last log" msgstr "Vizualizează ultima înregistrare în jurnal" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Gestionează profilurile…" #: qt/app.py:517 msgid "Shutdown" msgstr "Oprește" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Oprește sistemul după finalizarea instantaneului." #: qt/app.py:521 msgid "Setup language…" msgstr "Configurează limba…" #: qt/app.py:525 msgid "Exit" msgstr "Ieșire" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Fișierul de configurare al profilului" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Jurnal de modificări" #: qt/app.py:555 msgid "FAQ" msgstr "Întrebări frecvente" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Pune o întrebare" #: qt/app.py:563 msgid "Report a bug" msgstr "Raportează o defecțiune" #: qt/app.py:566 msgid "Translation" msgstr "Traducere" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Afișează din nou mesajul despre participarea la traducere." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Tranziție de criptare (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Afișează din nou mesajul despre înlăturarea EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Restaurează" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Restaurează fișierele sau dosarele selectate la destinația originală." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Restaurează la …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Restaurează fișierele sau dosarele selectate la o nouă destinație." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Restaurează dosarul afișat în prezent și tot conținutul acestuia la " "destinația originală." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Restaurează dosarul afișat în prezent și tot conținutul acestuia la o nouă " "destinație." #: qt/app.py:601 msgid "Up" msgstr "Sus" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Arată fișierele ascunse" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Compară instantaneele…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Afișează din nou mesajul despre înlăturarea EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Copie de rezervă" #: qt/app.py:692 msgid "&Restore" msgstr "&Restaurează" #: qt/app.py:698 msgid "&Help" msgstr "&Ajutor" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Dacă închideți această fereastră, Back In Time nu vă va putea opri sistemul " "când instantaneul este finalizat." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Sigur doriți să o închideți?" #: qt/app.py:1072 msgid "Working:" msgstr "Se lucrează:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Terminat, nicio copie de rezervă necesară" #: qt/app.py:1129 msgid "Working" msgstr "Se lucrează" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Eroare" #: qt/app.py:1161 msgid "Sent" msgstr "Trimis" #: qt/app.py:1162 msgid "Speed" msgstr "Viteză" #: qt/app.py:1163 msgid "ETA" msgstr "Timp rămas" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Home" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Dosare copie de rezervă" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Nume instantaneu" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Sigur doriți să eliminați acest instantaneu?" msgstr[1] "Sigur doriți să eliminați aceste instantanee?" msgstr[2] "Sigur doriți să eliminați aceste instantanee?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Crează copii de rezervă cu sufixul {suffix}\n" "înainte de a suprascrie sau de a elimina elementele locale." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Noile versiuni ale fișierelor vor fi redenumite cu sufixul {suffix} înainte " "de restaurare. Dacă nu mai aveți nevoie de ele, puteți să le eliminați cu " "următoarea comandă:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Restaurează doar elementele care nu există sau\n" "care sunt mai noi decât cele de la destinație.\n" "Se utilizează opțiunea „rsync --update”." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Elimină elementele mai noi din dosarul original." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Restaurează fișierele sau dosarele selectate la destinația originală și " "șterge fișiere sau dosare care nu se află în instantaneu. Fiți extrem de " "atent pentru că acest lucru va șterge fișiere și dosare care au fost excluse" " în timpul realizării instantaneului." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Sigur doriți să restaurați acest element în dosarul nou\n" "{path}?" msgstr[1] "" "Sigur doriți să restaurați aceste elemente în dosarul nou\n" "{path}?" msgstr[2] "" "Sigur doriți să restaurați aceste elemente în dosarul nou\n" "{path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Sigur doriți să restaurați acest element?" msgstr[1] "Sigur doriți să restaurați aceste elemente?" msgstr[2] "Sigur doriți să restaurați aceste elemente?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Sigur doriți să eliminați toate fisierele mai noi din {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Sigur doriți să eliminați toate fișierele mai noi din dosarul original?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Avertisment{BOLDEND}: Ștergerea fișierelor din root-ul sistemului de " "fișiere vă poate distruge întregul sistem." #: qt/app.py:1857 msgid "Snapshot" msgstr "Instantaneu" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Restaurează {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Restaurează {path} la …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Salut\n" "Ați utilizat Back In Time în limba {language} de câteva ori până acum.\n" "Traducerea versiunii instalate de Back In Time în {language} este {perc} completă. Indiferent de nivelul de expertiză tehnică, puteți contribui la traducere și, astfel, la Back In Time în sine.\n" "Vizitați {translation_platform_url} dacă doriți să contribuiți. Pentru asistență suplimentară și întrebări, vizitați {back_in_time_project_website}.\n" "Ne cerem scuze pentru întrerupere, iar acest mesaj nu va mai fi afișat. Acest dialog este disponibil în orice moment prin meniul de ajutor.\n" "Echipa ta Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "platforma de traducere" #: qt/app.py:2076 msgid "Website" msgstr "Pagină web" #: qt/app.py:2090 msgid "Your translation" msgstr "Traducerea ta" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Configurările de limbă intră în vigoare doar după repornirea Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Suportul pentru EncFS va fi întrerupt în viitorul apropiat. Nu este " "recomandat să utilizați acel mod pentru un profil de acum încolo." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "raport" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Următorul profil(uri) utilizează criptare cu EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Acest mesaj nu va fi afișat din nou. Acest dialog este disponibil în orice " "moment prin meniul de ajutor." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Echipa Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Configurează limba" #: qt/languagedialog.py:97 msgid "System default" msgstr "Implicit de sistem" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Utilizează limba sistemului de operare." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Tradus: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Ultima vizualizare a jurnalului" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Vizualizare jurnal de instantaneu" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Instantanee:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtrează:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Toate" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Modificări" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Erori" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informație" msgstr[1] "Informații" msgstr[2] "Informații" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "eșecuri de transfer rsync (experimental)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Eroare, [I] Informații, [C] Modificare" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "decodează căile" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Gestionează profilurile" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Editează" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Adaugă" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Elimină" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Generale" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Include" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Include fișierele și dosarele" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Adaugă un fișier" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Adaugă un dosar" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Exclude" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informații{ENDBOLD}: În modul „criptat SSH”, doar asterisk-urile " "simple sau duble sunt funcționale (de ex. {example2}). Alte tipuri de " "wildcard-uri și modele vor fi ignorate (de ex. {example1}). Numele " "fișierelor sunt imprevizibile în acest mod din cauza criptării cu EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Exclude modele, fișiere sau dosare" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Adaugă implicit" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Exclude fișierele mai mari decât:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Exclude fișierele mai mari decât valoarea în {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Cu „Modul rsync complet” dezactivat, acest lucru va afecta doar fișierele " "noi, deoarece pentru rsync aceasta este o opțiune de transfer, nu o opțiune " "de excludere. Prin urmare, fișierele mari care au fost copiate de rezervă " "anterior vor persista în instantanee chiar dacă au fost modificate." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opțiuni" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Opțiuni e&xpert" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Restaurează configurația" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Editează user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Profil nou" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Redenumește profilul" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Sigur doriți să ștergeți profilul „{name}”?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Foarte recomandat{ENDBOLD}: (Toate recomandările sunt deja incluse.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Foarte recomandat{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Exclude modelul" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Exclude fișierul" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Exclude dosarul" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Include fișierul" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "„{path}” este o legătură simbolică. Ținta legată nu se va copia de rezervă până când nu o și includeți.\n" "Doriți să includeți în schimb ținta legăturii simbolice?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Include dosarul" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Dezactivat pentru că acest model nu este funcțional în modul „criptat SSH”." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Program" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Zi:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Zi lucrătoare:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Ore:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Rulează Back In Time imediat după conectarea unității (doar o dată la X zile).\n" "Vi se va solicita parola sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Rulează Back In Time în mod repetat. Acest lucru este util dacă calculatorul" " nu rulează în mod regulat." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "La fiecare:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Activează înregistarea mesajelor de depanare" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Scrie mesaje la nivel de depanare în jurnalul de sistem prin „--debug”." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Atenție: Folosiți-l doar temporar pentru diagnosticare, deoarece generează o" " cantitate mare de rezultate." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Dezactivat" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "La fiecare pornire/restart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "La fiecare {n} minut" msgstr[1] "La fiecare {n} minute" msgstr[2] "La fiecare {n} de minute" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "La fiecare oră" msgstr[1] "La fiecare {n} ore" msgstr[2] "La fiecare {n} de ore" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "La fiecare {n} oră" msgstr[1] "La fiecare {n} ore" msgstr[2] "La fiecare {n} de ore" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Ore personalizate" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Zilnic" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "În mod repetat (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Când unitatea este conectată (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Săptămânal" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Lunar" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Anual" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Oră (Ore)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Zi (Zile)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Săptămână (Săptămâni)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Lună (Luni)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Orele personalizate pot fi doar o listă de ore separată prin virgulă (de ex." " 8,12,18,23) sau */3 pentru copii de rezervă periodice la fiecare 3 ore." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Gazdă:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Utilizator:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Conectați-vă la gazda țintă prin acest proxy (cunoscut și ca gazdă de salt)." " Consultați „-J” în documentația comenzii „ssh” sau „ProxyJump” în pagina " "man „ssh_config” pentru detalii." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Întrebare" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Rulează „rsync” cu „{cmd}”:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "ca sarcină cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "pe gazda de la distanță" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "când se ia un instantaneu manual" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Instalați „nocache” pentru a activa această opțiune)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "pe mașina locală" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Redirecționează stdout către /dev/null în sarcinile cron." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron va trimite automat un email cu rezultatul atașat al cronjob-urilor dacă" " un MTA este instalat." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Redirecționează stderr către /dev/null în sarcinile cron." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron va trimite automat un email cu erorile atașate ale cronjob-urilor dacă " "un MTA este instalat." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KO/sec" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Limitează utilizarea lățimii de bandă a rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Păstrează ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Păstrează atributele extinse (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Copiază legăturile nesigure (funcționează doar cu legăturile absolute)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Restricționează la un singur sistem de fișiere" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opțiunile trebuie citate, de ex. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Lipește opțiunile adiționale la rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefix de rulat înainte de fiecare comandă pe gazda de la distanță." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabilele trebuie să fie escapate cu \\$FOO. Acest lucru nu atinge rsync. " "Deci, pentru a adăuga un prefix pentru rsync utilizați „{example_value}” cu " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "implicit" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Adaugă un prefix la comenzile SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Verifică dacă gazda de la distanță este conectată" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Avertisment: dacă este dezactivat și gazda de la distanță nu este " "disponibilă, acest lucru ar putea duce la unele erori ciudate." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Verifică dacă gazda de la distanță suportă toate comenzile necesare." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Avertisment: dacă este dezactivat și gazda de la distanță nu suportă toate " "comenzile necesare, acest lucru ar putea duce la unele erori ciudate." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(implicit: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "dezactivat" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "activat" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Mod:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Unde să se salveze instantaneele" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Configurări SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Cale:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Cifru:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Cheie privată:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "Alegeți un fisier cheie privată existent (de obicei denumit „id_rsa”)" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Creează o nouă cheie SSH fără parolă (nu este permis dacă un fișier cheie " "privată este deja selectat)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Parola" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Salvează parola la inelul de chei" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Memorează parola pentru Cron în cache (problemă de securitate: root poate să" " citească parola)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avansat" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Cale completă instantaneu:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Nu ați ales un fișier cheie privată pentru SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Doriți să generați o nouă pereche de chei publice/private fără parolă?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Fișierul cheie privată „{file}” nu există." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Doriți să copiați cheia publică SSH la gazda de la distanță pentru a activa " "autentificarea fără parolă?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autenticitatea gazdei {host} nu poate fi stabilită." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Amprenta cheii {keytype} este:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Verificați această amprentă. Doriți să o adăugați la fișierul „known_hosts”?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Sigur doriți să modificați dosarul de instantanee?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Nu s-a putut crea o cheie SSH nouă în {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Activează înștiințările" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Dezactivează instantaneele când se utilizează bateria" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Starea alimentării nu este disponibilă din sistem" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Rulează doar un instantaneu la un moment dat" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Alte instantanee vor fi blocate până la finalizarea instantaneului curent. " "Aceasta este o opțiune globală. Deci, va afecta toate profilurile pentru " "acest utilizator. Dar trebuie să activați acest lucru și pentru toți " "ceilalți utilizatori." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Copiază de rezervă fișierele înlocuite la restaurare" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Noile versiuni ale fișierelor vor fi redenumite cu sufixul {suffix} înainte " "de restaurare. Dacă nu mai aveți nevoie de ele, puteți să le eliminați cu " "{cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Continuă la erori (păstrează instantanee incomplete)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Utilizează checksum pentru a detecta modificările" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ia un instantaneu nou indiferent dacă au existat modificări sau nu." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivel de jurnalizare:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nimic" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Nu elimina instantaneurile denumite." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Nu elimina instantaneurile denumite." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "An (Ani)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Elimină instantaneul" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Rulează pe fundal pe gazda de la distanță." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Păstrează toate instantaneele pentru ultimele" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "zi(zile)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Păstrează un instantaneu pe zi pentru ultimele" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Păstrează un instantaneu pe săptămână pentru ultimele" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "săptămână(săptămâni)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Păstrează un instantaneu pe lună pentru ultimele" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "lună(luni)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Păstrează toate instantaneele pentru ultimele" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Dacă spațiul liber este mai mic decât:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Dacă inode-urile libere sunt mai puține decât:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Se elimină instantaneele vechi" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Întrebare" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Vizualizează ultima înregistrare" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Pornește {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Se lucrează…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Trimis:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Viteză:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Instantanee" #: qt/qttools.py:506 msgid "Today" msgstr "Astăzi" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Ieri" #: qt/qttools.py:522 msgid "This week" msgstr "Săptămâna aceasta" #: qt/qttools.py:529 msgid "Last week" msgstr "Săptămâna trecută" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Aceasta NU este un instantaneu ci o vizualizare live a fișierelor locale" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Ultima verificare la {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importă configurația" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nu s-a găsit nicio configurație" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importă" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Selectați dosarul de instantaneu din care ar trebui să fie importat fișierul" " de configurație. Calea poate arăta astfel: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Dacă dosarul se află pe o unitate externă sau de la distanță, aceasta " "trebuie montată manual în prealabil." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Arată jurnalul complet" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opțiuni despre compararea instantaneelor" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Comandă:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Utilizați %1 și %2 pentru parametrii căii" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Stabiliți o comandă diff sau apăsați Anulează." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Comanda „{cmd}” nu poate fi găsită pe acest sistem. Încercați altceva sau " "apăsați Anulează." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Nu s-au stabilit parametri pentru comanda diff. Se utilizează valoarea " "implicită „{params}”." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Doar instantaneele care diferă" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Listează doar instantaneele care sunt egale cu:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Verificare profundă (mai precis, dar încet)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Șterge" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Selectează toate" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Compară" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Navighează la" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opțiuni" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nu puteți compara un instantaneu cu el însuși." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Sigur doriți să ștergeți {file} în instantaneul {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Sigur doriți să ștergeți {file} în {count} instantanee?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "AVERTISMENT: Acest lucru nu poate fi revocat." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Excludeți {path} din instantaneele viitoare?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Sub-dosarul copiei de rezervă nu poate fi inclus." backintime-1.5.4/common/po/ru.po000066400000000000000000002153211477034762000165410ustar00rootroot00000000000000# Russian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-01-09 16:14+0000\n" "Last-Translator: vulpes-viridis \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.9.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Предупреждение" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Основной профиль" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Локально (шифрование EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (шифрование EncFS)" #: common/config.py:278 msgid "Local" msgstr "Локально" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH приватный ключ" #: common/config.py:283 msgid "Local encrypted" msgstr "Локально, зашифровано" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Шифрование" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH зашифровано" #: common/config.py:296 msgid "Default" msgstr "По-умолчанию" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Профиль: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Каталог снимков задан неверно." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Хотя бы один каталог должен быть выбран для резервного копирования." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Восстановить {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Содержимое папки резервного копирования не должно быть включено." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Не удалось записать новый crontab." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron не запущен, хотя присутствует команда crontab. Архивация по расписанию " "выполняться не будет. Возможно, cron установлен, но не включен. Попробуйте " "выполнить команду «system enable cron» или свяжитесь с поддержкой вашего " "дистрибутива Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Не удалось установить правило Udev для профиля {profile_id}. Служба DBus " "'{dbus_interface}' недоступна" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Расписание udev не работает в режиме {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Не удалось найти UUID для {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Не удалось сохранить конфигурацию" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Не удалось загрузить конфигурацию" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Профиль \"{name}\" уже существует." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Последний профиль не может быть удален." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Невозможно смонтировать '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Не найдена конфигурация для зашифрованной директории." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Создать новую зашифрованную папку?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Отмена" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Пожалуйста, подтвердите пароль." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Пароль не подходит." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Сделать снимок" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Не удалось размонтировать {mountprocess} из {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Программа {command} не найдена. Установите ее (например через " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Точка монтирования {mntpoint} не пустая." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Введите пароль для {mode} профиля \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "НЕУСПЕШНО" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Восстановить права" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Готово" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Отсрочка резервного копирования при работе от батареи" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Невозможно найти каталог снимков." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Если он находится на съёмном диске, пожалуйста, подключите его и нажмите ОК." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Ждать %s секунду." msgstr[1] "Ждать %s секунды." msgstr[2] "Ждать %s секунд." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Не удалось создать снимок {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Пожалуйста, подождите. Завершение…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Невозможно создать каталог." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Сохранение файла конфигурации…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Сохранение разрешений…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Найдены остатки {snapshot_id}, с которыми можно продолжить." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Удаление остатков папки {snapshot_id}, оставшихся после последнего запуска" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Невозможно удалить каталог" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Создание снимка" #: common/snapshots.py:1430 msgid "Success" msgstr "Успешно" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Неполная передача из-за ошибки" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Частичный перенос из-за исчезновения исходных файлов (см. «man rsync»)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "rsync завершился c кодом {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Подробнее см. «man rsync»" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Неудачные коды выхода из rsync - это номера сигналов, см. 'kill -l' и 'man " "kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ничего не изменилось, нет необходимости в резервной копии" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Невозможно переименовать {new_path} в {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Умное удаление" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Удалить старые резервные копии" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Стараться сохранять минимальное свободное место" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Попытка сохранить минимум {perc} свободных инодов" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Сейчас" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Не удалось смонтировать {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-агент не найден. Убедитесь, что он установлен." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Не удалось разблокировать приватный ключ ssh. Неверный пароль или пароль не " "подходит для cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Пароль {cipher} не верен для {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Удаленный путь существует, но не является каталогом." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Удаленный путь недоступен для записи." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Удаленный путь не доступен для записи." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Не удалось создать удаленный путь." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Удаленный узел {host} не поддерживает{command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Дополнительные инструкции см. в man backintime" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Команды проверки на хосте {host} вернули неизвестную ошибку" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Удаленный хост {host} не поддерживает жесткие ссылки" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Скопировать открытый ssh-ключ \"{pubkey}\" на удаленный хост \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Пожалуйста, подтвердите пароль для \"{user}\"." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Файловая система назначения {path} отформатирована в FAT, не поддерживающая " "\"жесткие\" ссылки. Используйте нативные файловые системы Linux." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} существует, но не является каталогом." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Не удалось создать каталог:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Доступ на запись может быть ограничен." #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Файловая система назначения {path} отформатирована в FAT, не поддерживающая " "\"жесткие\" ссылки. Используйте нативные файловые системы Linux." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Файловая система назначения {path} является SMB-монтированным ресурсом. " "Убедитесь, что удаленный SMB-сервер поддерживает симлинки, или активируйте " "{copyLinks} в {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Копировать ссылки (разыменование символических ссылок)" #: common/tools.py:504 msgid "Expert Options" msgstr "Расширенные настройки" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Файловая система назначения для {path} смонтирована через sshfs. sshfs не " "поддерживает жесткие ссылки. Используйте режим «SSH»." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Не удалось создать файл в каталоге:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "О программе" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Разработчики" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Переводы" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Лицензия" #: qt/app.py:172 msgid "Shortcuts" msgstr "Ярлыки" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Этой папки не существует\n" "в выбранном снимке." #: qt/app.py:257 msgid "Add to Include" msgstr "Включить" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Добавить в исключения" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Похоже, что {app_name} запускается впервые, так как конфигурация не найдена." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Импортировать существующую конфигурацию (из резервной целевой папки или с " "другого компьютера)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Если он находится на съёмном диске, пожалуйста, подключите его и нажмите ОК." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Сделать снимок" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Используйте время модификации и размер для обнаружения изменений файла." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Сделать снимок (режим контрольной суммы)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Использовать контрольную сумму для обнаружения изменений." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Приостановить процесс создания снимка" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Продолжить процесс создания снимка" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Остановить процесс создания снимка" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Обновить список моментальных снимков" #: qt/app.py:497 msgid "Name snapshot" msgstr "Имя снимка" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Удалить снимок" #: qt/app.py:505 msgid "View snapshot log" msgstr "Смотреть log снимка" #: qt/app.py:509 msgid "View last log" msgstr "Смотреть последний log" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Управление профилями…" #: qt/app.py:517 msgid "Shutdown" msgstr "Выключить" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Выключить систему после завершения создания снимка." #: qt/app.py:521 msgid "Setup language…" msgstr "Изменить язык…" #: qt/app.py:525 msgid "Exit" msgstr "Выйти" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "config файл профиля" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Список изменений" #: qt/app.py:555 msgid "FAQ" msgstr "Часто задаваемые вопросы" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Задать вопрос" #: qt/app.py:563 msgid "Report a bug" msgstr "Сообщить об ошибке" #: qt/app.py:566 msgid "Translation" msgstr "Перевод" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Показать сообщение об участии в переводе." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Миграция с шифрования EncFS" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Показать сообщение об удалении EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Восстановить" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "" "Восстановление выбранных файлов или каталогов в исходное место назначения." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Восстановить в…" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "" "Восстановление выбранных файлов или каталогов в новое место назначения." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Восстановление текущей показанной папки и всего ее содержимого в исходное " "место назначения." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Восстановление текущей показанной папки и всего ее содержимого в новое место" " назначения." #: qt/app.py:601 msgid "Up" msgstr "Вверх" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Показать скрытые файлы" #: qt/app.py:607 #, fuzzy msgid "Compare snapshots…" msgstr "Сравнить снимки…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Показать сообщение об удалении EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "&Резервное копирование" #: qt/app.py:692 msgid "&Restore" msgstr "&Восстановление" #: qt/app.py:698 msgid "&Help" msgstr "&Справка" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Если вы закроете это окно - Back In Time не сможет выключить систему после " "завершения создания снимка." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Вы действительно хотите закрыть это?" #: qt/app.py:1072 msgid "Working:" msgstr "Работаю:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Сделано, сохранять ничего не надо" #: qt/app.py:1129 msgid "Working" msgstr "Работаю" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Ошибка" #: qt/app.py:1161 msgid "Sent" msgstr "Отправлено" #: qt/app.py:1162 msgid "Speed" msgstr "Скорость" #: qt/app.py:1163 msgid "ETA" msgstr "Приблизительно оставшееся время" #: qt/app.py:1225 msgid "Global" msgstr "Общее" #: qt/app.py:1226 msgid "Root" msgstr "Корневой каталог" #: qt/app.py:1227 msgid "Home" msgstr "Домашний каталог" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Резервные директории" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Название резервной копии" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Вы точно хотите удалить этот снимок?" msgstr[1] "Вы точно хотите удалить эти снимки?" msgstr[2] "Вы точно хотите удалить эти снимки?" #: qt/app.py:1496 #, fuzzy, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Создать резервные копии с последующим {suffix} перед\n" "перезаписью или удалением локальных файлов." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Более новые версии файлов перед восстановлением будут переименованы с " "трейлингом {suffix}. Если они вам больше не нужны, то можете удалить их с " "помощью команды:" #: qt/app.py:1520 #, fuzzy msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Восстанавливать только несуществующие элементы\n" "или элементы новее, чем имеющиеся.\n" "Использует опцию \"rsync --update\"." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Удалять более новые файлы в исходной папке." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Восстановление выбранных файлов/папок в исходное место назначения и удаление" " файлов/папок, которых нет в снимке. Будьте предельно осторожны, потому что " "при этом будут удалены файлы/папки, исключенные при создании снимка." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Вы действительно хотите восстановить этот файл в новую папку\n" "{path}?" msgstr[1] "" "Вы действительно хотите восстановить эти файлы в новую папку\n" "{path}?" msgstr[2] "" "Вы действительно хотите восстановить эти файлы в новую папку\n" "{path}?" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Вы действительно хотите восстановить этот файл?" msgstr[1] "Вы действительно хотите восстановить эти файлы?" msgstr[2] "Вы действительно хотите восстановить эти файлы?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Вы уверены, что хотите удалить все новые файлы в {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Вы уверены, что хотите удалить все новые файлы в исходной папке?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}ВНИМАНИЕ{BOLDEND}: Удаление файлов в корне файловой системы может " "сломать всю вашу систему." #: qt/app.py:1857 msgid "Snapshot" msgstr "Снимок" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Восстановить {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Восстановить {path} в…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Здравствуйте!\n" "При работе с Back In Time вы используете {language} язык.\n" "Перевод установленной вами версии Back In Time на {language} завершён на {perc}. Каким бы ни был ваш уровень знаний, вы можете внести свой вклад в перевод и тем самым помочь Back In Time.\n" "Если вы хотите поучаствовать в переводе — пожалуйста, посетите {translation_platform_url}. Задать вопросы и получить помощь можно на {back_in_time_project_website}.\n" "Приносим извинения за неудобства — это сообщение больше не появится. Снова найти это диалоговое окно можно будет в меню помощи.\n" "Ваша команда Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "платформы для перевода" #: qt/app.py:2076 msgid "Website" msgstr "Сайт" #: qt/app.py:2090 msgid "Your translation" msgstr "Ваш перевод" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Смена языка произойдет только после перезапуска Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Поддержка EncFS будет удалена в ближайшем будущем. Использовать этот профиль" " не рекомендуется." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "статье" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Следующие профили используют шифрование EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Изменить язык" #: qt/languagedialog.py:97 msgid "System default" msgstr "Язык системы" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Использовать язык операционных систеы." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Переведено: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Просмотр последнего лога" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Просмотр журнала снимка" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Профиль:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Снимки:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Фильтр:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Все" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Изменения" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Ошибки" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Информация" msgstr[1] "Информация" msgstr[2] "Информация" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "сбои передач rsync (экспериментально)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Ошибка, [I] Информация, [C] Изменение" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "декодирование путей" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Управление профилями" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Изменить" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Добавить" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Удалить" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Общие" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Включить" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Включить файлы и папки" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Добавить файл" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Добавить каталог" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Исключить" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Исключить шаблоны, файлы или папки" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Добавить по умолчанию" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Исключить файлы размером более:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Исключить файлы больше указанного размера (в {size_unit})." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "При отключенном 'Full rsync mode' это будет влиять только на новые файлы, " "поскольку для rsync это опция передачи, а не исключения. Таким образом, " "большие файлы, резервные копии которых были созданы ранее, останутся в " "снимках, даже если они изменились." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Параметры" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Р&асширенные параметры" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Восстановить конфигурацию" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Редактирование обратного вызова пользователя" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Новый профиль" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Переименовать профиль" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Вы действительно хотите удалить профиль \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Настоятельно рекомендуется{ENDBOLD}: (Все уже включено.)" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Настоятельно рекомендуется{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Исключать папку по шаблону" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Исключая файл" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Исключить каталог" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Включить файл" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" - это символическая ссылка. Резервное копирование связанной цели не будет выполняться до тех пор, пока вы не включите и ее.\n" "Хотите ли вы включить вместо этого цель по символической ссылке?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Включить каталог" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Отключено, так как шаблон не поддерживается в режиме «Зашифрованный SSH»." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Расписание" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Число:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "День недели:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Часа:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Запускать Back In Time как только устройство подключено (один раз каждые X " "дней). Будет запрошен sudo-пароль." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Многократный запуск программы Back In Time. Это удобно если компьютер " "работает нерегулярно." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Каждые:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Записывать отладочные сообщения в журнал" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Отключено" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "При каждой загрузке системы" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Каждую {n} минуту" msgstr[1] "Каждые {n} минут" msgstr[2] "Каждые {n} минут" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Каждый {n} час" msgstr[1] "Каждые {n} часа" msgstr[2] "Каждые {n} часов" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Каждый {n} час" msgstr[1] "Каждые {n} часа" msgstr[2] "Каждые {n} часов" #: qt/manageprofiles/schedulewidget.py:159 #, fuzzy msgid "Custom hours" msgstr "Другой период (в часах)" #: qt/manageprofiles/schedulewidget.py:160 #, fuzzy msgid "Every day" msgstr "Каждый день" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Периодически (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "При подключении носителя (udev)" #: qt/manageprofiles/schedulewidget.py:163 #, fuzzy msgid "Every week" msgstr "Каждую неделю" #: qt/manageprofiles/schedulewidget.py:164 #, fuzzy msgid "Every month" msgstr "Каждый месяц" #: qt/manageprofiles/schedulewidget.py:165 #, fuzzy msgid "Every year" msgstr "Ежегодно" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Час(ов)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Дней (Дня)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Недель" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Месяцев" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Настроенные часы могут быть только списком часов, разделенных запятыми " "(например, 8,12,18,23) или */3 для периодического резервного копирования " "каждые 3 часа." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH-прокси" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Хост:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Порт:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Пользователь:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Вопрос:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Запустить 'rsync' с '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "как задача cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "на удаленном сервере" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "при создании снимков вручную" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Чтобы включить эту опцию, установите 'nocache'." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "на локальной машине" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Перенаправление stdout в /dev/null в cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron автоматически отправит результат работы команд если в системе " "установлен MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Перенаправление stderr в /dev/null в заданиях cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron автоматически отправит ошибки работы команд на почту, если в системе " "установлен MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "КБ/сек" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Ограничение полосы пропускания rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Сохранять ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Сохранять дополнительные атрибуты (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Копировать небезопасные ссылки (работает только с абсолютными ссылками)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "В пределах одной файловой системы" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Параметры должны быть заключены в кавычки, например: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Вставьте дополнительные опции в rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Префикс для каждой выполняемой на удаленном узле команды." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Переменные должны быть экранированы с помощью \\$FOO. Это не касается rsync." " Поэтому для добавления префикса для rsync используйте «{example_value}» с " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "по умолчанию" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Добавить префикс для SSH команд" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Проверка наличия удаленного узла в сети" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Предупреждение: если отключено и удаленный хост недоступен, это может " "вызвать странные ошибки." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Проверьте, поддерживает ли удаленный хост все необходимые команды." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Внимание: если команда отключена и удаленный хост не поддерживает все " "необходимые команды, это может вызвать странные ошибки." #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "по умолчанию" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "отключено" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "включено" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Режим:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Место для сохранения резервных копий" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Найстроки SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Путь:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "шифр:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Приватный ключ:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Выберите существующий файл приватного ключа (обычно с именем\"id_ed25519\" " "или \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Создать новый SSH-ключ без пароля (не допускается, если файл закрытого ключа" " уже выбран)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Пароль" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Сохранить пароль в связку ключей" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Закешировать пароль для Cron (Внимание: root может прочитать пароль)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Дополнительно" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Полный путь снимка:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Не был выбран закрытый ключ для SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Хотите ли вы сгенерировать новую пару открытого/закрытого ключей без пароля?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Файл приватного ключа \"{file}\" не существует." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Вы хотите скопировать свой открытый SSH-ключ на удаленный узел, чтобы " "обеспечить вход в систему без пароля?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Подлинность хоста {host} не может быть установлена." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Отпечаток ключа {keytype}:" #: qt/manageprofiles/tab_general.py:536 #, fuzzy msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Пожалуйста, проверьте этот отпечаток! Вы хотите добавить его в файл " "'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Вы уверены, что хотите изменить каталог для хранения резервных копий?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Не удалось создать новый SSH-ключ в {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Включить уведомления" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Отключить создание резервных копий при работе от батареи" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Статус питания недоступен" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Одновременный запуск только одного снимка" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Другие снимки будут блокироваться до тех пор, пока не завершится текущий " "снимок. Это глобальная опция. Поэтому она будет влиять на все профили " "данного пользователя. Но необходимо активировать ее и для всех остальных " "пользователей." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Резервное копирование замененных файлов при восстановлении" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Более новые версии файлов перед восстановлением будут переименованы " "дописыванием {suffix}. Если они вам больше не нужны, то можно удалить их " "командой {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Игнорировать ошибки (сохранять незавершенные копии)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Использовать контрольную сумму для обнаружения изменений" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Сделать новый снимок независимо от наличия изменений." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Уровень журнала:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Нет" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Не удалять переименованные снимки." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Не удалять переименованные снимки." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Лет (Года)" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Удалить снимок" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Запустить в фоновом режиме на удаленном хосте." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Хранить все копии за последние" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 #, fuzzy msgid "day(s)." msgstr "дней." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Хранить дневную копию за последние" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Хранить недельную копию за последние" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "неделя(ль)." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Хранить месячную копию за последние" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "месяц(ев)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Хранить все копии за последние" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Если свободно меньше, чем:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Если свободных inode'ов меньше, чем:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Удалить старые резервные копии" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Вопрос" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Профиль: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Просмотреть последний журнал" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Запустить {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Работаю…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Отправлено:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Скорость:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "До завершения:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Резервные копии" #: qt/qttools.py:506 msgid "Today" msgstr "Сегодня" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Вчера" #: qt/qttools.py:522 msgid "This week" msgstr "Эта неделя" #: qt/qttools.py:529 msgid "Last week" msgstr "На прошлой неделе" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Это НЕ снимок, а живой вид ваших локальных файлов" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Последняя проверка {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Импорт конфигурации" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Не найдено конфигурации" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Импорт" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Если каталог находится в сети или на съемном диске, его сначала нужно " "примонтировать вручную." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Показать весь лог" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Параметры сравнения снимков" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Команда:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Параметры:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Использовать %1 и %2 для комманды" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Задайте команду diff или нвжмите «Отмена»." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Команда «{cmd}» не найдена в системе. Выберите другую или нажмите «Отмена»." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Для команды diff не заданы аргументы. Используется значение по умолчанию " "«{params}»." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Только различающиеся снимки" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Только снимки, равные:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Глубокая проверка (более точная, но медленная)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Удалить" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Выделить всё" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Сравнение" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Перейти к" #: qt/snapshotsdialog.py:196 #, fuzzy msgid "Options" msgstr "Параметры" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Нельзя сравнивать резервную копию саму с собой." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Вы действительно хотите удалить файл {file} в снимке {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Вы действительно хотите удалить \"{file}\" в {count} снимках?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "ВНИМАНИЕ: Это не может быть отменено." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Исключить {path} из будущих снимков?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Содержимое папки резервного копирования не должно быть включено." backintime-1.5.4/common/po/sk.po000066400000000000000000002005221477034762000165250ustar00rootroot00000000000000# Slovak translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # Tomáš Vadina , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-15 21:25+0000\n" "Last-Translator: nostragodus \n" "Language-Team: Slovak \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" "X-Poedit-Country: SLOVAKIA\n" "X-Poedit-Language: Slovak\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Varovanie" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hlavný profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokálny (EncFS šifrovanie)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS šifrovanie)" #: common/config.py:278 msgid "Local" msgstr "Lokálny" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privátny kľúč" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokálne šifrovanie" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Šifrovanie" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH šifrovanie" #: common/config.py:296 msgid "Default" msgstr "Predvolené" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Adresár snímok nie je platný." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Pre zálohovanie musí byť vybraný aspoň jeden adresár." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Adresár: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Tento adresár nemôže byť zahrnutý do zálohovania, pretože je súčasťou " "samotného cieľa zálohovania." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Nepodarilo sa zapísať nový crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron nebeží, hoci príkaz crontab je dostupný. Plánované úlohy zálohovania sa" " nespustia. Cron môže byť nainštalovaný, ale nie povolený. Skúste príkaz " "\"systemctl enable cron\" alebo sa obráťte na podporu vašej distribúcie " "GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Pravidlo pre profil {profile_id} nebolo definované. Služba DBus pre " "'{dbus_interface}' nie je dostupná" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev plánovanie nefunguje s režimom {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nepodarilo sa nájsť UUID pre {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Nepodarilo sa uložiť konfiguráciu" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nepodarilo sa načítať konfiguráciu" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" už existuje." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Posledný profil sa nedá odstrániť." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nepodarilo sa pripojiť '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Konfigurácia šifrovaného priečinka nebola nájdená." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Vytvoriť nový šifrovaný priečinok?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Zrušiť" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Prosím, potvrďte heslo." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Heslo sa nezhoduje." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Urobiť snímku" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Nepodarilo sa odpojiť {mountprocess} z {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} sa nenašiel. Nainštalujte ho (napríklad pomocou " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Bod pripojenia {mntpoint} nie je prázdny." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Zadajte heslo pre {mode} profilu \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "ZLYHANIE" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Obnoviť oprávnenia" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Hotovo" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Zálohovanie odložené pri behu na batériu" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Nie je možné vytvoriť priečinok snímok." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Ak je na vymeniteľnom disku, pripojte ho, prosím." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čakám %s sekúnd." msgstr[1] "Čakám %s sekundu." msgstr[2] "Čakám %s sekundy." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Zlyhalo vytváranie snímky {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Prosím, buďte trpezliví. Dokončuje sa…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Nie je možné vytvoriť priečinok." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Uložiť konfiguračný súbor…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Ukladám práva…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "" "Bola nájdená zvyšková snímka {snapshot_id}, v ktorej je možné pokračovať." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Odstraňujem zvyškový priečinok {snapshot_id} z predchádzajúceho spustenia" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Priečinok nie je možné odstrániť" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Robím snímok" #: common/snapshots.py:1430 msgid "Success" msgstr "Hotovo" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Prenos bol čiastočný kvôli chybe" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Čiastočny prenos kvôli zmiznutému zdrojovému súboru (pozri 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' ukončený s kódom {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Pozri 'man rsync' pre viac detailov" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negatívne ukončovacie kódy rsync sú čísla signálov, pozrite si 'kill -l' a " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nič sa nezmenilo, nová snímka nie je potrebná" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Nie je možné premenovať {new_path} na {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Inteligentné odstránenie" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Použiť pravidlá na odstránenie starých snímok" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Použiť politiku uchovávania" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Pracujem na minimálnom voľnom mieste" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Pokúšam sa udržať minimálne {perc} voľných i-uzlov" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Teraz" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nepodarilo sa pripojiť {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent nebol nájdený. Uistite sa, že je nainštalovaný." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nepodarilo sa odomknúť súkromný kľúč SSH. Nesprávne heslo alebo heslo nie je" " dostupné pre cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Šifra {cipher} zlyhala pre {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Vzdialená cesta existuje, ale nie je to adresár." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Vzdialená cesta nie je zapisovateľná." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Vzdialená cesta nie je spustiteľná." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nepodarilo sa vytvoriť vzdialenú cestu." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Vzdialený hostiteľ {host} nepodporuje {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Pozrite si 'man backintime' pre ďalšie inštrukcie" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kontrola príkazov na hostiteľovi {host} vrátila neznámu chybu" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Vzdialený hostiteľ {host} nepodporuje pevné odkazy" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Skopírovať verejný SSH kľúč \"{pubkey}\" na vzdialeného hostiteľa \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Prosím, zadajte heslo pre \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Cieľový súborový systém pre {path} je formátovaný pomocou NTFS, ktorý má " "známe nekompatibility so súborovými systémami typu Unix." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} nie je platný adresár." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Vytvorenie nasledujúceho adresára zlyhalo:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Prístup pre zápis môže byť obmedzený." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Cieľový súborový systém pre {path} je formátovaný pomocou FAT, ktorý " "nepodporuje pevné odkazy. Použite natívny súborový systém GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Cieľový súborový systém pre {path} je zdieľaný disk pripojený cez SMB. " "Uistite sa, že vzdialený server SMB podporuje symbolické odkazy alebo " "aktivujte \"{copyLinks}\" v \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopírovať odkazy (znefunkční symbolické odkazy)" #: common/tools.py:504 msgid "Expert Options" msgstr "Pokročilé nastavenia" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Cieľový súborový systém pre {path} je zdieľane pripojený cez sshfs. Sshfs " "nepodporuje pevné odkazy. Použite režim \"SSH\" namiesto toho." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Vytvorenie súboru v tomto adresári zlyhalo:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O programe" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autori" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Preklady" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licencia" #: qt/app.py:172 msgid "Shortcuts" msgstr "Skratky" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Tento adresár neexistuje\n" " v aktuálne vybranej snímke." #: qt/app.py:257 msgid "Add to Include" msgstr "Pridať do zahrnutých" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Pridať do vylúčených" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Zdá sa, že {app_name} sa spúšťa prvýkrát, pretože nebola nájdená žiadna " "konfigurácia." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importovať existujúcu konfiguráciu (z cieľového adresára zálohy alebo iného " "počítača)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Ak je na vymeniteľnom disku, pripojte ho a potom stlačte OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Urobiť snímku" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Použiť čas úpravy a veľkosť na detekciu zmien súborov." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Vytvoriť snímku (režim kontrolného súčtu)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Použiť kontrolný súčet pre zistenie zmien." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pozastaviť proces snímky" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Obnoviť proces snímky" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Zastaviť proces snímky" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Obnoviť zoznam snímok" #: qt/app.py:497 msgid "Name snapshot" msgstr "Urobiť snímku" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Odstrániť snímku" #: qt/app.py:505 msgid "View snapshot log" msgstr "Zobraziť záznam snímok" #: qt/app.py:509 msgid "View last log" msgstr "Zobraziť posledný log" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Hlavný profil…" #: qt/app.py:517 msgid "Shutdown" msgstr "Vypnúť" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Vypnúť systém po dokončení snímky." #: qt/app.py:521 msgid "Setup language…" msgstr "Nastaviť jazyk…" #: qt/app.py:525 msgid "Exit" msgstr "Koniec" #: qt/app.py:529 msgid "User manual" msgstr "Používateľská príručka" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Otvoriť používateľskú príručku v prehliadači (lokálne, ak je k dispozícii, " "inak online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "stránka manuálu: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Zobrazí stránku manuálu o Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "stránka manuálu: Konfiguračný súbor profilov" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Zobrazí stránku manuálu o konfiguračnom súbore profilov (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Webová stránka projektu" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Otvoriť webovú stránku aplikácie Back In Time v prehliadači" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Zoznam zmien" #: qt/app.py:555 msgid "FAQ" msgstr "Často kladené otázky (FAQ)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Otvoriť často kladené otázky (FAQ) v prehliadači" #: qt/app.py:559 msgid "Ask a question" msgstr "Položiť otázku" #: qt/app.py:563 msgid "Report a bug" msgstr "Nahlásiť chybu" #: qt/app.py:566 msgid "Translation" msgstr "Preklad" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Znova zobraziť správu o účasti na preklade." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Prechod na šifrovanie (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Znova zobraziť správu o odstránení EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Obnoviť" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Obnoviť vybrané súbory alebo adresáre do pôvodného cieľa." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Obnoviť …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Obnoviť vybrané súbory alebo adresáre do nového cieľa." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Obnoviť aktuálne zobrazený adresár a celý jeho obsah do pôvodného cieľa." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Obnoviť aktuálne zobrazený adresár a celý jeho obsah do nového cieľa." #: qt/app.py:601 msgid "Up" msgstr "Hore" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Ukázať skryté súbory" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Urobiť snímku…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kandidát na vydanie" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Znova zobraziť správu o tomto kandidátovi na vydanie." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Záloha" #: qt/app.py:692 msgid "&Restore" msgstr "&Obnoviť" #: qt/app.py:698 msgid "&Help" msgstr "&Pomocník" #: qt/app.py:743 msgid "Icons only" msgstr "Iba ikony" #: qt/app.py:746 msgid "Text only" msgstr "Iba text" #: qt/app.py:749 msgid "Text below icons" msgstr "Text pod ikonami" #: qt/app.py:752 msgid "Text beside icon" msgstr "Text vedľa ikony" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ak zatvoríte toto okno, Back In Time nebude môcť vypnúť váš systém po " "dokončení snímky." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Naozaj to chcete zavrieť?" #: qt/app.py:1072 msgid "Working:" msgstr "Pracujem:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Hotovo, záloha nie je potrebná" #: qt/app.py:1129 msgid "Working" msgstr "Prebieha" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Chyba" #: qt/app.py:1161 msgid "Sent" msgstr "Odoslané" #: qt/app.py:1162 msgid "Speed" msgstr "Rýchlosť" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "Globálne" #: qt/app.py:1226 msgid "Root" msgstr "Koreňový priečinok" #: qt/app.py:1227 msgid "Home" msgstr "Domovský priečinok" #: qt/app.py:1255 msgid "Backup directories" msgstr "Adresár záloh" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Názov snímky" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Ste si istí, že chcete odstrániť snímky?" msgstr[1] "Ste si istí, že chcete odstrániť snímku?" msgstr[2] "Ste si istí, že chcete odstrániť snímky?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Vytvoriť záložné kópie s príponou {suffix}\n" "pred prepísaním alebo odstránením lokálnych prvkov." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Novšie verzie súborov budú pred obnovením premenované s príponou {suffix}. " "Ak ich už nepotrebujete, môžete ich odstrániť pomocou nasledujúceho príkazu:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Obnoviť iba prvky, ktoré neexistujú alebo\n" "sú novšie ako tie v mieste určenia.\n" "Používa sa možnosť \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Odstrániť novšie prvky v pôvodnom adresári." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Obnoviť vybrané súbory alebo adresáre do pôvodného cieľa a odstrániť súbory " "alebo adresáre, ktoré nie sú v snímke. Buďte mimoriadne opatrní, pretože " "toto odstráni súbory a adresáre, ktoré boli vylúčené počas vytvárania " "snímky." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Naozaj chcete obnoviť tieto prvky do nového adresára?" msgstr[1] "Naozaj chcete obnoviť tento prvok do nového adresára?" msgstr[2] "Naozaj chcete obnoviť tieto prvky do nového adresára?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Naozaj chcete obnoviť tieto prvky?" msgstr[1] "Naozaj chcete obnoviť tento prvok?" msgstr[2] "Naozaj chcete obnoviť tieto prvky?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Naozaj chcete odstrániť všetky novšie súbory v {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Naozaj chcete odstrániť všetky novšie súbory v pôvodnom adresári?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Upozornenie{BOLDEND}: Odstránenie súborov v koreňovom adresári " "súborového systému môže poškodiť celý váš systém." #: qt/app.py:1857 msgid "Snapshot" msgstr "Snímka" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Obnoviť {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Obnoviť {path} …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Dobrý deň,\n" "aplikáciu Back In Time v jazyku: {language} ste otvorili už viackrát.\n" "Preklad nainštalovanej verzie aplikácie Back In Time do jazyka: {language} je hotový na {perc}. Bez ohľadu na úroveň vašich technických znalostí môžete pomôcť s prekladom aplikácie, čím podporíte aj samotný projekt Back In Time.\n" "Ak chcete pomôcť, navštívte webovú stránku {translation_platform_url}. Viac informácií nájdete na webovej stránke {back_in_time_project_website}.\n" "Za vyrušenie sa ospravedlňujeme, táto správa sa už znovu nezobrazí. Toto dialógové okno nájdete kedykoľvek v menu Pomoc.\n" "Back In Time tím" #: qt/app.py:2071 msgid "translation platform" msgstr "prekladateľská platforma" #: qt/app.py:2076 msgid "Website" msgstr "Webová stránka" #: qt/app.py:2090 msgid "Your translation" msgstr "Váš preklad" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Na Fediverse na Mastodone: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-mail na {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Poštová konferencia {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} na webovej stránke projektu." #: qt/app.py:2118 msgid "Open an issue" msgstr "Nahlásiť problém" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Prípadne môžete použiť iný kanál podľa vlastného výberu." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Táto verzia aplikácie Back In Time je kandidátom na vydanie a je určená predovšetkým na testovanie stability v rámci prípravy na nasledujúce oficiálne vydanie.\n" "Nezhromažďujú sa žiadne používateľské údaje ani telemetria. Tím aplikácie Back In Time má však veľký záujem vedieť, či sa kandidát na vydanie používa a či sa oplatí pokračovať v poskytovaní takýchto predbežných verzií.\n" "Preto tím láskavo žiada o krátku spätnú väzbu o tom, či ste túto verziu testovali, aj keď ste nenarazili na žiadne problémy. Aj rýchle testovanie v priebehu niekoľkých minút by nám veľmi pomohlo.\n" "K dispozícii sú nasledujúce možnosti kontaktu:\n" "{contact_list}\n" "V tejto verzii sa táto správa už nezobrazí, ale bude k nej možné kedykoľvek pristupovať cez ponuku Pomocník.\n" "Ďakujeme vám za vašu podporu a za pomoc pri zlepšovaní aplikácie Back In Time!\n" "Váš tím aplikácie Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Nastavenie jazyka sa zmení po reštartovaní aplikácie Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Vytváranie profilov EncFS bude odstránené v nasledujúcom menšom vydaní " "(1.7), plánovanom na rok 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Používanie tohto režimu pre profil sa už neodporúča." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "odbornej štúdii" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Podpora pre EncFS sa ukončuje z dôvodu bezpečnostných zraniteľností." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Pre viac informácií, vrátane potenciálnych alternatív, si prosím pozrite v " "tejto {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Nasledujúce profily používajú šifrovanie s EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "Pripravujeme náhradu, ale nemôžeme zaručiť, že bude pripravená včas." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Používatelia sú pozvaní zapojiť sa do tejto diskusie. Aktualizované " "podrobnosti o ďalších krokoch sú k dispozícii v tejto {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Táto správa sa už nebude zobrazovať. Toto dialógové okno je k dispozícii " "kedykoľvek cez ponuku Pomocník." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Váš tím Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Nastavenie jazyka" #: qt/languagedialog.py:97 msgid "System default" msgstr "Predvolené nastavenie" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Použiť jazyk operačného systému." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Preložené na: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Posledný záznam z denníka" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Záznam z denníka snímky" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Snímky:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Všetko" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Zmeny" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Chyby" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informácie" msgstr[1] "Informácia" msgstr[2] "Informácie" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Zlyhania prenosu rsync (experimentálne)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Chyba, [I] Informácia, [C] Zmena" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekódovanie ciest" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Hlavný profil" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Zmeň" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Pridať" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Odstráň" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Hlavné" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Zahrnúť" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Zahrňuje súbory a adresáre" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Pridať súbor" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Pridať adresár" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Vylúčiť" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Informácia{ENDBOLD}: V režime \"Šifrované cez SSH\" sú funkčné iba " "jednoduché alebo dvojité hviezdičky (napr. {example2}). Ostatné typy " "zástupných znakov a vzorov budú ignorované (napr. {example1}). Názvy súborov" " sú v tomto režime nepredvídateľné kvôli šifrovaniu pomocou EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Vylúčiť vzory, súbory alebo adresáre" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Pridať predvolené" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Vylúčiť súbor:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Vylúčiť súbory väčšie ako hodnota v {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Pri vypnutom režime \"Úplný rsync režim\" to ovplyvní iba nové súbory, " "pretože pre rsync je toto možnosť prenosu, nie možnosť vylúčenia. Preto " "veľké súbory, ktoré boli predtým zálohované, zostanú v snímkach, aj keď boli" " upravené." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Odstrániť & Zachovať" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Možnosti" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Možnosti e&xpertov" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Obnoviť konfiguráciu" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Upraviť užívateľskú spätnú väzbu" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nový profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Premenovať profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Určite chcete vymazať profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Dôrazne odporúčané{ENDBOLD}: (Všetky odporúčania už zahrnuté.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Dôrazne odporúčané{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Vylúčiť vzor" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Vylúčiť súbor" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Vylúčiť adresár" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Zahrnúť súbor" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" je symbolický odkaz. Prepojený cieľ nebude zálohovaný, pokiaľ ho tiež nezahrniete.\n" "Chcete namiesto toho zahrnúť cieľ symbolického odkazu?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Zahrnúť adresár" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Zakázané, pretože tento vzor nie je funkčný v režime \"Šifrované cez SSH\"." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Plánovanie" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Deň:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Deň v týždni:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Čas:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Hodina:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "minút po hodine" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minúty:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Spustiť Back In Time hneď po pripojení disku (iba raz za X dní). Budete " "vyzvaný na zadanie vášho sudo hesla." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Spúšťať Back In Time opakovane. Toto je užitočné, ak počítač nie je spúšťaný" " pravidelne." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Každých:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Povoliť zapisovanie ladiacich správ do denníka" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Zapisuje správy na úrovni ladenia do systémového denníka pomocou \"--" "debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Upozornenie: Používajte len dočasne na diagnostiku, pretože je generované " "veľké množstvo výstupu." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Zakázané" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Pri každom štarte/reštarte" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Každých {n} minút" msgstr[1] "Každú {n} minútu" msgstr[2] "Každé {n} minúty" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Každých {n} hodín" msgstr[1] "Každú hodinu" msgstr[2] "Každé {n} hodiny" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Každých {n} hodín" msgstr[1] "Každú {n} hodinu" msgstr[2] "Každé {n} hodiny" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Voliteľné hodiny" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Každý deň" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Opakovane (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Po pripojení disku (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Každý týždeň" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Každý mesiac" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Každý rok" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Hodiny" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dni" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Týždne" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mesiace" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Voliteľné hodiny môžu byť iba zoznam hodín oddelených čiarkami (napr. " "8,12,18,23) alebo */3 pre pravidelné zálohy každé 3 hodiny." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Server:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Používateľ:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Pripojiť sa k cieľovému hostiteľovi cez tento proxy server (známy aj ako " "jump host). Podrobnosti nájdete v \"-J\" v dokumentácii príkazu \"ssh\" " "alebo v \"ProxyJump\" v manuálovej stránke \"ssh_config\"." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Upozornenie:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Tieto možnosti sú pre pokročilé konfigurácie. Upravujte ich len vtedy, ak si" " plne uvedomujete ich dôsledky." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Spustiť 'rsync' s '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "ako úloha cronu" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "na vzdialenom hostiteľovi" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "pri vytváraní manuálnej snímky" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Prosím, nainštalujte 'nocache' na povolenie tejto možnosti." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na lokálnom počítači" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Presmerovať stdout do /dev/null v cron úlohách." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron automaticky odošle e-mail s pripojeným výstupom cron úloh, ak je " "nainštalovaný MTA." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Presmerovať stderr do /dev/null v cron úlohách." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron automaticky odošle e-mail s pripojenými chybami cron úloh, ak je " "nainštalovaný MTA." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Obmedziť rýchlosť prenosu rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Zachovať ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Zachovať rozšírené atribúty (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopírovať nebezpečné odkazy (funguje len s absolútnymi odkazmi)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Obmedziť na jeden súborový systém" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Možnosti musia byť v úvodzovkách, napr. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Vložte dodatočné možnosti pre rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Predpona na spustenie pred každým príkazom na vzdialenom hostiteľovi." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Premenné je potrebné escapovať pomocou \\$FOO. Toto sa netýka rsync. Takže " "pre pridanie predpony pre rsync použite \"{example_value}\" s " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "predvolené" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Pridať predponu k SSH príkazom" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Overiť, či je vzdialený hostiteľ online" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Upozornenie: Ak je táto možnosť vypnutá a vzdialený hostiteľ nie je " "dostupný, môže to viesť k zvláštnym chybám." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Overiť, či vzdialený hostiteľ podporuje všetky potrebné príkazy." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Upozornenie: Ak je táto možnosť vypnutá a vzdialený hostiteľ nepodporuje " "všetky potrebné príkazy, môže to viesť k zvláštnym chybám." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(predvolené: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "zakázané" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "povolené" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Režim:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kam sa uložia snímky" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH Nastavenia" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Cesta:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šifra:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privátny kľúč:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Vyberte existujúci súbor privátneho kľúča (zvyčajne s názvom \"id_ed25519\" " "a v starších nastaveniach \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Vytvoriť nový SSH kľúč bez hesla (nie je povolené, ak už je vybratý súbor " "privátneho kľúča)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Heslo" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Uložiť Heslo do Kľúčenky" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Uložiť Heslo do vyrovnávacej pamäte pre Cron (Bezpečnostný problém: root " "môže čítať heslo)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Pokročilé" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Úplná cesta k snímke:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Nevybrali ste súbor privátneho kľúča pre SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Chcete vygenerovať nový bezheslový pár verejný/privátny kľúč?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Súbor privátneho kľúča \"{file}\" neexistuje." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Chcete skopírovať svoj verejný SSH kľúč na vzdialeného hostiteľa, aby ste " "povolili bezheslové prihlásenie?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autenticita hostiteľa {host} nemôže byť overená." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Odtlačok {keytype} kľúča je:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Prosím, overte tento odtlačok. Chcete ho pridať do vášho súboru " "'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Naozaj chcete zmeniť adresár snímok?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Nepodarilo sa vytvoriť nový SSH kľúč v {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Povoliť upozornenia" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Nevytvárať snímky pokiaľ systém beží na batérii" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Nie je možné zistiť stav napájania" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Spustiť len jednu snímku naraz" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Ostatné snímky budú blokované, kým sa aktuálna snímka nedokončí. Toto je " "globálna možnosť. Takže ovplyvní všetky profily pre tohto používateľa. Ale " "musíte to aktivovať aj pre všetkých ostatných používateľov." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Zálohovať nahradené súbory pri obnovení" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Novšie verzie súborov budú pred obnovením premenované s koncovkou {suffix}. " "Ak ich už nepotrebujete, môžete ich odstrániť pomocou {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Pokračovať pri chybách (zachovať nekompletné snímky)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Použiť kontrolný súčet pre zistenie zmien" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Vytvoriť novú snímku bez ohľadu na to, či došlo k zmenám." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Úroveň záznamu:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Žiadne" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Nasledujúce pravidlá sa spracúvajú zhora nadol. Neskôr uvedené pravidlá " "prepíšu skoršie a nie sú nimi obmedzené. Podrobnosti a príklady nájdete v " "{manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "užívateľská príručka" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Otvoriť používateľskú príručku v prehliadači." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Ponechať najnovšiu snímku." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "Posledná alebo najnovšia snímka sa uchová za každých okolností." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Tento priebeh sa nedá zmeniť." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Ponechať pomenované snímky." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Snímky, ktorým bol okrem bežnej časovej pečiatky priradený aj názov, budú " "uchované za každých okolností a nebudú odstránené." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Roky" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Odstrániť snímky staršie ako" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Celé dni. Aktuálny deň sa ignoruje." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Kalendárne týždne s pondelkom ako prvým dňom. Aktuálny týždeň sa ignoruje." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12-mesačné obdobia. Aktuálny mesiac sa ignoruje." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Pravidlá uchovávania" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Spustiť na pozadí na vzdialenom hostiteľovi." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Procedúra inteligentného odstraňovania sa spustí priamo na vzdialenom " "počítači, nie lokálne. Príkazy \"bash\", \"screen\" a \"flock\" musia byť " "nainštalované a dostupné na vzdialenom počítači." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Ak je vybraté, Back In Time najprv otestuje vzdialený počítač." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dni sa počítajú od dnešného dňa." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Uchovať všetky snímky za posledných" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Počet dní." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Uchovať poslednú snímku z každého dňa za posledných" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Týždne sa počítajú od aktuálneho prebiehajúceho týždňa. Týždeň začína v " "pondelok." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Uchovať poslednú snímku z každého týždňa za posledných" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Týždne." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Mesiace sa počítajú ako kalendárne mesiace, počnúc aktuálnym mesiacom." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Uchovať poslednú snímku z každého mesiaca za posledných" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mesiac(e)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Roky sa počítajú ako kalendárne roky, počnúc aktuálnym rokom." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Uchovať poslednú snímku z každého roka za" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "všetky roky." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… voľný priestor je menší ako" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… voľné i-uzly sú menšie ako" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Odstrániť najstaršie snímky, ak …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Otázka" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Zobraziť posledný log" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Spustiť {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Prebieha…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Odoslané:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Rýchlosť:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snímky" #: qt/qttools.py:506 msgid "Today" msgstr "Dnes" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Včera" #: qt/qttools.py:522 msgid "This week" msgstr "Tento týždeň" #: qt/qttools.py:529 msgid "Last week" msgstr "Minulý týždeň" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Toto NIE JE snímka, ale živý náhľad vašich lokálnych súborov" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Posledná kontrola {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importovať konfiguráciu" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Nenašla sa žiadna konfigurácia" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importovať" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Vyberte adresár snímky, z ktorého sa má importovať konfiguračný súbor. Cesta" " môže vyzerať napríklad takto: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Ak sa adresár nachádza na externom alebo vzdialenom disku, musí byť predtým " "manuálne pripojený." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Zobraziť celý záznam" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Možnosti porovnávania snímok" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Príkaz:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametre:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Použiť %1 a %2 parametre cesty" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Prosím, nastavte príkaz diff alebo stlačte Zrušiť." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Príkaz \"{cmd}\" sa v tomto systéme nenašiel. Skúste niečo iné alebo stlačte" " Zrušiť." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Pre príkaz diff neboli nastavené žiadne parametre. Používa sa predvolená " "hodnota \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Iba odlišné snímky" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Zoznam snímok, ktoré sú rovné:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Hĺbková kontrola (presnejšia, ale pomalšia)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Vymazať" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Vybrať všetko" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Porovnať" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Ísť na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Možnosti" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nemôžete porovnávať snímku s ňou samou." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Naozaj chcete odstrániť {file} zo snímky {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Naozaj chcete odstrániť {file} v {count} snímkach?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "UPOZORNENIE: Nie je možné odvolať." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Vylúčiť {path} z budúcich snímok?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Pod-priečinok Zálohy nemože byť zahrnutý." backintime-1.5.4/common/po/sl.po000066400000000000000000001662561477034762000165450ustar00rootroot00000000000000# msgid "" msgstr "" "Project-Id-Version: Back In Time 0.9.10\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-21 12:46+0000\n" "Last-Translator: buhtz \n" "Language-Team: Slovenian \n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" "X-Poedit-Country: SLOVENIA\n" "X-Poedit-Language: Slovenian\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Opozorilo" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Glavni profil" #: common/config.py:266 #, fuzzy msgid "Local (EncFS encrypted)" msgstr "Lokalno šifrirano" #: common/config.py:267 #, fuzzy msgid "SSH (EncFS encrypted)" msgstr "SSH šifrirano" #: common/config.py:278 msgid "Local" msgstr "Lokalno" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Privatni ključ SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalno šifrirano" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Šifriranje" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH šifrirano" #: common/config.py:296 msgid "Default" msgstr "Privzeto" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "Mapa s posnetki ni veljavna!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Obnovi {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Podmape za varnostne kopije ni mogoče vključiti." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Novega crontaba ni mogoče zapisati." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Ni bilo mogoče namestiti pravila Udev za profil {profile_id}. Storitev DBus " "'{dbus_interface}' ni bila na voljo" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Razpored udev ne deluje z načinom {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Ni bilo mogoče najti UUID za {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Konfiguracije ni bilo mogoče shraniti" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Konfiguracije ni bilo mogoče naložiti" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" že obstaja." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Zadnjega profila ni mogoče odstraniti." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Ni mogoče namestiti '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Ni mogoče najti konfiguracije za šifrirano mapo." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Želite ustvariti novo šifrirano mapo?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Prekliči" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Prosim potrdite geslo." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Geslo se ne ujema." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ustvari posnetek" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "{mountprocess} ni bilo mogoče odklopiti iz {mountpoint}." #: common/mount.py:709 #, fuzzy, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} ni mogoče najti. Namestite ga prosim (npr. z \"{installcommand}\"" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Točka priklopa {mntpoint} ni prazna." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Vpišite geslo za profil {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "SPODLETELO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Obnovi dovoljenja" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Končano" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Odložitev varnostnega kopiranja med delovanjem na bateriji" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Imenik za posnetke ni na razpolago." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "Če je na izmenljivem pogonu, ga priključite in pritisnite OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čakanje %s sekund." msgstr[1] "Čakanje %s sekundo." msgstr[2] "Čakanje %s sekundi." msgstr[3] "Čakanje %s sekunde." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Posnetek {snapshot_id} ni uspel." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Mape ni mogoče ustvariti" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Shranjevanje konfiguracijske datoteke…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Shranjevanje dovoljenj…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Najden ostanek {snapshot_id}, ki ga je mogoče nadaljevati." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Odstranjevanje ostankov mape {snapshot_id} od zadnjega zagona" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Mape ni mogoče odstraniti" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Ustvarjanje posnetka" #: common/snapshots.py:1430 msgid "Success" msgstr "Uspeh" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Delni prenos zaradi napake" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Delni prenos zaradi izginulih izvornih datotek (glej 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' se je končal z izhodno kodo {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Za več informacij glej 'man rsync'" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negativne izhodne kode rsync so signalne številke, glej 'kill -l' in 'man " "kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nič se ni spremenilo, nov posnetek ni potreben" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "{new_path} ni mogoče preimenovati v {path}" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Pametno odstranjevanje" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Odstranjevanje starih posnetkov" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Poskus ohranjanja minimalnega prostora" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Poskus ohranjanja najmanj {perc} prostih inodov" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Zdaj" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs} ni bilo mogoče namestiti" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent ni bil najden. Prepričajte se, da je nameščen." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Zasebnega ključa ssh ni bilo mogoče odkleniti. Napačno geslo ali geslo ni na" " voljo za cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Šifra {cipher} ni uspela za {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Oddaljena pot obstaja, ampak ni mapa." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Oddaljena pot ni zapisljiva." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Oddaljena pot ni izvršljiva." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Oddaljene poti ni bilo mogoče ustvariti." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Oddaljeni gostitelj {host} ne podpira {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Za več navodil, glej 'man backintime'" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Ukazi za preverjanje na gostitelju {host} so vrnili neznano napako" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Oddaljeni gostitelj {host} ne podpira trdih povezav" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopiraj javni ssh-ključ \"{pubkey}\" na oddaljenega gostitelja \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Prosim vpišite geslo za \"{user}\"." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Ciljni datotečni sistem za {path} je formatiran s FAT, ki ne podpira trdih " "povezav. Uporabite lastni datotečni sistem Linux." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Oddaljena pot obstaja, ampak ni mapa." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Ciljni datotečni sistem za {path} je formatiran s FAT, ki ne podpira trdih " "povezav. Uporabite lastni datotečni sistem Linux." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Ciljni datotečni sistem za {path} je SMB priklopjen v skupno rabo. " "Preverite, ali oddaljeni strežnik SMB podpira simbolne povezave ali " "aktivirajte {copyLinks} v {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiraj povezave (dereferenciraj simbolne povezave)" #: common/tools.py:504 msgid "Expert Options" msgstr "Napredne možnosti" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Ciljni datotečni sistem za {path} je priklopljen v skupno rabo s protokolom " "sshfs . Sshfs ne podpira trdih povezav. Namesto tega uporabite način 'SSH'." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O programu" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Avtorji" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Prevodi" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenca" #: qt/app.py:172 msgid "Shortcuts" msgstr "Bližnjice" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ta mapa ne obstaja\n" "v trenutno izbranem posnetku." #: qt/app.py:257 msgid "Add to Include" msgstr "Dodaj v Vključi" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Dodaj v Izključi" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Zgleda, da ste prvič zagnali {app_name}, ker ni mogoče najti konfiguracije." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Uvozi obstoječo konfiguracijo (iz imenika varnostne kopije ali iz drugega " "računalnika)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Če je na izmenljivem pogonu, ga priključite in pritisnite OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ustvari posnetek" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Za zaznavanje datotečnih sprememb uporabite čas in velikost." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ustvari posnetek (način checksum)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Za zaznavanje datotečnih sprememb uporabite checksum." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Začasno ustavi postopek posnetka" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Nadaljuj postopek posnetka" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Ustavi postopek posnetka" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Osveži seznam posnetkov" #: qt/app.py:497 msgid "Name snapshot" msgstr "Imenuj posnetek" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Odstrani posnetek" #: qt/app.py:505 #, fuzzy msgid "View snapshot log" msgstr "Ogled dnevnika posnetkov" #: qt/app.py:509 msgid "View last log" msgstr "Ogled zadnjega dnevnika" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Upravljanje profilov…" #: qt/app.py:517 msgid "Shutdown" msgstr "Zaustavi" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Zaustavite sistem, ko je posnetek končan." #: qt/app.py:521 msgid "Setup language…" msgstr "Nastavitev jezika…" #: qt/app.py:525 msgid "Exit" msgstr "Izhod" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Konfiguracijska datoteka profilov" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Dnevnik sprememb" #: qt/app.py:555 msgid "FAQ" msgstr "Pogosta vprašanja" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Postavite vprašanje" #: qt/app.py:563 msgid "Report a bug" msgstr "Prijavite napako" #: qt/app.py:566 msgid "Translation" msgstr "Prevod" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Obnovi" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Obnovi izbrane datoteke ali mape v prvotni cilj." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Obnovi v …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Obnovi izbrane datoteke ali mape v nov cilj." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "Obnovi trenutno prikazano mapo in vso njeno vsebino v prvotni cilj." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Obnovi trenutno prikazano mapo in vso njeno vsebino v nov cilj." #: qt/app.py:601 msgid "Up" msgstr "Gor" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Pokaži skrite datoteke" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Primerjava posnetkov…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&VarnostnaKopija" #: qt/app.py:692 msgid "&Restore" msgstr "&Obnovi" #: qt/app.py:698 msgid "&Help" msgstr "&Pomoč" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Če zaprete to okno, Back In Time ne bo mogel ugasniti vašega sistema, ko se " "posnetek stanja zaključi." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Ali res želite zapreti okno?" #: qt/app.py:1072 msgid "Working:" msgstr "V obdelavi:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Narejeno, varnostna kopija ni potrebna" #: qt/app.py:1129 msgid "Working" msgstr "V obdelavi" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Napaka" #: qt/app.py:1161 msgid "Sent" msgstr "Poslano" #: qt/app.py:1162 msgid "Speed" msgstr "Hitrost" #: qt/app.py:1163 msgid "ETA" msgstr "Predvideni čas" #: qt/app.py:1225 msgid "Global" msgstr "Splošno" #: qt/app.py:1226 msgid "Root" msgstr "Koren" #: qt/app.py:1227 msgid "Home" msgstr "Domov" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Mape za varnostno kopijo" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Ime posnetka" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Ali res želite odstraniti te posneteke?" msgstr[1] "Ali res želite odstraniti ta posnetek?" msgstr[2] "Ali res želite odstraniti ta posnetka?" msgstr[3] "Ali res želite odstraniti te posnetke?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Preden prepišete ali odstranite lokalne datoteke,\n" "ustvarite varnostne kopije s pripono {suffix}." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Imenom novejših različic datotek bo pred obnovitvijo dodana pripona " "{suffix}. Če jih ne potrebujete več, jih lahko odstranite z ukazom {cmd}" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Obnovi le datoteke, ki ne obstajajo ali\n" "so novejše od tistih na ciljni lokaciji.\n" "Uporablja možnost \"rsync --update\"." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Odstrani novejše datoteke v prvotni mapi." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Obnovite izbrane datoteke ali mape na prvotno ciljno lokacijo in odstranite " "datoteke ali mape, ki jih ni v posnetku. Bodite zelo previdni, saj bo to " "odstranilo datoteke in mape, ki so bile izključene med ustvarjanjem " "posnetka." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Ali res želite obnoviti te elemente v novo mapo\n" "{path}?" msgstr[1] "" "Ali res želite obnoviti ta element v novo mapo\n" "{path}?" msgstr[2] "" "Ali res želite obnoviti ta elementa v novo mapo\n" "{path}?" msgstr[3] "" "Ali res želite obnoviti te elemente v novo mapo\n" "{path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ali res želite obnoviti te elemente?" msgstr[1] "Ali res želite obnoviti ta element?" msgstr[2] "Ali res želite obnoviti ta elementa?" msgstr[3] "Ali res želite obnoviti te elemente?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Ali res želite zbrisati vse novejše datoteke v {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Ali res želite odstraniti vse novejše datoteke v svoji originalni mapi?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}POZOR{BOLDEND}: Brisanje datotek v korenskem datotečnem sistemu lahko " "pokvari ves sistem." #: qt/app.py:1857 msgid "Snapshot" msgstr "Posnetek" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Obnovi {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Obnovi {path} v …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Pozdravljeni!\n" "Back In Time v jeziku {language} ste do zdaj že nekajkrat uporabljali.\n" "Prevod vaše nameščene verzije Back In Time v {language} je {perc} dokončan. Ne glede na vaš nivo na tehničnega znanja, lahko prispevate k prevodu in s tem k samemu projektu Back In Time.\n" "Če želite prispevati, obiščite {translation_platform_url}. Za dodatno pomoč in vprašanja, prosimo obiščite {back_in_time_project_website}.\n" "Opravičujemo se za prekinitev, to sporočilo ne bo več prikazano. To pogovorno okno je kadar koli na voljo prek menija za pomoč.\n" "Vaša ekipa Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "prevajalna platforma" #: qt/app.py:2076 msgid "Website" msgstr "Spletna stran" #: qt/app.py:2090 msgid "Your translation" msgstr "Vaš prevod" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Nastavitve jezika se uveljavijo po ponovnem zagonu Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 #, fuzzy msgid "Your Back In Time Team" msgstr "Back In &Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Nastavitev jezika" #: qt/languagedialog.py:97 msgid "System default" msgstr "Sistemsko privzeto" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Uporabi jezik operacijskega sistema." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Prevedeno: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Ogled zadnjega dnevnika" #: qt/logviewdialog.py:62 #, fuzzy msgid "Snapshot Log View" msgstr "Ogled dnevnika posnetkov" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Posnetki:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Vse" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Spremembe" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Napake" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informacij" msgstr[1] "Informacija" msgstr[2] "Informaciji" msgstr[3] "Informacije" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Neuspešni prenosi rsync (eksperimentalno)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Napake, [I] Informacije, [C] Spremembe" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dešifriranje poti" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Upravljanje profilov" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Uredi" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Dodaj" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Odstrani" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Splošno" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Vključitev" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Vključi datoteke in mape" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dodaj datoteko" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Dodaj mapo" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Izključitev" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: V načinu 'SSH Šifrirano' so delujoče zamo enojne ali " "dvojne zvezdice (npr. {example2}). Drugi tipi znakov in vzorcev bodo " "ignorirani (npr. {example1}). Imena datotek so v tem načinu nepredvidljiva " "zaradi šifriranja EncFS." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Izključi vzorce, datoteke ali mape" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Dodaj privzeto" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Izključi datoteke večje kot:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Izključi datoteke večje kot {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Če je 'Full rsync mode' izklopljen, bo to vplivalo le na nove datoteke, ker " "je za rsync to prenosna opcija, ne izjema. Tako bodo velike datoteke, ki so " "bile varnostno kopiranje že prej, ostale v posnetkih, tudi če so se " "spremenile." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Možnosti" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Napredne nastavitve" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Obnovi konfiguracijo" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Uredi user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Nov profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Preimenuj profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Ali ste prepričani, da želite izbrisati profil \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Močno priporočljivo{ENDBOLD}: (Vsa priporočila so že vključena.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Zelo priporočljivo{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Izključitveni vzorec" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Izključi datoteko" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Izključi mapo" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Vključi datoteko" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" je symlink. Povezani cilj ne bo varnostno kopiran, dokler ga ne vključite.\n" "Ali namesto tega želite vključiti cilj symlinka?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Vključi mapo" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Onemogočeno, ker ta vzorec ni delujoč v načinu 'SSH Šifrirano'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Časovni razpored" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dan:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Dan v tednu:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Ur:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Zaženi Back In Time takoj, ko se disk poveže (zgolj enkrat na X dni).\n" "Od vas bo zahtevan vpis korenskega gesla." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Zaženi Back In Time večkrat. To služi za primer, ko računalnik ni redno " "prižgan." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Vsakih:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Omogoči beleženje razhroščevalnih sporočil" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Zapiše razhroščevalna poročila v sistemsko beleženje z uporabo \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Pozor: uporabite samo začasno za odpravljanje napak, ker ustvari zelo veliko" " podatkov." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Onemogočeno" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Ob vsakem zagonu/ponovnem zagonu" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Vsakih {n} minut" msgstr[1] "Vsako {n} minuto" msgstr[2] "Vsake {n} minute" msgstr[3] "Vsake {n} minute" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Vsakih {n} ur" msgstr[1] "Vsakih {n} uro" msgstr[2] "Vsaki {n} uri" msgstr[3] "Vsake {n} ure" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Vsakih {n} ur" msgstr[1] "Vsako {n} uro" msgstr[2] "Vsake {n} ure" msgstr[3] "Vsake {n} ure" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Ure po meri" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Vsak dan" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Ponavljajoče (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Ko se priključi disk (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Vsak teden" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Vsak mesec" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Vsako leto" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Ura/ur" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dan/dni" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Teden/tednov" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mesec/mesecev" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Ure po meri so lahko samo seznam ur, ločenih z vejicami (npr. 8,12,18,23) " "ali */3 za občasne varnostne kopije vsake 3 ure." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Gostitelj:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Vrata:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Uporabnik:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Poveži se do gostitelja preko tega strežnika (imenovan tudi jump host). " "Preberite podrobnosti glede \"-J\" v dokumentaciji ukaza \"ssh\" ali " "\"ProxyJump\" v strani priročnika man za \"ssh_config\"." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Vprašanje" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Poženi 'rsync' z ukazom '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "kot nalogo cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "na oddaljenem gostitelju" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "pri ročnem ustvarjanju posnetka" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Da lahko omogočite to možnost morate namestiti 'nocache')" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na lokalnem računalniku" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "V periodičnih opravilih preusmeri stdout na /dev/null." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Če je MTA nameščen, bo Cron samodejno poslal e-pošto s priloženimi cronjobi." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "V periodičnih opravilih preusmeri stderr na /dev/null." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Če je MTA nameščen, bo Cron samodejno poslal e-pošto s priloženimi napakami " "cronjobov." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Omeji pasovno širino za rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Ohrani ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Ohrani razširjene atribute (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopiraj ne varne povezave (deluje samo z absolutnimi povezavami)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Omejitev na en datotečni sistem" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Možnosti morajo biti v narekovajih, npr. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Prilepite dodatne možnosti za rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Predpona za zagon pred vsemi ukazi na oddaljenem gostitelju." #: qt/manageprofiles/tab_expert_options.py:310 #, fuzzy, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Spremenljivke je treba ubežati z \\$FOO. To se ne dotika rsync. Za dodajanje" " predpone za rsync uporabite \"{example_value}\" z {rsync_options_value}" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "privzeto" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Dodaj predpono ukazom SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Preveri ali je oddaljeni gostitelj povezan" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Opozorilo: v primeru, da je ta možnost onemogočena in oddaljeni gostitelj ni" " dosegljiv se lahko pojavijo nenavadne napake." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Preverite ali oddaljeni gostitelj podpira vse potrebne ukaze." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Opozorilo: v primeru, da je ta možnost onemogočena in oddaljeni gostitelj ne" " podpira vseh potrebnih ukazov, se lahko pojavijo nenavadne napake." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(privzeto: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "onemogočeno" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "omogočeno" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Način:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Kam naj se shranijo posnetki" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Nastavitve SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Pot:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šifriranje:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Zasebni ključ:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Izberite obstoječo datoteko z zasebnim ključem (običajno imenovano " "\"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 #, fuzzy msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Ustvari nov ključ SSH brez gesla (ni dovoljeno, če je datoteka z zasebnim " "ključem že izbrana)" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Geslo" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Shrani geslo v zbirko ključev" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Začasno shrani geslo za Cron (Varnostno tveganje: root uporabnik lahko " "prebere geslo)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Napredno" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Celotna pot posnetka:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Niste izbrali zasebnega ključa za SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Ali želite ustvariti nov par javnih/zasebnih ključev brez gesla?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Datoteka z zasebnim ključem \"{file}\" ne obstaja." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Ali bi želeli kopirati svoj javni SSH ključ na oddaljenega gostitelja za " "vključitev brezgeselne prijave?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Pristnosti gostitelja {host} ni bilo mogoče vspostaviti." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Prstni odtis ključa {keytype} je:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Prosimo, preverite ta prstni odtis! Ali bi ga želeli dodati v vašo " "'known_hosts' datoteko?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Ali res želite zamenjati mapo s posnetki?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Novega SSH ključa v {path} ni bilo mogoče ustvariti" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Omogoči prikaz obvestil" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Med porabo baterije onemogoči zajemanje posnetkov" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Stanje o porabi energije ni na voljo" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Poženi le en zajem posnetka naenkrat" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Drugi zajemi posnetkov bodo blokirani do konca trenutnega zajema. To je " "globalna opcija, zato bo vplivala na vse profile tega uporabnika. Toda to " "možnost morate vklopiti tudi za druge uporabnike." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Pri obnovitvi naredi kopijo zamenjanih datotek" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Imenom novejših različic datotek bo pred obnovitvijo dodana pripona " "{suffix}. Če jih ne potrebujete več, jih lahko odstranite z ukazom {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Nadaljuj klub napakam (obdrži nepopolne posnetke)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Za zaznavanje sprememb uporabite checksum" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ustvari nov posnetek, tudi če ni bilo sprememb." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivo beleženja:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Brez" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Ne odstranjuj posnetkov z imenom." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Ne odstranjuj posnetkov z imenom." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Leto/Let" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Odstrani posnetek" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Zagon v ozadju na oddaljenem gostitelju." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Obdrži vse posnetke za zadnjih" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dan/dni." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Obdrži en posnetek na dan za zadnjih" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Obdrži en posnetek na teden za zadnjih" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "teden/tednov." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Obdrži en posnetek na mesec za zadnjih" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mesec/mesecev." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Obdrži vse posnetke za zadnjih" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Če je prostega prostora manj od:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Če je prostih inod manj kot:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Odstranjevanje starih posnetkov" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Vprašanje" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Ogled zadnjega dnevnika" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Zaženi {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "V obdelavi…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Poslano:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hitrost:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Posnetki" #: qt/qttools.py:506 msgid "Today" msgstr "Danes" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Včeraj" #: qt/qttools.py:522 msgid "This week" msgstr "Ta teden" #: qt/qttools.py:529 msgid "Last week" msgstr "Prejšnji teden" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "To NI posnetek, ampak ogled vaših trenutnih lokalnih datotek" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Zadnj pregled {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Uvoz konfiguracije" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Konfiguracija ni najdena" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Uvoz" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Izberite mapo s posnetki, iz katere bo uvožena konfiguracijska datoteka. Pot" " lahko izgleda tako: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Če se mapa nahaja na zunanjem ali oddaljenem disku, se mora predhodno " "vmestiti." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Prikaži celoten dnevnik" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Nastavitve primerjave posnetkov" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Ukaz:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Uporabi %1 in %2 kot vrednosti za pot" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Prosimo nastavite diff ukaz ali izberite Prekliči." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Ukaz \"{cmd}\" ni bil našen na tem sistemu. Prosimo poskusite nekaj drugega " "ali izberite Prekliči." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Ni nastavljenih parametrov za diff ukaz. Uporabljena bo privzeta vrednost " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Samo različni posnetki" #: qt/snapshotsdialog.py:134 #, fuzzy msgid "List only snapshots that are equal to:" msgstr "Prikaži samo enake posnetke za: " #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Globinsko preverjanje (bolj natančno, a počasno)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Izbriši" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Izberi vse" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Primerjaj" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Pojdi na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Nastavitve" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Posnetka ni mogoče primerjati s samim sabo." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Ali res želite odstraniti {file} v {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ali res želite odstraniti {file} v {count} posnetkov?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "POZOR: Tega ni mogoče razveljaviti." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Želite izključiti {path} iz prihodnjih posnetkov?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Podmape za varnostne kopije ni mogoče vključiti." backintime-1.5.4/common/po/sr.po000066400000000000000000002231611477034762000165400ustar00rootroot00000000000000# Serbian translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-11 13:28+0000\n" "Last-Translator: buhtz \n" "Language-Team: Serbian \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Упозорење" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Главни профил" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Локално (криптовано са EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (криптовано са EncFS)" #: common/config.py:278 msgid "Local" msgstr "Локално" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH приватни кључ" #: common/config.py:283 msgid "Local encrypted" msgstr "Локално криптовано" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Енкрипција" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH криптовано" #: common/config.py:296 msgid "Default" msgstr "Подразумевано" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Профил: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Директоријум снимка није валидан." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Најмање један директоријум мора бити изабран за резервну копију." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Direktorijum: {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Директоријум не може бити укључен у резервну копију." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Неуспешно чување новог crontab-а." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron није покренут иако је команда crontab доступна. Заказани резервни " "послови неће се извршавати. Cron можда није инсталиран или није омогућен. " "Покушајте команду \"systemctl enable cron\" или се консултујте са каналима " "подршке ваше GNU/Linux дистрибуције." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Није могуће инсталирати Udev правило за профил {profile_id}. DBus сервис " "'{dbus_interface}' није био доступан" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev распоред не ради са режимом {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Није могуће пронаћи UUID за {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Неуспешно чување конфигурације" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Неуспешно учитавање конфигурације" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Профил \"{name}\" већ постоји." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Последњи профил не може бити уклоњен." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Није било могуће монтирати '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Конфигурација за шифровани директоријум није пронађена." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Да ли желите да креирате нови шифровани директоријум?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Откажи" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Молимо потврдите лозинку." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Лозинка се не поклапа." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Направи снимак" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Није било могуће одмонтирати {mountprocess} са {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} није пронађена. Молимо вас да је инсталирате (нпр. преко " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Монтирајућа тачка {mntpoint} није празна." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Унесите лозинку за {mode} профил \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "НЕУСПЕШНО" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Поврати дозволе" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Готово" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Одлагање резервне копије док је уређај на батерији" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Не могу да пронађем директоријум снимка." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Ако је на преносивом уређају, молимо прикључите га и затим притисните ОК." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Чекамо %s секунд." msgstr[1] "Чекамо %s секунде." msgstr[2] "Чекамо %s секунди." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Неуспешно прављење снимка {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Молимо будите стрпљиви. Завршавање…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Не могу да креирам директоријум." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Чување конфигурационог фајла…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Чување дозвола…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Пронађен је преостали снимак {snapshot_id} који може бити настављен." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Уклањање преосталог директоријума {snapshot_id} из последњег покретања" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Не могу да уклоним директоријум" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Прављење снимка" #: common/snapshots.py:1430 msgid "Success" msgstr "Успех" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Делимичан пренос због грешке" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Делимичан пренос због нестанка изворних фајлова (погледајте 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' је завршен са излазним кодом {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Погледајте 'man rsync' за више детаља" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Негативни излазни кодови rsync-а су бројеви сигнала, погледајте 'kill -l' и " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Ништа није промењено, није потребан нови снимак" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Није било могуће преименовати {new_path} у {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Паметно уклањање" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Уклањање старог снимка" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Покушавамо сачувати минимални слободан простор" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Покушавам да задржим мин {perc} слободних инода" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Сада" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Није било могуће монтирати {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent није пронађен. Молимо вас да осигурате да је инсталиран." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Нисам могао откључати ssh приватни кључ. Погрешна лозинка или лозинка није " "доступна за cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Шифра {cipher} није успела за {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Удаљена путања постоји али није директоријум." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Удаљена путања није уписива." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Удаљена путања није извршива." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Нисам могао креирати удаљену путању." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Удаљени домаћин {host} не подржава {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Погледајте 'man backintime' за даља упутства" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Провера команди на домаћину {host} вратила је непознату грешку" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Удаљени домаћин {host} не подржава тврде везе" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Копирај јавни ssh кључ \"{pubkey}\" на удаљени хост \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Молимо унесите лозинку за \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Одредишни фајл систем за {path} је форматиран са NTFS, који има познате " "некомпатибилности са Unix-стил фајл системима." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} није валидан директоријум." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Креирање следећег директоријума није успело:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Приступ за писање може бити ограничен." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Одредишни фајл систем за {path} је форматиран са FAT који не подржава хард-" "линкове. Молимо вас да користите нативни GNU/Linux фајл систем." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Одредишни фајл систем за {path} је монтиран преко SMB. Молимо вас да се " "уверите да удаљени SMB сервер подржава симболичке везе или активирајте " "\"{copyLinks}\" у \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Копирај везе (дереференцирај симболичке везе)" #: common/tools.py:504 msgid "Expert Options" msgstr "Опције за стручњаке" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Одредишни фајл систем за {path} је монтиран преко sshfs. Sshfs не подржава " "тврде везе. Молимо вас да користите режим \"SSH\" уместо sshfs." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Креирање фајла није успело у овом директоријуму:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "О апликацији" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Аутори" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Преводи" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Лиценца" #: qt/app.py:172 msgid "Shortcuts" msgstr "Пречице" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Овај директоријум не постоји\n" "у тренутном изабраном снимку." #: qt/app.py:257 msgid "Add to Include" msgstr "Додај у Укључења" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Додај у Искључења" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "Чини се да {app_name} ради први пут јер није пронађена конфигурација." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Увоз постојеће конфигурације (из резервне мета директоријума или другог " "рачунара)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Ако је на преносивом уређају, молимо прикључите га и затим притисните ОК." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Направи снимак" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Користи време измене и величину за детекцију промене фајла." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Направи снимак (режим контролне суме)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Користи контролне суме за детекцију промене фајла." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Паузирај процес снимања" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Настави процес снимања" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Заустави процес снимања" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Освежи листу снимка" #: qt/app.py:497 msgid "Name snapshot" msgstr "Именуј снимак" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Уклони снимак" #: qt/app.py:505 msgid "View snapshot log" msgstr "Погледај лог снимка" #: qt/app.py:509 msgid "View last log" msgstr "Погледај последњи лог" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Управљај профилима…" #: qt/app.py:517 msgid "Shutdown" msgstr "Искључивање" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Искључи систем након што снимак буде завршен." #: qt/app.py:521 msgid "Setup language…" msgstr "Подеси језик…" #: qt/app.py:525 msgid "Exit" msgstr "Излаз" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Конфигурациони фајл профила" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Дневник измена" #: qt/app.py:555 msgid "FAQ" msgstr "Честа питања" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Постави питање" #: qt/app.py:563 msgid "Report a bug" msgstr "Пријави грешку" #: qt/app.py:566 msgid "Translation" msgstr "Превод" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Поново приказује поруку о учешћу у преводу." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Прелазак на шифровање (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Поново приказује поруку о уклањању EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Поврати" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "Вратите изабране фајлове или директоријуме на оригиналну одредиште." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Поврати у …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Вратите изабране фајлове или директоријуме на нову одредиште." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Вратите тренутно приказани директоријум и све његове садржаје на оригинално " "одредиште." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Вратите тренутно приказани директоријум и све његове садржаје на ново " "одредиште." #: qt/app.py:601 msgid "Up" msgstr "Горе" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Прикажи скривене фајлове" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Упореди снимке…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Кандидат за објаву" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Поново приказује поруку о овом кандидату објаве." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Резервна копија" #: qt/app.py:692 msgid "&Restore" msgstr "&Врати" #: qt/app.py:698 msgid "&Help" msgstr "Помоћ" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ако затворите овај прозор, Back In Time неће моћи да искључи ваш систем када" " снимак буде завршен." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Да ли заиста желите да га затворите?" #: qt/app.py:1072 msgid "Working:" msgstr "Радим:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Завршено, снимање није потребно" #: qt/app.py:1129 msgid "Working" msgstr "Радим" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Грешка" #: qt/app.py:1161 msgid "Sent" msgstr "Послато" #: qt/app.py:1162 msgid "Speed" msgstr "Брзина" #: qt/app.py:1163 msgid "ETA" msgstr "Процењено време завршетка" #: qt/app.py:1225 msgid "Global" msgstr "Глобално" #: qt/app.py:1226 msgid "Root" msgstr "Корен (root)" #: qt/app.py:1227 msgid "Home" msgstr "Почетак" #: qt/app.py:1255 msgid "Backup directories" msgstr "Директоријуми резервне копије" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Име Снимка" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Да ли сте сигурни да желите да уклоните овај снимак?" msgstr[1] "Да ли сте сигурни да желите да уклоните ове снимке?" msgstr[2] "Да ли сте сигурни да желите да уклоните ове снимке?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Креирај резервне копије са завршетком {suffix}\n" "пре преписивања или уклањања локалних елемената." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Новије верзије фајлова ће бити преименоване са завршетком {suffix} пре " "враћања. Ако вам више нису потребни, можете их уклонити следећом командом:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Врати само елементе који не постоје или\n" "су новији од оних на одредишту.\n" "Користећи опцију \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Уклоните новије елементе у оригиналном директоријуму." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Вратите изабране фајлове или директоријуме на оригинално одредиште и " "обришите фајлове или директоријуме који нису у снимку. Будите изузетно " "опрезни јер ће ово обрисати фајлове и директоријуме који су били изостављени" " током прављења снимка." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Да ли заиста желите да вратите овај елемент у нови директоријум?" msgstr[1] "Да ли заиста желите да повратите ове елементе у нови директоријум?" msgstr[2] "Да ли заиста желите да повратите ове елементе у нови директоријум?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Да ли заиста желите да повратите овај елемент?" msgstr[1] "Да ли заиста желите да повратите ове елементе?" msgstr[2] "Да ли заиста желите да повратите ове елементе?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Да ли заиста желите да повратите све новије фајлове у {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Да ли сте сигурни да желите да уклоните све новије фајлове у вашем " "оригиналном директоријуму?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Упозорење{BOLDEND}: Брисање фајлова у корену фајл система може " "покварити цео ваш систем." #: qt/app.py:1857 msgid "Snapshot" msgstr "Снимак" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Поврати {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Врати {path} на …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Здраво\n" "Искористили сте Back In Time на {language} језику већ пар пута до сада.\n" "Превод ваше инсталиране верзије Back In Time-a у {language} је готова {perc}. Без обзира на ваш ниво техничког знања, можете помоћи преводу, и тиме помоћи Back In Time-u.\n" "Молимо вас да посетите {translation_platform_url} уколико желите да помогнете. За даљу помоћ и питања, молимо вас посетите {back_in_time_project_website}.\n" "Жао нам је што вас ометамо, а ова се порука више неће приказивати. Овај диалог је доступан у било ком тренутку у менију за помоћ.\n" "Ваш Back In Time тим" #: qt/app.py:2071 msgid "translation platform" msgstr "платформа за превод" #: qt/app.py:2076 msgid "Website" msgstr "Веб сајт" #: qt/app.py:2090 msgid "Your translation" msgstr "Ваш превод" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Имејл на {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Mailing list {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} на вебсајту пројекта." #: qt/app.py:2118 msgid "Open an issue" msgstr "Отворите питање" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Алтернативно, можете користити други канал по вашем избору." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Ова верзија Back In Time је кандидат за објаву и првенствено је намењена тестирању стабилности у припреми за следећу званичну објаву.\n" "Никакви подаци корисника или телеметрија се не прикупљају. Међутим, тим Back In Time је веома заинтересован да сазна да ли се кандидат за објаву користи и да ли вреди наставити са пружањем таквих верзија пре објаве.\n" "Стога, тим љубазно пита за кратке повратне информације о томе да ли сте тестирали ову верзију, чак и ако нисте наишли на било какве проблеме. Чак и брз тест од неколико минута би нам много помогао.\n" "Следеће опције контакта су доступне:\n" "{contact_list}\n" "У овој верзији, ова порука неће бити поново приказана, али ће бити доступна у било ком тренутку преко менија помоћи.\n" "Хвала вам на подршци и што нам помажете да побољшамо Back In Time!\n" "Ваш Back In Time тим" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Језичка подешавања ступају на снагу тек након поновног покретања Back In " "Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Подршка за EncFS ће бити прекинута у догледној будућности. Не препоручује се" " коришћење тог режима за профил убудуће." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "бели папир" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Следећи профил(и) користе шифровање са EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ова порука више неће бити приказана. Овај дијалог је доступан у било ком " "тренутку преко менија за помоћ." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Ваш Back In Time тим" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Подесите језик" #: qt/languagedialog.py:97 msgid "System default" msgstr "Подразумевано системско" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Користи језик оперативног система." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Преведено: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Приказ последњег дневника" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Приказ дневника снимка" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Профил:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Снимци:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Филтер:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Све" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Измене" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Грешке" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Информација" msgstr[1] "Информације" msgstr[2] "Информација" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync преносни неуспеси (експериментално)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Грешка, [I] Информација, [C] Измена" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "декодирај путање" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Управљај профилима" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Уреди" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Додај" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Уклони" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "Општ&е" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Укључи" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Укључи фајлове и директоријуме" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Додај фајл" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Додајте директоријум" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Искључи" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Информације{ENDBOLD}: У 'SSH шифровано' режиму, само једноструке или " "двоструке звездице су функционалне (нпр. {example2}). Други типови џокера и " "шаблона ће бити игнорисани (нпр. {example1}). Имена датотека су непредвидива" " у овом режиму због шифровања од стране EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Изоставите шаблоне, фајлове или директоријуме" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Додај подразумевано" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Изостави фајлове веће од:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Изостави фајлове веће од вредности у {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Са онемогућеним 'Full rsync mode', ово ће утицати само на нове фајлове јер " "је за rsync ово опција преноса, а не опција изостављања. Стога, велики " "фајлови који су претходно резервно копирани ће остати у снимцима чак и ако " "су модификовани." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Опције" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Е&ксперт Опције" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Поврати Конфигурацију" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Промени user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Нови профил" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Преименуј профил" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Да ли сте сигурни да желите да уклоните профил \"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Топло препоручено{ENDBOLD}: (Све препоруке су већ укључене.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Топло препоручено{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Изостави шаблон" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Изостави фајл" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Изоставите директоријум" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Укључи фајл" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" је симболичка веза. Повезана мета неће бити резервно копирана док је не укључите.\n" "Да ли желите да укључите мету симболичке везе?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Укључите директоријум" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Деактивирано зато што шаблони не функционишу у 'SSH шифрованом' моду." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "План рада" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Дан:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Радни дан:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Време:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Сати:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Покрени Back In Time чим се диск повеже (само једном сваког X дана). Од вас " "ће бити тражено да унесете своју sudo лозинку." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Покретање Back In Time узастопно. Ово је корисно ако се компјутер не користи" " често." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Сваких:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Омогућите евидентирање порука о грешкама" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Пише поруке нивоа дебаговања у системски лог преко \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Опасност: Користите ово само привремено за дијагностику, јер генерише велику" " количину излаза." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Онемогућено" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "При сваком покретању/рестарту" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Сваких {n} минут" msgstr[1] "Сваких {n} минута" msgstr[2] "Сваких {n} минута" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Сваки {n} сат времена" msgstr[1] "Сваких {n} сата времена" msgstr[2] "Сваких {n} сати времена" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Сваки {n} сат" msgstr[1] "Сваких {n} сата" msgstr[2] "Сваких {n} сати" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Прилагођени сати" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Сваког дана" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Учестало (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Када се диск повеже (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Сваке недеље" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Сваког месеца" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Сваке године" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Сат(и)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Дан(а)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Седмица" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Месец(и)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Прилагођени сати могу бити само листа сати одвојена зарезима (нпр. " "8,12,18,23) или */3 за периодичне резервне копије свака 3 сата." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH прокси" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Домаћин:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Порт:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Корисник:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Повежите се са циљним домаћином преко овог проксија (познатог и као jump " "host). Погледајте \"-J\" у документацији за \"ssh\" команду или " "\"ProxyJump\" у \"ssh_config\" man страници за детаље." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Упозорење:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Ове опције су за напредне конфигурације. Измените само ако сте у потпуности " "свесни њихових импликација." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Покрените 'rsync' са '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "као cron посао" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "на удаљеном домаћину" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "када се креира ручни снимак" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Молимо вас да инсталирате 'nocache' да бисте омогућили ову опцију." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "на локалној машини" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Преусмерите stdout ка /dev/null у cron пословима." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron ће аутоматски послати email са приложеним излазом cronjob-ова уколико " "је MTA инсталиран." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Преусмерите stderr према /dev/null у cron пословима." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron ће аутоматски послати email са приложеним грешкама од cronjob-ова " "уколико је MTA инсталиран." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/сек" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Ограничите употребу пропусног опсега rsync-а:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Сачувај ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Сачувај проширене атрибуте (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Копирај небезбедни линк (функционише само са апсолутним линковима)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Ограничите на само један фајл систем" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Опције морају бити под наводницима нпр. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Налепи додатне опције за rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Префикс који ће се покретати пре сваке команде на удаљеном домаћину." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Променљиве треба искочити са \\$FOO. Ово не дотиче rsync. Тако да би додали " "префикс за rsync користите \"{example_value}\" са {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "подразумевано" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Додај префикс SSH командама" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Провери да ли је удаљени домаћин онлајн" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Упозорење: уколико је онемогућено и удаљени домаћин није доступан, ово може " "довести до неких чудних грешака." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Проверите да ли удаљени домаћин подржава све неопходне команде." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Упозорење: уколико је онемогућено и удаљени домаћин не подржава све " "неопходне команде, ово може довести до неких чудних грешака." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(подразумевано: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "онемогућено" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "омогућено" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Мод:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Где да чувам снимке" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH Поставке" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Путања:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Шифра:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Приватни Кључ:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Изаберите постојећи приватни кључ фајл (обично именован \"id_ed25519\" а у " "старијим подешавањима \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Креирајте нови SSH кључ без лозинке (није дозвољено ако је фајл приватног " "кључа већ одабран)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Лозинка" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Сачувај лозинку у Keyring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Кеширај лозинку за Cron (Безбедносни проблем: root може читати лозинку)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Напредно" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Пуна путања снимка:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Нисте изабрали датотеку приватног кључа за SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Да ли желите да генеришете нови пар јавних/приватних кључева без лозинке?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Датотека приватног кључа у \"{file}\" не постоји." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Да ли желите да копирате ваш јавни SSH кључ на удаљеном домаћину за " "омогућавање пријаве без лозинке?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Аутентичност домаћина {host} се не може утврдити." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} отисак прста кључа је:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Молимо проверите овај отисак прста. Да ли желите да га додате у своју " "датотеку 'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Да ли сте сигурни да желите да промените директоријум снимка?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Креирање новог SSH кључа у {path} није успело." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Омогући обавештења" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Онемогући снимке када се рачунар напаја из батерије" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Информација о статусу напајања није доступна од система" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Покрени само један снимак у исто време" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Остали снимци ће бити блокирани док се тренутни снимак не заврши. Ово је " "глобална опција. Тако да ће утицати на све профиле за овог корисника. Али " "ово морате активирати и за све остале кориснике такође." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Резервна копија је заменила фајлове приликом враћања" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Новије верзије фајлова ће се преименовати са претечим {suffix} пре враћања. " "Ако вам више не требају, можете их уклонити помоћу {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Настави након грешке (задржи непотпун снимак)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Користи контролни број за примећивање промена" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Направи нови снимак без обзира да ли је било промена или не." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Ниво детаља у извештају:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Ниједан" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Чувајте именоване снимке." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Чувајте именоване снимке." #: qt/manageprofiles/tab_remove_retention.py:243 #, fuzzy msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Снимци који, поред уобичајене временске ознаке, имају дато име неће бити " "обрисани." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Година" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Уклони снимак" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Покрени у позадини на удаљеном домаћину." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Процедура паметног уклањања ће се извршити директно на удаљеној машини, а не" " локално. Команде \"bash\", \"screen\" и \"flock\" морају бити инсталиране и" " доступне на удаљеној машини." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Ако је изабрано, Back In Time ће прво тестирати удаљену машину." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Задржи све снимке за последњи" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "дан(а)." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Задржи један снимак дневно за последњи" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Задржи један снимак недељно за последњи" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "недеља/е." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Задржи један снимак месечно за последњи" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "месец(и)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Задржи све снимке за последњи" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Ако је слободан простор мањи од:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Ако је број слободних inode-ова мањи од:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Уклањање старог снимка" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Питање" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Профил: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Прикажи последњи извештај" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Покрени {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Радим…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Послато:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Брзина:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Процењено време завршетка:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Снимци" #: qt/qttools.py:506 msgid "Today" msgstr "Данас" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Јуче" #: qt/qttools.py:522 msgid "This week" msgstr "Ове недеље" #: qt/qttools.py:529 msgid "Last week" msgstr "Претходна седмица" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Ово НИЈЕ снимак, већ ужив приказ ваших локалних фајлова" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Задња провера {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Увези конфигурацију" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Конфигурација није пронађена" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Увези" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Изаберите директоријум снимка из којег треба да се увезе конфигурациони " "фајл. Путања може изгледати овако: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Ако се директоријум налази на спољном или удаљеном диску, мора бити ручно " "монтиран пре тога." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Прикажи целокупни дневник" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Опције о упоређивању снимака" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Команда:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Параметри:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Користи %1 и %2 као параметре за путање" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Молим поставите команду за тражење разлика или притисните Откажи." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Команда \"{cmd}\" није пронађена на овом систему. Молимо пробајте нешто " "друго или притисните Откажи." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Параметри нису постављени за команду за тражење разлика. Користиће се " "подразумевана вредност \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Само различити снимци" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Излистај само снимке једнаке следећим:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Дубока провера (прецизнија али спора)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Избриши" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Одабери Све" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Упореди" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Иди на" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Опције" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Не можете упоредити снимак са самим собом." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Да ли стварно желите да избришете {file} у снимку {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Да ли стварно желите да избришете {file} у {count} снимака?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "УПОЗОРЕЊЕ: Ово се не може опозвати." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Изостави {path} из будућих снимака?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Под-директоријуми не могу бити укључени у резервну копију." backintime-1.5.4/common/po/sr_Latn.po000066400000000000000000001773521477034762000175300ustar00rootroot00000000000000# Serbian translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-11 11:20+0000\n" "Last-Translator: Maki711 \n" "Language-Team: Serbian (Latin script) \n" "Language: sr_Latn\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Upozorenje" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Glavni profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalno (EncFS šifrovano)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS šifrovano)" #: common/config.py:278 msgid "Local" msgstr "Lokalno" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privatni ključ" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalno šifrovano" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Enkripcija" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH enkriptovano" #: common/config.py:296 msgid "Default" msgstr "Podrazumevano" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Direktorijum za snimak nije važeći." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Najmanje jedan direktorijum za rezerne kopije mora biti izabran." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Direktorijum: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Ovaj direktorijum ne može biti izabran za rezervne kopije pošto je deo " "ciljnog direktorijuma za kopije." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Neuspešno čuvanje novog crontab-a." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron nije pokrenut, uprkos tome što je crontab komanda dostupna. Zakazana " "rezervna kopija neće biti pokrenuta. Cron je možda instaliran ali nije " "omogućen. Isprobajte komandu \"systemctl enable cron\" ili kontaktirajte " "podršku za GNU/Linux distribuciju." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Neuspešno instaliranje Udev pravila za profil {profile_id}. DBus servis " "'{dbus_interface}' nije dostupan" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev raspored ne radi sa režimom {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Nije moguće naći UUID za {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Neuspešno čuvanje konfiguracije" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Neuspešno učitavanje konfiguracije" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profil \"{name}\" već postoji." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Poslednji profil se ne može ukloniti." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Nije moguće montirati '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Podešavanja za enkriptovani direktorijum nisu pronađena." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Napraviti novi enkriptovani direktorijum?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Otkazati" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Molimo potvrdite lozinku." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Lozinka se ne poklapa." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Napravi snimak" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Nije moguće demontirati {mountprocess} sa {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} nije pronađen. Molimo da ga instalirate (npr. sa " "\"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Tačka montiranja {mntpoint} nije prazna." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Unesi šifru za {mode} profil \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "NEUSPEŠNO" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Povrati dozvole" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Gotovo" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Odlaganje sigurnosne kopije dok je uređaj na bateriji" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Ne mogu da pronađem direktorijum snimaka." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Ako je na prenosivom disku, priključite ga." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Čeka se %s sekunda." msgstr[1] "Čeka se %s sekunde." msgstr[2] "Čeka se %s sekundi." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Neuspešno čuvanje snimka {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Molim vas budite strpljivi. Završavanje u toku…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Neuspešno kreiranje direktorijuma." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Čuvanje konfiguracionog fajla…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Čuvanje dozvola…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Pronađen preostali snimak {snapshot_id} koji se može nastaviti." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Uklanjanje preostalog direktorijuma {snapshot_id} iz poslednjeg pokretanja" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Neuspešno uklanjanje direktorijuma" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Pravljenje snimka" #: common/snapshots.py:1430 msgid "Success" msgstr "Uspelo" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Delimičan prenos zbog greške" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Delimičan prenos zbog iščezlih izvornih fajlova (pogledajte 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' se završio sa izlaznim kodom {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Pogledaj 'man rsync' za više detalja" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negativni rsync izlazni kodovi su signalni brojevi, pogledajte 'kill -l' i " "'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Nikakve promene, nepotreban novi snimak" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Neuspešno preimenovanje {new_path} u {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Pametno uklanjanje" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Primenite pravila za uklanjanje starih snimaka" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Primenite smernice čuvanja" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Pokušavam da zadržim minimalno slobodnog prostora" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Pokušavam da zadržim minimalno {perc} slobodnih inode-ova" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Sada" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Nemoguće montirati {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent nije pronađen. Molim vas da se uverite da je instaliran." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Nije moguće otključati ssh privatni ključ. Pogrešna lozinka ili lozinka nije" " dostupna za cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Šifrovanje {cipher} nije uspelo za {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Udaljena putanja postoji, ali nije direktorijum." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Udaljena putanja nije dostupan za pisanje." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Udaljena putanja nije izvršna." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Nije moguće kreirati udaljenu putanju." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Udaljena mašina {host} ne podržava {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Pogledajte 'man backintime' za dalja uputstva" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Provera komandi na mašini {host} vratila je nepoznatu grešku" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Udaljena mašina {host} ne podržava tvrde veze" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopiraj javni ssh-ključ \"{pubkey}\" na udaljenoj mašini \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Molim vas unesite lozinku za \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Ciljni sistem datoteka za {path} je formatiran u NTFS, koji ima poznate " "nekompatibilnost sa sistemima datoteka sličnim Unix-u." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "Putanja {path} nije važeći direktorijum." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Kreiranje sledećeg direktorijuma je bilo neuspešno:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Pristup za pisanje je možda ograničen." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Ciljni sistema datoteka za {path} je formatiran sa FAT koji ne podržava " "čvrste veze. Molim Vas da koristite izvorne sistemske datoteke GNU/Linux-a." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Ciljni sistema datoteke za {path} je deljeno mesto preko SMB. Molim Vas da " "potvrdite da udaljeni SMB server podržava symlinks ili uključite {copyLinks}" " u {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiraj linkove (prati simbolične linkove)" #: common/tools.py:504 msgid "Expert Options" msgstr "Napredne Postavke" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Ciljni sistema datoteka za {path} je deljeno mesto preko SSHFS koji ne " "podržava čvrste veze. Molimo vas da koristite 'SSH' umesto toga." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Kreiranje datoteke u ovom direktorijumu nije uspelo:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "O aplicaciji" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Autori" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Prevodi" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licenca" #: qt/app.py:172 msgid "Shortcuts" msgstr "Prečice" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Ovaj direktorijum ne postoji\n" "u aktuelnom snimku." #: qt/app.py:257 msgid "Add to Include" msgstr "Dodaj u listu inkluzija" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Dodaj u listu ekskluzija" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Izgleda da se {app_name} pokreće prvi put pošto konfiguracija nije " "pronađena." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Uvezite postojeću konfiguraciju (iz direktorijuma sa rezervnim kopijama ili " "sa drugog računara)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Ako se nalazi na prenosivom disku, molim vas priključite ga i pritisnete OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Napravi snimak" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Koristi vreme i veličinu za detekciju promene datoteka." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Napravi snimak (checksum režim)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Koristi checksum-ove za detekciju promene datoteka." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pauziraj proces snimanja" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Nastavi proces snimanja" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Zaustavi proces snimanja" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Osveži listu snimaka" #: qt/app.py:497 msgid "Name snapshot" msgstr "Imenuj snimak" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Ukloni snimak" #: qt/app.py:505 msgid "View snapshot log" msgstr "Pogledaj izveštaj snimka" #: qt/app.py:509 msgid "View last log" msgstr "Prikaži poslednji izveštaj" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Upravljaj profilima…" #: qt/app.py:517 msgid "Shutdown" msgstr "Gašenje" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Ugasi sistem nakon završetka snimka." #: qt/app.py:521 msgid "Setup language…" msgstr "Podesi jezik…" #: qt/app.py:525 msgid "Exit" msgstr "Izlaz" #: qt/app.py:529 msgid "User manual" msgstr "Uputstvo za upotrebu" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Otvorite uputstvo za upotrebu u pretraživaču (lokalno, ako je dostupno - " "inače onlajn)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "Man stranica: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Prikaži man stranicu o Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "Man stranica: Konfiguracioni fajl profila" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Prikaži man stranicu o konfiguracionalnom fajlu za profile (backintime-" "config)" #: qt/app.py:547 msgid "Project website" msgstr "Web stranica projekta" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Otvori Back In Time web stranicu u pretraživaču" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Izveštaj promena" #: qt/app.py:555 msgid "FAQ" msgstr "Česta pitanja (FAQ)" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Otvorite Često postavljana pitanja (FAQ) u pretraživaču" #: qt/app.py:559 msgid "Ask a question" msgstr "Postavi pitanje" #: qt/app.py:563 msgid "Report a bug" msgstr "Prijavi grešku" #: qt/app.py:566 msgid "Translation" msgstr "Prevod" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Ponovo prikaži poruku o učestvovanju u prevodu." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Prevod enkripcije (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Ponovo prikaži poruku o uklanjanju EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Povrati" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Povrati odabrane datoteke ili direktorijume na njihovu prvobitno odredište." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Povrati na …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Povrati odabrane datoteke ili direktorijume na novo odredište." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Povrati trenutno prikazan direktorijum i sav njegov sadržaj na prvobitno " "odredište." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Povrati trenutno prikazan direktorijum i sav njegov sadržaj na novo " "odredište." #: qt/app.py:601 msgid "Up" msgstr "Gore" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Prikaži skrivene datoteke" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Uporedi snimke…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Kandidat za izdavanje" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Ponovo prikaži poruku o kandidatu za izdavanje." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Rezervna kopija" #: qt/app.py:692 msgid "&Restore" msgstr "&Povratak" #: qt/app.py:698 msgid "&Help" msgstr "&Pomoć" #: qt/app.py:743 msgid "Icons only" msgstr "Samo ikonice" #: qt/app.py:746 msgid "Text only" msgstr "Samo tekst" #: qt/app.py:749 msgid "Text below icons" msgstr "Tekst ispod ikonica" #: qt/app.py:752 msgid "Text beside icon" msgstr "Tekst pored ikonica" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Ako zatvorite ovaj prozor Back In Time neće moći da ugasi vaš sistem kada se" " snimak završi." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Da li sigurno želite da ga zatvorite?" #: qt/app.py:1072 msgid "Working:" msgstr "U obradi:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Završeno, sigurnosna kopija nike potrebna" #: qt/app.py:1129 msgid "Working" msgstr "Obrada" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Greška" #: qt/app.py:1161 msgid "Sent" msgstr "Poslato" #: qt/app.py:1162 msgid "Speed" msgstr "Brzina" #: qt/app.py:1163 msgid "ETA" msgstr "Ostalo" #: qt/app.py:1225 msgid "Global" msgstr "Globalno" #: qt/app.py:1226 msgid "Root" msgstr "Izvorni direktorijum" #: qt/app.py:1227 msgid "Home" msgstr "Lični direktorijum" #: qt/app.py:1255 msgid "Backup directories" msgstr "Direktorijumi za rezervne kopije" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Ime snimaka" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Da li ste sigurni da želite da uklonite ovaj snimak?" msgstr[1] "Da li ste sigurni da želite da uklonite ove snimke?" msgstr[2] "Da li ste sigurni da želite da uklonite ove snimke?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Napravite rezervne kopije sa pratećim {suffix}\n" "pre pisanja preko ili uklanjanja lokalnih elemenata." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Novije verzije datoteka će se preimenovati sa pretećim {suffix} pre " "vraćanja. Ako vam više nisu potrebne, možete ih ukloniti pomoću komande:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Povratite samo elemente koji nepostoje ili\n" "su noviji od onih u odredištu.\n" "Ovo koristi \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Ukloni novije elemente u originalnom direktorijumu." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Povratite odabrane datoteke ili direktorijume na originalno odredište i " "izbrišite datoteke ili direktorijume koji se ne nalaze u snimku. Budite " "izuzetno oprezni jer će ovo obrisati datoteke i direktorijume koji su bili " "isključeni tokom pravljenja snimka." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Da li zaista želite da povratite ovaj element u novi direktorijum {path}?" msgstr[1] "" "Da li zaista želite da vratite ove elemente u novi direktorijum {path}?" msgstr[2] "" "Da li zaista želite da vratite ove elemente u novi direktorijum {path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Da li zaista želite da vratite ovaj element?" msgstr[1] "Da li zaista želite da vratite ove elemente?" msgstr[2] "Da li zaista želite da vratite ove elemente?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Da li ste sigurni da želite da uklonite sve novije datoteke u {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Da li ste sigurni da želite da uklonite sve novije datoteke u originalnom " "direktorijumu?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Upozorenje{BOLDEND}: Brisanje datoteka u izvornom sistemu datoteka " "može uništiti vaš ceo sistem." #: qt/app.py:1857 msgid "Snapshot" msgstr "Snimak" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Povrati {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Povrati {path} u …" # ignore-placeholder-compare #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Zdravo\n" "Koristili ste Back In Time na {language} jeziku već par puta.\n" "Prevod vaše instalirane verzije Back In Time-a u {language} je {perc} gotov. Bez obzira na vaše tehničko znanje, sami možete doprineti prevodu, a time i Back In Time-u.\n" "Molimo vas da posetite {translation_platform_url} ako želite da doprinesete. Za dalju pomoć i pitanja, posetite {back_in_time_project_website}\n" "Izvinjavamo se zbog ometanja. Ova poruka se više neće pojaviti, ali je dostupna u bilo kom trenutku iz menija Pomoć\n" "Vaš Back In Time tim" #: qt/app.py:2071 msgid "translation platform" msgstr "platforma za prevod" #: qt/app.py:2076 msgid "Website" msgstr "Veb stranica" #: qt/app.py:2090 msgid "Your translation" msgstr "Vaš prevod" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "U Fediverse na Mastodon-u: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email na {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Dopisna lista {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} na web stranici projekta." #: qt/app.py:2118 msgid "Open an issue" msgstr "Otvorite problem" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativno, možete koristiti drugi kanal po svom izboru." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Ova verzija Back In Time je kandidat za izdanje i prvenstveno je namenjena za testiranje stabilnosti u pripremi za sledeće zvanično izdanje.\n" "Korisnički podaci ili telemetrija se ne prikupljaju. Međutim, tim Back In Time je veoma zainteresovan da zna da li će kandidat za izdanje biti korišćen i da li je vredno nastaviti da nudi takve verzije pre izdanja.\n" "Stoga, tim ljubazno traži kratku povratnu informaciju o tome da li ste testirali ovu verziju, čak i ako niste naišli na probleme. Čak i kratko testiranje od samo nekoliko minuta bi nam mnogo pomoglo.\n" "Dostupne su sledeće opcije kontakta:\n" "{contact_list}\n" "U ovoj verziji, ova poruka se više neće prikazivati, ali joj se može pristupiti u bilo kom trenutku preko menija pomoći (Help).\n" "Hvala vam na podršci i što ste nam pomogli da poboljšamo Back In Time!\n" "Vaš Back In Time tim" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Podešavanja jezika stupaju na snagu tek nakon ponovnog pokretanja Back In " "Time-a." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Mogućnost kreiranja EncFS profila biće uklonjeno u sledećem manjem izdanju" " (1.7), zakazanom za 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Ne preporučuje se više da koristite taj modus za profile." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "beli papiri" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Podrška za EncFS se ukida zbog sigurnosnih propusta." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Za više detalja, uključujući potencijalne alternative, pročitajte " "{whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Sledeći profil odn. profili koriste enkripciju sa EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "U planu je zamena, ali nema garancije da će biti dostupna blagovremeno." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Korisnici su pozvani da učestvuju u ovim diskusijama. Ažurirani detalji o " "sledećim koracima dostupni su u ovom {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Ova poruka se više neće prikazati. Ova poruka je dostupna u svakom trenutku " "preko menija za pomoć." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Vaš Back In Time tim" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Podesite jezik" #: qt/languagedialog.py:97 msgid "System default" msgstr "Standardne sistemske opcije" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Koristi jezik operativnog sistema." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Prevedeno: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Prikaz zadnjeg protokola" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Prikaz protokola snimaka" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Snimci:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Sve" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Izneme" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Greške" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Informacija" msgstr[1] "Informacije" msgstr[2] "Informacija" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "neuspešni rsync prenosi (eksperimentalno)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Greška, [I] Informacija, [C] Izmena" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "dekodiraj putanju" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Upravljaj profilima" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Uredi" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Dodaj" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Ukloni" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "Opšt&e" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkludirano" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Inkludiraj datoteke i direktorijume" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dodaj datoteku" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Dodaj direktorijum" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Izostavi" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: U 'SSH šifrovanom' režimu rada, funkcionišu samo jedna " "ili dve zvezdica (primer {example2}). Ostali tipovi džokerskih znakova i " "obrazaca će biti ignorisani (primer {example1}). Imena datoteka su " "nepredvidljiva u ovom načinu rada zbog EncFS šifrovanja." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Izostavi šablone, datoteke, ili direktorijume" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Dodaj standardna podešavanja" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Izostavi datoteke veće od:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Izostavi datoteke veće od {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Kada je 'Full rsync mode' onemogućen, ovo će uticati samo na nove datoteke " "jer za rsync ovo je opcija za prenos, a ne opcija za izostavljanje. Tako da " "će velike datoteke za koje je ranije napravljena rezervna kopija ostati u " "snimcima čak i ako su se promenili." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Uklanjanje & Vremensko čuvanje" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Opcije" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Napredne opcije" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Povrati konfiguraciju" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Promeni user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Novi profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Preimenuj profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Da li ste sigurni da želite da uklonite profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Strogo preporučeno{ENDBOLD}: (Sve preporuke su već uključene.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Toplo preporučeno{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Izostavi šablon" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Izostavi fajl" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Izostavi direktorijum" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkludiraj datoteku" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" je simbolična veza. Povezana meta neće biti sigurnosno kopiran dok ga ne uključite.\n" "Da li želite da uključite metu simboličku veze?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Inkludiraj direktorijum" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Deaktivirano zato što ovaj šablon ne funkcioniše u 'SSH šifrovanom' režimu." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Plan rada" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dan:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Radni dan:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Vreme:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Sati:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "posle punog sata" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuti:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Pokreni Back In Time čim se disk poveže (samo jednom svakih X dana). Od vas " "će biti traženo da unesete svoju sudo lozinku." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Pokretanje Back In Time uzastopno. Ovo je korisno ako se kompjuter ne " "koristi često." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Svakih:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Omogućite evidentiranje poruka o greškama" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Zapiši poruke debug nivoa u sistemski protokol pomoću \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Oprez: ovo koristite samo privremeno za dijagnostiku, jer generiše veliku " "količinu informacija." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Onemogućeno" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Pri svakom pokretanju računara/restartu" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Svakog {n} minuta" msgstr[1] "Svakih {n} minuta" msgstr[2] "Svakih {n} minuta" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Svakog {n} sata" msgstr[1] "Svakih {n} sata" msgstr[2] "Svakih {n} sati" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Svakih {n} sat" msgstr[1] "Svakih {n} sati" msgstr[2] "Svakih {n} sati" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Prilagođeni sati" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Svakog dana" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Ponavljanje (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Kada se disk poveže (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Svake nedelje" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Svakog meseca" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Svake godine" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Sat(i)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dan(a)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Nedelja/(e)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Mesec(i)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Prilagođeni sati mogu biti samo lista sati razdvojena zarezima (npr. " "8,12,18,23) ili */3 za periodične sigurnosne kopije svakih 3 sata." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Proxy" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Mašina:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Korisnik:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Povežite te se sa željenom mašinom preko ovog proxy-a (poznatijeg kao Jump-" "Host). Za detalje pogledajte \"-J\" u dokumentaciji za \"ssh\" komandu ili " "\"ProxyJump\" na \"ssh_config\" man stranici." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Upozorenje:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Ove opcije su predviđene za napredne konfiguracije. Izmenite samo ako ste " "potpuno svesni njihovih implikacija." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Pokrenite 'rsync' sa '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "kao cron-job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "na udaljeno mašini" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "kada se kreira ručni snimak" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Molim vas instalirajte 'nocache' kako bi ste omogućili ovu opciju." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "na lokalnoj mašini" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Preusmerite stdout ka /dev/null u cronjob-u." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron će automatski poslati email sa izlaznim protokolom cronjob-ova ukoliko " "je MTA instaliran." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Preusmerite stderr prema /dev/null u cronjob-ovima." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron će automatski poslati email sa priloženim greškama od cronjob-ova " "ukoliko je MTA instaliran." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sek" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Ograniči upotrebu propusnog opsega rsync-a:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Održi ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Sačuvaj proširene atribute (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopiraj nebezbedne prečice (funkcioniše samo sa apsolutnim prečicama)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Ograniči na samo jedan sistem datoteka" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Opcije moraju biti pod navodnicima npr. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Nalepi dodatne opcije za rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefiks koji će se pokretati pre svake komande na udaljenoj mašini." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Varijable treba maskirati sa \\$FOO. Ovo ne utiče na rsync. Kako biste " "dodali prefix za rsync, koristite \"{example_value}\" sa " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standardno" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Dodaj prefiks SSH komandi" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Proveri da li je udaljena mašina onlajn" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Upozorenje: ukoliko je onemogućeno i udaljena mašina nije dostupna, ovo može" " dovesti do nekih čudnih grešaka." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Proveri da li udaljena mašina podržava sve neophodne komande." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Upozorenje: ukoliko je onemogućeno i udaljena mašina ne podržava sve " "neophodne komande, ovo može dovesti do nekih čudnih grešaka." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(podrazumevano: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "onemogućeno" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "omogućeno" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Režim:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Gde da čuvam snimke" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH Podešavanja" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Putanja:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Šifra:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privatni Ključ:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Izaberite postojeći fajl privatnog ključa (obično se zove \"id_ed25519\" ili" " na starijim mašinama \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Kreirajte novi SSH ključ bez lozinke (nije dozvoljeno ako je fajl privatnog " "ključa već odabran)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Lozinka" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Sačuvaj lozinku u Keyring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Keširaj lozinku za Cron (Sigurnosni problem: root može čitati lozinku)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Napredno" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Puna putanja snimka:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Niste izabrali datoteku privatnog ključa za SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Da li želite da generišete novi par javnih/privatnih ključeva bez lozinke?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Datoteka privatnog ključa \"{file}\" ne postoji." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Da li želite da kopirate vaš javni SSH ključ na udaljenom domaćinu za " "omogućavanje prijave bez lozinke?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autentičnost mašine {host} se ne može utvrditi." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} otisak prsta ključa je:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Molimo proverite ovaj otisak prsta! Da li želite da ga dodate u svoju " "datoteku 'known_hosts'?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Da li stvarno želite da promenite direktorijum za snimke?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Kreiranje novog SSH ključa u {path} nije uspelo." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Omogući obaveštenja" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Onemogući snimke kada se računar napaja iz baterije" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Informacija o status napajanja nije dostupna od sistema" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Pokreni samo jedan snimak u isto vreme" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Ostali snimci će biti blokirani dok se trenutni snimak ne završi. Ovo je " "globalna opcije. Tako da će uticati na sve profile za ovog korisnika. Ali " "ovo morate aktivirati i za sve ostale korisnike takođe." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Rezervna kopija je zamenila fajlove prilikom vraćanja" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Novije verzije fajlova će se preimenovati sa pretećim {suffix} prije " "vraćanja. Ako vam više ne trebaju, možete ih ukloniti pomoću {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Nastavi nakon greške (zadrži nekompletan snimak)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Користи контролни број за примећивање промена" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Napravi novi snimak bez obzira da li je bilo promena ili ne." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Nivo detalja u izveštaju:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Nijedan" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Sledeća pravila se obrađuju odozgore prema dole. Kasnija pravila " "prepisivaju preko ranijih i nisu njima ograničena. Pogledajte {manual} za " "detalje i primere." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "uputstvo za upotrebu" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Otvori uputstvo za upotrebu u pretraživaču." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Zadrži najnoviji snimak." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "Zadnji odn. najnoviji snimak se čuva u svim okolnostima." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "To ponašanje je nepromenljivo." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Zadrži imenovane snimke." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Snimci kojima je dato ime pored uobičajene vremenske oznake biće zadržani " "pod svim okolnostima i neće biti uklonjeni." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Година" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Ukloni snimak stariji od" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Puni dani. Trenutan dan biće ignorisan." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Kalendarske nedelje počevši od ponedeljka. Trenutna nedelja se ignoriše." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 meseci period. Trenutni mesec se ignoriše." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Pravila čuvanja" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Pokreni u pozadini na udaljenom domaćinu." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Procedura pametnog uklanjanja će se pokrenuti direktno na udaljenoj mašini," " a ne lokalno. Komande \"bash\", \"screen\" i \"flock\" moraju biti " "instalirane i dostupne na udaljenoj mašini." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Ako je izabrano, Back In Time će prvo isprobati udaljenu mašinu." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dani se računaju počevši od danas." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Zadrži sve snimke za poslednji" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "Dan(a)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Zadržite poslednji snimak za svaki dan za poslednji" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Nedelje se računaju počevši od trenutne tekuće nedelje. Nedelja počinje sa " "ponedeljkom." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Zadržite poslednji snimak svake nedelje za poslednje" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "Nedelja/e." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" "Meseci se računaju kao kalendarski meseci počevši od trenutnog tekućeg " "meseca." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Zadržite poslednji snimak svakog meseca za poslednje" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "mesec(i)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" "Godine se računaju kao kalendarske godine počevši od trenutne tekuće " "godine." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Zadrži poslednji snimak svake godine za" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "sve godine." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… ako je slobodan prostor manji od" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… ako je broj slobodnih inode-ova manji od" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Ukloni najstarije snimke ako …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Pitanje" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Prikaži poslednji protokol" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Pokreni {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Radim…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Poslato:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Brzina:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snimci" #: qt/qttools.py:506 msgid "Today" msgstr "Danas" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Juče" #: qt/qttools.py:522 msgid "This week" msgstr "Ove nedelje" #: qt/qttools.py:529 msgid "Last week" msgstr "Predhodne nedelje" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Ovo NIJE snimak, već aktuelan prikaz vaših lokalnih datoteka" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Zadnja provera {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Uvezi sertifikat" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Konfiguracije nije pronađena" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Uvezi" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Odaberite direktorijum za snimak iz koga konfiguracionu fajl treba da bude " "uvezen. Ova putanja može da izgleda kao: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Ukoliko se datoteka nalazi na lokalnom ili udaljenom disku, potrebno je " "unapred ručno montira disk." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Prikaži celokupni protokol" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Opcije o upoređivanju snimaka" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Komanda:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametri:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Користи %1 и %2 као параметре за путање" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Molim postavite diff komandu ili pritisnite otkaži." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Komanda \"{cmd}\" nije pronađena na ovom sistemu. Molimo probajte nešto " "drugo ili pritisnite otkaži." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Parametri nisu postavljeni za diff komandu. Koristiće se podrazumevane " "vrednosti \"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Samo različiti snimci" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Samo izlistaj snimke jednaki sa:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Detaljna provera (preciznija ali sporija)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Izbriši" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Odaberi sve" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Uporedi" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Idi na" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Opcije" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Nije moguće uporediti snimak sa samim sobom." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Da li stvarno želite da izbrišete {file} u snimku {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Da li stvarno želite da izbrišete {file} u {count} snimka?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "Upozorenja: Ovo se ne može opožvati." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Isključi {path} iz budućih snimaka?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Pod-direktorijum za rezervne kopije ne moze biti uključen." backintime-1.5.4/common/po/sv.po000066400000000000000000001776521477034762000165610ustar00rootroot00000000000000# Swedish translation for backintime # Copyright (c) 2008 Rosetta Contributors and Canonical Ltd 2008 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2008. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 13:42+0000\n" "Last-Translator: bittin \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Varning" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Huvudprofil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Lokalt (EncFS-krypterad)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS-krypterad)" #: common/config.py:278 msgid "Local" msgstr "Lokal" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH privat nyckel" #: common/config.py:283 msgid "Local encrypted" msgstr "Lokalt krypterad" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Kryptering" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH krypterad" #: common/config.py:296 msgid "Default" msgstr "Standard" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Mappen för ögonblicksavbilder är inte giltig." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Minst en katalog måste väljas för säkerhetskopiering." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Katalog: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Den här katalogen kan inte inkluderas i säkerhetskopian, eftersom att " "katalogen är en del av själva säkerhetskopian." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Misslyckades med att skriva ny crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron körs inte trots att crontab kommandot är tillgängligt. Schemalagda " "säkerhetskopieringsjobb kommer inte att köras. Cron kan vara installerat men" " inte aktiverat. Prova kommandot \"systemctl enable cron\" eller uppsök " "supportkanalerna för din GNU/Linux-distribution." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Kunde inte installera Udev-regel för profil {profile_id}. DBus-tjänst " "\"{dbus_interface}\" var inte tillgänglig" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev schema fungerar inte med läge {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Kunde inte hitta UUID för {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Misslyckades med att spara konfiguration" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Misslyckades med att ladda konfiguration" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Profilen \"{name}\" finns redan." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Den sista profilen kan inte tas bort." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Kan inte montera '{command}'" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Konfiguration för den krypterade katalogen hittades inte." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Skapa en ny krypterad katalog?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Avbryt" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Bekräfta lösenord." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Lösenord matchar inte." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Ta ögonblicksavbild" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Kund inte avmontera {mountprocess} från {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} hittades inte. Vänligen installera (t.ex via \"{installcommand}\")" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Monteringspunkten {mntpoint} är inte tom." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Fyll i lösenordet för {mode}profilen \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "MISSLYCKADES" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Återställ behörigheter" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Färdig" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Uppskjuter säkerhetskopiering vid batteridrift" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Kan inte skapa mapp för ögonblicksavbilder." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Om den finns på en flyttbar enhet, anslut den." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Väntar %s sekund." msgstr[1] "Väntar %s sekunder." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Misslyckades med att ta ögonblicksavbild {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Var snäll och ha tålamod. Slutför…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Kunde inte skapa mapp." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Sparar konfigurationsfil…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Sparar behörigheter…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Hittade överbliven ögonblicksavbild {snapshot_id} som kan återupptas." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Tar bort överbliven {snapshot_id}-mapp från den senaste körningen" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Kan inte ta bort mapp" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Tar ögonblicksavbild" #: common/snapshots.py:1430 msgid "Success" msgstr "Lyckades" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Partiell överföring på grund av fel" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" "Ofullständig överföring på grund av källfiler som försvann (se \"man " "rsync\")" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "\"rsync\" avslutades med felkod {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Se \"man rsync\" för fler detaljer" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "Negativa felkoder från rsync är signalnummer, se \"kill -l\" och \"man kill\"" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Inget har förändrats, ingen ny ögonblicksavbild behövs" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Kan inte byta namn på {new_path} till {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Smart borttagning" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Verkställ regler för att ta bort gamla ögonblicksavbilder" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Verkställ policy för bevarande" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Försöker att behålla minimum ledigt utrymme" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Försöker behålla minst {perc} fria inoder" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Nu" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Kan inte montera {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent hittades inte. Kontrollera att den är installerad." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Kunde inte låsa upp privat ssh-nyckel. Fel lösenord eller lösenordet är inte" " tillgängligt för cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Chiffer {cipher} misslyckades för {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Fjärrsökväg existerar men är inte en katalog." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Fjärrsökväg är inte skrivbar." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Fjärrsökväg är inte körbar." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Kunde inte skapa fjärrsökväg." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Fjärrvärd {host} stöder inte {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Se \"man backintime\" för ytterligare instruktioner" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Kontrollera kommandon på värd {host} gav okänt fel" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Fjärrvärd {host} stöder inte hårda länkar" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Kopiera offentlig ssh-nyckel \"{pubkey}\" till fjärrvärd \"{host}\"." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Ange lösenord för \"{user}\"." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Filsystemet för destinationen till \"{path}\" är formaterad med NTFS vilket " "har kända kompabilitetsproblem med filsystem av Unix-typ." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} är inte en giltig katalog." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Skapande av följande katalog misslyckades:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Skrivåtkomst kan vara begränsad." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Destinationsfilsystemet för {path} är formaterat med FAT som inte stöder " "hårda länkar. AVänligen använd ett inbyggt GNU/Linux filsystem." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Destinationsfilsystem för {path} är en SMB-monterad delning. Kontrollera att" " fjärr-SMB-servern stöder symboliska länkar eller aktivera \"{copyLinks}\" i" " \"{expertOptions}\"." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Kopiera länkar (följ symboliska länkar)" #: common/tools.py:504 msgid "Expert Options" msgstr "Expertinställningar" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Destinationsfilsystem för {path} är en sshfs-monterad delning. sshfs stöder " "inte hårda länkar. Vänligen använd läget \"SSH\" istället." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Filskapandet misslyckades i denna katalog:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Om" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Utvecklare" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Översättningar" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Licens" #: qt/app.py:172 msgid "Shortcuts" msgstr "Genvägar" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Denna mapp existerar inte\n" "i den nu valda ögonblicksavbilden." #: qt/app.py:257 msgid "Add to Include" msgstr "Lägg till i inkludera" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Lägg till i exkludera" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} verkar köras för första gången eftersom att ingen inställning " "kunde hittas." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Importera en befintlig konfiguration (från en målkatalog för " "säkerhetskopiering eller en annan dator)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "Om den är på en flyttbar enhet anslut den och tryck sedan på OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Ta en ögonblicksavbild" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Använd tid för senaste ändring & storlek för att upptäcka förändringar." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Ta ögonblicksavbild (med checksumma)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Använd checksumma för att detektera ändringar." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Pausa process för ögonblicksavbilder" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Återuppta process för ögonblicksavbilder" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Stoppa process för ögonblicksavbilder" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Uppdatera listan över ögonblicksavbilder" #: qt/app.py:497 msgid "Name snapshot" msgstr "Namnge ögonblicksavbild" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Ta bort ögonblicksavbild" #: qt/app.py:505 msgid "View snapshot log" msgstr "Visa logg för ögonblicksavbilder" #: qt/app.py:509 msgid "View last log" msgstr "Visa senaste logg" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Hantera profiler…" #: qt/app.py:517 msgid "Shutdown" msgstr "Stäng av" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Stäng av systemet när ögonblicksavbild har slutförts." #: qt/app.py:521 msgid "Setup language…" msgstr "Välj språk…" #: qt/app.py:525 msgid "Exit" msgstr "Avsluta" #: qt/app.py:529 msgid "User manual" msgstr "Användarmanual" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Öppna användarmanualen i webbläsaren (lokal om tillgängligt annars online)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "manual sida: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Visar manual sidan om Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "manualsida: Konfigurationsfil för profiler" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Visar manualsidan om konfigurationsfil för profiler (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Projektets hemsida" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Öppna Back In Time-webbplatsen i webbläsaren" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Ändringslogg" #: qt/app.py:555 msgid "FAQ" msgstr "Vanliga frågor" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Öppna Vanliga frågor (FAQ) i webbläsaren" #: qt/app.py:559 msgid "Ask a question" msgstr "Ställ en fråga" #: qt/app.py:563 msgid "Report a bug" msgstr "Rapportera ett fel" #: qt/app.py:566 msgid "Translation" msgstr "Översättningar" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Visar meddelandet om att delta i översättningen igen." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Övergång till kryptering (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Visar meddelandet om borttagningen av EncFS igen." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Återskapa" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Återskapa de valda filerna eller mapparna på den ursprungliga platsen." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Återskapa till…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Återskapa de valda filerna eller mapparna på en ny plats." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Återskapa denna mappen och hela dess innehåll på den ursprungliga platsen." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Återskapa denna mappen och hela dess innehåll på en ny plats." #: qt/app.py:601 msgid "Up" msgstr "Upp" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Visa dolda filer" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Jämför ögonblicksavbilder…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Släppkandidat" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Visar meddelandet om denna släppkandidat igen." #: qt/app.py:676 msgid "Back In &Time" msgstr "Tillbaka I &Tid" #: qt/app.py:681 msgid "&Backup" msgstr "&Säkerhetskopiera" #: qt/app.py:692 msgid "&Restore" msgstr "&Återskapa" #: qt/app.py:698 msgid "&Help" msgstr "&Hjälp" #: qt/app.py:743 msgid "Icons only" msgstr "Ikoner endast" #: qt/app.py:746 msgid "Text only" msgstr "Text endast" #: qt/app.py:749 msgid "Text below icons" msgstr "Text under ikoner" #: qt/app.py:752 msgid "Text beside icon" msgstr "Text bredvid ikoner" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Om du stänger det här fönstret så kan Back In Time inte stänga av ditt " "system när ögonblicksavbilden är färdig." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Vill du verkligen stänga det?" #: qt/app.py:1072 msgid "Working:" msgstr "Arbetar:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Färdig, ingen säkerhetskopiering behövdes" #: qt/app.py:1129 msgid "Working" msgstr "Arbetar" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Fel" #: qt/app.py:1161 msgid "Sent" msgstr "Skickat" #: qt/app.py:1162 msgid "Speed" msgstr "Hastighet" #: qt/app.py:1163 msgid "ETA" msgstr "Tid kvar" #: qt/app.py:1225 msgid "Global" msgstr "Global" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Hem" #: qt/app.py:1255 msgid "Backup directories" msgstr "Mappar för säkerhetskopior" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Namn på ögonblicksavbild" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Är du säker på att du vill ta bort denna ögonblicksavbild?" msgstr[1] "Är du säker på att du vill ta bort de här ögonblicksavbilderna?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Skapa säkerhetskopior med efterföljande \"{suffix}\"\n" "innan lokala filer skrivs över eller tas bort ." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Nyare versioner av filer kommer att döpas om med efterföljande {suffix} före" " återställning. Om du inte behöver dem längre kan du ta bort dem med " "följande kommando:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Återställ endast filer som inte existerar eller\n" "är nyare än de i destinationen.\n" "Använder alternativet \"rsync --update\"." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Ta bort nyare element i den ursprungliga katalogen." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Återställ valda filer eller kataloger till den ursprungliga destinationen " "och ta bort filer eller kataloger som inte finns i ögonblicksbilden. Var " "extremt försiktig eftersom detta kommer att radera filer och kataloger som " "uteslöts när ögonblicksavbilden togs." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Vill du verkligen återställa det här elementet till den nya katalogen?" msgstr[1] "" "Vill du verkligen återställa det här dessa elementen till den nya katalogen?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Vill du verkligen återställa den här filen?" msgstr[1] "Vill du verkligen återställa de här filerna?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Är du säker på att du vill ta bort alla nyare filer i {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Är du säker på att du vill ta bort alla nyare filer i din ursprungliga " "katalog?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}Varning{BOLDEND}: Att ta bort filer i filsystemets rot kan förstöra " "hela ditt system." #: qt/app.py:1857 msgid "Snapshot" msgstr "Ögonblicksavbilder" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Återskapa {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Återskapa {path} till…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Hej\n" "Du har använt Back In Time på språket {language} några gånger nu.\n" "Översättningen av din installerade version av Back In Time till {language} är {perc} färdig. Oavsett dina tekniska färdigheter så kan du bidra till översättningen och därmed till Back In Time självt.\n" "Besök {translation_platform_url} om du vill bidra. Besök {back_in_time_project_website} för vidare hjälp och frågor.\n" "Vi ber om ursäkt för avbrottet, detta meddelande kommer inte visas igen. Denna dialogruta finns tillgänglig när som helst från hjälpmenyn.\n" "Back In Time-gruppen" #: qt/app.py:2071 msgid "translation platform" msgstr "översättningsplattformen" #: qt/app.py:2076 msgid "Website" msgstr "Webbsida" #: qt/app.py:2090 msgid "Your translation" msgstr "Din översättning" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "I Fediverse på Mastodon {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-posta till {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "E-postlista {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} på projektets hemsida." #: qt/app.py:2118 msgid "Open an issue" msgstr "Öppna en bugg" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternativt kan du använda en annan kanal du väljer." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Den här versionen av Back In Time är en Release-kandidat och är främst avsedd för stabilitetstester inför nästa officiella utgåva.\n" "Inga användardata eller telemetri samlas in. Hur som helst så är Back In Time-teamet dock mycket intresserade av att veta om Release-kandidaten används och om det är värt att fortsätta tillhandahålla sådana versioner före lansering.\n" "Därför ber teamet vänligen om en kort återkoppling om huruvida du har testat den här versionen, även om du inte stötte på några problem. Även en snabb testkörning på några minuter skulle hjälpa oss mycket.\n" "Följande kontaktalternativ finns tillgängliga:\n" "{contact_list}\n" "I den här versionen så visas inte det här meddelandet igen, men kan kommas åt när som helst via hjälp-menyn.\n" "Tack för ditt stöd och för att du hjälper oss att förbättra Back In Time!\n" "Ditt Back In Time-team" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "Språkinställningarna aktiveras inte förrän Back in Time startas om." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Skapandet av EncFS-profil kommer att tas bort i den nästkommande mindre " "utgåvan (1.7), schemalagd för 2026." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Det är inte rekommenderat att använda det där läget längre för en profil." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "vitpapper" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Stödet för EncFS upphör på grund av säkerhetsbrister." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Vänligen referera till det här {whitepaper} för mer detaljer inklusive " "potentiella alternativ." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Följande profil(erna) använder kryptering med EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "En ersättning är planerad, men det kan inte garanteras att den dyker upp i " "tid." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Användare är inbjudna att gå med i den här diskussionen. Uppdaterad " "information om nästa steg finns i det här {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Det här meddelandet kommer inte visas igen. Den här rutan är tillgänglig när" " som helst via hjälp-menyn." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Ditt team för Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Välj språk" #: qt/languagedialog.py:97 msgid "System default" msgstr "Standardval för systemet" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Använd operativsystemets språk." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Översatt: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Visning av senaste logg" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Visning av logg för ögonblicksavbild" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Ögonblicksavbilder:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filter:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Alla" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Ändringar" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Fel" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Information" msgstr[1] "Information" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync-överföringsfel (experimentell)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Fel, [I] Information, [C] Ändring" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "avkoda sökvägar" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Hantera profiler" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Redigera" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Lägg till" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Ta bort" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Allmänt" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Inkludera" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Inkludera filer och mappar" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Lägg till fil" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Lägg till mapp" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Exkludera" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Info{ENDBOLD}: I \"SSH-krypterat\" läge är endast enkla eller dubbla " "asterisker funktionella (t.ex. {example2}). Andra typer av jokertecken och " "mönster kommer att ignoreras (t.ex. {example1}) Filnamn är oförutsägbara i " "detta läge på grund av kryptering med EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Exkludera mönster, filer eller kataloger" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Lägg till standard" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Exkludera filer större än:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Exkludera filer som är större än värdet i {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Med 'Fullständigt rsync-läge' inaktiverat kommer detta bara att påverka nya " "filer eftersom för rsync är detta ett överföringsalternativ, inte ett " "undantagsalternativ. Därför kommer stora filer som har säkerhetskopierats " "tidigare att finnas kvar i ögonblicksavbilder även om de har ändrats." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "Ta &bort & bibehåll" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Inställningar" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "E&xpertinställningar" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Återställ konfiguration" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Redigera user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Ny profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Byt namn på profil" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Är du säker på att du vill ta bort denna profil \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Rekommenderas starkt{ENDBOLD}: (Alla rekommendationer är redan " "inkluderade.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Starkt rekommenderade{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Exkludera mönster" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Exkludera fil" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Exkludera mapp" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Inkludera fil" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" är en symbolisk länk. Det länkade målet kommer inte att säkerhetskopieras förrän du inkluderar det också.\n" "Vill du inkludera länkens mål istället?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Inkludera mapp" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "Avstängt eftersom att det här mönstret inte är funktionellt i läget " "'Krypterad SSH'." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Schema" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Dag:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Veckodag:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Tid:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Timmar:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "efter en timme" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Minuter:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Kör Back In Time så snart enheten ansluts (endast en gång var X dag). Du " "kommer att bli tillfrågad om ditt sudo-lösenord." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Kör Back In Time upprepade gånger. Detta är användbart om datorn inte körs " "regelbundet." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Varje:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Aktivera loggning av felsökningsmeddelanden" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "Skriver felsökningsmeddelanden in i systemets logg via \"--debug\"." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Var försiktig: Använd endast det här tillfälligt för diagnostik då det " "genererar en stor mängd utmatning." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Inaktiverad" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Vid varje start/omstart" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Varje minut" msgstr[1] "Med {n} minuters mellanrum" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Varje timme" msgstr[1] "Varje {n} timmar" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Varje timme" msgstr[1] "Med {n} timmars mellanrum" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Anpassade timmar" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Varje dag" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Upprepad (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "När enhet ansluts (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Varje vecka" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Varje månad" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Varje år" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Timme(-ar)" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Dag(ar)" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Vecka(-or)" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Månad(er)" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Anpassade timmar kan endast vara en kommaseparerad lista av timmar (t.ex. " "8,12,18,23) eller */3 för periodiska säkerhetskopior var 3:e timme." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Proxy-server för SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Värd:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Användare:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Anslut till målvärden via den här proxyn (även känd som en hoppvärd). Se " "\"-J\" i kommandodokumentationen för \"ssh\", eller \"ProxyJump\" i manualen" " för \"ssh_config\", för detaljer." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Försiktighet:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Dessa alternativ är för avancerade konfigurationer. Ändra endast om du är " "fullt medveten om deras konsekvenser." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Kör 'rsync' med '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "som cronjobb" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "på fjärrvärd" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "vid tagning av en manuell ögonblicksavbild" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Vänligen installera 'nocache' för att aktivera detta alternativ." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "på lokal maskin" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Omdirigera stdout till /dev/null i cronjobb." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron kommer automatiskt att skicka e-post med bifogad utmatning av cron-jobb" " om en MTA är installerad." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Omdirigera stderr till /dev/null i cronjobb." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Cron kommer automatiskt att skicka ett e-postmeddelande med bifogade fel i " "cron-jobb om en MTA är installerad." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/s" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Bandbreddsbegränsning för rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Behåll ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Behåll utökade attribut (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Kopiera osäkra länkar (fungerar endast med absoluta länkar)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Begränsa till ett filsystem" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Alternativ måste skrivas inom citationstecken t.ex. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Klistra in ytterligare alternativ till rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Prefix som ska köras före varje kommando på fjärrvärden." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Variabler måste avslutas med \\$FOO. Detta rör inte rsync. Så för att lägga " "till ett prefix för rsync använd \"{example_value}\" med " "{rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "standard" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Lägg till prefix till SSH-kommandon" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Kontrollera om fjärrvärd är uppkopplad" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Varning: Om det är inaktiverat och fjärrvärden inte är tillgänglig kan detta" " leda till konstiga fel." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Kontrollera om fjärrvärden stöder alla nödvändiga kommandon." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Varning: Om det är inaktiverad och fjärrvärden inte stöder alla nödvändiga " "kommandon kan detta leda till konstiga fel." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(standard: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "inaktiverad" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "aktiverad" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Läge:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Var ögonblicksavbilder ska sparas" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH-inställningar" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Sökväg:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Chiffer:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Privat nyckel:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Välj en befintlig privat nyckel-fil (normalt kallad \"id_ed25519\" och i " "äldre konfigurationer \"id_rsa\")." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Skapa en ny SSH-nyckel utan lösenord (inte tillåtet om en privat nyckelfil " "redan är vald)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Lösenord" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Spara lösenord till nyckelring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Spara lösenordet i en cache för Cron (säkerhetsproblem: root kan läsa " "lösenordet)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Avancerat" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Fullständig sökväg för ögonblicksavbild:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Du valde inte en privat nyckel-fil för SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Vill du generera ett nytt lösenordslöst offentligt/privat nyckelpar?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Privat nyckelfil \"{file}\" existerar inte." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Vill du kopiera din offentliga SSH-nyckel till fjärrvärden för att aktivera " "lösenordslös inloggning?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Autenticiteten för värd {host} kan inte fastställas." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} nyckelfingeravtryck är:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Vänligen verifiera detta fingeravtryck. Vill du lägga till det i din " "'known_hosts'-fil?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Är du säker på att du vill ändra mappen för ögonblicksavbilder?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Misslyckades med att skapa ny SSH-nyckel i {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Aktivera aviseringar" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Inaktivera ögonblicksavbilder vid batteridrift" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Strömstatus inte tillgängligt från system" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Gör bara en ögonblicksavbild i taget" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Andra ögonblicksavbilder kommer att blockeras tills den aktuella " "ögonblicksavbilden är klar. Detta är ett globalt alternativ. Så det kommer " "att påverka alla profiler för denna användare. Men du måste aktivera detta " "för alla andra användare också." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Säkerhetskopiera ersatta filer vid återställning" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Nyare versioner av filer kommer att döpas om med avslutande {suffix} innan " "de återställs. Om du inte behöver dem längre kan du ta bort dem med {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Fortsätt vid fel (behåll icke kompletta ögonblicksavbilder)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Använd checksummor för att detektera ändringar" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Ta en ny ögonblicksavbild oavsett om det fanns ändringar eller inte." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Loggnivå:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Inga" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Följande regler behandlas från topp till botten. Senare regler åsidosätter " "tidigare och är inte begränsade av dem. Se {manual} för detaljer och " "exempel." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "användarmanual" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Öppna användarmanual i webbläsaren." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Behåll den mest senaste ögonblicksavbilden." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Den sista eller färskaste ögonblicksavbilden bevaras under alla " "omständigheter." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Det beteendet går inte att ändra på." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Behåll namngivna ögonblicksavbilder." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Ögonblicksavbilder som har fått ett namn, utöver den vanliga tidsstämpeln, " "kommer att behållas under alla omständigheter och kommer inte att tas bort." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "År" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Ta bort ögonblicksavbilder äldre än" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Hela dagar. Aktuell dag ignoreras." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Kalenderveckor med måndag som första dag. Aktuell vecka ignoreras." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Tolvmånaders perioder. Nuvarande månad ignoreras." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Bevarandepolicy" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Kör i bakgrunden på fjärrvärden." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Proceduren för smart borttagning kommer att köras direkt på fjärrmaskinen, " "inte lokalt. Kommandona \"bash\", \"screen\" och \"flock\" måste vara " "installerade och tillgängliga på fjärrmaskinen." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Om det väljs kommer Back In Time först att testa fjärrmaskinen." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Dagarna räknas från och med idag." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Behåll alla ögonblicksavbilder för de senaste" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "dag(ar)." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Behåll den sista ögonblicksavbilden för varje dag till den sista" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Veckorna räknas från och med den aktuella löpveckan. En vecka börjar på " "måndag." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Behåll den sista ögonblicksavbilden för varje vecka till den sista" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "vecka/veckor." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Månaderna räknas som kalendermånader från och med nuvarande månad." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Spara den sista ögonblicksavbilden för varje månad till den sista" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "månad(er)." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Åren räknas som kalenderår från och med det nuvarande året." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Spara den sista ögonblicksavbilden för varje år för" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "alla år." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… det lediga utrymmet är mindre än" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… de lediga inoderna är mindre än" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Ta bort gamla ögonblicksavbilder om …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Fråga" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Visa senaste logg" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Starta {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Arbetar…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Skickat:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hastighet:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Tid kvar:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Ögonblicksavbilder" #: qt/qttools.py:506 msgid "Today" msgstr "Idag" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Igår" #: qt/qttools.py:522 msgid "This week" msgstr "Denna vecka" #: qt/qttools.py:529 msgid "Last week" msgstr "Förra veckan" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Detta är INTE en ögonblicksavbild utan en levande visning av dina lokala " "filer" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Senaste kontroll {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Importera konfiguration" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Ingen konfiguration hittades" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Importera" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Välj mappen för ögonblicksavbilder som konfigurationsfilen ska importeras " "ifrån. Sökvägen kan se ut så här: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Om katalogen finns på en extern eller fjärrenhet måste den monteras manuellt" " i förväg." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Visa fullständig logg" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Alternativ för att jämföra ögonblicksavbilder" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Kommando:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametrar:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Använd %1 och %2 för sökvägsparametrar" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Vänligen ställ in ett diff-kommando eller tryck på Avbryt." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Kommandot \"{cmd}\" kan inte hittas i ditt system. Vänligen prova något " "annat eller tryck på Avbryt." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Inga parametrar är inställda för diff-kommandot. Använder standardvärdet " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Endast ögonblicksavbilder med olikheter" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Lista bara ögonblicksavbilder som är lika med:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Djupkontroll (mer noggrann, men långsam)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Ta bort" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Välj alla" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Jämför" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Gå till" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Alternativ" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Du kan inte jämföra en ögonblicksavbild med sig själv." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Vill du verkligen ta bort \"{file}\" i ögonblicksavbild \"{snapshot_id}\"?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Vill du verkligen ta bort \"{file}\" i {count} ögonblicksavbilder?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "VARNING: Det här kan inte återkallas." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Exkludera \"{path}\" från framtida ögonblicksavbilder?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Underkatalogerna kan inte inkluderas i säkerhetskopian." backintime-1.5.4/common/po/th.po000066400000000000000000002103271477034762000165270ustar00rootroot00000000000000# Thai translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-03 09:53+0000\n" "Last-Translator: buhtz \n" "Language-Team: Thai \n" "Language: th\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "คำเตือน" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "โปรไฟล์หลัก" #: common/config.py:266 #, fuzzy msgid "Local (EncFS encrypted)" msgstr "SSH ที่เข้ารหัสแล้ว" #: common/config.py:267 #, fuzzy msgid "SSH (EncFS encrypted)" msgstr "SSH ที่เข้ารหัสแล้ว" #: common/config.py:278 msgid "Local" msgstr "ท้องถิ่น" #: common/config.py:280 msgid "SSH" msgstr "" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "คีย์ส่วนตัว SSH" #: common/config.py:283 #, fuzzy msgid "Local encrypted" msgstr "SSH ที่เข้ารหัสแล้ว" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "การเข้ารหัส" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH ที่เข้ารหัสแล้ว" #: common/config.py:296 msgid "Default" msgstr "ค่าเริ่มต้น" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "โปรไฟล์: \"{name}\"" #: common/config.py:328 #, fuzzy msgid "Snapshots directory is not valid." msgstr "โฟลเดอร์ Snapshots ไม่ถูกต้อง!" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "คืนค่า {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "ไม่สามารถเขียน crontab ใหม่ได้" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "ไม่สามารถติดตั้งกฎ Udev สำหรับโปรไฟล์ {profile_id} ได้ DBus Service " "'{dbus_interface}' ไม่พร้อมใช้งาน" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "ตารางงานของ udev ไม่ทำงานกับโหมด {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "ไม่พบ UUID สำหรับ \"{path}\"" #: common/configfile.py:101 msgid "Failed to save config" msgstr "ไม่สามารถบันทึกการตั้งค่าได้" #: common/configfile.py:137 msgid "Failed to load config" msgstr "ไม่สามารถโหลดการตั้งค่าได้" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "โปรไฟล์ \"{name}\" มีอยู่แล้ว" #: common/configfile.py:729 #, fuzzy msgid "The last profile cannot be removed." msgstr "ไม่สามารถเพิกถอนสิ่งนี้ได้" #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "ไม่สามารถเชื่อมต่อ '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "ไม่พบการตั้งค่าสำหรับโฟลเดอร์ที่เข้ารหัส" #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "ต้องการสร้างโฟลเดอร์ที่เข้ารหัสใหม่หรือไม่?" #: common/encfstools.py:146 msgid "Cancel" msgstr "" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "โปรดยืนยันรหัสผ่าน." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "สร้างสแนปช็อต" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "ล้มเหลว" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "เรียกคืนสิทธิ์" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "ทำเสร็จ" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "การเลื่อนการสำรองข้อมูลขณะใช้แบตเตอรี่" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "ไม่สามารถสร้างโฟลเดอร์ได้" #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "ไม่พบโฟลเดอร์สแนปช็อต\n" "หากอยู่บนไดรฟ์ที่เปลี่ยนได้ โปรดเสียบเข้าแล้วกด OK" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "รอ %s วินาที." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "ไม่สามารถสร้างสแนปช็อต {snapshot_id} ได้" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "ไม่สามารถสร้างโฟลเดอร์ได้" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "กำลังบันทึกไฟล์กำหนดค่า…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "กำลังบันทึกสิทธิ์การเข้าถึง…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "พบส่วนที่เหลืออยู่ {snapshot_id} ซึ่งสามารถดำเนินการต่อได้" #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "พบส่วนที่เหลืออยู่ {snapshot_id} ซึ่งสามารถทำต่อได้" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "ไม่สามารถลบโฟลเดอร์ได้" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "กำลังสร้างสแนปช็อต" #: common/snapshots.py:1430 msgid "Success" msgstr "" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "ไม่มีการเปลี่ยนแปลงใด ๆ ไม่จำเป็นต้องสร้างสแนปช็อตใหม่" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "ไม่สามารถเปลี่ยนชื่อ {new_path} เป็น {path}" #: common/snapshots.py:1855 #, fuzzy msgid "Smart removal" msgstr "การลบอย่างฉลาด" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "กำลังลบสแนปช็อตเก่า" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "พยายามรักษาพื้นที่ว่างขั้นต่ำ" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "พยายามรักษาเครื่องหมายเชิงว่างขั้นต่ำที่ {perc}" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "เดี๋ยวนี้" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "ไม่สามารถเชื่อมต่อ {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "ไม่สามารถสร้างโฟลเดอร์ได้" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "" #: common/sshtools.py:1191 #, fuzzy, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "คัดลอก SSH public key \"{pubkey}\" ไปยังโฮสต์ระยะไกล \"{host}\"" #: common/sshtools.py:1193 #, fuzzy, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "โปรดป้อนรหัสผ่านสำหรับ \"{user}\"" #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "ระบบไฟล์ปลายทางสำหรับ {path} ถูกฟอร์แมตด้วย FAT ซึ่งไม่รองรับ hard-links " "โปรดใช้ระบบไฟล์ของ Linux ที่เป็นธรรมชาติ" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "ระบบไฟล์ปลายทางสำหรับ {path} ถูกฟอร์แมตด้วย FAT ซึ่งไม่รองรับ hard-links " "โปรดใช้ระบบไฟล์ของ Linux ที่เป็นธรรมชาติ" #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "ระบบไฟล์ปลายทางสำหรับ {path} เป็นการแชร์ที่เชื่อมต่อด้วย SMB " "โปรดตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ SMB ระยะไกลรองรับ symlink หรือเปิดใช้งาน " "{copyLinks} ใน {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "คัดลอกลิงก์ (เคลียร์ลิงก์สัญลักษณ์)" #: common/tools.py:504 msgid "Expert Options" msgstr "ตัวเลือกขั้นสูง" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "ระบบไฟล์ปลายทางสำหรับ {path} เป็นการแชร์ที่เชื่อมต่อด้วย sshfs ซึ่งไม่รองรับ" " hard-links โปรดใช้โหมด 'SSH' แทน" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "เกี่ยวกับ" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "ผู้เขียน" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "การแปล" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "ใบอนุญาต" #: qt/app.py:172 msgid "Shortcuts" msgstr "ทางลัด" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "โฟลเดอร์นี้ไม่มีอยู่\n" "ในสแนปช็อตที่เลือกในปัจจุบัน" #: qt/app.py:257 msgid "Add to Include" msgstr "เพิ่มในรายการรว" #: qt/app.py:259 msgid "Add to Exclude" msgstr "เพิ่มไปยังรายการยกเว้น" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "ไม่พบโฟลเดอร์สแนปช็อต\n" "หากอยู่บนไดรฟ์ที่เปลี่ยนได้ โปรดเสียบเข้าแล้วกด OK" #: qt/app.py:470 msgid "Take a snapshot" msgstr "สร้างสแนปช็อต" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "ทำสแนปช็อตพร้อมแสดงผลการตรวจสอบสำหรับ checksum" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "ใช้ checksum เพื่อตรวจจับการเปลี่ยนแปลง" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "หยุดกระบวนการสร้างสแนปช็อตชั่วคราว" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "ดำเนินกระบวนการสร้างสแนปช็อตต่อ" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "หยุดกระบวนการสร้างสแนปช็อต" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "รีเฟรชรายการสแนปช็อต" #: qt/app.py:497 msgid "Name snapshot" msgstr "สร้างสแนปช็อต" #: qt/app.py:501 msgid "Remove snapshot" msgstr "ลบสแนปช็อต" #: qt/app.py:505 msgid "View snapshot log" msgstr "ดูบันทึกสแนปช็อต" #: qt/app.py:509 msgid "View last log" msgstr "ดูบันทึกล่าสุด" #: qt/app.py:513 msgid "Manage profiles…" msgstr "โปรไฟล์หลัก…" #: qt/app.py:517 msgid "Shutdown" msgstr "ปิดเครื่อง" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "ปิดเครื่องหลังสแนปช็อตเสร็จสิ้น" #: qt/app.py:521 msgid "Setup language…" msgstr "" #: qt/app.py:525 msgid "Exit" msgstr "ออก" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "กำลังบันทึกไฟล์กำหนดค่า..." #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "บันทึกการเปลี่ยนแปลง" #: qt/app.py:555 msgid "FAQ" msgstr "FAQ" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "แปลว่า \"ถามคำถาม" #: qt/app.py:563 msgid "Report a bug" msgstr "รายงานข้อบกพร่อง" #: qt/app.py:566 msgid "Translation" msgstr "การแปล" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "คืน" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "เรียกคืนไฟล์หรือโฟลเดอร์ที่เลือกไปยังตำแหน่งเดิม" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "กู้คืนไปยัง …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "เรียกคืนไฟล์หรือโฟลเดอร์ที่เลือกไปยังตำแหน่งใหม่" #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "คืนค่าโฟลเดอร์ที่แสดงอยู่ในปัจจุบันพร้อมทั้งเนื้อหาทั้งหมดไปยังตำแหน่งเดิม" #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "คืนค่าโฟลเดอร์ที่แสดงอยู่ในปัจจุบันพร้อมทั้งเนื้อหาทั้งหมดไปยังตำแหน่งใหม่" #: qt/app.py:601 msgid "Up" msgstr "ขึ้น" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "แสดงแฟ้มที่ซ่อน" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "สร้างสแนปช็อต…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "" #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "" #: qt/app.py:692 msgid "&Restore" msgstr "&คืนค่า" #: qt/app.py:698 msgid "&Help" msgstr "&ช่วยเหลือ" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 #, fuzzy msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "หากคุณปิดหน้าต่างนี้ โปรแกรม Back In Time จะไม่สามารถปิดเครื่องของคุณเมื่อสแนปช็อตเสร็จสิ้นแล้วได้\n" "คุณต้องการปิดหรือไม่?" #: qt/app.py:900 #, fuzzy msgid "Do you really want to close it?" msgstr "คุณต้องการคืนค่าไฟล์เหล่านี้ใช่หรือไม่" #: qt/app.py:1072 msgid "Working:" msgstr "กำลังทำงาน中:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "ทำเสร็จ, ไม่จำเป็นต้องสำรอง" #: qt/app.py:1129 msgid "Working" msgstr "กำลังทำงาน" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "ข้อผิดพลาด" #: qt/app.py:1161 msgid "Sent" msgstr "ได้ส่งแล้ว" #: qt/app.py:1162 msgid "Speed" msgstr "ความเร็ว" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "ทั่วโลก" #: qt/app.py:1226 msgid "Root" msgstr "รูท" #: qt/app.py:1227 msgid "Home" msgstr "โฮม" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "โฟลเดอร์สำรองข้อมูล" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "ชื่อสแนปช็อต" #: qt/app.py:1398 #, fuzzy msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "คุณแน่ใจว่าต้องการลบสแนปช็อตหรือไม่" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "สำรองข้อมูลไฟล์ท้องถิ่นก่อนเขียนทับหรือลบ\n" "ลบพร้อมคำติดท้าย {suffix}." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "เวอร์ชันใหม่ของไฟล์จะถูกเปลี่ยนชื่อด้วยคำติดท้าย {suffix} ก่อนที่จะถูกคืนค่า" " หากคุณไม่ต้องการใช้งานอีกต่อไป คุณสามารถลบไฟล์เหล่านี้ด้วย {cmd}" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "คืนค่าเฉพาะไฟล์ที่ไม่มีอยู่หรือ\n" "เป็นไฟล์เวอร์ชันใหม่กว่าที่อยู่ในตำแหน่งปลายทาง\n" "ใช้ตัวเลือก \"rsync --update\"" #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "ลบไฟล์ที่เป็นเวอร์ชันใหม่กว่าในโฟลเดอร์เดิม" #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "คืนค่าไฟล์หรือโฟลเดอร์ที่เลือกไปยังตำแหน่งเดิมและ\n" "ลบไฟล์/โฟลเดอร์ที่ไม่อยู่ในสแนปช็อต\n" "การดำเนินการนี้จะลบไฟล์/โฟลเดอร์ที่ถูกยกเว้นในขณะที่สแนปช็อตถูกสร้างขึ้น!\n" "โปรดระมัดระวังอย่างยิ่ง!!!" #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "คุณต้องการคืนค่าไฟล์เหล่านี้ใช่หรือไม่\n" "ไปยังโฟลเดอร์ใหม่ {path}" #: qt/app.py:1580 #, fuzzy msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "คุณต้องการคืนค่าไฟล์เหล่านี้ใช่หรือไม่" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "คุณแน่ใจว่าต้องการลบไฟล์เวอร์ชันใหม่ทั้งหมดใน {path} หรือไม่?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "คุณแน่ใจว่าต้องการลบไฟล์เวอร์ชันใหม่ทั้งหมดในโฟลเดอร์เดิมของคุณหรือไม่?" #: qt/app.py:1608 #, fuzzy, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "คำเตือน: การลบไฟล์ในระบบไฟล์รูทอาจทำให้ระบบของคุณเสียหายได้ทั้งหมด!!!" #: qt/app.py:1857 msgid "Snapshot" msgstr "สแนปช็อต" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "คืนค่า {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "คืนค่า {path} ไปยัง…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "สวัสดี\n" "คุณได้ใช้โปรแกรม Back In Time ในภาษา {language} มาแล้ว 2-3 ครั้ง\n" "การแปลภาษาของ Black In Time ในเวอร์ชั่นที่คุณติดตั้งเป็นภาษา {language} ได้ {perc} สำเร็จ ไม่ว่าคุณจะมีความสามารถในทางเทคนิคหรือไม่ คุณสามารถมีส่วนร่วมในการแปลภาษา และมีส่วนร่วมกับโปรแกรม Back In Time ได้\n" "ไปที่ {translation_platform_url} ถ้าคุณอยากจะมีส่วนร่วม สำหรับคำถามและการช่วยเหลือเพิ่มเติม ไปที่ {back_in_time_project_website}\n" "ทางเราต้องขออภัยสำหรับการรบกวน และข้อความนี้จะไม่แสดงบนหน้าจอของคุณอีก ข้อความนี้จะอยู่ที่เมนูความช่วยเหลือ\n" "ทีมงาน Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "การแปล" #: qt/app.py:2076 msgid "Website" msgstr "เว็บไซต์" #: qt/app.py:2090 msgid "Your translation" msgstr "การแปล" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "" #: qt/languagedialog.py:97 msgid "System default" msgstr "เพิ่มค่าเริ่มต้น" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "มุมมองบันทึกล่าสุด" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "มุมมองบันทึกสแนปช็อต" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "โปรไฟล์:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "สแนปช็อต:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "ตัวกรอง:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "ทั้งหมด" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "การเปลี่ยนแปลง" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "ข้อผิดพลาด" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "ข้อมูล" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] ข้อผิดพลาด, [I] ข้อมูล, [C] การเปลี่ยนแปลง" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "ถอดรหัสเส้นทาง" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "โปรไฟล์หลัก" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "แก้ไข" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "เพิ่ม" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "ลบ" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&ทั่วไป" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&รวมเข้ากับ" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "รวมไฟล์และโฟลเดอร์" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "เพิ่มไฟล์" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "เพิ่มโฟลเดอร์" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&ยกเว้น" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "ระบุรูปแบบที่ต้องการยกเว้น, ไฟล์ หรือ โฟลเดอร์ที่ต้องการยกเว้น" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "เพิ่มค่าเริ่มต้น" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "ยกเว้นไฟล์ที่มีขนาดใหญ่กว่า:" #: qt/manageprofiles/__init__.py:233 #, fuzzy, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "ยกเว้นไฟล์ที่มีขนาดใหญ่กว่า: " #: qt/manageprofiles/__init__.py:235 #, fuzzy msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "ยกเว้นไฟล์ที่มีขนาดใหญ่กว่าค่าที่ระบุใน %(prefix)s\n" "เมื่อ 'โหมดการสำรองข้อมูลแบบ rsync เต็มรูปแบบ' ถูกปิดใช้งาน สิ่งนี้จะมีผลกับไฟล์ใหม่เท่านั้น\n" "เนื่องจากสำหรับ rsync นี้เป็นตัวเลือกการถ่ายโอน ไม่ใช่ตัวเลือกในการยกเว้น\n" "ดังนั้นไฟล์ขนาดใหญ่ที่ได้รับการสำรองข้อมูลมาก่อนหน้านี้จะยังคงอยู่ในสแนปช็อต\n" "แม้ว่าไฟล์เหล่านั้นจะเปลี่ยนแปลงลง" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "& ตัวเลือก" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&ตัวเลือกขั้นสูง" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "คุณแน่ใจว่าต้องการลบไฟล์เวอร์ชันใหม่ทั้งหมดใน {name} หรือไม่?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "แนะนำอย่างมาก" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "กำหนดเวลาตามกำหนดการ" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "วันในสัปดาห์:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "ชั่วโมง:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "ให้ Back In Time เรียกใช้งานเมื่อไดรฟ์ถูกเชื่อมต่อ (เพียงครั้งเดียวในช่วง X วัน) \n" "คุณจะได้รับคำถามให้กรอกรหัสผ่านของ sudo ของคุณ" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "ให้ Back In Time ทำงานซ้ำอย่างต่อเนื่อง " "ซึ่งเป็นประโยชน์หากเครื่องคอมพิวเตอร์ไม่ทำงานอย่างเป็นประจำ" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "ทุกๆ:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "ถูกปิดใช้งานแล้ว" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "ทุกครั้งที่เปิดเครื่อง/เริ่มรีบูต" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "ทุก {n} นาที" #: qt/manageprofiles/schedulewidget.py:150 #, fuzzy, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "ทุกชั่วโมง" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "ทุก {n} ชั่วโมง" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "ชั่วโมงที่กำหนดเอง" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "ทุกวัน" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "เป็นรูปแบบที่ทำซ้ำตามเวลาที่กำหนด (ระบบ anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "เมื่อไดรฟ์เชื่อมต่อกับระบบ (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "ทุกสัปดาห์" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "ทุกเดือน" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "ทุกปี" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "ชั่วโมง" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "วัน" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "สัปดาห์" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "เดือน" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "โฮสต์:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "พอร์ต:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "ผู้ใช้งาน:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "คำถาม" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "รัน 'rsync' ด้วย '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "เป็นงาน cron" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "บนโฮสต์ระยะไกล" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "เมื่อสร้างสแนปช็อตด้วยตนเอง" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(โปรดติดตั้ง 'nocache' เพื่อเปิดใช้งานตัวเลือกนี้)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "บนเครื่องใช้งานท้องถิ่น" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "เปลี่ยนเส้นทาง stdout เป็น /dev/null ใน cronjobs" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "เปลี่ยนเส้นทาง stderr เป็น /dev/null ใน cronjobs" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sec" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "จำกัดการใช้แบนด์วิดธ์ของ rsync:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "สงวน ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "สงวนแอตทริบิวต์ขยาย(xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "คัดลอกลิงก์ที่ไม่ปลอดภัย (ทำงานเฉพาะลิงก์ที่เป็นแบบสมบูรณ์)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, fuzzy, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "ตัวเลือกจะต้องอยู่ในเครื่องหมายคำพูด เช่น {example}" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "วางตัวเลือกเพิ่มเติมให้กับ rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, fuzzy, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "คำนำหน้าที่จะเรียกใช้ก่อนทุกคำสั่งบนเครื่องโฮสต์ระยะไกล\n" "ตัวแปรต้องถูกหนีเอสด้วย $FOO\n" "การตั้งค่านี้ไม่มีผลต่อ rsync ดังนั้นในการเพิ่มคำนำหน้าสำหรับ rsync ให้ใช้ \"%(cbRsyncOptions)s\" พร้อมกับ\n" " %(rsync_options_value)s\n" "\n" "%(default)s: %(def_value)s" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "เพิ่มคำนำหน้าให้กับคำสั่ง SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "ค่าเริ่มต้น" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "โหมด:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "สถานที่ที่จะบันทึกสแนปช็อต" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "การตั้งค่า SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "เส้นทาง:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "วิธีการเข้ารหัส:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "กุญแจส่วนตัว:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "เลือกไฟล์กุญแจส่วนตัวที่มีอยู่ (ซึ่งมักมีชื่อว่า \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 #, fuzzy msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "สร้างคีย์ SSH ใหม่โดยไม่มีรหัสผ่าน " "(ไม่อนุญาตหากไฟล์กุญแจส่วนตัวถูกเลือกแล้ว)" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "รหัสผ่าน" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "บันทึกรหัสผ่านใน Keyring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "เก็บรหัสผ่านในแคชสำหรับ Cron (ปัญหาด้านความปลอดภัย: root " "สามารถอ่านรหัสผ่านได้)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "ขั้นสูง" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "เส้นทางสแนปช็อตทั้งหมด:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "คุณแน่ใจว่าต้องการลบสแนปช็อตหรือไม่" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "ไม่สามารถเขียน crontab ใหม่ได้" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "เปิดใช้งานการแจ้งเตือน" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "ปิดใช้งานการสร้างสแนปช็อตเมื่อใช้งานบนแบตเตอรี่" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "ไม่สามารถรับสถานะพลังงานจากระบบได้" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "เรียกใช้สแนปช็อตเพียงหนึ่งตัวในเวลาเดียวกันเท่านั้น" #: qt/manageprofiles/tab_options.py:53 #, fuzzy msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "สแนปช็อตอื่น ๆ จะถูกระบบปิดกั้นจนกว่าสแนปช็อตปัจจุบันจะเสร็จสมบูรณ์\n" "นี่เป็นตัวเลือกที่มีผลทั่วโลก ดังนั้นจะมีผลต่อโปรไฟล์ทั้งหมดสำหรับผู้ใช้รายนี้\n" "แต่คุณจำเป็นต้องเปิดใช้งานตัวเลือกนี้สำหรับผู้ใช้อื่น ๆ ด้วย" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "สำรองข้อมูลไฟล์ที่ถูกแทนที่เมื่อกู้คืน" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "เวอร์ชันใหม่ของไฟล์จะถูกเปลี่ยนชื่อด้วยคำติดท้าย {suffix} ก่อนที่จะถูกคืนค่า" " หากคุณไม่ต้องการใช้งานอีกต่อไป คุณสามารถลบไฟล์เหล่านี้ด้วย {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "ดำเนินการต่อเมื่อเกิดข้อผิดพลาด (เก็บสแนปช็อตที่ไม่สมบูรณ์)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "ใช้ checksum เพื่อตรวจจับการเปลี่ยนแปลง" #: qt/manageprofiles/tab_options.py:83 #, fuzzy msgid "Take a new snapshot whether there were changes or not." msgstr "สร้างสแนปช็อตใหม่โดยไม่ว่าจะมีการเปลี่ยนแปลงหรือไม่ก็ตาม" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "ระดับบันทึก:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "ไม่มี" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "ไม่ลบสแนปช็อตที่มีชื่อ" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "ไม่ลบสแนปช็อตที่มีชื่อ" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "ปี" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "ลบสแนปช็อต" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 #, fuzzy msgid "Run in background on remote host." msgstr "เรียกใช้ในพื้นหลังบนโฮสต์ระยะไกล" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "เก็บรักษาสแนปช็อตทั้งหมดสำหรับช่วงเวลาล่าสุด" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 #, fuzzy msgid "day(s)." msgstr "วัน" #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "เก็บรักษาสแนปช็อตหนึ่งต่อวันสำหรับช่วงเวลาล่าสุด" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "เก็บรักษาสแนปช็อตหนึ่งต่อสัปดาห์สำหรับช่วงเวลาล่าสุด" #: qt/manageprofiles/tab_remove_retention.py:336 #, fuzzy msgid "week(s)." msgstr "สัปดาห์" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "เก็บรักษาสแนปช็อตหนึ่งต่อเดือนสำหรับช่วงเวลาล่าสุด" #: qt/manageprofiles/tab_remove_retention.py:349 #, fuzzy msgid "month(s)." msgstr "เดือน" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "เก็บรักษาสแนปช็อตทั้งหมดสำหรับช่วงเวลาล่าสุด" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "หากพื้นที่ว่างน้อยกว่า:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "หากพื้นที่ว่างของไอโนด์น้อยกว่า:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "กำลังลบสแนปช็อตเก่า" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "คำถาม" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "โปรไฟล์: \"{profile_name}\"" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "ดูบันทึกล่าสุด" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "กำลังทำงาน…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "ได้ส่งแล้ว:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "ความเร็ว:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "สแนปช็อต" #: qt/qttools.py:506 msgid "Today" msgstr "วันนี้" #: qt/qttools.py:513 msgid "Yesterday" msgstr "เมื่อวาน" #: qt/qttools.py:522 msgid "This week" msgstr "สัดาห์นี้" #: qt/qttools.py:529 msgid "Last week" msgstr "สัปดาห์ที่แล้ว" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "นี่ไม่ใช่สแนปช็อต แต่เป็นมุมมองสดของไฟล์ท้องถิ่นของคุณ" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "ตรวจสอบล่าสุดเมื่อ {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "แสดงบันทึกทั้งหมด" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "คำสั่ง:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "พารามิเตอร์:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "ใช้ %1 และ %2 สำหรับพารามิเตอร์เส้นทาง" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "เฉพาะสแนปช็อตที่แตกต่างเท่านั้น" #: qt/snapshotsdialog.py:134 #, fuzzy msgid "List only snapshots that are equal to:" msgstr "รายการเฉพาะสแนปช็อตที่เท่ากับ: " #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "ตรวจสอบลึก (มากขึ้นในความแม่นยำ แต่ช้ากว่า)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "ลบ" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "เลือกทั้งหมด" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "ไปยัง" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "& ตัวเลือก" #: qt/snapshotsdialog.py:353 #, fuzzy msgid "You can't compare a snapshot to itself." msgstr "คุณไม่สามารถเปรียบเทียบสแนปช็อตกับตัวเองได้" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "คุณต้องการลบ \"{file}\" ในสแนปช็อต \"{snapshot_id}\" จริงหรือไม่?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "คุณต้องการลบ \"{file}\" ในสแนปช็อต {count} รายการ จริงหรือไม่?" #: qt/snapshotsdialog.py:406 #, fuzzy msgid "WARNING: This cannot be revoked." msgstr "ไม่สามารถเพิกถอนสิ่งนี้ได้!" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "ยกเว้น \"{path}\" จากสแนปช็อตในอนาคตหรือไม่?" backintime-1.5.4/common/po/tr.po000066400000000000000000002015131477034762000165360ustar00rootroot00000000000000# Turkish translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-12 11:07+0000\n" "Last-Translator: buhtz \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Uyarı" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Ana profil" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Yerel (EncFS şifreli)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (EncFS şifreli)" #: common/config.py:278 msgid "Local" msgstr "Yerel" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH gizli anahtarı" #: common/config.py:283 msgid "Local encrypted" msgstr "Yerel olarak şifrelenmiş" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Şifreleme" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH şifrelenmiş" #: common/config.py:296 msgid "Default" msgstr "Varsayılan" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Profil: \"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Anlık görüntü dizini geçersiz." #: common/config.py:340 #, fuzzy msgid "At least one directory must be selected for backup." msgstr "Yedekleme için en az bir klasör seçmelisiniz" #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "{path} geri yükle" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Yedekleme alt klasörü dahil edilemez." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Yeni crontab yazımı başarısız oldu." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Crontab komutu mevcut olmasına rağmen Cron çalışmıyor. Planlanan yedekleme " "işleri çalışmayacak. Cron yüklü olabilir ancak etkinleştirilmemiş olabilir. " "\"systemctl enable cron\" komutunu deneyin veya GNU Linux dağıtımınızın " "destek kanallarına başvurun." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "{profile_id} profili için Udev kuralı yüklenemedi. '{dbus_interface}' DBus " "Hizmeti kullanılabilir değildi" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Udev zamanlama kipi {mode} ile çalışmıyor" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "{path} için UUID bulunamadı" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Yapılandırma kaydedilemedi" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Yapılandırma yüklenemedi" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "\"{name}\" profili zaten var." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Son profil kaldırılamaz." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "'{command}' bağlanamıyor" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Şifrelenmiş klasör için yapılandırma bulunamadı." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Yeni şifreli klasör oluşturulsun mu?" #: common/encfstools.py:146 msgid "Cancel" msgstr "İptal" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Lütfen parolayı onaylayın." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Parola eşleşmiyor." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Anlık görüntü al" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "{mountprocess} , {mountpoint} den ayrılamıyor." #: common/mount.py:709 #, fuzzy, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} bulunamadı. Lütfen {installcommand} komutunu kullanarak yükleyin." #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Bağlantı noktası {mntpoint} boş değil." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Şifrenizi {mode}profili için giriniz \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "BAŞARISIZ" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "İzinleri geri yükle" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Tamamlandı" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Pille çalışırken yedeklemeyi erteleme" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Klasör oluşturulamadı." #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Eğer bu bir çıkarılabilir sürücüde ise lütfen takın ve ardından Tamam'a " "basın." #: common/snapshots.py:849 #, fuzzy, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "%s saniye bekliyor." msgstr[1] "%s saniye bekliyor." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "{snapshot_id} anlık görüntüsü alınamadı." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Lütfen sabırlı olun. Tamamlanıyor…" #: common/snapshots.py:1077 #, fuzzy msgid "Can't create directory." msgstr "Klasör oluşturulamadı" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Yapılandırma dosyası kaydediliyor…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "İzinler kaydediliyor…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Devam edilebilecek {snapshot_id} artık anlık görüntüsü bulundu." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Son çalıştırmadan kalan {snapshot_id} klasörü kaldırılıyor" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Klasör kaldırılamıyor" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Anlık görüntü al" #: common/snapshots.py:1430 msgid "Success" msgstr "Başarılı" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Hata sebebiyle kısmen aktarıldı" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Kaybolan kaynak dosyalar nedeniyle kısmi aktarım (bkz. 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' sonlandı, çıkış kodu: {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Daha fazla ayrıntı için bakınız; 'man rsync'" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Negatif rsync çıkış kodları sinyal numaralarıdır, bkz. 'kill -l' ve 'man " "kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Hiçbir değişiklik yok, yeni anlık görüntü almak gereksiz" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "{new_path} yolu {path} olarak yeniden adlandırılamadı" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Akıllı kaldırma" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Eski anlık görüntüleri kaldırma" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Saklama ilkelerini uygula" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "En az boş alan korunmaya çalışılıyor" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "En az {perc} boş düğümü korumaya çalışıyor" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Şimdi" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "{sshfs} bağlanamadı" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent bulunamadı. Lütfen kurulu olduğundan emin olun." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "ssh özel anahtarının kilidi açılamadı. Parola yanlış ya da Cron için parola " "yok." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{host} için {cipher} şifresi başarısız oldu." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Uzak yol mevcut ancak bir dizin değil." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Uzak yol yazılabilir değil." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Uzak yol çalıştırılabilir değil." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Uzak klasör oluşturulamadı." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Uzak bilgisayar {host} desteklemediği komut: {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Daha fazla yönerge için 'man backintime'a bakın" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "" "{host} ana bilgisayarındaki kontrol komutları bilinmeyen bir hata döndürdü" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Uzak sunucu {host} sabit bağlantıları desteklemiyor" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "" "Genel SSH anahtarını \"{pubkey}\" uzak ana bilgisayar \"{host}\" üzerine " "kopyala." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "\"{user}\" kullanıcısı için parola giriniz." #: common/tools.py:400 #, fuzzy, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "{path} için girilen hedef dosya sistemi hard-link desteklemeyen FAT ile " "biçimlendirilmiş. Lütfen özgün Linux dosya sistemi kullanın." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Uzak yol mevcut ancak bir dizin değil." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Klasörler oluşturulamadı:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Yazma erişimi kısıtlanmış olabilir." #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "{path} için girilen hedef dosya sistemi hard-link desteklemeyen FAT ile " "biçimlendirilmiş. Lütfen özgün Linux dosya sistemi kullanın." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "{path} için girilen hedef dosya sistemi bir paylaşımlı SMB dizini. Lütfen " "SMB sunucunun sembolik bağları desteklediğini teyit edin ya da " "{expertOptions} bölümündeki {copyLinks} seçeneğini etkinleştirin." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Linkleri kopyala (sembolik linklerin hedef dosyalarını kopyalar)" #: common/tools.py:504 msgid "Expert Options" msgstr "Uzman Seçenekleri" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "{path} için hedef dosya sistemi bir sshfs ile bağlanmış paylaşımdır. Sshfs " "sabit bağlantıları desteklemez. Lütfen 'SSH' modunu kullanın." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Bu klasör içerisinde dosya oluşturulması sırasında hata:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Hakkında" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Yazanlar" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Çeviriler" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Lisans" #: qt/app.py:172 msgid "Shortcuts" msgstr "Kısayollar" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Bu klasör, \n" "seçili anlık görüntüde yok." #: qt/app.py:257 msgid "Add to Include" msgstr "Dahil Et'e Ekle" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Dışla'ya Ekle" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "{app_name} herhangi bir yapılandırma bulunamadığı için ilk defa " "çalıştırılıyor gibi görünüyor." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Var olan bir yapılandırmayı içe aktarın (yedekeleme hedef dosyasından veya " "farklı bir bilgisayardan)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Eğer bu bir çıkarılabilir sürücüde ise lütfen takın ve ardından Tamam'a " "basın." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Anlık görüntü al" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "" "Dosya değişikliği tespiti için değişiklik zamanı ve boyutunu kullanın." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Anlık görüntü kipi (sağlama toplamı kipi)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Dosya değişikliklerini algılamak için sağlama toplamlarını kullan." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Anlık görüntü sürecini duraklat" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Anlık görüntü sürecini sürdür" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Anlık görüntü sürecini durdur" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Anlık görüntü listesini yenile" #: qt/app.py:497 msgid "Name snapshot" msgstr "Anlık görüntüyü adlandır" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Anlık görüntüyü sil" #: qt/app.py:505 msgid "View snapshot log" msgstr "Anlık görüntü günlüğünü görüntüle" #: qt/app.py:509 msgid "View last log" msgstr "Son günlüğü görüntüle" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Profilleri yönet…" #: qt/app.py:517 msgid "Shutdown" msgstr "Kapat" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Anlık görüntü tamamlandığında sistemi kapat." #: qt/app.py:521 msgid "Setup language…" msgstr "Kurulum dili…" #: qt/app.py:525 msgid "Exit" msgstr "Çıkış" #: qt/app.py:529 msgid "User manual" msgstr "Kullanım kılavuzu" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" "Kullanım kılavuzunu tarayıcıda açın (mevcutsa yerel, aksi takdirde " "çevrimiçi)" #: qt/app.py:535 #, fuzzy msgid "man page: Back In Time" msgstr "Zaman Tüneli" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "\"Back In Time\" hakkındaki man sayfasını göster" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Profiller yapılandırma dosyası" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" "Profil yapılandırma dosyası (backintime-config) hakkında man sayfasını " "görüntüler" #: qt/app.py:547 msgid "Project website" msgstr "Proje Websitesi" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "\"Back In Time\" web sitesini aç" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Değişiklik Günlüğü" #: qt/app.py:555 msgid "FAQ" msgstr "SSS" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Sıkça Sorulan Sorular'ı (SSS) tarayıcıda açın" #: qt/app.py:559 msgid "Ask a question" msgstr "Soru Sor" #: qt/app.py:563 msgid "Report a bug" msgstr "Hata Bildir" #: qt/app.py:566 msgid "Translation" msgstr "Çeviri" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Çeviriye katılım mesajını tekrar gösterir." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Şifreleme Geçişi (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "EncFS kaldırma mesajını tekrar gösterir." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Geri Yükle" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Seçilen dosyaları veya klasörleri özgün hedefe geri yükle." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Şuraya geri yükle …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Seçilen dosyaları veya klasörleri yeni hedefe geri yükle." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "Gösterilen klasörü ve tüm içeriğini özgün hedefe geri yükle." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "Şu anda gösterilen klasörü ve tüm içeriğini yeni hedefe geri yükle." #: qt/app.py:601 msgid "Up" msgstr "Yukarı" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Gizli dosyaları göster" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Anlık görüntüleri karşılaştır…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Sürüm adayı" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "EncFS kaldırma mesajını tekrar gösterir." #: qt/app.py:676 msgid "Back In &Time" msgstr "Zaman Tüneli" #: qt/app.py:681 msgid "&Backup" msgstr "&Yedekle" #: qt/app.py:692 msgid "&Restore" msgstr "&Geri Yükle" #: qt/app.py:698 msgid "&Help" msgstr "Y&ardım" #: qt/app.py:743 msgid "Icons only" msgstr "Sadece simgeler" #: qt/app.py:746 msgid "Text only" msgstr "Sadece Metin" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Eğer bu pencereyi kapatırsanız, Zaman Tüneli anlık görüntü işlemi " "tamamlandığında sisteminizi kapatamayacak." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Gerçekten kapatmak istiyor musunuz?" #: qt/app.py:1072 msgid "Working:" msgstr "Çalışıyor:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Tamamlandı, yedekleme gerekmiyor" #: qt/app.py:1129 msgid "Working" msgstr "Çalışıyor" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Hata" #: qt/app.py:1161 msgid "Sent" msgstr "Gönder" #: qt/app.py:1162 msgid "Speed" msgstr "Hız" #: qt/app.py:1163 msgid "ETA" msgstr "ETA" #: qt/app.py:1225 msgid "Global" msgstr "Küresel" #: qt/app.py:1226 msgid "Root" msgstr "Kök Dizini" #: qt/app.py:1227 msgid "Home" msgstr "Ev" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Yedekleme klasörleri" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Anlık Görüntü Adı" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Bu anlık görüntüyü silmek istediğinizden emin misiniz?" msgstr[1] "Bu anlık görüntüleri silmek istediğinizden emin misiniz?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Üzerine yazmadan veya kaldırmadan önce\n" "{suffix} ile yerel dosyaları yedekleyin." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Daha yeni dosya sürümleri, geri yüklenmeden önce sonuna {suffix} eklenerek " "yeniden adlandırılacaktır. Artık onlara ihtiyacınız yoksa, aşağıdaki komutla" " silebilirsiniz:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Yalnızca var olmayan ya da hedefteki ögelerden\n" "daha yeni olanları geri yükle.\n" "\"rsync --update\" seçeneğini kullanarak." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Özgün klasördeki daha yeni ögeleri kaldır." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Seçilen dosyaları veya klasörleri orijinal hedefe geri yükleyin ve anlık " "görüntüde bulunmayan dosya veya klasörleri silin. Çok dikkatli olun çünkü bu" " işlem, anlık görüntü alınırken hariç tutulan dosya ve klasörleri " "silecektir." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Bu ögeyi gerçekten {path} yeni klasörüne\n" "geri yüklemek istiyor musunuz?" msgstr[1] "" "Bu ögeleri gerçekten {path} yeni klasörüne\n" "geri yüklemek istiyor musunuz?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Bu ögeyi gerçekten geri yüklemek istiyor musunuz?" msgstr[1] "Bu ögeleri gerçekten geri yüklemek istiyor musunuz?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "{path} içindeki tüm yeni dosyaları kaldırmak istediğinizden emin misiniz?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Özgün klasördeki tüm yeni dosyaları kaldırmak istediğinizden emin misiniz?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}UYARI{BOLDEND}: Dosyaları dosya sistemi kökünden silmek sisteminizin " "tamamını bozabilir." #: qt/app.py:1857 msgid "Snapshot" msgstr "Anlık görüntü" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "{path} geri yükle" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "{path} geri yükle, hedef …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Merhaba\n" "Back In Time'ı an itibarıyla {language} dilinde bir süredir kullanmaktasınız.\n" "Yüklediğiniz Back In Time sürümünün {language} çevirisi henüz {perc} tamamlandı. Teknik uzmanlık seviyeniz ne olursa olsun çeviriye yardımcı olarak Back In Time'a katkıda bulunabilirsiniz.\n" "Çeviriye katkıda bulunmak için {translation_platform_url} adresini ziyaret edebilirsiniz. Daha çok yardım ve soru için {back_in_time_project_website} adresini ziyaret edebilirsiniz.\n" "Böldüğümüz için özür dileriz. Bu mesaj tekrar gösterilmeyecektir. Bu mesajı istediğiniz zaman yardım menüsünden görüntüleyebilirsiniz.\n" "Back In Time Ekibi" #: qt/app.py:2071 msgid "translation platform" msgstr "çeviri platformu" #: qt/app.py:2076 msgid "Website" msgstr "Web Sitesi" #: qt/app.py:2090 msgid "Your translation" msgstr "Sizin çeviriniz" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "Mastodon'daki Fediverse: {link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "E-posta {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "E-posta listesi {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "Proje web sitesinde {link_and_label}." #: qt/app.py:2118 msgid "Open an issue" msgstr "hata bildir" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Alternatif olarak istediğiniz iletişim yolunu kullanabilirsiniz." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Back In Time'ın bu sürümü bir Sürüm Adayıdır ve öncelikli olarak bir sonraki resmi sürüme hazırlık olarak kararlılık testi için tasarlanmıştır..\n" "Hiçbir kullanıcı verisi veya telemetri toplanmaz. Ancak, Back In Time ekibi Sürüm Adayı'nın kullanılıp kullanılmadığını ve bu tür ön sürüm sürümlerini sağlamaya devam etmenin değerli olup olmadığını bilmekle çok ilgilenmektedir.\n" "Bu nedenle, ekip herhangi bir sorunla karşılaşmamış olsanız bile bu sürümü test edip etmediğinize dair kısa bir geri bildirim rica etmektedir. Birkaç dakikalık kısa bir test çalışması bile bize çok yardımcı olacaktır..\n" "Aşağıdaki iletişim seçenekleri mevcuttur:\n" "{contact_list}\n" "Bu sürümde, bu mesaj tekrar gösterilmeyecek ancak yardım menüsünden istediğiniz zaman erişilebilir.\n" "Desteğiniz ve Back In Time'ı geliştirmemize yardımcı olduğunuz için teşekkür ederiz!!\n" "\"Back In Time\" ekibi" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Dil ayarları yalnızca Zamanda Geri Dönüş yeniden başlatıldıktan sonra etkili" " olur." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "EncFS profil oluşturulması 2026 yılında planlanan bir sonraki sürümde (1.7) " "kaldırılacaktır." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "EncFS desteği yakın gelecekte sonlandırılacak. Profil için artık o modu " "kullanmanız önerilmiyor." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "Teknik döküman" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "EncFS desteği güvenlik zafiyetleri nedeni ile sonlandırılacaktır." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Daha fazla detay ve alternatif öneriler için lütfen {whitepaper}'a başvurun." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Aşağıdaki profil(ler) EncFS ile şifreleme kullanıyor:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Bu mesaj bir daha gösterilmeyecek. Bu iletişim kutusu her zaman yardım " "menüsünden erişilebilir." #: qt/encfsmsgbox.py:94 #, fuzzy msgid "Your Back In Time Team" msgstr "Zaman Tüneli" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Kurulum dili" #: qt/languagedialog.py:97 msgid "System default" msgstr "Sistem öntanımlısı" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "İşletim sistemi dilini kullanın." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Çevrilen: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Son Günlük Görünüm" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Anlık Görüntü Günlük Görünümü" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Profil:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Anlık görüntüler:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Filtrele:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tümü" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Değişiklikler" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Hatalar" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Bilgi" msgstr[1] "Bilgiler" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync aktarımı başarısızlıkları (deneysel)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Hata, [I] Bilgi, [C] Değiştir" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "kod çözümleme yolları" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Profilleri yönet" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Düzenle" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Ekle" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Kaldır" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Genel" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Dahil Et" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Dosyaları ve klasörleri dahil et" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Dosya Ekle" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Klasör Ekle" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "Dışl&a" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Bilgi{ENDBOLD}: 'SSH şifreli' modda, yalnızca tek veya çift yıldızlar " "işlevseldir (örneğin {example2}). Diğer türdeki joker karakterler ve " "desenler göz ardı edilir (örneğin {example1}). Dosya adları, EncFS " "tarafından şifrelendiği için bu modda öngörülemez." #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Dışlama deseni, dosyalar veya klasörler" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Öntanımlı Ekle" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Dışarıda bırakılacak dosyaların boyutundan büyük olanlar:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "" "{size_unit} biriminde belirtilen değerden büyük dosyaları dışarıda bırakın." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "'Tam rsync modu' devre dışı bırakıldığında, bu yalnızca rsync için bir " "aktarım seçeneği olduğu için yeni dosyaları etkiler. Bu nedenle, daha önce " "yedeklenmiş büyük dosyalar, değiştirilmiş olsalar bile anlık görüntülerde " "korunacaktır." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Kaldırma & Saklama" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Seçenekler" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "&Uzman Seçenekleri" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Yapılandırma Geri Yükle" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Kullanıcı Geri Çağrısını Düzenle" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Yeni profil" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Profili yeniden adlandır" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "\"{name}\" profilini silmek istediğinizden emin misiniz?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}Önemle Önerilir{ENDBOLD}: (Tüm öneriler zaten dahil edildi.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Önemle Tavsiye Edlilir{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Dışlama deseni" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Dosyayı dışla" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Klasörü dışla" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Dosyayı dahil et" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" bir sembolik bağlantı. Bağlantılı hedef, siz onu da dahil edene kadar yedeklenmeyecek.\n" "Bunun yerine sembolik bağlantının hedefini dahil etmek ister misiniz?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Klasörü dahil et" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" "'SSH şifrelenmiş' modunda bu desen işlevli olmadığı için devre dışı " "bırakıldı." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Zamanlama" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "Gün:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "Haftanın günü:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Saatler:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Sürücü bağlanır bağlanmaz Back In Time'ı çalıştır (yalnızca X günde bir).\n" "Sizden sudo parolası istenecektir." #: qt/manageprofiles/schedulewidget.py:97 #, fuzzy msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Back In Time'ı tekrar tekrar çalıştır. Bu, bilgisayar düzenli olarak " "çalışmıyorsa kullanışlıdır." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Her:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Hata ayıklama mesajlarının kaydetmeyi etkinleştir" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Sorun giderme düzeyindeki iletileri '--debug' seçeneğiyle sistem günlüğüne " "yazar." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Dikkat: Yüksek miktarda çıktı yaratacağından sadece geçici bir süreliğine " "tanılama yapmak için kullanın." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Devre dışı" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Her Başlatıldığında/Yeniden Başlatıldığında" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, fuzzy, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "{n} dakikada bir" msgstr[1] "{n} dakikada bir" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Her Saat" msgstr[1] "Her {n} saatte" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, fuzzy, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "{n} saatte bir" msgstr[1] "{n} saatte bir" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Özel saatler" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Her gün" #: qt/manageprofiles/schedulewidget.py:161 #, fuzzy msgid "Repeatedly (anacron)" msgstr "Tekrar Tekrar (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Sürücü bağlandığında (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Her hafta" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Her ay" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Her yıl" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Saat" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Gün" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Hafta" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Ay" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Özel saatler yalnızca virgülle ayrılmış saat listesi (ör. 8,12,18, 23) ya da" " her 3 saatte bir düzenli yedekleme için */3 olabilir." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH Vekil" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Ana Makine:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Port:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Kullanıcı:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Hedef ana bilgisayara bu vekil sunucu (aynı zamanda atlama sunucusu olarak " "da bilinir) üzerinden bağlanın. Ayrıntılar için \"ssh\" komut belgesindeki " "\"-J\" veya \"ssh_config\" man sayfasındaki \"ProxyJump\" seçeneğine bakın." #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Soru" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Aşağıdaki gelişmiş yapılandırma seçeneklerini sadece etkilerinin " "farkındaysanız kullanın." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "'rsync' komutunu '{cmd}' ile çalıştır:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "zamanlanmış görev olarak" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "uzak makinede" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "elle anlık görüntü alınırken" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Bu seçeneği etkinleştirmek için lütfen 'nocache' kurun)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "yerel makinede" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Zamanlanmış görevlerde stdout'u /dev/null'a yönlendir." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Cron, bir MTA yüklü ise, cron işlerinin çıktısını ekli bir e-posta ile " "otomatik olarak gönderecektir." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Zamanlanmış görevlerde stderr'ı /dev/null'a yönlendir." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Eğer bir MTA yüklü ise, Cron otomatik olarak cron işlerinin hatalarını " "içeren bir e-posta gönderecektir." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/sn" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Rsync bant genişliği kullanımını sınırla:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "ACL koru" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Genişletilmiş öznitelikleri koru (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Güvenli olmayan bağlantıları kopyala (yalnızca mutlak bağlantılarla çalışır)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Yalnızca bir dosya sistemiyle sınırla" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Seçenekler çift tırnak içine alınmalıdır, ör: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Ek seçenekleri rsyncʼa yapıştır" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Uzak ana bilgisayar üzerinde her komuttan önce çalıştırılacak önek." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Değişkenler $FOO ile kaçınılmalıdır. Bu rsync'i etkilemez. Rsync için bir ön" " ek eklemek için \"{example_value}\" ve {rsync_options_value} kullanın." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "öntanımlı" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "SSH komutlarına ön ek ekle" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Uzak makinenin çevrim içi olduğunu denetle" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Uyarı: Eğer devre dışı bırakılırsa ve uzak ana bilgisayar erişilemezse, bu " "bazı garip hatalara neden olabilir." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "" "Uzak ana bilgisayarın gerekli tüm komutları destekleyip desteklemediğini " "kontrol edin." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Uyarı: Eğer devre dışı bırakılırsa ve uzak ana bilgisayar gerekli tüm " "komutları desteklemiyorsa, bu bazı garip hatalara neden olabilir." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(varsayılan: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "devre dışı" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "etkin" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Kip:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Anlık görüntülerin nereye kaydedileceği" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH Ayarları" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Yol:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Şifre:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Özel Anahtar:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Var olan bir özel anahtar dosyası seçin (normalde \"id_rsa\" olarak " "adlandırılır)" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Parola olmadan yeni SSH anahtarı oluştur (özel anahtar dosyası zaten " "seçiliyse buna izin verilmez)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Parola" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Parolayı Anahtarlığa Kaydet" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Cron için Parolayı Önbellekle (Güvenlik sorunu: root parolayı okuyabilir)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Gelişmiş" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Tam anlık görüntü yolu:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "SSH için bir gizli anahtar dosyası seçmediniz." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Yeni bir şifresiz genel/özel anahtar çifti oluşturmak ister misiniz?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Özel anahtar dosyası \"{file}\" yok." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Şifresiz girişi etkinleştirmek için genel SSH anahtarınızı uzak ana " "bilgisayara kopyalamak ister misiniz?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "{host} ana bilgisayarının kimliği doğrulanamıyor." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} anahtar parmak iziniz:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Lütfen bu parmak izini doğrulayın. 'known_hosts' dosyanıza eklemek ister " "misiniz?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Anlık görüntüler klasörünü değiştirmek istediğinizden emin misiniz?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "{path} yolunda yeni SSH anahtarı oluşturulamadı" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Bildirimleri etkinleştir" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Pille çalışırken anlık görüntüleri devre dışı bırak" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Güç durumu sistemden alınamıyor" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Her seferinde yalnızca bir anlık görüntü çalıştır" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Diğer anlık görüntüler şu anlık yapılan anlık görüntüleme işlemi bitene " "kadar engellenecek. Bu global bir seçenektir, bu nedenle bu kullanıcı için " "tüm profilleri etkileyecektir. Ancak diğer kullanıcılar için de bunu " "etkinleştirmeniz gerekecek." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Geri yüklemede değiştirilen dosyaları yedekle" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Dosyaların daha yeni sürümleri geri yüklenmeden önce sonuna {suffix} " "eklenerek yeniden adlandırılacak. Onlara artık ihtiyacınız yoksa {cmd} ile " "kaldırabilirsiniz" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Hatalarda devam et (eksik anlık görüntüleri tut)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Değişiklikleri algılamak için sağlama toplamı kullan" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Değişiklik olsun ya da olmasın yeni anlık görüntü al." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Günlük Düzeyi:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Yok" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Aşağıdaki kurallar yukarıdan aşağıya doğru işlenir. Sonraki kurallar önceki " "kuralları geçersiz kılar ve bunlarla kısıtlanmaz. Ayrıntılar ve örnekler " "için {manual}'na bakın." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "kullanım kılavuzu" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Kullanım kılavuzunu tarayıcınızda açın." #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Adlandırılmış anlık görüntüleri kaldırma." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "En son veya en yeni yedekleme her durumda saklanacaktır." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Diğer kurallar bu davranışı değiştiremez." #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Adlandırılmış anlık görüntüleri kaldırma." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Alışılmış zaman damgasına ek olarak isim verilen anlık görüntüler her " "durumda saklanacak ve kaldırılmayacaktır." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Yıl" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Anlık görüntüyü sil" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Tüm günler, bu gün atlanacaktır." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "Pazartesi gününden başlayan takvim haftası, bu hafta atlanacaktır." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 aylık dönemler. Mevcut ay dikkate alınmaz." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Saklama ilkeleri" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Uzak makinede arka planda çalıştır." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Akıllı kaldırma prosedürü doğrudan uzak makinede çalışacaktır. \"bash\", " "\"screen\" ve \"flock\" komutları uzak makinede yüklü ve kullanılabilir " "olmalıdır." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" "Seçilmesi durumunda \"Back In Time\" ilk olarak uzak makine'yi test " "edecektir." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "saymaya bu gün dahil edilerek başlanacaktır." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Tüm anlık görüntüleri şu kadar süre için sakla" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 #, fuzzy msgid "day(s)." msgstr "gün" #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Son X gün için her gün bir anlık görüntü sakla" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "haftalar bu hafta dahil edilerek sayılacaktır. Hafta, pazartesi gününden " "başlar." #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Son X hafta için her hafta bir anlık görüntü sakla" #: qt/manageprofiles/tab_remove_retention.py:336 #, fuzzy msgid "week(s)." msgstr "hafta" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Aylar, içinde bulunulan aydan başlayarak takvim ayı olarak sayılır." #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Son X ay için her ay bir anlık görüntü sakla" #: qt/manageprofiles/tab_remove_retention.py:349 #, fuzzy msgid "month(s)." msgstr "ay" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" "Yıllar, içinde bulunulan yıldan başlayarak takvim yılı olarak sayılır." #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Tüm anlık görüntüleri şu kadar süre için sakla" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "tüm yıllar." #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Eğer boş alan şundan azsa:" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Eğer boş inode sayısı şundan azsa:" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Eski anlık görüntüleri kaldırma" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Soru" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Profil: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Son Günlüğü Görüntüle" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "{appname}ʼı Başlat" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Çalışıyor…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Gönderilen:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Hız:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Tahmini Varış Süresi:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Anlık görüntüler" #: qt/qttools.py:506 msgid "Today" msgstr "Bugün" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Dün" #: qt/qttools.py:522 msgid "This week" msgstr "Bu hafta" #: qt/qttools.py:529 msgid "Last week" msgstr "Geçen hafta" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Bu bir anlık görüntü DEĞİL, yerel dosyalarınızın canlı bir görüntüsüdür" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Son denetim {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Ayarları İçe Aktar" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Yapılandırma bulunamadı" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "İçe Aktar" #: qt/restoreconfigdialog.py:164 #, fuzzy, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Ayarlama dosyasının içe aktarılacağı anlık görüntü klasörünü seçin. Yol şu " "şekilde olabilir: {samplePath}" #: qt/restoreconfigdialog.py:169 #, fuzzy msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Eğer klasör harici veya uzak bir sürücüde bulunuyorsa, önceden manuel olarak" " bağlanmalıdır." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Tüm Günlüğü Göster" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Anlık görüntüleri karşılaştırmayla ilgili seçenekler" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Komut:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Parametreler:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Yol parametreleri olarak %1 ve %2 kullan" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Lütfen farklı fark komutu belirleyin veya İptal'e basın." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Bu komut \"{cmd}\" bu sistemde bulunmamaktadır. Lütfen farklı bir şey " "deneyin veya İptal'e basın." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Fark komutu için parametre belirlenmedi. Varsayılan değerler kullanılıyor " "\"{params}\"." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Yalnızca fark anlık görüntüleri" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Yalnızca şuna eşit anlık görüntüleri listele:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Derin denetim (daha doğru, ancak yavaş)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Sil" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Tümünü Seç" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Karşılaştır" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Git" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Seçenekler" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Bir anlık görüntüyü kendisiyle karşılaştıramazsınız." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "" "{snapshot_id} anlık görüntüsündeki {file} dosyasını gerçekten silmek istiyor" " musun?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "" "{count} anlık görüntü içindeki {file} dosyasını gerçekten silmek istiyor " "musun?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "UYARI: Bu işlemin geri alınması mümkün değil." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "{path} yolu gelecek anlık görüntülerden dışlansın mı?" #, fuzzy #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Yedekleme alt klasörü dahil edilemez." backintime-1.5.4/common/po/uk.po000066400000000000000000002304771477034762000165430ustar00rootroot00000000000000# Ukrainian translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-06 15:08+0000\n" "Last-Translator: SomeTr \n" "Language-Team: Ukrainian \n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\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" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Попередження" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Основний профіль" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Локальний (зашифрований EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (зашифрований EncFS)" #: common/config.py:278 msgid "Local" msgstr "Локальний" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Приватний ключ SSH" #: common/config.py:283 msgid "Local encrypted" msgstr "Локальний зашифрований" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Шифрування" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH зашифрований" #: common/config.py:296 msgid "Default" msgstr "За замовчуванням" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Профіль: «{name}»" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Каталог для резервних копій не є дійсним." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Для резервного копіювання необхідно вибрати принаймні один каталог." #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "Каталог: {path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "" "Цей каталог неможливо включити в резервну копію, оскільки він є частиною " "місця призначення резервної копії." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Не вдалося записати новий crontab." #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron не запускається, незважаючи на наявність команди crontab. Заплановані " "завдання резервного копіювання не буде виконано. Можливо, Cron встановлено, " "але не ввімкнено. Спробуйте команду «systemctl enable cron» або зверніться " "до каналів підтримки Вашого дистрибутиву GNU/Linux." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Не вдалося встановити правило Udev для профілю {profile_id}. DBus Service " "«{dbus_interface}» недоступний" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Розклад udev не працює з режимом {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Не вдалося знайти UUID для {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Не вдалося зберегти конфігурацію" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Не вдалося завантажити конфігурацію" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Профіль «{name}» вже існує." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Неможливо видалити останній профіль." #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "Не вдається змонтувати «{command}»" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "Конфігурацію для зашифрованого каталогу не знайдено." #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "Створити новий зашифрований каталог?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Скасувати" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Підтвердіть пароль." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Пароль не збігається." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Зробити копію" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Не вдається розмонтувати {mountprocess} з {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "{command} не знайдено. Встановіть її (напр., за допомогою " "«{installcommand}»)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Точка монтування {mntpoint} не порожня." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Введіть пароль для профілю {mode} «{profile}»:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "НЕВДАЧА" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Відновлення дозволів" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Виконано" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Вимкнення резервування при роботі від батареї" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "Не вдається знайти каталог резервних копій." #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "Якщо він знаходиться на знімному диску, підключіть диск." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Очікування %s секунда." msgstr[1] "Очікування %s секунди." msgstr[2] "Очікування %s секунд." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Не вдалося зробити копію {snapshot_id}." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "Будь ласка, зачекайте. Завершення…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Не вдається створити каталог." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Збереження файлу конфігурації…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Збереження дозволів…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Знайдено незавершену копію {snapshot_id}, яку можна продовжити." #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "" "Видалення каталогу незавершеної копії {snapshot_id} від попереднього запуску" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "Не вдається видалити каталог" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Створення резервної копії" #: common/snapshots.py:1430 msgid "Success" msgstr "Успішно" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Переміщено частково, через помилку" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Переміщено частково, оскільки вихідні файли зникли (див. «man rsync»)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "«rsync» завершився з кодом виходу {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Докладніше див. «man rsync»" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "" "Від'ємні значення кодів виходу rsync є сигнальними номерами, див. «kill -l» " "і «man kill»" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Немає змін, резервування не потрібне" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Не вдається перейменувати {new_path} в {path}." #: common/snapshots.py:1855 msgid "Smart removal" msgstr "Розумне видалення" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "Застосувати правила для видалення старих копій" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "Застосувати політику збереження" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Спроба зберегти мінімум вільного місця" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Спроба зберегти мінімум {perc} вільних айнодів" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Зараз" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Не вдається змонтувати {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "ssh-agent не знайдено. Переконайтеся, що його встановлено." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Не вдалося розблокувати приватний ключ SSH. Пароль неправильний або " "недоступний для cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Помилка шифру {cipher} для сервера {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Віддалений шлях існує, але це не каталог." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Неможливо записати у віддалений шлях." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Віддалений шлях неможливо виконати." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Не вдається створити віддалений шлях." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Сервер {host} не підтримує {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Дивіться «man backintime» для подальших інструкцій" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Перевірка команд на сервері {host} повернула невідому помилку" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Сервер {host} не підтримує жорсткі посилання" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Копіювати публічний ключ SSH «{pubkey}» на сервер «{host}»." #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Будь ласка, введіть пароль для «{user}»." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Вказане розташування {path} відформатовано у NTFS, яка має відому " "несумісність з Unix-подібними файловими системами." #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} не є допустимим каталогом." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "Не вдалося створити каталог:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "Можливо, доступ на запис обмежений." #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Файлову систему призначення для {path} відформатовано у FAT, яка не " "підтримує жорсткі посилання. Використовуйте файлові системи для GNU/Linux." #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Файлова система призначення для {path} — змонтований спільний SMB-ресурс. " "Переконайтеся, що віддалений SMB-сервер підтримує символьні посилання, або " "активуйте «{copyLinks}» в «{expertOptions}»." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Копіювати посилання (слідувати за символьними посиланнями)" #: common/tools.py:504 msgid "Expert Options" msgstr "Розширені налаштування" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Файлова система призначення для {path} — змонтований спільний sshfs-ресурс. " "Sshfs не підтримує жорсткі посилання. Будь ласка, використовуйте режим " "«SSH»." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "Не вдалося створити файл у каталозі:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Про програму" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Автори" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Переклади" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Ліцензія" #: qt/app.py:172 msgid "Shortcuts" msgstr "Скорочення" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Такого каталогу немає\n" "в обраній резервній копії." #: qt/app.py:257 msgid "Add to Include" msgstr "Включити" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Виключити" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Схоже, що це перший запуск {app_name}, оскільки не знайдено жодної " "конфігурації." #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "" "Імпортувати існуючу конфігурацію (з каталогу резервної копії або з іншого " "комп'ютера)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Якщо вона знаходиться на знімному диску, підключіть його і натисніть OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Зробити копію" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Виявляти зміни за датою зміни і розміром." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Зробити копію з контрольними сумами" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Виявляти зміни за контрольними сумами." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Зупинити створення копії" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Продовжити створення копії" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Скасувати створення копії" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Оновити список копій" #: qt/app.py:497 msgid "Name snapshot" msgstr "Назвати копію" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Видалити копію" #: qt/app.py:505 msgid "View snapshot log" msgstr "Переглянути журнал копій" #: qt/app.py:509 msgid "View last log" msgstr "Переглянути останній журнал" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Керувати профілями…" #: qt/app.py:517 msgid "Shutdown" msgstr "Вимкнення" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Вимкнути систему після завершення резервування." #: qt/app.py:521 msgid "Setup language…" msgstr "Змінити мову…" #: qt/app.py:525 msgid "Exit" msgstr "Вийти" #: qt/app.py:529 msgid "User manual" msgstr "Інструкція користувача" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "Відкриває посібник у браузері (локальний, якщо є, або ж онлайн)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "man page: Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "Показує посібник про Back In Time (backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "man page: Файл конфігурації профілів" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "Показує посібник про файл конфігурації профілів (backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "Сторінка проєкту" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "Відкриває сторінку Back In Time у браузері" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Історія змін" #: qt/app.py:555 msgid "FAQ" msgstr "Питання та відповіді" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "Відкриває відповіді на поширені питання (ЧаПи) у браузері" #: qt/app.py:559 msgid "Ask a question" msgstr "Задати запитання" #: qt/app.py:563 msgid "Report a bug" msgstr "Повідомити про помилку" #: qt/app.py:566 msgid "Translation" msgstr "Переклад" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Показує повідомлення про участь у перекладі." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Перехід на нове шифрування (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Показує повідомлення про видалення EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Відновити" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "" "Відновити обрані файли чи каталоги до їхнього початкового розташування." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Відновити до …" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "Відновити обрані файли чи каталоги до вказаного розташування." #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Відновити поточний каталог і весь його вміст до початкового розташування." #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Відновити поточний каталог і весь його вміст до вказаного розташування." #: qt/app.py:601 msgid "Up" msgstr "Вгору" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Показати приховані файли" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Порівняти копії…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "Release Candidate" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "Показує повідомлення про Release Candidate." #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&Резервування" #: qt/app.py:692 msgid "&Restore" msgstr "&Відновлення" #: qt/app.py:698 msgid "&Help" msgstr "&Допомога" #: qt/app.py:743 msgid "Icons only" msgstr "Лише значки" #: qt/app.py:746 msgid "Text only" msgstr "Лише текст" #: qt/app.py:749 msgid "Text below icons" msgstr "Текст під значками" #: qt/app.py:752 msgid "Text beside icon" msgstr "Текст поряд із значками" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Якщо закрити це вікно, Back In Time не зможе вимкнути Вашу систему після " "закінчення резервування." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Справді закрити?" #: qt/app.py:1072 msgid "Working:" msgstr "Виконання:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Виконано, резервування не потрібне" #: qt/app.py:1129 msgid "Working" msgstr "Виконання" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Помилка" #: qt/app.py:1161 msgid "Sent" msgstr "Надіслано" #: qt/app.py:1162 msgid "Speed" msgstr "Швидкість" #: qt/app.py:1163 msgid "ETA" msgstr "Залишилося" #: qt/app.py:1225 msgid "Global" msgstr "Загальні" #: qt/app.py:1226 msgid "Root" msgstr "Root" #: qt/app.py:1227 msgid "Home" msgstr "Home" #: qt/app.py:1255 msgid "Backup directories" msgstr "Каталоги резервування" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Назва копії" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Бажаєте видалити цю резервну копію?" msgstr[1] "Бажаєте видалити ці резервні копії?" msgstr[2] "Бажаєте видалити ці резервні копії?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Робити копію елементів перед їх перезаписом\n" "або видаленням, додаючи до назви {suffix}." #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Перед відновленням новіші версії файлів буде перейменовано з додаванням " "{suffix}. Якщо вони Вам не потрібні, можна видалити їх за допомогою команди:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Відновити лише елементи, які відсутні або\n" "новіші, ніж ті, що у вказаному розташуванні.\n" "Використовується «rsync --update»." #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "Видалити новіші елементи у початковому розташуванні." #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Відновити обрані файли чи каталоги до початкового розташування і видалити " "файли/каталоги, яких немає в резервній копії. Будьте дуже обережні, оскільки" " це призведе до видалення файлів і каталогів, які було виключено під час " "резервування." #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "Ви справді хочете відновити цей елемент до нового каталогу?" msgstr[1] "Ви справді хочете відновити ці елементи до нового каталогу?" msgstr[2] "Ви справді хочете відновити ці елементи до нового каталогу?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Ви справді хочете відновити цей елемент?" msgstr[1] "Ви справді хочете відновити ці елементи?" msgstr[2] "Ви справді хочете відновити ці елементи?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "Бажаєте видалити всі новіші файли в {path}?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "Бажаєте видалити всі новіші файли в початковому розташуванні?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "{BOLD}УВАГА{BOLDEND}: видалення файлів у root може зламати всю Вашу систему." #: qt/app.py:1857 msgid "Snapshot" msgstr "Копія" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Відновити {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Відновити {path} до …" # ignore-placeholder-compare #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Вітаємо\n" "Ви вже кілька разів користувалися Back In Time українською мовою.\n" "Переклад встановленої версії Back In Time на українську завершено на {perc}. Незалежно від Вашого рівня технічних знань, Ви може зробити свій внесок у переклад і, таким чином, у розвиток Back In Time.\n" "Якщо бажаєте зробити внесок, відвідайте {translation_platform_url}. Додаткову допомогу та відповіді на запитання можна отримати на сайті проєкту {back_in_time_project_website}.\n" "Перепрошуємо за переривання, це повідомлення більше не виводитиметься. Це діалогове вікно доступне в будь-який час через меню «Допомога».\n" "Ваша команда Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "платформу для перекладу" #: qt/app.py:2076 msgid "Website" msgstr "Вебсайт" #: qt/app.py:2090 msgid "Your translation" msgstr "Ваш переклад" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "На Mastodon {link_and_label} у Федісвіті" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "Email {link_and_label}." #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "Список розсилки {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} на вебсайті проєкту." #: qt/app.py:2118 msgid "Open an issue" msgstr "Створити задачу" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "Крім того, Ви можете скористатися іншим каналом на свій вибір." #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "Ця версія Back In Time є реліз-кандидатом (Release Candidate). Вона призначена в першу чергу для тестування стабільності при підготовці до наступного офіційного релізу.\n" "Жодних даних користувачів або телеметрії не збирається. Однак команду Back In Time дуже цікавить, чи використовується реліз-кандидат і чи варто надалі випускати такі тестові версії.\n" "Тому команда просить Вас надати короткий відгук про те, чи тестували Ви цю версію, навіть якщо у Вас не виникло ніяких проблем. Навіть побіжний тест протягом кількох хвилин дуже нам допоможе.\n" "Доступні такі варіанти зв'язку:\n" "{contact_list}\n" "У цій версії це повідомлення більше не виводитиметься, але воно доступне в будь-який час через меню «Допомога».\n" "Дякуємо за вашу підтримку і за те, що допомагаєте нам покращувати Back In Time!\n" "Ваша команда Back In Time" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Налаштування мови набувають чинності лише після перезапуску Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" "Створення профілю EncFS буде видалено в наступному випуску (1.7), " "запланованому на 2026 рік." #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "Не рекомендується надалі використовувати цей режим для профілю." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "документі" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "Підтримка EncFS припиняється через уразливості в системі безпеки." #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" "Докладнішу інформацію, в тому числі щодо потенційних альтернатив, дивіться у" " цьому {whitepaper}." #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Профілі, які використовують шифрування EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" "Заплановано заміну, але немає жодних гарантій, що вона буде готова вчасно." #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" "Запрошуємо користувачів долучитися до обговорення. Оновлену інформацію про " "наступні кроки див. у цьому {whitepaper}." #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" "Це повідомлення більше не виводитиметься. Це діалогове вікно доступне в " "будь-який час через меню «Допомога»." #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Ваша команда Back In Time" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Змінити мову" #: qt/languagedialog.py:97 msgid "System default" msgstr "Як у системі" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Використовувати мову операційної системи." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Перекладено: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Останній журнал" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Журнал копій" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Профіль:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "Резервні копії:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "Фільтр:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Усе" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Зміни" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Помилки" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "Інформація" msgstr[1] "Інформація" msgstr[2] "Інформація" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "Помилки переміщення rsync (експериментально)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Помилка, [I] Інформація, [C] Зміна" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "декодувати шляхи" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Керувати профілями" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Редагувати" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Додати" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Видалити" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Загальне" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "В&ключити" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "Включити файли і каталоги" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Додати файл" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "Додати каталог" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "Вик&лючити" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}Підказка{ENDBOLD}: в режимі «SSH зашифрований» можна використовувати " "лише одну або дві зірочки (напр., {example2}). Інші символи підстановки і " "шаблони ігноруються (напр., {example1}). Імена файлів у цьому режимі " "непередбачувані через шифрування EncFS." #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "Виключити шаблони, файли або каталоги" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Додати за замовчуванням" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Виключити файли більші ніж:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Виключити файли більші ніж значення в {size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Якщо «Full rsync mode» вимкнено, це вплине лише на нові файли, оскільки для " "rsync це переміщення, а не виключення. Тому великі файли, зарезервовані " "раніше, залишаться в копіях, навіть якщо вони змінилися." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "&Видалення і збереження" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "&Налаштування" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Роз&ширені налаштування" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Відновити конфігурацію" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Редаг. user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Новий профіль" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Перейменувати профіль" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Ви впевнені, що хочете видалити профіль «{name}»?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" "{BOLD}Настійно рекомендується{ENDBOLD}: (Усі рекомендації вже включено.)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}Настійно рекомендується{ENDBOLD}: {files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Виключити за шаблоном" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Виключити файл" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "Виключити каталог" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Включити файл" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "«{path}» — символьне посилання. Об'єкт, на який воно вказує, не буде зарезервовано, якщо його не включити.\n" "Включити цей об'єкт у резервну копію?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "Включити каталог" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "Вимкнено, оскільки цей шаблон не працює у режимі «SSH зашифрований»." #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Розклад" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "День:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "День тижня:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "Час:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "Години:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "після години" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "Хвилини:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Запускати Back In Time, коли Ви підключаєте диск (один раз на X днів). Вам " "потрібно буде ввести пароль sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Запускати Back In Time повторно. Корисно, якщо комп'ютер не працює постійно." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Кожні:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "Увімкнути запис повідомлень про налагодження" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" "Записує повідомлення рівня налагодження до системного журналу за допомогою " "«--debug»." #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" "Обережно: використовуйте лише тимчасово для діагностики, оскільки " "генерується велика кількість вихідних даних." #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Вимкнено" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "При кожному запуску/перезапуску" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Кожну {n} хвилину" msgstr[1] "Кожні {n} хвилини" msgstr[2] "Кожні {n} хвилин" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Кожну годину" msgstr[1] "Кожні {n} години" msgstr[2] "Кожні {n} годин" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Кожну {n} годину" msgstr[1] "Кожні {n} години" msgstr[2] "Кожні {n} годин" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Вказати години" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Щодня" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Повторно (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Коли диск приєднано (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Щотижня" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Щомісяця" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Щороку" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "годин" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "днів" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "тижнів" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "місяців" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Вказуйте години через кому (напр. 8,12,18,23) або */3 для резервування кожні" " 3 години." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "Проксі-сервер SSH" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Сервер:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Порт:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Користувач:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "Підключайтеся до цільового сервера через цей проксі (також відомий як " "проміжний сервер або jump host). Докладніше див. розділ «-J» у документації " "до команди «ssh» або розділ «ProxyJump» у посібнику «ssh_config»." #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "Обережно:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" "Це параметри для просунутого налаштування. Змінюйте їх, тільки якщо повністю" " усвідомлюєте їхню дію." #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Запустити «rsync» з «{cmd}»:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "як cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "на віддаленому сервері" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "під час резервування вручну" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "Встановіть «nocache», щоб увімкнути цей параметр." #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "на локальному комп'ютері" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Перенаправити stdout на /dev/null в cronjobs." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" "Якщо встановлено MTA, Cron автоматично надішле електронного листа з " "прикріпленим виводом cronjobs." #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Перенаправити stderr на /dev/null в cronjobs." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" "Якщо встановлено MTA, Cron автоматично надішле електронного листа з " "прикріпленими помилками cronjobs." #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "кбіт/с" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "Обмежити пропускну здатність:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Зберігати ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Зберігати додаткові атрибути (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "Копіювати ненадійні посилання (працює лише з абсолютними посиланнями)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "Обмежити однією файловою системою" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Параметри необхідно брати в лапки, напр. {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Додаткові параметри для rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "Префікс для виконання перед кожною командою на віддаленому сервері." #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Екрануйте змінні за допомогою \\$FOO. Це не стосується rsync. Щоб додати " "префікс для rsync, використовуйте «{example_value}» з {rsync_options_value}." #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "за замовчуванням" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Додати префікс до команд SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Перевіряти, чи сервер онлайн" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Увага: якщо вимкнено, а сервер недоступний, це може призвести до " "непередбачуваних помилок." #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "Перевіряти, чи підтримує сервер усі необхідні команди." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Увага: якщо вимкнено, а сервер не підтримує всіх необхідних команд, це може " "призвести до непередбачуваних помилок." #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(за замовчуванням: {})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "вимкнено" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "увімкнено" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Режим:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Де зберігати резервні копії" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Налаштування SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Шлях:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Шифр:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Приватний ключ:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "" "Оберіть файл приватного ключа (зазвичай має назву «id_ed25519», а в старих " "версіях — «id_rsa»)." #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Створити новий ключ SSH без пароля (недоступно, якщо Ви вже обрали файл " "приватного ключа)." #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Пароль" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Зберегти пароль у зв'язці ключів" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Кешувати пароль для Cron (Увага: root може читати пароль)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Додатково" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Повний шлях до копії:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "Ви не вибрали файл приватного ключа для SSH." #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "Бажаєте згенерувати нову пару публічний/приватний ключ без пароля?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Приватний ключ «{file}» не існує." #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Бажаєте скопіювати свій публічний ключ SSH на сервер, щоб увімкнути " "безпарольний доступ?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "Автентичність сервера {host} не вдалося встановити." #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "Відбиток ключа {keytype}:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Перевірте цей відбиток. Бажаєте додати його до свого файлу «known_hosts»?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "Ви впевнені, що хочете змінити каталог для резервних копій?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Не вдалося створити новий ключ SSH у {path}." #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Увімкнути сповіщення" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Вимкнути резервування при роботі від батареї" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Статус живлення недоступний" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Створювати одну резервну копію за раз" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Інші копії буде заблоковано, доки триває поточне резервування. Це глобальне " "налаштування, отже вплине на всі профілі цього користувача. Але для інших " "користувачів його потрібно вмикати окремо." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Під час відновлення зберігати копії переміщених файлів" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Перед відновленням новіші версії файлів буде перейменовано з додаванням " "{suffix}. Якщо вони Вам не потрібні, можна видалити їх, використавши {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Ігнорувати помилки (зберігати незавершені копії)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Виявляти зміни за контрольними сумами" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Резервувати незалежно від того, чи були зміни." #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "Рівень ведення журналу:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Нічого" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" "Правила обробляються зверху вниз. Пізніші правила мають перевагу над " "попередніми і не обмежуються ними. Подробиці та приклади див. в {manual}." #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "iнструкції користувача" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "Відкрити посібник користувача в браузері." #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "Не видаляти найновішу резервну копію." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" "Остання або найсвіжіша резервна копія зберігається за будь-яких обставин." #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "Цю поведінку неможливо змінити." #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "Не видаляти названі резервні копії." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" "Резервні копії, яким, окрім звичайної позначки часу, було присвоєно ім'я, " "будуть збережені за будь-яких обставин і не видалятимуться." #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "років" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "Видаляти копії старіші за" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "Повні дні. Поточний день не враховується." #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" "Календарні тижні, що починаються з понеділка. Поточний тиждень не " "враховується." #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "Періоди по 12 місяців. Поточний місяць не враховується." #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "Політика збереження" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Виконувати у фоні на сервері." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" "Процедура розумного видалення виконуватиметься безпосередньо на віддаленому " "комп'ютері, а не локально. На віддаленому комп'ютері мають бути встановлені " "і доступні команди «bash», «screen» і «flock»." #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "Якщо вибрано, Back In Time спочатку протестує віддалений комп'ютер." #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "Відлік днів ведеться від сьогоднішнього дня." #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Зберігати всі копії за останні" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "днів." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "Зберігати останню копію за кожен день за останні" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" "Відлік тижнів, починаючи з поточного. Тиждень починається з понеділка." #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "Зберігати останню копію за кожен тиждень за останні" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "тижнів." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "Відлік календарних місяців, починаючи з поточного місяця." #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "Зберігати останню копію за кожен місяць за останні" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "місяців." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "Відлік календарних років, починаючи з поточного року." #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "Зберігати останню копію за кожен рік за" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "всі роки." #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… вільного місця менше ніж" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… вільних айнодів менше ніж" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "Видаляти старі копії, якщо…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Питання" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Профіль: {profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Переглянути останній журнал" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Запуск {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Виконання…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Надіслано:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Швидкість:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "Залишилося:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Резервні копії" #: qt/qttools.py:506 msgid "Today" msgstr "Сьогодні" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Вчора" #: qt/qttools.py:522 msgid "This week" msgstr "Цього тижня" #: qt/qttools.py:529 msgid "Last week" msgstr "Попереднього тижня" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "Це НЕ резервна копія, а Ваші файли на комп'ютері" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Остання перевірка {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "Імпортувати конфігурацію" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Не знайдено конфігурації" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "Імпорт" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" "Виберіть каталог для резервних копій, з якого слід імпортувати файл " "конфігурації. Шлях може мати такий вигляд: {samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" "Якщо це каталог на зовнішньому або віддаленому диску, його потрібно " "попередньо змонтувати вручну." #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Показати повний журнал" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Параметри порівняння резервних копій" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "Команда:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "Параметри:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Використовуйте %1 та %2 як параметри шляху" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "Задайте команду diff або натисніть «Скасувати»." #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" "Не вдається знайти команду «{cmd}» у цій системі. Будь ласка, спробуйте щось" " інше або натисніть «Скасувати»." #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" "Для команди diff не задано жодних параметрів. Використовується значення за " "замовчуванням «{params}»." #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Тільки копії, що відрізняються" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "Показати лише копії, однакові з:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Глибока перевірка (більш точна, але повільніша)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Видалити" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Вибрати все" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "Порівняти" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Перейти до" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Налаштування" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Не можна порівнювати резервну копію саму з собою." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Ви справді хочете видалити {file} з резервної копії {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Ви справді хочете видалити {file} з {count} резервних копій?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "УВАГА: це не можна буде скасувати." #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Виключити {path} з майбутніх резервних копій?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Підкаталоги не можна включити в резервну копію." backintime-1.5.4/common/po/vi.po000066400000000000000000001730041477034762000165320ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the Back In Time package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Back In Time 1.3.4-dev\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-03 09:53+0000\n" "Last-Translator: buhtz \n" "Language-Team: Vietnamese \n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "Cảnh báo" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "Hồ sơ chính" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "Cục bộ (được mã hóa bằng EncFS)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH (được mã hóa EncFS)" #: common/config.py:278 msgid "Local" msgstr "Cục bộ" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "Khóa SSH riêng" #: common/config.py:283 msgid "Local encrypted" msgstr "Mã hóa cục bộ" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "Mã hóa" #: common/config.py:289 msgid "SSH encrypted" msgstr "Đã mã hóa SSH" #: common/config.py:296 msgid "Default" msgstr "Mặc định" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "Hồ sơ: “{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "Thư mục snapshot không hợp lệ." #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "Phải chọn ít nhất một thư mục để sao lưu." #: common/config.py:358 common/config.py:373 #, fuzzy, python-brace-format msgid "Directory: {path}" msgstr "Khôi phục {path}" #: common/config.py:359 common/config.py:374 #, fuzzy msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "Thư mục con sao lưu không thể được thêm vào." #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "Ghi crontab mới thất bại." #: common/config.py:1475 #, fuzzy msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "Cron không hoạt động mặc dù lệnh crontab có sẵn. Các công việc sao lưu đã " "lên lịch sẽ không chạy. Có thể cron đã được cài đặt nhưng chưa được kích " "hoạt. Hãy thử lệnh \"systemctl enable cron\" hoặc tham khảo các kênh hỗ trợ " "của bản phân phối GNU Linux của bạn." #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "" "Không thể cài đặt lệnh Udev cho hồ sơ {profile_id} vì Dịch vụ DBus " "“{dbus_interface}” không khả dụng" #: common/config.py:1571 #, fuzzy, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "Lịch trình theo udev không hoạt động trong chế độ {mode}" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "Không tìm thấy UUID cho {path}" #: common/configfile.py:101 msgid "Failed to save config" msgstr "Lưu cấu hình thất bại" #: common/configfile.py:137 msgid "Failed to load config" msgstr "Nạp cấu hình thất bại" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "Hồ sơ \"{name}\" đã tồn tại." #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "Hồ sơ cuối cùng không thể bị xóa bỏ." #: common/encfstools.py:81 #, fuzzy, python-brace-format msgid "Unable to mount '{command}'" msgstr "Không thể mount '{command}'" #: common/encfstools.py:131 #, fuzzy msgid "Configuration for the encrypted directory not found." msgstr "Không tìm thấy cấu hình cho thư mục đã mã hóa." #: common/encfstools.py:139 #, fuzzy msgid "Create a new encrypted directory?" msgstr "Tạo một thư mục được mã hóa mới?" #: common/encfstools.py:146 msgid "Cancel" msgstr "Hủy" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "Vui lòng xác nhận mật khẩu." #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "Mật khẩu không trùng khớp." #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "Chụp snapshot" #: common/mount.py:622 #, fuzzy, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "Không thể unmount {mountprocess} từ {mountpoint}." #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "" "Không tìm thấy {command}. Xin hãy cài đặt (ví dụ: thông qua " "{installcommand})" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "Vị trí mount {mntpoint} không trống." #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "Nhập mật khẩu cho hồ sơ {mode} \"{profile}\":" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "THẤT BẠI" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "Khôi phục quyền hạn" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "Xong" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "Trì hoãn sao lưu khi đang sử dụng pin" #: common/snapshots.py:842 qt/app.py:363 #, fuzzy msgid "Can't find snapshots directory." msgstr "Không tạo được thư mục" #: common/snapshots.py:846 #, fuzzy msgid "If it is on a removable drive please plug it in." msgstr "" "Không thể tìm thấy thư mục snapshots.\n" "Nếu nó nằm trên ổ cứng có thể tháo rời thì vui lòng cắm vào máy rồi ấn nút OK." #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "Đang chờ %s giây." #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "Chụp snapshot {snapshot_id} thất bại." #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "Không tạo được thư mục." #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "Đang lưu tập tin cấu hình…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "Đang lưu quyền hạn…" #: common/snapshots.py:1290 #, fuzzy, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "Tìm thấy {snapshot_id} đang dang dở và có thể tiếp tục." #: common/snapshots.py:1314 #, fuzzy, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "Đang xóa thư mục {snapshot_id} dang dở từ lần chạy trước" #: common/snapshots.py:1325 #, fuzzy msgid "Can't remove directory" msgstr "Không thể xóa thư mục" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "Đang chụp snapshot" #: common/snapshots.py:1430 msgid "Success" msgstr "Thành công" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "Truyền một phần do lỗi" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "Truyền một phần do file nguồn biến mất (xem 'man rsync')" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "'rsync' kết thúc với mã kết thúc {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "Xem 'man rsync' để biết nhiều chi tiết hơn" #: common/snapshots.py:1458 #, fuzzy msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "Mã kết thúc rsync âm là số chỉ thị, xem 'kill -l' và 'man kill'" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "Không có gì thay đổi, không cần snapshot mới" #: common/snapshots.py:1523 #, fuzzy, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "Không thể đổi tên {new_path} thành {path}" #: common/snapshots.py:1855 #, fuzzy msgid "Smart removal" msgstr "Xóa thông minh" #: common/snapshots.py:1888 #, fuzzy msgid "Apply rules to remove old snapshots" msgstr "Đang xóa các snapshot cũ" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "Đang cố gắng giữ dung lượng trống tối thiểu" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "Đang cố gắng giữ tổi thiểu {perc} inode trống" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "Vừa mới đây" #: common/sshtools.py:232 #, fuzzy, python-brace-format msgid "Unable to mount {sshfs}" msgstr "Không thể mount {sshfs}" #: common/sshtools.py:300 #, fuzzy msgid "ssh-agent not found. Please ensure it is installed." msgstr "Không tìm thấy ssh-agent. Đảm bảo rằng nó đã được cài." #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "" "Không thể mở khóa SSH riêng. Mật khẩu bị sai hay không thể truy cập bởi " "cron." #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "Thuật toán mã hóa {cipher} thất bại cho {host}." #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "Đường dẫn từ xa tồn tại nhưng không phải là một thư mục." #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "Đường dẫn từ xa không thể được viết vào." #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "Đường dẫn từ xa không thể được thực thi." #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "Không tạo được đường dẫn từ xa." #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "Máy từ xa {host} không hỗ trợ {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "Xem 'man backintime' cho các chỉ dẫn sâu hơn" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "Lệnh kiểm tra trên máy khách {host} trả về lỗi không xác định" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "Máy ở xa {host} không hỗ trợ harklink" #: common/sshtools.py:1191 #, fuzzy, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "Sao chép khóa ssh công khai \"{pubkey}\" đến máy chủ từ xa \"{host}\"" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "Vui lòng nhập mật khẩu cho “{user}”." #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "" "Hệ thống tập tin đích cho “{path}” được định dạng bằng chuẩn NTFS, chuẩn này" " không hỗ trợ liên kết cứng. Vui lòng dùng một hệ thống tập tin được Linux " "hỗ trợ." #: common/tools.py:432 #, fuzzy, python-brace-format msgid "{path} is not a valid directory." msgstr "Đường dẫn {path} không phải là một thư mục." #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "" #: common/tools.py:488 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "" "Hệ thống tập tin đích cho “{path}” được định dạng bằng chuẩn FAT, chuẩn này " "không hỗ trợ liên kết cứng. Vui lòng dùng một hệ thống tập tin được Linux hỗ" " trợ." #: common/tools.py:499 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "Hệ thống tập tin đích cho {path} là một phần gắn kết SMB. Vui lòng đảm bảo " "máy chủ SMB từ xa hỗ trợ liên kết tượng trưng hoặc kích hoạt {copyLinks} " "trong {expertOptions}." #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "Sao chép liên kết (truy cập liên kết tượng trưng)" #: common/tools.py:504 msgid "Expert Options" msgstr "Tùy chọn dành cho chuyên gia" #: common/tools.py:508 #, fuzzy, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "" "Hệ thống tập tin đích cho {path} là một phần gắn kết sshfs. Sshfs không hỗ " "trợ liên kết cứng. Vui lòng sử dụng chế độ 'SSH'." #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "Giới thiệu" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "Tác giả" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "Phiên dịch" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "Giấy phép" #: qt/app.py:172 msgid "Shortcuts" msgstr "Lối tắt" #: qt/app.py:192 #, fuzzy msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "Thư mục này không tồn tại\n" "trong bản snapshot đang được chọn." #: qt/app.py:257 msgid "Add to Include" msgstr "Thêm vào Bao gồm" #: qt/app.py:259 msgid "Add to Exclude" msgstr "Thêm vào Loại trừ" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "" "Có vẻ như {app_name} đang chạy lần đầu tiên vì không tìm thấy cấu hình nào." #: qt/app.py:336 #, fuzzy msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "Nhập cấu hình hiện có (từ thư mục sao lưu hoặc từ máy tính khác)?" #: qt/app.py:364 #, fuzzy msgid "If it is on a removable drive please plug it in and then press OK." msgstr "" "Không thể tìm thấy thư mục snapshots.\n" "Nếu nó nằm trên ổ cứng có thể tháo rời thì vui lòng cắm vào máy rồi ấn nút OK." #: qt/app.py:470 msgid "Take a snapshot" msgstr "Chụp snapshot" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "Dùng thời gian thay đổi & kích cỡ để dò sự thay đổi của file." #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "Chụp snapshot với checksum" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "Dùng checksum để phát hiện sự thay đổi của file." #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "Tạm dừng quá trình chụp snapshot" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "Tiếp tục quá trình chụp snapshot" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "Dừng hẳn quá trình chụp snapshot" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "Tải lại danh sách snapshot" #: qt/app.py:497 msgid "Name snapshot" msgstr "Đặt tên snapshot" #: qt/app.py:501 msgid "Remove snapshot" msgstr "Xóa snapshot" #: qt/app.py:505 msgid "View snapshot log" msgstr "Xem nhật ký Snapshot" #: qt/app.py:509 msgid "View last log" msgstr "Xem nhật ký cuối cùng" #: qt/app.py:513 msgid "Manage profiles…" msgstr "Quản lý hồ sơ…" #: qt/app.py:517 msgid "Shutdown" msgstr "Tắt máy" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "Tắt máy sau khi chụp snapshot hoàn tất." #: qt/app.py:521 msgid "Setup language…" msgstr "Cài đặt ngôn ngữ…" #: qt/app.py:525 msgid "Exit" msgstr "Thoát" #: qt/app.py:529 msgid "User manual" msgstr "" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "" #: qt/app.py:540 #, fuzzy msgid "man page: Profiles config file" msgstr "Tập tin cấu hình hồ sơ" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "" #: qt/app.py:547 msgid "Project website" msgstr "" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "Nhật ký thay đổi" #: qt/app.py:555 msgid "FAQ" msgstr "Câu hỏi thường gặp" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "" #: qt/app.py:559 msgid "Ask a question" msgstr "Đặt câu hỏi" #: qt/app.py:563 msgid "Report a bug" msgstr "Báo lỗi" #: qt/app.py:566 msgid "Translation" msgstr "Phiên dịch" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "Hiển thị lại thông báo về việc tham gia dịch thuật." #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "Chuyển đổi mã hóa (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "Hiển thị lại thông báo về việc gỡ bỏ EncFS." #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "Khôi phục" #: qt/app.py:581 #, fuzzy msgid "Restore the selected files or directories to the original destination." msgstr "Khôi phục các tập tin và thư mục được chọn về vị trí ban đầu." #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "Khôi phục đến …" #: qt/app.py:586 #, fuzzy msgid "Restore the selected files or directories to a new destination." msgstr "Khôi phục các tập tin và thư mục được chọn đến vị trí mới." #: qt/app.py:592 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "" "Khôi phục thư mục hiện tại và tất cả nội dung bên trong nó về vị trí ban " "đầu." #: qt/app.py:598 #, fuzzy msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "" "Khôi phục thư mục hiện tại và tất cả nội dung bên trong nó đến vị trí mới." #: qt/app.py:601 msgid "Up" msgstr "Lên" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "Hiện tập tin ẩn" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "Chụp snapshot…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "" #: qt/app.py:640 #, fuzzy msgid "Shows the message about this Release Candidate again." msgstr "Hiển thị lại thông báo về việc gỡ bỏ EncFS." #: qt/app.py:676 msgid "Back In &Time" msgstr "" #: qt/app.py:681 msgid "&Backup" msgstr "&Sao lưu" #: qt/app.py:692 msgid "&Restore" msgstr "&Khôi phục" #: qt/app.py:698 msgid "&Help" msgstr "T&rợ giúp" #: qt/app.py:743 msgid "Icons only" msgstr "" #: qt/app.py:746 msgid "Text only" msgstr "" #: qt/app.py:749 msgid "Text below icons" msgstr "" #: qt/app.py:752 msgid "Text beside icon" msgstr "" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "" "Nếu bạn đóng cửa sổ này, Back In Time sẽ không thể tắt máy của bạn khi quá " "trình chụp snapshot hoàn tất." #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "Bạn có thật sự muốn đóng nó ?" #: qt/app.py:1072 msgid "Working:" msgstr "Đang chạy:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "Xong, không cần sao lưu" #: qt/app.py:1129 msgid "Working" msgstr "Đang chạy" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "Lỗi" #: qt/app.py:1161 msgid "Sent" msgstr "Đã gửi" #: qt/app.py:1162 msgid "Speed" msgstr "Tốc độ" #: qt/app.py:1163 msgid "ETA" msgstr "Còn lại" #: qt/app.py:1225 msgid "Global" msgstr "Toàn cục" #: qt/app.py:1226 msgid "Root" msgstr "Thư mục Root" #: qt/app.py:1227 msgid "Home" msgstr "Thư mục Home" #: qt/app.py:1255 #, fuzzy msgid "Backup directories" msgstr "Các thư mục sao lưu" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "Đổi tên snapshot" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "Bạn có chắc chắn muốn xóa snapshot không?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "Tạo thêm bản sao lưu với {suffix} ở cuối tên\n" "trước khi ghi đè hoặc xóa các phần tử cục bộ." #: qt/app.py:1504 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "" "Những phiên bản mới hơn của các tập tin sẽ được đổi tên với {suffix} ở cuối " "tên trước khi khôi phục. Nếu bạn không cần chúng nữa, bạn có thể xóa chúng " "với {command}:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "Chỉ khôi phục những tập tin không tồn tại hoặc\n" "có phiên bản mới hơn so với trong thư mục đích.\n" "Sử dụng lệnh \"rsync --update\"." #: qt/app.py:1555 #, fuzzy msgid "Remove newer elements in original directory." msgstr "Xóa các tập tin có phiên bản mới hơn trong thư mục gốc." #: qt/app.py:1558 #, fuzzy msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "" "Khôi phục các tập tin hay thư mục được chọn đến thư mục đích và\n" "xóa các tập tin hay thư mục không có trong snapshot.\n" "Hãy cực kỳ cẩn thận bởi vì việc này sẽ \n" "xóa bỏ các tệp tin và thư mục \n" "đã bị loại trừ trong khi chụp snapshot." #: qt/app.py:1570 #, fuzzy msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "" "Bạn có thật sự muốn khôi phục các phần tử này vào thư mục mới\n" " {path}?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "Bạn có thật sự muốn khôi phục các phần tử này?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "" "Bạn có thật sự muốn xóa hết các tập tin có phiên bản mới hơn trong {path}?" #: qt/app.py:1602 #, fuzzy msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "" "Bạn có chắc chắn muốn xóa hết các tập tin có phiên bản mới hơn trong thư mục" " gốc?" #: qt/app.py:1608 #, fuzzy, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "" "CẢNH BÁO: Xóa các tập tin trong thư mục root của hệ thống tập tin có thể làm" " hỏng hệ thống của bạn!" #: qt/app.py:1857 msgid "Snapshot" msgstr "Snapshot" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "Khôi phục {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "Khôi phục {path} đến …" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "Xin chào\n" "Bạn cũng đã sử dụng Back In Time bằng {language} được vài lần rồi.\n" "Bản dịch sang {language} của phiên bản Back In Time mà bạn cài đặt đã {perc} hoàn thành. Dù với bất cứ trình độ hiểu biết công nghệ nào, bạn cũng có thể đóng góp bản dịch và cũng là đóng góp cho chính Back In Time.\n" "Xin hãy ghé thăm {translation_platform_url} nếu bạn muốn đóng góp. Về trợ giúp và giải đáp thắc mặc, xin hãy truy cập {back_in_time_project_website}.\n" "Chúng tôi xin thứ lỗi về sự gián đoạn này, và thông báo này sẽ không xuất hiện nữa. Hộp thoại này lúc nào cũng có thể được tìm thấy trong menu trợ giúp.\n" "Nhóm phát triển Back In Time" #: qt/app.py:2071 msgid "translation platform" msgstr "nền tảng phiên dịch" #: qt/app.py:2076 msgid "Website" msgstr "Trang web" #: qt/app.py:2090 msgid "Your translation" msgstr "Bản dịch của bạn" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "" #: qt/app.py:2118 msgid "Open an issue" msgstr "" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "" "Thiết đặt ngôn ngữ chỉ có tác dụng sau khi khởi động lại Back In Time." #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 #, fuzzy msgid "It is not recommended to use that mode for a profile furthermore." msgstr "" "Hỗ trợ cho EncFS sẽ ngừng trong tương lai gần. Không khuyến khích sử dụng " "chế độ đó cho hồ sơ nữa." #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "sách trắng" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "Các hồ sơ cá nhân sau đây sử dụng mã hóa với EncFS:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "Thiết đặt ngôn ngữ" #: qt/languagedialog.py:97 msgid "System default" msgstr "Mặc định hệ thống" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "Dùng ngôn ngữ của hệ điều hành." #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "Đã dịch: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "Xem nhật ký được lưu lần cuối cùng" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "Xem nhật ký snapshot" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "Hồ sơ:" #: qt/logviewdialog.py:78 #, fuzzy msgid "Snapshots:" msgstr "Snapshot" #: qt/logviewdialog.py:93 #, fuzzy msgid "Filter:" msgstr "Bộ lọc" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "Tất cả" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "Có thay đổi" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "Có lỗi" #: qt/logviewdialog.py:111 qt/messagebox.py:60 #, fuzzy msgid "Information" msgid_plural "Information" msgstr[0] "Thông tin" #: qt/logviewdialog.py:114 #, fuzzy msgid "rsync transfer failures (experimental)" msgstr "Truyền rsync thất bại (thử nghiệm)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] Lỗi, [I] Thông tin, [C] Thay đổi" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "giải mã đường dẫn" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "Quản lý hồ sơ" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "Sửa" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "Thêm" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "Gỡ bỏ" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&Tổng quan" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "&Bao gồm" #: qt/manageprofiles/__init__.py:125 #, fuzzy msgid "Include files and directories" msgstr "Bao gồm các tập tin và thư mục" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "Thêm tập tin" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 #, fuzzy msgid "Add directory" msgstr "Thêm thư mục" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&Ngoại trừ" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" #: qt/manageprofiles/__init__.py:183 #, fuzzy msgid "Exclude patterns, files or directories" msgstr "Loại trừ các pattern, tập tin hoặc thư mục" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "Thêm mặc định" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "Loại trừ các tập tin có kích thước lớn hơn :" #: qt/manageprofiles/__init__.py:233 #, fuzzy, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "Loại trừ các tập tin có kích thước lớn hơn : " #: qt/manageprofiles/__init__.py:235 #, fuzzy msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "Loại trừ các tập tin có kích thước lớn hơn giá trị trong %(prefix)s.\n" "Khi 'chế độ rsync đầy đủ' đã tắt, cài đặt này chỉ có hiệu lực với các tập tin mới\n" "bởi vì đối với rsync đây là cài đặt chuyển đổi, không phải cài đặt loại trừ.\n" "Nên những tập tin lớn đã được sao lưu trước đó sẽ được giữ nguyên trong snapshot\n" "ngay cả khi chúng có thay đổi." #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "Tùy &chọn" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "Tùy chọn chuyên &gia" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "Khôi phục cấu hình" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "Sửa user-callback" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "Hồ sơ mới" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "Đổi tên hồ sơ" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "Bạn có chắc chắn muốn xóa hồ sơ \"{name}\" ?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "" #: qt/manageprofiles/__init__.py:384 #, fuzzy, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "Rất khuyến khích" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "Loại trừ pattern" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "Loại trừ tập tin" #: qt/manageprofiles/__init__.py:625 #, fuzzy msgid "Exclude directory" msgstr "Loại trừ thư mục" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "Bao gồm tập tin" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "\"{path}\" là một liên kết tượng trưng. Tập tin gốc sẽ không được sao lưu cho đến khi bạn bao gồm nó vào nữa.\n" "Bạn có muốn bao gồm tập tin gốc thay vào đó?" #: qt/manageprofiles/__init__.py:679 #, fuzzy msgid "Include directory" msgstr "Bao gồm thư mục" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "Lịch trình" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "ngày thường:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "giờ:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "" #: qt/manageprofiles/schedulewidget.py:92 #, fuzzy msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "" "Chạy Back In Time ngay khi ổ cứng được kết nối (chỉ một lần mỗi X ngày).\n" "Bạn sẽ bị yêu cầu nhập mật khẩu sudo." #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "" "Chạy Back In Time theo định kỳ. Lựa chọn này hữu ích khi máy tính không được" " mở thường xuyên." #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "Mỗi:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "Đang tắt" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "Mỗi lần khởi động máy" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "Mỗi {n} phút" #: qt/manageprofiles/schedulewidget.py:150 #, fuzzy, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "Mỗi giờ" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "Mỗi {n} giờ" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "Theo giờ tùy chỉnh" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "Hàng ngày" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "Theo định kỳ (anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "Khi ổ cứng kết nối thành công (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "Hàng tuần" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "Hàng tháng" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "Hàng năm" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "Giờ" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "Ngày" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "Tuần" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "Tháng" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "" "Giờ tùy chỉnh phải là các số giờ được ngăn cách bởi dấu phẩy (vd: " "8,12,18,23) hoặc theo định dạng */3 để sao lưu sau mỗi 3 tiếng." #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "Máy chủ:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "Cổng:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "Người dùng:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" #: qt/manageprofiles/tab_expert_options.py:39 #, fuzzy msgid "Caution:" msgstr "Thắc mắc" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "Chạy 'rsync' với '{cmd}':" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "bằng cron job" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "trên máy chủ từ xa" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "khi đang chụp snapshot thủ công" #: qt/manageprofiles/tab_expert_options.py:103 #, fuzzy msgid "Please install 'nocache' to enable this option." msgstr "(Vui lòng cài 'nocache' để bật tùy chọn này)" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "trên máy cục bộ" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "Chuyển hướng stdout vào /dev/null trong cronjob." #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "Chuyển hướng stderr vào /dev/null trong cronjob." #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/giây" #: qt/manageprofiles/tab_expert_options.py:156 #, fuzzy msgid "Limit rsync bandwidth usage:" msgstr "Giới hạn sử dụng băng thông rsync" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "Giữ nguyên ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "Giữ nguyên thuộc tính mở rộng (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "" "Sao chép liên kết không an toàn (chỉ có tác dụng với liên kết tuyệt đối)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "Tùy chọn phải nằm trong ngoặc kép. Ví dụ: {example}." #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "Dán các tùy chọn phụ vào rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "" #: qt/manageprofiles/tab_expert_options.py:310 #, fuzzy, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "Tiền tố để chạy trước mỗi lệnh trên máy chủ từ xa.\n" "Các biến cần phải được kết thúc bằng \\$FOO.\n" "Tùy chọn này không đụng đến rsync. Nên để thêm một tiền tố\n" "cho rsync hãy sử dụng \"%(cbRsyncOptions)s\" với\n" "%(rsync_options_value)s\n" "\n" "%(default)s: %(def_value)s" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "mặc định" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "Thêm tiền tố vào các lệnh SSH" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "Kiểm tra liệu máy chủ từ xa có online" #: qt/manageprofiles/tab_expert_options.py:337 #, fuzzy msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "" "Cảnh báo: Nếu tắt tùy chọn này và máy chủ từ xa\n" "hiện không khả dụng, tình trạng này có thể\n" "dẫn đến một vài lỗi kỳ lạ." #: qt/manageprofiles/tab_expert_options.py:341 #, fuzzy msgid "Check if remote host supports all necessary commands." msgstr "Kiểm tra liệu máy chủ từ xa có hỗ trợ tất cả các lệnh cần thiết" #: qt/manageprofiles/tab_expert_options.py:344 #, fuzzy msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "" "Cảnh báo: nếu tắt tùy chọn này và máy chủ từ xa\n" "không hỗ trợ tất cả các lệnh cần thiết,\n" "tình trạng này có thể dẫn đến một vài lỗi kỳ lạ." #: qt/manageprofiles/tab_expert_options.py:359 #, fuzzy msgid "(default: {})" msgstr "mặc định" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "đang tắt" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "đang bật" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "Chế độ:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "Nơi lưu các snapshot" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "Cài đặt SSH" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "Đường dẫn:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "Thuật toán mã hóa:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "Khóa riêng:" #: qt/manageprofiles/tab_general.py:152 #, fuzzy msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "Chọn một tập tin khóa riêng đã tồn tại (thường được đặt tên \"id_rsa\")" #: qt/manageprofiles/tab_general.py:164 #, fuzzy msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "" "Tạo một khóa SSH mới mà không cần mật khẩu (không được phép nếu một tập tin " "khóa riêng đã được chọn)" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "Mật khẩu" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "Lưu mật khẩu vào Keyring" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "" "Lưu mật khẩu cho Cron vào cache (Vấn đề bảo mật: tài khoản root có thể đọc " "mật khẩu)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "Nâng cao" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "Đường dẫn đầy đủ của snapshot:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "" #: qt/manageprofiles/tab_general.py:395 #, fuzzy msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "" "Bạn chưa chọn một tập tin khóa riêng cho SSH.\n" "Bạn có muốn tạo một cặp khóa riêng và khóa công khai không có mật khẩu?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "Tập tin khóa riêng \"{file}\" không tồn tại." #: qt/manageprofiles/tab_general.py:491 #, fuzzy msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "" "Bạn có muốn sao chép khóa SSH công khai của bạn đến\n" "máy chủ từ xa để bật đăng nhập không cần mật khẩu?" #: qt/manageprofiles/tab_general.py:525 #, fuzzy, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "" "Không thể xác thực máy chủ {host}.\n" "\n" "Vân tay khóa {keytype} là:" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "" #: qt/manageprofiles/tab_general.py:536 #, fuzzy msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "" "Vui lòng xác nhận vân tay này! Bạn có muốn thêm nó vào tập tin 'known_hosts'" " của bạn?" #: qt/manageprofiles/tab_general.py:627 #, fuzzy msgid "Are you sure you want to change snapshots directory?" msgstr "Bạn có chắc chắn muốn thay đổi thư mục snapshot không?" #: qt/manageprofiles/tab_general.py:664 #, fuzzy, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "Tạo khoá SSH trong đường dẫn {path} thất bại" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "Bật thông báo" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "Tắt chụp snapshot khi đang dùng pin" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "Trạng thái nguồn điện không khả dụng từ hệ thống" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "Chỉ chạy từng snapshot một" #: qt/manageprofiles/tab_options.py:53 #, fuzzy msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "" "Các bản snapshot khác sẽ bị chặn cho đến khi bản snapshot hiện tại chạy xong.\n" "Đây là cài đặt toàn cục. Nên nó sẽ có hiệu lực với tất cả hồ sơ của người dùng này.\n" "Nhưng bạn sẽ cần kích hoạt tùy chọn này cho tất cả người dùng khác nữa." #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "Sao lưu những tập tin bị thay thế trong quá trình khôi phục" #: qt/manageprofiles/tab_options.py:64 #, fuzzy, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "" "Những phiên bản mới hơn của các tập tin sẽ được đổi tên với {suffix} ở cuối tên trước khi khôi phục.\n" "Nếu bạn không cần chúng nữa, bạn có thể xóa chúng với {cmd}" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "Tiếp tục khi gặp lỗi (giữ các bản snapshot không hoàn thiện)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "Dùng checksum để phát hiện có thay đổi" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "Chụp snapshot mới dù có thay đổi hay không." #: qt/manageprofiles/tab_options.py:90 #, fuzzy msgid "Log Level:" msgstr "Ghi lại mức độ" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "Không có gì" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:222 #, fuzzy msgid "Keep the most recent snapshot." msgstr "Đừng xóa các bản snapshot đã được đổi tên." #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:240 #, fuzzy msgid "Keep named snapshots." msgstr "Đừng xóa các bản snapshot đã được đổi tên." #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "Năm" #: qt/manageprofiles/tab_remove_retention.py:263 #, fuzzy msgid "Remove snapshots older than" msgstr "Xóa snapshot" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "Chạy ngầm trên máy từ xa." #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "Giữ tất cả snapshot trong" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "ngày vừa qua." #: qt/manageprofiles/tab_remove_retention.py:318 #, fuzzy msgid "Keep the last snapshot for each day for the last" msgstr "Giữ một bản snapshot từ mỗi ngày trong" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:331 #, fuzzy msgid "Keep the last snapshot for each week for the last" msgstr "Giữ một bản snapshot từ mỗi tuần trong" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "tuần vừa qua." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:344 #, fuzzy msgid "Keep the last snapshot for each month for the last" msgstr "Giữ một bản snapshot từ mỗi tháng trong" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "tháng vừa qua." #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:356 #, fuzzy msgid "Keep the last snapshot for each year for" msgstr "Giữ tất cả snapshot trong" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "" #: qt/manageprofiles/tab_remove_retention.py:380 #, fuzzy msgid "… the free space is less than" msgstr "Nếu dung lượng trống còn ít hơn" #: qt/manageprofiles/tab_remove_retention.py:385 #, fuzzy msgid "… the free inodes are less than" msgstr "Nếu số inode trống còn ít hơn" #: qt/manageprofiles/tab_remove_retention.py:394 #, fuzzy msgid "Remove oldest snapshots if …" msgstr "Đang xóa các snapshot cũ" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "Thắc mắc" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "Hồ sơ: “{profile_name}”" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "Xem nhật ký cuối cùng được lưu" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "Bắt đầu {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "Đang chạy…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "Đã gửi:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "Tốc độ:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "Snapshot" #: qt/qttools.py:506 msgid "Today" msgstr "Hôm nay" #: qt/qttools.py:513 msgid "Yesterday" msgstr "Hôm qua" #: qt/qttools.py:522 msgid "This week" msgstr "Tuần này" #: qt/qttools.py:529 msgid "Last week" msgstr "Tuần trước" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "" "Đây không phải là một snapshot mà là hình ảnh trực tiếp của các tập tin cục " "bộ của bạn" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "Kiểm tra lần cuối: {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "Không tìm thấy cấu hình" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "Hiện toàn bộ Nhật ký" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "Thiết đặt so sánh các snapshot" #: qt/snapshotsdialog.py:50 #, fuzzy msgid "Command:" msgstr "Lệnh" #: qt/snapshotsdialog.py:54 #, fuzzy msgid "Parameters:" msgstr "Tham số" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "Hãy dùng “%1” và “%2” cho tham số đường dẫn" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "Chỉ những snapshot khác nhau" #: qt/snapshotsdialog.py:134 #, fuzzy msgid "List only snapshots that are equal to:" msgstr "Chỉ những snapshot giống với: " #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "Kiểm tra toàn diện (chính xác hơn nhưng chậm hơn)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "Xóa" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "Chọn tất cả" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "So sánh" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "Đi tới" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "Tùy chọn" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "Không thể so sánh một snapshot với chính nó." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "Bạn có thật sự muốn xóa {file} trong snapshot {snapshot_id}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "Bạn có thật sự muốn xóa {file} trong snapshot {count}?" #: qt/snapshotsdialog.py:406 #, fuzzy msgid "WARNING: This cannot be revoked." msgstr "Lệnh này không thể thu hồi!" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "Loại trừ {path} ra khỏi các snapshot trong tương lai?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "Thư mục sao lưu không thể chứa thư mục con." backintime-1.5.4/common/po/zh_CN.po000066400000000000000000001663441477034762000171260ustar00rootroot00000000000000# Simplified Chinese translation for backintime # Copyright (c) 2009 Rosetta Contributors and Canonical Ltd 2009 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2009. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-07 05:28+0000\n" "Last-Translator: Outbreak2096 \n" "Language-Team: Chinese (Simplified Han script) \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "警告" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "主要配置" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "本地(EncFS 加密)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH(EncFS 加密)" #: common/config.py:278 msgid "Local" msgstr "本地" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH 私钥" #: common/config.py:283 msgid "Local encrypted" msgstr "本地加密" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "加密" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH 加密" #: common/config.py:296 msgid "Default" msgstr "默认" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "配置:“{name}”" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "快照目录无效。" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "必须至少选择一个目录进行备份。" #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "目录:{path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "此目录不能包含在备份中,因为它是备份目标本身的一部分。" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "新增定时任务失败。" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "crontab 命令可用但 cron 未在运行,因此无法执行定时备份。cron 可能已安装但未启用,请尝试命令“systemctl enable " "cron”或向您 GNU/Linux 发行版的支持频道求助。" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "无法为配置 {profile_id} 安装 Udev 规则。DBus 服务“{dbus_interface}”不可用" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "计划的 Udev 不适用于 {mode} 模式" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "找不到 {path} 的 UUID" #: common/configfile.py:101 msgid "Failed to save config" msgstr "保存配置失败" #: common/configfile.py:137 msgid "Failed to load config" msgstr "加载配置失败" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "配置“{name}”已存在。" #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "无法移除最后一个配置。" #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "无法挂载“{command}”" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "未找到加密目录的配置。" #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "创建新的加密目录?" #: common/encfstools.py:146 msgid "Cancel" msgstr "取消" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "请确认密码。" #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "密码不匹配。" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "创建快照" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "无法从 {mountpoint} 卸载 {mountprocess}。" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "未找到 {command},请安装它(例如通过“{installcommand}”)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "挂载点 {mntpoint} 不为空。" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "输入{mode}配置“{profile}”的密码:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "失败" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "恢复权限" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "已完成" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "依靠电池供电时,延后备份" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "找不到快照目录。" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "如果它位于可移动驱动器上,请将其插入。" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "等待 %s 秒。" #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "创建快照 {snapshot_id} 失败。" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "请耐心等待。正在最后确定…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "无法创建目录。" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "保存配置文件…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "保存权限…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "找到了可以继续的剩余快照 {snapshot_id}。" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "移除上次运行留下的 {snapshot_id} 目录" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "无法移除目录" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "创建快照" #: common/snapshots.py:1430 msgid "Success" msgstr "成功" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "由于错误仅部分转移" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "由于源文件消失导致仅部分传输(请参阅“man rsync”)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "“rsync”以退出代码 {exit_code} 结束" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "要了解详情,请查看“man rsync”" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "负的 rsync 退出代码是信号编号,请参阅“kill -l”和“man Kill”" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "没有任何更改,无需新快照" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "无法将 {new_path} 重命名为 {path}。" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "智能移除" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "应用规则以移除旧快照" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "应用保留策略" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "尝试保留最小可用空间" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "尝试保留至少 {perc} 个可用的 inodes" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "现在" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "无法挂载 {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "未找到 ssh-agent。请确保已安装。" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "无法解锁 SSH 私钥,可能密码不正确或该密码不适用于 cron。" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{host} 的密码 {cipher} 失败。" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "远程路径存在但不是目录。" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "远程路径不可写。" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "远程路径不可执行。" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "无法创建远程路径。" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "远程主机 {host} 不支持 {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "请参阅“man backintime”以获取更多说明" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "检查主机 {host} 上返回未知错误的命令" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "远程主机 {host} 不支持硬链接" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "将 SSH 公钥“{pubkey}”复制到远程主机“{host}”。" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "请输入“{user}”的密码。" #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "{path} 的目标文件系统采用 NTFS 格式,已知 NTFS 与 Unix 风格的文件系统不兼容。" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} 不是有效目录。" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "创建以下目录失败:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "写入权限可能受到限制。" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "{path} 的目标文件系统格式为 FAT,不支持硬连接。请使用原生 GNU/Linux 文件系统。" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "{path} 的目标文件系统是通过 SMB 挂载的共享文件系统。请确保远程 SMB " "服务器支持符号链接,或在“{expertOptions}”中激活“{copyLinks}”。" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "复制链接(取消引用符号链接)" #: common/tools.py:504 msgid "Expert Options" msgstr "专家选项" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "{path} 的目标文件系统是通过 sshfs 挂载的共享文件系统。Sshfs 不支持硬链接。请改用“SSH”模式。" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "在此目录中创建文件失败:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "关于" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "作者" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "翻译" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "许可" #: qt/app.py:172 msgid "Shortcuts" msgstr "快捷方式" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "当前所选快照\n" "不存在此目录。" #: qt/app.py:257 msgid "Add to Include" msgstr "添加到包括" #: qt/app.py:259 msgid "Add to Exclude" msgstr "添加到排除" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "{app_name} 似乎是首次运行,未找到配置。" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "是否导入现有配置(从备份目标目录或另一台计算机)?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "如果它位于可移动驱动器上,请将其插入,然后按“确定”。" #: qt/app.py:470 msgid "Take a snapshot" msgstr "创建快照" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "使用修改时间和大小进行文件更改检测。" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "创建快照(校验和模式)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "使用校验和检测文件更改。" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "暂停快照进程" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "恢复快照过程" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "停止快照进程" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "刷新快照列表" #: qt/app.py:497 msgid "Name snapshot" msgstr "命名快照" #: qt/app.py:501 msgid "Remove snapshot" msgstr "移除快照" #: qt/app.py:505 msgid "View snapshot log" msgstr "查看快照日志" #: qt/app.py:509 msgid "View last log" msgstr "查看最近的日志" #: qt/app.py:513 msgid "Manage profiles…" msgstr "管理配置…" #: qt/app.py:517 msgid "Shutdown" msgstr "关机" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "快照完成后关闭系统。" #: qt/app.py:521 msgid "Setup language…" msgstr "设置语言…" #: qt/app.py:525 msgid "Exit" msgstr "退出" #: qt/app.py:529 msgid "User manual" msgstr "用户手册" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "在浏览器中打开用户手册(如果可用,本地打开,否则在线打开)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "手册页:Back In Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "显示关于 Back In Time 的手册页(backintime)" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "手册页:配置的配置文件" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "显示配置的配置文件手册页(backintime-config)" #: qt/app.py:547 msgid "Project website" msgstr "项目网站" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "在浏览器中打开 Back In Time 网站" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "更新日志" #: qt/app.py:555 msgid "FAQ" msgstr "常见问题" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "在浏览器中打开常见问题(FAQ)" #: qt/app.py:559 msgid "Ask a question" msgstr "提出问题" #: qt/app.py:563 msgid "Report a bug" msgstr "报告错误" #: qt/app.py:566 msgid "Translation" msgstr "翻译" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "再次显示翻译参与者的相关信息。" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "加密改动(EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "再次显示关于移除 EncFS 加密的消息。" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "恢复" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "将所选文件或目录恢复到原目标。" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "恢复至…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "将所选文件或目录恢复到新目标。" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "将当前显示的目录及其全部内容恢复到原目标。" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "将当前显示的目录及其全部内容恢复到新目标。" #: qt/app.py:601 msgid "Up" msgstr "上移" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "显示隐藏文件" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "比较快照…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "候选版本" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "再次显示有关此候选版本的消息。" #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "备份(&B)" #: qt/app.py:692 msgid "&Restore" msgstr "恢复(&R)" #: qt/app.py:698 msgid "&Help" msgstr "帮助(&H)" #: qt/app.py:743 msgid "Icons only" msgstr "仅图标" #: qt/app.py:746 msgid "Text only" msgstr "仅文本" #: qt/app.py:749 msgid "Text below icons" msgstr "图标下方的文本" #: qt/app.py:752 msgid "Text beside icon" msgstr "图标旁边的文本" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "如果关闭此窗口,则快照完成后 Back In Time 无法关闭你的系统。" #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "确定要关闭它?" #: qt/app.py:1072 msgid "Working:" msgstr "运行中:" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "已完成,无需备份" #: qt/app.py:1129 msgid "Working" msgstr "运行中" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "错误" #: qt/app.py:1161 msgid "Sent" msgstr "已发送" #: qt/app.py:1162 msgid "Speed" msgstr "速度" #: qt/app.py:1163 msgid "ETA" msgstr "预计完成时间" #: qt/app.py:1225 msgid "Global" msgstr "全局" #: qt/app.py:1226 msgid "Root" msgstr "根目录" #: qt/app.py:1227 msgid "Home" msgstr "主目录" #: qt/app.py:1255 msgid "Backup directories" msgstr "备份目录" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "快照名" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "是否确定要移除快照?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "在覆盖或移除本地文件前创建带有后缀 {suffix}\n" "的备份副本。" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "在恢复之前,较新版本的文件将使用后缀 {suffix} 进行重命名。如果您不再需要它们,以下的指令删除他们:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "只恢复不存在或\n" "比目标更新的元素。\n" "使用“rsync --update”选项。" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "移除原目录中的较新元素。" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "将所选文件或目录恢复到原目标,并删除不在快照中的文件或目录。请务必小心,因为这将删除创建快照时排除的文件和目录。" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "是否确定要将这些元素恢复到新目录?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "是否确定要恢复这些元素?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "是否确定要移除 {path} 中的全部新文件?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "是否确定要移除原目录中的全部新文件?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "{BOLD}警告{BOLDEND}:删除文件系统根目录中的文件可能会破坏整个系统。" #: qt/app.py:1857 msgid "Snapshot" msgstr "快照" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "恢复 {path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "恢复 {path} 至…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "您好\n" "您已经以{language}语言使用了数次 Back In Time 程序。\n" "您所安装的 Back In Time 程序的当前版本对{language}的翻译完成了 {perc}。无论您技术水平如何,您都可以通过帮助翻译的方式为 Back In Time 程序做贡献。\n" "如您想要做出贡献,请访问 {translation_platform_url} 页面。如需更多帮助,请访问 {back_in_time_project_website}。\n" "我们为这次的突然提示感到抱歉,且该信息将不会再次显示。您可以随时通过帮助菜单重新打开本对话框。\n" "Back In Time 团队" #: qt/app.py:2071 msgid "translation platform" msgstr "翻译平台" #: qt/app.py:2076 msgid "Website" msgstr "网站" #: qt/app.py:2090 msgid "Your translation" msgstr "您的翻译" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "在联邦宇宙 Mastodon:{link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "发送电子邮件至 {link_and_label}。" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "邮件列表 {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "{link_and_label} 在项目网站上。" #: qt/app.py:2118 msgid "Open an issue" msgstr "打开问题" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "或者,您可以使用您选择的另一种途径。" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "此版本的 Back In Time 是一个候选版本,主要用于稳定性测试,为下一个正式版本做准备。\n" "不收集用户数据或遥测数据。然而,Back In Time 团队非常想知道是否正在使用候选版本,以及是否值得继续提供此类预发布版本。\n" "因此,即使您没有遇到任何问题,团队友好地向您提供了有关您是否已经测试此版本的简短反馈。即使是几分钟的快速试运行也会对我们有很大帮助。\n" "可以使用以下联系选项:\n" "{contact_list}\n" "在此版本中,不会再次显示此消息,但可通过帮助菜单随时访问。\n" "感谢您的支持和帮助我们改进 Back In Time!\n" "您的 Back In Time 团队" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "语言设置仅在重新启动 Back In Time 后生效。" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "将在 2026 年计划的下一个次版本(1.7)中移除 EncFS 配置创建。" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "不推荐将该模式用于配置。" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "白皮书" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "由于安全漏洞,将停止对 EncFS 的支持。" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "如需了解详情,包括潜在的替代方案,请参阅此{whitepaper}。" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "以下配置将使用 EncFS 进行加密:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "计划取代,但无法保证会按时提供。" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "欢迎用户加入讨论。有关下一步的更新详情,请参阅此{whitepaper}。" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "该消息仅会显示这一次。您可以在帮助菜单随时回顾这个对话框。" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "Back In Time团队" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "设置语言" #: qt/languagedialog.py:97 msgid "System default" msgstr "系统默认" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "使用操作系统语言。" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "翻译:{percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "最近日志查看" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "快照日志查看" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "配置:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "快照:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "过滤器:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "全部" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "更改" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "错误" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "提示信息" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync 传输失败(实验性" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] 错误,[I] 通知,[C] 变更" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "解码路径" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "管理配置" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "编辑" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "新增" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "移除" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "常规(&G)" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "包括(&I)" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "包括文件和目录" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "添加文件" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "添加目录" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "排除(&E)" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}信息{ENDBOLD}:在“SSH 加密”模式下,只有单星号或双星号有效(例如 {example2})。其他类型的通配符和模式将被忽略(例如" " {example1})。由于 EncFS 加密,此模式下文件名不可预测。" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "排除模式、文件或目录" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "添加默认值" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "排除大于以下的文件:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "排除大于以下的文件{size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "排除大于 %(prefix)s 的文件。禁用“完全 rsync 模式”后,这只会影响新文件,因为对于 rsync " "这是一个传输选项,而不是排除选项。因此之前备份过的大文件将保留在快照中,即使他们已经改变。" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "移除和保留(&R)" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "选项(&O)" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "专家选项(&X)" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "恢复配置" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "编辑用户回调" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "新建配置" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "重命名配置" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "是否确定要删除配置“{name}”?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}强烈推荐{ENDBOLD}:(全部推荐均已包括在内。)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}强烈推荐{ENDBOLD}:{files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "排除模式" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "排除文件" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "排除目录" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "包括文件" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "“{path}”是符号链接,链接的目标也要包括在内才会备份。\n" "是否改为包括符号链接目标?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "包括目录" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "已禁用,因为此模式在“SSH 加密”模式下不起作用。" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "计划任务" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "天:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "工作日:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "时间:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "小时:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "小时之后" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "分钟:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "驱动器连接后立即运行 Back In Time(每 X 天仅一次)。系统将提示您输入 sudo 密码。" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "重复运行 Back In Time。如果计算机没有正常运行,这很有用。" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "每:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "启用调试消息记录" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "通过“--debug”将调试级别的消息写入系统日志。" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "警告:仅暂时将其用于诊断,因为它会生成大量输出。" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "已禁用" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "每次启动/重启时" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "每{n}分钟" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "每{n}小时" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "每{n}小时" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "自定义小时" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "每天" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "重复(anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "当驱动器连接时(udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "每周" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "每月" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "每年" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "小时" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "天" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "周" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "月" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "自定义时间只能是逗号分隔的时间列表(例如 8,12,18,23)或 */3(每 3 小时定期备份一次)。" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH 代理" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "主机:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "端口:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "用户:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "通过此代理(又称跳转主机)连接到目标主机。详情请参阅“ssh”命令文档中的“-J”或“ssh_config”手册页中的“ProxyJump”。" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "注意:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "这些选项适用于高级配置。只有完全意识到其影响的情况下才修改。" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "使用“{cmd}”运行“rsync”:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "作为 cron 作业" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "在远程主机上" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "当手动创建快照时" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "请安装“nocache”以启用此选项。" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "在本地机器上" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "在定时任务中将标准输出重定向到 /dev/null。" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "如果安装了 MTA,Cron 将自动发送一封附有 cronjobs 输出的电子邮件。" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "在定时任务中将标准错误重定向到 /dev/null。" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "如果安装了 MTA,Cron 将自动发送一封附有 cronjobs 错误的电子邮件。" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/秒" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "限制 rsync 使用带宽:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "保留 ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "保留扩展属性(xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "复制不安全链接(仅适用于绝对链接)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "限制为一个文件系统" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "选项必须使用引号,例如:{example}。" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "粘贴附加选项到 rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "在远程主机上每个命令之前运行的前缀。" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "变量需要使用 \\$FOO 进行转义。因为这不涉及 rsync,所以要为 rsync " "添加前缀请使用{example_value}和{rsync_options_value}。" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "默认" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "为 SSH 命令添加前缀" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "检查远程主机是否在线" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "警告:如果禁用且远程主机不可用,这可能会导致一些奇怪的错误。" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "检查远程主机是否支持所有必要的命令。" #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "警告:如果禁用且远程主机不支持所有必要的命令,这可能会导致一些奇怪的错误。" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(默认:{})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "已禁用" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "已启用" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "模式:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "何处保存快照" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH 设置" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "路径:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "密码:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "私钥:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "选择一个现有的私钥文件(通常名为“id_ed25519”,在旧设置中为“id_rsa”)。" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "创建一个新的没有密码的 SSH 密钥(如果已经选择了私钥文件则不允许)。" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "密码" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "保存密码至密钥环" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Cron 的缓存密码(安全问题:root 可以读取密码)" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "高级" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "快照完整路径:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "您没有选择 SSH 的私钥文件。" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "是否生成新的无密码公钥/私钥对?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "私钥文件“{file}”不存在。" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "是否将您的 SSH 公钥复制到远程主机以启用无密码登录?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "无法确定主机 {host} 的真实性。" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} 密钥指纹为:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "请验证此指纹。是否将其添加到您的“known_hosts”文件中?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "是否确定要更改快照目录?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "在 {path} 创建 SSH 密钥失败。" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "启用通知" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "使用电池时禁用快照" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "无法从系统中获取电源状态" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "一次仅运行一个快照" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "在当前快照完成前会阻塞其他快照。这是一个全局选项,因此会影响当前用户的所有配置。而你需要为其他所有用户也开启此选项的。" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "恢复时备份替换的文件" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "在恢复之前,较新版本的文件将使用后缀 {suffix} 进行重命名。如果您不再需要它们,可以使用 {cmd} 删除它们" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "出错时继续(保留不完整的快照)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "使用校验和检测更改" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "无论是否有更改,都要创建新快照。" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "日志级别:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "空" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "从上到下处理以下规则。后面的规则会覆盖前面的规则,并且不受它们的约束。有关详情和示例,请参阅{manual}。" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "用户手册" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "在浏览器中打开用户手册。" #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "保留最近快照。" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "在任何情况下都会保留最后或最新快照。" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "这种行为无法更改。" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "保留已命名的快照。" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "除了通常的时间戳外,已命名的快照在任何情况下都将保留,不会被移除。" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "年" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "移除多久前的快照" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "整天数,当日忽略不计。" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "星期一作为第一天的日历周,当前周忽略不计。" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 个月的周期,当前月份忽略不计。" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "保留策略" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "在远程主机后台运行。" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "智能移除过程将直接在远程计算机上运行,而不是在本地运行。命令“bash”、“screen”和“flock”必须在远程计算机上安装并使用。" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "如果选择,Back In Time 将首先测试远程计算机。" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "从今天开始计算天数。" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "保留全部快照" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "天。" #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "保留每天的最后快照" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "周数从当前周开始计算,一周从星期一开始。" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "保留每周的最后快照" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "周。" #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "月份从当前月份开始,按日历月份计算。" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "保留每月的最后快照" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "月。" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "年份从当前年份开始,按日历年份计算。" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "保留每年的最后快照" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "所有年份。" #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "… 可用空间小于" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "… 可用索引节点少于" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "移除最旧快照,如果 …" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "问题" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "配置:{profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "查看最近的日志" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "启动 {appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "运行中…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "已发送:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "速度:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "预计完成时间:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "快照" #: qt/qttools.py:506 msgid "Today" msgstr "今天" #: qt/qttools.py:513 msgid "Yesterday" msgstr "昨天" #: qt/qttools.py:522 msgid "This week" msgstr "本周" #: qt/qttools.py:529 msgid "Last week" msgstr "上周" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "这不是快照,而是本地文件的实时视图" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "最近检查 {time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "导入配置" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "没有找到配置" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "导入" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "选择要从中导入配置文件的快照目录。路径可能类似于:{samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "如果该目录位于外部或远程驱动器上,则必须事先手动挂载。" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "显示完整日志" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "有关比较快照的选项" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "命令:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "参数:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "用 %1 和 %2 作为路径参数" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "请设置 diff 命令或按取消。" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "此系统上找不到命令“{cmd}”。请尝试其他命令或按“取消”。" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "diff 命令未设置参数。使用默认值“{params}”。" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "仅区分快照" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "仅列出与以下内容相同的快照:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "深度检查(更准确,但较慢)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "删除" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "全选" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "比较" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "转到" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "选项" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "不能将快照与其自身比较。" #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "是否确定要在快照 {snapshot_id} 中删除 {file}?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "是否确定要在 {count} 个快照中删除 {file}?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "警告:此操作无法撤销。" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "是否从未来的快照中排除 {path}?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "子目录不能包括在备份中。" backintime-1.5.4/common/po/zh_TW.po000066400000000000000000001667241477034762000171620ustar00rootroot00000000000000# Chinese (Traditional) translation for backintime # Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 # This file is distributed under the same license as the backintime package. # FIRST AUTHOR , 2010. # msgid "" msgstr "" "Project-Id-Version: backintime\n" "Report-Msgid-Bugs-To: https://github.com/bit-team/backintime\n" "POT-Creation-Date: 2025-03-23 19:11+0100\n" "PO-Revision-Date: 2025-03-10 07:50+0000\n" "Last-Translator: ktzhao \n" "Language-Team: Chinese (Traditional Han script) \n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 5.10.2\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" #: common/config.py:37 common/tools.py:80 qt/encfsmsgbox.py:24 #: qt/messagebox.py:77 msgid "Warning" msgstr "警告" #: common/config.py:149 common/config.py:259 msgid "Main profile" msgstr "主要設定檔" #: common/config.py:266 msgid "Local (EncFS encrypted)" msgstr "本地(EncFS 加密)" #: common/config.py:267 msgid "SSH (EncFS encrypted)" msgstr "SSH(EncFS 加密)" #: common/config.py:278 msgid "Local" msgstr "本地端" #: common/config.py:280 msgid "SSH" msgstr "SSH" #: common/config.py:280 common/config.py:290 #: qt/manageprofiles/tab_general.py:648 msgid "SSH private key" msgstr "SSH 私鑰" #: common/config.py:283 msgid "Local encrypted" msgstr "本地加密的" #: common/config.py:284 common/config.py:291 msgid "Encryption" msgstr "加密" #: common/config.py:289 msgid "SSH encrypted" msgstr "SSH 加密" #: common/config.py:296 msgid "Default" msgstr "預設" #: common/config.py:327 common/config.py:339 common/config.py:357 #: common/config.py:371 #, python-brace-format msgid "Profile: \"{name}\"" msgstr "設定檔:\"{name}\"" #: common/config.py:328 msgid "Snapshots directory is not valid." msgstr "快照目錄不合規定。" #: common/config.py:340 msgid "At least one directory must be selected for backup." msgstr "至少必須選擇一個目錄進行備份。" #: common/config.py:358 common/config.py:373 #, python-brace-format msgid "Directory: {path}" msgstr "目錄{path}" #: common/config.py:359 common/config.py:374 msgid "" "This directory cannot be included in the backup as it is part of the backup " "destination itself." msgstr "該目錄不能包含在備份中,因為它是備份目標本身的一部分。" #: common/config.py:1467 msgid "Failed to write new crontab." msgstr "無法寫入新的 crontab。" #: common/config.py:1475 msgid "" "Cron is not running despite the crontab command being available. Scheduled " "backup jobs will not run. Cron might be installed but not enabled. Try the " "command \"systemctl enable cron\" or consult the support channels of your " "GNU/Linux distribution." msgstr "" "儘管 crontab 命令可用,但 Cron 並未運行。已排程的備份作業將不會運作。 Cron 可能已安裝但未啟用。嘗試命令「systemctl " "enable cron」或諮詢您的 GNU Linux 發行版的支援服務商。" #: common/config.py:1556 #, python-brace-format msgid "" "Could not install Udev rule for profile {profile_id}. DBus Service " "'{dbus_interface}' wasn't available" msgstr "無法為設定檔 {profile_id} 安裝 Udev 規則。 DBus 服務「{dbus_interface}」不可用" #: common/config.py:1571 #, python-brace-format msgid "Udev schedule doesn't work with mode {mode}" msgstr "定期 udev 不適用於 {mode} 模式" #: common/config.py:1582 #, python-brace-format msgid "Couldn't find UUID for {path}" msgstr "找不到 {path} 的 UUID" #: common/configfile.py:101 msgid "Failed to save config" msgstr "設定儲存失敗" #: common/configfile.py:137 msgid "Failed to load config" msgstr "設定載入失敗" #: common/configfile.py:684 common/configfile.py:783 #, python-brace-format msgid "Profile \"{name}\" already exists." msgstr "\"{name}\" 設定檔已存在。" #: common/configfile.py:729 msgid "The last profile cannot be removed." msgstr "無法刪除最後一個設定檔。" #: common/encfstools.py:81 #, python-brace-format msgid "Unable to mount '{command}'" msgstr "無法掛載 “{command}”" #: common/encfstools.py:131 msgid "Configuration for the encrypted directory not found." msgstr "找不到加密目錄的設定。" #: common/encfstools.py:139 msgid "Create a new encrypted directory?" msgstr "建立一個新的加密目錄?" #: common/encfstools.py:146 msgid "Cancel" msgstr "取消" #: common/encfstools.py:152 msgid "Please confirm the password." msgstr "請確認密碼。" #: common/encfstools.py:158 msgid "Password doesn't match." msgstr "密碼不符。" #: common/encfstools.py:516 common/snapshots.py:1042 msgid "Take snapshot" msgstr "進行快照" #: common/mount.py:622 #, python-brace-format msgid "Unable to unmount {mountprocess} from {mountpoint}." msgstr "無法從 {mountpoint} 卸載 {mountprocess}。" #: common/mount.py:709 #, python-brace-format msgid "{command} not found. Please install it (e.g. via \"{installcommand}\")" msgstr "找不到指令{command}。請安裝它(例如透過“{installcommand}”)" #: common/mount.py:733 #, python-brace-format msgid "Mountpoint {mntpoint} not empty." msgstr "掛載點 {mntpoint} 不為空。" #: common/password.py:279 #, python-brace-format msgid "Enter password for {mode} profile \"{profile}\":" msgstr "輸入 {mode} 設定檔「{profile}」的密碼:" #: common/snapshots.py:363 common/snapshots.py:617 msgid "FAILED" msgstr "失敗" #: common/snapshots.py:560 common/snapshots.py:628 msgid "Restore permissions" msgstr "回復權限" #: common/snapshots.py:623 qt/app.py:292 qt/app.py:1082 qt/app.py:1117 #: qt/qtsystrayicon.py:73 msgid "Done" msgstr "完成" #: common/snapshots.py:743 msgid "Deferring backup while on battery" msgstr "使用電池時延遲備份" #: common/snapshots.py:842 qt/app.py:363 msgid "Can't find snapshots directory." msgstr "找不到快照目錄。" #: common/snapshots.py:846 msgid "If it is on a removable drive please plug it in." msgstr "如果它在可移動磁碟中,請插入。" #: common/snapshots.py:849 #, python-format msgid "Waiting %s second." msgid_plural "Waiting %s seconds." msgstr[0] "等待 %s 秒。" #: common/snapshots.py:914 #, python-brace-format msgid "Failed to take snapshot {snapshot_id}." msgstr "建立快照 {snapshot_id} 執行失敗。" #: common/snapshots.py:946 msgid "Please be patient. Finalizing…" msgstr "請耐心等待。正在完成中…" #: common/snapshots.py:1077 msgid "Can't create directory." msgstr "無法创建目錄。" #: common/snapshots.py:1094 msgid "Saving config file…" msgstr "正在儲存設定檔…" #: common/snapshots.py:1175 msgid "Saving permissions…" msgstr "正在儲存權限設定…" #: common/snapshots.py:1290 #, python-brace-format msgid "Found leftover snapshot {snapshot_id} that can be continued." msgstr "發現尚未完成的快照 {snapshot_id} 可繼續處理。" #: common/snapshots.py:1314 #, python-brace-format msgid "Removing leftover {snapshot_id} directory from last run" msgstr "正在刪除上次執行中剩餘的目錄:{snapshot_id}" #: common/snapshots.py:1325 msgid "Can't remove directory" msgstr "無法刪除目錄" #: common/snapshots.py:1379 msgid "Taking snapshot" msgstr "正在建立快照" #: common/snapshots.py:1430 msgid "Success" msgstr "成功" #: common/snapshots.py:1433 msgid "Partial transfer due to error" msgstr "由於錯誤只轉移部分" #: common/snapshots.py:1434 msgid "Partial transfer due to vanished source files (see 'man rsync')" msgstr "由於來源檔消失而導致只傳輸部分(請見“man rsync”)" #: common/snapshots.py:1438 #, python-brace-format msgid "'rsync' ended with exit code {exit_code}" msgstr "“rsync”已終止退出代碼 {exit_code}" #: common/snapshots.py:1451 msgid "See 'man rsync' for more details" msgstr "有關更多詳細信息,請參閱“man rsync”" #: common/snapshots.py:1458 msgid "" "Negative rsync exit codes are signal numbers, see 'kill -l' and 'man kill'" msgstr "rsync 異常終止,請參閱 “kill -l” 和 “man Kill”" #: common/snapshots.py:1479 msgid "Nothing changed, no new snapshot necessary" msgstr "沒有任何改變,不需要新的快照" #: common/snapshots.py:1523 #, python-brace-format msgid "Unable to rename {new_path} to {path}." msgstr "無法將 {new_path} 重新命名為 {path}。" #: common/snapshots.py:1855 msgid "Smart removal" msgstr "智慧移除" #: common/snapshots.py:1888 msgid "Apply rules to remove old snapshots" msgstr "應用程式規則刪除舊快照" #: common/snapshots.py:1921 msgid "Apply retention policy" msgstr "應用保留策略" #: common/snapshots.py:1931 msgid "Trying to keep min free space" msgstr "嘗試保留最小剩餘空間" #: common/snapshots.py:1970 #, python-brace-format msgid "Trying to keep min {perc} free inodes" msgstr "嘗試保留最小 {perc} 可用 inode" #: common/snapshots.py:3103 qt/app.py:1849 msgid "Now" msgstr "現在" #: common/sshtools.py:232 #, python-brace-format msgid "Unable to mount {sshfs}" msgstr "無法掛載 {sshfs}" #: common/sshtools.py:300 msgid "ssh-agent not found. Please ensure it is installed." msgstr "未找到ssh-agent。 請確保它已安裝。" #: common/sshtools.py:470 msgid "" "Could not unlock ssh private key. Wrong password or password not available " "for cron." msgstr "無法解鎖 ssh 私鑰。 密碼錯誤或密碼不可用於 cron。" #: common/sshtools.py:559 #, python-brace-format msgid "Cipher {cipher} failed for {host}." msgstr "{host} 的密碼 {cipher} 失敗。" #: common/sshtools.py:706 msgid "Remote path exists but is not a directory." msgstr "遠端路徑存在但不是目錄。" #: common/sshtools.py:711 msgid "Remote path is not writable." msgstr "遠端路徑不可寫入。" #: common/sshtools.py:716 msgid "Remote path is not executable." msgstr "遠端路徑不可執行。" #: common/sshtools.py:721 msgid "Couldn't create remote path." msgstr "無法建立遠端路徑。" #: common/sshtools.py:1008 #, python-brace-format msgid "Remote host {host} doesn't support {command}" msgstr "遠端主機 {host} 不支援 {command}" #: common/sshtools.py:1012 common/sshtools.py:1021 msgid "Look at 'man backintime' for further instructions" msgstr "請參閱“man backintime”以獲取更多說明" #: common/sshtools.py:1016 #, python-brace-format msgid "Check commands on host {host} returned unknown error" msgstr "檢查主機 {host} 上的指令回傳未知錯誤" #: common/sshtools.py:1037 #, python-brace-format msgid "Remote host {host} doesn't support hardlinks" msgstr "遠端主機 {host} 不支援硬連結(Hard links)" #: common/sshtools.py:1191 #, python-brace-format msgid "Copy public ssh-key \"{pubkey}\" to remote host \"{host}\"." msgstr "將ssh公鑰“{pubkey}”複製到遠端主機“{host}”。" #: common/sshtools.py:1193 #, python-brace-format msgid "Please enter a password for \"{user}\"." msgstr "請輸入「{user}」的密碼。" #: common/tools.py:400 #, python-brace-format msgid "" "The destination filesystem for {path} is formatted with NTFS, which has " "known incompatibilities with Unix-style filesystems." msgstr "{path} 的目標檔案系統採用 NTFS 格式,已知其與 Unix 風格的檔案系統不相容。" #: common/tools.py:432 #, python-brace-format msgid "{path} is not a valid directory." msgstr "{path} 不是有效的目錄。" #: common/tools.py:446 msgid "Creation of following directory failed:" msgstr "建立以下目錄失敗:" #: common/tools.py:448 common/tools.py:544 msgid "Write access may be restricted." msgstr "寫入權限可能受到限制。" #: common/tools.py:488 #, python-brace-format msgid "" "Destination filesystem for {path} is formatted with FAT which doesn't " "support hard-links. Please use a native GNU/Linux filesystem." msgstr "{path} 的檔案系統採用 FAT 格式,不支援硬連結。 請使用原生 Linux 檔案系統。" #: common/tools.py:499 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via SMB. Please make " "sure the remote SMB server supports symlinks or activate \"{copyLinks}\" in " "\"{expertOptions}\"." msgstr "" "{path} 的目標檔案系統是透過 SMB 掛載共用。請確保遠端 SMB " "伺服器支援符號連結或在「{expertOptions}」中啟動「{copyLinks}」。" #: common/tools.py:503 qt/manageprofiles/tab_expert_options.py:253 msgid "Copy links (dereference symbolic links)" msgstr "複製鏈結 (dereference symbolic links)" #: common/tools.py:504 msgid "Expert Options" msgstr "進階選項" #: common/tools.py:508 #, python-brace-format msgid "" "Destination filesystem for {path} is a share mounted via sshfs. Sshfs " "doesn't support hard-links. Please use mode \"SSH\" instead." msgstr "{path} 的目標檔案系統是透過 sshfs 掛載的共用。 sshfs 不支援硬連結。請改用模式“SSH”。" #: common/tools.py:542 msgid "File creation failed in this directory:" msgstr "在此目錄中建立檔案失敗:" #: qt/aboutdlg.py:37 qt/app.py:576 msgid "About" msgstr "關於" #: qt/aboutdlg.py:61 qt/aboutdlg.py:99 msgid "Authors" msgstr "作者" #: qt/aboutdlg.py:62 qt/aboutdlg.py:105 msgid "Translations" msgstr "翻譯" #: qt/aboutdlg.py:63 qt/aboutdlg.py:111 msgid "License" msgstr "授權條款" #: qt/app.py:172 msgid "Shortcuts" msgstr "快速鍵" #: qt/app.py:192 msgid "" "This directory doesn't exist\n" "in the current selected snapshot." msgstr "" "在目前選定的快照中\n" "不存在該目錄。" #: qt/app.py:257 msgid "Add to Include" msgstr "加入包含項目" #: qt/app.py:259 msgid "Add to Exclude" msgstr "加入排除項目" #: qt/app.py:331 #, python-brace-format msgid "" "{app_name} appears to be running for the first time as no configuration is " "found." msgstr "未找到設定檔,{app_name} 看起來是第一次啟動。" #: qt/app.py:336 msgid "" "Import an existing configuration (from a backup target directory or another " "computer)?" msgstr "是否從備份目標目錄或另一台電腦匯入現有設定檔?" #: qt/app.py:364 msgid "If it is on a removable drive please plug it in and then press OK." msgstr "如果它在可移動磁碟中,請插入並按下確定。" #: qt/app.py:470 msgid "Take a snapshot" msgstr "建立快照" #: qt/app.py:472 msgid "Use modification time & size for file change detection." msgstr "使用修改時間和大小來檢測檔案變更。" #: qt/app.py:475 msgid "Take a snapshot (checksum mode)" msgstr "建立快照(校驗模式)" #: qt/app.py:477 msgid "Use checksums for file change detection." msgstr "使用校驗和(checksums)來檢測檔案變更。" #: qt/app.py:480 qt/qtsystrayicon.py:78 msgid "Pause snapshot process" msgstr "暫停快照處理" #: qt/app.py:485 qt/qtsystrayicon.py:82 msgid "Resume snapshot process" msgstr "恢復快照處理" #: qt/app.py:489 qt/qtsystrayicon.py:87 msgid "Stop snapshot process" msgstr "停止快照處理" #: qt/app.py:493 msgid "Refresh snapshot list" msgstr "重新整理快照列表" #: qt/app.py:497 msgid "Name snapshot" msgstr "快照名稱" #: qt/app.py:501 msgid "Remove snapshot" msgstr "刪除快照" #: qt/app.py:505 msgid "View snapshot log" msgstr "檢視快照記錄" #: qt/app.py:509 msgid "View last log" msgstr "查看最後的記錄" #: qt/app.py:513 msgid "Manage profiles…" msgstr "管理設定檔…" #: qt/app.py:517 msgid "Shutdown" msgstr "關閉" #: qt/app.py:519 msgid "Shut down system after snapshot has finished." msgstr "快照完成後關閉系統。" #: qt/app.py:521 msgid "Setup language…" msgstr "設定語言…" #: qt/app.py:525 msgid "Exit" msgstr "離開" #: qt/app.py:529 msgid "User manual" msgstr "使用者手冊" #: qt/app.py:531 msgid "Open user manual in browser (local if available otherwise online)" msgstr "在瀏覽器中開啟使用手冊(如果可用則在本地,否則在線)" #: qt/app.py:535 msgid "man page: Back In Time" msgstr "手冊頁:Back In &Time" #: qt/app.py:537 msgid "Displays man page about Back In Time (backintime)" msgstr "顯示有關 Back In Time(backintime)的手冊頁" #: qt/app.py:540 msgid "man page: Profiles config file" msgstr "手冊頁:設定檔" #: qt/app.py:543 msgid "Displays man page about profiles config file (backintime-config)" msgstr "顯示有關設定檔 (backintime-config) 的手冊頁" #: qt/app.py:547 msgid "Project website" msgstr "專案網站" #: qt/app.py:550 msgid "Open Back In Time website in browser" msgstr "在瀏覽器中開啟 Back In Time 網站" #: qt/app.py:552 qt/app.py:1463 msgid "Changelog" msgstr "變更日誌" #: qt/app.py:555 msgid "FAQ" msgstr "常見問題" #: qt/app.py:557 msgid "Open Frequently Asked Questions (FAQ) in browser" msgstr "在瀏覽器中開啟常見問題 (FAQ)" #: qt/app.py:559 msgid "Ask a question" msgstr "提出問題" #: qt/app.py:563 msgid "Report a bug" msgstr "報告錯誤" #: qt/app.py:566 msgid "Translation" msgstr "翻譯" #: qt/app.py:568 msgid "Shows the message about participation in translation again." msgstr "再次顯示參與翻譯的訊息。" #: qt/app.py:572 msgid "Encryption Transition (EncFS)" msgstr "加密轉換 (EncFS)" #: qt/app.py:574 msgid "Shows the message about EncFS removal again." msgstr "再次顯示有關 EncFS 刪除的訊息。" #: qt/app.py:579 qt/restoredialog.py:38 qt/snapshotsdialog.py:156 #: qt/snapshotsdialog.py:161 msgid "Restore" msgstr "還原" #: qt/app.py:581 msgid "Restore the selected files or directories to the original destination." msgstr "將選定的檔案或目錄還原到原始目標。" #: qt/app.py:584 qt/app.py:1640 qt/app.py:1672 qt/snapshotsdialog.py:158 msgid "Restore to …" msgstr "還原至…" #: qt/app.py:586 msgid "Restore the selected files or directories to a new destination." msgstr "將選定的檔案或目錄還原到新的目的地。" #: qt/app.py:592 msgid "" "Restore the currently shown directory and all its contents to the original " "destination." msgstr "將目前顯示的目錄及其所有內容還原至原始目標。" #: qt/app.py:598 msgid "" "Restore the currently shown directory and all its contents to a new " "destination." msgstr "將目前顯示的目錄及其所有內容還原至新目的地。" #: qt/app.py:601 msgid "Up" msgstr "回到上一層" #: qt/app.py:604 qt/restoreconfigdialog.py:90 msgid "Show hidden files" msgstr "顯示隱藏檔案" #: qt/app.py:607 msgid "Compare snapshots…" msgstr "比較快照…" #: qt/app.py:637 qt/app.py:2152 msgid "Release Candidate" msgstr "候選版本(Release Candidate)" #: qt/app.py:640 msgid "Shows the message about this Release Candidate again." msgstr "再次顯示有關此候選版本的消息。" #: qt/app.py:676 msgid "Back In &Time" msgstr "Back In &Time" #: qt/app.py:681 msgid "&Backup" msgstr "&備份" #: qt/app.py:692 msgid "&Restore" msgstr "&還原" #: qt/app.py:698 msgid "&Help" msgstr "&幫助" #: qt/app.py:743 msgid "Icons only" msgstr "僅限圖示" #: qt/app.py:746 msgid "Text only" msgstr "限文字" #: qt/app.py:749 msgid "Text below icons" msgstr "圖示下方的文字" #: qt/app.py:752 msgid "Text beside icon" msgstr "圖示旁邊的文字" #: qt/app.py:897 msgid "" "If you close this window, Back In Time will not be able to shut down your " "system when the snapshot is finished." msgstr "如果您關閉此窗口,Back In Time 將無法在快照完成後關閉您的系統。" #: qt/app.py:900 msgid "Do you really want to close it?" msgstr "您確定要關閉嗎?" #: qt/app.py:1072 msgid "Working:" msgstr "運作中 :" #: qt/app.py:1120 msgid "Done, no backup needed" msgstr "已完成,不需要進行備份" #: qt/app.py:1129 msgid "Working" msgstr "運作中" #: qt/app.py:1138 qt/messagebox.py:84 msgid "Error" msgstr "錯誤" #: qt/app.py:1161 msgid "Sent" msgstr "傳送" #: qt/app.py:1162 msgid "Speed" msgstr "速度" #: qt/app.py:1163 msgid "ETA" msgstr "預計完成時間" #: qt/app.py:1225 msgid "Global" msgstr "全域設定" #: qt/app.py:1226 msgid "Root" msgstr "根目錄" #: qt/app.py:1227 msgid "Home" msgstr "家目錄" #: qt/app.py:1255 msgid "Backup directories" msgstr "備份目錄" #: qt/app.py:1351 msgid "Snapshot Name" msgstr "快照名稱" #: qt/app.py:1398 msgid "Are you sure you want to remove this snapshot?" msgid_plural "Are you sure you want to remove these snapshots?" msgstr[0] "確認要刪除快照?" #: qt/app.py:1496 #, python-brace-format msgid "" "Create backup copies with trailing {suffix}\n" "before overwriting or removing local elements." msgstr "" "建立帶有尾隨 {suffix} 的備份副本\n" "在覆蓋或刪除本地元素之前。" #: qt/app.py:1504 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with the " "following command:" msgstr "在復原之前,較新版本的檔案將使用尾隨 {suffix} 進行重新命名。如果您不再需要它們,可以使用以下命令刪除它們:" #: qt/app.py:1520 msgid "" "Only restore elements which do not exist or\n" "are newer than those in destination.\n" "Using \"rsync --update\" option." msgstr "" "只恢復不存在或\n" "比目的地新的元素。\n" "使用“rsync --update”選項。" #: qt/app.py:1555 msgid "Remove newer elements in original directory." msgstr "刪除原始資料夾中較新的元素。" #: qt/app.py:1558 msgid "" "Restore selected files or directories to the original destination and delete" " files or directories which are not in the snapshot. Be extremely careful " "because this will delete files and directories which were excluded during " "taking the snapshot." msgstr "將選定的檔案或目錄還原到原始目標,並刪除快照中不存在的檔案或目錄。請務必小心,因為這將刪除在拍攝快照時排除的檔案和目錄。" #: qt/app.py:1570 msgid "Do you really want to restore this element into the new directory?" msgid_plural "" "Do you really want to restore these elements into the new directory?" msgstr[0] "您確定要將此項目還原到新目錄嗎?" #: qt/app.py:1580 msgid "Do you really want to restore this element?" msgid_plural "Do you really want to restore these elements?" msgstr[0] "你真的想恢復這些元素嗎?" #: qt/app.py:1599 #, python-brace-format msgid "Are you sure you want to remove all newer files in {path}?" msgstr "您確定要刪除 {path} 中的所有較新檔案嗎?" #: qt/app.py:1602 msgid "" "Are you sure you want to remove all newer files in your original directory?" msgstr "您確實要刪除原始目錄中所有較新的檔案嗎?" #: qt/app.py:1608 #, python-brace-format msgid "" "{BOLD}Warning{BOLDEND}: Deleting files in the filesystem root could break " "your entire system." msgstr "{BOLD}警告{BOLDEND}:刪除檔案系統根目錄中的檔案可能會破壞整個系統。" #: qt/app.py:1857 msgid "Snapshot" msgstr "快照" #: qt/app.py:1896 #, python-brace-format msgid "Restore {path}" msgstr "還原{path}" #: qt/app.py:1898 #, python-brace-format msgid "Restore {path} to …" msgstr "還原{path}到…" #: qt/app.py:2042 #, python-brace-format msgid "" "Hello\n" "You have used Back In Time in the {language} language a few times by now.\n" "The translation of your installed version of Back In Time into {language} is {perc} complete. Regardless of your level of technical expertise, you can contribute to the translation and thus Back In Time itself.\n" "Please visit the {translation_platform_url} if you wish to contribute. For further assistance and questions, please visit the {back_in_time_project_website}.\n" "We apologize for the interruption, and this message will not be shown again. This dialog is available at any time via the help menu.\n" "Your Back In Time Team" msgstr "" "您好,\n" "您已經多次以 {language} 使用 Back In Time 了。\n" "當前安裝的 Back In Time 所使用的 {language} 翻譯完成了 {perc}。無論您技術能力如何,都可以向 Back In Time 貢獻翻譯。\n" "若您希望參與翻譯,請訪問 {translation_platform_url}。如需協助或瞭解詳情,請訪問 {back_in_time_project_website}。\n" "非常抱歉打斷您的使用,本訊息今後不會再顯示。此對話框可以隨時在「幫助」菜單內呼出。\n" "Back In Time 團隊" #: qt/app.py:2071 msgid "translation platform" msgstr "翻譯平台" #: qt/app.py:2076 msgid "Website" msgstr "網站" #: qt/app.py:2090 msgid "Your translation" msgstr "您的翻譯" #: qt/app.py:2103 #, python-brace-format msgid "In the Fediverse at Mastodon: {link_and_label}" msgstr "在聯邦宇宙 Mastodon:{link_and_label}" #: qt/app.py:2108 #, python-brace-format msgid "Email to {link_and_label}." msgstr "發送電子郵件至{link_and_label}。" #: qt/app.py:2111 #, python-brace-format msgid "Mailing list {link_and_label}" msgstr "郵件清單 {link_and_label}" #: qt/app.py:2115 #, python-brace-format msgid "{link_and_label} on the project website." msgstr "項目網站上的 {link_and_label}。" #: qt/app.py:2118 msgid "Open an issue" msgstr "打開問題" #: qt/app.py:2119 msgid "Alternatively, you can use another channel of your choice." msgstr "或者,您也可以使用您選擇的其他管道。" #: qt/app.py:2124 #, python-brace-format msgid "" "This version of Back In Time is a Release Candidate and is primarily intended for stability testing in preparation for the next official release.\n" "No user data or telemetry is collected. However, the Back In Time team is very interested in knowing if the Release Candidate is being used and if it is worth continuing to provide such pre-release versions.\n" "Therefore, the team kindly asks for a short feedback on whether you have tested this version, even if you didn’t encounter any issues. Even a quick test run of a few minutes would help us a lot.\n" "The following contact options are available:\n" "{contact_list}\n" "In this version, this message won't be shown again but can be accessed anytime through the help menu.\n" "Thank you for your support and for helping us improve Back In Time!\n" "Your Back In Time Team" msgstr "" "此版本的“Back In Time”為候選版本,主要用於穩定性測試,為下一個正式版本做準備。\n" "不收集任何用戶資料或遙測資料。然而,Back In Time 團隊非常有興趣了解候選版本是否正在使用,以及是否值得繼續提供這樣的預發布版本。\n" "因此,即使您沒有遇到任何問題,團隊仍懇請您簡短回饋是否已經測試過此版本。即使只是幾分鐘的快速測試運行也會對我們有很大幫助。\n" "可用的聯絡方式如下:\n" "{contact_list}\n" "在此版本中,此訊息不會再次顯示,但可以隨時透過說明選單存取。\n" "感謝您的支持並幫助我們改進“Back In Time”!\n" "您的 Back In Time團隊" #: qt/app.py:2175 msgid "The language settings take effect only after restarting Back In Time." msgstr "語言設定僅在重新啟動 Back In Time 後生效。" #: qt/encfsmsgbox.py:42 qt/encfsmsgbox.py:68 #: qt/manageprofiles/tab_general.py:588 msgid "" "EncFS profile creation will be removed in the next minor release (1.7), " "scheduled for 2026." msgstr "EncFS 設定檔建立將在下一個次要版本 (1.7)(計劃於 2026 年發布)中刪除。" #: qt/encfsmsgbox.py:44 qt/encfsmsgbox.py:70 msgid "It is not recommended to use that mode for a profile furthermore." msgstr "不建議將該模式用於設定檔。" #: qt/encfsmsgbox.py:47 qt/encfsmsgbox.py:79 #: qt/manageprofiles/tab_general.py:597 msgid "whitepaper" msgstr "白皮書" #: qt/encfsmsgbox.py:49 qt/encfsmsgbox.py:85 #: qt/manageprofiles/tab_general.py:590 msgid "" "Support for EncFS is being discontinued due to security vulnerabilities." msgstr "由於安全漏洞,對 EncFS 的支援即將停止。" #: qt/encfsmsgbox.py:52 qt/manageprofiles/tab_general.py:592 #, python-brace-format msgid "" "For more details, including potential alternatives, please refer to this " "{whitepaper}." msgstr "欲了解更多詳情,包括潛在的替代方案,請參閱此{whitepaper}。" #: qt/encfsmsgbox.py:82 msgid "The following profile(s) use encryption with EncFS:" msgstr "以下設定檔使用 EncFS 進行加密:" #: qt/encfsmsgbox.py:87 msgid "" "A replacement is planned, but it cannot be guaranteed that it will arrive on" " time." msgstr "正在計劃更換,但無法保證會按時提供。" #: qt/encfsmsgbox.py:89 #, python-brace-format msgid "" "Users are invited to join this discussion. Updated details on the next steps" " are available in this {whitepaper}." msgstr "歡迎用戶參與本次討論。後續步驟的更新詳細資訊請參閱本{whitepaper}。" #: qt/encfsmsgbox.py:92 msgid "" "This message will not be shown again. This dialog is available at any time " "via the help menu." msgstr "此訊息將不會再次顯示。您可以隨時透過幫助選單存取此對話框。" #: qt/encfsmsgbox.py:94 msgid "Your Back In Time Team" msgstr "您的Back In Time團隊" #: qt/languagedialog.py:35 msgid "Setup language" msgstr "設定語言" #: qt/languagedialog.py:97 msgid "System default" msgstr "系統預設" #: qt/languagedialog.py:107 msgid "Use operating systems language." msgstr "使用作業系統語言。" #: qt/languagedialog.py:161 #, python-brace-format msgid "Translated: {percent}" msgstr "已翻譯: {percent}" #: qt/logviewdialog.py:60 msgid "Last Log View" msgstr "最後一次日誌查看" #: qt/logviewdialog.py:62 msgid "Snapshot Log View" msgstr "快照日誌視圖" #: qt/logviewdialog.py:70 qt/manageprofiles/__init__.py:75 #: qt/manageprofiles/tab_general.py:265 qt/restoreconfigdialog.py:269 msgid "Profile:" msgstr "設定:" #: qt/logviewdialog.py:78 msgid "Snapshots:" msgstr "快照:" #: qt/logviewdialog.py:93 msgid "Filter:" msgstr "篩選:" #: qt/logviewdialog.py:99 qt/manageprofiles/tab_options.py:133 msgid "All" msgstr "全部" #: qt/logviewdialog.py:106 qt/logviewdialog.py:110 #: qt/manageprofiles/tab_options.py:132 msgid "Changes" msgstr "變化" #: qt/logviewdialog.py:106 qt/logviewdialog.py:109 #: qt/manageprofiles/tab_options.py:131 qt/manageprofiles/tab_options.py:132 msgid "Errors" msgstr "錯誤" #: qt/logviewdialog.py:111 qt/messagebox.py:60 msgid "Information" msgid_plural "Information" msgstr[0] "資訊" #: qt/logviewdialog.py:114 msgid "rsync transfer failures (experimental)" msgstr "rsync 傳輸失敗(實驗性)" #: qt/logviewdialog.py:126 msgid "[E] Error, [I] Information, [C] Change" msgstr "[E] 錯誤,[I] 訊息,[C] 更改" #: qt/logviewdialog.py:129 qt/qtsystrayicon.py:91 msgid "decode paths" msgstr "解碼路徑" #: qt/manageprofiles/__init__.py:67 msgid "Manage profiles" msgstr "管理設定檔" #: qt/manageprofiles/__init__.py:84 msgid "Edit" msgstr "編輯" #: qt/manageprofiles/__init__.py:88 qt/manageprofiles/__init__.py:203 msgid "Add" msgstr "添加" #: qt/manageprofiles/__init__.py:92 qt/manageprofiles/__init__.py:150 #: qt/manageprofiles/__init__.py:221 msgid "Remove" msgstr "消除" #: qt/manageprofiles/__init__.py:113 msgid "&General" msgstr "&一般的" #: qt/manageprofiles/__init__.py:117 msgid "&Include" msgstr "包含" #: qt/manageprofiles/__init__.py:125 msgid "Include files and directories" msgstr "包括文件和目錄" #: qt/manageprofiles/__init__.py:142 qt/manageprofiles/__init__.py:207 msgid "Add file" msgstr "新增檔案" #: qt/manageprofiles/__init__.py:146 qt/manageprofiles/__init__.py:211 msgid "Add directory" msgstr "新增目錄" #: qt/manageprofiles/__init__.py:156 msgid "&Exclude" msgstr "&排除" #: qt/manageprofiles/__init__.py:160 #, python-brace-format msgid "" "{BOLD}Info{ENDBOLD}: In 'SSH encrypted' mode, only single or double " "asterisks are functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are unpredictable in " "this mode due to encryption by EncFS." msgstr "" "{BOLD}訊息{ENDBOLD}:在「SSH 加密」模式下,只有單星號或雙星號有效(例如 {example2})。其他類型的通配符和模式將被忽略(例如" " {example1})。由於 EncFS 加密,在此模式下檔案名稱是不可預測的。" #: qt/manageprofiles/__init__.py:183 msgid "Exclude patterns, files or directories" msgstr "排除模式、檔案或目錄" #: qt/manageprofiles/__init__.py:216 msgid "Add default" msgstr "新增預設值" #: qt/manageprofiles/__init__.py:229 msgid "Exclude files bigger than:" msgstr "排除大於以下文件:" #: qt/manageprofiles/__init__.py:233 #, python-brace-format msgid "Exclude files bigger than value in {size_unit}." msgstr "排除大於以下文件{size_unit}." #: qt/manageprofiles/__init__.py:235 msgid "" "With 'Full rsync mode' disabled, this will only impact new files since for " "rsync, this is a transfer option, not an exclusion option. Therefore, large " "files that have been backed up previously will persist in snapshots even if " "they have been modified." msgstr "" "排除大於 %(prefix)s 中的值的檔案。停用「完全 rsync 模式」後,這只會影響新文件因為對於 rsync " "這是一個傳輸選項,而不是排除選項。因此之前備份過的大檔案將保留在快照中,即使他們已經改變。" #: qt/manageprofiles/__init__.py:265 msgid "&Remove & Retention" msgstr "移除 & 保留" #: qt/manageprofiles/__init__.py:269 msgid "&Options" msgstr "選項" #: qt/manageprofiles/__init__.py:273 msgid "E&xpert Options" msgstr "專家選項" #: qt/manageprofiles/__init__.py:280 msgid "Restore Config" msgstr "恢復配置" #: qt/manageprofiles/__init__.py:282 msgid "Edit user-callback" msgstr "編輯用戶回調" #: qt/manageprofiles/__init__.py:300 msgid "New profile" msgstr "新增設定檔" #: qt/manageprofiles/__init__.py:317 msgid "Rename profile" msgstr "重新命名設定檔" #: qt/manageprofiles/__init__.py:333 #, python-brace-format msgid "Are you sure you want to delete the profile \"{name}\"?" msgstr "確認刪除設定檔\"{name}\"?" #: qt/manageprofiles/__init__.py:379 #, python-brace-format msgid "" "{BOLD}Highly recommended{ENDBOLD}: (All recommendations already included.)" msgstr "{BOLD}強烈推薦{ENDBOLD}:(所有建議均已包含在內。)" #: qt/manageprofiles/__init__.py:384 #, python-brace-format msgid "{BOLD}Highly recommended{ENDBOLD}: {files}" msgstr "{BOLD}強烈推薦{ENDBOLD}:{files}" #: qt/manageprofiles/__init__.py:608 msgid "Exclude pattern" msgstr "排除樣式" #: qt/manageprofiles/__init__.py:621 msgid "Exclude file" msgstr "排除檔案" #: qt/manageprofiles/__init__.py:625 msgid "Exclude directory" msgstr "排除目錄" #: qt/manageprofiles/__init__.py:649 msgid "Include file" msgstr "包含檔案" #: qt/manageprofiles/__init__.py:658 qt/manageprofiles/__init__.py:688 #, python-brace-format msgid "" "\"{path}\" is a symlink. The linked target will not be backed up until you include it, too.\n" "Would you like to include the symlink target instead?" msgstr "" "{path}是一個符號連結。 除非您也將連結的目標包含在內,否則不會對其進行備份。\n" "您想改為包含符號連結目標嗎?" #: qt/manageprofiles/__init__.py:679 msgid "Include directory" msgstr "包含目錄" #: qt/manageprofiles/__init__.py:738 msgid "" "Disabled because this pattern is not functional in mode 'SSH encrypted'." msgstr "已停用,因為此模式在「SSH 加密」模式下不起作用。" #: qt/manageprofiles/schedulewidget.py:37 msgid "Schedule" msgstr "排程" #: qt/manageprofiles/schedulewidget.py:63 msgid "Day:" msgstr "天:" #: qt/manageprofiles/schedulewidget.py:68 msgid "Weekday:" msgstr "工作日:" #: qt/manageprofiles/schedulewidget.py:73 msgid "Time:" msgstr "時間:" #: qt/manageprofiles/schedulewidget.py:78 msgid "Hours:" msgstr "時:" #: qt/manageprofiles/schedulewidget.py:86 msgid "after the hour" msgstr "小時後" #: qt/manageprofiles/schedulewidget.py:88 msgid "Minutes:" msgstr "分鐘:" #: qt/manageprofiles/schedulewidget.py:92 msgid "" "Run Back In Time as soon as the drive is connected (only once every X days)." " You will be prompted for your sudo password." msgstr "一旦驅動器連接,立即運行 Back In Time(每 X 天僅一次)。系統將提示您輸入 sudo 密碼。" #: qt/manageprofiles/schedulewidget.py:97 msgid "" "Run Back In Time repeatedly. This is useful if the computer is not running " "regularly." msgstr "反覆運行Back In Time。 如果計算機沒有正常運行,這非常有用。" #: qt/manageprofiles/schedulewidget.py:109 msgid "Every:" msgstr "每天:" #: qt/manageprofiles/schedulewidget.py:113 msgid "Enable logging of debug messages" msgstr "啟用偵錯訊息的日誌記錄" #: qt/manageprofiles/schedulewidget.py:117 msgid "Writes debug-level messages into the system log via \"--debug\"." msgstr "透過“--debug”將偵錯等級訊息寫入系統日誌。" #: qt/manageprofiles/schedulewidget.py:119 msgid "" "Caution: Only use this temporarily for diagnostics, as it generates a large " "amount of output." msgstr "注意:僅臨時使用它進行診斷,因為它會產生大量輸出。" #: qt/manageprofiles/schedulewidget.py:141 msgid "Disabled" msgstr "關閉" #: qt/manageprofiles/schedulewidget.py:142 msgid "At every boot/reboot" msgstr "每次啟動/重新啟動時" #: qt/manageprofiles/schedulewidget.py:144 #: qt/manageprofiles/schedulewidget.py:146 #: qt/manageprofiles/schedulewidget.py:148 #, python-brace-format msgid "Every {n} minute" msgid_plural "Every {n} minutes" msgstr[0] "每{n}分鐘" #: qt/manageprofiles/schedulewidget.py:150 #, python-brace-format msgid "Every hour" msgid_plural "Every {n} hours" msgstr[0] "每隔{n}小時" #: qt/manageprofiles/schedulewidget.py:152 #: qt/manageprofiles/schedulewidget.py:154 #: qt/manageprofiles/schedulewidget.py:156 #: qt/manageprofiles/schedulewidget.py:158 #, python-brace-format msgid "Every {n} hour" msgid_plural "Every {n} hours" msgstr[0] "每{n}月" #: qt/manageprofiles/schedulewidget.py:159 msgid "Custom hours" msgstr "客製化時間" #: qt/manageprofiles/schedulewidget.py:160 msgid "Every day" msgstr "每天" #: qt/manageprofiles/schedulewidget.py:161 msgid "Repeatedly (anacron)" msgstr "重複(anacron)" #: qt/manageprofiles/schedulewidget.py:162 msgid "When drive gets connected (udev)" msgstr "當驅動器連接 (udev)" #: qt/manageprofiles/schedulewidget.py:163 msgid "Every week" msgstr "每週" #: qt/manageprofiles/schedulewidget.py:164 msgid "Every month" msgstr "每月" #: qt/manageprofiles/schedulewidget.py:165 msgid "Every year" msgstr "每年" #: qt/manageprofiles/schedulewidget.py:214 msgid "Hour(s)" msgstr "小時" #: qt/manageprofiles/schedulewidget.py:215 #: qt/manageprofiles/tab_remove_retention.py:256 msgid "Day(s)" msgstr "天" #: qt/manageprofiles/schedulewidget.py:216 #: qt/manageprofiles/tab_remove_retention.py:257 msgid "Week(s)" msgstr "週" #: qt/manageprofiles/schedulewidget.py:217 msgid "Month(s)" msgstr "月" #: qt/manageprofiles/schedulewidget.py:311 msgid "" "Custom hours can only be a comma separated list of hours (e.g. 8,12,18,23) " "or */3 for periodic backups every 3 hours." msgstr "自訂時間只能是逗號分隔的時間清單(例如 8,12,18,23)或 */3(每 3 小時定期備份一次)。" #: qt/manageprofiles/sshproxywidget.py:47 msgid "SSH Proxy" msgstr "SSH 代理" #: qt/manageprofiles/sshproxywidget.py:54 qt/manageprofiles/tab_general.py:115 #: qt/manageprofiles/tab_general.py:253 msgid "Host:" msgstr "主機:" #: qt/manageprofiles/sshproxywidget.py:58 qt/manageprofiles/tab_general.py:120 msgid "Port:" msgstr "端口:" #: qt/manageprofiles/sshproxywidget.py:62 qt/manageprofiles/tab_general.py:125 #: qt/manageprofiles/tab_general.py:259 msgid "User:" msgstr "用戶:" #: qt/manageprofiles/sshproxywidget.py:71 msgid "" "Connect to the target host via this proxy (also known as a jump host). See " "\"-J\" in the \"ssh\" command documentation or \"ProxyJump\" in " "\"ssh_config\" man page for details." msgstr "" "透過此代理程式(也稱為跳轉主機)連接到目標主機。有關詳細信息,請參閱“ssh”命令文件中的“-J”或“ssh_config”手冊頁中的“ProxyJump”。" #: qt/manageprofiles/tab_expert_options.py:39 msgid "Caution:" msgstr "警告:" #: qt/manageprofiles/tab_expert_options.py:40 msgid "" "These options are for advanced configurations. Modify only if fully aware of" " their implications." msgstr "這些選項用於進階配置。只有在充分了解其意義的情況下才可以進行修改。" #: qt/manageprofiles/tab_expert_options.py:47 #: qt/manageprofiles/tab_expert_options.py:67 #: qt/manageprofiles/tab_expert_options.py:92 #, python-brace-format msgid "Run 'rsync' with '{cmd}':" msgstr "使用“{cmd}”運行“rsync”:" #: qt/manageprofiles/tab_expert_options.py:54 #: qt/manageprofiles/tab_expert_options.py:73 msgid "as cron job" msgstr "作為 cron 作業" #: qt/manageprofiles/tab_expert_options.py:60 #: qt/manageprofiles/tab_expert_options.py:85 #: qt/manageprofiles/tab_expert_options.py:116 msgid "on remote host" msgstr "在遠端主機上" #: qt/manageprofiles/tab_expert_options.py:79 msgid "when taking a manual snapshot" msgstr "進行手動快照時" #: qt/manageprofiles/tab_expert_options.py:103 msgid "Please install 'nocache' to enable this option." msgstr "請安裝“nocache”以啟用此選項。" #: qt/manageprofiles/tab_expert_options.py:109 msgid "on local machine" msgstr "本機" #: qt/manageprofiles/tab_expert_options.py:123 msgid "Redirect stdout to /dev/null in cronjobs." msgstr "在 cronjobs 中將 stdout 重新導向到 /dev/null。" #: qt/manageprofiles/tab_expert_options.py:129 msgid "" "Cron will automatically send an email with attached output of cronjobs if an" " MTA is installed." msgstr "如果安裝了 MTA,Cron 將自動發送一封電子郵件,其中附有 cronjobs 的輸出。" #: qt/manageprofiles/tab_expert_options.py:135 msgid "Redirect stderr to /dev/null in cronjobs." msgstr "在 cronjobs 中將 stdout 重新導向到 /dev/null。" #: qt/manageprofiles/tab_expert_options.py:141 msgid "" "Cron will automatically send an email with attached errors of cronjobs if an" " MTA is installed." msgstr "如果安裝了 MTA,Cron 將自動發送一封電子郵件,其中附有 cronjobs 錯誤。" #: qt/manageprofiles/tab_expert_options.py:151 msgid "KB/sec" msgstr "KB/秒" #: qt/manageprofiles/tab_expert_options.py:156 msgid "Limit rsync bandwidth usage:" msgstr "限制 rsync 頻寬:" #: qt/manageprofiles/tab_expert_options.py:197 msgid "Preserve ACL" msgstr "保留 ACL" #: qt/manageprofiles/tab_expert_options.py:215 msgid "Preserve extended attributes (xattr)" msgstr "保留擴充屬性 (xattr)" #: qt/manageprofiles/tab_expert_options.py:238 msgid "Copy unsafe links (works only with absolute links)" msgstr "複製不安全連結(僅適用於絕對連結)" #: qt/manageprofiles/tab_expert_options.py:274 msgid "Restrict to one file system" msgstr "限制為一個檔案系統" #: qt/manageprofiles/tab_expert_options.py:292 #, python-brace-format msgid "Options must be quoted e.g. {example}." msgstr "選項必須加引號,例如{example}。" #: qt/manageprofiles/tab_expert_options.py:301 msgid "Paste additional options to rsync" msgstr "將附加選項貼到 rsync" #: qt/manageprofiles/tab_expert_options.py:309 msgid "Prefix to run before every command on remote host." msgstr "在遠端主機上的每個命令之前運行的前綴。" #: qt/manageprofiles/tab_expert_options.py:310 #, python-brace-format msgid "" "Variables need to be escaped with \\$FOO. This doesn't touch rsync. So to " "add a prefix for rsync use \"{example_value}\" with {rsync_options_value}." msgstr "" "在遠端主機上的每個命令之前運行的前綴。變數需要使用 \\$FOO 進行轉義。這不涉及 rsync。 " "所以要加上前綴{example_value}{rsync_options_value}。" #: qt/manageprofiles/tab_expert_options.py:318 msgid "default" msgstr "預設" #: qt/manageprofiles/tab_expert_options.py:324 msgid "Add prefix to SSH commands" msgstr "為 SSH 指令加上前綴" #: qt/manageprofiles/tab_expert_options.py:334 msgid "Check if remote host is online" msgstr "檢查遠端主機是否在線" #: qt/manageprofiles/tab_expert_options.py:337 msgid "" "Warning: If disabled and the remote host is not available, this could lead " "to some weird errors." msgstr "警告:如果已停用且遠端主機不可用,這可能會導致一些奇怪的錯誤。" #: qt/manageprofiles/tab_expert_options.py:341 msgid "Check if remote host supports all necessary commands." msgstr "檢查遠端主機是否支援所有必要的命令." #: qt/manageprofiles/tab_expert_options.py:344 msgid "" "Warning: If disabled and the remote host does not support all necessary " "commands, this could lead to some weird errors." msgstr "警告:如果已停用且遠端主機不支援所有必要的命令,這可能會導致一些奇怪的錯誤。" #: qt/manageprofiles/tab_expert_options.py:359 msgid "(default: {})" msgstr "(預設:{})" #: qt/manageprofiles/tab_expert_options.py:360 msgid "disabled" msgstr "被禁用" #: qt/manageprofiles/tab_expert_options.py:360 msgid "enabled" msgstr "已啟用" #: qt/manageprofiles/tab_general.py:65 qt/restoreconfigdialog.py:271 msgid "Mode:" msgstr "模式:" #: qt/manageprofiles/tab_general.py:77 qt/manageprofiles/tab_general.py:620 msgid "Where to save snapshots" msgstr "快照存放位置" #: qt/manageprofiles/tab_general.py:103 msgid "SSH Settings" msgstr "SSH 設定" #: qt/manageprofiles/tab_general.py:130 msgid "Path:" msgstr "路徑:" #: qt/manageprofiles/tab_general.py:136 msgid "Cipher:" msgstr "密碼:" #: qt/manageprofiles/tab_general.py:141 msgid "Private Key:" msgstr "私鑰:" #: qt/manageprofiles/tab_general.py:152 msgid "" "Choose an existing private key file (normally named \"id_ed25519\" and in " "older setups \"id_rsa\")." msgstr "選擇一個現有的私鑰檔案(通常名為“id_ed25519”,在舊設定中名為“id_rsa”)。" #: qt/manageprofiles/tab_general.py:164 msgid "" "Create a new SSH key without password (not allowed if a private key file is " "already selected)." msgstr "建立一個新的無密碼 SSH 金鑰(如果已選擇私鑰檔案則不允許)。" #: qt/manageprofiles/tab_general.py:200 qt/manageprofiles/tab_general.py:207 #: qt/manageprofiles/tab_general.py:211 msgid "Password" msgstr "密碼" #: qt/manageprofiles/tab_general.py:221 msgid "Save Password to Keyring" msgstr "將密碼儲存到密鑰環" #: qt/manageprofiles/tab_general.py:225 msgid "Cache Password for Cron (Security issue: root can read password)" msgstr "Cron 的快取密碼(安全性問題:root 可以讀取密碼" #: qt/manageprofiles/tab_general.py:241 msgid "Advanced" msgstr "進階" #: qt/manageprofiles/tab_general.py:271 qt/manageprofiles/tab_general.py:676 msgid "Full snapshot path:" msgstr "完整快照路徑:" #: qt/manageprofiles/tab_general.py:394 msgid "You did not choose a private key file for SSH." msgstr "您沒有為 SSH 選擇私鑰檔案。" #: qt/manageprofiles/tab_general.py:395 msgid "" "Would you like to generate a new password-less public/private key pair?" msgstr "您沒有為 SSH 選擇私鑰檔案。您想產生一個新的無密碼公鑰/私鑰對嗎?" #: qt/manageprofiles/tab_general.py:406 #, python-brace-format msgid "Private key file \"{file}\" does not exist." msgstr "私鑰檔案“{file}”不存在。" #: qt/manageprofiles/tab_general.py:491 msgid "" "Would you like to copy your public SSH key to the remote host to enable " "password-less login?" msgstr "您想要將您的SSH 公 鑰複製到遠端主機啟用無密碼登入?" #: qt/manageprofiles/tab_general.py:525 #, python-brace-format msgid "The authenticity of host {host} can't be established." msgstr "無法確定主機 {host} 的真實性。" #: qt/manageprofiles/tab_general.py:528 #, python-brace-format msgid "{keytype} key fingerprint is:" msgstr "{keytype} 指紋是:" #: qt/manageprofiles/tab_general.py:536 msgid "" "Please verify this fingerprint. Would you like to add it to your " "'known_hosts' file?" msgstr "請驗證此指紋. 您想將其新增至您的「known_hosts」檔案嗎?" #: qt/manageprofiles/tab_general.py:627 msgid "Are you sure you want to change snapshots directory?" msgstr "確認修改快照目錄?" #: qt/manageprofiles/tab_general.py:664 #, python-brace-format msgid "Failed to create new SSH key in {path}." msgstr "無法在 {path} 中建立新的 SSH 金鑰。" #: qt/manageprofiles/tab_options.py:37 msgid "Enable notifications" msgstr "開啟通知" #: qt/manageprofiles/tab_options.py:41 msgid "Disable snapshots when on battery" msgstr "使用電池時停用快照功能" #: qt/manageprofiles/tab_options.py:47 msgid "Power status not available from system" msgstr "無法獲得系統電源狀態" #: qt/manageprofiles/tab_options.py:49 msgid "Run only one snapshot at a time" msgstr "一次僅運行一個快照" #: qt/manageprofiles/tab_options.py:53 msgid "" "Other snapshots will be blocked until the current snapshot is done. This is " "a global option. So it will affect all profiles for this user. But you need " "to activate this for all other users, too." msgstr "其他快照將被阻止,直到目前快照完成。這是一個全域選項。 因此它將影響該用戶的所有設定檔。但您也需要為所有其他用戶啟動此功能。" #: qt/manageprofiles/tab_options.py:60 msgid "Backup replaced files on restore" msgstr "恢復時備份替換的文件" #: qt/manageprofiles/tab_options.py:64 #, python-brace-format msgid "" "Newer versions of files will be renamed with trailing {suffix} before " "restoring. If you don't need them anymore you can remove them with {cmd}" msgstr "在復原之前,較新版本的檔案將使用 {suffix} 進行重新命名。如果您不再需要它們,可以使用 {cmd} 刪除它們" #: qt/manageprofiles/tab_options.py:75 msgid "Continue on errors (keep incomplete snapshots)" msgstr "出錯時繼續(保留不完整的快照)" #: qt/manageprofiles/tab_options.py:79 msgid "Use checksum to detect changes" msgstr "使用校驗和來檢測更改" #: qt/manageprofiles/tab_options.py:83 msgid "Take a new snapshot whether there were changes or not." msgstr "無論是否發生更改,都拍攝新快照。" #: qt/manageprofiles/tab_options.py:90 msgid "Log Level:" msgstr "日誌等級:" #: qt/manageprofiles/tab_options.py:130 msgid "None" msgstr "沒有任何" #: qt/manageprofiles/tab_remove_retention.py:190 #, python-brace-format msgid "" "The following rules are processed from top to bottom. Later rules override " "earlier ones and are not constrained by them. See the {manual} for details " "and examples." msgstr "以下規則按從上到下的順序處理。後續規則將覆蓋先前的規則,並且不受先前規則的約束。有關詳細資訊和範例,請參閱{manual}。" #: qt/manageprofiles/tab_remove_retention.py:195 msgid "user manual" msgstr "使用者手冊" #: qt/manageprofiles/tab_remove_retention.py:208 msgid "Open user manual in browser." msgstr "在瀏覽器中開啟使用者手冊。" #: qt/manageprofiles/tab_remove_retention.py:222 msgid "Keep the most recent snapshot." msgstr "保留最新的快照。" #: qt/manageprofiles/tab_remove_retention.py:226 msgid "The last or freshest snapshot is kept under all circumstances." msgstr "在任何情況下都會保留最新或最新的快照。" #: qt/manageprofiles/tab_remove_retention.py:228 msgid "That behavior cannot be changed." msgstr "這種行為無法改變。" #: qt/manageprofiles/tab_remove_retention.py:240 msgid "Keep named snapshots." msgstr "保留命名的快照。" #: qt/manageprofiles/tab_remove_retention.py:243 msgid "" "Snapshots that have been given a name, in addition to the usual timestamp, " "will be retained under all circumstances and will not be removed." msgstr "除通常的時間戳外,已命名的快照在任何情況下都會保留,並且不會被刪除。" #: qt/manageprofiles/tab_remove_retention.py:258 msgid "Year(s)" msgstr "年" #: qt/manageprofiles/tab_remove_retention.py:263 msgid "Remove snapshots older than" msgstr "刪除早於以下時間的快照" #: qt/manageprofiles/tab_remove_retention.py:269 msgid "Full days. Current day is ignored." msgstr "整天。忽略當天。" #: qt/manageprofiles/tab_remove_retention.py:271 msgid "Calendar weeks with Monday as first day. Current week is ignored." msgstr "以星期一為第一天的日曆週。忽略當前週。" #: qt/manageprofiles/tab_remove_retention.py:274 msgid "12 months periods. Current month is ignored." msgstr "12 個月為一個週期。忽略目前月份。" #: qt/manageprofiles/tab_remove_retention.py:289 msgid "Retention policy" msgstr "保留政策" #: qt/manageprofiles/tab_remove_retention.py:294 msgid "Run in background on remote host." msgstr "在遠端主機的後台運行。" #: qt/manageprofiles/tab_remove_retention.py:297 msgid "" "The smart remove procedure will run directly on the remote machine, not " "locally. The commands \"bash\", \"screen\", and \"flock\" must be installed " "and available on the remote machine." msgstr "智慧刪除過程將直接在遠端機器上運行,而不是在本地運行。必須在遠端機器上安裝並可使用指令「bash」、「screen」和「flock」。" #: qt/manageprofiles/tab_remove_retention.py:301 msgid "If selected, Back In Time will first test the remote machine." msgstr "如果選擇,Back In Time 將首先測試遠端機器。" #: qt/manageprofiles/tab_remove_retention.py:305 msgid "The days are counted starting from today." msgstr "從今天開始計算天數。" #: qt/manageprofiles/tab_remove_retention.py:306 msgid "Keep all snapshots for the last" msgstr "將所有快照保留到最後" #: qt/manageprofiles/tab_remove_retention.py:311 #: qt/manageprofiles/tab_remove_retention.py:323 msgid "day(s)." msgstr "天." #: qt/manageprofiles/tab_remove_retention.py:318 msgid "Keep the last snapshot for each day for the last" msgstr "保留每天的最後快照" #: qt/manageprofiles/tab_remove_retention.py:328 msgid "" "The weeks are counted starting from the current running week. A week starts " "on Monday." msgstr "週數從當週開始計算,一週從星期一開始。" #: qt/manageprofiles/tab_remove_retention.py:331 msgid "Keep the last snapshot for each week for the last" msgstr "保留每週的最後快照" #: qt/manageprofiles/tab_remove_retention.py:336 msgid "week(s)." msgstr "週." #: qt/manageprofiles/tab_remove_retention.py:341 msgid "" "The months are counted as calendar months starting with the current month." msgstr "月份從當前月份開始,按日曆月份計算。" #: qt/manageprofiles/tab_remove_retention.py:344 msgid "Keep the last snapshot for each month for the last" msgstr "保留每個月的最後快照" #: qt/manageprofiles/tab_remove_retention.py:349 msgid "month(s)." msgstr "月。" #: qt/manageprofiles/tab_remove_retention.py:354 msgid "" "The years are counted as calendar years starting with the current year." msgstr "年份從當前年份開始,按日曆年份計算。" #: qt/manageprofiles/tab_remove_retention.py:356 msgid "Keep the last snapshot for each year for" msgstr "保留每年的最後快照" #: qt/manageprofiles/tab_remove_retention.py:358 msgid "all years." msgstr "所有年份。" #: qt/manageprofiles/tab_remove_retention.py:380 msgid "… the free space is less than" msgstr "...剩餘空間少於:" #: qt/manageprofiles/tab_remove_retention.py:385 msgid "… the free inodes are less than" msgstr "...剩餘空間少於:" #: qt/manageprofiles/tab_remove_retention.py:394 msgid "Remove oldest snapshots if …" msgstr "刪除最舊的快照,如果…" #: qt/messagebox.py:93 qt/messagebox.py:103 msgid "Question" msgstr "問題" #: qt/qtsystrayicon.py:69 #, python-brace-format msgid "Profile: {profile_name}" msgstr "設定檔:{profile_name}" #: qt/qtsystrayicon.py:96 msgid "View Last Log" msgstr "查看最後的日誌" #: qt/qtsystrayicon.py:100 #, python-brace-format msgid "Start {appname}" msgstr "啟動{appname}" #: qt/qtsystrayicon.py:166 msgid "Working…" msgstr "運作中…" #: qt/qtsystrayicon.py:197 msgid "Sent:" msgstr "傳送:" #: qt/qtsystrayicon.py:198 msgid "Speed:" msgstr "速度:" #: qt/qtsystrayicon.py:199 msgid "ETA:" msgstr "ETA:" #: qt/qttools.py:483 qt/snapshotsdialog.py:115 msgid "Snapshots" msgstr "快照" #: qt/qttools.py:506 msgid "Today" msgstr "今天" #: qt/qttools.py:513 msgid "Yesterday" msgstr "昨天" #: qt/qttools.py:522 msgid "This week" msgstr "本週" #: qt/qttools.py:529 msgid "Last week" msgstr "上週" #: qt/qttools.py:675 msgid "This is NOT a snapshot but a live view of your local files" msgstr "這不是快照,而是本地文件的即時視圖" #: qt/qttools.py:680 #, python-brace-format msgid "Last check {time}" msgstr "最後一次檢查{time}" #: qt/restoreconfigdialog.py:55 msgid "Import configuration" msgstr "導入配置" #: qt/restoreconfigdialog.py:111 qt/restoreconfigdialog.py:207 msgid "No config found" msgstr "沒有找到配置" #: qt/restoreconfigdialog.py:136 msgid "Import" msgstr "導入" #: qt/restoreconfigdialog.py:164 #, python-brace-format msgid "" "Select the snapshot directory from which the configuration file should be " "imported. The path may look like: {samplePath}" msgstr "選擇應從中匯入設定檔的快照目錄。該路徑可能如下所示:{samplePath}" #: qt/restoreconfigdialog.py:169 msgid "" "If the directory is located on an external or remote drive, it must be " "manually mounted beforehand." msgstr "如果該資料夾位於外部或遠端磁碟機上,則必須事先手動掛載。" #: qt/restoredialog.py:51 msgid "Show full Log" msgstr "顯示完整日誌" #: qt/snapshotsdialog.py:43 msgid "Options about comparing snapshots" msgstr "有關比較快照的選項" #: qt/snapshotsdialog.py:50 msgid "Command:" msgstr "命令:" #: qt/snapshotsdialog.py:54 msgid "Parameters:" msgstr "參數:" #: qt/snapshotsdialog.py:59 msgid "Use %1 and %2 for path parameters" msgstr "使用%1和%2作為路徑參數" #: qt/snapshotsdialog.py:76 msgid "Please set a diff command or press Cancel." msgstr "請設定 diff 指令或按「取消」。" #: qt/snapshotsdialog.py:82 #, python-brace-format msgid "" "The command \"{cmd}\" cannot be found on this system. Please try something " "else or press Cancel." msgstr "在此系統上找不到指令“{cmd}”。請嘗試其他操作或按“取消”。" #: qt/snapshotsdialog.py:90 #, python-brace-format msgid "No parameters set for the diff command. Using default value \"{params}\"." msgstr "沒有為 diff 指令設定參數。使用預設值“{params}”。" #: qt/snapshotsdialog.py:126 msgid "Differing snapshots only" msgstr "僅不同快照" #: qt/snapshotsdialog.py:134 msgid "List only snapshots that are equal to:" msgstr "僅列出與以下內容相同的快照:" #: qt/snapshotsdialog.py:145 msgid "Deep check (more accurate, but slow)" msgstr "深度檢查(更準確,但速度慢)" #: qt/snapshotsdialog.py:166 msgid "Delete" msgstr "刪除" #: qt/snapshotsdialog.py:170 msgid "Select All" msgstr "全選" #: qt/snapshotsdialog.py:183 msgid "Compare" msgstr "比較" #: qt/snapshotsdialog.py:195 msgid "Go To" msgstr "前往" #: qt/snapshotsdialog.py:196 msgid "Options" msgstr "選項" #: qt/snapshotsdialog.py:353 msgid "You can't compare a snapshot to itself." msgstr "無法進行快照自我比對." #: qt/snapshotsdialog.py:396 #, python-brace-format msgid "Do you really want to delete {file} in snapshot {snapshot_id}?" msgstr "您確實要刪除快照 {snapshot_id} 中的 {file} 嗎?" #: qt/snapshotsdialog.py:402 #, python-brace-format msgid "Do you really want to delete {file} in {count} snapshots?" msgstr "您確實要刪除 {count} 個快照中的 {file} 嗎?" #: qt/snapshotsdialog.py:406 msgid "WARNING: This cannot be revoked." msgstr "警告:此操作無法撤銷。" #: qt/snapshotsdialog.py:424 #, python-brace-format msgid "Exclude {path} from future snapshots?" msgstr "從未來的快照中排除 {path} 嗎?" #~ msgid "The sub-directories cannot be included in the backup." #~ msgstr "此子資料夾不能被包含備份資料夾中。" backintime-1.5.4/common/progress.py000066400000000000000000000015631477034762000173540ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import configfile class ProgressFile(configfile.ConfigFile): RSYNC = 50 def __init__(self, cfg, filename=None): super(ProgressFile, self).__init__() self.config = cfg self.filename = filename if self.filename is None: self.filename = self.config.takeSnapshotProgressFile() def save(self): return super(ProgressFile, self).save(self.filename) def load(self): return super(ProgressFile, self).load(self.filename) def fileReadable(self): return os.access(self.filename, os.R_OK) backintime-1.5.4/common/qt_probing.py000066400000000000000000000150061477034762000176510ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Jürgen Altfeld (aryoda) # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import resource import logger logger.openlog() # from tools import isRoot # This mini python script is used to determine if a Qt GUI application # can be created without an error. # # It is used e.g. for diagnostics output of backintime # or to check if a system tray icon could be shown... # # It is called by "tools.is_Qt_working()" normally # but you can also execute it manually via # python3 qt_probing.py # It works by trying to create a QApplication instance # Any error indicates that Qt is not available or not correctly configured. # WORK AROUND: # # The C++ code of Qt ends abruptly with a SIGABRT signal (qFatal macro) # if a QApplication cannot be instantiated. # This causes a coredump creation by the python default signal handler # and the signal handler cannot be disabled since it reacts to a # non-python low-level signal sent via C/C++. # # Even though the coredump message cannot be prevented there is # workaround to prevent the coredump **file** creation which # would take too much time just to probe Qt's availability: # # Use resource.setrlimit() to set resource.RLIMIT_CORE’s soft limit to 0 # # Note: This does NOT prevent the console output "Aborted (core dumped)" # even though no coredump file will be created! # You can check that no coredump file was created with the command # sudo coredumpctl list -r # # More details: # # To suppress the creation of coredump file on GNU/Linux # use resource.setrlimit() to set resource.RLIMIT_CORE’s soft limit to 0 # to prevent coredump file creation. # https://docs.python.org/3.10/library/resource.html#resource.RLIMIT_CORE # https://docs.python.org/3.10/library/resource.html#resource.setrlimit # See also the source code of the test.support.SuppressCrashReport() context manager: # if self.resource is not None: # try: # self.old_value = self.resource.getrlimit(self.resource.RLIMIT_CORE) # self.resource.setrlimit(self.resource.RLIMIT_CORE, # (0, self.old_value[1])) # except (ValueError, OSError): # pass # https://github.com/python/cpython/blob/32718f908cc92c474fd968912368b8a4500bd055/Lib/test/support/__init__.py#L1712-L1718 # and cpython "faulthandler_suppress_crash_report()" # https://github.com/python/cpython/blob/32718f908cc92c474fd968912368b8a4500bd055/Modules/faulthandler.c#L954 # See "man 2 getrlimit" for more details: # > RLIMIT_CORE # > This is the maximum size of a core file (see core(5)) in bytes # > that the process may dump. When 0 no core dump files are created # > When nonzero, larger dumps are truncated to this size. # > ... # > The soft limit is the value that the kernel enforces for the corresponding resource. # > The hard limit acts as a ceiling for the soft limit: # > an unprivileged process may set only its soft limit to a value # > in the range from 0 up to the hard limit, and (irreversibly) lower its # > hard limit. A privileged process (under GNU/Linux: one with the # > CAP_SYS_RESOURCE capability in the initial user namespace) may make # > arbitrary changes to either limit value. # # Note: The context manager test.support.SuppressCrashReport() is NOT used # here since the "test.support" module not public and its API is subject # to change without backwards compatibility concerns between releases. # Work-around to prevent the time-consuming creation of a core dump old_limits = resource.getrlimit(resource.RLIMIT_CORE) resource.setrlimit(resource.RLIMIT_CORE, (0, old_limits[1])) exit_code = 0 try: if "--debug" in sys.argv: # HACK: Minimal arg parsing to enable debug-level logging logger.DEBUG = True logger.debug(f"{__file__} started... Call args: {str(sys.argv)}") logger.debug(f"Display system: {os.environ.get('XDG_SESSION_TYPE', '($XDG_SESSION_TYPE is not set)')}") logger.debug(f"XDG_RUNTIME_DIR={os.environ.get('XDG_RUNTIME_DIR', '($XDG_RUNTIME_DIR is not set)')}") logger.debug(f"XAUTHORITY={os.environ.get('XAUTHORITY', '($XAUTHORITY is not set)')}") logger.debug(f"QT_QPA_PLATFORM={os.environ.get('QT_QPA_PLATFORM', '($QT_QPA_PLATFORM is not set)')}") logger.debug(f"Current euid: {os.geteuid()}") # Jan 25, 2024 Not enabled but just documented here since this "fix" is a hack (assumes hard-coded UID 1000 to be always correct). But it works in 99 % of installations # if isRoot(): # logger.debug("Changing euid from root to user as work-around for #1592 (qt_probing hangs in root cron job)") # # Fix inspired by # # https://stackoverflow.com/questions/71425861/connecting-to-user-dbus-as-root # os.seteuid(1000) # logger.debug(f"New euid: {os.geteuid()}") # pylint: disable-next=unused-import from PyQt6 import QtCore from PyQt6.QtWidgets import QApplication app = QApplication(['']) exit_code = 1 # https://doc.qt.io/qt-5/qsystemtrayicon.html#details: # > To check whether a system tray is present on the user's desktop, # > call the QSystemTrayIcon::isSystemTrayAvailable() static function. # # This requires a QApplication instance (otherwise Qt causes a segfault) # which we don't have here so we create it to check if a window manager # ("GUI") is active at all (e.g. in headless installations it isn't). # See: https://forum.qt.io/topic/3852/issystemtrayavailable-always-crashes-segfault-on-ubuntu-10-10-desktop/6 from PyQt6.QtWidgets import QSystemTrayIcon is_sys_tray_available = QSystemTrayIcon.isSystemTrayAvailable() if is_sys_tray_available: exit_code = 2 logger.debug(f"isSystemTrayAvailable for Qt: {is_sys_tray_available}") except Exception as e: logger.debug(f"Error: {repr(e)}") logger.debug(f"{__file__} is terminating normally (exit code: {exit_code})") # Exit codes: # 0 = no Qt GUI available # 1 = only Qt GUI available (no sys tray support) # 2 = Qt GUI and sys tray available # 134 (-6 as signed byte exit code type!) = SIGABRT caught by python # ("interrupted by signal 6: SIGABRT"). # This is most probably caused by a misconfigured Qt... # So the interpretation is the same as exit code 0. sys.exit(exit_code) backintime-1.5.4/common/schedule.py000066400000000000000000000134231477034762000173020ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """ Basic functions for handling Cron, Crontab, and other scheduling-related features. """ import subprocess import logger _MARKER = '#Back In Time system entry, this will be edited by the gui:' """The string is used in crontab file to mark entries as owned by Back In Time. **WARNING**: Don't modify that string in code because it is used as match target while parsing the crontab file. See :func:`remove_bit_from_crontab()` for details. """ def _determine_crontab_command() -> str: """Return the name of one of the supported crontab commands if available. Returns: (str): The command name. Usually "crontab" or "fcrontab". Raises: RuntimeError: If none of the supported commands available. """ to_check_commands = ['crontab', 'fcrontab'] for cmd in to_check_commands: proc = subprocess.run( ['which', cmd], stdout=subprocess.PIPE, check=False ) if proc.returncode == 0: return cmd # syslog is not yet initialized logger.openlog() msg = 'Command ' + ' and '.join(to_check_commands) + ' not found.' logger.critical(msg) raise RuntimeError(msg) CRONTAB_COMMAND = _determine_crontab_command() def read_crontab(): """Read current users crontab. On errors an empty list is returned. Returns: list: Crontab lines. """ proc = subprocess.run( [CRONTAB_COMMAND, '-l'], check=False, capture_output=True, text=True) # Error? if proc.returncode != 0: # Ignore missing crontabs if not proc.stderr.startswith('no crontab for'): logger.error(f'Failed to get content via "{CRONTAB_COMMAND}". ' f'Return code of {proc.args} was {proc.returncode}. ' f'Stderr: {proc.stderr}') return [] content = proc.stdout.split('\n') # Remove empty lines from the end try: while content[-1] == '': content = content[:-1] except IndexError: pass # Fixes issue #1181 (line count of empty crontab was 1 instead of 0) if content == ['']: content = [] return content def write_crontab(lines): """Write users crontab. This will overwrite the whole users crontab. So to keep the old crontab and only add new entries you need to read it first with :py:func:`tools.readCrontab`, append new entries to the list and write it back. Args: lines (list, tuple): Lines that should be written to crontab. Returns: bool: ``True`` if successful otherwise ``False``. """ content = '\n'.join(lines) # Crontab needs to end with a newline if not content.endswith('\n'): content += '\n' # Pipe the content (via echo over stdout) to crontab's stdin with subprocess.Popen(['echo', content], stdout=subprocess.PIPE) as echo: try: subprocess.run( [CRONTAB_COMMAND, '-'], stdin=echo.stdout, check=True, capture_output=True, text=True ) except subprocess.CalledProcessError as err: logger.error( f'Failed to write crontab lines with "{CRONTAB_COMMAND}". ' f'Return code was {err.returncode}. ' f'Error was:\n{err.stderr}') return False return True def remove_bit_from_crontab(crontab): """Remove crontab entries related to backintime and having a marker line in the line before. Args: lines(list): List of crontab lines. """ # Indices of lines containing the marker marker_indexes = list(filter( lambda idx: _MARKER in crontab[idx], range(len(crontab)) )) # Check if there is a valid BIT entry after the marker lines for idx in marker_indexes[:]: try: if 'backintime' in crontab[idx+1]: continue except IndexError: pass # Remove the current index because the following line is not valid marker_indexes.remove(marker_indexes.index(idx)) modified_crontab = crontab[:] # Remove the marker comment line and the following backintime line for idx in reversed(marker_indexes): del modified_crontab[idx:idx+2] return modified_crontab def append_bit_to_crontab(crontab, bit_lines): """Add new entries to existing crontab content. Args: crontab(list): A list of strings as crontab lines. bit_lines(list): A list of strings as new crontab lines. Returns: list: The new crontab lines. """ for line in bit_lines: crontab.append(_MARKER) crontab.append(line) return crontab def is_cron_running(): """Validate if a cron instance is running. The output of ``ps`` is searched (case-insensitive) via ``grep`` for the string ``cron``. Returns: bool: The answer. """ with subprocess.Popen(['ps', '-eo', 'comm'], stdout=subprocess.PIPE) as ps: try: subprocess.run( ['grep', '--ignore-case', 'cron'], stdin=ps.stdout, stdout=subprocess.PIPE, check=True ) except subprocess.CalledProcessError: return False return True backintime-1.5.4/common/singleton.py000066400000000000000000000051311477034762000175050ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2022 Mars Landis # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See file/folder LICENSE or # go to # and . # # Credits to Mr. Mars Landis describing that solution and comparing it to # alternatives in his article 'Better Python Singleton with a Metaclass' at # # himself referring to this Stack Overflow # question as his inspiration. # # Original code adapted by Christian Buhtz. """Flexible and pythonic singleton implementation. Support inheritance and multiple classes. Multilevel inheritance is theoretically possible if the '__allow_reinitialization' approach would be implemented as described in the original article. Example :: >>> from singleton import Singleton >>> >>> class Foo(metaclass=Singleton): ... def __init__(self): ... self.value = 'Alyssa Ogawa' >>> >>> class Bar(metaclass=Singleton): ... def __init__(self): ... self.value = 'Naomi Wildmann' >>> >>> f = Foo() >>> ff = Foo() >>> f'{f.value=} :: {ff.value=}' "f.value='Alyssa Ogawa' :: ff.value='Alyssa Ogawa'" >>> ff.value = 'Who?' >>> f'{f.value=} :: {ff.value=}' "f.value='Who?' :: ff.value='Who?'" >>> >>> b = Bar() >>> bb = Bar() >>> f'{b.value=} :: {bb.value=}' "b.value='Naomi Wildmann' :: bb.value='Naomi Wildmann'" >>> b.value = 'thinking ...' >>> f'{b.value=} :: {bb.value=}' "b.value='thinking ...' :: bb.value='thinking ...'" >>> >>> id(f) == id(ff) True >>> id(b) == id(bb) True >>> id(f) == id(b) False """ class Singleton(type): """Singleton implementation supporting inheritance and multiple classes.""" _instances = {} """Hold single instances of multiple classes.""" def __call__(cls, *args, **kwargs): try: # Reuse existing instance return cls._instances[cls] except KeyError: # Create new instance cls._instances[cls] = super().__call__(*args, **kwargs) return cls._instances[cls] backintime-1.5.4/common/snapshotlog.py000066400000000000000000000342001477034762000200430ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import re import logger import snapshots import tools class LogFilter: """ A Filter for snapshot logs which will both decode log lines and filter them for the requested ``mode``. Args: mode (int): which filter should be used. Possible values: :py:data:`NO_FILTER`, :py:data:`ERROR`, :py:data:`CHANGES`, :py:data:`INFORMATION` or :py:data:`ERROR_AND_CHANGES` decode (encfstools.Decode): instance used for decoding lines or ``None`` """ # TODO Better use an enumeration NO_FILTER = 0 ERROR = 1 CHANGES = 2 INFORMATION = 3 ERROR_AND_CHANGES = 4 RSYNC_TRANSFER_FAILURES = 5 # Regular expressions used for filtering log file lines. # RegExp syntax see: https://docs.python.org/3.10/library/re.html#regular-expression-syntax # (?:...) = the matched substring cannot be retrieved in a group (non-capturing) REGEX = {None: None, NO_FILTER: None, ERROR: re.compile(r'^(?:\[E\]|[^\[])'), CHANGES: re.compile(r'^(?:\[C\]|[^\[])'), INFORMATION: re.compile(r'^(?:\[I\]|[^\[])'), ERROR_AND_CHANGES: re.compile(r'^(?:\[E\]|\[C\]|[^\[])'), RSYNC_TRANSFER_FAILURES: re.compile( # All links to rsync's source reference the commit 2f9b963 from Jun 27, 2023 (most-recent commit on "master" as at Jan 28, 2024) r'.*(?:' r'Invalid cross-device link' # not directly contained in rsync's source code but may be caught and passed through as-is r'|symlink has no referent' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1281 r'|readlink_stat\(.?\) failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1294 r'|link_stat .* failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1810 r'|receive_sums failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L347 r'|send_files failed to open' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L361 r'|fstat failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L373 r'|read errors mapping' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L435 r'|change_dir .* failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/main.c#L749 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/main.c#L807 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/main.c#L827 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/main.c#L1161 r'|skipping overly long name' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1247 r'|skipping file with bogus \(zero\) st_mode' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1300 r'|skipping symlink with 0-length value' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1569 r'|cannot convert filename' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L748 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1599 r'|cannot convert symlink data for' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1144 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1613 r'|opendir .* failed' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1842 r'|filename overflows max-path len by' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1868 r'|cannot send file with empty name in' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1876 r'|readdir\(.*\)' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L1888 r'|cannot add local filter rules in long-named directory' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/exclude.c#L817 r'|failed to re-read xattr' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/xattrs.c#L662 r'|Skipping sender remove of destination file' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L152 r'|Skipping sender remove for changed file' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/sender.c#L161 r'|could not make way for' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/delete.c#L220 r'|system says the ACL I packed is invalid' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/acls.c#L435 r'|recv_acl_access: value out of range' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/acls.c#L689 r'|recv_acl_index: .* ACL index' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/acls.c#L739 r'|Create time value of .* truncated on receiver' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L858 r'|FATAL I/O ERROR: dying to avoid a \-\-delete' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/flist.c#L2005 r'|IO error encountered' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/generator.c#L295 r'|some files/attrs were not transferred' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/log.c#L97 r'|temporary filename too long' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/receiver.c#L138 r'|No batched update for' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/receiver.c#L456 r'|recv_files: .* is a directory' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/receiver.c#L805 r'|no ftruncate for over-long pre-alloc' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/util1.c#L438 r'|daemon refused to receive' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/generator.c#L1270 r'|get_xattr_data: lgetxattr' # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/xattrs.c#L199 # https://github.com/WayneD/rsync/blob/2f9b963abaa52e44891180fe6c0d1c2219f6686d/xattrs.c#L215 # r').*' # no need to match the remainder of the line r')' )} def __init__(self, mode = 0, decode = None): self.regex = self.REGEX[mode] self.decode = decode if decode: self.header = ( '### This log has been decoded with automatic search pattern\n' '### If some paths are not decoded you can manually decode ' 'them with:\n' '### \'backintime --quiet ' ) if int(decode.config.currentProfile()) > 1: self.header += '--profile "%s" ' % decode.config.profileName() self.header += '--decode \'\n\n' else: self.header = '' def filter(self, line): """ Filter and decode ``line`` with predefined ``mode`` and ``decode`` instance. Args: line (str): log line read from disk Returns: str: decoded ``line`` or ``None`` if the line was filtered """ if not line: #keep empty lines return line if self.regex and not self.regex.match(line): return if self.decode: return self.decode.log(line) else: return line class SnapshotLog: """ Read and write Snapshot log to "~/.local/share/backintime/takesnapshot_.log". Where is the profile ID ``profile``. Args: cfg (config.Config): current config profile (int): profile that should be used to identify the log """ NONE = 0 ERRORS = 1 CHANGES_AND_ERRORS = 2 ALL = 3 def __init__(self, cfg, profile = None): self.config = cfg if profile: self.profile = profile else: self.profile = cfg.currentProfile() self.logLevel = cfg.logLevel() self.logFileName = cfg.takeSnapshotLogFile(self.profile) self.logFile = None self.timer = tools.Alarm(self.flush, overwrite = False) def __del__(self): if self.logFile: self.logFile.close() def get(self, mode = None, decode = None, skipLines = 0): """ Read the log, filter and decode it and yield its lines. Args: mode (int): Mode used for filtering. Take a look at :py:class:`snapshotlog.LogFilter` decode (encfstools.Decode): instance used for decoding lines or ``None`` skipLines (int): skip ``n`` lines before yielding lines. This is used to append only new lines to LogView Yields: str: filtered and decoded log lines """ logFilter = LogFilter(mode, decode) count = logFilter.header.count('\n') try: with open(self.logFileName, 'rt') as f: if logFilter.header and not skipLines: yield logFilter.header for line in f.readlines(): line = logFilter.filter(line.rstrip('\n')) if not line is None: count += 1 if count <= skipLines: continue yield line except Exception as e: msg = ('Failed to get take_snapshot log from {}:'.format(self.logFile), str(e)) logger.debug(' '.join(msg), self) for line in msg: yield line def new(self, date): """ Create a new log file or - if the last new_snapshot can be continued - add a note to the current log. Args: date (datetime.datetime): current date """ if snapshots.NewSnapshot(self.config).saveToContinue: msg = "Last snapshot didn't finish but can be continued.\n\n" msg += "======== continue snapshot (profile %s): %s ========\n" else: if os.path.exists(self.logFileName): if self.logFile: self.logFile.close() self.logFile = None os.remove(self.logFileName) msg = "========== Take snapshot (profile %s): %s ==========\n" self.append(msg %(self.profile, date.strftime('%c')), 1) def append(self, msg, level): """ Append ``msg`` to the log if ``level`` is lower than configured log level. Args: msg (str): message line that should be added to the log level (int): verbosity level of current line. msg will only be added to log if level is lower than configured log level :py:func:`config.Config.logLevel`. Possible Values: :py:data:`SnapshotLog.ERRORS`, :py:data:`SnapshotLog.CHANGES_AND_ERRORS` or :py:data:`SnapshotLog.ALL` """ if level > self.logLevel: return if not self.logFile: self.logFile = open(self.logFileName, 'at') self.logFile.write(msg + '\n') self.timer.start(5) # flush the log output buffer after 5 seconds def flush(self): """ Write the in-memory buffer of the log output into the log file. """ if self.logFile: try: # TODO flush() does not necessarily write the file’s data to disk. # Use flush() followed by os.fsync() to ensure this behavior. # https://docs.python.org/2/library/stdtypes.html#file.flush self.logFile.flush() except RuntimeError: # Fixes #1003 (RTE reentrant call inside io.BufferedWriter) # This RTE will not be logged since this would be another reentrant call pass backintime-1.5.4/common/snapshots.py000066400000000000000000003424671477034762000175450ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raack # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . from __future__ import annotations import os from pathlib import Path import stat import datetime import calendar import gettext import bz2 import pwd import getpass import grp import subprocess import shutil import time import re from tempfile import TemporaryDirectory import config import configfile import logger import tools import encfstools import mount import progress import snapshotlog import flock from applicationinstance import ApplicationInstance from exceptions import MountException, LastSnapshotSymlink from uniquenessset import UniquenessSet class Snapshots: """ Collection of take-snapshot and restore commands. BUHTZ 2022-10-09: In my understanding this is the representation of a snapshot in the "application layer". This seems to be the difference to the class `SID` which represents a snapshot in the "data layer". BUHTZ 2024-02-23: Not sure but it seems to be one concrete snapshot and not a collection of snapshots. In this case the class name is misleading because it is in plural form. Args: cfg (config.Config): current config """ SNAPSHOT_VERSION = 3 def __init__(self, cfg = None): self.config = cfg if self.config is None: self.config = config.Config() self.snapshotLog = snapshotlog.SnapshotLog(self.config) self.clearIdCache() self.clearNameCache() #rsync --info=progress2 output #search for: 517.38K 26% 14.46MB/s 0:02:36 #or: 497.84M 4% -449.39kB/s ??:??:?? #but filter out: 517.38K 26% 14.46MB/s 0:00:53 (xfr#53, to-chk=169/452) # because this shows current run time self.reRsyncProgress = re.compile(r'.*?' #trash at start r'(\d*[,\.]?\d+[KkMGT]?)\s+' #bytes sent r'(\d*)%\s+' #percent done r'(-?\d*[,\.]?\d*[KkMGT]?B/s)\s+' #speed r'([\d\?]+:[\d\?]{2}:[\d\?]{2})' #estimated time of arrival r'(.*$)') #trash at the end self.lastBusyCheck = datetime.datetime(1, 1, 1) self.restorePermissionFailed = False # TODO: make own class for takeSnapshotMessage def clearTakeSnapshotMessage(self): """Delete message and progress file""" Path(self.config.takeSnapshotMessageFile()).unlink(missing_ok=True) Path(self.config.takeSnapshotProgressFile()).unlink(missing_ok=True) # TODO: make own class for takeSnapshotMessage def takeSnapshotMessage(self): """Get the current message from the message file. Returns: (tuple(int, str)): The message type and its string or `None`. See `setTakeSnapshotMessage()` for further details. Dev note (buhtz): Too many try..excepts in here. """ # Dev note (buhtz): Not sure what happens here or why this is useful. wait = datetime.datetime.now() - datetime.timedelta(seconds=5) if self.lastBusyCheck < wait: self.lastBusyCheck = datetime.datetime.now() if not self.busy(): self.clearTakeSnapshotMessage() return None # Filename of the message file message_fn = self.config.takeSnapshotMessageFile() if not os.path.exists(message_fn): return None try: with open(message_fn, 'rt') as handle: items = handle.read().split('\n') # TODO (buhtz): Too broad exception except Exception as exc: logger.debug('Failed to get takeSnapshot message from ' f'{message_fn}: {str(exc)}', self) return None if len(items) < 2: return None # "Message id": Type of the message. mid = 0 try: mid = int(items[0]) # TODO (buhtz): Too broad exception except Exception as exc: logger.debug('Failed to extract message ID from ' f'{items}: {str(exc)}', self) return (mid, '\n'.join(items[1:])) # TODO: make own class for takeSnapshotMessage def setTakeSnapshotMessage(self, type_id, message, timeout=-1): """Update the status message of the active snapshot creation job Write the status message into a message file to allow async processing for the GUI, plug-ins (like user-callback) and desktop notifications. Args: type_id: Simplified severity level of the status message: 0: INFO 1: ERROR other values: defaults to INFO (may change in the future) message: status message string timeout: Requested maximum processing duration in plug-ins. Default: -1 (no limit) Called plug-ins must try to keep the timeout itself (it is not enforced by the ``PluginManager``. In fact currently all known plug-ins do ignore the timeout value! """ message_fn = self.config.takeSnapshotMessageFile() try: # Write message to file (and overwrites the previous one) with open(message_fn, 'wt') as f: f.write(str(type_id) + '\n' + message) except Exception as exc: logger.debug('Failed to set takeSnapshot message ' f'to {message_fn}: {str(exc)}', self) # Error message? if type_id == 1: self.snapshotLog.append('[E] ' + message, 1) else: self.snapshotLog.append('[I] ' + message, 3) try: profile_id = self.config.currentProfile() profile_name = self.config.profileName(profile_id) self.config.PLUGIN_MANAGER.message( profile_id, profile_name, type_id, message, timeout) except Exception as exc: logger.debug(f'Failed to send message to plugins: {str(exc)}', self) def busy(self): instance = ApplicationInstance(self.config.takeSnapshotInstanceFile(), False) return instance.busy() def pid(self): instance = ApplicationInstance(self.config.takeSnapshotInstanceFile(), False) return instance.readPidFile()[0] def clearNameCache(self): """ Reset the cache for user and group names. """ self.userCache = {} self.groupCache = {} def clearIdCache(self): """ Reset the cache for UIDs and GIDs. """ self.uidCache = {} self.gidCache = {} def uid(self, name, callback = None, backup = None): """ Get the User identifier (UID) for the user in ``name``. name->uid will be cached to speed up subsequent requests. Args: name (:py:class:`str`, :py:class:`bytes`): username to search for callback (method): callable which will handle a given message backup (int): UID which will be used if the username is unknown on this machine Returns: int: UID of the user in name or -1 if not found """ if isinstance(name, bytes): name = name.decode() if name in self.uidCache: return self.uidCache[name] else: uid = -1 try: uid = pwd.getpwnam(name).pw_uid except Exception as e: if backup: uid = backup msg = "UID for '%s' is not available on this system. Using UID %s from snapshot." %(name, backup) logger.info(msg, self) if callback is not None: callback(msg) else: self.restorePermissionFailed = True msg = 'Failed to get UID for %s: %s' %(name, str(e)) logger.error(msg, self) if callback: callback(msg) self.uidCache[name] = uid return uid def gid(self, name, callback = None, backup = None): """ Get the Group identifier (GID) for the group in ``name``. name->gid will be cached to speed up subsequent requests. Args: name (:py:class:`str`, :py:class:`bytes`): groupname to search for callback (method): callable which will handle a given message backup (int): GID which will be used if the groupname is unknown on this machine Returns: int: GID of the group in name or -1 if not found """ if isinstance(name, bytes): name = name.decode() if name in self.gidCache: return self.gidCache[name] else: gid = -1 try: gid = grp.getgrnam(name).gr_gid except Exception as e: if backup is not None: gid = backup msg = "GID for '%s' is not available on this system. Using GID %s from snapshot." %(name, backup) logger.info(msg, self) if callback: callback(msg) else: self.restorePermissionFailed = True msg = 'Failed to get GID for %s: %s' %(name, str(e)) logger.error(msg, self) if callback: callback(msg) self.gidCache[name] = gid return gid def userName(self, uid): """ Get the username for the given uid. uid->name will be cached to speed up subsequent requests. Args: uid (int): User identifier (UID) to search for Returns: str: name of the user with UID uid or '-' if not found """ if uid in self.userCache: return self.userCache[uid] else: name = '-' try: name = pwd.getpwuid(uid).pw_name except Exception as e: logger.debug('Failed to get user name for UID %s: %s' %(uid, str(e)), self) self.userCache[uid] = name return name def groupName(self, gid): """ Get the groupname for the given gid. gid->name will be cached to speed up subsequent requests. Args: gid (int): Group identifier (GID) to search for Returns: str: name of the Group with GID gid or '.' if not found """ if gid in self.groupCache: return self.groupCache[gid] else: name = '-' try: name = grp.getgrgid(gid).gr_name except Exception as e: logger.debug('Failed to get group name for GID %s: %s' %(gid, str(e)), self) self.groupCache[gid] = name return name def restoreCallback(self, callback, ok, msg): """ Format messages thrown by restore depending on whether they where successful or failed. Args: callback (method): callable instance which will handle the message ok (bool): ``True`` if the logged action was successful or ``False`` if it failed msg (str): message that should be send to callback """ if not callback is None: if not ok: # TODO # This string might appear in a message dialog. # Let us know the steps to reproduce that behavior. msg = msg + ' : ' + _('FAILED') self.restorePermissionFailed = True callback(msg) def restorePermission(self, key_path, path, fileInfoDict, callback = None): """ Restore permissions (owner, group and mode). If permissions are already identical with the new ones just skip. Otherwise try to 'chown' to new owner and new group. If that fails (most probably because we are not running as root and normal user has no rights to change ownership of files) try to at least 'chgrp' to the new group. Finally 'chmod' the new mode. Args: key_path (bytes): original path during backup. Same as in fileInfoDict. path (bytes): current path of file that should be changed. fileInfoDict (FileInfoDict): FileInfoDict """ assert isinstance(key_path, bytes), 'key_path is not bytes type: %s' % key_path assert isinstance(path, bytes), 'path is not bytes type: %s' % path assert isinstance(fileInfoDict, FileInfoDict), 'fileInfoDict is not FileInfoDict type: %s' % fileInfoDict if key_path not in fileInfoDict or not os.path.exists(path): return info = fileInfoDict[key_path] #restore uid/gid uid = self.uid(info[1], callback) gid = self.gid(info[2], callback) #current file stats st = os.stat(path) # logger.debug('%(path)s: uid %(target_uid)s/%(cur_uid)s, gid %(target_gid)s/%(cur_gid)s, mod %(target_mod)s/%(cur_mod)s' # %{'path': path.decode(), # 'target_uid': uid, # 'cur_uid': st.st_uid, # 'target_gid': gid, # 'cur_gid': st.st_gid, # 'target_mod': info[0], # 'cur_mod': st.st_mode # }) if uid != -1 or gid != -1: ok = False if uid != st.st_uid: try: os.chown(path, uid, gid) ok = True except: pass self.restoreCallback(callback, ok, "chown %s %s : %s" % (path.decode(errors = 'ignore'), uid, gid)) st = os.stat(path) #if restore uid/gid failed try to restore at least gid if not ok and gid != st.st_gid: try: os.chown(path, -1, gid) ok = True except: pass self.restoreCallback(callback, ok, "chgrp %s %s" % (path.decode(errors = 'ignore'), gid)) st = os.stat(path) #restore perms ok = False if info[0] != st.st_mode: try: os.chmod(path, info[0]) ok = True except: pass self.restoreCallback(callback, ok, "chmod %s %04o" % (path.decode(errors = 'ignore'), info[0])) def restore(self, sid, paths, callback = None, restore_to = '', delete = False, backup = True, only_new = False): """ Restore one or more files from snapshot ``sid`` to either original or a different destination. Restore is done with rsync. If available permissions will be restored from ``fileinfo.bz2``. Args: sid (SID): snapshot from whom to restore paths (:py:class:`list`, :py:class:`tuple` or :py:class:`str`): single path (str) or multiple paths (list, tuple) that should be restored. For every path this will run a new rsync process. Permissions will be restored for all paths in one run callback (method): callable instance which will handle messages restore_to (str): full path to restore to. If empty restore to original destination delete (bool): delete newer files which are not in the snapshot backup (bool): create backup files (``*.backup.YYYYMMDD``) before changing or deleting local files. only_new (bool): Only restore files which do not exist or are newer than those in destination. Using ``rsync --update`` option. """ instance = ApplicationInstance( pidFile=self.config.restoreInstanceFile(), autoExit=False, flock=True) if instance.check(): instance.startApplication() else: logger.warning('Restore is already running', self) return if restore_to.endswith('/'): restore_to = restore_to[: -1] if not isinstance(paths, (list, tuple)): paths = (paths,) logger.info("Restore: %s to: %s" %(', '.join(paths), restore_to), self) info = sid.info cmd_prefix = tools.rsyncPrefix(self.config, no_perms=False, use_mode=['ssh']) cmd_prefix.extend(('-R', '-v')) if backup: cmd_prefix.extend(('--backup', '--suffix=%s' % self.backupSuffix())) if delete: cmd_prefix.append('--delete') cmd_prefix.append('--filter=protect %s' % self.config.snapshotsPath()) cmd_prefix.append('--filter=protect %s' % self.config._LOCAL_DATA_FOLDER) cmd_prefix.append('--filter=protect %s' % self.config._MOUNT_ROOT) if only_new: cmd_prefix.append('--update') restored_paths = [] for path in paths: tools.makeDirs(os.path.dirname(path)) src_path = path src_delta = 0 src_base = sid.pathBackup(use_mode = ['ssh']) if not src_base.endswith(os.sep): src_base += os.sep cmd = cmd_prefix[:] if restore_to: items = os.path.split(src_path) aux = items[0].lstrip(os.sep) # bugfix: restore system root ended in //. if aux: src_base = os.path.join(src_base, aux) + '/' src_path = '/' + items[1] if items[0] == '/': src_delta = 0 else: src_delta = len(items[0]) cmd.append(self.rsyncRemotePath('%s.%s' % (src_base, src_path), use_mode=['ssh'], quote='')) cmd.append('%s/' % restore_to) proc = tools.Execute(cmd, callback=callback, filters=(self.filterRsyncProgress,), parent=self) self.restoreCallback(callback, True, proc.printable_cmd) proc.run() self.restoreCallback(callback, True, ' ') restored_paths.append((path, src_delta)) try: os.remove(self.config.takeSnapshotProgressFile()) except Exception as e: logger.debug('Failed to remove snapshot progress file %s: %s' %(self.config.takeSnapshotProgressFile(), str(e)), self) #restore permissions logger.info('Restore permissions', self) self.restoreCallback(callback, True, ' ') self.restoreCallback( callback, True, '{}:'.format(_('Restore permissions'))) self.restorePermissionFailed = False fileInfoDict = sid.fileInfo #cache uids/gids for uid, name in info.listValue('user', ('int:uid', 'str:name')): self.uid(name.encode(), callback = callback, backup = uid) for gid, name in info.listValue('group', ('int:gid', 'str:name')): self.gid(name.encode(), callback = callback, backup = gid) if fileInfoDict: all_dirs = [] #restore dir permissions after all files are done for path, src_delta in restored_paths: #explore items snapshot_path_to = sid.pathBackup(path).rstrip('/') root_snapshot_path_to = sid.pathBackup().rstrip('/') #use bytes instead of string from here if isinstance(path, str): path = path.encode() if isinstance(restore_to, str): restore_to = restore_to.encode() if not restore_to: path_items = path.strip(b'/').split(b'/') curr_path = b'/' for path_item in path_items: curr_path = os.path.join(curr_path, path_item) if curr_path not in all_dirs: all_dirs.append(curr_path) else: if path not in all_dirs: all_dirs.append(path) if os.path.isdir(snapshot_path_to) and not os.path.islink(snapshot_path_to): head = len(root_snapshot_path_to.encode()) for explore_path, dirs, files in os.walk(snapshot_path_to.encode()): for item in dirs: item_path = os.path.join(explore_path, item)[head:] if item_path not in all_dirs: all_dirs.append(item_path) for item in files: item_path = os.path.join(explore_path, item)[head:] real_path = restore_to + item_path[src_delta:] self.restorePermission(item_path, real_path, fileInfoDict, callback) all_dirs.reverse() for item_path in all_dirs: real_path = restore_to + item_path[src_delta:] self.restorePermission(item_path, real_path, fileInfoDict, callback) self.restoreCallback(callback, True, '') if self.restorePermissionFailed: # TODO # This string might appear in a message dialog. # Let us know the steps to reproduce that behavior. status = _('FAILED') else: # TODO # This string might appear in a message dialog. # Let us know the steps to reproduce that behavior. status = _('Done') self.restoreCallback( callback, True, '{}: {}'.format(_('Restore permissions'), status) ) instance.exitApplication() def backupSuffix(self): """ Get suffix for backup files. Returns: str: backup suffix in form of '.backup.YYYYMMDD' """ return '.backup.' + datetime.date.today().strftime('%Y%m%d') def remove(self, sid): """ Remove snapshot ``sid``. BUHTZ 2022-10-11: From my understanding rsync is used here to sync the directory of a concrete snapshot (``sid``) against an empty temporary directory. In the consequence the sid directory is empty but not deleted. To delete that directory simple `rm` call (via `shutil` package) is used to delete the directory. No need to do this via SSH because the directory is temporary mounted. It is not clear for me why it is done that way. Why not simply "rm" the directory when it is mounted instead of using rsync in a previous step?! But I won't change it yet. Args: sid (SID): snapshot to remove Returns: (bool): ``True`` if succeeded otherwise ``False``. """ if isinstance(sid, RootSnapshot): return # build the rsync command and it's arguments rsync = tools.rsyncRemove(self.config) # an empty temporary directory # e.g. /tmp/tmp8g59onuz with TemporaryDirectory() as d: # the temp dir rsync.append(d + os.sep) # the real remote path of a concrete snapshot (a "sid") # e.g. user@myserver:"/MyBackup/.backintime/backintime/HOST/user/ \ # MyProfile/20221005-000003-880" rsync.append( self.rsyncRemotePath( sid.path(use_mode=['ssh', 'ssh_encfs']), # No quoting because of new argument protection of rsync. quote='' ) ) # Syncing the empty tmp directory against the sid directory # will clear the sid directory. rc = tools.Execute(rsync).run() # if rc != 0: logger.error( f'Last rsync command failed with return code "{rc}". ' 'See previous WARNING message in the logs for details.') return False # Delete the sid dir. BUT here isn't the remote path used but the # temporary mounted variant of it. # e.g. /home/user/.local/share/backintime/mnt/4_8030/backintime/ \ # HOST/user/MyProfile/20221005-000003-880 shutil.rmtree(sid.path()) return True # TODO Refactor: This functions is extremely difficult to understand: # - Nested "if"s # - Fuzzy names of classes, attributes and methods # - unclear variable names (at least for the return values) def backup(self, force=False): """Wrapper for :py:func:`takeSnapshot` which will prepare and clean up things for the main :py:func:`takeSnapshot` method. This will check that no other snapshots are running at the same time, there is nothing prohibiting a new snapshot (e.g. on battery) and the profile is configured correctly. This will also mount and unmount remote destinations. Args: force (bool): Force taking a new snapshot even if the profile is not scheduled or the machine is running on battery. Returns: bool: ``True`` if there was an error. """ ret_val, ret_error = False, True sleep = True self.config.PLUGIN_MANAGER.load(self) if not self.config.isConfigured(): logger.warning('Not configured', self) # not configured self.config.PLUGIN_MANAGER.error(1) elif (not force and self.config.noSnapshotOnBattery() and tools.onBattery()): self.setTakeSnapshotMessage( 0, _('Deferring backup while on battery')) logger.info('Deferring backup while on battery', self) logger.warning('Backup not performed', self) ret_error = False elif not force and not self.config.backupScheduled(): logger.info(f'Profile "{self.config.profileName()}" is not ' 'scheduled to run now.', self) ret_error = False else: instance = ApplicationInstance( self.config.takeSnapshotInstanceFile(), False, flock=True ) restore_instance = ApplicationInstance( self.config.restoreInstanceFile(), False ) if not instance.check(): logger.warning( 'A backup is already running. The pid of the already ' f'running backup is in file {instance.pidFile}. Maybe ' 'delete it.', self) # a backup is already running self.config.PLUGIN_MANAGER.error(2) elif not restore_instance.check(): logger.warning( 'Restore is still running. Stop backup until restore is ' 'done. The pid of the already running restore is in ' f'{restore_instance.pidFile}. Maybe delete it.', self) else: if (self.config.noSnapshotOnBattery() and not tools.powerStatusAvailable()): logger.warning('Backups disabled on battery but power ' 'status is not available', self) instance.startApplication() # Global flock to block backups from other profiles or users # (and run them serialized). The argument "disabled" is a # workaround (#1751) that should be removed/refactored after # this method ("backup()") is refactored. with flock.GlobalFlock(disable=not self.config.globalFlock()): logger.info('Lock', self) now = datetime.datetime.today() # inhibit suspend/hibernate during snapshot is running self.config.inhibitCookie = tools.inhibitSuspend( toplevel_xid=self.config.xWindowId) # mount try: hash_id = mount.Mount(cfg=self.config).mount() except MountException as ex: logger.error(str(ex), self) instance.exitApplication() logger.info('Unlock', self) time.sleep(2) return True else: self.config.setCurrentHashId(hash_id) include_folders = self.config.include() if not include_folders: logger.info('Nothing to do', self) elif not self.config.PLUGIN_MANAGER.processBegin(): logger.info('A plugin prevented the backup', self) else: # take snapshot process begin self.setTakeSnapshotMessage(0, '…') self.snapshotLog.new(now) profile_id = self.config.currentProfile() profile_name = self.config.profileName() logger.info(f"Take a new snapshot. Profile: {profile_id} " f"{profile_name}", self) if not self.config.canBackup(profile_id): if (self.config.PLUGIN_MANAGER.hasGuiPlugins and self.config.notify()): message = ( _("Can't find snapshots directory.") + '\n' + self.config.snapshotsFullPath(profile_id) + '\n' + _('If it is on a removable drive ' 'please plug it in.') + '\n' + gettext.ngettext('Waiting %s second.', 'Waiting %s seconds.', 30) % 30 ) self.setTakeSnapshotMessage( type_id=1, message=message, timeout=30) logger.warning( 'Cannot start snapshot yet: target directory ' 'not accessible. Will retry each second in ' 'the next 30 seconds. Please wait.') for _idx in range(30): time.sleep(1) if self.config.canBackup(): break if not self.config.canBackup(profile_id): logger.error('Snapshots directory not ' 'accessible. Tries stopped.', self) # Can't find snapshots directory (is it on a # removable drive ?) self.config.PLUGIN_MANAGER.error(3) else: ret_error = False sid = SID(now, self.config) if sid.exists(): logger.warning( f'Snapshot directory "{sid.path()}" ' 'already exists', self) # This snapshot already exists self.config.PLUGIN_MANAGER.error(4, sid) else: try: # TODO # rename ret_val to new_snapshot_created # and ret_error to has_error for clearer # code ret_val, ret_error = self.takeSnapshot( sid, now, include_folders) except: # TODO too broad exception new = NewSnapshot(self.config) if new.exists(): new.saveToContinue = False new.failed = True raise if not ret_val: self.remove(sid) if ret_error: logger.error( 'Failed to take snapshot.', self) msg = _('Failed to take snapshot ' '{snapshot_id}.').format( snapshot_id=sid.displayID) self.setTakeSnapshotMessage(1, msg) # Fixes #1491 self.config.PLUGIN_MANAGER.error(5, msg) time.sleep(2) else: logger.warning("No new snapshot", self) else: # new snapshot taken... if ret_error: logger.error('New snapshot taken but ' 'errors detected', self) # Fixes #1491 self.config.PLUGIN_MANAGER.error( 6, sid.displayID) # Why ignore errors now? ret_error = False # Probably because a new snapshot has been # created (= changes transferred) and # "continue on errors" is enabled if not ret_error: # Start auto- and smart-remove self.freeSpace(now) self.setTakeSnapshotMessage( 0, _('Please be patient. Finalizing…')) time.sleep(2) sleep = False if ret_val: # new snapshot self.config.PLUGIN_MANAGER.newSnapshot( sid, sid.path()) # Take snapshot process end self.config.PLUGIN_MANAGER.processEnd() if sleep: time.sleep(2) sleep = False # unmount try: mount.Mount(cfg=self.config) \ .umount(self.config.current_hash_id) except MountException as ex: logger.error(str(ex), self) if not ret_error: self.clearTakeSnapshotMessage() instance.exitApplication() logger.info('Unlock', self) # --- END GlobalFlock context --- if sleep: # max 1 backup / second time.sleep(2) # release inhibit suspend if self.config.inhibitCookie: self.config.inhibitCookie = tools.unInhibitSuspend( *self.config.inhibitCookie) return ret_error def filterRsyncProgress(self, line): """ Filter rsync's stdout for progress information and store them in '~/.local/share/backintime/worker.progress' file. Args: line (str): stdout line from rsync Returns: str: ``line`` if it had no progress infos. ``None`` if ``line`` was a progress """ ret = [] for l in line.split('\n'): m = self.reRsyncProgress.match(l) if m: # if m.group(5).strip(): # return pg = progress.ProgressFile(self.config) pg.setIntValue('status', pg.RSYNC) pg.setStrValue('sent', m.group(1)) pg.setIntValue('percent', int(m.group(2))) pg.setStrValue('speed', m.group(3)) #pg.setStrValue('eta', m.group(4)) pg.save() del pg else: ret.append(l) return '\n'.join(ret) def rsyncCallback(self, line, params): """ Parse rsync's stdout, send it to takeSnapshotMessage and takeSnapshotLog. Also check if there has been changes or errors in current rsync. Args: line (str): stdout line from rsync params (list): list of two bool '[error, changes]'. Uses a side effect by changing list items here to change the original list of the caller, too (lists are passed as reference in Python). If rsync reported an error ``params[0]`` will be set to ``True``. If rsync reported a changed file ``params[1]`` will be set to ``True`` """ if not line: return # Warning (2023-11): Do not modify the source string. # See #1559 for details. self.setTakeSnapshotMessage( 0, _('Take snapshot') + " (rsync: %s)" % line) # Did rsync report an error? if line.endswith(')'): if line.startswith('rsync:'): if not line.startswith('rsync: chgrp ') and not line.startswith('rsync: chown '): # matches rsync error lines like: # rsync: [generator] link [...] failed: Invalid cross-device link (18) params[0] = True self.setTakeSnapshotMessage(1, 'Error: ' + line) if len(line) >= 13: # The prefix is created by rsync via the argument "--out-format=BACKINTIME: %i %n%L" if line.startswith('BACKINTIME: '): if line[12] != '.' and line[12:14] != 'cd': params[1] = True self.snapshotLog.append('[C] ' + line[12:], 2) def makeDirs(self, path): """ Wrapper for :py:func:`tools.makeDirs()`. Create directories ``path`` recursive and return success. If not successful send error-message to log. Args: path (str): fullpath to directories that should be created Returns: bool: ``True`` if successful """ if not tools.makeDirs(path): logger.error(f"Can't create directory: {path}", self) self.setTakeSnapshotMessage( 1, '{}: {}'.format( _("Can't create directory."), path) ) time.sleep(2) # max 1 backup / second return False return True def backupConfig(self, sid): """ Backup the config file to the snapshot and to the backup root if backup is encrypted. Args: sid (SID): snapshot in which the config should be stored """ logger.info('Save config file', self) self.setTakeSnapshotMessage(0, _('Saving config file…')) with open(self.config._LOCAL_CONFIG_PATH, 'rb') as src: with open(sid.path('config'), 'wb') as dst1: dst1.write(src.read()) if self.config.snapshotsMode() == 'local_encfs': src.seek(0) dst2_path = os.path.join( self.config.localEncfsPath(), 'config' ) with open(dst2_path, 'wb') as dst2: dst2.write(src.read()) elif self.config.snapshotsMode() == 'ssh_encfs': cmd = tools.rsyncPrefix(self.config, no_perms=False) cmd.append(self.config._LOCAL_CONFIG_PATH) remote_path = self.rsyncRemotePath( self.config.sshSnapshotsPath(), # no quoting because of rsync modern argument # protection (argument -s) quote='' ) cmd.append(remote_path) proc = tools.Execute(cmd, parent=self) rc = proc.run() # WORKAROUND # tools.Execute only create warnings if 'cmd' fails. # But we need a real ERROR here. if rc != 0: logger.error( f'Backing up the config in "{self.config.snapshotsMode()}"' f' mode failed! The return code was {rc} and the' f' command was {cmd}. Also see the previous ' 'WARNING message for a more details.', parent=self) def _backup_info_file(self, sid): """ Save infos about the snapshot into the 'info' file. The result is stored in 'sid.info' also. Args: sid (SID): Snapshot that should get the info file. """ logger.debug( f'Create info file for snapshot "{sid.displayName}".', self) machine = self.config.host() user = getpass.getuser() profile_id = self.config.currentProfile() i = configfile.ConfigFile() i.setStrValue('snapshot_date', sid.withoutTag) i.setStrValue('snapshot_machine', machine) i.setStrValue('snapshot_user', user) i.setIntValue('snapshot_profile_id', profile_id) i.setIntValue('snapshot_tag', sid.tag) i.setListValue( 'user', ('int:uid', 'str:name'), list(self.userCache.items())) i.setListValue( 'group', ('int:gid', 'str:name'), list(self.groupCache.items())) sid.info = i def backupPermissions(self, sid): """ Save permissions (owner, group, read-, write- and executable) for all files in Snapshot ``sid`` into snapshots fileInfoDict. Args: sid (SID): snapshot that should be scanned Returns: int: Return code of rsync. """ logger.info('Save permissions', self) self.setTakeSnapshotMessage(0, _('Saving permissions…')) fileInfoDict = FileInfoDict() if self.config.snapshotsMode() == 'ssh_encfs': decode = encfstools.Decode(self.config, False) else: decode = encfstools.Bounce() # backup permissions of / # bugfix for https://github.com/bit-team/backintime/issues/708 self.backupPermissionsCallback(b'/', (fileInfoDict, decode)) rsync = ['rsync', '--dry-run', '-s', '-r', '--out-format=%n'] rsync.extend(tools.rsyncSshArgs(self.config)) rsync.append( self.rsyncRemotePath( path=sid.pathBackup( use_mode=['ssh', 'ssh_encfs'] ), quote='' ) + os.sep ) with TemporaryDirectory() as d: rsync.append(d + os.sep) proc = tools.Execute(rsync, callback=self.backupPermissionsCallback, user_data=(fileInfoDict, decode), parent=self, conv_str=False, join_stderr=False) rc = proc.run() sid.fileInfo = fileInfoDict return rc def backupPermissionsCallback(self, line, user_data): """ Rsync callback for :py:func:`Snapshots.backupPermissions`. Args: line(bytes): output from rsync command user_data (tuple): two item tuple of (:py:class:`FileInfoDict`, :py:class:`encfstools.Decode`) """ fileInfoDict, decode = user_data self.collectPermission(fileInfoDict, b'/' + decode.path(line).rstrip(b'/')) def collectPermission(self, fileinfo, path): """ Collect permission infos about ``path`` and store them into ``fileinfo``. Args: fileinfo (FileInfoDict): dict of: {path: (permission, user, group)} Using sideefect on changing dict item will change original dict, too. path (bytes): Full path to file or directory. """ assert isinstance(path, bytes), 'path is not bytes type: %s' % path if path and os.path.exists(path): info = os.stat(path) mode = info.st_mode user = self.userName(info.st_uid).encode('utf-8', 'replace') group = self.groupName(info.st_gid).encode('utf-8', 'replace') fileinfo[path] = (mode, user, group) def takeSnapshot(self, sid, now, include_folders): """This is the main backup routine. It will take a new snapshot and store permissions of included files and folders into ``fileinfo.bz2``. Args: sid (SID): snapshot ID which the new snapshot should get now (datetime.datetime): date and time when this snapshot was started include_folders (list): folders to include. list of tuples (item, int) where ``int`` is 0 if ``item`` is a folder or 1 if ``item`` is a file Returns: list: list of two bool (``ret_val``, ``ret_error``) where ``ret_val`` is ``True`` if a new snapshot has been created and ``ret_error`` is ``True`` if there was an error during taking the snapshot """ self.setTakeSnapshotMessage(0, '...') new_snapshot = NewSnapshot(self.config) encode = self.config.ENCODE # "return" values set during async rsync execution (as user data "by ref") params = [False, False] # [error, changes] # TODO # docstring of return value for this function swaps the meaning of the # elements, this is confusing (``ret_val``, ``ret_error``) and # error-prone. Use a mutable data structure with named elements # instead, e.g. a DataClass if new_snapshot.exists() and new_snapshot.saveToContinue: logger.info(f"Found leftover snapshot '{new_snapshot.displayID}' " "that can be continued.", self) # TODO # Not sure but {snapshot_id} is always "new_snapshot", isn't it? # Might make no sense to put that name in that string. self.setTakeSnapshotMessage( 0, _('Found leftover snapshot {snapshot_id} ' 'that can be continued.') .format(snapshot_id=new_snapshot.displayID) ) # fix permissions for file in os.listdir(new_snapshot.path()): file = os.path.join(new_snapshot.path(), file) mode = os.stat(file).st_mode try: os.chmod(file, mode | stat.S_IWUSR) except PermissionError: pass # search previous log for changes and set params params[1] = new_snapshot.hasChanges elif new_snapshot.exists() and not new_snapshot.saveToContinue: logger.info(f'Removing leftover snapshot {new_snapshot.displayID} ' 'directory from last run') self.setTakeSnapshotMessage( 0, _('Removing leftover {snapshot_id} directory from last run') .format(snapshot_id=new_snapshot.displayID) ) self.remove(new_snapshot) if os.path.exists(new_snapshot.path()): logger.error( f"Can't remove directory: {new_snapshot.path()}", self) self.setTakeSnapshotMessage( 1, '{}: {}'.format(_("Can't remove directory"), new_snapshot.path()) ) time.sleep(2) # max 1 backup / second return [False, True] if not new_snapshot.saveToContinue and not new_snapshot.makeDirs(): return [False, True] prev_sid = None snapshots = listSnapshots(self.config) if snapshots: prev_sid = snapshots[0] # rsync prefix & suffix rsync_prefix = tools.rsyncPrefix(self.config, no_perms=False) if self.config.excludeBySizeEnabled(): rsync_prefix.append('--max-size=%sM' % self.config.excludeBySize()) rsync_suffix = self.rsyncSuffix(include_folders) # When there is no snapshots it takes the last snapshot from the other folders # It should delete the excluded folders then rsync_prefix.extend(('--delete', '--delete-excluded')) rsync_prefix.append('-v') # Use a fixed logging format for the rsync "changed files" list to # make it parsable e.g. in rsyncCallback() # %i = itemized list (11 characters) of what is being updated # (see "--itemize-changes" in "man rsync") # %n = the filename (short form; trailing "/" on dir) # %L = the string " -> SYMLINK", " => HARDLINK", or "" # (where SYMLINK or HARDLINK is a filename) # (see log format section in "man rsyncd.conf") rsync_prefix.extend(('-i', '--out-format=BACKINTIME: %i %n%L')) if prev_sid: link_dest = encode.path(os.path.join(prev_sid.sid, 'backup')) link_dest = os.path.join(os.pardir, os.pardir, link_dest) rsync_prefix.append('--link-dest=%s' % link_dest) # sync changed folders logger.info("Call rsync to take the snapshot", self) new_snapshot.saveToContinue = True cmd = rsync_prefix + rsync_suffix # No quoting (quote='') because of new argument protection of rsync. cmd.append(self.rsyncRemotePath( new_snapshot.pathBackup(use_mode=['ssh', 'ssh_encfs']), quote='')) self.setTakeSnapshotMessage(0, _('Taking snapshot')) # run rsync proc = tools.Execute(cmd, # TODO # interprets the user_data in params as: list of # two bool [error, changes] but params is reused # as return value of this function with [changes, # error]. Use a separate variable to avoid # confusion! callback=self.rsyncCallback, user_data=params, filters=(self.filterRsyncProgress,), parent=self) # TODO # introduce centralized log msg builder to avoid spread severity level # indicators like "[I]" here? self.snapshotLog.append('[I] ' + proc.printable_cmd, 3) # TODO # Process return value with rsync exit code to recognize errors that # cannot be recognized by parsing the rsync output currently rsync_exit_code = proc.run() # Fix for #1491 and #489 # Note that the return value (containing the exit code) of the # rsync child process is not the only way to detect errors (and # sometimes not reliably delivers <> 0 in case of an error): # Errors are also indicated via the pass-by-ref argument # user_data="params" list (updated by the callback function that # parses the rsync output for error message patterns). # cleanup try: os.remove(self.config.takeSnapshotProgressFile()) except Exception as e: logger.debug('Failed to remove snapshot progress file %s: %s' % (self.config.takeSnapshotProgressFile(), str(e)), self) # handle errors # TODO # Fix inconsistent usage: Collects return value, but errors are also # checked via params[0] has_errors = False # dict of exit codes (as keys) that are treated as INFO only by BiT # (not as ERROR). The values are message strings for the snapshot log. rsync_non_error_exit_codes = { 0: _("Success"), # ignored as fix for #1587 (until we introduce a new snapshot # result category "(with warnings)") 23: _("Partial transfer due to error"), 24: _("Partial transfer due to vanished source files " "(see 'man rsync')") } rsync_exit_code_msg = _("'rsync' ended with exit code {exit_code}") \ .format(exit_code=rsync_exit_code) if rsync_exit_code in rsync_non_error_exit_codes: self.setTakeSnapshotMessage( 0, rsync_exit_code_msg + ": " + rsync_non_error_exit_codes[rsync_exit_code]) elif rsync_exit_code > 0: # an rsync error # HACK to fix #489 (params[0] and has_errors should be merged) params[0] = True self.setTakeSnapshotMessage( 1, rsync_exit_code_msg + ": " + _("See 'man rsync' for more details")) elif rsync_exit_code < 0: # an rsync error caused by a signal # HACK to fix #489 (params[0] and has_errors should be merged) params[0] = True self.setTakeSnapshotMessage( 1, rsync_exit_code_msg + ": " + _("Negative rsync exit codes are signal numbers, see " "'kill -l' and 'man kill'")) # params[0] -> error? if params[0]: if not self.config.continueOnErrors(): self.remove(new_snapshot) return [False, True] has_errors = True new_snapshot.failed = True # params[1] -> changes? if not params[1] and not self.config.takeSnapshotRegardlessOfChanges(): self.remove(new_snapshot) logger.info("Nothing changed, no new snapshot necessary", self) self.snapshotLog.append( '[I] ' + _('Nothing changed, no new snapshot necessary'), 3) if prev_sid: prev_sid.setLastChecked() if not has_errors: tools.writeTimeStamp(self.config.anacronSpoolFile()) # Part of fix for #1491: # Returns "has_errors" instead of False now to signal rsync errors # (which may have prevented processing any changes) return [False, has_errors] self.backupConfig(new_snapshot) self.backupPermissions(new_snapshot) # copy snapshot log try: self.snapshotLog.flush() with open(self.snapshotLog.logFileName, 'rb') as logfile: new_snapshot.setLog(logfile.read()) except Exception as e: logger.debug('Failed to write takeSnapshot log %s into ' 'compressed file %s: %s' % ( self.config.takeSnapshotLogFile(), new_snapshot.path(SID.LOG), str(e)), self) # TODO How is this error handled? Currently it looks like it is # ignored (just logged)! new_snapshot.saveToContinue = False # rename snapshot os.rename(new_snapshot.path(), sid.path()) if not sid.exists(): logger.error( f"Can't rename {new_snapshot.path()} to {sid.path()}", self) self.setTakeSnapshotMessage( 1, _('Unable to rename {new_path} to {path}.') .format(new_path=new_snapshot.path(), path=sid.path()) ) time.sleep(2) # max 1 backup / second return [False, True] self._backup_info_file(sid) if not has_errors: tools.writeTimeStamp(self.config.anacronSpoolFile()) # create last_snapshot symlink self.createLastSnapshotSymlink(sid) return [True, has_errors] def smartRemoveKeepAll(self, snapshots: list[SID], min_date: datetime.date, max_date: datetime.date) -> set[SID]: """ Return all snapshots in the timedelta beginning with ``min_date`` and ending before ``max_date``. Args: snapshots (list): Full list of :py:class:`SID` objects. min_date (datetime.date): Minimum date (included in the range). max_date (datetime.date): Maximum date (excluded from the range). Returns: set: Set of snapshots that should be kept. """ logger.debug(f'Keep all >= {min_date} < {max_date}', self) result = filter(lambda sid: sid.date.date() >= min_date and sid.date.date() < max_date, snapshots) return set(result) def smartRemoveKeepFirst(self, snapshots, min_date, max_date, keep_healthy=False): """Return the first snapshot between ``min_date`` and ``max_date``. The first snapshot in ``snapshots`` that hit the timedetla beginning with ``min_date`` and ending before ``max_date`` will be returned. Snapshots outthat that range are also lost. The list is not ordered by date. Args: snapshots (list): Full list of :py:class:`SID` objects. min_date (datetime.date): Minimum date (included in the range). max_date (datetime.date): Maximum date (excluded from the range). keep_healthy (bool): Return the first healthy snapshot (not marked as failed) instead of the first at all. If all snapshots failed this will again return the very first snapshot. Returns: set: Set of one snapshot that should be kept or an empty set. TODO: It should compare datest not SIDs because of their tag. """ logger.debug('Keep first >= {} and < {}'.format( min_date.strftime('%c'), max_date.strftime('%c')), self) for sid in snapshots: # try to keep the first healthy snapshot if keep_healthy and sid.failed: logger.debug(f'Do not keep failed snapshot {sid}', self) continue if sid.date.date() >= min_date and sid.date.date() < max_date: return set([sid]) # if all snapshots failed return the first snapshot # no matter if it has errors if keep_healthy: return self.smartRemoveKeepFirst(snapshots, min_date, max_date, keep_healthy=False) return set() def incMonth(self, date): """ First day of next month of ``date`` with respect on new years. So if ``date`` is December this will return 1st of January next year. Args: date (datetime.date): old date that should be increased Returns: datetime.date: 1st day of next month """ # Last day in current month last = datetime.date( year=date.year, month=date.month, day=calendar.monthrange(date.year, date.month)[1]) return last + datetime.timedelta(days=1) def decMonth(self, date): """ First day of previous month of ``date`` with respect on previous years. So if ``date`` is January this will return 1st of December previous year. Args: date (datetime.date): old date that should be decreased Returns: datetime.date: 1st day of previous month """ # First day of current month first = datetime.date(year=date.year, month=date.month, day=1) # Last day of previous month prev = first - datetime.timedelta(days=1) # First day of previous month return datetime.date(year=prev.year, month=prev.month, day=1) def smartRemoveList(self, now_full, keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month): """Get list of backups to be removed based on configurable intervals. Args: now_full (datetime.datetime): date and time when takeSnapshot was started keep_all (int): keep all snapshots for the last ``keep_all`` days keep_one_per_day (int): keep one snapshot per day for the last ``keep_one_per_day`` days keep_one_per_week (int): keep one snapshot per week for the last ``keep_one_per_week`` weeks keep_one_per_month (int): keep one snapshot per month for the last ``keep_one_per_month`` months Returns: list: snapshots that should be removed """ # Latest/younges backup first, the oldest is last snapshots = listSnapshots(self.config, reverse=True) logger.debug(f'Considered: {snapshots}', self) if len(snapshots) <= 1: logger.debug('There is only one snapshot, so keep it', self) return [] if now_full is None: now_full = datetime.datetime.today() now = now_full.date() # keep the last/youngest backup keep = set([snapshots[0]]) # keep all for the last keep_all days if keep_all > 0: keep |= self.smartRemoveKeepAll( snapshots, now - datetime.timedelta(days=keep_all-1), now + datetime.timedelta(days=1)) # keep one per day for the last keep_one_per_day days if keep_one_per_day > 0: d = now for i in range(0, keep_one_per_day): keep |= self.smartRemoveKeepFirst( snapshots, d, d + datetime.timedelta(days=1), keep_healthy=True) d -= datetime.timedelta(days=1) # keep one per week for the last keep_one_per_week weeks if keep_one_per_week > 0: # Make sure the period always starts on Monday # Step back in time to the last Monday d = now - datetime.timedelta(days=now.weekday()) for i in range(0, keep_one_per_week): keep |= self.smartRemoveKeepFirst( snapshots, # Monday d, # Step one week into the future d + datetime.timedelta(days=7), keep_healthy=True) # One week back in time d -= datetime.timedelta(days=7) # keep one per month for the last keep_one_per_month months if keep_one_per_month > 0: d1 = datetime.date(now.year, now.month, 1) d2 = self.incMonth(d1) for i in range(0, keep_one_per_month): keep |= self.smartRemoveKeepFirst( snapshots, d1, d2, keep_healthy=True) d2 = d1 d1 = self.decMonth(d1) # keep one per year for all years first_year = int(snapshots[-1].sid[:4]) for i in range(first_year, now.year+1): keep |= self.smartRemoveKeepFirst(snapshots, datetime.date(i, 1, 1), datetime.date(i+1, 1, 1), keep_healthy=True) logger.debug(f'Keep snapshots: {keep}', self) del_snapshots = [] for sid in snapshots: if sid in keep: continue if self.config.dontRemoveNamedSnapshots(): if sid.name: logger.debug( f'Keep snapshot: {sid}, because it has a name', self) continue del_snapshots.append(sid) return del_snapshots def smartRemove(self, del_snapshots, log = None): """ Remove multiple snapshots either with :py:func:`Snapshots.remove` or in background on the remote host if mode is `ssh` or `ssh_encfs` and smart-remove in background is activated. Args: del_snapshots (list): list of :py:class:`SID` that should be removed log (method): callable method that will handle progress log """ if not del_snapshots: return if not log: log = lambda x: self.setTakeSnapshotMessage(0, x) if self.config.snapshotsMode() in ['ssh', 'ssh_encfs'] and self.config.smartRemoveRunRemoteInBackground(): logger.info('[smart remove] remove snapshots in background: %s' % del_snapshots, self) lckFile = os.path.normpath( os.path.join( del_snapshots[0].path(use_mode=['ssh', 'ssh_encfs']), os.pardir, 'smartremove.lck' ) ) maxLength = self.config.sshMaxArgLength() if not maxLength: import ssh_max_arg user_host = '%s@%s' % (self.config.sshUser(), self.config.sshHost()) maxLength = ssh_max_arg.probe_max_ssh_command_size(self.config) self.config.setSshMaxArgLength(maxLength) self.config.save() ssh_max_arg.report_result(user_host, maxLength) additionalChars = len(self.config.sshPrefixCmd(cmd_type = str)) head = 'screen -d -m bash -c "(' # create temp dir used for delete files with rsync head += 'TMP=\\$(mktemp -d); ' # make sure $TMP dir was created head += 'test -z \\\"\\$TMP\\\" && exit 1; ' # make sure $TMP is empty head += 'test -n \\\"\\$(ls \\$TMP)\\\" && exit 1; ' if logger.DEBUG: head += 'logger -t \\\"backintime smart-remove [$BASHPID]\\\" \\\"start\\\"; ' head += 'flock -x 9; ' if logger.DEBUG: head += 'logger -t \\\"backintime smart-remove [$BASHPID]\\\" \\\"got exclusive flock\\\"; ' tail = 'rmdir \\$TMP) 9>\\\"%s\\\""' %lckFile cmds = [] for sid in del_snapshots: remote = self.rsyncRemotePath(sid.path(use_mode = ['ssh', 'ssh_encfs']), use_mode = [], quote = '\\\"') rsync = ' '.join(tools.rsyncRemove(self.config, run_local = False)) rsync += ' \\\"\\$TMP/\\\" {}; '.format(remote) s = 'test -e \\\"%s\\\" && (' %sid.path(use_mode = ['ssh', 'ssh_encfs']) if logger.DEBUG: s += 'logger -t \\\"backintime smart-remove [$BASHPID]\\\" ' s += '\\\"snapshot %s still exist\\\"; ' %sid s += 'sleep 1; ' #add one second delay because otherwise you might not see serialized process with small snapshots s += rsync s += 'rmdir \\\"%s\\\"; ' %sid.path(use_mode = ['ssh', 'ssh_encfs']) if logger.DEBUG: s += 'logger -t \\\"backintime smart-remove [$BASHPID]\\\" ' s += '\\\"snapshot %s remove done\\\"' %sid s += '); ' cmds.append(s) for cmd in tools.splitCommands(cmds, head = head, tail = tail, maxLength = maxLength - additionalChars): tools.Execute(self.config.sshCommand([cmd,], quote = False, nice = False, ionice = False)).run() else: logger.info("[smart remove] remove snapshots: %s" %del_snapshots, self) for i, sid in enumerate(del_snapshots, 1): log(_('Smart removal') + ' %s/%s' %(i, len(del_snapshots))) self.remove(sid) def freeSpace(self, now): """Remove old backups based on several rules (if enabled). Rules are considered in the following order: 1. Remove snapshots older than X years. 2. Smart-remove rules with calling :py:func:`smartRemoveList`. See there for details. 3. Remove the oldest backup until there is enough free space. 4. Remove the oldest backup until there are enough free inodes. The 'last_snapshot' symlink will be fixed when done. Args: now (datetime.datetime): Timestamp when takeSnapshot was started. """ # All existing snapshots, ordered from old to new. # e.g. 2025-01-11 to 2025-01-19 snapshots = listSnapshots(self.config, reverse=False) if not snapshots: return logger.debug(f'Backups from {snapshots[0]} to {snapshots[-1]}.', self) last_snapshot = snapshots[-1] # Remove snapshots older than N years/weeks/days if self.config.removeOldSnapshotsEnabled(): self.setTakeSnapshotMessage( 0, _('Apply rules to remove old snapshots')) # The oldest backup to keep. Others older than this are removed. oldSID = SID(self.config.removeOldSnapshotsDate(), self.config) oldBackupId = oldSID.withoutTag logger.debug(f'Remove snapshots older than: {oldBackupId}', self) while True: # Keep min one backup if len(snapshots) <= 1: break # ... younger or same as ... if snapshots[0].withoutTag >= oldBackupId: break if self.config.dontRemoveNamedSnapshots(): if snapshots[0].name: del snapshots[0] continue msg = 'Remove snapshot {} because it is older than {}' logger.debug(msg.format( snapshots[0].withoutTag, oldBackupId), self) self.remove(snapshots[0]) del snapshots[0] # smart remove enabled, keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month = self.config.smartRemove() if enabled: self.setTakeSnapshotMessage(0, _('Apply retention policy')) del_snapshots = self.smartRemoveList(now, keep_all, keep_one_per_day, keep_one_per_week, keep_one_per_month) self.smartRemove(del_snapshots) # Try to keep min free space if self.config.minFreeSpaceEnabled(): self.setTakeSnapshotMessage(0, _('Trying to keep min free space')) minFreeSpace = self.config.minFreeSpaceMib() logger.debug("Keep min free disk space: {} MiB".format(minFreeSpace), self) snapshots = listSnapshots(self.config, reverse=False) while True: if len(snapshots) <= 1: break free_space = self.statFreeSpaceLocal(self.config.snapshotsFullPath()) if free_space is None: free_space = self.statFreeSpaceSsh() if free_space is None: logger.warning('Failed to get free space. Skipping', self) break if free_space >= minFreeSpace: break if self.config.dontRemoveNamedSnapshots(): if snapshots[0].name: del snapshots[0] continue msg = "free disk space: {} MiB. Remove snapshot {}" logger.debug(msg.format(free_space, snapshots[0].withoutTag), self) self.remove(snapshots[0]) del snapshots[0] # Try to keep free inodes if self.config.minFreeInodesEnabled(): minFreeInodes = self.config.minFreeInodes() self.setTakeSnapshotMessage( 0, _('Trying to keep min {perc} free inodes') .format(perc=f'{minFreeInodes}%') ) logger.debug( "Keep min {perc}% free inodes".format(perc=minFreeInodes), self) snapshots = listSnapshots(self.config, reverse = False) while True: if len(snapshots) <= 1: break try: info = os.statvfs(self.config.snapshotsPath()) free_inodes = info.f_favail max_inodes = info.f_files except Exception as e: logger.debug('Failed to get free inodes for snapshot path %s: %s' % (self.config.snapshotsPath(), str(e)), self) break if free_inodes >= max_inodes * (minFreeInodes / 100.0): break if self.config.dontRemoveNamedSnapshots(): if snapshots[0].name: del snapshots[0] continue logger.debug("free inodes: %.2f%%. Remove snapshot %s" %((100.0 / max_inodes * free_inodes), snapshots[0].withoutTag), self) self.remove(snapshots[0]) del snapshots[0] # Set correct last snapshot again if last_snapshot is not snapshots[-1]: self.createLastSnapshotSymlink(snapshots[-1]) def statFreeSpaceLocal(self, path): """ Get free space on filesystem containing ``path`` in MiB using :py:func:`os.statvfs()`. Depending on remote SFTP server this might fail on sshfs mounted shares. Args: path (str): full path Returns: int free space in MiB """ try: info = os.statvfs(path) if info.f_blocks != info.f_bavail: return info.f_frsize * info.f_bavail // (1024 * 1024) except Exception as e: logger.debug('Failed to get free space for %s: %s' %(path, str(e)), self) logger.warning('Failed to stat snapshot path', self) def statFreeSpaceSsh(self): """ Get free space on remote filesystem in MiB. This will call ``df`` on remote host and parse its output. Returns: int free space in MiB """ if self.config.snapshotsMode() not in ('ssh', 'ssh_encfs'): return None snapshots_path_ssh = self.config.sshSnapshotsFullPath() if not len(snapshots_path_ssh): snapshots_path_ssh = './' cmd = self.config.sshCommand(['df', snapshots_path_ssh], nice=False, ionice=False) df = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = df.communicate()[0] # Filesystem 1K-blocks Used Available Use% Mounted on # /tmp 127266564 115596412 5182296 96% / # ^^^^^^^ for line in output.split(b'\n'): m = re.match(r'^.*?\s+\d+\s+\d+\s+(\d+)\s+\d+%', line.decode(), re.M) if m: return int(int(m.group(1)) / 1024) logger.warning('Failed to get free space on remote', self) def filter(self, base_sid, base_path, snapshotsList, list_diff_only=False, flag_deep_check=False, list_equal_to=''): """Filter snapshots from ``snapshotsList`` based on whether ``base_path`` file is included and optional if the snapshot is unique or equal to ``list_equal_to``. Args: base_sid (SID): snapshot ID that contained the original file ``base_path`` base_path (str): path to file on root filesystem. snapshotsList (list): List of :py:class:`SID` objects that should be filtered list_diff_only (bool): if ``True`` only return unique snapshots. Which means if a file is exactly the same in different snapshots only the first snapshot will be listed flag_deep_check (bool): use md5sum to check uniqueness of files. More accurate but slow list_equal_to (str): full path to file. If not empty only return snapshots which have exactly the same file as this file Returns: list: filtered list of :py:class:`SID` objects """ snapshotsFiltered = [] base_full_path = base_sid.pathBackup(base_path) if not os.path.lexists(base_full_path): return [] allSnapshotsList = [RootSnapshot(self.config)] allSnapshotsList.extend(snapshotsList) # links if os.path.islink(base_full_path): targets = [] for sid in allSnapshotsList: path = sid.pathBackup(base_path) if os.path.lexists(path) and os.path.islink(path): if list_diff_only: target = os.readlink(path) if target in targets: continue targets.append(target) snapshotsFiltered.append(sid) return snapshotsFiltered # directories if os.path.isdir(base_full_path): for sid in allSnapshotsList: path = sid.pathBackup(base_path) if (os.path.exists(path) and not os.path.islink(path) and os.path.isdir(path)): snapshotsFiltered.append(sid) return snapshotsFiltered # files if not list_diff_only and not list_equal_to: for sid in allSnapshotsList: path = sid.pathBackup(base_path) if (os.path.exists(path) and not os.path.islink(path) and os.path.isfile(path)): snapshotsFiltered.append(sid) return snapshotsFiltered # check for duplicates uniqueness = UniquenessSet( flag_deep_check, follow_symlink=False, list_equal_to=list_equal_to) for sid in allSnapshotsList: path = sid.pathBackup(base_path) if (os.path.exists(path) and not os.path.islink(path) and os.path.isfile(path) and uniqueness.check(path)): snapshotsFiltered.append(sid) return snapshotsFiltered def rsyncRemotePath(self, path, use_mode = ['ssh', 'ssh_encfs'], quote = '"'): """ Format the destination string for rsync depending on which profile is used. Args: path (str): destination path use_mode (list): list of modes in which the result should change to ``user@host:path`` instead of just ``path`` quote (str): use this to quote the path Returns: str: quoted ``path`` like '"/foo"' or if the current mode is using ssh and current mode is in ``use_mode`` a combination of user, host and ``path`` like ''user@host:"/foo"'' """ mode = self.config.snapshotsMode() if mode in ['ssh', 'ssh_encfs'] and mode in use_mode: user = self.config.sshUser() host = tools.escapeIPv6Address(self.config.sshHost()) return '%(u)s@%(h)s:%(q)s%(p)s%(q)s' % {'u': user, 'h': host, 'q': quote, 'p': path} else: return path def deletePath(self, sid, path): """ Delete ``path`` and all files and folder inside in snapshot ``sid``. Args: sid (SID): snapshot ID in which ``path`` should be deleted path (str): path to delete """ def errorHandler(fn, path, excinfo): """ Error handler for :py:func:`deletePath`. This will fix permissions and try again to remove the file. Args: fn (method): callable which failed before path (str): file to delete excinfo: NotImplemented """ dirname = os.path.dirname(path) st = os.stat(dirname) os.chmod(dirname, st.st_mode | stat.S_IWUSR) st = os.stat(path) os.chmod(path, st.st_mode | stat.S_IWUSR) fn(path) full_path = sid.pathBackup(path) dirname = os.path.dirname(full_path) dir_st = os.stat(dirname) os.chmod(dirname, dir_st.st_mode | stat.S_IWUSR) if os.path.isdir(full_path) and not os.path.islink(full_path): shutil.rmtree(full_path, onerror = errorHandler) else: st = os.stat(full_path) os.chmod(full_path, st.st_mode | stat.S_IWUSR) os.remove(full_path) os.chmod(dirname, dir_st.st_mode) def createLastSnapshotSymlink(self, sid): """ Create symlink 'last_snapshot' to snapshot ``sid`` Args: sid (SID): snapshot that should be linked. Returns: bool: ``True`` if successful """ if sid is None: return symlink = self.config.lastSnapshotSymlink() try: if os.path.islink(symlink): if os.path.basename(os.path.realpath(symlink)) == sid.sid: return True os.remove(symlink) if os.path.exists(symlink): logger.error('Could not remove symlink %s' %symlink, self) return False logger.debug('Create symlink %s => %s' %(symlink, sid), self) os.symlink(sid.sid, symlink) return True except Exception as e: logger.error('Failed to create symlink %s: %s' %(symlink, str(e)), self) return False def rsyncSuffix(self, includeFolders=None, excludeFolders=None): """Create suffixes for rsync. Args: includeFolders (list): Folders to include. list of tuples (item, int). Where ``int`` is ``0`` if ``item`` is a folder or ``1`` if ``item`` is a file. excludeFolders (list): List of folders to exclude. Returns: (list): Rsync include and exclude options. """ # Create exclude patterns string rsync_exclude = self.rsyncExclude(excludeFolders) # Create include patterns list rsync_include, rsync_include2 = self.rsyncInclude(includeFolders) encode = self.config.ENCODE ret = ['--chmod=Du+wx'] ret.extend([ '--exclude=' + i for i in ( encode.exclude(self.config.snapshotsPath()), encode.exclude(self.config._LOCAL_DATA_FOLDER), encode.exclude(self.config._MOUNT_ROOT) ) ]) # TODO: fix bug #561: # after rsync_exclude we need to explicitly include files inside # excluded folders, recursive exclude folder-content again and finally # add the rest from rsync_include2 ret.extend(rsync_include) ret.extend(rsync_exclude) ret.extend(rsync_include2) ret.append('--exclude=*') ret.append(encode.chroot) return ret def rsyncExclude(self, excludeFolders=None): """Format exclude list for rsync. See `rsyncInclude()` for more details. Args: excludeFolders (list): List of folders to exclude. Returns: (list): Rsync exclude options. """ items = [] encode = self.config.ENCODE if excludeFolders is None: excludeFolders = self.config.exclude() for exclude in excludeFolders: exclude = encode.exclude(exclude) if exclude is None: continue items.append(f'--exclude={exclude}') return items def rsyncInclude(self, includeFolders=None): """Format include list for rsync. Returns two lists of include strings. First string need to come before exclude, second after exclude. Args: includeFolders (list): Folders to include. List of tuples (item, int) where ``int`` is ``0`` if ``item`` is a folder or ``1`` if ``item`` is a file. Returns: (tuple): Two item tuple with two lists. """ # Include items.. # ...before the exclude items and... before = [] # ...after the exclude items after = [] # Except for EncFS profiles this does nothing encode = self.config.ENCODE if includeFolders is None: includeFolders = self.config.include() for include_folder in includeFolders: folder = include_folder[0] # If / is selected as included folder it should be changed to "" if folder == "/": # folder = "" # because an extra / is added below. # Patch thanks to Martin Hoefling after.append('--include=/') after.append('--include=/**') continue folder = encode.include(folder) # Folder(0) or file(1) if include_folder[1] == 0: after.append('--include={}/**'.format(folder)) else: after.append('--include={}'.format(folder)) folder = os.path.split(folder)[0] while True: if len(folder) <= 1: break before.append('--include={}/'.format(folder)) folder = os.path.split(folder)[0] # buhtz 2024-07-17: # It is not clear to me why here are two lists generated. But I tested # with this include entries: # folder: /home/user/Downloads # file: /home/user/mbox # file: /home/user/notizen # file: /home/user/mylock # folder: /home/user/foo # And this is the result: # # items1=OrderedSet([ # '--include=/home/user/Downloads/', # '--include=/home/user/', # '--include=/home/', # '--include=/home/user/foo/' # ]) # items2=OrderedSet([ # '--include=/home/user/Downloads/**', # '--include=/home/user/mbox', # '--include=/home/user/notizen', # '--include=/home/user/mylock', # '--include=/home/user/foo/**' # ]) return (before, after) class FileInfoDict(dict): """ A :py:class:`dict` that maps a path (as :py:class:`bytes`) to a tuple (:py:class:`int`, :py:class:`bytes`, :py:class:`bytes`). """ def __init__(self): # default permissions for / # only used if fileinfo.bz2 does not contain a value for / # when it was created with version <= 1.1.12 # bugfix for https://github.com/bit-team/backintime/issues/708 self[b'/'] = (16877, b'root', b'root') def __setitem__(self, key, value): assert isinstance(key, bytes), "key '{}' is not bytes instance".format(key) assert isinstance(value, tuple), "value '{}' is not tuple instance".format(value) assert len(value) == 3, "value '{}' does not have 3 items".format(value) assert isinstance(value[0], int), "first value '{}' is not int instance".format(value[0]) assert isinstance(value[1], bytes), "second value '{}' is not bytes instance".format(value[1]) assert isinstance(value[2], bytes), "third value '{}' is not bytes instance".format(value[2]) super(FileInfoDict, self).__setitem__(key, value) class SID: """ Snapshot ID object used to gather all information for a snapshot See :py:class:`Snapshots` to understand the difference. Args: date (:py:class:`str`, :py:class:`datetime.date` or :py:class:`datetime.datetime`): used for creating this snapshot. str must be in snapshot ID format (e.g 20151218-173512-123) cfg (config.Config): current config Raises: ValueError: if ``date`` is :py:class:`str` instance and doesn't match the snapshot ID format (20151218-173512-123 or 20151218-173512) TypeError: if ``date`` is not :py:class:`str`, :py:class:`datetime.date` or :py:class:`datetime.datetime` type """ __cValidSID = re.compile(r'^\d{8}-\d{6}(?:-\d{3})?$') INFO = 'info' NAME = 'name' FAILED = 'failed' FILEINFO = 'fileinfo.bz2' LOG = 'takesnapshot.log.bz2' def __init__(self, date, cfg): self.config = cfg self.profileID = cfg.currentProfile() self.isRoot = False if isinstance(date, datetime.datetime): self.sid = '-'.join((date.strftime('%Y%m%d-%H%M%S'), self.config.tag(self.profileID))) # TODO: Don't use "date" as attribute name. Btw: It is not a date # but a datetime. self.date = date elif isinstance(date, datetime.date): self.sid = '-'.join((date.strftime('%Y%m%d-000000'), self.config.tag(self.profileID))) self.date = datetime.datetime.combine( date, datetime.datetime.min.time()) elif isinstance(date, str): if self.__cValidSID.match(date): self.sid = date self.date = datetime.datetime(*self.split()) elif date == 'last_snapshot': raise LastSnapshotSymlink() else: raise ValueError("'date' must be in snapshot ID format " f"(e.g 20151218-173512-123) but is '{date}'") else: raise TypeError("'date' must be an instance of str, datetime.date " f"or datetime.datetime but is '{date}'") def __repr__(self): return self.sid def __eq__(self, other): """ Compare snapshots based on self.sid Args: other (:py:class:`SID`, :py:class:`str`): an other :py:class:`SID` or str instance Returns: bool: ``True`` if other is equal """ if isinstance(other, SID): return self.sid == other.sid and self.profileID == other.profileID elif isinstance(other, str): return self.sid == other else: return NotImplemented def __ne__(self, other): return not self.__eq__(other) def __lt__(self, other): """ Sort snapshots (alphabetical order) based on self.sid Args: other (:py:class:`SID`, :py:class:`str`): an other :py:class:`SID` or str instance Returns: bool: ``True`` if other is lower """ if isinstance(other, SID): return self.sid < other.sid elif isinstance(other, str) and self.__cValidSID.match(other): return self.sid < other else: return NotImplemented def __le__(self, other): if isinstance(other, SID): return self.sid <= other.sid elif isinstance(other, str) and self.__cValidSID.match(other): return self.sid <= other else: return NotImplemented def __gt__(self, other): if isinstance(other, SID): return self.sid > other.sid elif isinstance(other, str) and self.__cValidSID.match(other): return self.sid > other else: return NotImplemented def __ge__(self, other): if isinstance(other, SID): return self.sid >= other.sid elif isinstance(other, str) and self.__cValidSID.match(other): return self.sid >= other else: return NotImplemented def __hash__(self): return hash(self.sid + self.profileID) def split(self): """ Split self.sid into a tuple of int's with Year, Month, Day, Hour, Minute, Second Returns: tuple: tuple of 6 int """ def split(s, e): return int(self.sid[s:e]) return (split(0, 4), split(4, 6), split(6, 8), split(9, 11), split(11, 13), split(13, 15)) @property def displayID(self): """ Snapshot ID in a user-readable format: YYYY-MM-DD HH:MM:SS Returns: str: formatted sID """ return "{:04}-{:02}-{:02} {:02}:{:02}:{:02}".format(*self.split()) @property def displayName(self): """ Combination of displayID, name and error indicator (if any) Returns: str: name """ ret = self.displayID name = self.name if name: ret += ' - {}'.format(name) if self.failed: ret += ' ({})'.format('WITH ERRORS !') return ret @property def tag(self): """ Snapshot ID's tag Returns: str: tag (last three digits) """ return self.sid[16:] @property def withoutTag(self): """ Snapshot ID without tag Returns: str: YYYYMMDD-HHMMSS """ return self.sid[0:15] def path(self, *path, use_mode = []): """ Current path of this snapshot automatically altered for remote/encrypted version of this path Args: *path (str): one or more folder/files to join at the end of the path. use_mode (list): list of modes that should alter this path. If the current mode is in this list, the path will automatically be altered for the remote/encrypted version of this path. Returns: str: full snapshot path """ path = [i.strip(os.sep) for i in path] current_mode = self.config.snapshotsMode(self.profileID) if 'ssh' in use_mode and current_mode == 'ssh': return os.path.join(self.config.sshSnapshotsFullPath(self.profileID), self.sid, *path) if 'ssh_encfs' in use_mode and current_mode == 'ssh_encfs': ret = os.path.join(self.config.sshSnapshotsFullPath(self.profileID), self.sid, *path) return self.config.ENCODE.remote(ret) return os.path.join(self.config.snapshotsFullPath(self.profileID), self.sid, *path) def pathBackup(self, *path, **kwargs): """ 'backup' folder inside snapshots path Args: *path (str): one or more folder/files to join at the end of the path. use_mode (list): list of modes that should alter this path. If the current mode is in this list, the path will automatically be altered for the remote/encrypted version of this path. Returns: str: full snapshot path """ return self.path('backup', *path, **kwargs) def makeDirs(self, *path): """ Create snapshot directory Args: *path (str): one or more folder/files to join at the end of the path Returns: bool: ``True`` if successful """ if not os.path.isdir(self.config.snapshotsFullPath(self.profileID)): logger.error('Snapshots path {} doesn\'t exist. Unable to make dirs for snapshot ID {}'.format( self.config.snapshotsFullPath(self.profileID), self.sid), self) return False return tools.makeDirs(self.pathBackup(*path)) def exists(self): """ ``True`` if the snapshot folder and the "backup" folder inside exist Returns: bool: ``True`` if exists """ return os.path.isdir(self.path()) and os.path.isdir(self.pathBackup()) def isExistingPathInsideSnapshotFolder(self, path): """ ``True`` if path is a file inside this snapshot Args: path (str): path from local filesystem (no snapshot path) Returns: bool: ``True`` if file exists """ fullPath = self.pathBackup(path) if not os.path.exists(fullPath): return False if not os.path.islink(fullPath): return True basePath = self.pathBackup() target = os.readlink(fullPath) target = os.path.join(os.path.abspath(os.path.dirname(fullPath)), target) return target.startswith(basePath) @property def name(self): """ Name of this snapshot Args: name (str): new name of the snapshot Returns: str: name of this snapshot """ nameFile = self.path(self.NAME) if not os.path.isfile(nameFile): return '' try: with open(nameFile, 'rt') as f: return f.read() except Exception as e: logger.debug('Failed to get snapshot {} name: {}'.format( self.sid, str(e)), self) @name.setter def name(self, name): nameFile = self.path(self.NAME) self.makeWritable() try: with open(nameFile, 'wt') as f: f.write(name) except Exception as e: logger.debug('Failed to set snapshot {} name: {}'.format( self.sid, str(e)), self) @property def lastChecked(self): """ Date when snapshot has finished last time. This can be the end of creation of this snapshot or the last time when this snapshot was checked against source without changes. Returns: str: date and time of last check (YYYY-MM-DD HH:MM:SS) """ info = self.path(self.INFO) if os.path.exists(info): return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(os.path.getatime(info))) return self.displayID # using @property.setter would be confusing here as there is no value to # give def setLastChecked(self): """ Set info files atime to current time to indicate this snapshot was checked against source without changes right now. """ info = self.path(self.INFO) if os.path.exists(info): os.utime(info, None) @property def failed(self): """ This snapshot has failed Args: enable (bool): set or remove flag Returns: bool: ``True`` if flag is set """ failedFile = self.path(self.FAILED) return os.path.isfile(failedFile) @failed.setter def failed(self, enable): failedFile = self.path(self.FAILED) if enable: self.makeWritable() try: with open(failedFile, 'wt') as f: f.write('') except Exception as e: logger.debug('Failed to mark snapshot {} failed: {}'.format( self.sid, str(e)), self) elif os.path.exists(failedFile): os.remove(failedFile) @property def info(self): """ Load/save "info" file which contains additional information about this snapshot (using configfile.ConfigFile) Args: i (configfile.ConfigFile): info that should be saved. Returns: configfile.ConfigFile: snapshots information """ i = configfile.ConfigFile() i.load(self.path(self.INFO)) return i @info.setter def info(self, i): assert isinstance(i, configfile.ConfigFile), 'i is not configfile.ConfigFile type: {}'.format(i) i.save(self.path(self.INFO)) @property def fileInfo(self): """ Load/save "fileinfo.bz2" Args: d (FileInfoDict): dict of: {path: (permission, user, group)} Returns: FileInfoDict: dict of: {path: (permission, user, group)} """ d = FileInfoDict() infoFile = self.path(self.FILEINFO) if not os.path.isfile(infoFile): return d try: with bz2.BZ2File(infoFile, 'rb') as fileinfo: for line in fileinfo: line = line.strip(b'\n') if not line: continue index = line.find(b'/') if index < 0: continue f = line[index:] if not f: continue info = line[:index].strip().split(b' ') if len(info) == 3: d[f] = (int(info[0]), info[1], info[2]) #perms, user, group except (FileNotFoundError, PermissionError) as e: logger.error('Failed to load {} from snapshot {}: {}'.format( self.FILEINFO, self.sid, str(e)), self) return d @fileInfo.setter def fileInfo(self, d): assert isinstance(d, FileInfoDict), 'd is not FileInfoDict type: {}'.format(d) try: with bz2.BZ2File(self.path(self.FILEINFO), 'wb') as f: for path, info in d.items(): f.write(b' '.join((str(info[0]).encode('utf-8', 'replace'), info[1], info[2], path)) + b'\n') except PermissionError as e: logger.error('Failed to write {}: {}'.format(self.FILEINFO, str(e))) # TODO use @property decorator? IMHO not because it is not a "getter" but processes data # TODO Should have an action name like "loadLogFile" def log(self, mode = None, decode = None): """ Load log from "takesnapshot.log.bz2" Args: mode (int): Mode used for filtering. Take a look at :py:class:`snapshotlog.LogFilter` decode (encfstools.Decode): instance used for decoding lines or ``None`` Yields: str: filtered and decoded log lines """ logFile = self.path(self.LOG) logFilter = snapshotlog.LogFilter(mode, decode) try: with bz2.BZ2File(logFile, 'rb') as f: if logFilter.header: yield logFilter.header for line in f.readlines(): line = logFilter.filter(line.decode('utf-8').rstrip('\n')) if not line is None: yield line except Exception as e: msg = ('Failed to get snapshot log from {}:'.format(logFile), str(e)) logger.debug(' '.join(msg), self) for line in msg: yield line def setLog(self, log): """ Write log to "takesnapshot.log.bz2" Args: log: full snapshot log """ if isinstance(log, str): log = log.encode('utf-8', 'replace') logFile = self.path(self.LOG) try: with bz2.BZ2File(logFile, 'wb') as f: f.write(log) except Exception as e: logger.error('Failed to write log into compressed file {}: {}'.format( logFile, str(e)), self) def makeWritable(self): """ Make the snapshot path writable so we can change files inside Returns: bool: ``True`` if successful """ path = self.path() rw = os.stat(path).st_mode | stat.S_IWUSR return os.chmod(path, rw) class GenericNonSnapshot(SID): @property def displayID(self): return self.name @property def displayName(self): return self.name @property def tag(self): return self.name @property def withoutTag(self): return self.name class NewSnapshot(GenericNonSnapshot): """ Snapshot ID object for 'new_snapshot' folder Args: cfg (config.Config): current config """ NEWSNAPSHOT = 'new_snapshot' SAVETOCONTINUE = 'save_to_continue' def __init__(self, cfg): self.config = cfg self.profileID = cfg.currentProfile() self.isRoot = False self.sid = self.NEWSNAPSHOT self.date = datetime.datetime(1, 1, 1) self.__le__ = self.__lt__ self.__ge__ = self.__gt__ def __lt__(self, other): return False def __gt__(self, other): return True @property def name(self): """ Name of this snapshot Returns: str: name of this snapshot """ return self.sid @property def saveToContinue(self): """ Check if 'save_to_continue' flag is set Args: enable (bool): set or remove flag Returns: bool: ``True`` if flag is set """ return os.path.exists(self.path(self.SAVETOCONTINUE)) @saveToContinue.setter def saveToContinue(self, enable): flag = self.path(self.SAVETOCONTINUE) if enable: try: with open(flag, 'wt'): pass except Exception as e: # should be "safe", throughout logger.error( "Failed to set 'save_to_continue' flag: %s" %str(e)) elif os.path.exists(flag): try: os.remove(flag) except Exception as e: # should be "safe", throughout logger.error( "Failed to remove 'save_to_continue' flag: %s" %str(e)) @property def hasChanges(self): """ Check if there where changes in previous sessions. Returns: bool: ``True`` if there where changes """ log = snapshotlog.SnapshotLog(self.config, self.profileID) c = re.compile(r'^\[C\] ') for line in log.get(mode = snapshotlog.LogFilter.CHANGES): if c.match(line): return True return False class RootSnapshot(GenericNonSnapshot): """ Snapshot ID for the filesystem root folder ('/') Args: cfg (config.Config): current config """ def __init__(self, cfg): self.config = cfg self.profileID = cfg.currentProfile() self.isRoot = True self.sid = '/' self.date = datetime.datetime(datetime.MAXYEAR, 12, 31) self.__le__ = self.__lt__ self.__ge__ = self.__gt__ def __lt__(self, other): return False def __gt__(self, other): return True @property def name(self): """ Name of this snapshot Returns: str: name of this snapshot """ return _('Now') def path(self, *path, use_mode = []): """ Current path of this snapshot automatically altered for remote/encrypted version of this path Args: *path (str): one or more folder/files to join at the end of the path. use_mode (list): list of modes that should alter this path. If the current mode is in this list, the path will automatically altered for the remote/encrypted version of this path. Returns: str: full snapshot path """ current_mode = self.config.snapshotsMode(self.profileID) if 'ssh_encfs' in use_mode and current_mode == 'ssh_encfs': if path: path = self.config.ENCODE.remote(os.path.join(*path)) return os.path.join(self.config.ENCODE.chroot, path) else: return os.path.join(os.sep, *path) def iterSnapshots(cfg, includeNewSnapshot=False): """A generator to iterate over snapshots in current snapshot path. Args: cfg (config.Config): Current config instance. includeNewSnapshot (bool): Include a NewSnapshot instance if 'new_snapshot' directory is available (default: False). Yields: SID: Snapshot IDs """ path = cfg.snapshotsFullPath() if not os.path.exists(path): return None for item in os.listdir(path): if item == NewSnapshot.NEWSNAPSHOT: newSid = NewSnapshot(cfg) if newSid.exists() and includeNewSnapshot: yield newSid continue try: sid = SID(item, cfg) if sid.exists(): yield sid # REFACTOR! # LastSnapshotSymlink is an exception instance and could be caught # explicit. But not sure about its purpose. except Exception as e: if not isinstance(e, LastSnapshotSymlink): logger.debug( "'{}' is not a snapshot ID: {}".format(item, str(e))) def listSnapshots(cfg, includeNewSnapshot=False, reverse=True): """ List of snapshots in current snapshot path. Args: cfg (config.Config): Current config instance. includeNewSnapshot (bool): Include a NewSnapshot instance if 'new_snapshot' directory is available (default: False). reverse (bool): Sort reverse (default: True). Returns: list: List of :py:class:`SID` objects. """ ret = list(iterSnapshots(cfg, includeNewSnapshot)) ret.sort(reverse=reverse) return ret def lastSnapshot(cfg): """ Most recent snapshot. Args: cfg (config.Config): current config (config.Config instance) Returns: SID: most recent snapshot ID """ sids = listSnapshots(cfg) if sids: return sids[0] if __name__ == '__main__': config = config.Config() snapshots = Snapshots(config) snapshots.backup() backintime-1.5.4/common/ssh_max_arg.py000066400000000000000000000127551477034762000200100ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-FileCopyrightText: © 2015-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """This module determines the maximum possible length of an SSH command. It can also can run as a stand alone script. The solution is based on https://www.theeggeadventure.com/wikimedia/index.php/Ssh_argument_length """ import random import string import subprocess import socket import argparse from config import Config # Must be divisible by 8 _INITIAL_SSH_CMD_SIZE = 1048320 _ERR_CODE_E2BIG = 7 def probe_max_ssh_command_size( cfg: Config, ssh_command_size: int = _INITIAL_SSH_CMD_SIZE, size_offset: int = _INITIAL_SSH_CMD_SIZE) -> int: """Determine the maximum length of SSH commands for the current config Try a SSH command with length ``ssh_command_size``. The command is decreased by ``size_offset`` if it was too long or increased if it worked. The function calls itself recursively until it finds the maximum possible length. The offset ``size_offset`` is bisect in each try. Args: config: Back In Time config instance including the details about the current SSH snapshot profile. The current profile must use the SSH mode. ssh_command_size: Initial length used for the test argument. size_offset: Offset for increase or decrease ``ssh_command_size``. Returns: The maximum possible SSH command length. Raises: Exception: If there are unhandled cases or the recurse ends in an undefined state. OSError: If there are unhandled cases. """ size_offset = round(size_offset / 2) # random string of desired length command_string = ''.join(random.choices( string.ascii_uppercase+string.digits, k=ssh_command_size)) # use that string in a printf statement via SSH ssh = cfg.sshCommand( cmd=['printf', command_string], nice=False, ionice=False, prefix=False) try: proc = subprocess.run(ssh, capture_output=True, text=True, check=True) out, err = proc.stdout, proc.stderr except OSError as exc: # Only handle "Argument to long error" if exc.errno != _ERR_CODE_E2BIG: raise exc report_test( ssh_command_size, f'Python exception: "{exc.strerror}". Decrease ' f'by {size_offset:,} and try again.') # test again with new ssh_command_size return probe_max_ssh_command_size( cfg, ssh_command_size - size_offset, size_offset) # Successful SSH command if out == command_string: # no increases possible anymore if size_offset == 0: report_test(ssh_command_size, 'Found correct length. Adding ' f'length of "{ssh[-2]}" to it.') # the final command size return ssh_command_size + len(ssh[-2]) # length of "printf" # there is room to increase the length report_test(ssh_command_size, f'Can be longer. Increase by {size_offset:,} ' 'and try again.') # increase by "size_offset" and try again return probe_max_ssh_command_size( cfg, ssh_command_size + size_offset, size_offset) # command string was too long if 'Argument list too long' in err: report_test(ssh_command_size, f'stderr: "{err.strip()}". Decrease ' f'by {size_offset:,} and try again.') # reduce by "size_offset" and try again return probe_max_ssh_command_size( cfg, ssh_command_size - size_offset, size_offset) raise RuntimeError('Unhandled case.\n' f'{ssh[:-1]}\n' f'out="{out}"\nerr="{err}"\n' f'ssh_command_size={ssh_command_size:,}\n' f'size_offset={size_offset:,}') def report_test(ssh_command_size, msg): """Report proceeding test.""" print(f'Tried length {ssh_command_size:,}... {msg}') def report_result(host, max_ssh_cmd_size): """Report test result.""" print(f'Maximum SSH command length between "{socket.gethostname()}" ' f'and "{host}" is {max_ssh_cmd_size:,}.') def main(args): """Entry.""" cfg = Config() # loop over all profiles in the configuration for profile_id in cfg.profiles(): cfg.setCurrentProfile(profile_id) print(f'Profile {profile_id} - {cfg.profileName()}: ' f'Mode = {cfg.snapshotsMode()}') if cfg.snapshotsMode() == 'ssh': ssh_command_size = probe_max_ssh_command_size( cfg, args.SSH_COMMAND_SIZE) report_result(cfg.sshHost(), ssh_command_size) if __name__ == '__main__': parser = argparse.ArgumentParser( description='Check the maximal ssh command size for all ssh profiles ' 'in the configurations', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('SSH_COMMAND_SIZE', type=int, nargs='?', default=_INITIAL_SSH_CMD_SIZE, help='Start checking with SSH_COMMAND_SIZE as length') main(parser.parse_args()) backintime-1.5.4/common/sshtools.py000066400000000000000000001275131477034762000173720ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # SPDX-FileCopyrightText: © 2012-2022 Taylor Raack # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import subprocess import string import random import tempfile import socket import re import atexit import signal from pathlib import Path from time import sleep import logger import tools import password import password_ipc from mount import MountControl from exceptions import MountException, NoPubKeyLogin, KnownHost import bcolors import version class SSH(MountControl): """ This is a backend for the mount API :py:class:`mount.MountControl`. This will mount the remote path with ``sshfs``, prepare the remote path and check that everything is set up correctly for `Back In Time` to run snapshots through SSH. This class will only mount the remote path. The real takeSnapshot process will use rsync over ssh. Other commands run remote over ssh. Args: cfg (config.Config): current config (handled by inherited :py:class:`mount.MountControl`) user (str): User name on remote host host (str): Name or IP Address of remote host port (int): Port used by SSHd on remote host path (str): remote path where snapshots are stored. Can be either relative from remote users homedir or an absolute path cipher (str): Cipher used to encrypt the network transfer private_key_file (str): Private key which is able to log on with Public/Private Key-Method on remote host nice (bool): use ``nice -n 19`` to run commands with low CPU priority on remote host ionice (bool): use ``ionice -c2 -n7`` to run commands with low IO priority on remote host nocache (bool): use ``nocache`` to deactivate RAM caching of files on remote host password (str): password to unlock the private key profile_id (str): profile ID that should be used (handled by inherited :py:class:`mount.MountControl`) hash_id (str): crc32 hash used to identify identical mountpoints (handled by inherited :py:class:`mount.MountControl`) tmp_mount (bool): if ``True`` mount to a temporary destination (handled by inherited :py:class:`mount.MountControl`) parent (QWidget): parent widget for QDialogs or ``None`` if there is no parent (handled by inherited :py:class:`mount.MountControl`) symlink (bool): if ``True`` set symlink to mountpoint (handled by inherited :py:class:`mount.MountControl`) mode (str): one of ``local``, ``local_encfs``, ``ssh`` or ``ssh_encfs`` (handled by inherited :py:class:`mount.MountControl`) hash_collision (int): global value used to prevent hash collisions on mountpoints (handled by inherited :py:class:`mount.MountControl`) Note: All Arguments are optional. Default values will be fetched from :py:class:`config.Config`. But after changing Settings we need to test the new values **before** storing them into :py:class:`config.Config`. This is why all values will be added as arguments. """ def __init__(self, *args, **kwargs): # init MountControl super(SSH, self).__init__(*args, **kwargs) # Workaround for linters self.user = None self.host = None self.port = None self.cipher = None self.proxy_user = None self.proxy_host = None self.proxy_port = None self.nice = None self.ionice = None self.nocache = None self.private_key_file = None self.password = None self.setattrKwargs( 'user', self.config.sshUser(self.profile_id), **kwargs) self.setattrKwargs( 'host', self.config.sshHost(self.profile_id), **kwargs) self.setattrKwargs( 'port', self.config.sshPort(self.profile_id), **kwargs) self.setattrKwargs( 'path', self.config.sshSnapshotsPath(self.profile_id), **kwargs) self.setattrKwargs( 'cipher', self.config.sshCipher(self.profile_id), **kwargs) self.setattrKwargs( 'private_key_file', self.config.sshPrivateKeyFile(self.profile_id), **kwargs) self.setattrKwargs( 'proxy_user', self.config.sshProxyUser(self.profile_id), **kwargs) self.setattrKwargs( 'proxy_host', self.config.sshProxyHost(self.profile_id), **kwargs) self.setattrKwargs( 'proxy_port', self.config.sshProxyPort(self.profile_id), **kwargs) self.setattrKwargs( 'nice', self.config.niceOnRemote(self.profile_id), store=False, **kwargs) self.setattrKwargs( 'ionice', self.config.ioniceOnRemote(self.profile_id), store=False, **kwargs) self.setattrKwargs( 'nocache', self.config.nocacheOnRemote(self.profile_id), store=False, **kwargs) self.setattrKwargs('password', None, store=False, **kwargs) if not self.path: self.path = './' self.setDefaultArgs() # config strings used in ssh-calls self.user_host_path \ = '%s@%s:%s' % (self.user, tools.escapeIPv6Address(self.host), self.path) self.user_host = '%s@%s' % (self.user, self.host) self.mountproc = 'sshfs' self.symlink_subfolder = None self.log_command = '%s: %s' % (self.mode, self.user_host_path) self.private_key_fingerprint = sshKeyFingerprint(self.private_key_file) if not self.private_key_fingerprint: logger.warning('Couldn\'t get fingerprint for private ' 'key %(path)s. ' 'Most likely because the public key %(path)s.pub ' 'wasn\'t found. Using fallback to private keys ' 'path instead. But this can make troubles with ' 'passphrase-less keys.' % {'path': self.private_key_file}, self) self.private_key_fingerprint = self.private_key_file self.unlockSshAgent() def _mount(self): """ Backend mount method. This will call ``sshfs`` to mount the remote path. Raises: exceptions.MountException: if mount wasn't successful """ sshfs = [self.mountproc] sshfs += self.config.sshDefaultArgs(self.profile_id) sshfs += ['-p', str(self.port)] if not self.cipher == 'default': sshfs.extend(['-o', 'Ciphers=%s' % self.cipher]) sshfs.extend(['-o', 'idmap=user', '-o', 'cache_dir_timeout=2', '-o', 'cache_stat_timeout=2']) sshfs.extend([self.user_host_path, self.currentMountpoint]) # bugfix: sshfs doesn't mount if locale in LC_ALL is not available on # remote host # LANG or other environment variable are no problem. env = os.environ.copy() if 'LC_ALL' in list(env.keys()): env['LC_ALL'] = 'C' logger.debug('Call mount command: %s' % ' '.join(sshfs), self) # SSH Proxy (aka Jump host) if self.proxy_host: sshfs.extend([ '-o', 'ssh_command=ssh -J ' f'{self.proxy_user}@{self.proxy_host}:{self.proxy_port}' ]) logger.debug(f'Execute SSHFS command {sshfs}.') proc = subprocess.Popen(sshfs, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, universal_newlines=True) err = proc.communicate()[1] if proc.returncode == 0: return raise MountException( "{}\n\n{}".format( _('Unable to mount {sshfs}').format(sshfs=" ".join(sshfs)), err ) ) def preMountCheck(self, first_run=False): """ Check that everything is prepared and ready for successfully mount the remote path. Default is to run a light version of checks which will only make sure the remote host is online, ``sshfs`` is installed and the remote folder is available. After changing settings this should be run with ``first_run = True`` to run a full check with all tests. Args: first_run (bool): Run a full test with all checks. Raises: exceptions.MountException: If one test failed an we can not mount the remote path. """ # Most of the called methods will raise an exception if something is # wrong. # try to open SSH socket self.checkPingHost() # sshfs (self.mountproc) installed? self.checkFuse() if first_run: self.unlockSshAgent(force=True) self.checkKnownHosts() self.checkLogin() if first_run: self.checkCipher() self.checkRemoteFolder() if first_run: self.checkRemoteCommands() return True def startSshAgent(self): """ Start a new ``ssh-agent`` if it is not already running. Raises: exceptions.MountException: if starting ``ssh-agent`` failed """ SOCK = 'SSH_AUTH_SOCK' PID = 'SSH_AGENT_PID' if os.getenv(SOCK, '') and os.getenv(PID, ''): logger.debug( 'ssh-agent already running. Skip starting a new one.', self) return sshAgent = tools.which('ssh-agent') if not sshAgent: raise MountException( _('ssh-agent not found. Please ensure it is installed.')) if isinstance(sshAgent, str): sshAgent = [sshAgent, ] sa = subprocess.Popen(sshAgent, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out, err = sa.communicate() if sa.returncode: raise MountException( 'Failed to start ssh-agent: [{}] {}' .format(sa.returncode, err)) m = re.match(r'.*{}(?:=|\s)([^;]+);.*{}(?:=|\s)(\d+);' .format(SOCK, PID), out, re.DOTALL | re.MULTILINE) if m: logger.debug('ssh-agent started successful: {}={} | {}={}' .format(SOCK, m.group(1), PID, m.group(2)), self) os.environ[SOCK] = m.group(1) os.environ[PID] = m.group(2) atexit.register(os.kill, int(m.group(2)), signal.SIGKILL) else: raise MountException( 'No matching output from ssh-agent: {} | {}'.format(out, err)) def unlockSshAgent(self, force=False): """ Unlock the private key in ``ssh-agent`` which will provide it for all other commands. The password to unlock the key will be provided by ``backintime-askpass``. Args: force (bool): Force to unlock the key by removing it first and add it again to make sure, the given values are correct. Raises: exceptions.MountException: If unlock failed. """ self.startSshAgent() env = os.environ.copy() env['SSH_ASKPASS'] = 'backintime-askpass' env['ASKPASS_PROFILE_ID'] = self.profile_id env['ASKPASS_MODE'] = self.mode if force: # remove private key first so we can check if the given # password is valid logger.debug( 'Remove private key %s from ssh agent' % self.private_key_file, self) proc = subprocess.Popen(['ssh-add', '-d', self.private_key_file], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, universal_newlines=True) proc.communicate() proc = subprocess.Popen(['ssh-add', '-l'], stdout=subprocess.PIPE, universal_newlines=True) output = proc.communicate()[0] if force or not output.find(self.private_key_fingerprint) >= 0: logger.debug( 'Add private key %s to ssh agent' % self.private_key_file, self) password_available = any([ self.config.passwordSave(self.profile_id), self.config.passwordUseCache(self.profile_id), self.password is not None ]) logger.debug('Password available: %s' % password_available, self) if not password_available and not tools.checkXServer(): # we need to unlink stdin from ssh-add in order to make it # use our own backintime-askpass. # But because of this we can NOT use getpass inside # backintime-askpass if password is not saved and there is no # x-server. # So, let's just keep ssh-add asking for the password in # that case. alarm = tools.Alarm() alarm.start(10) try: proc = subprocess.call(['ssh-add', self.private_key_file]) alarm.stop() except tools.Timeout: pass else: if self.password: logger.debug('Provide password through temp FIFO', self) thread = password_ipc.TempPasswordThread(self.password) env['ASKPASS_TEMP'] = thread.temp_file thread.start() # We need to validate the ssh key password which # `backintime-askpass` will provide before calling # ssh-add below. See Issue #1852. # Validate cached SSH key password: proc = subprocess.run( ['ssh-keygen', '-y', '-f', self.private_key_file], capture_output=True, # Ensure ssh-keygen uses backintime-askpass env=env | {'SSH_ASKPASS_REQUIRE': 'prefer'} ) # if backintime-askpass supplied an invalid cached password if proc.returncode > 0: pw = password.Password() # pw_id = 1 corresponds to the SSH password # (as opposed to the encryption password) # See qt/settingsdialog.py:SettingsDialog.updateProfile() pw.password( None, self.profile_id, self.mode, pw_id=1, refresh=True, ) proc = subprocess.Popen(['ssh-add', self.private_key_file], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, preexec_fn=os.setsid, universal_newlines=True) output, error = proc.communicate() if proc.returncode: logger.error('Failed to unlock SSH private key %s: %s' % (self.private_key_file, error), self) if self.password: thread.stop() proc = subprocess.Popen(['ssh-add', '-l'], stdout=subprocess.PIPE, universal_newlines=True) output = proc.communicate()[0] if not output.find(self.private_key_fingerprint) >= 0: logger.debug( 'Was not able to unlock private key %s' % self.private_key_file, self) raise MountException( _('Could not unlock ssh private key. Wrong password ' 'or password not available for cron.')) else: logger.debug('Private key %s is already unlocked in ssh agent' % self.private_key_file, self) def checkLogin(self): """Try to login to remote host with public/private-key-method (passwordless). Raises: exceptions.NoPubKeyLogin: If login failed. """ logger.debug('Check login', self) # Custom SSH arguments custom_ssh_args = [ '-o', 'PreferredAuthentications=publickey', '-p', str(self.port), self.user_host ] # Create SSH command ssh = self.config.sshCommand(cmd=['exit'], custom_args=custom_ssh_args, port=False, user_host=False, nice=False, ionice=False, profile_id=self.profile_id) proc = subprocess.Popen(ssh, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, universal_newlines=True) err = proc.communicate()[1] if proc.returncode: raise NoPubKeyLogin( 'Password-less authentication for %(user)s@%(host)s ' 'failed. Look at \'man backintime\' for further ' 'instructions.' % { 'user': self.user, 'host': self.host} + '\n\n' + err) def checkCipher(self): """Try to login to remote host with the chosen cipher. This should make sure both `localhost` and the remote host support the chosen cipher. Raises: exceptions.MountException: If login with the cipher failed. """ if not self.cipher == 'default': logger.debug('Check cipher', self) ssh = self.config.sshCommand(cmd=['exit'], custom_args=[ '-o', 'Ciphers=%s' % self.cipher, '-p', str(self.port), self.user_host ], port=False, cipher=False, user_host=False, nice=False, ionice=False, profile_id=self.profile_id) proc = subprocess.Popen(ssh, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, universal_newlines=True) err = proc.communicate()[1] if proc.returncode: logger.debug( 'Ciper %s is not supported' % self.config.SSH_CIPHERS[self.cipher], self) msg = _('Cipher {cipher} failed for {host}.').format( cipher=self.config.SSH_CIPHERS[self.cipher], host=self.host) raise MountException(f'{msg}:\n{err}') def benchmarkCipher(self, size=40): """ Rudimental benchmark to compare transfer speed of all available ciphers. Args: size (int): size of the testfile in MiB """ temp = tempfile.mkstemp()[1] print('create random data file') subprocess.call([ 'dd', 'if=/dev/urandom', 'of=%s' % temp, 'bs=1M', 'count=%s' % size ]) keys = list(self.config.SSH_CIPHERS.keys()) keys.sort() for cipher in keys: if cipher == 'default': continue print('%s%s:%s' % (bcolors.BOLD, cipher, bcolors.ENDC)) for _ in range(2): # scp uses -P instead of -p for port subprocess.call([ 'scp', '-P', str(self.port), '-c', cipher, temp, self.user_host_path ]) ssh = self.config.sshCommand( cmd=['rm', os.path.join(self.path, os.path.basename(temp))], custom_args=['-p', str(self.port), self.user_host], port=False, cipher=False, user_host=False, nice=False, ionice=False, profile_id=self.profile_id) subprocess.call(ssh) os.remove(temp) def checkKnownHosts(self): """Check if the remote host is in current users ``known_hosts`` file. Raises: exceptions.KnownHost: If the remote host wasn't found in ``known_hosts`` file. """ logger.debug('Check known hosts file', self) for host in (self.host, '[%s]:%s' % (self.host, self.port)): proc = subprocess.Popen(['ssh-keygen', '-F', host], stdout=subprocess.PIPE, universal_newlines=True) # subprocess.check_output doesn't exist # in Python 2.6 (Debian squeeze default) output = proc.communicate()[0] if output.find('Host %s found' % host) >= 0: logger.debug( 'Host %s was found in known hosts file' % host, self) return True logger.debug('Host %s is not in known hosts file' % self.host, self) raise KnownHost('%s not found in ssh_known_hosts.' % self.host) def checkRemoteFolder(self): """ Check the remote path. If the remote path doesn't exist this will create it. If it already exist this will check, that it is a folder and has correct permissions. Raises: exceptions.MountException: if remote path couldn't be created or doesn't have correct permissions. """ logger.debug('Check remote directory', self) cmd = 'd=0;' # path doesn't exist. set d=1 to indicate cmd += 'test -e "%s" || d=1;' % self.path # create path, get errorcode from mkdir cmd += 'test $d -eq 1 && mkdir "%s"; err=$?;' % self.path # return errorcode from mkdir cmd += 'test $d -eq 1 && exit $err;' # path is no directory cmd += 'test -d "%s" || exit 11;' % self.path # path is not writable cmd += 'test -w "%s" || exit 12;' % self.path # path is not executable cmd += 'test -x "%s" || exit 13;' % self.path # everything is fine cmd += 'exit 20' ssh = self.config.sshCommand( cmd=[cmd], custom_args=['-p', str(self.port), self.user_host], port=False, user_host=False, nice=False, ionice=False, profile_id=self.profile_id) logger.debug('Call command: %s' % ' '.join(ssh), self) proc = subprocess.Popen(ssh, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) proc.communicate() if proc.returncode: logger.debug('Command returncode: %s' % proc.returncode, self) if proc.returncode == 20: # clean exit pass elif proc.returncode == 11: raise MountException('{}:\n{}'.format( _('Remote path exists but is not a directory.'), self.path)) elif proc.returncode == 12: raise MountException('{}:\n{}'.format( _('Remote path is not writable.'), self.path)) elif proc.returncode == 13: raise MountException('{}:\n{}'.format( _('Remote path is not executable.'), self.path)) else: raise MountException('{}:\n{}'.format( _("Couldn't create remote path."), self.path)) else: # returncode is 0 logger.info(f'Create remote path {self.path}', self) def checkPingHost(self): """ Check if the remote host is online. Other than methods name may let suppose this does not use Ping (``ICMP``) but try to open a connection to the configured port on the remote host. In this way it will even work on remote hosts which have ``ICMP`` disabled. If connection failed it will retry five times before failing. Raises: exceptions.MountException: If connection failed most probably because remote host is offline. """ if not self.config.sshCheckPingHost(self.profile_id): return if self.proxy_host: ping_host = self.proxy_host ping_port = self.proxy_port else: ping_host = self.host ping_port = self.port logger.debug(f'Check ping host "{ping_host}:{ping_port}"', self) versionString = 'SSH-2.0-backintime_{}\r\n'.format( version.__version__).encode() count = 0 while count < 5: try: with socket.create_connection( (ping_host, ping_port), 2.0) as s: result = s.connect_ex(s.getpeername()) s.sendall(versionString) except: # Refactor: too broad exception result = -1 if result == 0: logger.debug( f'Host "{ping_host}:{ping_port}" is available', self) return count += 1 sleep(0.2) if result != 0: proxy_msg = f' via proxy "{ping_host}:{ping_port}"' \ if self.proxy_host else '' msg = f'Ping {self.host}{proxy_msg} failed. ' \ 'Host is down or wrong address.' logger.debug(msg, self) raise MountException(msg) def checkRemoteCommands(self, retry=False): """ Try out all relevant commands used by Back In Time on the remote host to make sure snapshots will be successful with the remote host. This will also check that hard-links are supported on the remote host. This check can be disabled with :py:func:`config.Config.sshCheckCommands`. Args: retry (bool): Retry to run the commands if it failed because the command string was to long. Raises: exceptions.MountException: If a command is not supported on remote host or if hard-links are not supported. """ if not self.config.sshCheckCommands(): return logger.debug('Check remote commands', self) def maxArg(): if retry: raise MountException( "Checking commands on remote host didn't return any " "output. We already checked the maximum argument length " "but it seems like there is another problem") logger.warning( 'Looks like the command was to long for remote SSHd. ' 'We will test max arg length now and retry.', self) import ssh_max_arg max_arg_size = ssh_max_arg.probe_max_ssh_command_size(self.config) ssh_max_arg.report_result(self.host, max_arg_size) self.config.setSshMaxArgLength(max_arg_size, self.profile_id) return self.checkRemoteCommands(retry=True) remote_tmp_dir_1 = os.path.join(self.path, 'tmp_%s' % self.randomId()) remote_tmp_dir_2 = os.path.join(self.path, 'tmp_%s' % self.randomId()) with tempfile.TemporaryDirectory() as tmp: tmp_file = os.path.join(tmp, 'a') with open(tmp_file, 'wt') as f: f.write('foo') # check rsync rsync1 = tools.rsyncPrefix( self.config, no_perms=False, progress=False) rsync1.append(tmp_file) rsync1.append('%s@%s:%s/' % ( self.user, tools.escapeIPv6Address(self.host), remote_tmp_dir_1)) # check remote rsync hard-link support rsync2 = tools.rsyncPrefix( self.config, no_perms=False, progress=False) rsync2.append( '--link-dest=../%s' % os.path.basename(remote_tmp_dir_1)) rsync2.append(tmp_file) rsync2.append('%s@%s:%s/' % ( self.user, tools.escapeIPv6Address(self.host), remote_tmp_dir_2)) for cmd in (rsync1, rsync2): logger.debug('Check rsync command: %s' % cmd, self) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) err = proc.communicate()[1] if err or proc.returncode: logger.debug(f'rsync command returned error: {err}', self) raise MountException( "Remote host {host} doesn't support '{command}:\n" "{err}\n" "Look at 'man backintime' for further instructions." .format( host=self.host, command=cmd, err=err) ) # check cp chmod find and rm head = 'tmp1="%s"; tmp2="%s"; ' % (remote_tmp_dir_1, remote_tmp_dir_2) # first define a function to clean up and exit head += 'cleanup(){ ' head += 'test -e "$tmp1/a" && rm "$tmp1/a" >/dev/null 2>&1; ' head += 'test -e "$tmp2/a" && rm "$tmp2/a" >/dev/null 2>&1; ' head += 'test -e smr.lock && rm smr.lock >/dev/null 2>&1; ' head += 'test -e "$tmp1" && rmdir "$tmp1" >/dev/null 2>&1; ' head += 'test -e "$tmp2" && rmdir "$tmp2" >/dev/null 2>&1; ' head += 'test -n "$tmp3" && test -e "$tmp3" && rmdir "$tmp3" >/dev/null 2>&1; ' head += 'exit $1; }; ' tail = [] # list inodes cmd = 'ls -i "$tmp1/a"; ls -i "$tmp2/a"; ' tail.append(cmd) # try nice -n 19 if self.nice: cmd = 'echo \"nice -n 19\"; nice -n 19 true >/dev/null; err_nice=$?; ' cmd += 'test $err_nice -ne 0 && cleanup $err_nice; ' tail.append(cmd) # try ionice -c2 -n7 if self.ionice: cmd = 'echo \"ionice -c2 -n7\"; ionice -c2 -n7 true >/dev/null; err_nice=$?; ' cmd += 'test $err_nice -ne 0 && cleanup $err_nice; ' tail.append(cmd) # try nocache if self.nocache: cmd = 'echo \"nocache\"; nocache true >/dev/null; err_nocache=$?; ' cmd += 'test $err_nocache -ne 0 && cleanup $err_nocache; ' tail.append(cmd) # try screen, bash and flock used by smart-remove running in background if self.config.smartRemoveRunRemoteInBackground(self.profile_id): cmd = 'echo \"screen -d -m bash -c ...\"; screen -d -m bash -c \"true\" >/dev/null; err_screen=$?; ' cmd += 'test $err_screen -ne 0 && cleanup $err_screen; ' tail.append(cmd) cmd = 'echo \"(flock -x 9) 9>smr.lock\"; bash -c \"(flock -x 9) 9>smr.lock\" >/dev/null; err_flock=$?; ' cmd += 'test $err_flock -ne 0 && cleanup $err_flock; ' tail.append(cmd) cmd = 'echo \"rmdir \\$(mktemp -d)\"; tmp3=$(mktemp -d); test -z "$tmp3" && cleanup 1; rmdir $tmp3 >/dev/null; err_rmdir=$?; ' cmd += 'test $err_rmdir -ne 0 && cleanup $err_rmdir; ' tail.append(cmd) # if we end up here, everything should be fine cmd = 'echo \"done\"; cleanup 0' tail.append(cmd) maxLength = self.config.sshMaxArgLength(self.profile_id) additionalChars = len('echo ""') \ + len(self.config.sshPrefixCmd(self.profile_id, cmd_type=str)) output = '' err = '' returncode = 0 for cmd in tools.splitCommands(tail, head=head, maxLength=maxLength-additionalChars): if cmd.endswith('; '): cmd += 'echo ""' c = self.config.sshCommand( cmd=[cmd], custom_args=['-p', str(self.port), self.user_host], port=False, user_host=False, nice=False, ionice=False, profile_id=self.profile_id) try: logger.debug('Call command: %s' % ' '.join(c), self) proc = subprocess.Popen(c, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) ret = proc.communicate() except OSError as e: # Argument list too long if e.errno == 7: logger.debug( 'Argument list too long (Python exception)', self) return maxArg() else: raise logger.debug('Command stdout: %s' % ret[0], self) logger.debug('Command stderr: %s' % ret[1], self) logger.debug('Command returncode: %s' % proc.returncode, self) output += ret[0].strip('\n') + '\n' err += ret[1].strip('\n') + '\n' returncode += proc.returncode if proc.returncode: break output_split = output.strip('\n').split('\n') while True: if output_split and not output_split[-1]: output_split = output_split[:-1] else: break if not output_split: return maxArg() if returncode or not output_split[-1].startswith('done'): for command in ('rm', 'nice', 'ionice', 'nocache', 'screen', '(flock'): if output_split[-1].startswith(command): command = f"'{output_split[-1]}':\n{err}" msg = _("Remote host {host} doesn't support {command}") \ .format(host=self.host, command=command) raise MountException('{}\n{}'.format( msg, _("Look at 'man backintime' for further instructions") ) ) msg = _('Check commands on host {host} returned unknown error') \ .format(host=self.host) raise MountException('{}:\n{}n{}'.format( msg, err, _("Look at 'man backintime' for further instructions"))) inodes = [] for tmp in (remote_tmp_dir_1, remote_tmp_dir_2): for line in output_split: m = re.match(r'^(\d+).*?%s' % tmp, line) if m: inodes.append(m.group(1)) logger.debug('remote inodes: ' + ' | '.join(inodes), self) if len(inodes) == 2 and inodes[0] != inodes[1]: raise MountException( _("Remote host {host} doesn't support hardlinks") .format(host=self.host)) def randomId(self, size=6, chars=string.ascii_uppercase + string.digits): """ Create a random string. Args: size (int): length of the string chars (str): characters used as basis for the random string Returns: str: random string with length ``size`` """ return ''.join(random.choice(chars) for x in range(size)) def sshKeyGen(keyfile): """ Generate a new ssh-key pair (private and public key) in ``keyfile`` and ``keyfile``.pub Args: keyfile (str): path for private key file Returns: bool: True if successful; False if ``keyfile`` already exist or if there was an error """ if os.path.exists(keyfile): logger.warning( 'SSH keyfile "{}" already exist. Skip creating a new one' .format(keyfile)) return False cmd = ['ssh-keygen', '-t', 'rsa', '-N', '', '-f', keyfile] proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, universal_newlines=True) err = proc.communicate()[1] if proc.returncode: logger.error('Failed to create a new ssh-key: {}'.format(err)) else: logger.info('Successfully created new ssh-key "{}"'.format(keyfile)) return not proc.returncode def sshCopyIdCommand( pubkey, user, host, port='22', proxy_user=None, proxy_host=None, proxy_port='22', cipher=None ): """ Generate a ssh-copy-id command to copy the given public ssh-key to a remote host. Args: pubkey (str): path to the public key file user (str): remote user host (str): remote host port (str): ssh port on remote host proxy_user (str): proxy host user proxy_host (str): proxy host proxy_port (str): proxy host port cipher (str): cipher used for ssh Returns: list: The ssh-copy-id command as a list. Raises: FileNotFoundError: If public key file not exist. """ if not Path(pubkey).exists(): msg = f'SSH public key "{pubkey}" does not exist.' logger.error(msg) raise FileNotFoundError(msg) cmd = [ 'ssh-copy-id', # key file '-i', pubkey, # port '-p', str(port), ] # cipher if cipher and cipher != 'default': cmd.extend(['-o', 'Ciphers={}'.format(cipher)]) # proxy if proxy_host: proxy_jump = f'{proxy_user}@{proxy_host}:{proxy_port}' cmd.extend(['-o', f'ProxyJump={proxy_jump}']) cmd.append(f'{user}@{host}') logger.debug(f'ssh-copy-id command {cmd}') return cmd def sshCopyId( pubkey, user, host, port='22', proxy_user=None, proxy_host=None, proxy_port=None, askPass='backintime-askpass', cipher=None ): """ Copy SSH public key ``pubkey`` to remote ``host``. Args: pubkey (str): path to the public key file user (str): remote user host (str): remote host port (str): ssh port on remote host askPass (str): program used to pipe password into ssh cipher (str): cipher used for ssh Returns: bool: True if successful """ cmd = sshCopyIdCommand( pubkey, user, host, port, proxy_user, proxy_host, proxy_port, cipher ) env = os.environ.copy() env['SSH_ASKPASS'] = askPass env['ASKPASS_MODE'] = 'USER' env['ASKPASS_PROMPT'] = '{}\n{}:'.format( _('Copy public ssh-key "{pubkey}" to remote host "{host}".').format( pubkey=pubkey, host=host), _('Please enter a password for "{user}".').format(user=user) ) proc = subprocess.Popen(cmd, env=env, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, preexec_fn=os.setsid, # cut of ssh from current # terminal to make it use # backintime-askpass universal_newlines=True) err = proc.communicate()[1] if proc.returncode: logger.error('Failed to copy ssh-key "{}" to "{}@{}": [{}] {}' .format(pubkey, user, host, proc.returncode, err)) else: logger.info('Successfully copied ssh-key "{}" to "{}@{}"' .format(pubkey, user, host)) return not proc.returncode def sshKeyFingerprint(path): """ Get the hex fingerprint from a given ssh key. Args: path (str): full path to key file Returns: str: hex fingerprint from key """ if not os.path.exists(path): return cmd = ['ssh-keygen', '-l', '-f', path] proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) output = proc.communicate()[0] m = re.match(r'\d+\s+(SHA256:\S+|[a-fA-F0-9:]+)\s.*', output.decode()) if m: return m.group(1) def sshHostKey(host, port='22'): """ Get the remote host key from ``host``. Args: host (str): host name or IP address port (str): port number of remote ssh-server Returns: tuple: three item tuple with (fingerprint, hashed host key, key type) """ for t in ('ecdsa', 'rsa'): cmd = ['ssh-keyscan', '-t', t, '-p', port, host] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) hostKey = proc.communicate()[0].strip() if hostKey: break if hostKey: logger.debug('Found {} key for host "{}"'.format(t.upper(), host)) with tempfile.TemporaryDirectory() as tmp: keyFile = os.path.join(tmp, 'key') with open(keyFile, 'wb') as f: f.write(hostKey + b'\n') hostKeyFingerprint = sshKeyFingerprint(keyFile) cmd = ['ssh-keygen', '-H', '-f', keyFile] proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) proc.communicate() with open(keyFile, 'rt') as f: hostKeyHash = f.read().strip() return (hostKeyFingerprint, hostKeyHash, t.upper()) return (None, None, None) def writeKnownHostsFile(key): """ Write host key ``key`` into `~/.ssh/known_hosts`. Args: key (str): host key """ sshDir = os.path.expanduser('~/.ssh') knownHostFile = os.path.join(sshDir, 'known_hosts') if not os.path.isdir(sshDir): tools.mkdir(sshDir, 0o700) with open(knownHostFile, 'at') as f: logger.info('Write host key to {}'.format(knownHostFile)) f.write(key + '\n') backintime-1.5.4/common/test/000077500000000000000000000000001477034762000161105ustar00rootroot00000000000000backintime-1.5.4/common/test/__init__.py000066400000000000000000000000001477034762000202070ustar00rootroot00000000000000backintime-1.5.4/common/test/config000066400000000000000000000012671477034762000173060ustar00rootroot00000000000000config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=/tmp/test profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=/tmp/snapshots profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 backintime-1.5.4/common/test/constants.py000066400000000000000000000014231477034762000204760ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Ihor Pryyma # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """ Constants that are used in the test files. """ import grp import os import pwd CURRENTUID = os.geteuid() CURRENTUSER = pwd.getpwuid(CURRENTUID).pw_name CURRENTGID = os.getegid() CURRENTGROUP = grp.getgrgid(CURRENTGID).gr_name CURRENTUID = os.geteuid() CURRENTGID = os.getegid() backintime-1.5.4/common/test/dummy_test_process.sh000077500000000000000000000006221477034762000223770ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # This is just a test dummy to simulate a running process while true; do sleep 2 done backintime-1.5.4/common/test/generic.py000066400000000000000000000315731477034762000201070ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # SPDX-FileCopyrightText: © 2023 Christian BUHTZ # SPDX-FileCopyrightText: © 2024 David Wales (@daviewales) # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """This module offers some helpers and tools for unittesting. Most of the content are `unittest.TestCase` derived classed doing basic setup for the testing environment. They are dealing with snapshot path's, SSH, config files and things like set. """ import os import pathlib import sys import unittest import socket from unittest.mock import patch from tempfile import TemporaryDirectory, NamedTemporaryFile from contextlib import contextmanager sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import logger import tools # Needed because backintime.startApp() is not invoked. tools.initiate_translation(None) import config import snapshots # mock notifyplugin to suppress notifications tools.registerBackintimePath('qt', 'plugins') TMP_FLOCK = NamedTemporaryFile(prefix='backintime', suffix='.flock') SSH_PATH = pathlib.Path.home() / '.ssh' AUTHORIZED_KEYS_FILE = SSH_PATH / 'authorized_keys' DUMMY = 'dummy_test_process.sh' public_keys = ( # RSA key SSH_PATH / 'id_rsa.pub', # ed25519 key SSH_PATH / 'id_ed25519.pub', ) existing_public_keys = tuple(filter(lambda k: k.exists(), public_keys)) authorised_public_keys = [] # Check if the existing keys are in authorized file if AUTHORIZED_KEYS_FILE.exists(): with AUTHORIZED_KEYS_FILE.open('rb') as auth: auth_keys = auth.readlines() for key in existing_public_keys: with key.open('rb') as pub: if pub.read() in auth_keys: authorised_public_keys.append(key) if authorised_public_keys: KEY_IN_AUTH = True PUBLIC_KEY_FILE = authorised_public_keys[0] PRIV_KEY_FILE = PUBLIC_KEY_FILE.with_suffix('') else: KEY_IN_AUTH = False try: PUBLIC_KEY_FILE = existing_public_keys[0] PRIV_KEY_FILE = PUBLIC_KEY_FILE.with_suffix('') except IndexError: PUBLIC_KEY_FILE = None PRIV_KEY_FILE = None PRIV_KEY_IS_FILE = PRIV_KEY_FILE.is_file() if PRIV_KEY_FILE else False # check if port 22 on localhost is available # sshd should be there... try: with socket.create_connection(('localhost', '22'), 2.0) as s: sshdPortAvailable = not bool(s.connect_ex(s.getpeername())) except ConnectionRefusedError: sshdPortAvailable = False ON_TRAVIS = os.environ.get('TRAVIS', 'None').lower() == 'true' ON_RTD = os.environ.get('READTHEDOCS', 'None').lower() == 'true' SKIP_SSH_TEST_MESSAGE = 'Skip as this test requires a local ssh server, ' \ 'public and private keys installed' # # DEBUG # print(f"{tools.processExists('sshd')=}") # print(f'{PUBLIC_KEY_FILE=}') # print(f'{PRIV_KEY_FILE=}') # print(f'{PRIV_KEY_IS_FILE=}') # print(f'{KEY_IN_AUTH=}') # print(f'{sshdPortAvailable=}') # If False all SSH related tests are skipped. # On TravisCI that tests are enforced and never skipped. LOCAL_SSH = True if ON_TRAVIS else all([ # Server process running? tools.processExists('sshd'), # Privat keyfile PRIV_KEY_IS_FILE, # Key known (copied via "ssh-copy-id") KEY_IN_AUTH, # SSH port (22) available at the server sshdPortAvailable ]) # Temporary workaround (buhtz: 2023-09) # Not all components of the code are able to handle Path objects PRIV_KEY_FILE = str(PRIV_KEY_FILE) PUBLIC_KEY_FILE = str(PUBLIC_KEY_FILE) AUTHORIZED_KEYS_FILE = str(AUTHORIZED_KEYS_FILE) class TestCase(unittest.TestCase): """Base class for Back In Time unit- and integration testing. In summary following is set via 'setUp()' and '__init__()': - Initialize logging. - Set path to config file (not open it). - Set path the "backup source" directory. """ def __init__(self, methodName): """Initialize logging and set the path of the config file. The config file in the "test" folder is used. Args: methodName: Unknown. """ # note by buhtz: This is not recommended. Unittest module handle # that itself. The default locale while unittesting is "C". # Need further investigation. os.environ['LANGUAGE'] = 'en_US.UTF-8' # Path to config file (in "common/test/config") self.cfgFile = os.path.abspath( os.path.join(__file__, os.pardir, 'config')) # Initialize logging logger.APP_NAME = 'BIT_unittest' logger.openlog() super(TestCase, self).__init__(methodName) def setUp(self): """ """ logger.DEBUG = '-v' in sys.argv # ? self.run = False # Not sure but this could be the "backup source" directory self.sharePathObj = TemporaryDirectory() self.sharePath = self.sharePathObj.name def tearDown(self): """ """ # BUHTZ 10/09/2022: In my understanding it is not needed and would be # done implicitly when the test class is destroyed. self.sharePathObj.cleanup() def callback(self, func, *args): """ """ func(*args) self.run = True # the next six assert methods are deprecated and can be replaced # by using Pythons in-build "pathlib.Path" def assertExists(self, *path): full_path = os.path.join(*path) if not os.path.exists(full_path): self.fail('File does not exist: {}'.format(full_path)) def assertNotExists(self, *path): full_path = os.path.join(*path) if os.path.exists(full_path): self.fail('File does unexpected exist: {}'.format(full_path)) def assertIsFile(self, *path): full_path = os.path.join(*path) if not os.path.isfile(full_path): self.fail('Not a File: {}'.format(full_path)) def assertIsNoFile(self, *path): full_path = os.path.join(*path) if os.path.isfile(full_path): self.fail('Unexpected File: {}'.format(full_path)) def assertIsDir(self, *path): full_path = os.path.join(*path) if not os.path.isdir(full_path): self.fail('Not a directory: {}'.format(full_path)) def assertIsLink(self, *path): full_path = os.path.join(*path) if not os.path.islink(full_path): self.fail('Not a symlink: {}'.format(full_path)) class TestCaseCfg(TestCase): """Testing base class opening the config file, creating the config instance and starting the notify plugin. The path to the config file was set by the inherited class :py:class:`generic.TestCase`. """ def setUp(self): super(TestCaseCfg, self).setUp() self.cfg = config.Config(self.cfgFile, self.sharePath) # mock notifyplugin to suppress notifications patcher = patch('notifyplugin.NotifyPlugin.message') self.mockNotifyPlugin = patcher.start() self.cfg.PLUGIN_MANAGER.load() class TestCaseSnapshotPath(TestCaseCfg): """Testing base class for snapshot test cases. It setup a temporary directory as the root for all snapshots. """ def setUp(self): """ """ super(TestCaseSnapshotPath, self).setUp() # The root of all snapshots. Like a "backup destination". # e.g. '/tmp/tmpf3mdnt8l' self.tmpDir = TemporaryDirectory() self.cfg.dict['profile1.snapshots.path'] = self.tmpDir.name # The full snapshot path combines the backup destination root # directory with hostname, username and the profile (backupjob) ID. # e.g. /tmp/tmpf3mdnt8l/backintime/test-host/test-user/1 self.snapshotPath = self.cfg.snapshotsFullPath() def tearDown(self): """ """ super(TestCaseSnapshotPath, self).tearDown() self.tmpDir.cleanup() class SnapshotsTestCase(TestCaseSnapshotPath): """Testing base class for snapshot testing unittest classes. Create the snapshot path and a :py:class:`Snapshot` instance of it. """ def setUp(self): """ """ super(SnapshotsTestCase, self).setUp() # e.g. /tmp/tmpf3mdnt8l/backintime/test-host/test-user/1 os.makedirs(self.snapshotPath) self.sn = snapshots.Snapshots(self.cfg) # use a tmp-file for flock because test_flockExclusive would deadlock # otherwise if a regular snapshot is running in background self.sn.GLOBAL_FLOCK = TMP_FLOCK.name class SnapshotsWithSidTestCase(SnapshotsTestCase): """Testing base class creating a concrete SID object. Backup content (folder and file) is created in that snapshot like the snapshot was taken in the past. """ def setUp(self): """ """ super(SnapshotsWithSidTestCase, self).setUp() # A snapthos "data object" self.sid = snapshots.SID('20151219-010324-123', self.cfg) # Create test files and folders # e.g. /tmp/tmp9rstvbsx/backintime/test-host/test-user/1/ # 20151219-010324-123/backup/foo/bar # 20151219-010324-123/backup/foo/bar/baz self.sid.makeDirs() self.testDir = 'foo/bar' self.testDirFullPath = self.sid.pathBackup(self.testDir) self.testFile = 'foo/bar/baz' self.testFileFullPath = self.sid.pathBackup(self.testFile) self.sid.makeDirs(self.testDir) with open(self.sid.pathBackup(self.testFile), 'wt'): pass class SSHTestCase(TestCaseCfg): """Base class for test cases using the SSH features. Running this test requires that user has public / private key pair created and SSH server (at localhost) running. """ def setUp(self): """ """ super(SSHTestCase, self).setUp() logger.DEBUG = '-v' in sys.argv self.cfg.setSnapshotsMode('ssh') self.cfg.setSshHost('localhost') self.cfg.setSshPrivateKeyFile(PRIV_KEY_FILE) # use a TemporaryDirectory for remote snapshot path # self.tmpDir = TemporaryDirectory(prefix='bit_test_', suffix=' with blank') self.tmpDir = TemporaryDirectory() self.remotePath = os.path.join(self.tmpDir.name, 'foo') self.remoteFullPath = os.path.join( self.remotePath, 'backintime', *self.cfg.hostUserProfile()) self.cfg.setSshSnapshotsPath(self.remotePath) self.mount_kwargs = {} def tearDown(self): """ """ super(SSHTestCase, self).tearDown() self.tmpDir.cleanup() class SSHSnapshotTestCase(SSHTestCase): """Testing base class for test cases using a snapshot and SSH. BUHTZ 2022-10-09: Seems exactly the same then `SnapshotsTestCase` except the inheriting class. """ def setUp(self): """ """ super(SSHSnapshotTestCase, self).setUp() self.snapshotPath = self.cfg.sshSnapshotsFullPath() os.makedirs(self.snapshotPath) self.sn = snapshots.Snapshots(self.cfg) # use a tmp-file for flock because test_flockExclusive would deadlock # otherwise if a regular snapshot is running in background self.sn.GLOBAL_FLOCK = TMP_FLOCK.name class SSHSnapshotsWithSidTestCase(SSHSnapshotTestCase): """Testing base class for test cases using an existing snapshot (SID) and SSH. BUHTZ 2022-10-09: Seems exactly the same then `SnapshotsWithSidTestCase` except the inheriting class. """ def setUp(self): """ """ super(SSHSnapshotsWithSidTestCase, self).setUp() self.sid = snapshots.SID('20151219-010324-123', self.cfg) self.remoteSIDBackupPath = os.path.join( self.snapshotPath, self.sid.sid, 'backup') os.makedirs(self.remoteSIDBackupPath) self.testDir = 'foo/bar' self.testDirFullPath = os.path.join( self.remoteSIDBackupPath, self.testDir) self.testFile = 'foo/bar/baz' self.testFileFullPath = os.path.join( self.remoteSIDBackupPath, self.testFile) os.makedirs(self.testDirFullPath) with open(self.testFileFullPath, 'wt'): pass def create_test_files(path): """Create folders and files. Args: path: Destination folder. That is the resulting folder structure :: foo └── bar ├── baz ├── file with spaces └── test """ os.makedirs(os.path.join(path, 'foo', 'bar')) with open(os.path.join(path, 'foo', 'bar', 'baz'), 'wt') as f: f.write('foo') with open(os.path.join(path, 'test'), 'wt') as f: f.write('bar') with open(os.path.join(path, 'file with spaces'), 'wt') as f: f.write('asdf') @contextmanager def mockPermissions(path, mode=0o000): """ """ st = os.stat(path) os.chmod(path, mode) yield # fix permissions so it can be removed os.chmod(path, st.st_mode) backintime-1.5.4/common/test/test_applicationinstance.py000066400000000000000000000244411477034762000235560ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import subprocess from unittest.mock import patch from threading import Thread from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), "..")) import tools from applicationinstance import ApplicationInstance class General(generic.TestCase): def setUp(self): """Preparing unittests including the instantiation of an ``ÀpplicationInstance``. """ super().setUp() self.temp_file = '/tmp/temp.txt' self.file_name = "/tmp/file_with_pid" self.app_instance = ApplicationInstance( pidFile=os.path.abspath(self.file_name), autoExit=False) self.subproc = None def tearDown(self): """Delete temporary files and kill subprocesses. """ super().tearDown() for f in (self.temp_file, self.file_name): if os.path.exists(f): os.remove(f) self._killProcess() def _createProcess(self): """Start a shell script and return ins PID.""" # path to the shell script dummyPath = os.path.join(os.path.dirname(__file__), generic.DUMMY) self.subproc = subprocess.Popen(dummyPath) return self.subproc.pid def _killProcess(self): if self.subproc: subproc = self.subproc subproc.kill() subproc.wait() self.subproc = None def test_create_and_remove_pid_file(self): # create pid file self.app_instance.startApplication() self.assertIsFile(self.file_name) # remove pid file self.app_instance.exitApplication() self.assertIsNoFile(self.file_name) def test_pid_file_content(self): """Content of pid file fits to current process.""" self.app_instance.startApplication() this_pid = os.getpid() this_procname = tools.processName(this_pid) expected_file_content = f'{this_pid}\n{this_procname}' with open(self.file_name, 'rt') as file_with_pid: pid_file_content = file_with_pid.read() self.assertEqual(pid_file_content, expected_file_content) @patch('builtins.open') def test_write_pid_fail(self, mock_open): """The test is not clear. Because of the OSError() a log error will be generated. But this isn't tested here. I assume the expected behavior is just that nothing bad happens because the OSError was caught. """ mock_open.side_effect = OSError() self.app_instance.startApplication() def test_existing_process_with_correct_procname(self): """ Test the check function with an existing process with correct process name """ pid = self._createProcess() procname = tools.processName(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write(str(pid) + "\n") file_with_pid.write(procname) # Execute test self.assertFalse(self.app_instance.check()) self.assertTrue(self.app_instance.busy()) def test_existing_process_with_correct_proc_cmdline(self): """ Test the check function with an existing process with correct process cmdline (for backwards compatibility) """ # start an extern shell script pid = self._createProcess() procname = tools.processCmdline(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write(str(pid) + "\n") file_with_pid.write(procname) # Execute test self.assertFalse(self.app_instance.check()) def test_no_pid_file(self): self.assertTrue(self.app_instance.check()) def test_existing_process_with_wrong_procname(self): """ Test the check function with an existing process with wrong process name """ pid = self._createProcess() procname = tools.processName(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write(str(pid) + "\n") file_with_pid.write(procname + "DELETE") # Execute test self.assertTrue(self.app_instance.check()) def test_existing_process_with_wrong_pid(self): """ Test the check function with an existing process with wrong pid """ pid = self._createProcess() procname = tools.processName(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write("987654321\n") file_with_pid.write(procname) # Execute test self.assertTrue(self.app_instance.check()) def test_killing_existing_process(self): """ Test the check function with an existing process with correct process name """ pid = self._createProcess() procname = tools.processName(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write(str(pid) + "\n") file_with_pid.write(procname) self.assertFalse(self.app_instance.check()) self._killProcess() # Execute test self.assertTrue(self.app_instance.check()) def test_non_existing_process(self): """ Test the check function with a non existing process """ # GIVE # # create file with fake pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write("987654321\n") file_with_pid.write("FAKE_PROCNAME") # Execute test self.assertTrue(self.app_instance.check()) def test_leftover_empty_lockfile(self): with open(self.file_name, 'wt'): pass self.assertTrue(self.app_instance.check()) def write_after_flock(self, pid_file): inst = ApplicationInstance(os.path.abspath(pid_file), autoExit = False, flock = True) with open(self.temp_file, 'wt') as f: f.write('foo') inst.flockUnlock() def test_thread_write_without_flock(self): thread = Thread(target = self.write_after_flock, args = (self.file_name,)) thread.start() #wait for the thread to finish thread.join() self.assertExists(self.temp_file) with open(self.temp_file, 'rt') as f: self.assertEqual(f.read(), 'foo') def test_flock_exclusive(self): self.app_instance.flockExclusiv() thread = Thread(target = self.write_after_flock, args = (self.file_name,)) thread.start() #give the thread some time thread.join(0.01) self.assertNotExists(self.temp_file) self.app_instance.flockUnlock() #wait for the thread to finish thread.join() self.assertExists(self.temp_file) with open(self.temp_file, 'rt') as f: self.assertEqual(f.read(), 'foo') @patch('builtins.open') def test_flock_exclusive_fail(self, mock_open): """Dev note (buhtz: 2023-09) Nothing is tested here. Looking into flockExclusive() there is only the opportunity to test for ERROR log output. Log output shouldn't be tested. The behavior to test is unclear. Proposal: - Remove the test. - Refactor flockExclusive() and related code to make its behavior clear. """ mock_open.side_effect = OSError() self.app_instance.flockExclusiv() def test_auto_flock(self): self.app_instance = ApplicationInstance(os.path.abspath(self.file_name), autoExit = False, flock = True) thread = Thread(target = self.write_after_flock, args = (self.file_name,)) thread.start() #give the thread some time thread.join(0.01) self.assertNotExists(self.temp_file) self.app_instance.startApplication() #wait for the thread to finish thread.join() self.assertExists(self.temp_file) with open(self.temp_file, 'rt') as f: self.assertEqual(f.read(), 'foo') def test_autoExit_unique_process(self): self.app_instance = ApplicationInstance(os.path.abspath(self.file_name), autoExit = True) self.assertExists(self.file_name) this_pid = os.getpid() this_procname = tools.processName(this_pid) with open(self.file_name, 'rt') as file_with_pid: self.assertEqual(file_with_pid.read(), '{}\n{}'.format(this_pid, this_procname)) def test_autoExit_other_running_process(self): pid = self._createProcess() procname = tools.processName(pid) # create file with pid and process name with open(self.file_name, "wt") as file_with_pid: file_with_pid.write(str(pid) + "\n") file_with_pid.write(procname) with self.assertRaises(SystemExit): self.app_instance = ApplicationInstance(os.path.abspath(self.file_name), autoExit = True) def test_readPidFile(self): with open(self.file_name, "wt") as f: f.write('123\nfoo') self.assertEqual(self.app_instance.readPidFile(), (123, 'foo')) # ValueError with open(self.file_name, "wt") as f: f.write('foo\nbar') self.assertEqual(self.app_instance.readPidFile(), (0, 'bar')) @patch('builtins.open') def test_readPidFile_fail(self, mock_open): mock_open.side_effect = OSError() self.assertEqual(self.app_instance.readPidFile(), (0, '')) backintime-1.5.4/common/test/test_argparser.py000066400000000000000000000230551477034762000215140ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2015-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import unittest import os import sys import itertools from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), "..")) import backintime def shuffleArgs(*args): """ Return every possible combination of arguments. Those arguments which need to keep in line have to be inside a tuple. args: two or more arguments (str) """ for i in itertools.permutations(args): ret = [] for j in i: if isinstance(j, (tuple, list)): ret.extend(j) else: ret.append(j) yield ret class General(generic.TestCase): def setUp(self): super().setUp() backintime.createParsers() def tearDown(self): super().tearDown() global parsers parsers = {} def test_invalid_arg(self): with self.assertRaises(SystemExit): backintime.argParse(['not_existing_command']) with self.assertRaises(SystemExit): backintime.argParse(['--not_existing_argument']) def test_config(self): args = backintime.argParse(['--config', '/tmp/config']) self.assertIn('config', args) self.assertEqual(args.config, '/tmp/config') def test_quiet(self): args = backintime.argParse(['--quiet',]) self.assertIn('quiet', args) self.assertTrue(args.quiet) def test_debug(self): args = backintime.argParse(['--debug',]) self.assertIn('debug', args) self.assertTrue(args.debug) def test_config_no_path(self): with self.assertRaises(SystemExit): backintime.argParse(['--config']) class Backup(generic.TestCase): def setUp(self): super().setUp() backintime.createParsers() def tearDown(self): super().tearDown() global parsers parsers = {} def test_simple(self): args = backintime.argParse(['backup']) self.assertIn('command', args) self.assertEqual(args.command, 'backup') self.assertIn('func', args) self.assertIs(args.func, backintime.backup) def test_backwards_compatiblity_alias(self): args = backintime.argParse(['--backup']) self.assertIn('func', args) self.assertIs(args.func, backintime.aliasParser) self.assertIn('replace', args) self.assertEqual(args.replace, '--backup') self.assertIn('alias', args) self.assertEqual(args.alias, 'backup') def test_profile(self): for argv in shuffleArgs('backup', ('--profile', 'foo')): with self.subTest(argv = argv): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'argv = %s' %argv args = backintime.argParse(argv) self.assertIn('command', args, msg) self.assertEqual(args.command, 'backup', msg) self.assertIn('profile', args, msg) self.assertEqual(args.profile, 'foo', msg) def test_profile_id(self): args = backintime.argParse(['backup', '--profile-id', '2']) self.assertIn('command', args) self.assertEqual(args.command, 'backup') self.assertIn('profile_id', args) self.assertEqual(args.profile_id, 2) def test_profile_and_profile_id(self): with self.assertRaises(SystemExit): backintime.argParse(['backup', '--profile', 'foo', '--profile-id', '2']) def test_quiet(self): args = backintime.argParse(['backup', '--quiet']) self.assertIn('command', args) self.assertEqual(args.command, 'backup') self.assertIn('quiet', args) self.assertTrue(args.quiet) def test_multi_args(self): for argv in shuffleArgs('--quiet', 'backup', ('--profile', 'foo'), '--checksum', ('--config', 'bar')): with self.subTest(argv = argv): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'argv = %s' %argv args = backintime.argParse(argv) self.assertIn('command', args, msg) self.assertEqual(args.command, 'backup', msg) self.assertIn('profile', args, msg) self.assertEqual(args.profile, 'foo', msg) self.assertIn('quiet', args, msg) self.assertTrue(args.quiet, msg) self.assertIn('checksum', args, msg) self.assertTrue(args.checksum, msg) self.assertIn('config', args, msg) self.assertEqual(args.config, 'bar', msg) class Restore(generic.TestCase): def setUp(self): super().setUp() backintime.createParsers() def tearDown(self): super().tearDown() global parsers parsers = {} def test_simple(self): args = backintime.argParse(['restore']) self.assertIn('command', args) self.assertEqual(args.command, 'restore') self.assertIn('func', args) self.assertIs(args.func, backintime.restore) def test_what_where_snapshot_id(self): args = backintime.argParse(['restore', '/home', '/tmp', '20151130-230501-984']) self.assertIn('command', args) self.assertEqual(args.command, 'restore') self.assertIn('WHAT', args) self.assertEqual(args.WHAT, '/home') self.assertIn('WHERE', args) self.assertEqual(args.WHERE, '/tmp') self.assertIn('SNAPSHOT_ID', args) self.assertEqual(args.SNAPSHOT_ID, '20151130-230501-984') def test_what_where_snapshot_id_multi_args(self): for argv in shuffleArgs('--quiet', ('restore', '/home', '/tmp', '20151130-230501-984'), '--checksum', ('--profile-id', '2'), '--local-backup', '--delete', ('--config', 'foo')): with self.subTest(argv = argv): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'argv = %s' %argv args = backintime.argParse(argv) self.assertIn('quiet', args, msg) self.assertTrue(args.quiet, msg) self.assertIn('checksum', args, msg) self.assertTrue(args.checksum, msg) self.assertIn('profile_id', args, msg) self.assertEqual(args.profile_id, 2, msg) self.assertIn('command', args, msg) self.assertEqual(args.command, 'restore', msg) self.assertIn('WHAT', args, msg) self.assertEqual(args.WHAT, '/home', msg) self.assertIn('WHERE', args, msg) self.assertEqual(args.WHERE, '/tmp', msg) self.assertIn('SNAPSHOT_ID', args, msg) self.assertEqual(args.SNAPSHOT_ID, '20151130-230501-984', msg) self.assertIn('local_backup', args, msg) self.assertTrue(args.local_backup, msg) self.assertIn('delete', args, msg) self.assertTrue(args.delete, msg) self.assertIn('config', args, msg) self.assertEqual(args.config, 'foo', msg) def test_multi_args(self): for argv in shuffleArgs(('--profile-id', '2'), '--quiet', 'restore', '--checksum', '--local-backup', '--delete', ('--config', 'foo')): with self.subTest(argv = argv): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'argv = %s' %argv args = backintime.argParse(argv) self.assertIn('quiet', args, msg) self.assertTrue(args.quiet, msg) self.assertIn('checksum', args, msg) self.assertTrue(args.checksum, msg) self.assertIn('profile_id', args, msg) self.assertEqual(args.profile_id, 2, msg) self.assertIn('command', args, msg) self.assertEqual(args.command, 'restore', msg) self.assertIn('local_backup', args, msg) self.assertTrue(args.local_backup, msg) self.assertIn('delete', args, msg) self.assertTrue(args.delete, msg) self.assertIn('config', args, msg) self.assertEqual(args.config, 'foo', msg) def test_snapshot_id_index(self): args = backintime.argParse(['restore', '/home', '/tmp', '1']) self.assertIn('SNAPSHOT_ID', args) self.assertEqual(args.SNAPSHOT_ID, '1') def test_empty_where(self): args = backintime.argParse(['restore', '/home', '', '20151130-230501-984']) self.assertIn('WHERE', args) self.assertEqual(args.WHERE, '') def test_where_space_in_path(self): args = backintime.argParse(['restore', '/home', '/tmp/foo bar/baz', '20151130-230501-984']) self.assertIn('WHERE', args) self.assertEqual(args.WHERE, '/tmp/foo bar/baz') def test_what_space_in_path(self): args = backintime.argParse(['restore', '/home/foo bar/baz', '/tmp', '20151130-230501-984']) self.assertIn('WHAT', args) self.assertEqual(args.WHAT, '/home/foo bar/baz') def test_local_backup_and_no_local_backup(self): with self.assertRaises(SystemExit): backintime.argParse(('restore', '--local-backup', '--no-local-backup')) if __name__ == '__main__': unittest.main() backintime-1.5.4/common/test/test_backintime.py000066400000000000000000000230761477034762000216370ustar00rootroot00000000000000# SPDX-FileCopyrightText: 2016 Taylor Raack # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import os import re import subprocess import sys from test import generic import json import config import version sys.path.append(os.path.join(os.path.dirname(__file__), '..')) class BackInTime(generic.TestCase): def test_quiet_mode(self): output = subprocess.getoutput('python3 backintime.py --quiet') # Remove "WARNING:" and "ERROR:" messages from output. # They should appear even in quite-mode. output = filter(lambda line: not line.startswith('WARNING:') and not line.startswith('ERROR:'), output.split('\n')) output = '\n'.join(list(output)) self.assertEqual('', output) def test_local_snapshot_is_successful(self): """From BIT initialization through snapshot From BIT initialization all the way through successful snapshot on a local mount. test one of the highest level interfaces a user could work with - the command line ensures that argument parsing, functionality, and output all work as expected is NOT intended to replace individual method tests, which are incredibly useful as well. Development notes (by Buhtz, 2023): Multiple tests do compare return codes and output on stdout. It is NOT tested what is on the file system. The intention might be a system test. But the asserts not qualified to answer the important questions and observe the intended behavior. Heavy refactoring is needed. But because of the "level" of that tests it won't happen in the near future. Also maintenance costs of this tests are damn high because every tiny modification of BIT gives a false fail of this test. Development notes (by Buhtz, 2024-05): It is just dumb stdout parsing. I tend to remove this test because of the calculation of its value and its maintenance costs. """ # ensure that we see full diffs of assert output if there are any self.maxDiff = None # create pristine source directory with single file subprocess.getoutput("chmod -R a+rwx /tmp/test && rm -rf /tmp/test") os.mkdir('/tmp/test') with open('/tmp/test/testfile', 'w') as f: f.write('some data') # create pristine snapshot directory subprocess.getoutput( "chmod -R a+rwx /tmp/snapshots && rm -rf /tmp/snapshots") os.mkdir('/tmp/snapshots') # remove restored directory subprocess.getoutput("rm -rf /tmp/restored") # install proper destination filesystem structure and verify output proc = subprocess.Popen(["./backintime", "--config", "test/config", "--share-path", self.sharePath, "check-config", # do not overwrite users crontab "--no-crontab"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() msg = 'Returncode: {}\nstderr: {}\nstdout: {}' \ .format(proc.returncode, error.decode(), output.decode()) self.assertEqual(proc.returncode, 0, msg) self.assertRegex(output.decode(), re.compile(r''' Back In Time Version: \d+.\d+.\d+.* Back In Time comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; type `backintime --license' for details. (INFO: Update to config version \d+ )? \+--------------------------------\+ | Check/prepare snapshot path | \+--------------------------------\+ Check/prepare snapshot path: done \+--------------------------------\+ | Check config | \+--------------------------------\+ Check config: done Config .*test/config profile 'Main profile' is fine.''', re.MULTILINE)) # execute backup and verify output proc = subprocess.Popen(["./backintime", "--config", "test/config", "--share-path", self.sharePath, "backup"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() msg = 'Returncode: {}\nstderr: {}\nstdout: {}' \ .format(proc.returncode, error.decode(), output.decode()) self.assertEqual(proc.returncode, 0, msg) self.assertRegex(output.decode(), re.compile(r''' Back In Time Version: \d+.\d+.\d+.* Back In Time comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; type `backintime --license' for details. ''', re.MULTILINE)) # Workaround until refactoring was done (Buhtz, Feb.'23) # The log output completely goes to stderr. # Note: DBus warnings at the begin and end are already ignored by the # regex but if the BiT serviceHelper.py DBus daemon is not # installed at all the warnings also occur in the middle of below # expected INFO log lines so they are removed by filtering here. # The same goes with Gtk warnings. line_beginnings_to_exclude = [ "WARNING", "Warning", ] # Warnings currently known: # - "WARNING: D-Bus message:" # - "WARNING: Udev-based profiles cannot be changed or checked" # - "WARNING: Inhibit Suspend failed" # - "Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use # QT_QPA_PLATFORM=wayland to run on Wayland anyway" line_contains_to_exclude = [ "Gtk-WARNING", "qt.qpa.plugin: Could not find the Qt platform plugin", 'qt.dbus.integration: Could not connect "org.freedesktop.IBus" ' 'to globalEngineChanged(QString)', ] # remove lines via startswith() filtered_log_output = filter( lambda line: not any([ line.startswith(ex) for ex in line_beginnings_to_exclude]), error.decode().split('\n') ) # remove lines via __contains__() filtered_log_output = filter( lambda line: not any([ ex in line for ex in line_contains_to_exclude]), filtered_log_output ) # remove empty lines filtered_log_output = filter( lambda line: line, filtered_log_output ) filtered_log_output = '\n'.join(filtered_log_output) self.assertRegex(filtered_log_output, re.compile(r'''INFO: Lock INFO: Take a new snapshot. Profile: 1 Main profile INFO: Call rsync to take the snapshot INFO: Save config file INFO: Save permissions INFO: Unlock''', re.MULTILINE)) # get snapshot id subprocess.check_output(["./backintime", "--config", "test/config", "snapshots-list"]) # execute restore and verify output proc = subprocess.Popen(["./backintime", "--config", "test/config", "--share-path", self.sharePath, "restore", "/tmp/test/testfile", "/tmp/restored", "0"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() msg = 'Returncode: {}\nstderr: {}\nstdout: {}' \ .format(proc.returncode, error.decode(), output.decode()) self.assertEqual(proc.returncode, 0, msg) self.assertRegex(output.decode(), re.compile(r''' Back In Time Version: \d+.\d+.\d+.* Back In Time comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions; type `backintime --license' for details. ''', re.MULTILINE)) # The log output completely goes to stderr self.assertRegex( error.decode(), re.compile( r'''INFO: Restore: /tmp/test/testfile to: /tmp/restored.*''', re.MULTILINE ) ) # verify that files restored are the same as those backed up subprocess.check_output(["diff", "-r", "/tmp/test", "/tmp/restored"]) def test_diagnostics_arg(self): # "output" from stdout may currently be polluted with logging output # lines from INFO and DEBUG log output. # Logging output of WARNING and ERROR is already written to stderr # so `check_output` does work here (returns only stdout without # stderr). output = subprocess.check_output(["./backintime", "--diagnostics"]) diagnostics = json.loads(output) self.assertEqual(diagnostics["backintime"]["name"], config.Config.APP_NAME) self.assertEqual(diagnostics["backintime"]["version"], version.__version__) backintime-1.5.4/common/test/test_backup.py000066400000000000000000000215451477034762000207750ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys from unittest.mock import patch, ANY from datetime import datetime from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import backintime import config import snapshots import tools import logger from applicationinstance import ApplicationInstance from pluginmanager import PluginManager from mount import Mount from exceptions import MountException @patch('time.sleep') # speed up unittest class TestBackup(generic.SnapshotsTestCase): @patch('snapshots.Snapshots.takeSnapshot') def test_backup(self, takeSnapshot, sleep): takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), False) self.assertEqual(takeSnapshot.call_count, 1) self.assertIsInstance(takeSnapshot.call_args[0][0], snapshots.SID) self.assertIsInstance(takeSnapshot.call_args[0][1], datetime) self.assertIsInstance(takeSnapshot.call_args[0][2], list) @patch('subprocess.Popen', autospec=True) def test_backup_async(self, Popen_mock, sleep): """:py:func:`backintime.takeSnapshotAsync`: Tests if the command for async execution is created as expected but does not execute it. Uses only default arguments. """ # Deactivate debug mode (is True on TravisCI due to "make unittest-v") # otherwise the OuT adds "--debug" to the cmd args (fails assertions) # The value will be reset in the setup() of the test. logger.DEBUG = False self.assertIsNone( backintime.takeSnapshotAsync(self.cfg, checksum=False)) expected_call = [ 'backintime', '--config', self.cfgFile, '--share-path', self.cfg.DATA_FOLDER_ROOT, 'backup' ] Popen_mock.assert_called_once_with(expected_call, env=ANY) @patch('subprocess.Popen', autospec=True) def test_backup_async_with_checksum(self, Popen_mock, sleep): """:py:func:`backintime.takeSnapshotAsync`: Tests if the command for async execution is created as expected but does not execute it. Uses ``checksum=True`` as non-default argument. """ # Deactivate debug mode (is True on TravisCI due to "make unittest-v") # otherwise the OuT adds "--debug" to the cmd args (fails assertions) # The value will be reset in the setup() of the test. logger.DEBUG = False self.assertIsNone( backintime.takeSnapshotAsync(self.cfg, checksum=True)) expected_call = [ 'backintime', '--config', self.cfgFile, '--share-path', self.cfg.DATA_FOLDER_ROOT, '--checksum', 'backup' ] Popen_mock.assert_called_once_with(expected_call, env=ANY) @patch('subprocess.Popen', autospec=True) def test_backup_async_profile_2(self, Popen_mock, sleep): """:py:func:`backintime.takeSnapshotAsync`: Tests if the command for async execution is created as expected but does not execute it. Uses a non-default profile (created for the test only). """ # Deactivate debug mode (is True on TravisCI due to "make unittest-v") # otherwise the OuT adds "--debug" to the cmd args (fails assertions) # The value will be reset in the setup() of the test. logger.DEBUG = False # Create and use a (new) profile (not the default '1') new_profile_id = self.cfg.addProfile("Profile #2") self.cfg.setCurrentProfile(new_profile_id) self.assertIsNone( backintime.takeSnapshotAsync(self.cfg, checksum=False)) expected_call = [ 'backintime', '--profile-id', new_profile_id, '--config', self.cfgFile, '--share-path', self.cfg.DATA_FOLDER_ROOT, 'backup' ] Popen_mock.assert_called_once_with(expected_call, env=ANY) @patch('snapshots.Snapshots.takeSnapshot') def test_no_changes(self, takeSnapshot, sleep): takeSnapshot.return_value = [False, False] self.assertIs(self.sn.backup(), False) self.assertTrue(takeSnapshot.called) sid = takeSnapshot.call_args[0][0] newSnapshot = snapshots.NewSnapshot(self.cfg) self.assertFalse(newSnapshot.exists()) self.assertFalse(sid.exists()) @patch('snapshots.Snapshots.takeSnapshot') def test_with_errors(self, takeSnapshot, sleep): takeSnapshot.return_value = [False, True] self.assertIs(self.sn.backup(), True) @patch('tools.onBattery') @patch('snapshots.Snapshots.takeSnapshot') def test_no_backup_on_battery(self, takeSnapshot, onBattery, sleep): self.cfg.setNoSnapshotOnBattery(True) takeSnapshot.return_value = [True, False] # run on battery onBattery.return_value = True self.assertFalse(self.sn.backup(force=False)) self.assertFalse(takeSnapshot.called) # force run self.assertFalse(self.sn.backup(force=True)) self.assertTrue(takeSnapshot.called) takeSnapshot.reset_mock() # ignore Battery self.cfg.setNoSnapshotOnBattery(False) self.assertFalse(self.sn.backup(force=False)) self.assertTrue(takeSnapshot.called) @patch('snapshots.Snapshots.takeSnapshot') def test_scheduled(self, takeSnapshot, sleep): # first run without timestamp takeSnapshot.return_value = [True, False] self.assertFalse(self.sn.backup(force=False)) self.assertTrue(takeSnapshot.called) takeSnapshot.reset_mock() # second run doesn't use an anacron-like schedule tools.writeTimeStamp(self.cfg.anacronSpoolFile()) self.assertFalse(self.sn.backup(force=False)) self.assertTrue(takeSnapshot.called) takeSnapshot.reset_mock() # third run uses anacron-like schedule so it should not run self.cfg.setScheduleMode(self.cfg.REPEATEDLY) self.assertFalse(self.sn.backup(force=False)) self.assertFalse(takeSnapshot.called) # finally force self.assertFalse(self.sn.backup(force=True)) self.assertTrue(takeSnapshot.called) @patch.object(ApplicationInstance, 'check') @patch('snapshots.Snapshots.takeSnapshot') def test_already_running(self, takeSnapshot, check, sleep): check.return_value = False takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), True) self.assertFalse(takeSnapshot.called) @patch.object(PluginManager, 'processBegin') @patch('snapshots.Snapshots.takeSnapshot') def test_plugin_prevented_backup(self, takeSnapshot, processBegin, sleep): processBegin.return_value = False takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), True) self.assertFalse(takeSnapshot.called) @patch.object(config.Config, 'isConfigured') @patch('snapshots.Snapshots.takeSnapshot') def test_not_configured(self, takeSnapshot, isConfigured, sleep): isConfigured.return_value = False takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), True) self.assertFalse(takeSnapshot.called) @patch.object(Mount, 'mount') @patch('snapshots.Snapshots.takeSnapshot') def test_mount_exception(self, takeSnapshot, mount, sleep): mount.side_effect = MountException() takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), True) self.assertFalse(takeSnapshot.called) @patch.object(Mount, 'umount') @patch('snapshots.Snapshots.takeSnapshot') def test_umount_exception(self, takeSnapshot, umount, sleep): umount.side_effect = MountException() takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), False) @patch.object(config.Config, 'canBackup') @patch('snapshots.Snapshots.takeSnapshot') def test_cant_backup(self, takeSnapshot, canBackup, sleep): canBackup.return_value = False takeSnapshot.return_value = [True, False] self.assertIs(self.sn.backup(), True) self.assertFalse(takeSnapshot.called) @patch('snapshots.Snapshots.takeSnapshot') def test_takeSnapshot_exception_cleanup(self, takeSnapshot, sleep): takeSnapshot.side_effect = Exception('Boom') new = snapshots.NewSnapshot(self.cfg) new.makeDirs() self.assertTrue(new.exists()) with self.assertRaises(Exception): self.sn.backup() self.assertFalse(new.saveToContinue) self.assertTrue(new.failed) backintime-1.5.4/common/test/test_config.py000066400000000000000000000205661477034762000207770ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016 Taylor Raack # SPDX-FileCopyrightText: © 2025 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Tests about config module. """ import os import sys import getpass import unittest import datetime from unittest.mock import patch from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import config class RemoveOldSnapshotsDate(unittest.TestCase): def test_invalid_unit(self): """1st January Year 1 on errors""" unit = 99999 value = 99 self.assertEqual( config._remove_old_snapshots_date(value, unit), datetime.date(1, 1, 1)) @patch('datetime.date', wraps=datetime.date) def test_day(self, m): """Three days""" m.today.return_value = datetime.date(2025, 1, 10) sut = config._remove_old_snapshots_date(3, config.Config.DAY) self.assertEqual(sut, datetime.date(2025, 1, 7)) @patch('datetime.date', wraps=datetime.date) def test_week_always_monday(self, m): """Result is always a Monday""" # 1-53 weeks back for weeks in range(1, 54): start = datetime.date(2026, 1, 1) # Every day in the year for count in range(366): m.today.return_value = start - datetime.timedelta(days=count) sut = config._remove_old_snapshots_date( weeks, config.Config.WEEK) # 0=Monday self.assertEqual(sut.weekday(), 0, f'{sut=} {weeks=}') @patch('datetime.date', wraps=datetime.date) def test_week_ignore_current(self, m): """Current (incomplete) week is ignored.""" for day in range(25, 32): # Monday (25th) to Sunday (31th) m.today.return_value = datetime.date(2025, 8, day) sut = config._remove_old_snapshots_date(2, config.Config.WEEK) self.assertEqual( sut, datetime.date(2025, 8, 11) # Monday ) @patch('datetime.date', wraps=datetime.date) def test_year_ignore_current_month(self, m): """Not years but 12 months are counted. But current month is ignored.""" m.today.return_value = datetime.date(2025, 7, 30) sut = config._remove_old_snapshots_date(2, config.Config.YEAR) self.assertEqual(sut, datetime.date(2023, 7, 1)) class SshCommand(generic.SSHTestCase): @classmethod def setUpClass(cls): cls._user = getpass.getuser() def test_full_command(self): cmd = self.cfg.sshCommand(cmd=['echo', 'foo']) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', 'echo', 'foo' ] ) def test_custom_args(self): cmd = self.cfg.sshCommand( cmd=['echo', 'foo'], custom_args=['-o', 'PreferredAuthentications=publickey']) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', '-o', 'PreferredAuthentications=publickey', f'{self._user}@localhost', 'echo', 'foo' ] ) def test_cipher_aes256_cbc(self): self.cfg.setSshCipher('aes256-cbc') cmd = self.cfg.sshCommand(cmd=['echo', 'foo']) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', '-o', 'Ciphers=aes256-cbc', f'{self._user}@localhost', 'echo', 'foo' ] ) def test_cipher_disabled(self): cmd = self.cfg.sshCommand(cmd=['echo', 'foo'], cipher=False) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', 'echo', 'foo' ] ) def test_without_command(self): cmd = self.cfg.sshCommand() self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', ] ) def test_nice_and_ionice(self): self.cfg.setNiceOnRemote(True) self.cfg.setIoniceOnRemote(True) cmd = self.cfg.sshCommand(cmd=['echo', 'foo']) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', 'ionice', '-c2', '-n7', 'nice', '-n19', 'echo', 'foo' ] ) def test_nice_and_ionice_without_command(self): self.cfg.setNiceOnRemote(True) self.cfg.setIoniceOnRemote(True) cmd = self.cfg.sshCommand() self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', ] ) def test_quote(self): cmd = self.cfg.sshCommand(cmd=['echo', 'foo'], quote=True) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', "'", 'echo', 'foo', "'" ] ) def test_quote_without_command(self): cmd = self.cfg.sshCommand(quote=True) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', ] ) def test_prefix(self): self.cfg.setSshPrefix(True, 'echo bar') cmd = self.cfg.sshCommand(cmd=['echo', 'foo']) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', 'echo', 'bar', 'echo', 'foo' ] ) def test_prefix_false(self): # disable prefix cmd = self.cfg.sshCommand(cmd=['echo', 'foo'], prefix=False) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', '-p', '22', f'{self._user}@localhost', 'echo', 'foo' ] ) def test_disable_args(self): cmd = self.cfg.sshCommand(port=False, user_host=False) self.assertListEqual( cmd, [ 'ssh', '-o', 'ServerAliveInterval=240', '-o', 'LogLevel=Error', '-o', f'IdentityFile={generic.PRIV_KEY_FILE}', ] ) backintime-1.5.4/common/test/test_config_crontab.py000066400000000000000000000113401477034762000224750ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian Buhtz # SPDX-FileCopyrightText: © 2024 Kosta Vukicevic # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests about Cron-related behavior of the config module. See also test_schedule.py for low-level-Cron-behavior implemented in schedule module.""" import inspect import os import sys import tempfile import unittest from pathlib import Path from unittest import mock import pyfakefs.fake_filesystem_unittest as pyfakefs_ut sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import config class Cron(unittest.TestCase): """Cron-related behavior of Config class.""" def test_cron_lines(self): """Creation of crontab lines per profile""" # Mock reading a config file with mock.patch('configfile.ConfigFile.append'): cfg = config.Config() # Profile 1 (default profile) cfg.setScheduleMode(12) # 12 = every two hours # Profile 2 profile_id = cfg.addProfile('NoSchedule') self.assertEqual(profile_id, '2') # Profile 3 profile_id = cfg.addProfile('Second') self.assertEqual(profile_id, '3') cfg.setScheduleMode(7, profile_id) # 7 = every 30 minutes result = cfg.profiles_cron_lines() self.assertEqual(len(result), 2) self.assertIn('*/2 * * *', result[0]) self.assertIn('backintime', result[0]) self.assertIn('backup-job', result[0]) self.assertNotIn('--profile-id', result[0]) self.assertIn('*/30 * * *', result[1]) self.assertIn('backintime', result[1]) self.assertIn('backup-job', result[1]) self.assertIn('--profile-id 3', result[1]) class CrontabDebug(pyfakefs_ut.TestCase): """Debug behavior when scheduled via crontab""" def setUp(self): """Setup a fake filesystem with a config file.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = tempfile.TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self.config_fp = self._create_config_file(parent_path=self.temp_path) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=duplicate-code cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # pylint: disable=R0801 # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp @mock.patch('tools.which', return_value='backintime') def test_crontab_contains_debug(self, mock_which): """ About mock_which: A workaround because the function gives false-negative when using a fake filesystem. """ conf = config.Config(str(self.config_fp)) # set and assert start conditions conf.setScheduleDebug(True) self.assertTrue(conf.scheduleDebug()) sut = conf._cron_cmd(profile_id='1') self.assertIn('--debug', sut) @mock.patch('tools.which', return_value='backintime') def test_crontab_without_debug(self, mock_which): """No debug output in crontab line. About mock_which: See test_crontab_with_debug(). """ conf = config.Config(str(self.config_fp)) # set and assert start conditions conf.setScheduleDebug(False) self.assertFalse(conf.scheduleDebug()) sut = conf._cron_cmd(profile_id='1') self.assertNotIn('--debug', sut) backintime-1.5.4/common/test/test_configfile.py000066400000000000000000000657241477034762000216440ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys from tempfile import NamedTemporaryFile import unittest from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import configfile class TestConfigFile(generic.TestCase): """ Tests for the ConfigFile class in the configfile module """ def test_save(self): """ Saves the config file in the tmp directory """ with NamedTemporaryFile() as cfgFile: cf = configfile.ConfigFile() self.assertTrue(cf.save(cfgFile.name)) self.assertExists(cfgFile.name) #test fail routine in ConfigFile.save with NamedTemporaryFile() as fakeDir: self.assertFalse(cf.save(os.path.join(fakeDir.name, 'foo'))) def test_load(self): """ ConfigFile should be able to load its content from a previously saved ConfigFile object. """ with NamedTemporaryFile() as cfgFile: original_cf = configfile.ConfigFile() key = "config_key" value = "config_value" original_cf.setStrValue(key, value) original_cf.save(cfgFile.name) cf = configfile.ConfigFile() cf.load(cfgFile.name) self.assertEqual(len(cf.keys()), len(original_cf.keys())) for k in original_cf.keys(): with self.subTest(k = k): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'k = %s' %k self.assertTrue(cf.hasKey(k), msg) self.assertEqual(original_cf.strValue(k), cf.strValue(k)) def test_remapKey(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': '123', 'bar': '456'} #old key not in dict cfg.remapKey('notExistedKey', 'baz') self.assertEqual(cfg.strValue('foo'), '123') self.assertEqual(cfg.strValue('bar'), '456') #valid remap cfg.remapKey('foo', 'baz') self.assertEqual(cfg.strValue('foo'), '') self.assertEqual(cfg.strValue('baz'), '123') self.assertEqual(cfg.strValue('bar'), '456') #do not overwrite existing keys cfg.remapKey('baz', 'bar') self.assertEqual(cfg.strValue('baz'), '') self.assertEqual(cfg.strValue('bar'), '456') def test_remapKeyRegex(self): cfg = configfile.ConfigFile() cfg.dict = {'asdf.foo.qwertz': '123', 'foo.qwertz': '456', 'asdf.foo': '789', 'yxcv': 'jkl'} cfg.remapKeyRegex('foo', 'bar') self.assertEqual(cfg.strValue('asdf.bar.qwertz', 'WrongValue'), '123') self.assertEqual(cfg.strValue('bar.qwertz', 'WrongValue'), '456') self.assertEqual(cfg.strValue('asdf.bar', 'WrongValue'), '789') self.assertEqual(cfg.strValue('asdf.foo.qwertz', ''), '') self.assertEqual(cfg.strValue('foo.qwertz', ''), '') self.assertEqual(cfg.strValue('asdf.foo', ''), '') self.assertEqual(cfg.strValue('yxcv', 'WrongValue'), 'jkl') def test_hasKey(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'bar'} self.assertTrue(cfg.hasKey('foo')) self.assertFalse(cfg.hasKey('non_existend_key')) ############################################################################ ### str_value ### ############################################################################ def test_strValue(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'bar'} self.assertEqual(cfg.strValue('foo', 'default'), 'bar') def test_strValue_default(self): cfg = configfile.ConfigFile() self.assertEqual(cfg.strValue('non_existend_key', 'default'), 'default') def test_setStrValue(self): cfg = configfile.ConfigFile() cfg.setStrValue('foo', 'bar') self.assertDictEqual(cfg.dict, {'foo': 'bar'}) ############################################################################ ### int_value ### ############################################################################ def test_intValue(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': '11'} self.assertEqual(cfg.intValue('foo', 22), 11) def test_intValue_default(self): cfg = configfile.ConfigFile() self.assertEqual(cfg.intValue('non_existend_key', 33), 33) def test_setIntValue(self): cfg = configfile.ConfigFile() cfg.setIntValue('foo', 44) self.assertDictEqual(cfg.dict, {'foo': '44'}) ############################################################################ ### bool_value ### ############################################################################ def test_boolValue(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'true', 'bar': '1', 'baz': 'false', 'bla': '0'} self.assertEqual(cfg.boolValue('foo', False), True) self.assertEqual(cfg.boolValue('bar', False), True) self.assertEqual(cfg.boolValue('baz', True), False) self.assertEqual(cfg.boolValue('bla', True), False) def test_boolValue_default(self): cfg = configfile.ConfigFile() self.assertEqual(cfg.boolValue('non_existend_key', False), False) self.assertEqual(cfg.boolValue('non_existend_key', True), True) def test_setBoolValue(self): cfg = configfile.ConfigFile() cfg.setBoolValue('foo', True) cfg.setBoolValue('bar', False) self.assertDictEqual(cfg.dict, {'foo': 'true', 'bar': 'false'}) ############################################################################ ### listValue ### ############################################################################ def test_listValue_default(self): cfg = configfile.ConfigFile() self.assertListEqual(cfg.listValue('test', 'str:value', ['asdf']), ['asdf']) def test_listValue_int(self): cfg = configfile.ConfigFile() cfg.dict = {'aaa.size': '3', 'aaa.1.bla': '55', 'aaa.2.bla': '66', 'aaa.3.bla': '77'} self.assertListEqual(cfg.listValue('aaa', 'int:bla'), [55, 66, 77]) def test_listValue_str(self): cfg = configfile.ConfigFile() cfg.dict = {'bbb.size': '3', 'bbb.1.value': 'foo', 'bbb.2.value': 'bar', 'bbb.3.value': 'baz'} self.assertListEqual(cfg.listValue('bbb', 'str:value'), ['foo', 'bar', 'baz']) def test_listValue_bool(self): cfg = configfile.ConfigFile() cfg.dict = {'ccc.size': '2', 'ccc.1.foo': 'true', 'ccc.2.foo': 'false'} self.assertListEqual(cfg.listValue('ccc', 'bool:foo'), [True, False]) def test_listValue_tuple(self): cfg = configfile.ConfigFile() cfg.dict = {'ddd.size': '3', 'ddd.1.value': 'foo', 'ddd.1.type': '11', 'ddd.1.enabled': 'true', 'ddd.2.value': 'bar', 'ddd.2.type': '22', 'ddd.2.enabled': 'false', 'ddd.3.value': 'baz', 'ddd.3.type': '33', 'ddd.3.enabled': 'true'} self.assertListEqual(cfg.listValue('ddd', ('str:value', 'int:type', 'bool:enabled')), [('foo', 11, True), ('bar', 22, False), ('baz', 33, True)]) def test_listValue_tuple_missing_values(self): """ Don't include missing values. Bug #521 https://github.com/bit-team/backintime/issues/521 """ cfg = configfile.ConfigFile() cfg.dict = {'eee.size': '3', 'eee.1.value': 'foo', 'eee.1.enabled': 'true', 'eee.2.type': '22', 'eee.2.enabled': 'false', 'eee.3.value': 'baz', 'eee.3.type': '33'} self.assertListEqual(cfg.listValue('eee', ('str:value', 'int:type', 'bool:enabled')), [('foo', 0, True), ('baz', 33, False)]) def test_listValue_invalid_type(self): cfg = configfile.ConfigFile() cfg.dict = {'aaa.size': '3', 'aaa.1.value': '55', 'aaa.2.value': '66', 'aaa.3.value': '77'} with self.assertRaises(TypeError): cfg.listValue('aaa', 'non_existend_type:value') with self.assertRaises(TypeError): cfg.listValue('aaa', {'dict:value'}) with self.assertRaises(TypeError): cfg.listValue('aaa', 1) def test_listValue_wrong_size(self): """ Don't include empty values if size is wrong. Bug #521 https://github.com/bit-team/backintime/issues/521 """ cfg = configfile.ConfigFile() cfg.dict = {'bbb.size': '4', 'bbb.1.value': 'foo', 'bbb.2.value': 'bar', 'bbb.3.value': 'baz'} self.assertListEqual(cfg.listValue('bbb', 'str:value'), ['foo', 'bar', 'baz']) def test_listValue_zero_count(self): cfg = configfile.ConfigFile() cfg.dict = {'ccc.size': '2', 'ccc.0.value': 'foo', 'ccc.1.value': 'bar', 'ccc.2.value': 'baz'} self.assertListEqual(cfg.listValue('ccc', 'str:value'), ['bar', 'baz']) def test_listValue_missing_values(self): """ Don't include missing values. Bug #521 https://github.com/bit-team/backintime/issues/521 """ cfg = configfile.ConfigFile() cfg.dict = {'ddd.size': '4', 'ddd.1.value': 'foo', 'ddd.2.value': 'bar', 'ddd.4.value': 'baz'} self.assertListEqual(cfg.listValue('ddd', 'str:value'), ['foo', 'bar', 'baz']) def test_listValue_empty_list(self): cfg = configfile.ConfigFile() cfg.dict = {'eee.size': '0'} self.assertListEqual(cfg.listValue('eee', 'str:value', default = ['foo', 'bar']), []) ############################################################################ ### setListValue ### ############################################################################ def test_setListValue_int(self): cfg = configfile.ConfigFile() cfg.setListValue('aaa', 'int:bla', [55, 66, 77]) self.assertDictEqual(cfg.dict, {'aaa.size': '3', 'aaa.1.bla': '55', 'aaa.2.bla': '66', 'aaa.3.bla': '77'}) def test_setListValue_str(self): cfg = configfile.ConfigFile() cfg.setListValue('bbb', 'str:value', ['foo', 'bar', 'baz']) self.assertDictEqual(cfg.dict, {'bbb.size': '3', 'bbb.1.value': 'foo', 'bbb.2.value': 'bar', 'bbb.3.value': 'baz'}) def test_setListValue_bool(self): cfg = configfile.ConfigFile() cfg.setListValue('ccc', 'bool:foo', [True, False]) self.assertDictEqual(cfg.dict, {'ccc.size': '2', 'ccc.1.foo': 'true', 'ccc.2.foo': 'false'}) def test_setListValue_tuple(self): cfg = configfile.ConfigFile() cfg.setListValue('ddd', ('str:value', 'int:type', 'bool:enabled'), [('foo', 11, True), ('bar', 22, False), ('baz', 33, True)]) self.assertDictEqual(cfg.dict, {'ddd.size': '3', 'ddd.1.value': 'foo', 'ddd.1.type': '11', 'ddd.1.enabled': 'true', 'ddd.2.value': 'bar', 'ddd.2.type': '22', 'ddd.2.enabled': 'false', 'ddd.3.value': 'baz', 'ddd.3.type': '33', 'ddd.3.enabled': 'true'}) def test_setListValue_tuple_missing_values(self): cfg = configfile.ConfigFile() cfg.setListValue('ddd', ('str:value', 'int:type', 'bool:enabled'), [('foo', 11, True), ('bar', 22), ('baz',)]) self.assertDictEqual(cfg.dict, {'ddd.size': '3', 'ddd.1.value': 'foo', 'ddd.1.type': '11', 'ddd.1.enabled': 'true', 'ddd.2.value': 'bar', 'ddd.2.type': '22', 'ddd.3.value': 'baz'}) def test_setListValue_remove_leftovers(self): cfg = configfile.ConfigFile() cfg.dict = {'eee.size': '5', 'eee.1.bla': '55', 'eee.2.bla': '66', 'eee.3.bla': '77', 'eee.4.bla': '88', 'eee.5.bla': '99'} cfg.setListValue('eee', 'int:bla', [55, 66, 77]) self.assertDictEqual(cfg.dict, {'eee.size': '3', 'eee.1.bla': '55', 'eee.2.bla': '66', 'eee.3.bla': '77'}) def test_setListValue_remove_leftovers_tuple(self): cfg = configfile.ConfigFile() cfg.dict = {'fff.size': '5', 'fff.1.value': 'foo', 'fff.1.type': '11', 'fff.1.enabled': 'true', 'fff.2.value': 'bar', 'fff.2.type': '22', 'fff.2.enabled': 'false', 'fff.3.value': 'baz', 'fff.3.type': '33', 'fff.3.enabled': 'true', 'fff.4.value': 'boom', 'fff.4.type': '44', 'fff.4.enabled': 'true', 'fff.5.value': 'bam', 'fff.5.type': '55', 'fff.5.enabled': 'true'} cfg.setListValue('fff', ('str:value', 'int:type', 'bool:enabled'), [('foo', 11, True), ('bar', 22), ('baz',)]) self.assertDictEqual(cfg.dict, {'fff.size': '3', 'fff.1.value': 'foo', 'fff.1.type': '11', 'fff.1.enabled': 'true', 'fff.2.value': 'bar', 'fff.2.type': '22', 'fff.3.value': 'baz'}) def test_setListValue_invalid_type_for_type_key(self): cfg = configfile.ConfigFile() with self.assertRaises(TypeError): cfg.setListValue('aaa', 'non_existend_type:value', ['foo',]) with self.assertRaises(TypeError): cfg.setListValue('aaa', {'dict:value'}, ['foo',]) with self.assertRaises(TypeError): cfg.setListValue('aaa', 1, ['foo',]) def test_setListValue_invalid_type_for_value(self): cfg = configfile.ConfigFile() with self.assertRaises(TypeError): cfg.setListValue('bbb', 'str:value', 'foo') with self.assertRaises(TypeError): cfg.setListValue('bbb', 'str:value', {'foo': 'bar'}) ############################################################################ ### remove keys ### ############################################################################ def test_remove_key(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'true', 'bar': '1', 'baz': 'false', 'bla': '0'} cfg.removeKey('bla') self.assertDictEqual(cfg.dict, {'foo': 'true', 'bar': '1', 'baz': 'false'}) def test_remove_keys_start_with(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'true', 'bar': '1', 'baz': 'false', 'bla': '0'} cfg.removeKeysStartsWith('ba') self.assertDictEqual(cfg.dict, {'foo': 'true', 'bla': '0'}) def test_remove_keys_start_with_not_matching_prefix(self): cfg = configfile.ConfigFile() cfg.dict = {'foo': 'true', 'bar': '1', 'baz': 'false', 'bla': '0'} cfg.removeKeysStartsWith('not_matching') self.assertDictEqual(cfg.dict, {'foo': 'true', 'bar': '1', 'baz': 'false', 'bla': '0'}) class TestConfigFileWithProfiles(generic.TestCase): def setUp(self): super(TestConfigFileWithProfiles, self).setUp() self.cfg = configfile.ConfigFileWithProfiles('DefaultProfileName') self.cfg.addProfile('foo') self.cfg.addProfile('bar') self.cfg.addProfile('baz') def test_load(self): """ ConfigFile should be able to load its content from a previously saved ConfigFile object. """ with NamedTemporaryFile() as cfgFile: origCfg = configfile.ConfigFileWithProfiles() origCfg.setIntValue('profiles.version', 1) key = "config_key" value = "config_value" origCfg.setProfileStrValue(key, value) origCfg.setProfileStrValue(key, value, profile_id = '2') origCfg.save(cfgFile.name) self.cfg.load(cfgFile.name) self.assertEqual(len(self.cfg.keys()), len(origCfg.keys())) for k in origCfg.keys(): with self.subTest(k = k): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'k = %s' %k self.assertTrue(self.cfg.hasKey(k), msg) self.assertEqual(origCfg.strValue(k), self.cfg.strValue(k)) def test_profiles(self): emptyCfg = configfile.ConfigFileWithProfiles() self.assertListEqual(emptyCfg.profiles(), ['1',]) self.assertListEqual(self.cfg.profiles(), ['1', '2', '3', '4']) self.cfg.removeProfile('3') self.assertListEqual(self.cfg.profiles(), ['1', '2', '4']) def test_profilesSortedByName(self): self.assertListEqual(self.cfg.profilesSortedByName(), ['3', '4', '1', '2']) def test_current_profile(self): self.assertEqual(self.cfg.currentProfile(), '1') self.assertTrue(self.cfg.setCurrentProfile(4)) self.assertEqual(self.cfg.currentProfile(), '4') self.assertTrue(self.cfg.setCurrentProfile('3')) self.assertEqual(self.cfg.currentProfile(), '3') self.assertFalse(self.cfg.setCurrentProfile('9')) self.assertEqual(self.cfg.currentProfile(), '3') def test_current_profile_by_name(self): self.assertEqual(self.cfg.currentProfile(), '1') self.assertTrue(self.cfg.setCurrentProfileByName('bar')) self.assertEqual(self.cfg.currentProfile(), '3') self.assertFalse(self.cfg.setCurrentProfileByName('NotExistingProfile')) self.assertEqual(self.cfg.currentProfile(), '3') def test_profileExists(self): self.assertTrue(self.cfg.profileExists('2')) self.assertTrue(self.cfg.profileExists(3)) self.assertFalse(self.cfg.profileExists('9')) self.assertFalse(self.cfg.profileExists(10)) def test_profileExistsByName(self): self.assertTrue(self.cfg.profileExistsByName('foo')) self.assertFalse(self.cfg.profileExistsByName('NotExistingProfile')) def test_profileName(self): self.assertEqual(self.cfg.profileName('1'), 'DefaultProfileName') self.assertEqual(self.cfg.profileName('2'), 'foo') self.assertEqual(self.cfg.profileName(3), 'bar') self.assertEqual(self.cfg.profileName(), 'DefaultProfileName') self.cfg.setCurrentProfile('3') self.assertEqual(self.cfg.profileName(), 'bar') self.assertEqual(self.cfg.profileName('4'), 'baz') del self.cfg.dict['profile4.name'] self.assertEqual(self.cfg.profileName('4'), 'Profile 4') def test_addProfile(self): #add already existing profile self.assertIsNone(self.cfg.addProfile('foo')) #new valid profile self.assertEqual(self.cfg.addProfile('asdf'), '5') #new valid profile fill an old profile ID self.cfg.removeProfile('3') self.assertEqual(self.cfg.addProfile('qwertz'), '3') def test_removeProfile(self): for profile in self.cfg.profiles(): self.cfg.setProfileStrValue('foo', 'bar', profile) self.assertFalse(self.cfg.removeProfile('9')) self.assertTrue(self.cfg.removeProfile('3')) self.assertNotIn('3', self.cfg.profiles()) self.assertNotIn('profile3.foo', self.cfg.dict) self.cfg.setCurrentProfile('4') self.assertTrue(self.cfg.removeProfile()) self.assertNotIn('4', self.cfg.profiles()) self.assertNotIn('profile4.foo', self.cfg.dict) self.assertEqual(self.cfg.currentProfile(), '1') self.assertTrue(self.cfg.removeProfile(2)) self.assertNotIn('2', self.cfg.profiles()) self.assertNotIn('profile2.foo', self.cfg.dict) self.assertFalse(self.cfg.removeProfile()) def test_setProfileName(self): self.assertFalse(self.cfg.setProfileName('foo', '3')) self.assertEqual(self.cfg.profileName('3'), 'bar') self.assertTrue(self.cfg.setProfileName('newName', '4')) self.assertEqual(self.cfg.profileName('4'), 'newName') self.assertTrue(self.cfg.setProfileName('otherName', 3)) self.assertEqual(self.cfg.profileName('3'), 'otherName') self.assertTrue(self.cfg.setProfileName('thirdName')) self.assertEqual(self.cfg.profileName('1'), 'thirdName') def test_get_profile_key(self): self.assertEqual(self.cfg.profileKey('foo'), 'profile1.foo') self.assertEqual(self.cfg.profileKey('foo', '2'), 'profile2.foo') self.assertEqual(self.cfg.profileKey('foo', 3), 'profile3.foo') def test_removeProfileKey(self): for profile in self.cfg.profiles(): self.cfg.setProfileStrValue('foo', 'bar', profile) self.assertIn('profile1.foo', self.cfg.dict) self.cfg.removeProfileKey('foo') self.assertNotIn('profile1.foo', self.cfg.dict) self.assertIn('profile3.foo', self.cfg.dict) self.cfg.removeProfileKey('foo', '3') self.assertNotIn('profile3.foo', self.cfg.dict) def test_removeProfileKeysStartsWith(self): for profile in self.cfg.profiles(): self.cfg.setProfileStrValue('foo', 'bar', profile) self.assertIn('profile1.foo', self.cfg.dict) self.cfg.removeProfileKeysStartsWith('f') self.assertNotIn('profile1.foo', self.cfg.dict) self.assertIn('profile3.foo', self.cfg.dict) self.cfg.removeProfileKeysStartsWith('f', '3') self.assertNotIn('profile3.foo', self.cfg.dict) def test_remapProfileKey(self): for profile in self.cfg.profiles(): self.cfg.setProfileStrValue('foo', '123', profile) self.cfg.setProfileStrValue('bar', '456', profile) # old key not in cfg self.cfg.remapProfileKey('notExistedKey', 'baz', 1) self.assertEqual(self.cfg.profileStrValue('foo', '', 1), '123') self.assertEqual(self.cfg.profileStrValue('bar', '', 1), '456') # valid remap self.cfg.remapProfileKey('foo', 'baz', 1) self.assertEqual(self.cfg.profileStrValue('foo', '', 1), '') self.assertEqual(self.cfg.profileStrValue('baz', '', 1), '123') self.assertEqual(self.cfg.profileStrValue('foo', '', 2), '123') self.assertEqual(self.cfg.profileStrValue('foo', '', 3), '123') # do not overwrite existing keys self.cfg.remapProfileKey('foo', 'bar', 1) self.assertEqual(self.cfg.profileStrValue('foo', '', 2), '123') self.assertEqual(self.cfg.profileStrValue('baz', '', 2), '') self.assertEqual(self.cfg.profileStrValue('bar', '', 2), '456') def test_hasProfileKey(self): for profile in self.cfg.profiles(): self.cfg.setProfileStrValue('foo', 'bar', profile) self.assertTrue(self.cfg.hasProfileKey('foo')) self.assertFalse(self.cfg.hasProfileKey('baz')) self.assertTrue(self.cfg.hasProfileKey('foo', '3')) self.assertFalse(self.cfg.hasProfileKey('baz', '3')) def test_set_profile_value(self): methods = {'str': ('foo', 'FOO'), 'int': ('bar', 123), 'bool': ('baz', True)} for profile in (None, '3'): for t in methods: with self.subTest(profile = profile, t = t): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'profile = {}, t = {}'.format(profile, t) key, value = methods[t] setFunc = getattr(self.cfg, 'setProfile{}Value'.format(t.capitalize())) getFunc = getattr(self.cfg, 'profile{}Value'.format(t.capitalize())) setFunc(key, value, profile_id = profile) self.assertEqual(getFunc(key, profile_id = profile), value, msg) with self.subTest(profile = profile): #workaround for py.test3 2.5.1 doesn't support subTest msg = 'profile = {}'.format(profile) self.cfg.setProfileListValue('bla', 'str:value', ['ASDF', 'QWERTZ'], profile_id = profile) result = self.cfg.profileListValue('bla', 'str:value', profile_id = profile) self.assertListEqual(result, ['ASDF', 'QWERTZ'], msg) if __name__ == '__main__': unittest.main() backintime-1.5.4/common/test/test_diagnostics.py000066400000000000000000000070421477034762000220330ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2022 Christian Buhtz # SPDX-FileCopyrightText: © 2022 Jürgen Altfeld (aryoda) # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Test related to diagnostics.py""" import sys import pathlib import unittest # This workaround will become obsolet when migrating to src-layout sys.path.append(str(pathlib.Path(__file__).parent)) import diagnostics # testing target class Diagnostics(unittest.TestCase): """Test about collecting diagnostic infos.""" def test_content_minimal(self): """Minimal set of elements.""" sut = diagnostics.collect_minimal_diagnostics() # 1st level keys self.assertCountEqual(sut.keys(), ['backintime', 'host-setup']) # 2nd level "backintime" self.assertCountEqual( sut['backintime'].keys(), ['name', 'version', 'running-as-root']) # 2nd level "host-setup" self.assertCountEqual(sut['host-setup'].keys(), ['OS']) def test_some_content(self): """Some contained elements""" result = diagnostics.collect_diagnostics() # 1st level keys self.assertCountEqual( result.keys(), ['backintime', 'external-programs', 'host-setup', 'python-setup'] ) # 2nd level "backintime" minimal_keys = ['name', 'version', 'latest-config-version', 'started-from', 'running-as-root'] for key in minimal_keys: self.assertIn(key, result['backintime'], key) # 2nd level "host-setup" minimal_keys = ['platform', 'system', 'display-system', 'locale', 'PATH', 'RSYNC_OLD_ARGS', 'RSYNC_PROTECT_ARGS'] for key in minimal_keys: self.assertIn(key, result['host-setup'], key) # 2nd level "python-setup" self.assertIn('python', result['python-setup'], 'python') # 2nd level "external-programs" minimal_keys = ['rsync', 'shell'] for key in minimal_keys: self.assertIn(key, result['external-programs'], key) def test_no_ressource_warning(self): """No ResourceWarning's. Using subprocess.Popen() often cause ResourceWarning's when not used as a context manaager. """ # an AssertionError must be raised! See next block for explanation. with self.assertRaises(AssertionError): # We expect NO ResourceWarnings. But Python doesn't offer # assertNoWarns(). # This will raise an AssertionError because no ResourceWarning's # are raised. with self.assertWarns(ResourceWarning): diagnostics.collect_diagnostics() def test_no_extern_version(self): """Get version from not existing tool.""" self.assertEqual( diagnostics._get_extern_versions(['fooXbar']), '(no fooXbar)' ) def test_replace_user_path(self): """Replace users path.""" d = { 'foo': '/home/rsync', 'bar': '~/rsync' } self.assertEqual( diagnostics._replace_username_paths(d, 'rsync'), { 'foo': '/home/UsernameReplaced', 'bar': '~/UsernameReplaced' } ) self.assertEqual( diagnostics._replace_username_paths(d, 'user'), d ) backintime-1.5.4/common/test/test_encfstools.py000066400000000000000000000023141477034762000217000ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Taylor Raack # SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) class TestEncFS_mount(generic.TestCase): # encrypted filesystem verification seems quite complex to unit test at the # moment, partially due to UI elements being created and expecting input, # without tests for pre-prepared unit test fixture data # TODO - perhaps pass encrypted fs class object which can be queried for # passwords when necessary (so runtime can pass UI classes which can bring # up actual UI elements and return credentials or unit tests can pass # objects which can return hard coded passwords to prevent UI pop-ups in # Travis) # TODO - then - code actual tests and remove this one def setUp(self): super(TestEncFS_mount, self).setUp() def test_dummy(self): self.assertTrue(True) backintime-1.5.4/common/test/test_languages.py000066400000000000000000000016331477034762000214720ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests about the languages module.""" import unittest import languages class General(unittest.TestCase): def test_completeness_key_types(self): """Language codes as strings""" sut = set(type(k) for k in languages.completeness.keys()) self.assertEqual(len(sut), 1) sut = sut.pop() self.assertIs(sut, str) def test_completeness_value_types(self): """Completeness as integers""" sut = set(type(v) for v in languages.completeness.values()) self.assertEqual(len(sut), 1) sut = sut.pop() self.assertIs(sut, int) backintime-1.5.4/common/test/test_lint.py000066400000000000000000000315051477034762000204730ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests using several linters. Linter tests are skipped on machines where the linters are not available. As an exception only on TravisCI tests are forced to run and will fail if linters not available. """ import unittest import os import pathlib import subprocess import shutil from typing import Iterable from packaging import version BASE_REASON = ('Using package {0} is mandatory on TravisCI, on ' 'other systems it runs only if `{0}` is available.') ON_TRAVIS = os.environ.get('TRAVIS', '') == 'true' TRAVIS_REASON = ('Running linter tests is mandatory on TravisCI only. On ' 'other machines they will run only if linters available.') PYLINT_AVAILABLE = shutil.which('pylint') is not None RUFF_AVAILABLE = shutil.which('ruff') is not None FLAKE8_AVAILABLE = shutil.which('flake8') is not None REUSE_AVAILABLE = shutil.which('reuse') is not None ANY_LINTER_AVAILABLE = any(( PYLINT_AVAILABLE, RUFF_AVAILABLE, FLAKE8_AVAILABLE, )) # "common" directory _base_dir = pathlib.Path(__file__).resolve().parent.parent # Files in this lists will get the full battery of linters and rule sets. full_test_files = [_base_dir / fp for fp in ( 'bitbase.py', 'languages.py', 'schedule.py', 'singleton.py', 'ssh_max_arg.py', 'version.py', 'test/test_lint.py', 'test/test_mount.py', 'test/test_singleton.py', 'test/test_uniquenessset.py', )] # Not all linters do respect PEP8 (e.g. ruff, PyLint) PEP8_MAX_LINE_LENGTH = 79 def create_pylint_cmd(include_error_codes=None): """Create the pylint base command for later use with subprocess.run(). Args: include_error_codes: List of exclusive rules to check for. If empty all default rules are checked. """ cmd = [ 'pylint', # Make sure BIT modules can be imported (to detect "no-member") '--init-hook=import sys;' 'sys.path.insert(0, "./../qt");' 'sys.path.insert(0, "./../common");', # Storing results in a pickle file is unnecessary '--persistent=n', # autodetec number of parallel jobs '--jobs=0', # Disable scoring ("Your code has been rated at xx/10") '--score=n', # prevent false-positive no-module-member errors '--extension-pkg-allow-list=PyQt6,PyQt6.QtCore', # Because of globally installed GNU gettext functions '--additional-builtins=_,ngettext', # PEP8 conform line length (see PyLint Issue #3078) f'--max-line-length={PEP8_MAX_LINE_LENGTH}', # Whitelist variable names '--good-names=idx,fp', # '--reports=yes', ] if include_error_codes: # Deactivate all checks by default cmd.append('--disable=all') # Include specific codes only cmd.append('--enable=' + ','.join(include_error_codes)) return cmd @unittest.skipUnless(ON_TRAVIS or ANY_LINTER_AVAILABLE, TRAVIS_REASON) class MirrorMirrorOnTheWall(unittest.TestCase): """Check all py-files in the package (incl. test files) for lints, potential bugs and if they are compliant to the coding styles (e.g. PEP8). """ @classmethod def _collect_py_files(cls) -> Iterable[pathlib.Path]: """All py-files related to that distribution package. Dev note (2023-11): Use package metadata after migration to pyproject.toml. """ path = pathlib.Path.cwd() # Make sure we are inside the test folder if path.name in ['qt', 'common']: # happens e.g. on TravisCI path = path / 'test' if not path.name.startswith('test'): raise RuntimeError('Something went wrong. The test should run ' 'inside the test folder but the current folder ' f'is {path}.') # Workaround path = path.parent # Find recursive all py-files. py_files = path.rglob('*.py') # Exclude full test files return filter(lambda fp: fp not in full_test_files, py_files) @classmethod def setUpClass(cls): cls.collected_py_files = cls._collect_py_files() def test005_ensure_linter_versions(self): """Workaround to ensure the correct linter versions are used. For sure there are better ways to solve this. But migration to a standard python package format need to be done first. See #1575. Until then this test will spare some hours of work, e.g. fixing linter errors (from out-dated linters) that are not relevant anymore in modern lintern versions. Another location where linter versions are relevant is CONTRIBUTING.md. """ if PYLINT_AVAILABLE: version_target = version.parse('3.3.0') proc = subprocess.run( ['pylint', '--version'], capture_output=True, text=True, check=True) version_string = proc.stdout.split('\n')[0].replace('pylint ', '') version_actual = version.parse(version_string) self.assertTrue( version_actual >= version_target, f'PyLint version is {version_actual} but need to ' f'be {version_target} or higher.') if RUFF_AVAILABLE: version_target = version.parse('0.6.0') proc = subprocess.run( ['ruff', '--version'], capture_output=True, text=True, check=True) version_string = proc.stdout.split('\n')[0].replace('ruff ', '') version_actual = version.parse(version_string) self.assertTrue( version_actual >= version_target, f'Ruff version is {version_actual} but need to ' f'be {version_target} or higher.') @unittest.skipUnless(RUFF_AVAILABLE, BASE_REASON.format('ruff')) def test010_ruff_default_ruleset(self): """Ruff in default mode.""" # ATTENTIION: Some settings are found in pyproject.toml cmd = [ 'ruff', 'check', # Additionally activate subset of special rules: # - PyLint (PL) # - PyCodestyle (E, W) # - flake8-gettext (INT) # - useless noqua (RUF100) '--extend-select=PL,E,W,INT,RUF100', # Ignore: redefined-loop-name '--ignore=PLW2901', '--line-length', str(PEP8_MAX_LINE_LENGTH), # Because of globally installed GNU gettext functions '--config', 'builtins=["_", "ngettext"]', # Ruff counting branches different from PyLint. # See: '--config', 'pylint.max-branches=13', '--config', 'flake8-quotes.inline-quotes = "single"', # one error per line (no context lines) '--output-format=concise', '--quiet', ] cmd.extend(full_test_files) proc = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True ) # No errors other then linter rules self.assertIn(proc.returncode, [0, 1], proc.stderr) error_n = len(proc.stdout.splitlines()) if error_n > 0: print(proc.stdout) self.assertEqual(0, error_n, f'Ruff found {error_n} problem(s).') # any other errors? self.assertEqual(proc.stderr, '') @unittest.skipUnless(FLAKE8_AVAILABLE, BASE_REASON.format('flake8')) def test020_flake8_default_ruleset(self): """Flake8 in default mode.""" cmd = [ 'flake8', f'--max-line-length={PEP8_MAX_LINE_LENGTH}', '--builtins=_,ngettext', # '--enable-extensions=' ] cmd.extend(full_test_files) proc = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True ) error_n = len(proc.stdout.splitlines()) if error_n > 0: print(proc.stdout) self.assertEqual(0, error_n, f'Flake8 found {error_n} problem(s).') # any other errors? self.assertEqual(proc.stderr, '') @unittest.skipUnless(PYLINT_AVAILABLE, BASE_REASON.format('PyLint')) def test030_pylint_default_ruleset(self): """Use Pylint with all default rules to check specific files. """ cmd = create_pylint_cmd() # Add py-files cmd.extend(full_test_files) r = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True) # Count lines except module headings error_n = len(list(filter(lambda line: not line.startswith('*****'), r.stdout.splitlines()))) print(r.stdout) self.assertEqual(0, error_n, f'PyLint found {error_n} problems.') # any other errors? self.assertEqual(r.stderr, '') @unittest.skipUnless(PYLINT_AVAILABLE, BASE_REASON.format('PyLint')) def test050_pylint_exclusive_ruleset(self): """Use Pylint to check for specific rules only. Some facts about PyLint - It is one of the slowest available linters. - It is able to catch lints other linters miss. """ # Explicit activate checks err_codes = [ 'C0305', # trailing-newlines 'C0325', # superfluous-parens 'C0410', # multiple-imports 'C0303', # trailing-whitespace 'E0100', # init-is-generator 'E0101', # return-in-init 'E0102', # function-redefined 'E0103', # not-in-loop 'E0106', # return-arg-in-generator 'E0213', # no-self-argument 'E0401', # import-error 'E0602', # undefined-variable 'E1101', # no-member 'I0021', # useless-suppression 'W0123', # eval-used 'W0237', # arguments-renamed 'W0311', # bad-indentation 'W0404', # reimported 'W0611', # unused-import 'W0612', # unused-variable 'W0614', # unused-wildcard-import 'W0707', # raise-missing-from 'W1301', # unused-format-string-key 'W1401', # anomalous-backslash-in-string (invalid escape sequence) 'W1515', # forgotten-debug-statement 'W4902', # deprecated-method 'W4904', # deprecated-class 'R0202', # no-classmethod-decorator 'R0203', # no-staticmethod-decorator # See PyLint bugs: # https://github.com/pylint-dev/pylint/issues/214 # https://github.com/pylint-dev/pylint/issues/7920 # 'R0801', # duplicate-code # Enable asap. This list is a selection of existing (not all!) # problems currently existing in the BIT code base. Quite easy to # fix because their count is low. # 'W0237', # arguments-renamed # 'W0221', # arguments-differ # 'W0603', # global-statement ] cmd = create_pylint_cmd(err_codes) # Add py-files cmd.extend(self._collect_py_files()) r = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True) # Count lines except module headings and output about duplicate code error_n = len(list(filter( lambda line: line[:2] not in ('**', ' ', '==', ' (', ''), r.stdout.splitlines()))) print(r.stdout) self.assertEqual(0, error_n, f'PyLint found {error_n} problems.') # any other errors? self.assertEqual(r.stderr, '') @unittest.skipUnless(REUSE_AVAILABLE, BASE_REASON.format('REUSE')) def test060_reuse(self): """The reuse linter check license and copyright information in the repository. The info need to be complete and available for all files. The info need to be provided as meta data conforming the SPDX standard. """ proc = subprocess.run( ['reuse', 'lint', '--lines'], check=False, universal_newlines=True, capture_output=True ) error_n = len(proc.stdout.splitlines()) if error_n > 0: print(proc.stdout) self.assertEqual( 0, error_n, f'REUSE linter found {error_n} problem(s).') # any other errors? self.assertEqual(proc.stderr, '') backintime-1.5.4/common/test/test_mount.py000066400000000000000000000133541477034762000206710ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests about lock mechanic while mounting.""" # pylint: disable=wrong-import-position,R0801 import os import sys import inspect import random import string from unittest import mock from pathlib import Path from tempfile import TemporaryDirectory import pyfakefs.fake_filesystem_unittest as pyfakefs_ut sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import config # noqa: E402,RUF100 import mount # noqa: E402,RUF100 class CheckLocks(pyfakefs_ut.TestCase): """Testing MountControl.checkLocks()""" def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically # pylint: disable-next=consider-using-with self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) # setup mount root fp = Path.cwd() / ''.join(random.choices(string.ascii_letters, k=10)) fp.mkdir() # pylint: disable-next=protected-access self.cfg._LOCAL_MOUNT_ROOT = str(fp) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=duplicate-code cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # pylint: disable=duplicate-code # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def test_not_existing_dir(self): """The lock directory does not exists.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() with self.assertRaises(FileNotFoundError): mntctrl.checkLocks('notexisting', '.lock') def test_ignore_own_lock(self): """Lock file of own process ignored.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() fp = Path(mntctrl.mount_root) / f'{os.getpid()}.lock' fp.touch() self.assertFalse(mntctrl.checkLocks(str(fp.parent), fp.suffix)) def test_own_lock_but_diff_tmpmount(self): """Lock file of own process but diff tmp-mount.""" mntctrl = mount.MountControl(cfg=self.cfg, tmp_mount=True) mntctrl.setDefaultArgs() fp = Path(mntctrl.mount_root) / f'{os.getpid()}.lock' fp.touch() self.assertTrue(mntctrl.checkLocks(str(fp.parent), fp.suffix)) @mock.patch('tools.processAlive', return_value=True) def test_foreign_lock(self, _mock_process_alive): """Lock file of foreign and existing process.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() fp = Path(mntctrl.mount_root) / '123456.lock' fp.touch() self.assertTrue(mntctrl.checkLocks(str(fp.parent), fp.suffix)) @mock.patch('tools.processAlive', return_value=False) def test_foreign_lock_notexisting_pid(self, _mock_process_alive): """Lock file of foreign and NOT existing process.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() pid = '123456' fp = Path(mntctrl.mount_root) / f'{pid}.lock' fp.touch() self.assertFalse(mntctrl.checkLocks(str(fp.parent), fp.suffix)) @mock.patch('tools.processAlive', return_value=False) def test_lock_remove(self, _mock_process_alive): """Remove lock files of NOT existing processes.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() pid = '123456' fp = Path(mntctrl.mount_root) / f'{pid}.lock' fp.touch() self.assertTrue(fp.exists()) mntctrl.checkLocks(str(fp.parent), fp.suffix) self.assertFalse(fp.exists()) @mock.patch('tools.processAlive', return_value=False) def test_symlinks_remove(self, _mock_process_alive): """Remove symlinks related to lock files of NOT existing processes.""" mntctrl = mount.MountControl(cfg=self.cfg) mntctrl.setDefaultArgs() pid = '123456' fp = Path(mntctrl.mount_root) / f'{pid}.lock' fp.touch() real = Path.cwd() / 'real' real.mkdir() sym = Path(mntctrl.mount_root) / f'symlink_mountpoint_{pid}' sym.symlink_to(real) self.assertTrue(sym.exists()) mntctrl.checkLocks(str(fp.parent), fp.suffix) self.assertFalse(sym.exists()) backintime-1.5.4/common/test/test_plugin_usercallback.py000066400000000000000000000253561477034762000235450ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import sys import inspect import io import unittest import unittest.mock as mock import tempfile import stat from contextlib import redirect_stdout, redirect_stderr from ast import literal_eval from pathlib import Path # This workaround will become obsolet when migrating to src-layout sys.path.append(str(Path(__file__).parent)) sys.path.append(str(Path(__file__).parent / 'plugins')) import pluginmanager from config import Config from snapshots import Snapshots from usercallbackplugin import UserCallbackPlugin class UserCallback(unittest.TestCase): """Simple test related to to UserCallbackPlugin class. Dev note (buhtz, 2024-02-08): Test value is low because they depend on implementation and are not robust against refactoring the productive code. Some observations and suggestions: - Rename method UserCallbackPlugin.init() - Make UserCallbackPlugin.callback() private - UserCallbackPlugin.callback() : Encapsulating the Popen() part would improve the mocking. - Unit tests about logger output. But migrate "logger" to Python's inbuild "logging" module first. """ def _generic_called_with(self, the_step, reason, *args): sut = UserCallbackPlugin() sut.config = Config() sut.script = '' mock_name = 'usercallbackplugin.UserCallbackPlugin.callback' with mock.patch(mock_name) as func_callback: the_step(sut, *args) func_callback.assert_called_once() func_callback.assert_called_with(reason, *args) def test_reason_processBegin(self): self._generic_called_with(UserCallbackPlugin.processBegin, '1') def test_reason_processEnd(self): self._generic_called_with(UserCallbackPlugin.processEnd, '2') def test_reason_processnewSnapshot(self): self._generic_called_with(UserCallbackPlugin.newSnapshot, '3', 'id1', 'path') def test_reason_error(self): sut = UserCallbackPlugin() sut.config = Config() sut.script = '' mock_name = 'usercallbackplugin.UserCallbackPlugin.callback' # with error message with mock.patch(mock_name) as func_callback: sut.error('code1', 'message') func_callback.assert_called_once() func_callback.assert_called_with('4', 'code1', 'message') # no error message with mock.patch(mock_name) as func_callback: sut.error('code2', None) func_callback.assert_called_once() func_callback.assert_called_with('4', 'code2') def test_reason_appStart(self): self._generic_called_with(UserCallbackPlugin.appStart, '5') def test_reason_appExit(self): self._generic_called_with(UserCallbackPlugin.appExit, '6') def test_reason_mount(self): sut = UserCallbackPlugin() sut.config = Config() sut.script = '' mock_name = 'usercallbackplugin.UserCallbackPlugin.callback' # No profileID with mock.patch(mock_name) as func_callback: sut.mount() func_callback.assert_called_once() func_callback.assert_called_with('7', profileID=None) # With profileID with mock.patch(mock_name) as func_callback: sut.mount('123') func_callback.assert_called_once() func_callback.assert_called_with('7', profileID='123') def test_reason_unmount(self): sut = UserCallbackPlugin() sut.config = Config() sut.script = '' mock_name = 'usercallbackplugin.UserCallbackPlugin.callback' # No profileID with mock.patch(mock_name) as func_callback: sut.unmount() func_callback.assert_called_once() func_callback.assert_called_with('8', profileID=None) # With profileID with mock.patch(mock_name) as func_callback: sut.unmount('987') func_callback.assert_called_once() func_callback.assert_called_with('8', profileID='987') class SystemTest(unittest.TestCase): """Full backup run and parsing the log output for the expected user-callback returns in correct order. Create and use your own config file and take it over via `--config` option. Place your own user-callback script in the same folder as this config file. """ @classmethod def _create_user_callback_file(cls, parent_path): content = inspect.cleandoc(''' #!/usr/bin/env python3 import sys print(sys.argv[1:]) ''') callback_fp = parent_path / 'user-callback' callback_fp.write_text(content, 'utf-8') callback_fp.chmod(stat.S_IRWXU) # Name of folder with files to backup. NAME_SOURCE = 'src' # Name of folder where snapshots (backups) are stored in. NAME_DESTINATION = 'dest' @classmethod def _extract_callback_responses(cls, output): """Extract response of user-callback script out of log output. See https://github.com/bit-team/user-callback for documentation about user-callback and the response codes. Example :: # Raw output INFO: user-callback returned '['1', 'Main profile', '2']' INFO: Something else INFO: user-callback returned '['1', 'Main profile', '8']' # Result in a two entry list [ ['1', 'Main profile', '2'] ['1', 'Main profile', '8'] ] Returns: A list of response values as lists. First entry is profile, second is profile id, third is reason code. If available further entries could be contained. """ if isinstance(output, str): output = output.splitlines() # only log lines related to user-callback response_lines = filter( lambda line: 'user-callback returned' in line, output) callback_responses = [] for line in response_lines: callback_responses.append( literal_eval(line[line.index("'")+1:line.rindex("'")]) ) # Workaround: Cast profile-id and response-code to integers for idx in range(len(callback_responses)): callback_responses[idx][0] = int(callback_responses[idx][0]) callback_responses[idx][2] = int(callback_responses[idx][2]) return callback_responses @classmethod def _create_source_and_destination_folders(cls, parent_path): # Folder to backup src_path = parent_path / cls.NAME_SOURCE src_path.mkdir() # Files and folders as backup content (src_path / 'one').write_bytes(b'0123') (src_path / 'subfolder').mkdir() (src_path / 'subfolder' / 'two').write_bytes(b'4567') # Folder to store backup dest_path = parent_path / cls.NAME_DESTINATION dest_path.mkdir() @classmethod def _create_config_file(cls, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value={rootpath}/{source} profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path={rootpath}/{destination} profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') cfg_content = cfg_content.format( rootpath=parent_path, source=cls.NAME_SOURCE, destination=cls.NAME_DESTINATION ) # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def setUp(self): """Setup a local snapshot profile including a user-callback""" # cleanup() happens automatically self._temp_dir = tempfile.TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._create_source_and_destination_folders(self.temp_path) self.config_fp = self._create_config_file(self.temp_path) self._create_user_callback_file(self.config_fp.parent) # Reset this instance because it is not isolated between tests. Config.PLUGIN_MANAGER = pluginmanager.PluginManager() def test_local_snapshot(self): """User-callback response while doing a local snapshot""" config = Config( config_path=str(self.config_fp), data_path=str(self.temp_path / '.local' / 'share') ) full_snapshot_path = config.snapshotsFullPath() Path(full_snapshot_path).mkdir(parents=True) snapshot = Snapshots(config) # DevNote : Because BIT don't use Python's logging module there is # no way to use assertLogs(). Current solution is to capture # stdout/stderr. stdout = io.StringIO() stderr = io.StringIO() with redirect_stdout(stdout), redirect_stderr(stderr): # Result is inverted. 'True' means there was an error. self.assertFalse(snapshot.backup()) # Empty STDOUT output self.assertFalse(stdout.getvalue()) responses = self._extract_callback_responses(stderr.getvalue()) # Number of responses self.assertEqual(5, len(responses)) # Test Name and ID self.assertEqual( {(1, 'Main profile')}, # de-duplicate (using set() )by first two elements in each entry {(entry[0], entry[1]) for entry in responses} ) # Order of response codes self.assertEqual( [ 7, # Mount 1, # Backup begins 3, # New snapshot was taken 2, # Backup ends 8, # Unmount ], [entry[2] for entry in responses] ) backintime-1.5.4/common/test/test_restore.py000066400000000000000000000162051477034762000212100ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import unittest import stat from tempfile import TemporaryDirectory from test import generic from test.constants import CURRENTUSER, CURRENTGROUP sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import mount class RestoreTestCase(generic.SnapshotsWithSidTestCase): def setUp(self): super(RestoreTestCase, self).setUp() self.include = TemporaryDirectory() generic.create_test_files(self.sid.pathBackup(self.include.name)) def tearDown(self): super(RestoreTestCase, self).tearDown() self.include.cleanup() def prepairFileInfo(self, restoreFile, mode = 33260): d = self.sid.fileInfo d[restoreFile.encode('utf-8', 'replace')] = (mode, CURRENTUSER.encode('utf-8', 'replace'), CURRENTGROUP.encode('utf-8', 'replace')) self.sid.fileInfo = d class TestRestore(RestoreTestCase): def test_restore_multiple_files(self): restoreFile1 = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile1) restoreFile2 = os.path.join(self.include.name, 'foo', 'bar', 'baz') self.prepairFileInfo(restoreFile2) self.sn.restore(self.sid, (restoreFile1, restoreFile2)) self.assertIsFile(restoreFile1) with open(restoreFile1, 'rt') as f: self.assertEqual(f.read(), 'bar') self.assertEqual(33260, os.stat(restoreFile1).st_mode) self.assertIsFile(restoreFile2) with open(restoreFile2, 'rt') as f: self.assertEqual(f.read(), 'foo') self.assertEqual(33260, os.stat(restoreFile2).st_mode) def test_restore_to_different_destination(self): restoreFile = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile) with TemporaryDirectory() as dest: destRestoreFile = os.path.join(dest, 'test') self.sn.restore(self.sid, restoreFile, restore_to = dest) self.assertIsFile(destRestoreFile) with open(destRestoreFile, 'rt') as f: self.assertEqual(f.read(), 'bar') self.assertEqual(33260, os.stat(destRestoreFile).st_mode) def test_restore_folder_to_different_destination(self): restoreFolder = self.include.name self.prepairFileInfo(restoreFolder) self.prepairFileInfo(os.path.join(restoreFolder, 'test')) self.prepairFileInfo(os.path.join(restoreFolder, 'file with spaces')) with TemporaryDirectory() as dest: destRestoreFile = os.path.join(dest, os.path.basename(restoreFolder), 'test') self.sn.restore(self.sid, restoreFolder, restore_to = dest) self.assertIsFile(destRestoreFile) with open(destRestoreFile, 'rt') as f: self.assertEqual(f.read(), 'bar') self.assertEqual(33260, os.stat(destRestoreFile).st_mode) def test_delete(self): restoreFolder = self.include.name junkFolder = os.path.join(self.include.name, 'junk') os.makedirs(junkFolder) self.assertExists(junkFolder) self.prepairFileInfo(restoreFolder) self.sn.restore(self.sid, restoreFolder, delete = True) self.assertIsFile(restoreFolder, 'test') self.assertNotExists(junkFolder) def test_backup(self): restoreFile = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile) with open(restoreFile, 'wt') as f: f.write('fooooooooooooooooooo') self.sn.restore(self.sid, restoreFile, backup = True) self.assertIsFile(restoreFile) with open(restoreFile, 'rt') as f: self.assertEqual(f.read(), 'bar') backupFile = restoreFile + self.sn.backupSuffix() self.assertIsFile(backupFile) with open(backupFile, 'rt') as f: self.assertEqual(f.read(), 'fooooooooooooooooooo') def test_no_backup(self): restoreFile = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile) with open(restoreFile, 'wt') as f: f.write('fooooooooooooooooooo') self.sn.restore(self.sid, restoreFile, backup = False) self.assertIsFile(restoreFile) with open(restoreFile, 'rt') as f: self.assertEqual(f.read(), 'bar') backupFile = restoreFile + self.sn.backupSuffix() self.assertIsNoFile(backupFile) def test_only_new(self): restoreFile = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile) with open(restoreFile, 'wt') as f: f.write('fooooooooooooooooooo') # change mtime to be newer than the one in snapshot st = os.stat(restoreFile) atime = st[stat.ST_ATIME] mtime = st[stat.ST_MTIME] new_mtime = mtime + 3600 os.utime(restoreFile, (atime, new_mtime)) self.sn.restore(self.sid, restoreFile, only_new = True) self.assertIsFile(restoreFile) with open(restoreFile, 'rt') as f: self.assertEqual(f.read(), 'fooooooooooooooooooo') class TestRestoreLocal(RestoreTestCase): """ Tests which should run on local and ssh profile """ def test_restore(self): restoreFile = os.path.join(self.include.name, 'test') self.prepairFileInfo(restoreFile) self.sn.restore(self.sid, restoreFile) self.assertIsFile(restoreFile) with open(restoreFile, 'rt') as f: self.assertEqual(f.read(), 'bar') self.assertEqual(33260, os.stat(restoreFile).st_mode) def test_restore_file_with_spaces(self): restoreFile = os.path.join(self.include.name, 'file with spaces') self.prepairFileInfo(restoreFile) self.sn.restore(self.sid, restoreFile) self.assertIsFile(restoreFile) with open(restoreFile, 'rt') as f: self.assertEqual(f.read(), 'asdf') self.assertEqual(33260, os.stat(restoreFile).st_mode) @unittest.skipIf(not generic.LOCAL_SSH, 'Skip as this test requires a local ssh server, public and private keys installed') class TestRestoreSSH(generic.SSHSnapshotsWithSidTestCase, TestRestoreLocal): """BUHTZ 2022-10-09: Seems to me that testing restore via SSH isn't implemented yet. """ def setUp(self): super(TestRestoreSSH, self).setUp() self.include = TemporaryDirectory() generic.create_test_files(os.path.join(self.remoteSIDBackupPath, self.include.name[1:])) #mount self.cfg.setCurrentHashId(mount.Mount(cfg = self.cfg).mount()) def tearDown(self): #unmount mount.Mount(cfg = self.cfg).umount(self.cfg.current_hash_id) super(TestRestoreSSH, self).tearDown() self.include.cleanup() backintime-1.5.4/common/test/test_schedule.py000066400000000000000000000051671477034762000213260ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . import unittest import schedule class Schedule(unittest.TestCase): """Manipulation of crontab content""" def test_remove_bit_entries(self): """Remove BIT entries from crontab. Three BIT entries in the crontab. The 1st and 3rd are auto generated by BIT schedule feature and will be removed. But the second is user defined and need to stay. """ content = [ '# -------------- min (0 - 59)', '# | --------------- hour (0 - 23)', '# | | ---------------- day of month (1 - 31),' '# | | | ----------------- month (1 - 12)', '# | | | | ------------------ day of week (0 - 6)', '# Saturday, or use names; 7 is Sunday, the same as 0)', '# | | | | |', '# | | | | |', '# * * * * *', '', '30/* * * * * dohyperorg > /def/null', '', '51 */3 * * * cronjobblock ' '/home/user/.my.scripts/thunderbird_backup_duplicity.sh', '', '#Back In Time system entry, this will be edited by the gui:', '0 8,12,18,23 * * * /usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 ' '/usr/bin/backintime backup-job >/dev/null', '0 2 3 4 5 /usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 ' '/usr/bin/backintime --profile-id 7 backup-job >/dev/null', '#Back In Time system entry, this will be edited by the gui:', '0 0 1 1 * /usr/bin/nice -n19 /usr/bin/ionice -c2 -n7 ' '/usr/bin/backintime --profile-id 3 backup-job >/dev/null', ] expect = content[:] # Remove the last BIT entry incl. comment del expect[-1] del expect[-1] # Remove the one before the one before the last del expect[-2] del expect[-2] result = schedule.remove_bit_from_crontab(content) self.assertEqual(result, expect) self.assertIn('--profile-id 7', result[-1]) def test_bit_to_crontab(self): result = schedule.append_bit_to_crontab( [], ['foo', 'bar'] ) self.assertEqual(len(result), 4) self.assertTrue(result[0][0], '#') self.assertTrue(result[1], 'foo') self.assertTrue(result[2][0], '#') self.assertTrue(result[3], 'bar') backintime-1.5.4/common/test/test_sid.py000066400000000000000000000526731477034762000203150ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import unittest import stat from datetime import date, datetime from test import generic from unittest.mock import patch sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import configfile import snapshots from snapshotlog import LogFilter, SnapshotLog class TestSID(generic.SnapshotsTestCase): def test_new_object_with_valid_date(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-010324', self.cfg) sid3 = snapshots.SID(datetime(2015, 12, 19, 1, 3, 24), self.cfg) sid4 = snapshots.SID(date(2015, 12, 19), self.cfg) self.assertEqual(sid1.sid, '20151219-010324-123') self.assertEqual(sid2.sid, '20151219-010324') self.assertRegex(sid3.sid, r'20151219-010324-\d{3}') self.assertRegex(sid4.sid, r'20151219-000000-\d{3}') def test_new_object_with_invalid_value(self): with self.assertRaises(ValueError): snapshots.SID('20151219-010324-1234', self.cfg) with self.assertRaises(ValueError): snapshots.SID('20151219-01032', self.cfg) with self.assertRaises(ValueError): snapshots.SID('2015121a-010324-1234', self.cfg) def test_new_object_with_invalid_type(self): with self.assertRaises(TypeError): snapshots.SID(123, self.cfg) def test_equal_sid(self): sid1a = snapshots.SID('20151219-010324-123', self.cfg) sid1b = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) self.assertIsNot(sid1a, sid1b) self.assertTrue(sid1a == sid1b) self.assertTrue(sid1a == '20151219-010324-123') self.assertTrue(sid1a != sid2) self.assertTrue(sid1a != '20151219-020324-123') def test_sort_sids(self): root = snapshots.RootSnapshot(self.cfg) new = snapshots.NewSnapshot(self.cfg) sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) sid3 = snapshots.SID('20151219-030324-123', self.cfg) sid4 = snapshots.SID('20151219-040324-123', self.cfg) sids1 = [sid3, sid1, sid4, sid2] sids1.sort() self.assertEqual(sids1, [sid1, sid2, sid3, sid4]) #RootSnapshot 'Now' should always stay on top sids2 = [sid3, sid1, root, sid4, sid2] sids2.sort() self.assertEqual(sids2, [sid1, sid2, sid3, sid4, root]) sids2.sort(reverse = True) self.assertEqual(sids2, [root, sid4, sid3, sid2, sid1]) #new_snapshot should always be the last sids3 = [sid3, sid1, new, sid4, sid2] sids3.sort() self.assertEqual(sids3, [sid1, sid2, sid3, sid4, new]) sids3.sort(reverse = True) self.assertEqual(sids3, [new, sid4, sid3, sid2, sid1]) def test_hash(self): sid1a = snapshots.SID('20151219-010324-123', self.cfg) sid1b = snapshots.SID('20151219-010324-123', self.cfg) sid2 = snapshots.SID('20151219-020324-123', self.cfg) self.assertEqual(sid1a.__hash__(), sid1b.__hash__()) self.assertNotEqual(sid1a.__hash__(), sid2.__hash__()) s = set() s.add(sid1a) self.assertEqual(len(s), 1) s.add(sid2) self.assertEqual(len(s), 2) s.add(sid1b) self.assertEqual(len(s), 2) def test_split(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertTupleEqual(sid.split(), (2015, 12, 19, 1, 3, 24)) def test_displayID(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertEqual(sid.displayID, '2015-12-19 01:03:24') def test_displayName(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) with open(sid.path('name'), 'wt') as f: f.write('foo') self.assertEqual(sid.displayName, '2015-12-19 01:03:24 - foo') with open(sid.path('failed'), 'wt') as f: pass self.assertRegex(sid.displayName, r'2015-12-19 01:03:24 - foo (.+?)') def test_withoutTag(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertEqual(sid.withoutTag, '20151219-010324') def test_tag(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertEqual(sid.tag, '123') def test_path(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertEqual(sid.path(), os.path.join(self.snapshotPath, '20151219-010324-123')) self.assertEqual(sid.path('foo', 'bar', 'baz'), os.path.join(self.snapshotPath, '20151219-010324-123', 'foo', 'bar', 'baz')) self.assertEqual(sid.pathBackup(), os.path.join(self.snapshotPath, '20151219-010324-123', 'backup')) self.assertEqual(sid.pathBackup('/foo'), os.path.join(self.snapshotPath, '20151219-010324-123', 'backup', 'foo')) def test_makeDirs(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertTrue(sid.makeDirs()) self.assertTrue(os.path.isdir(os.path.join(self.snapshotPath, '20151219-010324-123', 'backup'))) self.assertTrue(sid.makeDirs('foo', 'bar', 'baz')) self.assertTrue(os.path.isdir(os.path.join(self.snapshotPath, '20151219-010324-123', 'backup', 'foo', 'bar', 'baz'))) def test_exists(self): sid = snapshots.SID('20151219-010324-123', self.cfg) self.assertFalse(sid.exists()) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) self.assertFalse(sid.exists()) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123', 'backup')) self.assertTrue(sid.exists()) def test_isExistingPathInsideSnapshotFolder(self): sid = snapshots.SID('20151219-010324-123', self.cfg) backupPath = os.path.join(self.snapshotPath, '20151219-010324-123', 'backup') os.makedirs(os.path.join(backupPath, 'foo')) #test existing file and non existing file self.assertTrue(sid.isExistingPathInsideSnapshotFolder('/foo')) self.assertFalse(sid.isExistingPathInsideSnapshotFolder('/tmp')) #test valid absolute symlink inside snapshot os.symlink(os.path.join(backupPath, 'foo'), os.path.join(backupPath, 'bar')) self.assertIsLink(backupPath, 'bar') self.assertTrue(sid.isExistingPathInsideSnapshotFolder('/bar')) #test valid relative symlink inside snapshot os.symlink('./foo', os.path.join(backupPath, 'baz')) self.assertIsLink(backupPath, 'baz') self.assertTrue(sid.isExistingPathInsideSnapshotFolder('/baz')) #test invalid symlink os.symlink(os.path.join(backupPath, 'asdf'), os.path.join(backupPath, 'qwer')) self.assertIsLink(backupPath, 'qwer') self.assertFalse(sid.isExistingPathInsideSnapshotFolder('/qwer')) #test valid symlink outside snapshot os.symlink('/tmp', os.path.join(backupPath, 'bla')) self.assertIsLink(backupPath, 'bla') self.assertFalse(sid.isExistingPathInsideSnapshotFolder('/bla')) def test_name(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) self.assertEqual(sid.name, '') sid.name = 'foo' with open(sid.path('name'), 'rt') as f: self.assertEqual(f.read(), 'foo') self.assertEqual(sid.name, 'foo') def test_lastChecked(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'info') #no info file self.assertEqual(sid.lastChecked, '2015-12-19 01:03:24') #set time manually to 2015-12-19 02:03:24 with open(infoFile, 'wt'): pass d = datetime(2015, 12, 19, 2, 3, 24) os.utime(infoFile, (d.timestamp(), d.timestamp())) self.assertEqual(sid.lastChecked, '2015-12-19 02:03:24') #setLastChecked and check if it matches current date sid.setLastChecked() now = datetime.now() self.assertRegex(sid.lastChecked, now.strftime(r'%Y-%m-%d %H:%M:\d{2}')) def test_failed(self): sid = snapshots.SID('20151219-010324-123', self.cfg) snapshotPath = os.path.join(self.snapshotPath, '20151219-010324-123') failedPath = os.path.join(snapshotPath, sid.FAILED) os.makedirs(snapshotPath) self.assertNotExists(failedPath) self.assertFalse(sid.failed) sid.failed = True self.assertExists(failedPath) self.assertTrue(sid.failed) sid.failed = False self.assertNotExists(failedPath) self.assertFalse(sid.failed) def test_info(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'info') i1 = configfile.ConfigFile() i1.setStrValue('foo', 'bar') sid1.info = i1 #test if file exist and has correct content self.assertIsFile(infoFile) with open(infoFile, 'rt') as f: self.assertEqual(f.read(), 'foo=bar\n') #new sid instance and test if correct value is returned sid2 = snapshots.SID('20151219-010324-123', self.cfg) i2 = sid2.info self.assertEqual(i2.strValue('foo', 'default'), 'bar') def test_fileInfo(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'fileinfo.bz2') d = snapshots.FileInfoDict() d[b'/tmp'] = (123, b'foo', b'bar') d[b'/tmp/foo'] = (456, b'asdf', b'qwer') sid1.fileInfo = d self.assertIsFile(infoFile) #load fileInfo in a new snapshot sid2 = snapshots.SID('20151219-010324-123', self.cfg) self.assertDictEqual(sid2.fileInfo, d) @patch('logger.error') def test_fileInfoErrorRead(self, mock_logger): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = sid.path(sid.FILEINFO) # remove all permissions from file with open(infoFile, 'wt'): pass with generic.mockPermissions(infoFile): self.assertEqual(sid.fileInfo, snapshots.FileInfoDict()) self.assertTrue(mock_logger.called) @patch('logger.error') def test_fileInfoErrorWrite(self, mock_logger): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) infoFile = sid.path(sid.FILEINFO) # remove all permissions from file with open(infoFile, 'wt'): pass with generic.mockPermissions(infoFile): d = snapshots.FileInfoDict() d[b'/tmp'] = (123, b'foo', b'bar') d[b'/tmp/foo'] = (456, b'asdf', b'qwer') sid.fileInfo = d self.assertTrue(mock_logger.called) def test_log(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') #no log available self.assertRegex('\n'.join(sid.log()), r'Failed to get snapshot log from.*') sid.setLog('foo bar\nbaz') self.assertIsFile(logFile) self.assertEqual('\n'.join(sid.log()), 'foo bar\nbaz') def test_log_filter(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') sid.setLog('foo bar\n[I] 123\n[C] baz\n[E] bla') self.assertIsFile(logFile) self.assertEqual('\n'.join(sid.log(mode = LogFilter.CHANGES)), 'foo bar\n[C] baz') def test_setLog_binary(self): sid = snapshots.SID('20151219-010324-123', self.cfg) os.makedirs(os.path.join(self.snapshotPath, '20151219-010324-123')) logFile = os.path.join(self.snapshotPath, '20151219-010324-123', 'takesnapshot.log.bz2') sid.setLog(b'foo bar\nbaz') self.assertIsFile(logFile) self.assertEqual('\n'.join(sid.log()), 'foo bar\nbaz') def test_makeWritable(self): sid = snapshots.SID('20151219-010324-123', self.cfg) sidPath = os.path.join(self.snapshotPath, '20151219-010324-123') os.makedirs(sidPath) testFile = os.path.join(sidPath, 'test') #make only read and explorable os.chmod(sidPath, stat.S_IRUSR | stat.S_IXUSR) with self.assertRaises(PermissionError): with open(testFile, 'wt') as f: f.write('foo') sid.makeWritable() self.assertEqual(os.stat(sidPath).st_mode & stat.S_IWUSR, stat.S_IWUSR) try: with open(testFile, 'wt') as f: f.write('foo') except PermissionError: msg = 'writing to {} raised PermissionError unexpectedly!' self.fail(msg.format(testFile)) class TestNewSnapshot(generic.SnapshotsTestCase): def test_create_new(self): new = snapshots.NewSnapshot(self.cfg) self.assertFalse(new.exists()) self.assertTrue(new.makeDirs()) self.assertTrue(new.exists()) self.assertTrue(os.path.isdir(os.path.join(self.snapshotPath, new.NEWSNAPSHOT, 'backup'))) def test_saveToContinue(self): new = snapshots.NewSnapshot(self.cfg) snapshotPath = os.path.join(self.snapshotPath, new.NEWSNAPSHOT) saveToContinuePath = os.path.join(snapshotPath, new.SAVETOCONTINUE) os.makedirs(snapshotPath) self.assertNotExists(saveToContinuePath) self.assertFalse(new.saveToContinue) new.saveToContinue = True self.assertExists(saveToContinuePath) self.assertTrue(new.saveToContinue) new.saveToContinue = False self.assertNotExists(saveToContinuePath) self.assertFalse(new.saveToContinue) def test_hasChanges(self): now = datetime(2016, 7, 10, 16, 24, 17) new = snapshots.NewSnapshot(self.cfg) new.makeDirs() log = SnapshotLog(self.cfg) log.new(now) self.assertFalse(new.hasChanges) log.append('[I] foo', log.ALL) log.append('[E] bar', log.ALL) log.flush() self.assertFalse(new.hasChanges) log.append('[C] baz', log.ALL) log.flush() self.assertTrue(new.hasChanges) class TestRootSnapshot(generic.SnapshotsTestCase): #TODO: add test with 'sid.path(use_mode=['ssh_encfs'])' def test_create(self): sid = snapshots.RootSnapshot(self.cfg) self.assertTrue(sid.isRoot) self.assertEqual(sid.sid, '/') self.assertEqual(sid.name, 'Now') def test_path(self): sid = snapshots.RootSnapshot(self.cfg) self.assertEqual(sid.path(), '/') self.assertEqual(sid.path('foo', 'bar'), '/foo/bar') class TestIterSnapshots(generic.SnapshotsTestCase): def setUp(self): super(TestIterSnapshots, self).setUp() for i in ('20151219-010324-123', '20151219-020324-123', '20151219-030324-123', '20151219-040324-123'): os.makedirs(os.path.join(self.snapshotPath, i, 'backup')) def test_list_valid(self): l1 = snapshots.listSnapshots(self.cfg) self.assertListEqual(l1, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) self.assertIsInstance(l1[0], snapshots.SID) def test_list_new_snapshot(self): os.makedirs(os.path.join(self.snapshotPath, 'new_snapshot', 'backup')) l2 = snapshots.listSnapshots(self.cfg, includeNewSnapshot = True) self.assertListEqual(l2, ['new_snapshot', '20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) self.assertIsInstance(l2[0], snapshots.NewSnapshot) self.assertIsInstance(l2[-1], snapshots.SID) def test_list_snapshot_without_backup(self): #new snapshot without backup folder shouldn't be added os.makedirs(os.path.join(self.snapshotPath, '20151219-050324-123')) l3 = snapshots.listSnapshots(self.cfg) self.assertListEqual(l3, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) def test_list_invalid_snapshot(self): #invalid snapshot shouldn't be added os.makedirs(os.path.join(self.snapshotPath, '20151219-000324-abc', 'backup')) l4 = snapshots.listSnapshots(self.cfg) self.assertListEqual(l4, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) def test_list_without_new_snapshot(self): os.makedirs(os.path.join(self.snapshotPath, 'new_snapshot', 'backup')) l5 = snapshots.listSnapshots(self.cfg, includeNewSnapshot = False) self.assertListEqual(l5, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) def test_list_symlink_last_snapshot(self): os.symlink('./20151219-040324-123', os.path.join(self.snapshotPath, 'last_snapshot')) l6 = snapshots.listSnapshots(self.cfg) self.assertListEqual(l6, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) def test_list_not_reverse(self): os.makedirs(os.path.join(self.snapshotPath, 'new_snapshot', 'backup')) l7 = snapshots.listSnapshots(self.cfg, includeNewSnapshot = True, reverse = False) self.assertListEqual(l7, ['20151219-010324-123', '20151219-020324-123', '20151219-030324-123', '20151219-040324-123', 'new_snapshot']) self.assertIsInstance(l7[0], snapshots.SID) self.assertIsInstance(l7[-1], snapshots.NewSnapshot) def test_iter_snapshots(self): for i, sid in enumerate(snapshots.iterSnapshots(self.cfg)): self.assertIn(sid, ['20151219-040324-123', '20151219-030324-123', '20151219-020324-123', '20151219-010324-123']) self.assertIsInstance(sid, snapshots.SID) self.assertEqual(i, 3) def test_lastSnapshot(self): self.assertEqual(snapshots.lastSnapshot(self.cfg), '20151219-040324-123') class TestIterSnapshotsNonexistingSnapshotPath(generic.TestCaseSnapshotPath): def test_iterSnapshots(self): for _ in snapshots.iterSnapshots(self.cfg): self.fail('got unexpected snapshot') def test_listSnapshots(self): self.assertEqual(snapshots.listSnapshots(self.cfg), []) def test_lastSnapshots(self): self.assertIsNone(snapshots.lastSnapshot(self.cfg)) if __name__ == '__main__': unittest.main() backintime-1.5.4/common/test/test_singleton.py000066400000000000000000000033431477034762000215260ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). # See file LICENSE or go to . """Tests about singleton module.""" # pylint: disable=missing-class-docstring,too-few-public-methods import unittest import singleton class Test(unittest.TestCase): class Foo(metaclass=singleton.Singleton): def __init__(self): self.value = 'Ogawa' class Bar(metaclass=singleton.Singleton): def __init__(self): self.value = 'Naomi' def setUp(self): # Clean up all instances singleton.Singleton._instances = {} # pylint: disable=protected-access def test_twins(self): """Identical id and values.""" a = self.Foo() b = self.Foo() self.assertEqual(id(a), id(b)) self.assertEqual(a.value, b.value) def test_share_value(self): """Modify value""" a = self.Foo() b = self.Foo() a.value = 'foobar' self.assertEqual(a.value, 'foobar') self.assertEqual(a.value, b.value) def test_multi_class(self): """Two different singleton classes.""" a = self.Foo() b = self.Foo() x = self.Bar() y = self.Bar() self.assertEqual(id(a), id(b)) self.assertEqual(id(x), id(y)) self.assertNotEqual(id(a), id(y)) self.assertEqual(a.value, 'Ogawa') self.assertEqual(x.value, 'Naomi') a.value = 'who' self.assertEqual(b.value, 'who') self.assertEqual(x.value, 'Naomi') self.assertEqual(x.value, y.value) backintime-1.5.4/common/test/test_snapshotlog.py000066400000000000000000000156071477034762000220730ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import re from test import generic from datetime import datetime sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import snapshotlog import snapshots class TestLogFilter(generic.TestCase): # TODO: add decode test def __init__(self, *args, **kwargs): super(TestLogFilter, self).__init__(*args, **kwargs) self.e = '[E] foo bar' self.c = '[C] foo bar' self.i = '[I] foo bar' self.n = '' self.h = '========== header ===========' def test_filter(self): #No filter logFilter = snapshotlog.LogFilter() for line in (self.e, self.c, self.i, self.n, self.h): self.assertEqual(line, logFilter.filter(line)) #Error filter logFilter = snapshotlog.LogFilter(mode = snapshotlog.LogFilter.ERROR) for line in (self.e, self.n, self.h): self.assertEqual(line, logFilter.filter(line)) for line in (self.c, self.i): self.assertIsNone(logFilter.filter(line)) #Changes filter logFilter = snapshotlog.LogFilter(mode = snapshotlog.LogFilter.CHANGES) for line in (self.c, self.n, self.h): self.assertEqual(line, logFilter.filter(line)) for line in (self.e, self.i): self.assertIsNone(logFilter.filter(line)) #Information filter logFilter = snapshotlog.LogFilter(mode = snapshotlog.LogFilter.INFORMATION) for line in (self.i, self.n, self.h): self.assertEqual(line, logFilter.filter(line)) for line in (self.c, self.e): self.assertIsNone(logFilter.filter(line)) #Error + Changes filter logFilter = snapshotlog.LogFilter(mode = snapshotlog.LogFilter.ERROR_AND_CHANGES) for line in (self.e, self.c, self.n, self.h): self.assertEqual(line, logFilter.filter(line)) for line in (self.i,): self.assertIsNone(logFilter.filter(line)) # New filter (#1587): rsync transfer failures (experimental) logFilter = snapshotlog.LogFilter(mode=snapshotlog.LogFilter.RSYNC_TRANSFER_FAILURES) log_lines = ( '[I] Take snapshot (rsync: symlink has no referent: "/home/user/Documents/dead-link")', '[E] Error: rsync: [sender] send_files failed to open "/home/user/Documents/root_only_file.txt": Permission denied (13)', '[I] Schnappschuss erstellen (rsync: IO error encountered -- skipping file deletion)', '[I] Schnappschuss erstellen (rsync: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1333) [sender=3.2.3])', '[I] Take snapshot (rsync: rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1333) [sender=3.2.3])', ) for line in log_lines: self.assertEqual(line, logFilter.filter(line)) for line in (self.e, self.c, self.i, self.h): self.assertIsNone(logFilter.filter(line)) for line in self.n: self.assertEqual(line, logFilter.filter(line)) # empty line stays empty line class TestSnapshotLog(generic.SnapshotsTestCase): def setUp(self): super(TestSnapshotLog, self).setUp() self.logFile = os.path.join(self.cfg._LOCAL_DATA_FOLDER, 'takesnapshot_.log') def test_new(self): log = snapshotlog.SnapshotLog(self.cfg) now = datetime.today() with open(self.logFile, 'wt') as f: f.write('foo\nbar\n') log.new(now) log.flush() self.assertExists(self.logFile) with open(self.logFile, 'rt') as f: self.assertRegex(f.read(), re.compile(r'''========== Take snapshot \(profile .*\): .* ========== ''', re.MULTILINE)) def test_new_continue(self): log = snapshotlog.SnapshotLog(self.cfg) now = datetime.today() with open(self.logFile, 'wt') as f: f.write('foo\nbar\n') new = snapshots.NewSnapshot(self.cfg) new.makeDirs() new.saveToContinue = True log.new(now) log.flush() self.assertExists(self.logFile) with open(self.logFile, 'rt') as f: self.assertRegex(f.read(), re.compile(r'''foo bar Last snapshot didn't finish but can be continued. ======== continue snapshot \(profile .*\): .* ======== ''', re.MULTILINE)) def test_append(self): log = snapshotlog.SnapshotLog(self.cfg) log.append('foo', 1) log.flush() self.assertExists(self.logFile) with open(self.logFile, 'rt') as f: self.assertEqual(f.read(), 'foo\n') def test_append_log_level(self): self.cfg.setLogLevel(2) log = snapshotlog.SnapshotLog(self.cfg) log.append('foo', 3) log.flush() self.assertNotExists(self.logFile) log.append('bar', 1) log.flush() self.assertExists(self.logFile) with open(self.logFile, 'rt') as f: self.assertEqual(f.read(), 'bar\n') def test_get(self): log = snapshotlog.SnapshotLog(self.cfg) log.append('foo bar', 1) log.flush() self.assertExists(self.logFile) self.assertEqual('\n'.join(log.get()), 'foo bar') def test_get_filter(self): log = snapshotlog.SnapshotLog(self.cfg) log.append('foo bar', 1) log.append('[I] 123', 1) log.append('[C] baz', 1) log.append('[E] bla', 1) log.flush() self.assertExists(self.logFile) self.assertEqual('\n'.join(log.get(mode = snapshotlog.LogFilter.CHANGES)), 'foo bar\n[C] baz') def test_skipLines_show_all(self): log = snapshotlog.SnapshotLog(self.cfg) for i in range(10): log.append(str(i), 1) log.flush() self.assertEqual('\n'.join(log.get(skipLines = 0)), '\n'.join([str(i) for i in range(10)])) def test_skipLines(self): log = snapshotlog.SnapshotLog(self.cfg) for i in range(10): log.append(str(i), 1) log.flush() self.assertEqual('\n'.join(log.get(skipLines = 4)), '\n'.join([str(i) for i in range(4, 10)])) def test_skipLines_filtered(self): log = snapshotlog.SnapshotLog(self.cfg) log.append('foo bar', 1) log.append('[I] 123', 1) log.append('[C] baz', 1) log.append('[E] bla', 1) log.append('[C] 456', 1) log.append('[C] 789', 1) log.append('[E] qwe', 1) log.append('[C] asd', 1) log.flush() self.assertEqual('\n'.join(log.get(mode = snapshotlog.LogFilter.CHANGES, skipLines = 2)), '[C] 456\n[C] 789\n[C] asd') backintime-1.5.4/common/test/test_snapshots.py000066400000000000000000001052221477034762000215450ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import pathlib import shutil import stat import grp import re import random import string import unittest from unittest.mock import patch from tempfile import TemporaryDirectory from test import generic from test.constants import CURRENTUSER, CURRENTGROUP, CURRENTGID, CURRENTUID sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import logger import config import snapshots import tools import mount # all groups the current user is member in GROUPS = [i.gr_name for i in grp.getgrall() if CURRENTUSER in i.gr_mem] class SetTakeSnapshotMessage(generic.SnapshotsTestCase): def test_info(self): self.sn.setTakeSnapshotMessage(0, 'first message') self.sn.snapshotLog.flush() # test NotifyPlugin self.mockNotifyPlugin.assert_called_once_with(self.sn.config.currentProfile(), self.sn.config.profileName(), 0, 'first message', -1) self.assertExists(self.sn.config.takeSnapshotMessageFile()) # test message file with open(self.sn.config.takeSnapshotMessageFile(), 'rt') as f: message = f.read() self.assertEqual(message, '0\nfirst message') # test snapshot log self.assertEqual('\n'.join(self.sn.snapshotLog.get()), '[I] first message') def test_error(self): self.sn.setTakeSnapshotMessage(1, 'second message') self.sn.snapshotLog.flush() # test NotifyPlugin self.mockNotifyPlugin.assert_called_once_with(self.sn.config.currentProfile(), self.sn.config.profileName(), 1, 'second message', -1) # test message file self.assertExists(self.sn.config.takeSnapshotMessageFile()) with open(self.sn.config.takeSnapshotMessageFile(), 'rt') as f: message = f.read() self.assertEqual(message, '1\nsecond message') # test snapshot log self.assertEqual('\n'.join(self.sn.snapshotLog.get()), '[E] second message') class UserAndGroups(generic.SnapshotsTestCase): def test_uid_valid(self): self.assertEqual(self.sn.uid('root'), 0) self.assertEqual(self.sn.uid(b'root'), 0) self.assertEqual(self.sn.uid(CURRENTUSER), CURRENTUID) self.assertEqual(self.sn.uid(CURRENTUSER.encode()), CURRENTUID) def test_uid_invalid(self): self.assertEqual(self.sn.uid('nonExistingUser'), -1) self.assertEqual(self.sn.uid(b'nonExistingUser'), -1) def test_uid_backup(self): self.assertEqual(self.sn.uid('root', backup = 99999), 0) self.assertEqual(self.sn.uid(b'root', backup = 99999), 0) self.assertEqual(self.sn.uid('nonExistingUser', backup = 99999), 99999) self.assertEqual(self.sn.uid(b'nonExistingUser', backup = 99999), 99999) self.assertEqual(self.sn.uid(CURRENTUSER, backup = 99999), CURRENTUID) self.assertEqual(self.sn.uid(CURRENTUSER.encode(), backup = 99999), CURRENTUID) def test_gid_valid(self): self.assertEqual(self.sn.gid('root'), 0) self.assertEqual(self.sn.gid(b'root'), 0) self.assertEqual(self.sn.gid(CURRENTGROUP), CURRENTGID) self.assertEqual(self.sn.gid(CURRENTGROUP.encode()), CURRENTGID) def test_gid_invalid(self): self.assertEqual(self.sn.gid('nonExistingGroup'), -1) self.assertEqual(self.sn.gid(b'nonExistingGroup'), -1) def test_gid_backup(self): self.assertEqual(self.sn.gid('root', backup = 99999), 0) self.assertEqual(self.sn.gid(b'root', backup = 99999), 0) self.assertEqual(self.sn.gid('nonExistingGroup', backup = 99999), 99999) self.assertEqual(self.sn.gid(b'nonExistingGroup', backup = 99999), 99999) self.assertEqual(self.sn.gid(CURRENTGROUP, backup = 99999), CURRENTGID) self.assertEqual(self.sn.gid(CURRENTGROUP.encode(), backup = 99999), CURRENTGID) def test_username_valid(self): self.assertEqual(self.sn.userName(0), 'root') self.assertEqual(self.sn.userName(CURRENTUID), CURRENTUSER) def test_username_invalid(self): self.assertEqual(self.sn.userName(99999), '-') def test_groupname_valid(self): self.assertEqual(self.sn.groupName(0), 'root') self.assertEqual(self.sn.groupName(CURRENTGID), CURRENTGROUP) def test_groupname_invalid(self): self.assertEqual(self.sn.groupName(99999), '-') class HelperScripts(generic.SnapshotsTestCase): def test_rsync_remote_path(self): self.assertEqual(self.sn.rsyncRemotePath('/foo'), '/foo') # "quote" is ignored because the "mode" isn't ssh or ssh_encfs self.assertEqual(self.sn.rsyncRemotePath('/foo', quote = '\\\"'), '/foo') self.assertEqual(self.sn.rsyncRemotePath('/foo', use_mode = ['local']), '/foo') # The same as above. self.assertEqual(self.sn.rsyncRemotePath('/foo', use_mode = ['local'], quote = '\\\"'), '/foo') #set up SSH profile self.cfg.setSnapshotsMode('ssh') self.cfg.setSshHost('localhost') self.cfg.setSshUser('foo') self.assertEqual(self.sn.rsyncRemotePath('/bar'), 'foo@localhost:"/bar"') self.assertEqual(self.sn.rsyncRemotePath('/bar', quote = '\\\"'), 'foo@localhost:\\\"/bar\\\"') self.assertEqual(self.sn.rsyncRemotePath('/bar', use_mode = []), '/bar') def test_create_last_snapshot_symlink(self): sid1 = snapshots.SID('20151219-010324-123', self.cfg) sid1.makeDirs() symlink = self.cfg.lastSnapshotSymlink() self.assertNotExists(symlink) self.assertTrue(self.sn.createLastSnapshotSymlink(sid1)) self.assertIsLink(symlink) self.assertEqual(os.path.realpath(symlink), sid1.path()) sid2 = snapshots.SID('20151219-020324-123', self.cfg) sid2.makeDirs() self.assertTrue(self.sn.createLastSnapshotSymlink(sid2)) self.assertIsLink(symlink) self.assertEqual(os.path.realpath(symlink), sid2.path()) def test_stat_free_space_local(self): self.assertIsInstance(self.sn.statFreeSpaceLocal('/'), int) @patch('time.sleep') # speed up unittest def test_make_dirs(self, sleep): self.assertFalse(self.sn.makeDirs('/')) self.assertTrue(self.sn.makeDirs(os.getcwd())) with TemporaryDirectory() as d: path = os.path.join(d, 'foo', 'bar') self.assertTrue(self.sn.makeDirs(path)) class RsyncExcludeIncludeSuffix(generic.SnapshotsTestCase): def test_exclude_unique_items(self): exclude = self.sn.rsyncExclude(['/foo', '*bar', '/baz/1']) self.assertListEqual(list(exclude), ['--exclude=/foo', '--exclude=*bar', '--exclude=/baz/1']) def test_include_unique_items(self): i1, i2 = self.sn.rsyncInclude([('/foo', 0), ('/bar', 1), ('/baz/1/2', 1)]) self.assertListEqual(list(i1), ['--include=/foo/', '--include=/baz/1/', '--include=/baz/']) self.assertListEqual(list(i2), ['--include=/foo/**', '--include=/bar', '--include=/baz/1/2']) def test_include_root(self): i1, i2 = self.sn.rsyncInclude([('/', 0), ]) self.assertListEqual(list(i1), []) self.assertListEqual(list(i2), ['--include=/', '--include=/**']) def test_rsync_suffix(self): suffix = self.sn.rsyncSuffix(includeFolders = [('/foo', 0), ('/bar', 1), ('/baz/1/2', 1)], excludeFolders = ['/foo/bar', '*blub', '/bar/2']) self.assertIsInstance(suffix, list) self.assertRegex(' '.join(suffix), r'^--chmod=Du\+wx ' + r'--exclude=/tmp/.*? ' + r'--exclude=.*?\.local/share/backintime ' + r'--exclude=\.local/share/backintime/mnt ' + r'--include=/foo/ ' + r'--include=/baz/1/ ' + r'--include=/baz/ ' + r'--exclude=/foo/bar ' + r'--exclude=\*blub ' + r'--exclude=/bar/2 ' + r'--include=/foo/\*\* ' + r'--include=/bar ' + r'--include=/baz/1/2 ' + r'--exclude=\* /$') class Callbacks(generic.SnapshotsTestCase): def test_restore(self): msg = 'foo' callback = lambda x: self.callback(self.assertEqual, x, msg) self.sn.restoreCallback(callback, True, msg) self.assertTrue(self.run) self.assertFalse(self.sn.restorePermissionFailed) self.run = False callback = lambda x: self.callback(self.assertRegex, x, r'{} : \w+'.format(msg)) self.sn.restoreCallback(callback, False, msg) self.assertTrue(self.run) self.assertTrue(self.sn.restorePermissionFailed) def test_callback(self): params = [False, False] self.sn.rsyncCallback('foo', params) self.assertListEqual([False, False], params) with open(self.cfg.takeSnapshotMessageFile(), 'rt') as f: self.assertEqual('0\nTake snapshot (rsync: foo)', f.read()) self.sn.snapshotLog.flush() with open(self.cfg.takeSnapshotLogFile(), 'rt') as f: self.assertEqual('[I] Take snapshot (rsync: foo)\n', f.read()) def test_keep_params(self): params = [True, True] self.sn.rsyncCallback('foo', params) self.assertListEqual([True, True], params) def test_transfer(self): params = [False, False] self.sn.rsyncCallback('BACKINTIME: # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests related to Remove & Retention, formally known as Auto- and Smart-remove. About the current state of this test module: Most of the tests in this module are pseudo-tests. The do not test productive code but surrogates (e.g. method name `_org()` in each class). Because the productive code is in an untestable state and needs refactoring or totally rewrite. This is on the projects todo list. See meta issue #1945. """ import os import sys import inspect from unittest import mock from typing import Union from datetime import date, time, datetime, timedelta from pathlib import Path from tempfile import TemporaryDirectory import pyfakefs.fake_filesystem_unittest as pyfakefs_ut sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import config # noqa: E402,RUF100 import snapshots # noqa: E402,RUF100 def dt2sidstr(d: Union[date, datetime], t: time = None, tag: int = 123): """Create a SID identification string out ouf a date and time infos.""" if not t: try: # If d is datetime t = d.time() except AttributeError: t = time(7, 42, 31) return datetime.combine(d, t).strftime(f'%Y%m%d-%H%M%S-{tag}') def dt2str(d: Union[date, datetime]): return d.strftime('%a %d %b %Y') def sid2str(sid): """Convert a SID string into human readable date incl. weekday.""" if isinstance(sid, snapshots.SID): sid = str(sid) result = datetime.strptime(sid.split('-')[0], '%Y%m%d') \ .date().strftime('%c').strip() if result.endswith(' 00:00:00'): result = result[:-9] return result def create_SIDs(start_date: Union[date, datetime, list[date]], days: int, cfg: config.Config): sids = [] if isinstance(start_date, list): the_dates = start_date else: the_dates = [start_date + timedelta(days=x) for x in range(days)] for d in the_dates: sids.append(snapshots.SID(dt2sidstr(d), cfg)) return sorted(sids, reverse=True) class KeepFirst(pyfakefs_ut.TestCase): """Test Snapshot.removeKeepFirst(). PyFakeFS is used here because of Config file dependency.""" def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def test_one_but_set(self): """Return value is always a set with always only one element.""" # One SID for each of 20 days beginning with 5th March 2022 07:42:31 sids = create_SIDs( datetime(2020, 3, 5, 7, 42, 31), 700, self.cfg) sut = self.sn.smartRemoveKeepFirst( sids, date(2021, 8, 5), datetime.now().date()) self.assertIsInstance(sut, set) self.assertTrue(len(sut), 1) def test_simple_one(self): """First element in a range of SIDs""" sids = create_SIDs( datetime(2022, 3, 5, 7, 42, 31), 20, self.cfg) sut = self.sn.smartRemoveKeepFirst( sids, date(2022, 3, 5), datetime.now().date()) sut = sut.pop() self.assertTrue(str(sut).startswith('20220324-074231-')) def test_min_included_max_not(self): """Minimum date is included in range, but max date not""" sids = create_SIDs( [ datetime(2022, 3, 5), datetime(2022, 3, 3), ], None, self.cfg) sut = self.sn.smartRemoveKeepFirst( snapshots=sids, min_date=date(2022, 3, 3), max_date=date(2022, 3, 5), ) self.assertEqual(len(sut), 1) sut = sut.pop() # the min_date is included self.assertEqual(sut.date.date(), date(2022, 3, 3)) def test_no_date_ordering(self): """Hit first in the list and ignoring its date ordering. The list of snapshots is not ordered anywhere.""" sids = [] # April, 2016... for timestamp_string in ['20160424-215134-123', # …24th # This SID will hit because it is the first # in the range specified. '20160422-030324-123', # …22th '20160422-020324-123', # …22th '20160422-010324-123', # …22th # This might be the earliest/first SID in the # date range specified but it is not the first # in the list. So it won't be hit. '20160421-013218-123', # …21th '20160410-134327-123']: # …10th sids.append(snapshots.SID(timestamp_string, self.cfg)) sut = self.sn.smartRemoveKeepFirst(sids, date(2016, 4, 20), date(2016, 4, 23)) self.assertEqual(str(sut.pop()), '20160422-030324-123') def test_keep_first_range_outside(self): """No SID inside the specified range""" sids = [] # April, 2016... for timestamp_string in ['20160424-215134-123', # …24th '20160422-030324-123', # …22th '20160422-020324-123', # …22th '20160422-010324-123', # …22th '20160421-013218-123', # …21th '20160410-134327-123']: # …10th sids.append(snapshots.SID(timestamp_string, self.cfg)) # Between 11th and 18th April sut = self.sn.smartRemoveKeepFirst(sids, date(2016, 4, 11), date(2016, 4, 18)) # None will hit, because no SID in that range. self.assertEqual(len(sut), 0) @mock.patch.object(snapshots.SID, 'failed', new_callable=lambda: True) def test_all_invalid(self, _mock_failed): """All SIDS invalid (not healthy)""" sids = create_SIDs( datetime(2022, 3, 5, 7, 42, 31), 20, self.cfg) # By default healthy/invalid status is irrelevant sut = self.sn.smartRemoveKeepFirst( sids, date(2022, 3, 5), datetime.now().date()) self.assertTrue(len(sut), 1) # Now make it relevant sut = self.sn.smartRemoveKeepFirst( sids, date(2022, 3, 5), datetime.now().date(), keep_healthy=True) self.assertTrue(len(sut), 0) @mock.patch.object(snapshots.SID, 'failed', new_callable=mock.PropertyMock) def test_ignore_unhealthy(self, mock_failed): # The second call to failed-property returns True mock_failed.side_effect = [False, True, False, False, False, False] sids = [] for timestamp_string in ['20160424-215134-123', # could be hit, but is NOT healthy '20160422-030324-123', # hit this '20160422-020324-123', '20160422-010324-123', '20160421-013218-123', '20160410-134327-123']: sids.append(snapshots.SID(timestamp_string, self.cfg)) # keep the first healthy snapshot sut = self.sn.smartRemoveKeepFirst(sids, date(2016, 4, 20), date(2016, 4, 23), keep_healthy=True) self.assertEqual(str(sut.pop()), '20160422-020324-123') class KeepAllForLast(pyfakefs_ut.TestCase): """Test Snapshot.removeKeepAll(). Keep all snapshots for the last N days. PyFakeFS is used here because of Config file dependency.""" def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def _org(self, snapshots, now, days_to_keep): """Simulated production code. Refactoring is on the todo list.""" keep_all = days_to_keep keep = self.sn.smartRemoveKeepAll( snapshots, now - timedelta(days=keep_all-1), now + timedelta(days=1)) return sorted(keep, reverse=True) def test_border(self): """The dates used in the user manual example. Here the current (just running incomplete) day is contained in the calculation. """ sids = create_SIDs([ datetime(2025, 4, 17, 22, 0), datetime(2025, 4, 17, 18, 1), datetime(2025, 4, 17, 12, 0), datetime(2025, 4, 17, 4, 0), datetime(2025, 4, 16, 8, 30), datetime(2025, 4, 15, 16, 0), datetime(2025, 4, 15, 0, 0), datetime(2025, 4, 14, 23, 59), datetime(2025, 4, 14, 9, 0), ], None, self.cfg) sut = self._org( snapshots=sids, now=datetime(2025, 4, 17, 22, 00).date(), days_to_keep=2) self.assertEqual(sut[0].date, datetime(2025, 4, 17, 22, 0)) self.assertEqual(sut[1].date, datetime(2025, 4, 17, 18, 1)) self.assertEqual(sut[2].date, datetime(2025, 4, 17, 12, 0)) self.assertEqual(sut[3].date, datetime(2025, 4, 17, 4, 0)) self.assertEqual(sut[4].date, datetime(2025, 4, 16, 8, 30)) def test_simple(self): """Simple""" # 10th to 25th sids = create_SIDs(datetime(2024, 2, 10), 15, self.cfg) # keep... sut = self.sn.smartRemoveKeepAll( sids, # ... from 12th ... date(2024, 2, 12), # ... to 19th. date(2024, 2, 20) ) self.assertEqual(len(sut), 8) sut = sorted(sut) self.assertEqual(sut[0].date.date(), date(2024, 2, 12)) self.assertEqual(sut[1].date.date(), date(2024, 2, 13)) self.assertEqual(sut[2].date.date(), date(2024, 2, 14)) self.assertEqual(sut[3].date.date(), date(2024, 2, 15)) self.assertEqual(sut[4].date.date(), date(2024, 2, 16)) self.assertEqual(sut[5].date.date(), date(2024, 2, 17)) self.assertEqual(sut[6].date.date(), date(2024, 2, 18)) self.assertEqual(sut[7].date.date(), date(2024, 2, 19)) class KeepOneForLastNDays(pyfakefs_ut.TestCase): """Covering the smart remove setting 'Keep the last snapshot of each day for the last N days.'. That logic is implemented in 'Snapshots.smartRemoveList()' but not testable in isolation. So for a first shot we just duplicate that code in this tests (see self._org()). """ def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def _org(self, now, n_days, snapshots): """Copied and slightly refactored from inside 'Snapshots.smartRemoveList()'. """ keep = set() d = now for _ in range(0, n_days): keep |= self.sn.smartRemoveKeepFirst( snapshots, d, d + timedelta(days=1), keep_healthy=True) d -= timedelta(days=1) return sorted(keep, reverse=True) def test_doc_example(self): sids = create_SIDs([ datetime(2025, 4, 17, 22, 0), datetime(2025, 4, 17, 4, 0), datetime(2025, 4, 16, 8, 30), datetime(2025, 4, 15, 16, 0), datetime(2025, 4, 15, 0, 0), datetime(2025, 4, 14, 23, 59), datetime(2025, 4, 13, 19, 0), datetime(2025, 4, 13, 7, 0), datetime(2025, 4, 12, 18, 45), datetime(2025, 4, 12, 18, 5), datetime(2025, 4, 11, 9, 0), ], None, self.cfg) sut = self._org( now=date(2025, 4, 17), n_days=5, snapshots=sids) self.assertEqual(sut[0].date, datetime(2025, 4, 17, 22, 0)) self.assertEqual(sut[1].date, datetime(2025, 4, 16, 8, 30)) self.assertEqual(sut[2].date, datetime(2025, 4, 15, 16, 0)) self.assertEqual(sut[3].date, datetime(2025, 4, 14, 23, 59)) self.assertEqual(sut[4].date, datetime(2025, 4, 13, 19, 0)) class KeepOneForLastNWeeks(pyfakefs_ut.TestCase): """Covering the smart remove setting 'Keep the last snapshot for each week for the last N weeks'. That logic is implemented in 'Snapshots.smartRemoveList()' but not testable in isolation. So for a first shot we just duplicate that code in this tests (see self._org()). """ def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def _org(self, now, n_weeks, snapshots, keep_healthy=True): """Keep one per week for the last n_weeks weeks. Copied and slightly refactored from inside 'Snapshots.smartRemoveList()'. """ keep = set() # Sunday ??? (Sonntag) of previous week idx_date = now - timedelta(days=now.weekday()) for _ in range(0, n_weeks): min_date = idx_date max_date = idx_date + timedelta(days=7) keep |= self.sn.smartRemoveKeepFirst( snapshots, min_date, max_date, keep_healthy=keep_healthy) idx_date -= timedelta(days=7) return sorted(keep, reverse=True) def test_doc_example(self): """Example used in manual""" sids = create_SIDs( [ # 5 Weeks, each 3 days datetime(2025, 4, 17, 22, 0), datetime(2025, 4, 16, 4, 0), datetime(2025, 4, 15, 14, 0), datetime(2025, 4, 13, 22, 0), datetime(2025, 4, 9, 4, 0), datetime(2025, 4, 8, 14, 0), datetime(2025, 4, 3, 22, 0), datetime(2025, 4, 2, 4, 0), datetime(2025, 4, 1, 14, 0), datetime(2025, 3, 27, 22, 0), datetime(2025, 3, 26, 4, 0), datetime(2025, 3, 24, 14, 0), datetime(2025, 3, 20, 22, 0), datetime(2025, 3, 19, 4, 0), datetime(2025, 3, 18, 14, 0) ], None, self.cfg ) sut = self._org( now=date(2025, 4, 17), n_weeks=4, snapshots=sids) self.assertEqual(sut[0].date, datetime(2025, 4, 17, 22, 0)) self.assertEqual(sut[1].date, datetime(2025, 4, 13, 22, 0)) self.assertEqual(sut[2].date, datetime(2025, 4, 3, 22, 0)) self.assertEqual(sut[3].date, datetime(2025, 3, 27, 22, 0)) self.assertEqual(len(sut), 4) class KeepOneForLastNMonths(pyfakefs_ut.TestCase): """Covering the smart remove setting 'Keep the last snapshot for each month for the last N months'. That logic is implemented in 'Snapshots.smartRemoveList()' but not testable in isolation. So for a first shot we just duplicate that code in this tests (see self._org()). """ def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def _org(self, now, n_months, snapshots, keep_healthy=True): """Keep one per months for the last n_months months. Copied and slightly refactored from inside 'Snapshots.smartRemoveList()'. """ keep = set() d1 = date(now.year, now.month, 1) d2 = self.sn.incMonth(d1) # each months for _ in range(0, n_months): keep |= self.sn.smartRemoveKeepFirst( snapshots, d1, d2, keep_healthy=keep_healthy) d2 = d1 d1 = self.sn.decMonth(d1) return sorted(keep, reverse=True) def test_doc_example(self): sids = create_SIDs( [ # 10 months period date(2025, 8, 18), date(2025, 8, 6), date(2025, 7, 31), date(2025, 7, 1), date(2025, 6, 30), date(2025, 6, 1), # gap of 2 months date(2025, 3, 18), date(2025, 2, 9), date(2025, 1, 6), date(2024, 12, 26), date(2024, 11, 14), ], None, self.cfg ) now = sids[0].date.date() + timedelta(days=5) months = 6 sut = self._org( now=now, # Keep the last week n_months=months, snapshots=sids) expect = [ date(2025, 8, 18), date(2025, 7, 31), date(2025, 6, 30), date(2025, 3, 18), ] self.assertEqual(len(sut), len(expect)) for idx, expect_date in enumerate(expect): self.assertEqual(sut[idx].date.date(), expect_date) class KeepOnePerYearForAllYears(pyfakefs_ut.TestCase): """Covering the smart remove setting 'Keep the last snapshot for each year for all years.' That logic is implemented in 'Snapshots.smartRemoveList()' but not testable in isolation. So for a first shot we just duplicate that code in this tests (see self._org()). """ def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def _org(self, now, snapshots, keep_healthy=True): """Keep one per year Copied and slightly refactored from inside 'Snapshots.smartRemoveList()'. """ first_year = int(snapshots[-1].sid[:4]) keep = set() for i in range(first_year, now.year+1): keep |= self.sn.smartRemoveKeepFirst( snapshots, date(i, 1, 1), date(i+1, 1, 1), keep_healthy=keep_healthy) return sorted(keep, reverse=True) def test_doc_example(self): now = date(2024, 12, 16) sids = create_SIDs( [ date(2024, 10, 26), date(2024, 4, 13), date(2023, 10, 26), date(2023, 10, 8), date(2023, 1, 1), date(2022, 12, 31), date(2022, 4, 13), date(2020, 10, 26), date(2020, 4, 13), ], None, self.cfg ) sut = self._org( now=now, snapshots=sids) expect = [ date(2024, 10, 26), date(2023, 10, 26), date(2022, 12, 31), date(2020, 10, 26), ] self.assertEqual(len(sut), len(expect)) for idx, expect_date in enumerate(expect): self.assertTrue(sut[idx].date.date(), expect_date) class IncDecMonths(pyfakefs_ut.TestCase): """PyFakeFS is used here because of Config file dependency.""" def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) # cleanup() happens automatically self._temp_dir = TemporaryDirectory(prefix='bit.') # Workaround: tempfile and pathlib not compatible yet self.temp_path = Path(self._temp_dir.name) self._config_fp = self._create_config_file(parent_path=self.temp_path) self.cfg = config.Config(str(self._config_fp)) self.sn = snapshots.Snapshots(self.cfg) def _create_config_file(self, parent_path): """Minimal config file""" # pylint: disable-next=R0801 cfg_content = inspect.cleandoc(''' config.version=6 profile1.snapshots.include.1.type=0 profile1.snapshots.include.1.value=rootpath/source profile1.snapshots.include.size=1 profile1.snapshots.no_on_battery=false profile1.snapshots.notify.enabled=true profile1.snapshots.path=rootpath/destination profile1.snapshots.path.host=test-host profile1.snapshots.path.profile=1 profile1.snapshots.path.user=test-user profile1.snapshots.preserve_acl=false profile1.snapshots.preserve_xattr=false profile1.snapshots.remove_old_snapshots.enabled=true profile1.snapshots.remove_old_snapshots.unit=80 profile1.snapshots.remove_old_snapshots.value=10 profile1.snapshots.rsync_options.enabled=false profile1.snapshots.rsync_options.value= profiles.version=1 ''') # config file location config_fp = parent_path / 'config_path' / 'config' config_fp.parent.mkdir() config_fp.write_text(cfg_content, 'utf-8') return config_fp def test_inc_simple(self): sut = self.sn.incMonth(date(1982, 8, 6)) self.assertEqual(sut, date(1982, 9, 1)) def test_inc_next_year(self): sut = self.sn.incMonth(date(1982, 12, 16)) self.assertEqual(sut, date(1983, 1, 1)) def test_inc_leap_year(self): sut = self.sn.incMonth(date(2020, 12, 16)) self.assertEqual(sut, date(2021, 1, 1)) def test_inc_leap_months(self): sut = self.sn.incMonth(date(2020, 2, 29)) self.assertEqual(sut, date(2020, 3, 1)) def test_dec_simple(self): sut = self.sn.decMonth(date(1982, 8, 6)) self.assertEqual(sut, date(1982, 7, 1)) def test_dec_year(self): sut = self.sn.decMonth(date(1982, 1, 6)) self.assertEqual(sut, date(1981, 12, 1)) def test_dec_leap_months(self): sut = self.sn.decMonth(date(2020, 2, 29)) self.assertEqual(sut, date(2020, 1, 1)) backintime-1.5.4/common/test/test_sshtools.py000066400000000000000000000411711477034762000214030ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016-2022 Taylor Raack # SPDX-FileCopyrightText: © 2016-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import random import subprocess import stat import shutil import unittest from tempfile import TemporaryDirectory from unittest.mock import patch from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import mount import sshtools import tools from exceptions import MountException SKIP_MESSAGE_SSH = 'Skip as this test requires a local ssh server, public ' \ 'and private keys installed' @unittest.skipIf(not generic.LOCAL_SSH, SKIP_MESSAGE_SSH) class General(generic.SSHTestCase): def test_can_mount_ssh_rw(self): mnt = mount.Mount(cfg = self.cfg, tmp_mount = True) mnt.preMountCheck(mode = 'ssh', first_run = True, **self.mount_kwargs) try: hash_id = mnt.mount(mode = 'ssh', check = False, **self.mount_kwargs) full_path = os.path.join( self.sharePath, ".local", "share", "backintime", "mnt", hash_id, "mountpoint", "testfile") # warning - don't use os.access for checking writability # https://github.com/bit-team/backintime/issues/490#issuecomment-156265196 with open(full_path, 'wt') as f: f.write('foo') finally: mnt.umount(hash_id = hash_id) def test_unlockSshAgent(self): subprocess.Popen(['ssh-add', '-D'], stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL).communicate() ssh = sshtools.SSH(cfg = self.cfg) ssh.unlockSshAgent(force = True) out = subprocess.Popen(['ssh-add', '-l'], stdout = subprocess.PIPE, universal_newlines = True).communicate()[0] self.assertIn(ssh.private_key_fingerprint, out) def test_unlockSshAgent_fail(self): subprocess.Popen(['ssh-add', '-D'], stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL).communicate() ssh = sshtools.SSH(cfg = self.cfg) ssh.private_key_fingerprint = 'wrong fingerprint' with self.assertRaisesRegex(MountException, r"Could not unlock ssh private key\. Wrong password or password not available for cron\."): ssh.unlockSshAgent(force = True) def test_checkLogin(self): ssh = sshtools.SSH(cfg = self.cfg) ssh.checkLogin() def test_checkLogin_fail_wrong_user(self): self.cfg.setSshUser('non_existing_user') ssh = sshtools.SSH(cfg = self.cfg) with self.assertRaisesRegex(MountException, r"Password-less authentication for .+ failed.+"): ssh.checkLogin() def test_checkCipher_default(self): ssh = sshtools.SSH(cfg = self.cfg, cipher = 'default') ssh.checkCipher() def test_checkCipher_specific(self): ssh = sshtools.SSH(cfg = self.cfg, cipher = 'aes128-ctr') ssh.checkCipher() def test_checkCipher_fail(self): # fix debug log self.cfg.SSH_CIPHERS['non_existing_cipher'] = 'non_existing_cipher' ssh = sshtools.SSH(cfg = self.cfg, cipher = 'non_existing_cipher') with self.assertRaisesRegex(MountException, r"Cipher .+ failed for.+"): ssh.checkCipher() def test_checkKnownHosts(self): ssh = sshtools.SSH(cfg = self.cfg) ssh.checkKnownHosts() def test_checkKnownHosts_fail(self): self.cfg.setSshHost('non_existing_host') ssh = sshtools.SSH(cfg = self.cfg) with self.assertRaisesRegex(MountException, r".+ not found in ssh_known_hosts\."): ssh.checkKnownHosts() def test_checkRemoteFolder(self): ssh = sshtools.SSH(cfg = self.cfg) #create new directories ssh.checkRemoteFolder() self.assertIsDir(self.remotePath) #rerun check to test if it correctly recognize previous created folders ssh.checkRemoteFolder() #make folder read-only with generic.mockPermissions(self.remotePath, stat.S_IRUSR | stat.S_IXUSR): with self.assertRaisesRegex(MountException, r"Remote path is not writable.+"): ssh.checkRemoteFolder() #make folder not executable with generic.mockPermissions(self.remotePath, stat.S_IRUSR | stat.S_IWUSR): with self.assertRaisesRegex(MountException, r"Remote path is not executable.+"): ssh.checkRemoteFolder() def test_checkRemoteFolder_fail_not_a_folder(self): with open(self.remotePath, 'wt') as f: f.write('foo') self.cfg.setSshSnapshotsPath(self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) #path already exist but is not a folder with self.assertRaisesRegex(MountException, r"Remote path exists but is not a directory.+"): ssh.checkRemoteFolder() def test_checkRemoteFolder_fail_can_not_create(self): ssh = sshtools.SSH(cfg = self.cfg) #can not create path with generic.mockPermissions(self.tmpDir.name, stat.S_IRUSR | stat.S_IXUSR): with self.assertRaisesRegex(MountException, r"Couldn't create remote path.+"): ssh.checkRemoteFolder() def test_checkRemoteFolder_with_spaces(self): self.remotePath = os.path.join(self.tmpDir.name, 'foo bar') self.cfg.setSshSnapshotsPath(self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) #create new directories ssh.checkRemoteFolder() self.assertIsDir(self.remotePath) def test_checkPingHost(self): ssh = sshtools.SSH(cfg = self.cfg) ssh.checkPingHost() def test_checkPingHost_fail(self): self.cfg.setSshHost('non_existing_host') ssh = sshtools.SSH(cfg = self.cfg) with self.assertRaisesRegex(MountException, r'Ping .+ failed\. Host is down or wrong address\.'): ssh.checkPingHost() def test_check_remote_command(self): self.cfg.setNiceOnRemote(tools.checkCommand('nice')) self.cfg.setIoniceOnRemote(tools.checkCommand('ionice')) self.cfg.setNocacheOnRemote(tools.checkCommand('nocache')) self.cfg.setSmartRemoveRunRemoteInBackground(tools.checkCommand('screen') and tools.checkCommand('flock')) os.mkdir(self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) ssh.checkRemoteCommands() def test_check_remote_command_fail(self): cmds = [] if tools.checkCommand('nice'): cmds.append('nice') self.cfg.setNiceOnRemote(True) if tools.checkCommand('ionice'): cmds.append('ionice') self.cfg.setIoniceOnRemote(True) if tools.checkCommand('nocache'): cmds.append('nocache') self.cfg.setNocacheOnRemote(True) if tools.checkCommand('screen') and tools.checkCommand('flock'): cmds.extend(('screen', 'flock', 'rmdir', 'mktemp')) self.cfg.setSmartRemoveRunRemoteInBackground(True) # make one after an other command from 'cmds' fail by symlink them # to /bin/false false = tools.which('false') for cmd in cmds: msg = 'current trap: %s' %cmd with self.subTest(cmd = cmd): with TemporaryDirectory() as self.remotePath: self.cfg.setSshSnapshotsPath(self.remotePath) os.symlink(false, os.path.join(self.remotePath, cmd)) self.cfg.setSshPrefix(True, "export PATH=%s:$PATH; " %self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) with self.assertRaisesRegex(MountException, r"Remote host .+ doesn't support '.*?%s.*'" %cmd, msg = msg): ssh.checkRemoteCommands() def test_check_remote_command_hard_link_fail(self): # let hard-link check fail by manipulate one of the files os.mkdir(self.remotePath) self.cfg.setSshPrefix(True, 'TRAP=$(ls -1d %s/tmp_* | tail -n1)/a; rm $TRAP; echo bar > $TRAP; ' %self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) with self.assertRaisesRegex(MountException, r"Remote host .+ doesn't support hardlinks"): ssh.checkRemoteCommands() def test_check_remote_command_with_spaces(self): self.cfg.setSmartRemoveRunRemoteInBackground(tools.checkCommand('screen') and tools.checkCommand('flock')) self.remotePath = os.path.join(self.tmpDir.name, 'foo bar') self.cfg.setSshSnapshotsPath(self.remotePath) os.mkdir(self.remotePath) ssh = sshtools.SSH(cfg = self.cfg) ssh.checkRemoteCommands() def test_randomId(self): ssh = sshtools.SSH(cfg = self.cfg) self.assertRegex(ssh.randomId(size = 6), r'[A-Z0-9]{6}') class SshKey(generic.TestCaseCfg): def test_generate(self): with TemporaryDirectory() as tmp: secKey = os.path.join(tmp, 'key') pubKey = secKey + '.pub' # create new key self.assertTrue(sshtools.sshKeyGen(secKey)) self.assertIsFile(secKey) self.assertIsFile(pubKey) # do not overwrite existing keys self.assertFalse(sshtools.sshKeyGen(secKey)) @unittest.skipIf(not tools.checkCommand('ssh-keygen') and not generic.ON_TRAVIS, # enforce test on TravisCI "'ssh-keygen' not found." ) def test_fingerprint(self): self.assertIsNone( sshtools.sshKeyFingerprint(os.path.abspath(__file__))) with TemporaryDirectory() as d: key = os.path.join(d, 'key') cmd = ['ssh-keygen', '-q', '-N', '', '-f', key] proc = subprocess.Popen(cmd) proc.communicate() fingerprint = sshtools.sshKeyFingerprint(key) self.assertIsInstance(fingerprint, str) if fingerprint.startswith('SHA256'): self.assertEqual(len(fingerprint), 50) self.assertRegex(fingerprint, r'^SHA256:[a-zA-Z0-9/+]+$') else: self.assertEqual(len(fingerprint), 47) self.assertRegex(fingerprint, r'^[a-fA-F0-9:]+$') @unittest.skipIf(not generic.LOCAL_SSH, 'Skip as this test requires a local ssh server, public and private keys installed') def test_host_key(self): fingerprint, keyHash, keyType = sshtools.sshHostKey('localhost') self.assertIsInstance(fingerprint, str) self.assertIsInstance(keyHash, str) self.assertIsInstance(keyType, str) if fingerprint.startswith('SHA256'): self.assertEqual(len(fingerprint), 50) self.assertRegex(fingerprint, r'^SHA256:[a-zA-Z0-9/+]+$') else: self.assertEqual(len(fingerprint), 47) self.assertRegex(fingerprint, r'^[a-fA-F0-9:]+$') self.assertIn(keyType, ('ECDSA', 'RSA')) hostKey = '/etc/ssh/ssh_host_{}_key.pub'.format(keyType.lower()) self.assertExists(hostKey) def test_write_known_host_file(self): KEY = '|1|abcdefghijklmnopqrstuvwxyz= ecdsa-sha2-nistp256 AAAAABCDEFGHIJKLMNOPQRSTUVWXYZ=' with TemporaryDirectory() as tmp: knownHosts = os.path.expanduser('~/.ssh/known_hosts') knownHostsSic = os.path.join(tmp, 'known_hosts') if os.path.exists(knownHosts): shutil.copyfile(knownHosts, knownHostsSic) try: sshtools.writeKnownHostsFile(KEY) self.assertExists(knownHosts) with open(knownHosts, 'rt') as f: self.assertIn(KEY, [x.strip() for x in f.readlines()]) finally: # restore original known_hosts file if os.path.exists(knownHostsSic): shutil.copyfile(knownHostsSic, knownHosts) @unittest.skipIf(not generic.LOCAL_SSH, SKIP_MESSAGE_SSH) class StartSshAgent(generic.SSHTestCase): # running this test requires that user has public / private key pair created and ssh server running SOCK = 'SSH_AUTH_SOCK' PID = 'SSH_AGENT_PID' def setUp(self): super().setUp() self.ssh = sshtools.SSH(cfg = self.cfg) self.currentSock = os.environ.pop(self.SOCK, '') self.currentPid = os.environ.pop(self.PID, '') def tearDown(self): os.environ[self.SOCK] = self.currentSock os.environ[self.PID] = self.currentPid def test_just_start(self): self.ssh.startSshAgent() self.assertTrue(self.SOCK in os.environ) self.assertTrue(self.PID in os.environ) @patch('tools.which') @patch('os.kill') def test_equal_sign(self, mockKill, mockWhich): mockWhich.return_value = ['echo', 'setenv SSH_AUTH_SOCK=/tmp/ssh-zWg8uTdgh1QJ/agent.9070;\n', 'setenv SSH_AGENT_PID=9071;\n' 'echo Agent pid 9071;'] self.ssh.startSshAgent() self.assertTrue(self.SOCK in os.environ) self.assertTrue(self.PID in os.environ) @patch('tools.which') @patch('os.kill') def test_space(self, mockKill, mockWhich): mockWhich.return_value = ['echo', 'setenv SSH_AUTH_SOCK /tmp/ssh-zWg8uTdgh1QJ/agent.9070;\n', 'setenv SSH_AGENT_PID 9071;\n' 'echo Agent pid 9071;'] self.ssh.startSshAgent() self.assertTrue(self.SOCK in os.environ) self.assertTrue(self.PID in os.environ) @patch('tools.which') @patch('os.kill') def test_export(self, mockKill, mockWhich): mockWhich.return_value = ['echo', 'SSH_AUTH_SOCK=/tmp/ssh-zWg8uTdgh1QJ/agent.9070; export SSH_AUTH_SOCK;\n', 'SSH_AGENT_PID=9071; export SSH_AGENT_PID;\n' 'echo Agent pid 9071;'] self.ssh.startSshAgent() self.assertTrue(self.SOCK in os.environ) self.assertTrue(self.PID in os.environ) @patch('tools.which') def test_error(self, mockWhich): mockWhich.return_value = '/bin/false' with self.assertRaises(MountException): self.ssh.startSshAgent() @patch('tools.which') def test_missing(self, mockWhich): mockWhich.return_value = '' with self.assertRaises(MountException): self.ssh.startSshAgent() class SSHCopyID(unittest.TestCase): def test_complete_command(self): """Complete generated command""" command = sshtools.sshCopyIdCommand( generic.PRIV_KEY_FILE, 'user', 'non_existing_host', ) self.assertEqual( command, [ 'ssh-copy-id', '-i', generic.PRIV_KEY_FILE, '-p', '22', 'user@non_existing_host' ] ) def test_default_port(self): """Default port""" sut = sshtools.sshCopyIdCommand( generic.PRIV_KEY_FILE, 'user', 'non_existing_host', ) self.assertEqual(len(sut), 6, sut) # no port explicit specified self.assertEqual(sut[4], '22') def test_custom_port(self): """Custom (random) port""" custom_port = str(random.randint(23, 128)) sut = sshtools.sshCopyIdCommand( generic.PRIV_KEY_FILE, 'user', 'non_existing_host', port=custom_port ) self.assertEqual(sut[3], '-p') self.assertEqual(sut[4], custom_port) def test_proxy_with_default_port(self): """Used proxy and default port""" proxy_user = 'non_existing_proxy_user' proxy_host = 'non_existing_proxy_host' sut = sshtools.sshCopyIdCommand( generic.PRIV_KEY_FILE, 'user', 'non_existing_host', proxy_user=proxy_user, proxy_host=proxy_host ) self.assertIn( 'ProxyJump=non_existing_proxy_user@non_existing_proxy_host:22', sut) def test_proxy_with_custom_port(self): """Used proxy and custom port""" proxy_user = 'non_existing_proxy_user' proxy_host = 'non_existing_proxy_host' proxy_port = str(random.randint(23, 128)) sut = sshtools.sshCopyIdCommand( generic.PRIV_KEY_FILE, 'user', 'non_existing_host', proxy_user=proxy_user, proxy_host=proxy_host, proxy_port=proxy_port ) self.assertIn( 'ProxyJump=non_existing_proxy_user@non_existing_proxy_host' f':{proxy_port}', sut) backintime-1.5.4/common/test/test_takeSnapshot.py000066400000000000000000000253401477034762000221710ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys import unittest from unittest.mock import patch from datetime import datetime, timedelta from tempfile import TemporaryDirectory from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import snapshots import mount class Take(generic.SnapshotsTestCase): def setUp(self): super().setUp() self.include = TemporaryDirectory() generic.create_test_files(self.include.name) def tearDown(self): super().tearDown() self.include.cleanup() def remount(self): # dummy method only used in TestTakeSnapshotSSH pass def getInode(self, sid): return os.stat(sid.pathBackup(os.path.join(self.include.name, 'test'))).st_ino @patch('time.sleep') # speed up unittest def test_four_snapshots(self, sleep): now = datetime.today() - timedelta(minutes = 6) sid1 = snapshots.SID(now, self.cfg) # Note: 'self.sn' is of type 'Snapshots' # First boolean: Snapshot succeeded # Second boolean: Error occurred self.assertListEqual( [True, False], # Snapshot without error self.sn.takeSnapshot( sid=sid1, now=now, include_folders=[ (self.include.name, 0), # '0' means it is a file ] ) ) self.assertTrue(sid1.exists()) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'test'))) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'file with spaces'))) self.assertExists(self.cfg.anacronSpoolFile()) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertExists(sid1.path(f)) for f in ('failed', 'save_to_continue'): self.assertNotExists(sid1.path(f)) # second takeSnapshot which should not create a new snapshot as nothing # has changed os.remove(self.cfg.anacronSpoolFile()) now = datetime.today() - timedelta(minutes = 4) sid2 = snapshots.SID(now, self.cfg) self.assertListEqual([False, False], self.sn.takeSnapshot(sid2, now, [(self.include.name, 0),])) self.assertFalse(sid2.exists()) self.assertExists(self.cfg.anacronSpoolFile()) # third takeSnapshot self.remount() with open(os.path.join(self.include.name, 'lalala'), 'wt') as f: f.write('asdf') now = datetime.today() - timedelta(minutes = 2) sid3 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid3, now, [(self.include.name, 0),])) self.assertTrue(sid3.exists()) self.assertTrue(sid3.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'lalala'))) inode1 = self.getInode(sid1) inode3 = self.getInode(sid3) self.assertEqual(inode1, inode3) # fourth takeSnapshot with force create new snapshot even if nothing # has changed self.cfg.setTakeSnapshotRegardlessOfChanges(True) now = datetime.today() sid4 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid4, now, [(self.include.name, 0),])) self.assertTrue(sid4.exists()) self.assertTrue(sid4.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid4.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'test'))) @patch('time.sleep') # speed up unittest def test_spaces_in_include(self, sleep): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) include = os.path.join(self.include.name, 'test path with spaces') generic.create_test_files(include) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(include, 0),])) self.assertTrue(sid1.exists()) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(include, 'foo', 'bar', 'baz'))) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(include, 'test'))) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertExists(sid1.path(f)) for f in ('failed', 'save_to_continue'): self.assertNotExists(sid1.path(f)) @patch('time.sleep') # speed up unittest def test_exclude(self, sleep): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.cfg.setExclude(['bar/baz']) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar'))) self.assertFalse(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'test'))) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertExists(sid1.path(f)) for f in ('failed', 'save_to_continue'): self.assertNotExists(sid1.path(f)) @patch('time.sleep') # speed up unittest def test_spaces_in_exclude(self, sleep): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) exclude = os.path.join(self.include.name, 'test path with spaces') generic.create_test_files(exclude) self.cfg.setExclude([exclude]) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'test'))) self.assertFalse(sid1.isExistingPathInsideSnapshotFolder(exclude)) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2'): self.assertExists(sid1.path(f)) for f in ('failed', 'save_to_continue'): self.assertNotExists(sid1.path(f)) @patch('time.sleep') # speed up unittest def test_error(self, sleep): with generic.mockPermissions(os.path.join(self.include.name, 'test')): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([True, True], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertTrue(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'foo', 'bar', 'baz'))) self.assertFalse(sid1.isExistingPathInsideSnapshotFolder(os.path.join(self.include.name, 'test'))) for f in ('config', 'fileinfo.bz2', 'info', 'takesnapshot.log.bz2', 'failed'): self.assertExists(sid1.path(f)) self.assertNotExists(self.cfg.anacronSpoolFile()) @patch('time.sleep') # speed up unittest def test_error_without_continue(self, sleep): with generic.mockPermissions(os.path.join(self.include.name, 'test')): self.cfg.setContinueOnErrors(False) now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([False, True], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertFalse(sid1.exists()) @patch('time.sleep') # speed up unittest def test_new_exists(self, sleep): new_snapshot = snapshots.NewSnapshot(self.cfg) new_snapshot.makeDirs() with open(new_snapshot.path('leftover'), 'wt') as f: f.write('foo') now = datetime.today() - timedelta(minutes = 6) sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertNotExists(sid1.path('leftover')) @patch('time.sleep') # speed up unittest def test_new_exists_continue(self, sleep): new_snapshot = snapshots.NewSnapshot(self.cfg) new_snapshot.makeDirs() with open(new_snapshot.path('leftover'), 'wt') as f: f.write('foo') new_snapshot.saveToContinue = True now = datetime.today() - timedelta(minutes = 6) sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([True, False], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) self.assertTrue(sid1.exists()) self.assertExists(sid1.path('leftover')) @patch('time.sleep') # speed up unittest def test_fail_create_new_snapshot(self, sleep): with generic.mockPermissions(self.snapshotPath, 0o500): now = datetime.today() sid1 = snapshots.SID(now, self.cfg) self.assertListEqual([False, True], self.sn.takeSnapshot(sid1, now, [(self.include.name, 0),])) @unittest.skipIf( not generic.LOCAL_SSH, 'Skip as this test requires a local ssh server, ' 'public and private keys installed') class TakeSSH(generic.SSHSnapshotTestCase, Take): def setUp(self): super().setUp() self.include = TemporaryDirectory() generic.create_test_files(self.include.name) #mount self.cfg.setCurrentHashId(mount.Mount(cfg = self.cfg).mount()) def tearDown(self): #unmount mount.Mount(cfg = self.cfg).umount(self.cfg.current_hash_id) super().tearDown() self.include.cleanup() def remount(self): mount.Mount(cfg = self.cfg).umount(self.cfg.current_hash_id) mount.Mount(cfg = self.cfg).mount() def getInode(self, sid): return os.stat(os.path.join(self.snapshotPath, sid.sid, 'backup', self.include.name[1:], 'test')).st_ino backintime-1.5.4/common/test/test_tools.py000066400000000000000000000754221477034762000206730ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raack # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Tests about the tools module.""" import os import sys import subprocess import random import pathlib import gzip import stat import signal import unittest from datetime import datetime from time import sleep from unittest.mock import patch from copy import deepcopy from tempfile import NamedTemporaryFile, TemporaryDirectory import pyfakefs.fake_filesystem_unittest as pyfakefs_ut from test import generic sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import tools import configfile from bitbase import TimeUnit # chroot jails used for building may have no UUID devices (because of tmpfs) # we need to skip tests that require UUIDs DISK_BY_UUID_AVAILABLE = os.path.exists(tools.DISK_BY_UUID) UDEVADM_HAS_UUID = subprocess.Popen( ['udevadm', 'info', '-e'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).communicate()[0].find(b'ID_FS_UUID=') > 0 RSYNC_INSTALLED = tools.checkCommand('rsync') RSYNC_307_VERSION = """rsync version 3.0.7 protocol version 30 Copyright (C) 1996-2009 by Andrew Tridgell, Wayne Davison, and others. Web site: http://rsync.samba.org/ Capabilities: 64-bit files, 64-bit inums, 32-bit timestamps, 64-bit long ints, socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append, ACLs, xattrs, iconv, symtimes rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public License for details. """ RSYNC_310_VERSION = """rsync version 3.1.0 protocol version 31 Copyright (C) 1996-2013 by Andrew Tridgell, Wayne Davison, and others. Web site: http://rsync.samba.org/ Capabilities: 64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints, socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace, append, ACLs, xattrs, iconv, symtimes, prealloc rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. See the GNU General Public License for details. """ class TestTools(generic.TestCase): """ All functions test here come from tools.py """ def setUp(self): super().setUp() self.subproc = None def tearDown(self): super().tearDown() self._kill_process() def _create_process(self, *args): dummyPath = os.path.join(os.path.dirname(__file__), generic.DUMMY) cmd = [dummyPath] cmd.extend(args) self.subproc = subprocess.Popen(cmd) sleep(0.1) return self.subproc.pid def _kill_process(self): if self.subproc: self.subproc.kill() self.subproc.wait() self.subproc = None def test_sharePath(self): share = tools.sharePath() self.assertTrue(share.endswith('share'), 'share = {}'.format(share)) def test_backintimePath(self): path = tools.backintimePath('common') self.assertIn(path, __file__) def test_registerBackintimePath(self): path = tools.backintimePath('foo') tools.registerBackintimePath('foo') self.assertIn(path, sys.path) sys.path.remove(path) def test_runningFromSource(self): self.assertTrue(tools.runningFromSource()) def test_addSourceToPathEnviron(self): source = tools.backintimePath('common') path = [x for x in os.getenv('PATH').split(':') if x != source] os.environ['PATH'] = ':'.join(path) tools.addSourceToPathEnviron() self.assertIn(source, os.environ['PATH']) def test_readFile(self): """ Test the function readFile """ test_tools_file = os.path.abspath(__file__) test_directory = os.path.dirname(test_tools_file) non_existing_file = os.path.join(test_directory, "nonExistingFile") self.assertIsInstance(tools.readFile(test_tools_file), str) self.assertIsNone(tools.readFile(non_existing_file)) with NamedTemporaryFile('wt') as tmp: tmp.write('foo\nbar') tmp.flush() self.assertIsInstance(tools.readFile(tmp.name), str) self.assertEqual(tools.readFile(tmp.name), 'foo\nbar') tmp_gz = NamedTemporaryFile().name with gzip.open(tmp_gz + '.gz', 'wt') as f: f.write('foo\nbar') f.flush() self.assertIsInstance(tools.readFile(tmp_gz), str) self.assertEqual(tools.readFile(tmp_gz), 'foo\nbar') os.remove(tmp_gz + '.gz') def test_readFileLines(self): """ Test the function readFileLines """ test_tools_file = os.path.abspath(__file__) test_directory = os.path.dirname(test_tools_file) non_existing_file = os.path.join(test_directory, "nonExistingFile") output = tools.readFileLines(test_tools_file) self.assertIsInstance(output, list) self.assertGreaterEqual(len(output), 1) self.assertIsInstance(output[0], str) self.assertIsNone(tools.readFileLines(non_existing_file)) with NamedTemporaryFile('wt') as tmp: tmp.write('foo\nbar') tmp.flush() self.assertIsInstance(tools.readFileLines(tmp.name), list) self.assertListEqual(tools.readFileLines(tmp.name), ['foo', 'bar']) tmp_gz = NamedTemporaryFile().name with gzip.open(tmp_gz + '.gz', 'wt') as f: f.write('foo\nbar') f.flush() self.assertIsInstance(tools.readFileLines(tmp_gz), list) self.assertEqual(tools.readFileLines(tmp_gz), ['foo', 'bar']) os.remove(tmp_gz + '.gz') def test_checkCommand(self): """ Test the function checkCommand """ self.assertFalse(tools.checkCommand('')) self.assertFalse(tools.checkCommand("notExistedCommand")) self.assertTrue(tools.checkCommand("ls")) self.assertTrue(tools.checkCommand('backintime')) def test_which(self): """ Test the function which """ self.assertRegex(tools.which("ls"), r'/.*/ls') self.assertEqual(tools.which('backintime'), os.path.join(os.getcwd(), 'backintime')) self.assertIsNone(tools.which("notExistedCommand")) def test_makeDirs(self): self.assertFalse(tools.makeDirs('/')) self.assertTrue(tools.makeDirs(os.getcwd())) with TemporaryDirectory() as d: path = os.path.join(d, 'foo', 'bar') self.assertTrue(tools.makeDirs(path)) def test_makeDirs_not_writable(self): with TemporaryDirectory() as d: os.chmod(d, stat.S_IRUSR) path = os.path.join( d, 'foobar{}'.format(random.randrange(100, 999))) self.assertFalse(tools.makeDirs(path)) def test_mkdir(self): self.assertFalse(tools.mkdir('/')) with TemporaryDirectory() as d: path = os.path.join(d, 'foo') self.assertTrue(tools.mkdir(path)) for mode in (0o700, 0o644, 0o777): msg = 'new path should have octal permissions {0:#o}' \ .format(mode) path = os.path.join(d, '{0:#o}'.format(mode)) self.assertTrue(tools.mkdir(path, mode), msg) self.assertEqual( '{0:o}'.format(os.stat(path).st_mode & 0o777), '{0:o}'.format(mode), msg) def test_pids(self): pids = tools.pids() self.assertGreater(len(pids), 0) self.assertIn(os.getpid(), pids) def test_processStat(self): pid = self._create_process() stat = tools.processStat(pid) self.assertRegex( stat, r'{} \({}\) \w .*'.format(pid, generic.DUMMY[:15])) @patch('builtins.open') def test_processStat_exception(self, mock_open): mock_open.side_effect = OSError() pid = self._create_process() self.assertEqual(tools.processStat(pid), '') def test_processPaused(self): pid = self._create_process() self.assertFalse(tools.processPaused(pid)) self.subproc.send_signal(signal.SIGSTOP) sleep(0.01) self.assertTrue(tools.processPaused(pid)) self.subproc.send_signal(signal.SIGCONT) sleep(0.01) self.assertFalse(tools.processPaused(pid)) def test_processName(self): pid = self._create_process() self.assertEqual(tools.processName(pid), generic.DUMMY[:15]) def test_processCmdline(self): pid = self._create_process() self.assertRegex(tools.processCmdline(pid), r'.*/sh.*/common/test/dummy_test_process\.sh') self._kill_process() pid = self._create_process('foo', 'bar') self.assertRegex(tools.processCmdline(pid), r'.*/sh.*/common/test/dummy_test_process\.sh.foo.bar') @patch('builtins.open') def test_processCmdline_exception(self, mock_open): mock_open.side_effect = OSError() pid = self._create_process() self.assertEqual(tools.processCmdline(pid), '') def test_pidsWithName(self): self.assertEqual(len(tools.pidsWithName('nonExistingProcess')), 0) pid = self._create_process() pids = tools.pidsWithName(generic.DUMMY) self.assertGreaterEqual(len(pids), 1) self.assertIn(pid, pids) def test_processExists(self): self.assertFalse(tools.processExists('nonExistingProcess')) self._create_process() self.assertTrue(tools.processExists(generic.DUMMY)) def test_processAlive(self): """ Test the function processAlive """ # TODO: add test (in chroot) running proc as root and kill as non-root self.assertTrue(tools.processAlive(os.getpid())) pid = self._create_process() self.assertTrue(tools.processAlive(pid)) self._kill_process() self.assertFalse(tools.processAlive(pid)) self.assertFalse(tools.processAlive(999999)) with self.assertRaises(ValueError): tools.processAlive(0) self.assertFalse(tools.processAlive(-1)) def test_checkXServer(self): try: tools.checkXServer() except Exception as e: self.fail( 'tools.ckeck_x_server() raised exception {}'.format(str(e))) def test_preparePath(self): path_with_slash_at_begin = "/test/path" path_without_slash_at_begin = "test/path" path_with_slash_at_end = "/test/path/" path_without_slash_at_end = "/test/path" self.assertEqual( tools.preparePath(path_with_slash_at_begin), path_with_slash_at_begin) self.assertEqual( tools.preparePath(path_without_slash_at_begin), path_with_slash_at_begin) self.assertEqual( tools.preparePath(path_without_slash_at_end), path_without_slash_at_end) self.assertEqual( tools.preparePath(path_with_slash_at_end), path_without_slash_at_end) def test_powerStatusAvailable(self): if tools.processExists('upowerd') and not generic.ON_TRAVIS: self.assertTrue(tools.powerStatusAvailable()) else: self.assertFalse(tools.powerStatusAvailable()) self.assertIsInstance(tools.onBattery(), bool) def test_rsyncCaps(self): if RSYNC_INSTALLED: caps = tools.rsyncCaps() self.assertIsInstance(caps, list) self.assertGreaterEqual(len(caps), 1) self.assertListEqual(tools.rsyncCaps(data=RSYNC_307_VERSION), ['64-bit files', '64-bit inums', '32-bit timestamps', '64-bit long ints', 'socketpairs', 'hardlinks', 'symlinks', 'IPv6', 'batchfiles', 'inplace', 'append', 'ACLs', 'xattrs', 'iconv', 'symtimes']) self.assertListEqual(tools.rsyncCaps(data=RSYNC_310_VERSION), ['progress2', '64-bit files', '64-bit inums', '64-bit timestamps', '64-bit long ints', 'socketpairs', 'hardlinks', 'symlinks', 'IPv6', 'batchfiles', 'inplace', 'append', 'ACLs', 'xattrs', 'iconv', 'symtimes', 'prealloc']) def test_md5sum(self): with NamedTemporaryFile() as f: f.write(b'foo') f.flush() self.assertEqual(tools.md5sum(f.name), 'acbd18db4cc2f85cedef654fccc4a4d8') def test_checkCronPattern(self): self.assertTrue(tools.checkCronPattern('0')) self.assertTrue(tools.checkCronPattern('0,10,13,15,17,20,23')) self.assertTrue(tools.checkCronPattern('*/6')) self.assertFalse(tools.checkCronPattern('a')) self.assertFalse(tools.checkCronPattern(' 1')) self.assertFalse(tools.checkCronPattern('0,10,13,1a,17,20,23')) self.assertFalse(tools.checkCronPattern('0,10,13, 15,17,20,23')) self.assertFalse(tools.checkCronPattern('*/6,8')) self.assertFalse(tools.checkCronPattern('*/6 a')) def test_mountpoint(self): self.assertEqual(tools.mountpoint('/nonExistingFolder/foo/bar'), '/') proc = os.path.join('/proc', str(os.getpid()), 'fd') self.assertEqual(tools.mountpoint(proc), '/proc') def test_decodeOctalEscape(self): self.assertEqual(tools.decodeOctalEscape('/mnt/normalPath'), '/mnt/normalPath') self.assertEqual( tools.decodeOctalEscape('/mnt/path\\040with\\040space'), '/mnt/path with space') def test_mountArgs(self): rootArgs = tools.mountArgs('/') self.assertIsInstance(rootArgs, list) self.assertGreaterEqual(len(rootArgs), 3) self.assertEqual(rootArgs[1], '/') procArgs = tools.mountArgs('/proc') self.assertGreaterEqual(len(procArgs), 3) self.assertEqual(procArgs[0], 'proc') self.assertEqual(procArgs[1], '/proc') self.assertEqual(procArgs[2], 'proc') def test_isRoot(self): self.assertIsInstance(tools.isRoot(), bool) def test_usingSudo(self): self.assertIsInstance(tools.usingSudo(), bool) def test_patternHasNotEncryptableWildcard(self): self.assertFalse(tools.patternHasNotEncryptableWildcard('foo')) self.assertFalse(tools.patternHasNotEncryptableWildcard('/foo')) self.assertFalse(tools.patternHasNotEncryptableWildcard('foo/*/bar')) self.assertFalse(tools.patternHasNotEncryptableWildcard('foo/**/bar')) self.assertFalse(tools.patternHasNotEncryptableWildcard('*/foo')) self.assertFalse(tools.patternHasNotEncryptableWildcard('**/foo')) self.assertFalse(tools.patternHasNotEncryptableWildcard('foo/*')) self.assertFalse(tools.patternHasNotEncryptableWildcard('foo/**')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo?')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo[1-2]')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo*')) self.assertTrue(tools.patternHasNotEncryptableWildcard('*foo')) self.assertTrue(tools.patternHasNotEncryptableWildcard('**foo')) self.assertTrue(tools.patternHasNotEncryptableWildcard('*.foo')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo*bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo**bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo*/bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo**/bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo/*bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo/**bar')) self.assertTrue(tools.patternHasNotEncryptableWildcard('foo/*/bar*')) self.assertTrue(tools.patternHasNotEncryptableWildcard('*foo/*/bar')) def test_readTimeStamp(self): with NamedTemporaryFile('wt') as f: f.write('20160127 0124') f.flush() self.assertEqual(tools.readTimeStamp(f.name), datetime(2016, 1, 27, 1, 24)) with NamedTemporaryFile('wt') as f: f.write('20160127') f.flush() self.assertEqual(tools.readTimeStamp(f.name), datetime(2016, 1, 27, 0, 0)) def test_writeTimeStamp(self): with NamedTemporaryFile('rt') as f: tools.writeTimeStamp(f.name) s = f.read().strip('\n') self.assertTrue(s.replace(' ', '').isdigit()) self.assertEqual(len(s), 13) def test_splitCommands(self): ret = list(tools.splitCommands(['echo foo;'], head='echo start;', tail='echo end', maxLength=40)) self.assertEqual(len(ret), 1) self.assertEqual(ret[0], 'echo start;echo foo;echo end') ret = list(tools.splitCommands(['echo foo;']*3, head='echo start;', tail='echo end', maxLength=40)) self.assertEqual(len(ret), 2) self.assertEqual(ret[0], 'echo start;echo foo;echo foo;echo end') self.assertEqual(ret[1], 'echo start;echo foo;echo end') ret = list(tools.splitCommands(['echo foo;']*3, head='echo start;', tail='echo end', maxLength=0)) self.assertEqual(len(ret), 1) self.assertEqual(ret[0], 'echo start;echo foo;echo foo;echo foo;echo end') ret = list(tools.splitCommands(['echo foo;'] * 3, head='echo start;', tail='echo end', maxLength=-10)) self.assertEqual(len(ret), 1) self.assertEqual( ret[0], 'echo start;echo foo;echo foo;echo foo;echo end') class EscapeIPv6(generic.TestCase): def test_escaped(self): values_and_expected = ( ('fd00:0::5', '[fd00:0::5]'), ( '2001:db8:0:8d3:0:8a2e:70:7344', '[2001:db8:0:8d3:0:8a2e:70:7344]' ), ('::', '[::]'), ('::1', '[::1]'), ('::ffff:192.0.2.128', '[::ffff:192.0.2.128]'), ('fe80::1', '[fe80::1]'), ) for val, exp in values_and_expected: with self.subTest(val=val, exp=exp): self.assertEqual(tools.escapeIPv6Address(val), exp) def test_passed(self): test_values = ( '192.168.1.1', '172.17.1.133', '255.255.255.255', '169.254.0.1', ) for val in test_values: with self.subTest(val=val): # IPv4 addresses are not escaped self.assertEqual(tools.escapeIPv6Address(val), val) def test_invalid(self): """Invalid IP addresses and hostnames""" test_values = ( 'foo.bar', 'fd00', '2001:0db8:::0000:0000:8a2e:0370:7334', ':2001:0db8:85a3:0000:0000:8a2e:0370:7334', '2001:0gb8:85a3:0000:0000:8a2e:0370:7334', '2001:0db8:85a3:0000:0000:8a2e:0370:7334:abcd', 'localhost', ) for val in test_values: with self.subTest(val=val): self.assertEqual(tools.escapeIPv6Address(val), val) class Environ(generic.TestCase): """??? """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.env = deepcopy(os.environ) def setUp(self): super().setUp() self.temp_file = '/tmp/temp.txt' os.environ = deepcopy(self.env) def tearDown(self): super().tearDown() if os.path.exists(self.temp_file): os.remove(self.temp_file) os.environ = deepcopy(self.env) def test_envLoad_without_previous_values(self): test_env = configfile.ConfigFile() test_env.setStrValue('FOO', 'bar') test_env.setStrValue('ASDF', 'qwertz') test_env.save(self.temp_file) # make sure environ is clean self.assertNotIn('FOO', os.environ) self.assertNotIn('ASDF', os.environ) tools.envLoad(self.temp_file) self.assertIn('FOO', os.environ) self.assertIn('ASDF', os.environ) self.assertEqual(os.environ['FOO'], 'bar') self.assertEqual(os.environ['ASDF'], 'qwertz') def test_envLoad_do_not_overwrite_previous_values(self): test_env = configfile.ConfigFile() test_env.setStrValue('FOO', 'bar') test_env.setStrValue('ASDF', 'qwertz') test_env.save(self.temp_file) # add some environ vars that should not get overwritten os.environ['FOO'] = 'defaultFOO' os.environ['ASDF'] = 'defaultASDF' tools.envLoad(self.temp_file) self.assertIn('FOO', os.environ) self.assertIn('ASDF', os.environ) self.assertEqual(os.environ['FOO'], 'defaultFOO') self.assertEqual(os.environ['ASDF'], 'defaultASDF') def test_envSave(self): keys = ( 'GNOME_KEYRING_CONTROL', 'DBUS_SESSION_BUS_ADDRESS', 'DBUS_SESSION_BUS_PID', 'DBUS_SESSION_BUS_WINDOWID', 'DISPLAY', 'XAUTHORITY', 'GNOME_DESKTOP_SESSION_ID', 'KDE_FULL_SESSION') for i, k in enumerate(keys): os.environ[k] = str(i) tools.envSave(self.temp_file) self.assertIsFile(self.temp_file) test_env = configfile.ConfigFile() test_env.load(self.temp_file) for i, k in enumerate(keys): with self.subTest(i=i, k=k): # workaround for py.test3 2.5.1 doesn't support subTest msg = 'i = %s, k = %s' % (i, k) self.assertEqual(test_env.strValue(k), str(i), msg) class ExecuteSubprocess(generic.TestCase): # new method with subprocess def test_returncode(self): self.assertEqual(tools.Execute(['true']).run(), 0) self.assertEqual(tools.Execute(['false']).run(), 1) def test_callback(self): c = lambda x, y: self.callback(self.assertEqual, x, 'foo') tools.Execute(['echo', 'foo'], callback=c).run() self.assertTrue(self.run) self.run = False # give extra user_data for callback c = lambda x, y: self.callback(self.assertEqual, x, y) tools.Execute(['echo', 'foo'], callback=c, user_data='foo').run() self.assertTrue(self.run) self.run = False # no output c = lambda x, y: self.callback(self.fail, 'callback was called unexpectedly') tools.Execute(['true'], callback=c).run() self.assertFalse(self.run) self.run = False def test_pausable(self): proc = tools.Execute(['true']) self.assertTrue(proc.pausable) class Tools_FakeFS(pyfakefs_ut.TestCase): """Tests using a fake filesystem.""" def setUp(self): self.setUpPyfakefs(allow_root_user=False) def test_git_repo_info_none(self): """Actually not a git repo""" self.assertEqual(tools.get_git_repository_info(), None) def test_git_repo_info(self): """Simulate a git repo""" path = pathlib.Path('.git') path.mkdir() # Branch folders and hash containing file foobar = path / 'refs' / 'heads' / 'fix' / 'foobar' foobar.parent.mkdir(parents=True) with foobar.open('w') as handle: handle.write('01234') # HEAD file head = path / 'HEAD' with head.open('w') as handle: handle.write('ref: refs/heads/fix/foobar') # Test self.assertEqual( tools.get_git_repository_info(), { 'hash': '01234', 'branch': 'fix/foobar' } ) class ValidateSnapshotsPath(generic.TestCaseCfg): def test_writes(self): with TemporaryDirectory() as dirpath: ret = tools.validate_and_prepare_snapshots_path( path=dirpath, host_user_profile=self.cfg.hostUserProfile(), mode=self.cfg.snapshotsMode(), copy_links=self.cfg.copyLinks(), error_handler=self.cfg.notifyError) self.assertTrue(ret) def test_fails_on_ro(self): with TemporaryDirectory() as dirpath: # set directory to read only ro_dir_stats = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH with generic.mockPermissions(dirpath, ro_dir_stats): ret = tools.validate_and_prepare_snapshots_path( path=dirpath, host_user_profile=self.cfg.hostUserProfile(), mode=self.cfg.snapshotsMode(), copy_links=self.cfg.copyLinks(), error_handler=self.cfg.notifyError) self.assertFalse(ret) @patch('os.chmod') def test_permission_fail(self, mock_chmod): mock_chmod.side_effect = PermissionError() with TemporaryDirectory() as dirpath: ret = tools.validate_and_prepare_snapshots_path( path=dirpath, host_user_profile=self.cfg.hostUserProfile(), mode=self.cfg.snapshotsMode(), copy_links=self.cfg.copyLinks(), error_handler=self.cfg.notifyError) self.assertTrue(ret) @patch(f'{tools.__name__}.datetime', wraps=datetime) class OlderThan(unittest.TestCase): def test_hours_not_older(self, mock_dt): """Exact two hours Keep in mind: 20:23:00 is NOT two hours older than 18:23:00. But 20:23:01 IS OLDER than two hours. """ # year, month, day, hour=0, minute=0, second=0, microsecond=0 birth = datetime(1982, 8, 6, 18, 23, 0, 0) # exact two hours mock_dt.now.return_value = datetime(1982, 8, 6, 20, 23, 0, 0) self.assertFalse(tools.older_than(birth, 2, TimeUnit.HOUR)) def test_hours_older(self, mock_dt): """Two hours plus one ms""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) # two hours + 1 ms mock_dt.now.return_value = datetime(1982, 8, 6, 20, 23, 0, 1) self.assertTrue(tools.older_than(birth, 2, TimeUnit.HOUR)) def test_days_not_older(self, mock_dt): """Two days""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 8, 8, 18, 23, 0, 0) self.assertFalse(tools.older_than(birth, 2, TimeUnit.DAY)) def test_days_older(self, mock_dt): """Two days plus one ms""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 8, 8, 18, 23, 0, 1) self.assertTrue(tools.older_than(birth, 2, TimeUnit.DAY)) def test_week_not_older(self, mock_dt): """Two weeks""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 8, 20, 18, 23, 0, 0) self.assertFalse(tools.older_than(birth, 2, TimeUnit.WEEK)) def test_week_older(self, mock_dt): """Two weeks plus one ms""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 8, 20, 18, 23, 0, 1) self.assertTrue(tools.older_than(birth, 2, TimeUnit.WEEK)) def test_month_not_older(self, mock_dt): """Two months.""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 10, 6, 18, 23, 0, 0) self.assertFalse(tools.older_than(birth, 2, TimeUnit.MONTH)) def test_month_older(self, mock_dt): """Two months plus one ms.""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 10, 6, 18, 23, 0, 1) self.assertTrue(tools.older_than(birth, 2, TimeUnit.MONTH)) def test_month_31th(self, mock_dt): """From May with 31th as last day to September with 30th as last day.""" birth = datetime(1982, 5, 31, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 9, 30, 18, 23, 0, 0) self.assertFalse(tools.older_than(birth, 4, TimeUnit.MONTH)) def test_month_31th_plus_ms(self, mock_dt): """Plus one ms""" birth = datetime(1982, 5, 31, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1982, 9, 30, 18, 23, 0, 1) self.assertTrue(tools.older_than(birth, 4, TimeUnit.MONTH)) def test_month_next_year(self, mock_dt): """Into next year with 7 months.""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1983, 3, 6, 18, 23, 0, 0) self.assertFalse(tools.older_than(birth, 7, TimeUnit.MONTH)) def test_month_next_year_plus_ms(self, mock_dt): """Into next year with 7 months plus 1 ms.""" birth = datetime(1982, 8, 6, 18, 23, 0, 0) mock_dt.now.return_value = datetime(1983, 3, 6, 18, 23, 0, 1) self.assertTrue(tools.older_than(birth, 7, TimeUnit.MONTH)) class NestedDictUpdate(unittest.TestCase): """About nested_dict_update()""" def test_simple(self): """Simple""" org = { 'foo': 7, 'bar': { 'a': 'drei', 'b': 'uhr' } } update = { 'planet': 'erde', 'bar': { 'b': 'wecker' }, 'ecke': 9 } expect = { 'planet': 'erde', 'foo': 7, 'bar': { 'a': 'drei', 'b': 'wecker' }, 'ecke': 9 } self.assertDictEqual( tools.nested_dict_update(org, update), expect) backintime-1.5.4/common/test/test_uniquenessset.py000066400000000000000000000164351477034762000224450ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2010 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests about the uniquenessset module.""" # pylint: disable=wrong-import-position,C0411,import-outside-toplevel,R0801 import os import sys import unittest import packaging.version import pyfakefs.fake_filesystem_unittest as pyfakefs_ut from pathlib import Path from tempfile import TemporaryDirectory sys.path.append(os.path.join(os.path.dirname(__file__), '..')) import logger # noqa: E402,RUF100 from uniquenessset import UniquenessSet # noqa: E402,RUF100 logger.DEBUG = True class General(pyfakefs_ut.TestCase): """Behavior of class UniquenessSet. """ def setUp(self): """Setup a fake filesystem.""" self.setUpPyfakefs(allow_root_user=False) def _create_unique_file_pairs(self, pairs): result = [] for one, two, content in pairs: for fp in [one, two]: # create dir fp.parent.mkdir(parents=True, exist_ok=True) # create file with fp.open('wt', encoding='utf-8') as handle: handle.write(content) # Sync their timestamps os.utime(two, times=(one.stat().st_atime, one.stat().st_mtime)) result.extend((one, two)) return result @unittest.skipIf(sys.version_info[:2] < (3, 12), 'Relevant only with Python 3.12 or newer (#1911)') def test_001_depency_workaround(self): """Workaround until #1575 is fixed. Python 3.13 needs PyFakeFS at min version 5.7 Python 3.12 needs PyFakeFS at min version 5.6 See: """ import pyfakefs pyfakefs_version = packaging.version.parse(pyfakefs.__version__) min_required_version = packaging.version.parse('5.7.0') self.assertTrue( pyfakefs_version >= min_required_version, 'With Python 3.12 or later the PyFakeFS version should be ' f'minimum {min_required_version} ' f'or later but is {pyfakefs_version}.') def test_ctor_defaults(self): """Default values in constructor.""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) files = self._create_unique_file_pairs([( temp_path / 'foo', temp_path / 'bar', 'xyz')]) sut = UniquenessSet() # unique-check by default self.assertTrue(sut.check(files[0])) # Comopared to previous file, not unique by size & mtime self.assertFalse(sut.check(files[1])) def test_fail_equal_without_equal_to(self): """Uncovered (but not important) edge case.""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) fp = temp_path / 'foo' fp.write_text('bar') sut = UniquenessSet(deep_check=False, follow_symlink=False, equal_to='') with self.assertRaises(AttributeError): # Explicit equal-check not possible because 'equal_to' is # empty. sut.checkEqual(fp) def test_unique_myself(self): """Test file uniqueness to itself""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) fp = temp_path / 'bar' fp.write_text('foo') # unique-check is used because 'equal_to' is empty sut = UniquenessSet(deep_check=False, follow_symlink=False, equal_to='') # Is unique, because no check was done before. self.assertTrue(sut.check(fp)) # Not unique anymore, not even to itself, because its hash was # stored from the previous check. self.assertFalse(sut.check(fp)) def test_size_mtime(self): """Uniqueness by size and mtime""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) files = self._create_unique_file_pairs([ ( temp_path / '1' / 'foo', temp_path / '2' / 'foo', 'bar' ), ( temp_path / '3' / 'foo', temp_path / '4' / 'foo', '42' ), ]) sut = UniquenessSet(deep_check=False, follow_symlink=False, equal_to='') self.assertTrue(sut.check(files[0])) self.assertTrue(sut.check(files[2])) self.assertFalse(sut.check(files[1])) self.assertFalse(sut.check(files[3])) def test_unique_size_but_different_mtime(self): """Unique size but mtime is different.""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) files = self._create_unique_file_pairs([ ( temp_path / '1' / 'foo', temp_path / '2' / 'foo', 'bar' ), ( temp_path / '3' / 'foo', temp_path / '4' / 'foo', 'different_size' ), ]) # different mtime os.utime(files[0], times=(0, 0)) os.utime(files[2], times=(0, 0)) # same size different mtime sut = UniquenessSet(deep_check=False, follow_symlink=False, equal_to='') # Each file is unique (different from each other) self.assertTrue(sut.check(files[0])) self.assertTrue(sut.check(files[1])) self.assertTrue(sut.check(files[2])) self.assertTrue(sut.check(files[3])) def test_deep_check(self): """Uniqueness by content only""" with TemporaryDirectory(prefix='bit.') as temp_name: temp_path = Path(temp_name) # Size is the same (3 chars content per file) fpa = temp_path / 'foo' fpa.write_text('one') fpb = temp_path / 'bar' fpb.write_text('bar') # mtime is the same os.utime(fpb, times=(fpa.stat().st_atime, fpa.stat().st_mtime)) # Not deep: check by size and mtime sut = UniquenessSet(deep_check=False, follow_symlink=False, equal_to='') self.assertTrue(sut.check(fpa)) self.assertFalse(sut.check(fpb)) # Now with deep check sut = UniquenessSet(deep_check=True, follow_symlink=False, equal_to='') self.assertTrue(sut.check(fpa)) self.assertTrue(sut.check(fpb)) backintime-1.5.4/common/tools.py000066400000000000000000002473751477034762000166650ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raack # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Collection of helper functions not fitting to other modules. """ import os import sys import pathlib import subprocess import shlex import signal import re import errno import gzip import locale import gettext import hashlib import ipaddress from datetime import datetime, timedelta from collections.abc import MutableMapping from packaging.version import Version from typing import Union from bitbase import TimeUnit import logger # Try to import keyring is_keyring_available = False try: # Jan 4, 2024 aryoda: The env var BIT_USE_KEYRING is neither documented # anywhere nor used at all in the code. # Via "git blame" I have found a commit message saying: # "block subsequent 'import keyring' if it failed once" # So I assume it is an internal temporary env var only. # Note: os.geteuid() is used instead of tools.isRoot() here # because the latter is still not available here in the global # module code. if os.getenv('BIT_USE_KEYRING', 'true') == 'true' and os.geteuid() != 0: import keyring from keyring import backend import keyring.util.platform_ is_keyring_available = True except Exception as e: is_keyring_available = False # block subsequent 'import keyring' if it failed once before os.putenv('BIT_USE_KEYRING', 'false') logger.warning(f"'import keyring' failed with: {repr(e)}") # getting dbus imports to work in Travis CI is a huge pain # use conditional dbus import ON_TRAVIS = os.environ.get('TRAVIS', 'None').lower() == 'true' ON_RTD = os.environ.get('READTHEDOCS', 'None').lower() == 'true' try: import dbus except ImportError: if ON_TRAVIS or ON_RTD: # python-dbus doesn't work on Travis yet. dbus = None else: raise import configfile import bcolors from exceptions import Timeout, InvalidChar, InvalidCmd, LimitExceeded, PermissionDeniedByPolicy import languages # Workaround: # While unittesting and without regular invocation of BIT the GNU gettext # class-based API isn't setup yet. try: _('Warning') except NameError: _ = lambda val: val DISK_BY_UUID = '/dev/disk/by-uuid' # |-----------------| # | Handling paths | # |-----------------| def sharePath(): """Get path where Back In Time is installed. This is similar to ``XDG_DATA_DIRS``. If running from source return default ``/usr/share``. Share path like: :: /usr/share /usr/local/share /opt/usr/share Returns: str: Share path. """ share = os.path.abspath( os.path.join(__file__, os.pardir, os.pardir, os.pardir) ) if os.path.basename(share) == 'share': return share return '/usr/share' def backintimePath(*path): """ Get path inside ``backintime`` install folder. Args: *path (str): Paths that should be joined to ``backintime``. Returns: str: Child path of ``backintime`` child path e.g. ``/usr/share/backintime/common``or ``/usr/share/backintime/qt``. """ return os.path.abspath(os.path.join(__file__, os.pardir, os.pardir, *path)) def docPath(): """Not sure what this path is about. """ path = pathlib.Path(sharePath()) / 'doc' / 'backintime-common' # Dev note (buhtz, aryoda, 2024-02): # This piece of code originally resisted in Config.__init__() and was # introduced by Dan in 2008. The reason for the existence of this "if" # is unclear. # Makefile (in common) does only install into share/doc/backintime-common # but never into the the backintime "binary" path so I guess the if is # a) either a distro-specific exception for a distro package that # (manually?) installs the LICENSE into another path # b) or a left-over from old code where the LICENSE was installed # differently... license_file = pathlib.Path(backintimePath()) / 'LICENSE' if license_file.exists(): path = backintimePath() return str(path) # |---------------------------------------------------| # | Internationalization (i18n) & localization (L10n) | # |---------------------------------------------------| _GETTEXT_DOMAIN = 'backintime' _GETTEXT_LOCALE_DIR = pathlib.Path(sharePath()) / 'locale' def _determine_current_used_language_code(translation, language_code): """Return the language code used by GNU gettext for real. Args: translation(gettext.NullTranslations): The translation installed. language_code(str): Configured language code. The used language code can differ from the one in Back In Times config file and from the current systems locale. It is necessary because of situations where the language is not explicit setup in Back In Time config file and GNU gettext do try to find and use a language file for the current systems locale. But even this can fail and the fallback (source language "en") is used or an alternative locale. """ try: # The field "language" is rooted in header of the po-file. current_used_language_code = translation.info()['language'] except KeyError: # Workaround: # BIT versions 1.3.3 or older don't have the "language" field in the # header of their po-files. # The approach is to extract the language code from the full filepath # of the currently used mo-file. # Get the filepath of the used mo-file mo_file_path = gettext.find( domain=_GETTEXT_DOMAIN, localedir=_GETTEXT_LOCALE_DIR, languages=[language_code, ] if language_code else None, ) # Extract the language code form that path if mo_file_path: mo_file_path = pathlib.Path(mo_file_path) # e.g /usr/share/locale/de/LC_MESSAGES/backintime.mo # ^^ current_used_language_code = mo_file_path.relative_to( _GETTEXT_LOCALE_DIR).parts[0] else: # Workaround: Happens when LC_ALL=C, which in BIT context mean # its source language in English. current_used_language_code = 'en' return current_used_language_code def initiate_translation(language_code): """Initiate Class-based API of GNU gettext. Args: language_code(str): Language code to use (based on ISO-639). It installs the ``_()`` (and ``ngettext()`` for plural forms) in the ``builtins`` namespace and eliminates the need to ``import gettext`` and declare ``_()`` in each module. The systems current local is used if the language code is None. """ if language_code: logger.debug(f'Language code "{language_code}".') else: logger.debug('No language code. Use systems current locale.') translation = gettext.translation( domain=_GETTEXT_DOMAIN, localedir=_GETTEXT_LOCALE_DIR, languages=[language_code, ] if language_code else None, fallback=True ) translation.install(names=['ngettext']) used_code = _determine_current_used_language_code( translation, language_code) set_lc_time_by_language_code(used_code) logger.debug(f'Language code used: "{used_code}"') return used_code def set_lc_time_by_language_code(language_code: str): """Set ``LC_TIME`` based on a specific language code. Args: language_code(str): A language code consisting of two letters. The reason is to display correctly translated weekday and months names. Python's :mod:`datetime` module, as well ``PyQt6.QtCore.QDate``, use :mod:`locale` to determine the correct translation. The module :mod:`gettext` and ``PyQt6.QtCore.QTranslator`` is not involved so their setup does not take effect. Be aware that a language code (e.g. ``de``) is not the same as a locale code (e.g. ``de_DE.UTF-8``). This function attempts to determine the latter based on the language code. A warning is logged if it is not possible. """ # Determine the normalized locale code (e.g. "de_DE.UTF-8") by # language code (e.g. "de"). # "de" -> "de_DE.ISO8859-1" -> "de_DE" code = locale.normalize(language_code).split('.')[0] try: # "de_DE" -> "de_DE.UTF-8" code = code + '.' + locale.getencoding() except AttributeError: # Python 3.10 or older code = code + '.' + locale.getpreferredencoding() try: # logger.debug(f'Try to set locale.LC_TIME to "{code}" based on ' # f'language code "{language_code}".') locale.setlocale(locale.LC_TIME, code) except locale.Error: logger.debug( f'Determined normalized locale code "{code}" (from language code ' f'"{language_code}") not available (or invalid). The code will be ' 'ignored. This might lead to unusual display of dates and ' 'timestamps, but it does not affect the functionality of the ' f'application. Used locale is "{locale.getlocale()}".') def get_available_language_codes(): """Return language codes available in the current installation. The filesystem is searched for ``backintime.mo`` files and the language code is extracted from the full path of that files. Return: List of language codes. """ # full path of one mo-file # e.g. /usr/share/locale/de/LC_MESSAGES/backintime.mo mo = gettext.find(domain=_GETTEXT_DOMAIN, localedir=_GETTEXT_LOCALE_DIR) if mo: mo = pathlib.Path(mo) else: # Workaround. This happens if LC_ALL=C and BIT don't use an explicit # language. Should be re-design. mo = _GETTEXT_LOCALE_DIR / 'xy' / 'LC_MESSAGES' / 'backintime.mo' # e.g. de/LC_MESSAGES/backintime.mo mo = mo.relative_to(_GETTEXT_LOCALE_DIR) # e.g. */LC_MESSAGES/backintime.mo mo = pathlib.Path('*') / pathlib.Path(*mo.parts[1:]) mofiles = _GETTEXT_LOCALE_DIR.rglob(str(mo)) return [p.relative_to(_GETTEXT_LOCALE_DIR).parts[0] for p in mofiles] def get_language_names(language_code): """Return a list with language names in three different flavors. Language codes from `get_available_language_codes()` are combined with `languages.language_names` to prepare the list. If ``language_code`` is not one of the available languages English is used. Args: language_code (str): Usually the current language used by Back In Time. Returns: A dictionary indexed by language codes with 3-item tuples as values. Each tuple contain three representations of the same language: ``language_code`` (usually the current locales language), the language itself (native) and in English (the source language); e.g. ``ja`` (Japanese) for ``de`` (German) locale is ``('Japanisch', '日本語', 'Japanese')``. If ``language_code`` is not one of the available languages the first element in the tuple is ``None``. """ result = {} codes = ['en'] + get_available_language_codes() for c in codes: try: # A dict with one specific language and how its name is # represented in all other languages. # e.g. "Japanese" in "de" is "Japanisch" # e.g. "Deutsch" in "es" is "alemán" lang = languages.names[c] except KeyError: names = None else: names = ( # in currents locale language lang.get(language_code, None), # native lang['_native'], # in English (source language) lang['en'] ) result[c] = names return result def get_native_language_and_completeness(language_code: str ) -> tuple[str, int]: """Return the language name in its native flavor and the completeness of its translation in percent. Args: language_code(str): The language code. Returns: A two-entry tuple with language name as string and a percent as integer. """ name = languages.names[language_code][language_code] completeness = languages.completeness[language_code] return (name, completeness) # |---------------------------------------| # | Snapshot handling | # | | # | Candidates for refactoring and moving | # | into better suited modules/classes | # |---------------------------------------| NTFS_FILESYSTEM_WARNING = _( 'The destination filesystem for {path} is formatted with NTFS, which has ' 'known incompatibilities with Unix-style filesystems.') def validate_and_prepare_snapshots_path( path: Union[str, pathlib.Path], host_user_profile: tuple[str, str, str], mode: str, copy_links: bool, error_handler: callable) -> bool: """Check if the given path is valid for being a snapshot path. It is checked if it is a folder, if it is writable, if the filesystem is supported and several other things. Dev note (buhtz, 2024-09): That code is a good candidate to get moved into a class or module. Args: path: The path to validate as a snapshot path. host_user_profile: I three item list containing the values for 'host', 'user' and 'profile' used as additional components for the snapshots path. mode: The profiles mode. copy_links: The copy links value. error_handler: Handle function receiving error messages. Returns: Success (`True`) or failure (`False`). """ path = pathlib.Path(path) if not path.is_dir(): error_handler(_('{path} is not a valid directory.') .format(path=path)) return False # build full path # /backintime/// full_path = pathlib.Path(path, 'backintime', *host_user_profile) # create full_path try: full_path.mkdir(mode=0o777, parents=True, exist_ok=True) except PermissionError: error_handler('\n'.join([ _('Creation of following directory failed:'), str(full_path), _('Write access may be restricted.')])) return False # Test filesystem rc, msg = is_filesystem_valid( full_path, path, mode, copy_links) if msg: error_handler(msg) if rc is False: return False # Test write access for the folder rc, msg = is_writeable(full_path) if msg: error_handler(msg) if rc is False: return False return True def is_filesystem_valid(full_path, msg_path, mode, copy_links): """ Args: full_path: The path to validate. msg_path: The path used for display in error messages. mode: Snapshot profile mode. copy_links: Snapshot profiles copy links setting. Returns: (bool, str): A boolean value indicating success or failure and a msg string. """ fs = filesystem(full_path if isinstance(full_path, str) else str(full_path)) msg = None if fs == 'vfat': msg = _( "Destination filesystem for {path} is formatted with FAT " "which doesn't support hard-links. " "Please use a native GNU/Linux filesystem.").format(path=msg_path) return False, msg elif fs.startswith('ntfs'): msg = NTFS_FILESYSTEM_WARNING.format(path=msg_path) elif fs == 'cifs' and not copy_links: msg = _( 'Destination filesystem for {path} is a share mounted via SMB. ' 'Please make sure the remote SMB server supports symlinks or ' 'activate "{copyLinks}" in "{expertOptions}".') \ .format(path=msg_path, copyLinks=_('Copy links (dereference symbolic links)'), expertOptions=_('Expert Options')) elif fs == 'fuse.sshfs' and mode not in ('ssh', 'ssh_encfs'): msg = _( "Destination filesystem for {path} is a share mounted via sshfs. " "Sshfs doesn't support hard-links. " 'Please use mode "SSH" instead.').format(path=msg_path) return False, msg return True, msg def is_writeable(folder): """Test write access for the folder. Args: folder: The folder to check. Returns: (bool, str): A boolean value indicating success or failure and a msg string. """ folder = pathlib.Path(folder) check_path = folder / 'check' try: check_path.mkdir( # Do not create parent folders parents=False, # Raise error if exists exist_ok=False ) except PermissionError: msg = '\n'.join([ _('File creation failed in this directory:'), str(folder), _('Write access may be restricted.')]) return False, msg else: check_path.rmdir() return True, None # |-----------------------------------| # | Manimpulation of basic data types | # |-----------------------------------| def nested_dict_update(org: dict, update: dict) -> dict: """Nested update of dict-like 'org' with dict-like 'update'. See *Deep merge dictionaries of dictionaries in Python* at StackOverflow: https://stackoverflow.com/q/7204805/4865723 Credits for current solution: https://stackoverflow.com/a/52319248/4865723 """ for key in update: if (key in org and isinstance(org[key], MutableMapping) and isinstance(update[key], MutableMapping)): nested_dict_update(org[key], update[key]) continue org[key] = update[key] return org # |------------------------------------| # | Miscellaneous, not categorized yet | # |------------------------------------| def registerBackintimePath(*path): """ Add BackInTime path ``path`` to :py:data:`sys.path` so subsequent imports can discover them. Args: *path (str): paths that should be joined to 'backintime' Note: Duplicate in :py:func:`qt/qttools.py` because modules in qt folder would need this to actually import :py:mod:`tools`. """ path = backintimePath(*path) if path not in sys.path: sys.path.insert(0, path) def runningFromSource(): """Check if BackInTime is running from source (without installing). Dev notes by buhtz (2024-04): This function is dangerous and will give a false-negative in fake filesystems (e.g. PyFakeFS). The function should not exist. Beside unit tests it is used only two times. Remove it until migration to pyproject.toml based project packaging (#1575). Returns: bool: ``True`` if BackInTime is running from source. """ return os.path.isfile(backintimePath('common', 'backintime')) def addSourceToPathEnviron(): """ Add 'backintime/common' path to 'PATH' environ variable. """ source = backintimePath('common') path = os.getenv('PATH') if path and source not in path.split(':'): os.environ['PATH'] = '%s:%s' % (source, path) def get_git_repository_info(path=None, hash_length=None): """Return the current branch and last commit hash. About the length of a commit hash. There is no strict rule but it is common sense that 8 to 10 characters are enough to be unique. Credits: https://stackoverflow.com/a/51224861/4865723 Args: path (Path): Path with '.git' folder in (default is current working directory). cut_hash (int): Restrict length of commit hash. Returns: (dict): Dict with keys "branch" and "hash" if it is a git repo, otherwise an `None`. """ if not path: # Default is current working dir path = pathlib.Path.cwd() elif isinstance(path, str): # WORKAROUND until cmoplete migration to pathlib path = pathlib.Path(path) git_folder = path / '.git' if not git_folder.exists(): return None result = {} # branch name with (git_folder / 'HEAD').open('r') as handle: val = handle.read() if not val.startswith('ref: '): result['branch'] = '(detached HEAD)' result['hash'] = val else: result['branch'] = '/'.join(val.split('/')[2:]).strip() # commit hash with (git_folder / 'refs' / 'heads' / result['branch']) \ .open('r') as handle: result['hash'] = handle.read().strip() if hash_length: result['hash'] = result['hash'][:hash_length] return result def readFile(path, default=None): """ Read the file in ``path`` or its '.gz' compressed variant and return its content or ``default`` if ``path`` does not exist. Args: path (str): full path to file that should be read. '.gz' will be added automatically if the file is compressed default (str): default if ``path`` does not exist Returns: str: content of file in ``path`` """ ret_val = default try: if os.path.exists(path): with open(path) as f: ret_val = f.read() elif os.path.exists(path + '.gz'): with gzip.open(path + '.gz', 'rt') as f: ret_val = f.read() except: pass return ret_val def readFileLines(path, default=None): """ Read the file in ``path`` or its '.gz' compressed variant and return its content as a list of lines or ``default`` if ``path`` does not exist. Args: path (str): full path to file that should be read. '.gz' will be added automatically if the file is compressed default (list): default if ``path`` does not exist Returns: list: content of file in ``path`` split by lines. """ ret_val = default try: if os.path.exists(path): with open(path) as f: ret_val = [x.rstrip('\n') for x in f.readlines()] elif os.path.exists(path + '.gz'): with gzip.open(path + '.gz', 'rt') as f: ret_val = [x.rstrip('\n') for x in f.readlines()] except: pass return ret_val def older_than(dt: datetime, value: int, unit: TimeUnit) -> bool: """Return ``True`` if ``dt`` is older than ``value`` months, weeks, days or hours compared to the current time (`datetime.now()`). The resolution used is on microseconds level. Months are calculated based on calendar. Args: dt: Timestamp to be compared with on microsecond level. value: Number of units. unit: Specify to treat ``value`` as hours, days, weeks or months. Return: ``True`` if older, otherwise ``False``. """ if not isinstance(unit, TimeUnit): unit = TimeUnit(unit) now = datetime.now() if unit is TimeUnit.HOUR: return dt < now - timedelta(hours=value) if unit is TimeUnit.DAY: return dt < now - timedelta(days=value) if unit is TimeUnit.WEEK: return dt < now - timedelta(weeks=value) if unit is TimeUnit.MONTH: # Calculate months based on calendar because timedelta do not support # months. compare_month = (dt.month + value - 1) % 12 + 1 compare_year = dt.year + (dt.month + value - 1) // 12 # make sure that day exist in the month last_day_dt \ = datetime(compare_year, compare_month + 1, 1) - timedelta(days=1) compare_day = min(dt.day, last_day_dt.day) compare_dt = datetime( compare_year, compare_month, compare_day, now.hour, now.minute, now.microsecond) return now < compare_dt # Dev note (buhtz, 2024-09): This code branch already existed in the # original code (but silent, without throwing an exception). Even if it may # seem (nearly) pointless, it will be kept for now to ensure that it is # never executed. raise RuntimeError(f'Unexpected situation. {dt=} {value=} {unit=} ' 'Please report it via a bug ticket.') def checkCommand(cmd): """Check if command ``cmd`` is a file in 'PATH' environment. Args: cmd (str): The command. Returns: bool: ``True`` if ``cmd`` is in 'PATH' environment otherwise ``False``. """ cmd = cmd.strip() if not cmd: return False if os.path.isfile(cmd): return True return which(cmd) is not None def which(cmd): """Get the fullpath of executable command ``cmd``. Works like command-line 'which' command. Dev note by buhtz (2024-04): Give false-negative results in fake filesystems. Quit often use in the whole code base. But not sure why can we replace it with "which" from shell? Args: cmd (str): The command. Returns: str: Fullpath of command ``cmd`` or ``None`` if command is not available. """ pathenv = os.getenv('PATH', '') path = pathenv.split(':') common = backintimePath('common') if runningFromSource() and common not in path: path.insert(0, common) for directory in path: fullpath = os.path.join(directory, cmd) if os.path.isfile(fullpath) and os.access(fullpath, os.X_OK): return fullpath return None def makeDirs(path): """ Create directories ``path`` recursive and return success. Args: path (str): fullpath to directories that should be created Returns: bool: ``True`` if successful """ path = path.rstrip(os.sep) if not path: return False if os.path.isdir(path): return True else: try: os.makedirs(path) except Exception as e: logger.error("Failed to make dirs '%s': %s" % (path, str(e)), traceDepth=1) return os.path.isdir(path) def mkdir(path, mode=0o755, enforce_permissions=True): """ Create directory ``path``. Args: path (str): full path to directory that should be created mode (int): numeric permission mode Returns: bool: ``True`` if successful """ if os.path.isdir(path): try: if enforce_permissions: os.chmod(path, mode) except: return False return True else: os.mkdir(path, mode) if mode & 0o002 == 0o002: # make file world (other) writable was requested # debian and ubuntu won't set o+w with os.mkdir # this will fix it os.chmod(path, mode) return os.path.isdir(path) def pids(): """ List all PIDs currently running on the system. Returns: list: PIDs as int """ return [int(x) for x in os.listdir('/proc') if x.isdigit()] def processStat(pid): """ Get the stat's of the process with ``pid``. Args: pid (int): Process Indicator Returns: str: stat from /proc/PID/stat """ try: with open('/proc/{}/stat'.format(pid), 'rt') as f: return f.read() except OSError as e: logger.warning('Failed to read process stat from {}: [{}] {}' .format(e.filename, e.errno, e.strerror)) return '' def processPaused(pid): """ Check if process ``pid`` is paused (got signal SIGSTOP). Args: pid (int): Process Indicator Returns: bool: True if process is paused """ m = re.match(r'\d+ \(.+\) T', processStat(pid)) return bool(m) def processName(pid): """ Get the name of the process with ``pid``. Args: pid (int): Process Indicator Returns: str: name of the process """ m = re.match(r'.*\((.+)\).*', processStat(pid)) if m: return m.group(1) def processCmdline(pid): """ Get the cmdline (command that spawnd this process) of the process with ``pid``. Args: pid (int): Process Indicator Returns: str: cmdline of the process """ try: with open('/proc/{}/cmdline'.format(pid), 'rt') as f: return f.read().strip('\n') except OSError as e: logger.warning('Failed to read process cmdline from {}: [{}] {}' .format(e.filename, e.errno, e.strerror)) return '' def pidsWithName(name): """ Get all processes currently running with name ``name``. Args: name (str): name of a process like 'python3' or 'backintime' Returns: list: PIDs as int """ # /proc/###/stat stores just the first 16 chars of the process name return [x for x in pids() if processName(x) == name[:15]] def processExists(name): """ Check if process ``name`` is currently running. Args: name (str): name of a process like 'python3' or 'backintime' Returns: bool: ``True`` if there is a process running with ``name`` """ return len(pidsWithName(name)) > 0 def processAlive(pid): """Check if the process with PID ``pid`` is alive. Args: pid (int): Process Indicator Returns: bool: ``True`` if alive otherwise ``False``. Raises: ValueError: If ``pid`` is 0 because 'kill(0, SIG)' would send SIG to all processes. """ if pid < 0: return False if pid == 0: raise ValueError('Invalid PID 0') try: # Signal 0 is a dummy signal without effect. But an OSError is raised # if the process does not exists. os.kill(pid, 0) except OSError as err: if err.errno == errno.ESRCH: # ESRCH == No such process return False if err.errno == errno.EPERM: # EPERM clearly means there's a process to deny access to return True raise return True def checkXServer(): """ Check if there is a X11 server running on this system. Use ``is_Qt_working`` instead if you want to be sure that Qt is working. Returns: bool: ``True`` if X11 server is running """ # Note: Return values of xdpyinfo <> 0 are not clearly documented. # xdpyinfo does indeed return 1 if it prints # xdypinfo: unable to open display "..." # This seems to be undocumented (at least not in the man pages) # and the source is not obvious here: # https://cgit.freedesktop.org/xorg/app/xdpyinfo/tree/xdpyinfo.c if checkCommand('xdpyinfo'): proc = subprocess.Popen(['xdpyinfo'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) proc.communicate() return proc.returncode == 0 else: return False def is_Qt_working(systray_required=False): """ Check if the Qt GUI library is working (installed and configured) This function is contained in BiT CLI (not BiT Qt) to allow Qt diagnostics output even if the BiT Qt GUI is not installed. This function does NOT add a hard Qt dependency (just "probing") so it is OK to be in BiT CLI. Args: systray_required: Set to ``True`` if the systray of the desktop environment must be available too to consider Qt as "working" Returns: bool: ``True`` Qt can create a GUI ``False`` Qt fails (or the systray is not available if ``systray_required`` is ``True``) """ # Spawns a new process since it may crash with a SIGABRT and we # don't want to crash BiT if this happens... try: path = os.path.join(backintimePath("common"), "qt_probing.py") cmd = [sys.executable, path] if logger.DEBUG: cmd.append('--debug') with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) as proc: # to get the exit code "timeout" fixes #1592 (qt_probing.py may # hang as root): Kill after timeout std_output, error_output = proc.communicate(timeout=30) logger.debug(f"Qt probing result: exit code {proc.returncode}") # if some Qt parts are missing: Show details if proc.returncode != 2 or logger.DEBUG: logger.debug(f"Qt probing stdout:\n{std_output}") logger.debug(f"Qt probing errout:\n{error_output}") return proc.returncode == 2 or (proc.returncode == 1 and systray_required is False) except FileNotFoundError: logger.error(f"Qt probing script not found: {cmd[0]}") raise # Fix for #1592 (qt_probing.py may hang as root): Kill after timeout except subprocess.TimeoutExpired: proc.kill() outs, errs = proc.communicate() logger.info("Qt probing sub process killed after timeout " "without response") logger.debug(f"Qt probing stdout:\n{outs}") logger.debug(f"Qt probing errout:\n{errs}") except Exception as e: logger.error(f"Error: {repr(e)}") raise def preparePath(path): """ Removes trailing slash '/' from ``path``. Args: path (str): absolute path Returns: str: path ``path`` without trailing but with leading slash """ path = path.strip("/") path = os.sep + path return path def powerStatusAvailable(): """ Check if org.freedesktop.UPower is available so that :py:func:`tools.onBattery` would return the correct power status. Returns: bool: ``True`` if :py:func:`tools.onBattery` can report power status """ if dbus: try: bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.UPower', '/org/freedesktop/UPower') return 'OnBattery' in proxy.GetAll( 'org.freedesktop.UPower', dbus_interface='org.freedesktop.DBus.Properties') except dbus.exceptions.DBusException: pass return False def onBattery(): """ Checks if the system is on battery power. Returns: bool: ``True`` if system is running on battery """ if dbus: try: bus = dbus.SystemBus() proxy = bus.get_object('org.freedesktop.UPower', '/org/freedesktop/UPower') return bool(proxy.Get( 'org.freedesktop.UPower', 'OnBattery', dbus_interface='org.freedesktop.DBus.Properties')) except dbus.exceptions.DBusException: pass return False def rsyncCaps(data=None): """ Get capabilities of the installed rsync binary. This can be different from version to version and also on build arguments used when building rsync. Args: data (str): 'rsync --version' output. This is just for unittests. Returns: list: List of str with rsyncs capabilities """ if not data: proc = subprocess.Popen(['rsync', '--version'], stdout=subprocess.PIPE, universal_newlines=True) data = proc.communicate()[0] caps = [] # rsync >= 3.1 does provide --info=progress2 matchers = [r'rsync\s*version\s*(\d\.\d)', r'rsync\s*version\s*v(\d\.\d.\d)'] for matcher in matchers: m = re.match(matcher, data) if m and Version(m.group(1)) >= Version('3.1'): caps.append('progress2') break # all other capabilities are separated by ',' between # 'Capabilities:' and '\n\n' m = re.match(r'.*Capabilities:(.+)\n\n.*', data, re.DOTALL) if not m: return caps for line in m.group(1).split('\n'): caps.extend( [i.strip(' \n') for i in line.split(',') if i.strip(' \n')]) return caps def rsyncPrefix(config, no_perms=True, use_mode=['ssh', 'ssh_encfs'], progress=True): """ Get rsync command and all args for creating a new snapshot. Args are based on current profile in ``config``. Args: config (config.Config): current config no_perms (bool): don't sync permissions (--no-p --no-g --no-o) if ``True``. :py:func:`config.Config.preserveAcl` == ``True`` or :py:func:`config.Config.preserveXattr` == ``True`` will overwrite this to ``False`` use_mode (list): if current mode is in this list add additional args for that mode progress (bool): add '--info=progress2' to show progress Returns: list: rsync command with all args but without --include, --exclude, source and destination """ caps = rsyncCaps() cmd = [] if config.nocacheOnLocal(): cmd.append('nocache') cmd.append('rsync') cmd.extend(( # recurse into directories '--recursive', # preserve modification times '--times', # preserve device files (super-user only) '--devices', # preserve special files '--specials', # preserve hard links '--hard-links', # numbers in a human-readable format '--human-readable', # use "new" argument protection '-s' )) if config.useChecksum() or config.forceUseChecksum: cmd.append('--checksum') if config.copyUnsafeLinks(): cmd.append('--copy-unsafe-links') if config.copyLinks(): cmd.append('--copy-links') else: cmd.append('--links') if config.oneFileSystem(): cmd.append('--one-file-system') if config.preserveAcl() and "ACLs" in caps: cmd.append('--acls') # preserve ACLs (implies --perms) no_perms = False if config.preserveXattr() and "xattrs" in caps: cmd.append('--xattrs') # preserve extended attributes no_perms = False if no_perms: cmd.extend(('--no-perms', '--no-group', '--no-owner')) else: cmd.extend(('--perms', # preserve permissions '--executability', # preserve executability '--group', # preserve group '--owner')) # preserve owner (super-user only) if progress and 'progress2' in caps: cmd.extend(('--info=progress2', '--no-inc-recursive')) if config.bwlimitEnabled(): cmd.append('--bwlimit=%d' % config.bwlimit()) if config.rsyncOptionsEnabled(): cmd.extend(shlex.split(config.rsyncOptions())) cmd.extend(rsyncSshArgs(config, use_mode)) return cmd def rsyncSshArgs(config, use_mode=['ssh', 'ssh_encfs']): """ Get SSH args for rsync based on current profile in ``config``. Args: config (config.Config): Current config instance. use_mode (list): If the profiles current mode is in this list add additional args. Returns: list: List of rsync args related to SSH. """ cmd = [] mode = config.snapshotsMode() if mode in ['ssh', 'ssh_encfs'] and mode in use_mode: ssh = config.sshCommand(user_host=False, ionice=False, nice=False) cmd.append('--rsh=' + ' '.join(ssh)) if config.niceOnRemote() \ or config.ioniceOnRemote() \ or config.nocacheOnRemote(): rsync_path = '--rsync-path=' if config.niceOnRemote(): rsync_path += 'nice -n 19 ' if config.ioniceOnRemote(): rsync_path += 'ionice -c2 -n7 ' if config.nocacheOnRemote(): rsync_path += 'nocache ' rsync_path += 'rsync' cmd.append(rsync_path) return cmd def rsyncRemove(config, run_local=True): """ Get rsync command and all args for removing snapshots with rsync. Args: config (config.Config): current config run_local (bool): if True and current mode is ``ssh`` or ``ssh_encfs`` this will add SSH options Returns: list: rsync command with all args """ cmd = ['rsync', '-a', '--delete', '-s'] if run_local: cmd.extend(rsyncSshArgs(config)) return cmd # TODO: check if we really need this def tempFailureRetry(func, *args, **kwargs): while True: try: return func(*args, **kwargs) except (os.error, IOError) as ex: if ex.errno == errno.EINTR: continue else: raise def md5sum(path): """ Calculate md5sum for file in ``path``. Args: path (str): full path to file Returns: str: md5sum of file """ md5 = hashlib.md5() with open(path, 'rb') as f: while True: data = f.read(4096) if not data: break md5.update(data) return md5.hexdigest() def checkCronPattern(s): """ Check if ``s`` is a valid cron pattern. Examples:: 0,10,13,15,17,20,23 */6 Args: s (str): pattern to check Returns: bool: ``True`` if ``s`` is a valid cron pattern Dev note: Schedule for removal. See comment in `config.Config.saveProfile()`. """ if s.find(' ') >= 0: return False try: if s.startswith('*/'): if s[2:].isdigit() and int(s[2:]) <= 24: return True else: return False for i in s.split(','): if i.isdigit() and int(i) <= 24: continue else: return False return True except ValueError: return False def envLoad(f): """ Load environ variables from file ``f`` into current environ. Do not overwrite existing environ variables. Args: f (str): full path to file with environ variables """ env = os.environ.copy() env_file = configfile.ConfigFile() env_file.load(f, maxsplit = 1) for key in env_file.keys(): value = env_file.strValue(key) if not value: continue if not key in list(env.keys()): os.environ[key] = value del env_file def envSave(f): """ Save environ variables to file that are needed by cron to connect to keyring. This will only work if the user is logged in. Args: f (str): full path to file for environ variables """ env = os.environ.copy() env_file = configfile.ConfigFile() for key in ('GNOME_KEYRING_CONTROL', 'DBUS_SESSION_BUS_ADDRESS', 'DBUS_SESSION_BUS_PID', 'DBUS_SESSION_BUS_WINDOWID', 'DISPLAY', 'XAUTHORITY', 'GNOME_DESKTOP_SESSION_ID', 'KDE_FULL_SESSION'): if key in env: env_file.setStrValue(key, env[key]) env_file.save(f) def keyringSupported(): """ Checks if a keyring (supported by BiT) is available Returns: bool: ``True`` if a supported keyring could be loaded """ if not is_keyring_available: logger.debug('No keyring due to import error.') return False keyring_config_file_folder = "Unknown" try: keyring_config_file_folder = keyring.util.platform_.config_root() except: pass logger.debug( f"Keyring config file directory: {keyring_config_file_folder}") # Determine the currently active backend try: # get_keyring() internally calls keyring.core.init_backend() # which fixes non-available backends for the first call. # See related issue #1321: # https://github.com/bit-team/backintime/issues/1321 # The module name is used instead of the class name # to show only the keyring name (not the technical name) displayName = keyring.get_keyring().__module__ except: displayName = str(keyring.get_keyring()) # technical class name! logger.debug("Available keyring backends:") try: for b in backend.get_all_keyring(): logger.debug(str(b)) except Exception as e: logger.debug("Available backends cannot be listed: " + repr(e)) available_backends = [] # Create a list of installed backends that BiT supports (white-listed). # This is done by trying to put the meta classes ("class definitions", # NOT instances of the class itself!) of the supported backends # into the "backends" list backends_to_check = [ (keyring.backends, ['SecretService', 'Keyring']), (keyring.backends, ['Gnome', 'Keyring']), (keyring.backends, ['kwallet', 'Keyring']), (keyring.backends, ['kwallet', 'DBusKeyring']), (keyring.backend, ['SecretServiceKeyring']), (keyring.backend, ['GnomeKeyring']), (keyring.backend, ['KDEWallet']), # See issue #1410: ChainerBackend is now supported to solve the # problem of configuring the used backend since it iterates over all # of them and is to be the default backend now. Please read the issue # details to understand the unwanted side-effects the chainer could # bring with it. # See also: # https://github.com/jaraco/keyring/blob/977ed03677bb0602b91f005461ef3dddf01a49f6/keyring/backends/chainer.py#L11 # noqa (keyring.backends, ('chainer', 'ChainerBackend')), ] not_found_metaclasses = [] for backend_package, backends in backends_to_check: result = backend_package # e.g. keyring.backends try: # Load the backend step-by-step. # e.g. When the target is "keyring.backends.Gnome.Keyring" then in # a first step "Gnome" part is loaded first and if successful the # "keyring" part. for b in backends: result = getattr(result, b) except AttributeError: # # Debug message if backend is not available. # logger.debug('Metaclass {}.{} not found: {}' # .format(backend_package.__name__, # '.'.join(backends), # repr(err))) not_found_metaclasses.append('{}.{}'.format( backend_package.__name__, '.'.join(backends))) else: # Remember the backend class (not an instance) as available. available_backends.append(result) logger.debug(f'Not found Metaclasses: {not_found_metaclasses}') logger.debug("Available supported backends: " + repr(available_backends)) if available_backends and isinstance(keyring.get_keyring(), tuple(available_backends)): logger.debug("Found appropriate keyring '{}'".format(displayName)) return True logger.debug(f"No appropriate keyring found. '{displayName}' can't be " "used with BackInTime.") logger.debug("See https://github.com/bit-team/backintime on how to fix " "this by creating a keyring config file.") return False def password(*args): if is_keyring_available: return keyring.get_password(*args) return None def setPassword(*args): if is_keyring_available: return keyring.set_password(*args) return False def mountpoint(path): """ Get the mountpoint of ``path``. If your HOME is on a separate partition mountpoint('/home/user/foo') would return '/home'. Args: path (str): full path Returns: str: mountpoint of the filesystem """ path = os.path.realpath(os.path.abspath(path)) while path != os.path.sep: if os.path.ismount(path): return path path = os.path.abspath(os.path.join(path, os.pardir)) return path def decodeOctalEscape(s): """ Decode octal-escaped characters with its ASCII dependence. For example '\040' will be a space ' ' Args: s (str): string with or without octal-escaped characters Returns: str: human readable string """ def repl(m): return chr(int(m.group(1), 8)) return re.sub(r'\\(\d{3})', repl, s) def mountArgs(path): """ Get all /etc/mtab args for the filesystem of ``path`` as a list. Example:: [DEVICE, MOUNTPOINT, FILESYSTEM_TYPE, OPTIONS, DUMP, PASS] ['/dev/sda3', '/', 'ext4', 'defaults', '0', '0'] ['/dev/sda1', '/boot', 'ext4', 'defaults', '0', '0'] Args: path (str): full path Returns: list: mount args """ mp = mountpoint(path) with open('/etc/mtab', 'r') as mounts: for line in mounts: args = line.strip('\n').split(' ') if len(args) >= 2: args[1] = decodeOctalEscape(args[1]) if args[1] == mp: return args return None def device(path): """ Get the device for the filesystem of ``path``. Example:: /dev/sda1 /dev/mapper/vglinux proc Args: path (str): full path Returns: str: device """ args = mountArgs(path) if args: return args[0] return None def filesystem(path): """ Get the filesystem type for the filesystem of ``path``. Args: path (str): full path Returns: str: filesystem """ args = mountArgs(path) if args and len(args) >= 3: return args[2] return None def _uuidFromDev_via_filesystem(dev): """Get the UUID for the block device ``dev`` from ``/dev/disk/by-uuid`` in the filesystem. Args: dev (pathlib.Path): The block device path (e.g. ``/dev/sda1``). Returns: str: The UUID or ``None`` if nothing found. """ # /dev/disk/by-uuid path_DISK_BY_UUID = pathlib.Path(DISK_BY_UUID) if not path_DISK_BY_UUID.exists(): return None # Each known uuid for uuid_symlink in path_DISK_BY_UUID.glob('*'): # Resolve the symlink (get it's target) to get the real device name # and compare it with the device we are looking for if dev == uuid_symlink.resolve(): # e.g. 'c7aca0a7-89ed-43f0-a4f9-c744dfe673e0' return uuid_symlink.name # Nothing found return None def _uuidFromDev_via_blkid_command(dev): """Get the UUID for the block device ``dev`` via the extern command ``blkid``. Hint: On most systems the ``blkid`` command is available only for the super-user (e.g. via ``sudo``). Args: dev (pathlib.Path): The block device path (e.g. ``/dev/sda1``). Returns: str: The UUID or ``None`` if nothing found. """ # Call "blkid" command try: # If device does not exist, blkid will exit with a non-zero code output = subprocess.check_output( ['blkid', dev], stderr=subprocess.DEVNULL, universal_newlines=True) except (subprocess.CalledProcessError, FileNotFoundError): return None # Parse the commands output for a UUID try: return re.findall(r'.*\sUUID=\"([^\"]*)\".*', output)[0] except IndexError: # nothing found via the regex pattern pass return None def _uuidFromDev_via_udevadm_command(dev): """Get the UUID for the block device ``dev`` via the extern command ``udevadm``. Args: dev (pathlib.Path): The block device path (e.g. ``/dev/sda1``). Returns: str: The UUID or ``None`` if nothing found. """ # Call "udevadm" command try: output = subprocess.check_output( ['udevadm', 'info', f'--name={dev}'], stderr=subprocess.DEVNULL, universal_newlines=True) except (subprocess.CalledProcessError, FileNotFoundError): return None # Parse the commands output for a UUID try: return re.findall(r'.*?ID_FS_UUID=(\S+)', output)[0] except IndexError: # nothing found via the regex pattern pass return None def uuidFromDev(dev): """ Get the UUID for the block device ``dev``. Args: dev (str, pathlib.Path): block device path Returns: str: UUID """ # handle Path objects only if not isinstance(dev, pathlib.Path): dev = pathlib.Path(dev) if dev.exists(): dev = dev.resolve() # when /dev/sda1 is a symlink # Look at /dev/disk/by-uuid/ uuid = _uuidFromDev_via_filesystem(dev) if uuid: return uuid # Try extern command "blkid" uuid = _uuidFromDev_via_blkid_command(dev) if uuid: return uuid # "dev" doesn't exist in the filesystem # Try "udevadm" command at the end return _uuidFromDev_via_udevadm_command(dev) def uuidFromPath(path): """ Get the UUID for the for the filesystem of ``path``. Args: path (str): full path Returns: str: UUID """ return uuidFromDev(device(path)) def isRoot(): """ Check if we are root. Returns: bool: ``True`` if we are root """ # The EUID (Effective UID) may be different from the UID (user ID) # in case of SetUID or using "sudo" (where EUID is "root" and UID # is the original user who executed "sudo"). return os.geteuid() == 0 def usingSudo(): """ Check if 'sudo' was used to start this process. Returns: bool: ``True`` if the process was started with sudo """ return isRoot() and os.getenv('HOME', '/root') != '/root' re_wildcard = re.compile(r'(?:\[|\]|\?)') re_asterisk = re.compile(r'\*') re_separate_asterisk = re.compile(r'(?:^\*+[^/\*]|[^/\*]\*+[^/\*]|[^/\*]\*+|\*+[^/\*]|[^/\*]\*+$)') def patternHasNotEncryptableWildcard(pattern): """ Check if ``pattern`` has wildcards ``[ ] ? *``. but return ``False`` for ``foo/*``, ``foo/*/bar``, ``*/bar`` or ``**/bar`` Args: pattern (str): path or pattern to check Returns: bool: ``True`` if ``pattern`` has wildcards ``[ ] ? *`` but ``False`` if wildcard look like ``foo/*``, ``foo/*/bar``, ``*/bar`` or ``**/bar`` """ if not re_wildcard.search(pattern) is None: return True if not re_asterisk is None and not re_separate_asterisk.search(pattern) is None: return True return False def readTimeStamp(fname): """ Read date string from file ``fname`` and try to return datetime. Args: fname (str): Full path to timestamp file. Returns: datetime.datetime: Timestamp object. """ if not os.path.exists(fname): logger.debug(f"No timestamp file '{fname}'") return with open(fname, 'r') as f: s = f.read().strip('\n') time_formats = ( '%Y%m%d %H%M', # BIT like '%Y%m%d', # Anacron like ) for form in time_formats: try: stamp = datetime.strptime(s, form) except ValueError: # invalid format # next iteration pass else: # valid time stamp logger.debug(f"Read timestamp '{stamp}' from file '{fname}'") return stamp def writeTimeStamp(fname): """Write current date and time into file ``fname``. Args: fname (str): Full path to timestamp file. """ now = datetime.now().strftime('%Y%m%d %H%M') logger.debug(f"Write timestamp '{now}' into file '{fname}'") makeDirs(os.path.dirname(fname)) with open(fname, 'w') as f: f.write(now) INHIBIT_LOGGING_OUT = 1 INHIBIT_USER_SWITCHING = 2 INHIBIT_SUSPENDING = 4 INHIBIT_IDLE = 8 INHIBIT_DBUS = ( {'service': 'org.gnome.SessionManager', 'objectPath': '/org/gnome/SessionManager', 'methodSet': 'Inhibit', 'methodUnSet': 'Uninhibit', 'interface': 'org.gnome.SessionManager', 'arguments': (0, 1, 2, 3) }, {'service': 'org.mate.SessionManager', 'objectPath': '/org/mate/SessionManager', 'methodSet': 'Inhibit', 'methodUnSet': 'Uninhibit', 'interface': 'org.mate.SessionManager', 'arguments': (0, 1, 2, 3) }, {'service': 'org.freedesktop.PowerManagement', 'objectPath': '/org/freedesktop/PowerManagement/Inhibit', 'methodSet': 'Inhibit', 'methodUnSet': 'UnInhibit', 'interface': 'org.freedesktop.PowerManagement.Inhibit', 'arguments': (0, 2) }) def inhibitSuspend(app_id = sys.argv[0], toplevel_xid = None, reason = 'take snapshot', flags = INHIBIT_SUSPENDING | INHIBIT_IDLE): """ Prevent machine to go to suspend or hibernate. Returns the inhibit cookie which is used to end the inhibitor. """ if ON_TRAVIS or dbus is None: # no suspend on travis (no dbus either) return # Fixes #1592 (BiT hangs as root when trying to establish a dbus user session connection) # Side effect: In BiT <= 1.4.1 root still tried to connect to the dbus user session # and it may have worked sometimes (without logging we don't know) # so as root suspend can no longer inhibited. if isRoot(): logger.debug("Inhibit Suspend failed because BIT was started as root.") return if not app_id: app_id = 'backintime' try: if not toplevel_xid: toplevel_xid = 0 except IndexError: toplevel_xid = 0 for dbus_props in INHIBIT_DBUS: try: #connect directly to the socket instead of dbus.SessionBus because #the dbus.SessionBus was initiated before we loaded the environ #variables and might not work if 'DBUS_SESSION_BUS_ADDRESS' in os.environ: bus = dbus.bus.BusConnection(os.environ['DBUS_SESSION_BUS_ADDRESS']) else: bus = dbus.SessionBus() # This code may hang forever (if BiT is run as root via cron job and no user is logged in). See #1592 interface = bus.get_object(dbus_props['service'], dbus_props['objectPath']) proxy = interface.get_dbus_method(dbus_props['methodSet'], dbus_props['interface']) cookie = proxy(*[(app_id, dbus.UInt32(toplevel_xid), reason, dbus.UInt32(flags))[i] for i in dbus_props['arguments']]) logger.debug('Inhibit Suspend started. Reason: {}'.format(reason)) return (cookie, bus, dbus_props) except dbus.exceptions.DBusException: pass logger.warning('Inhibit Suspend failed.') def unInhibitSuspend(cookie, bus, dbus_props): """ Release inhibit. """ assert isinstance(cookie, int), 'cookie is not int type: %s' % cookie assert isinstance(bus, dbus.bus.BusConnection), 'bus is not dbus.bus.BusConnection type: %s' % bus assert isinstance(dbus_props, dict), 'dbus_props is not dict type: %s' % dbus_props try: interface = bus.get_object(dbus_props['service'], dbus_props['objectPath']) proxy = interface.get_dbus_method(dbus_props['methodUnSet'], dbus_props['interface']) proxy(cookie) logger.debug('Release inhibit Suspend') return None except dbus.exceptions.DBusException: logger.warning('Release inhibit Suspend failed.') return (cookie, bus, dbus_props) def splitCommands(cmds, head = '', tail = '', maxLength = 0): """ Split a list of commands ``cmds`` into multiple commands with each length lower than ``maxLength``. Args: cmds (list): commands head (str): command that need to run first on every iteration of ``cmds`` tail (str): command that need to run after every iteration of ``cmds`` maxLength (int): maximum length a command could be. Don't split if <= 0 Yields: str: new command with length < ``maxLength`` Example:: head cmds[0] cmds[n] tail """ while cmds: s = head while cmds and ((len(s + cmds[0] + tail) <= maxLength) or maxLength <= 0): s += cmds.pop(0) s += tail yield s def escapeIPv6Address(address): """Escape IP addresses with square brackets ``[]`` if they are IPv6. If it is an IPv4 address or a hostname (lettersonly) nothing is changed. Args: address (str): IP-Address to escape if needed. Returns: str: The address, escaped if it is IPv6. """ try: ip = ipaddress.ip_address(address) except ValueError: # invalid IP, e.g. a hostname return address if ip.version == 6: return f'[{address}]' return address def camelCase(s): """ Remove underlines and make every first char uppercase. Args: s (str): string separated by underlines (foo_bar) Returns: str: string without underlines but uppercase chars (FooBar) """ return ''.join([x.capitalize() for x in s.split('_')]) class Alarm: """Establish a callback function that is called after a timeout using SIGALRM signal. If no callback is specified a `exception.Timeout` will be raised instead. The implementation uses a SIGALRM signal. Attention: Do not call code in the callback that does not support multi-threading (reentrance) or you may cause non-deterministic "random" RuntimeErrors (RTE). """ def __init__(self, callback=None, overwrite=True): """Create a new alarm instance. Args: callback (callable): Function to call when the timer ran down (ensure calling only reentrant code). Use ``None`` to throw a `exceptions.Timeout` exception instead. overwrite (bool): Is it allowed to (re)start the timer even though the current timer is still running ("ticking"). ``True`` cancels the current timer (if active) and restarts with the new timeout. ``False`` silently ignores the start request if the current timer is still "ticking" """ self.callback = callback self.ticking = False self.overwrite = overwrite def start(self, timeout): """Start the timer (which calls the handler function when the timer ran down). If `self.overwrite` is ``False`` and the current timer is still ticking the start is silently ignored. Args: timeout: Timer count down in seconds. """ if self.ticking and not self.overwrite: return try: # Warning: This code may cause non-deterministic RunTimeError # if the handler function calls code that does # not support reentrance (see e.g. issue #1003). signal.signal(signal.SIGALRM, self.handler) signal.alarm(timeout) except ValueError: # Why??? pass self.ticking = True def stop(self): """Stop timer before it comes to an end.""" try: signal.alarm(0) self.ticking = False # TODO: What to catch? except: pass def handler(self, signum, frame): """This method is called after the timer ran down to zero and calls the callback function of the alarm instance. Raises: `exceptions.Timeout`: If no callback function was set for the alarm instance. """ self.ticking = False if self.callback is None: raise Timeout() else: self.callback() class ShutDown: """ Shutdown the system after the current snapshot has finished. This should work for KDE, Gnome, Unity, Cinnamon, XFCE, Mate and E17. """ DBUS_SHUTDOWN ={'gnome': {'bus': 'sessionbus', 'service': 'org.gnome.SessionManager', 'objectPath': '/org/gnome/SessionManager', 'method': 'Shutdown', #methods Shutdown # Reboot # Logout 'interface': 'org.gnome.SessionManager', 'arguments': () #arg (only with Logout) # 0 normal # 1 no confirm # 2 force }, 'kde': {'bus': 'sessionbus', 'service': 'org.kde.ksmserver', 'objectPath': '/KSMServer', 'method': 'logout', 'interface': 'org.kde.KSMServerInterface', 'arguments': (-1, 2, -1) #1st arg -1 confirm # 0 no confirm #2nd arg -1 full dialog with default logout # 0 logout # 1 restart # 2 shutdown #3rd arg -1 wait 30sec # 2 immediately }, 'xfce': {'bus': 'sessionbus', 'service': 'org.xfce.SessionManager', 'objectPath': '/org/xfce/SessionManager', 'method': 'Shutdown', #methods Shutdown # Restart # Suspend (no args) # Hibernate (no args) # Logout (two args) 'interface': 'org.xfce.Session.Manager', 'arguments': (True,) #arg True allow saving # False don't allow saving #1st arg (only with Logout) # True show dialog # False don't show dialog #2nd arg (only with Logout) # True allow saving # False don't allow saving }, 'mate': {'bus': 'sessionbus', 'service': 'org.mate.SessionManager', 'objectPath': '/org/mate/SessionManager', 'method': 'Shutdown', #methods Shutdown # Logout 'interface': 'org.mate.SessionManager', 'arguments': () #arg (only with Logout) # 0 normal # 1 no confirm # 2 force }, 'e17': {'bus': 'sessionbus', 'service': 'org.enlightenment.Remote.service', 'objectPath': '/org/enlightenment/Remote/RemoteObject', 'method': 'Halt', #methods Halt -> Shutdown # Reboot # Logout # Suspend # Hibernate 'interface': 'org.enlightenment.Remote.Core', 'arguments': () }, 'e19': {'bus': 'sessionbus', 'service': 'org.enlightenment.wm.service', 'objectPath': '/org/enlightenment/wm/RemoteObject', 'method': 'Shutdown', #methods Shutdown # Restart 'interface': 'org.enlightenment.wm.Core', 'arguments': () }, 'z_freed': {'bus': 'systembus', 'service': 'org.freedesktop.login1', 'objectPath': '/org/freedesktop/login1', 'method': 'PowerOff', 'interface': 'org.freedesktop.login1.Manager', 'arguments': (True,) } } def __init__(self): self.is_root = isRoot() if self.is_root: self.proxy, self.args = None, None else: self.proxy, self.args = self._prepair() self.activate_shutdown = False self.started = False def _prepair(self): """ Try to connect to the given dbus services. If successful it will return a callable dbus proxy and those arguments. """ try: if 'DBUS_SESSION_BUS_ADDRESS' in os.environ: sessionbus = dbus.bus.BusConnection(os.environ['DBUS_SESSION_BUS_ADDRESS']) else: sessionbus = dbus.SessionBus() systembus = dbus.SystemBus() except: return (None, None) des = list(self.DBUS_SHUTDOWN.keys()) des.sort() for de in des: if de == 'gnome' and self.unity7(): continue dbus_props = self.DBUS_SHUTDOWN[de] try: if dbus_props['bus'] == 'sessionbus': bus = sessionbus else: bus = systembus interface = bus.get_object(dbus_props['service'], dbus_props['objectPath']) proxy = interface.get_dbus_method(dbus_props['method'], dbus_props['interface']) return (proxy, dbus_props['arguments']) except dbus.exceptions.DBusException: continue return (None, None) def canShutdown(self): """ Indicate if a valid dbus service is available to shutdown system. """ return not self.proxy is None or self.is_root def askBeforeQuit(self): """ Indicate if ShutDown is ready to fire and so the application shouldn't be closed. """ return self.activate_shutdown and not self.started def shutdown(self): """ Run 'shutdown -h now' if we are root or call the dbus proxy to start the shutdown. """ if not self.activate_shutdown: return False if self.is_root: self.started = True proc = subprocess.Popen(['shutdown', '-h', 'now']) proc.communicate() return proc.returncode if self.proxy is None: return False else: self.started = True return self.proxy(*self.args) def unity7(self): """ Unity >= 7.0 doesn't shutdown automatically. It will only show shutdown dialog and wait for user input. """ if not checkCommand('unity'): return False proc = subprocess.Popen(['unity', '--version'], stdout = subprocess.PIPE, universal_newlines = True) unity_version = proc.communicate()[0] m = re.match(r'unity ([\d\.]+)', unity_version) return m and Version(m.group(1)) >= Version('7.0') and processExists('unity-panel-service') class SetupUdev: """ Setup Udev rules for starting BackInTime when a drive get connected. This is done by serviceHelper.py script (included in backintime-qt) running as root though DBus. """ CONNECTION = 'net.launchpad.backintime.serviceHelper' OBJECT = '/UdevRules' INTERFACE = 'net.launchpad.backintime.serviceHelper.UdevRules' MEMBERS = ('addRule', 'save', 'delete') def __init__(self): if dbus is None: self.isReady = False return try: bus = dbus.SystemBus() conn = bus.get_object(SetupUdev.CONNECTION, SetupUdev.OBJECT) self.iface = dbus.Interface(conn, SetupUdev.INTERFACE) except dbus.exceptions.DBusException as e: # Only DBusExceptions are handled to do a "graceful recovery" # by working without a serviceHelper D-Bus connection... # All other exceptions are still raised causing BiT # to stop during startup. # if e._dbus_error_name in ('org.freedesktop.DBus.Error.NameHasNoOwner', # 'org.freedesktop.DBus.Error.ServiceUnknown', # 'org.freedesktop.DBus.Error.FileNotFound'): logger.warning('Failed to connect to Udev serviceHelper daemon ' 'via D-Bus: ' + e.get_dbus_name()) logger.warning('D-Bus message: ' + e.get_dbus_message()) logger.warning('Udev-based profiles cannot be changed or checked ' 'due to Udev serviceHelper connection failure') conn = None # else: # raise self.isReady = bool(conn) def addRule(self, cmd, uuid): """Prepare rules in serviceHelper.py """ if not self.isReady: return try: return self.iface.addRule(cmd, uuid) except dbus.exceptions.DBusException as exc: if exc._dbus_error_name == 'net.launchpad.backintime.InvalidChar': raise InvalidChar(str(exc)) from exc elif exc._dbus_error_name == 'net.launchpad.backintime.InvalidCmd': raise InvalidCmd(str(exc)) from exc elif exc._dbus_error_name == 'net.launchpad.backintime.LimitExceeded': raise LimitExceeded(str(exc)) from exc else: raise def save(self): """Save rules with serviceHelper.py after authentication. If no rules where added before this will delete current rule. """ if not self.isReady: return try: return self.iface.save() except dbus.exceptions.DBusException as err: if err._dbus_error_name == 'com.ubuntu.DeviceDriver.PermissionDeniedByPolicy': raise PermissionDeniedByPolicy(str(err)) from err else: raise err def clean(self): """Clean up remote cache. """ if not self.isReady: return self.iface.clean() class PathHistory: def __init__(self, path): self.history = [path,] self.index = 0 def append(self, path): #append path after the current index self.history = self.history[:self.index + 1] + [path,] self.index = len(self.history) - 1 def previous(self): if self.index == 0: return self.history[0] try: path = self.history[self.index - 1] except IndexError: return self.history[self.index] self.index -= 1 return path def next(self): if self.index == len(self.history) - 1: return self.history[-1] try: path = self.history[self.index + 1] except IndexError: return self.history[self.index] self.index += 1 return path def reset(self, path): self.history = [path,] self.index = 0 class Execute: """Execute external commands and handle its output. Args: cmd (list): Command with arguments that should be called. The command will be called by :py:class:`subprocess.Popen`. callback (method): Function which will handle output returned by command (e.g. to extract errors). user_data: Extra arguments which will be forwarded to ``callback`` function (e.g. a ``tuple`` - which is passed by reference in Python - to "return" results of the callback function as side effect). filters (tuple): Tuple of functions used to filter messages before sending them to the ``callback`` function. parent (instance): Instance of the calling method used only to proper format log messages. conv_str (bool): Convert output to :py:class:`str` if ``True`` or keep it as :py:class:`bytes` if ``False``. join_stderr (bool): Join ``stderr`` to ``stdout``. Note: Signals ``SIGTSTP`` ("keyboard stop") and ``SIGCONT`` send to Python main process will be forwarded to the command. ``SIGHUP`` will kill the process. """ def __init__(self, cmd, callback=None, user_data=None, filters=(), parent=None, conv_str=True, join_stderr=True): self.cmd = cmd self.callback = callback self.user_data = user_data self.filters = filters self.currentProc = None self.conv_str = conv_str self.join_stderr = join_stderr # Need to forward parent to have the correct class name in debug log. self.parent = parent if parent else self # Dev note (buhtz, 2024-07): Previous version was calling os.system() # if cmd was a string instead of a list of strings. This is not secure # and to my knowledge and research also not used anymore in BIT. # It is my assumption that the RuntimeError will never be raised. But # let's keep it for some versions to be sure. if not isinstance(self.cmd, list): raise RuntimeError( 'Command is a string but should be a list of strings. This ' 'method is not supported anymore since version 1.5.0. The ' 'current situation is unexpected. Please open a bug report ' 'at https://github.com/bit-team/backintime/issues/new/choose ' 'or report to the projects mailing list ' '.') self.pausable = True self.printable_cmd = ' '.join(self.cmd) logger.debug(f'Call command "{self.printable_cmd}"', self.parent, 2) def run(self): """Run the command using ``subprocess.Popen``. Returns: int: Code from the command. """ ret_val = 0 out = '' try: # register signals for pause, resume and kill # Forward these signals (sent to the "backintime" process # normally) to the child process ("rsync" normally). # Note: SIGSTOP (unblockable stop) cannot be forwarded because # it cannot be caught in a signal handler! signal.signal(signal.SIGTSTP, self.pause) signal.signal(signal.SIGCONT, self.resume) signal.signal(signal.SIGHUP, self.kill) except ValueError: # signal only work in qt main thread # TODO What does this imply? pass stderr = subprocess.STDOUT if self.join_stderr else subprocess.DEVNULL logger.debug(f"Starting command '{self.printable_cmd}'") self.currentProc = subprocess.Popen( self.cmd, stdout=subprocess.PIPE, stderr=stderr) # # TEST code for developers to simulate a killed rsync process # if self.printable_cmd.startswith("rsync --recursive"): # self.currentProc.terminate() # signal 15 (SIGTERM) like "killall" and "kill" do by default # # self.currentProc.send_signal(signal.SIGHUP) # signal 1 # # self.currentProc.kill() # signal 9 # logger.error("rsync killed for testing purposes during development") if self.callback: for line in self.currentProc.stdout: if self.conv_str: line = line.decode().rstrip('\n') else: line = line.rstrip(b'\n') for f in self.filters: line = f(line) if not line: continue self.callback(line, self.user_data) # We use communicate() instead of wait() to avoid a deadlock # when stdout=PIPE and/or stderr=PIPE and the child process # generates enough output to pipe that it blocks waiting for # free buffer. See also: # https://docs.python.org/3.10/library/subprocess.html#subprocess.Popen.wait out = self.currentProc.communicate()[0] # TODO Why is "out" empty instead of containing all stdout? # Most probably because Popen was called with a PIPE as stdout # to directly process each stdout line by calling the callback... ret_val = self.currentProc.returncode # TODO ret_val is sometimes 0 instead of e.g. 23 for rsync. Why? try: # reset signal handler to their default signal.signal(signal.SIGTSTP, signal.SIG_DFL) signal.signal(signal.SIGCONT, signal.SIG_DFL) signal.signal(signal.SIGHUP, signal.SIG_DFL) except ValueError: # signal only work in qt main thread # TODO What does this imply? pass if ret_val == 0: msg = f'Command "{self.printable_cmd[:16]}" returns {ret_val}' if out: msg += ': ' + out.decode().strip('\n') logger.debug(msg, self.parent, 2) else: msg = f'Command "{self.printable_cmd}" ' \ f'returns {bcolors.WARNING}{ret_val}{bcolors.ENDC}' if out: msg += ' | ' + out.decode().strip('\n') logger.warning(msg, self.parent, 2) return ret_val def pause(self, signum, frame): """Slot which will send ``SIGSTOP`` to the command. Is connected to signal ``SIGTSTP``. """ if self.pausable and self.currentProc: logger.info( f'Pause process "{self.printable_cmd}"', self.parent, 2) return self.currentProc.send_signal(signal.SIGSTOP) def resume(self, signum, frame): """Slot which will send ``SIGCONT`` to the command. Is connected to signal ``SIGCONT``. """ if self.pausable and self.currentProc: logger.info( f'Resume process "{self.printable_cmd}"', self.parent, 2) return self.currentProc.send_signal(signal.SIGCONT) def kill(self, signum, frame): """Slot which will kill the command. Is connected to signal ``SIGHUP``. """ if self.pausable and self.currentProc: logger.info(f'Kill process "{self.printable_cmd}"', self.parent, 2) return self.currentProc.kill() backintime-1.5.4/common/uniquenessset.py000066400000000000000000000133631477034762000204240ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2010 paul # SPDX-FileCopyrightText: © 2010 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Module about UniquenessSet""" import os import logger from tools import md5sum class UniquenessSet: """Check for uniqueness or equality of file(s). Uniqueness means that there are no duplicates. Equality means that two elements have the same value or properties. Equality is checked only if a file is specified with ``equal_to`` otherwise uniqueness will be checked. The latter is based on previous file checks. The class store hashes of each file checked via ``check()`` or ``checkUnique()``. Dev note (buhtz, 2024-10): The class is used in SnapshotsDialog and only in the specific/rare case when single files are compared. The class does two different things implicit. Not sure if this is a good solution. My recommendation is to move that code/feature into 'qt' into or near the `SnapshotsDialog` class. """ def __init__(self, deep_check=False, follow_symlink=False, equal_to=''): """ Args: deep_check (bool): If ``True`` use deep check which will compare files md5sums if they are of same size but no hardlinks (don't have the same inode). If ``False`` use files size and mtime follow_symlink (bool): Check symlinks target instead of the link itself (default: ``False``). equal_to (str): Full path to file. If not empty only return equal files to the given path instead of unique files. (default: ``''``) """ self.deep_check = deep_check self.follow_sym = follow_symlink # if not self._uniq_dict[size] -> size already checked with md5sum self._uniq_dict = {} # if (size, inode) in self._size_inode -> path is a hlink self._size_inode = set() self.equal_to = equal_to if equal_to: st = os.stat(equal_to) if self.deep_check: self.reference = (st.st_size, md5sum(equal_to)) else: self.reference = (st.st_size, int(st.st_mtime)) def check(self, input_path): """Check file ``input_path`` for either uniqueness or equality (depending on ``equal_to`` from constructor). Args: input_path (str): full path to file Returns: bool: ``True`` if file is unique and ``equal_to`` is empty. Or ``True`` if file is equal to file in ``equal_to`` """ path = input_path # follow symlinks ? if self.follow_sym and os.path.islink(input_path): path = os.readlink(input_path) if self.equal_to: return self.checkEqual(path) else: return self.checkUnique(path) def checkUnique(self, path): """Check file ``path`` for uniqueness and store a unique key for ``path``. This check is performed if `equal_to` is empty. By default (``deep_check is False``) the uniqueness is based on file size and mtime. If ``deep_check is True`` the uniqueness is based on inode number and the files size (or md5sum). Args: path (str): Full path to file. Returns: bool: ``True`` if file is unique. """ logger.debug(f'{path=}') if self.deep_check: stat = os.stat(path) size, inode = stat.st_size, stat.st_ino # Hardlink? if (size, inode) in self._size_inode: logger.debug( "[deep test]: skip, it's a duplicate (size, inode)", self) return False self._size_inode.add((size, inode)) if size not in self._uniq_dict: # first item of that size unique_key = size logger.debug("[deep test]: store current size?", self) else: prev = self._uniq_dict[size] if prev: # store md5sum instead of previously stored size md5sum_prev = md5sum(prev) self._uniq_dict[md5sum_prev] = prev # remove the entry with that size self._uniq_dict[size] = None logger.debug( "[deep test]: size duplicate, remove the size, store " "prev md5sum", self) unique_key = md5sum(path) logger.debug("[deep test]: store current md5sum?", self) else: # store a tuple of (size, modification time) obj = os.stat(path) unique_key = (obj.st_size, int(obj.st_mtime)) # store if not already present, then return True if unique_key not in self._uniq_dict: logger.debug(" >> ok, store!", self) self._uniq_dict[unique_key] = path return True logger.debug(" >> skip (it's a duplicate)", self) return False def checkEqual(self, path): """Check if ``path`` is equal to the file specified by ``equal_to``. Args: path (str): Full path to file. Returns: bool: ``True`` if file is equal. """ st = os.stat(path) if self.deep_check: if self.reference[0] == st.st_size: return self.reference[1] == md5sum(path) return False else: return self.reference == (st.st_size, int(st.st_mtime)) backintime-1.5.4/common/version.py000066400000000000000000000015441477034762000171740ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Centralize management about the version. That file is a workaround until the project migrated to a Python build-system. See Issue #1575 for details about that migration. """ import re # Version string regularyly used by the application and presented to users. __version__ = '1.5.4' def is_release_candidate() -> bool: """Test if the current version is a release candidate. It is the case if the version string ends with lower case ``rc`` and optionally with a number. """ return bool(re.search(r'^.+rc\d+$', __version__)) backintime-1.5.4/create-manpage-backintime-config.py000077500000000000000000000313721477034762000224440ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # SPDX-FileCopyrightText: © 2023 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """This script is a helper to create a manpage about Back In Times's config file. The file `common/config.py` is parsed for variable names, default values and other information. The founder of that script @Germar gave a detailed description about that script in #1354. The script reads every line and tries to analyze it: - It searches for `DEFAULT` and puts those into a `dict` for later replacing the variable with the value. - If that didn't match it will look for lines starting with `#?` which is basically my own description for the manpage-entry. Multiple lines will get merged and stored in `commentline` until the processing of the current config option is done. That will reset `commentline`. - If a line starts with `#` it will be skipped. - Next the script searches for lines which ``return`` the config value (like `snapshots.ssh.port`. There it will extract the key/name (`snapshots.ssh.port`), the default value (`22`), the instance (`Int`) and if it is a profile or general value. - If the line contains a `List` value like `snapshots.include` it will process all values for the list like `snapshots.include..value` and `snapshots.include..type`. Also it will add the size like `snapshots.include.size`. In `process_line` it will replace some information with those I wrote manually in the `#?` description, separated by `;` there is the comment, value, force_default and force_var. If there is no forced value it will chose the value based on the instance with `select_values` """ import re import os import sys from time import strftime, gmtime PATH = os.path.join(os.getcwd(), 'common') CONFIG = os.path.join(PATH, 'config.py') MAN = os.path.join(PATH, 'man/C/backintime-config.1') with open(os.path.join(PATH, '../VERSION'), 'r') as f: VERSION = f.read().strip('\n') SORT = True # True = sort by alphabet; False = sort by line numbering c_list = re.compile(r'.*?self\.(?!set)((?:profile)?)(List)Value ?\( ?[\'"](.*?)[\'"], ?((?:\(.*\)|[^,]*)), ?[\'"]?([^\'",\)]*)[\'"]?') c = re.compile(r'.*?self\.(?!set)((?:profile)?)(.*?)Value ?\( ?[\'"](.*?)[\'"] ?(%?[^,]*?), ?[\'"]?([^\'",\)]*)[\'"]?') HEADER = r'''.TH backintime-config 1 "%s" "version %s" "USER COMMANDS" .SH NAME config \- BackInTime configuration files. .SH SYNOPSIS ~/.config/backintime/config .br /etc/backintime/config .SH DESCRIPTION Back In Time was developed as pure GUI program and so most functions are only usable with backintime-qt. But it is possible to use Back In Time e.g. on a headless server. You have to create the configuration file (~/.config/backintime/config) manually. Look inside /usr/share/doc/backintime\-common/examples/ for examples. .PP The configuration file has the following format: .br keyword=arguments .PP Arguments don't need to be quoted. All characters are allowed except '='. .PP Run 'backintime check-config' to verify the configfile, create the snapshot folder and crontab entries. .SH POSSIBLE KEYWORDS ''' % (strftime('%b %Y', gmtime()), VERSION) FOOTER = r'''.SH SEE ALSO backintime, backintime-qt, backintime-askpass. .PP Back In Time also has a website: https://github.com/bit-team/backintime .SH AUTHOR This manual page was written by BIT Team(). ''' INSTANCE = 'instance' NAME = 'name' VALUES = 'values' DEFAULT = 'default' COMMENT = 'comment' REFERENCE = 'reference' LINE = 'line' def groff_indented_paragraph(label: str, indent: int=6) -> str: """.IP - Indented Paragraph""" return f'.IP "{label}" {indent}' def groff_italic(text: str) -> str: """\\fi - Italic""" return f'\\fI{text}\\fR' def groff_indented_block(text: str) -> str: """ .RS - Start indented block .RE - End indented block """ return f'\n.RS\n{text}\n.RE\n' def groff_linebreak() -> str: """.br - Line break""" return '.br\n' def groff_paragraph_break() -> str: """.PP - Paragraph break""" return '.PP\n' def output(instance='', name='', values='', default='', comment='', reference='', line=0): """Generate GNU Troff (groff) markup code for the given config entry.""" if not default: default = "''" ret = f'Type: {instance.lower():<10}Allowed Values: {values}\n' ret += groff_linebreak() ret += f'{comment}\n' ret += groff_paragraph_break() if SORT: ret += f'Default: {default}' else: ret += f'Default: {default:<18} {reference} line: {line}' ret = groff_indented_block(ret) ret = groff_indented_paragraph(groff_italic(name)) + ret return ret def select(a, b): if a: return a return b def select_values(instance, values): if values: return values return { 'bool': 'true|false', 'str': 'text', 'int': '0-99999' }[instance.lower()] def process_line(d, key, profile, instance, name, var, default, commentline, values, force_var, force_default, replace_default, counter): """Parsing the config.py Python code""" # Ignore commentlines with #?! and 'config.version' comment = None if not commentline.startswith('!') and key not in d: d[key] = {} commentline = commentline.split(';') try: comment = commentline[0] values = commentline[1] force_default = commentline[2] force_var = commentline[3] except IndexError: pass if default.startswith('self.') and default[5:] in replace_default: default = replace_default[default[5:]] if isinstance(force_default, str) \ and force_default.startswith('self.') \ and force_default[5:] in replace_default: force_default = replace_default[force_default[5:]] if instance.lower() == 'bool': default = default.lower() d[key][INSTANCE] = instance d[key][NAME] = re.sub( r'%[\S]', '<%s>' % select(force_var, var).upper(), name ) d[key][VALUES] = select_values(instance, values) d[key][DEFAULT] = select(force_default, default) d[key][COMMENT] = re.sub(r'\\n', '\n.br\n', comment) d[key][REFERENCE] = 'config.py' d[key][LINE] = counter def main(): d = { 'profiles.version': { INSTANCE: 'int', NAME: 'profiles.version', VALUES: '1', DEFAULT: '1', COMMENT: 'Internal version of profiles config.', REFERENCE: 'configfile.py', LINE: 419 }, 'profiles': { INSTANCE: 'str', NAME: 'profiles', VALUES: 'int separated by colon (e.g. 1:3:4)', DEFAULT: '1', COMMENT: 'All active Profiles ( in profile.snapshots...).', REFERENCE: 'configfile.py', LINE: 472 }, 'profile.name': { INSTANCE: 'str', NAME: 'profile.name', VALUES: 'text', DEFAULT: 'Main profile', COMMENT: 'Name of this profile.', REFERENCE: 'configfile.py', LINE: 704 } } # Default variables and there values collected from config.py replace_default = {} # Variables named "CONFIG_VERSION" or with names starting with "DEFAULT" regex_default = re.compile(r'(^DEFAULT[\w]*|CONFIG_VERSION)[\s]*= (.*)') with open(CONFIG, 'r') as f: print(f'Read and parse "{CONFIG}".') commentline = '' values = force_var = force_default = instance \ = name = var = default = None for counter, line in enumerate(f, 1): line = line.lstrip() # parse for DEFAULT variable m_default = regex_default.match(line) # DEFAULT variable if m_default: replace_default[m_default.group(1)] \ = m_default.group(2) continue # Comment intended to use for the manpage if line.startswith('#?'): if commentline \ and ';' not in commentline \ and not commentline.endswith('\\n'): commentline += ' ' commentline += line.lstrip('#?').rstrip('\n') continue # Simple comments are ignored if line.startswith('#'): commentline = '' continue # e.g. "return self.profileListValue('snapshots.include', ('str:value', 'int:type'), [], profile_id)" # becomes # ('profile', 'List', 'snapshots.include', "('str:value', 'int:type')", '[]') m = c_list.match(line) if not m: # e.g. "return self.profileBoolValue('snapshots.use_checksum', False, profile_id)" # becomes # ('profile', 'Bool', 'snapshots.use_checksum', '', 'False') m = c.match(line) # Ignore undocumented (without "#?" comments) variables. if m and not commentline: continue if m: profile, instance, name, var, default = m.groups() if profile == 'profile': name = 'profile.' + name var = var.lstrip('% ') if instance.lower() == 'list': type_key = [x.strip('"\'') for x in re.findall(r'["\'].*?["\']', var)] commentline_split = commentline.split('::') for i, tk in enumerate(type_key): t, k = tk.split(':', maxsplit=1) process_line( d, key, profile, 'int', '%s.size' % name, var, r'\-1', 'Quantity of %s. entries.' % name, values, force_var, force_default, replace_default, counter) key = '%s.%s' % (name, k) key = key.lower() process_line( d, key, profile, t, '%s..%s' % (name, k), var, '', commentline_split[i], values, force_var, force_default, replace_default, counter ) else: key = re.sub(r'%[\S]', var, name).lower() process_line( d, key, profile, instance, name, var, default, commentline, values, force_var, force_default, replace_default, counter ) values = force_var = force_default = instance \ = name = var = default = None commentline = '' """ Example for content of 'd': { "profiles": { "instance": "str", "name": "profiles", "values": "int separated by colon (e.g. 1:3:4)", "default": "1", "comment": "All active Profiles ( in profile.snapshots...).", "reference": "configfile.py", "line": 472 }, "profile.name": { "instance": "str", "name": "profile.name", "values": "text", "default": "Main profile", "comment": "Name of this profile.", "reference": "configfile.py", "line": 704 } """ with open(MAN, 'w') as f: print(f'Write GNU Troff (groff) markup to "{MAN}". {SORT=}') f.write(HEADER) if SORT: # Sort by alphabet s = lambda x: x else: # Sort by line numbering (in the source file) s = lambda x: d[x][LINE] f.write('\n'.join(output(**d[key]) for key in sorted(d, key=s))) f.write(FOOTER) if __name__ == '__main__': main() backintime-1.5.4/doc/000077500000000000000000000000001477034762000144065ustar00rootroot00000000000000backintime-1.5.4/doc/ENCRYPT_TRANSITION.md000066400000000000000000000127111477034762000176300ustar00rootroot00000000000000 # Transition of the encryption feature in _Back In Time_ February 2025 This document outlines the current status of the encryption feature in _Back In Time_. Support for encrypted snapshot profiles is undergoing significant changes. **Please note** that we have a [pending PR implementing gocryptfs for local encrypted profiles](https://github.com/bit-team/backintime/pull/1897). * [Short summary](#short-summary) * [Rational](#rational) * [Alternatives to EncFS](#alternatives-to-encfs) * [Planned steps of the transition process](#planned-steps-of-the-transition-process) * [About EncFS security issues](#about-encfs-security-issues) * [Further readings and resources](#further-readings-and-resources) ## Short summary - To realize encrypted snapshots in _Back In Time_, [EncFS] is used. - EncFS has known security issues and also is no longer maintained. - EncFS **deprecation starts in year 2025**. - EncFS library will be **removed** from _Back In Time_ **around the year 2029**. This will happen in slow and small steps with sufficient advance warnings and lead time. - The plan is to replace EncFS with [GoCryptFS] as an alternative. - The current maintenance team does not have the resources to implement an alternative for EncFS. So extern contributors are need to step in. See [meta issue #1734](https://github.com/bit-team/backintime/issues/1734) about the current progress. - The replacement with an alternative happens indepeneded from from the EncFS deprecation and removal process. ## Rational Removing [EncFS] is necessary because it has known security issues, the upstream project is not active anymore and its maintainer himself recommends to replace EncFS. To keep _Back In Time_ secure and maintenable there is no alternative to deprecat EncFS in _Back In Time_ and finally remove it. The necessity to remove EncFS exists regardless of whether an alternative for this library is implemented or not. ## Alternatives to EncFS The [EncFS] maintainer himself [recommends to switch](https://github.com/vgough/encfs?tab=readme-ov-file#status) to [GoCryptFS]. It seems to work similar to EncFS. Therefore, according to the [current state of research and discussion](https://github.com/bit-team/backintime/issues/1734), GoCryptFS is the preferred choice for a solution. It was also discussed if file system encryption (e.g. [LUKS]) could be an option. In this case _Back In Time_ won't need an encryption feature anymore because the file system tools do take care of it. It might be an option for some of the affected users but [it was also shown](https://github.com/bit-team/backintime/issues/1734#issuecomment-2151875246) that file system encryption is not an option in all use cases. The project also is open for other alternative solutions. ## Planned steps of the transition process The transition is a process *not fixed* in all details and planned to take until the *year 2029 or 2030*. The project will try to adapt to users needs and other extern issues. Therefore the plan is not written in stone. The transition is scheduled around the release cycles of Debian GNU Linux because Debian has very long release cycles and is the base for most of the distributions out there. The goal is to have slow and transparent steps in a timeline of multiple years until round about the year 2029 or 2030 when Debian 15 will be released. Current stable Debian is version 12. 1. Year 2024: Clear and strong warning about the planned removing or replacement of EncFS ([#1735](https://github.com/bit-team/backintime/issues/1734)). Planned for the upcoming release 1.5.0 reaching Ubuntu 24.10 ("Oracular Oriole"). 2. After Debian 13 released (year 2025 or 2026): Disable creation of new EncFS profiles. This become "relevant" for "Debian stable" users round about year 2027/28 when Debian 14 is released. 3. After Debian 14 released (Year 2027 or 2028): Remove EncFS in upstream BIT. This will affect rolling release GNU Linux distributions (e.g. Arch) and upcoming Ubuntu releases. 4. Debian 15 in year 2029 or 2030: Our transformation then has reached Debian stable. ## About EncFS security issues - EncFS Security Audit - https://defuse.ca/audits/encfs.htm (as updated blog post) - https://sourceforge.net/p/encfs/mailman/message/31849549/ (original mailing list entry) - [EncFS#314](https://github.com/vgough/encfs/issues/314) (a **not-fixed** meta issue with a list of several open issues related to the Security Audit) - [EncFS#659](https://github.com/vgough/encfs/issues/659) - [EncFS#9](https://github.com/vgough/encfs/issues/9) - [EncFS - Ubuntu Users Wiki (German)](https://wiki.ubuntuusers.de/Archiv/EncFS) ## Further readings and resources - The meta issue [#1734](https://github.com/bit-team/backintime/issues/1734) about the transition, its current state and related steps and issues. - First discussion about deprecating EncFS was in [#1549](https://github.com/bit-team/backintime/issues/1549). - Our [mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org). - [EncFS] - [GoCryptFS] [EncFS]: https://github.com/vgough/encfs [GoCryptFS]: https://github.com/rfjakob/gocryptfs [LUKS]: https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup backintime-1.5.4/doc/README.md000066400000000000000000000044471477034762000156760ustar00rootroot00000000000000 - [Overview](#overview) - [Build user manual](#build-user-manual) - [How to reduce file size of images](#how-to-reduce-file-size-of-images) # Overview This directory contains the source files for various types of documentation for _Back In Time_. - `manual`: User Manual - `coderef`: Source Code Documentation (...coming soon...) - `maintain`: Several documents regarding mainteanance of the _Back In Time_ project and nearly all other documents not fitting to one of the other categories. # Build user manual The user manual is build from markdown files (in directory `src`) and converted into HTML (directory `html`). The tool `mkdocs` is used for this. ```sh $ cd backintime/doc/manual $ mkdocs build INFO - Cleaning site directory INFO - Building documentation to directory: XYZ INFO - Documentation built in 2.66 seconds $ ``` Open `html/index.html` to inspect the result. As an alternative `mkdocs` is able to provide a live preview of docs while editing the markdown files. A local web server is used for this. ```sh $ cd backintime/doc/manual $ mkdocs serve INFO - Building documentation... INFO - Cleaning site directory INFO - Documentation built in 1.40 seconds INFO - [10:17:21] Watching paths for changes: 'src', 'mkdocs.yml' INFO - [10:17:21] Serving on http://127.0.0.1:8000/ ``` Inspect the result in browser: [127.0.0.1:8000](http://127.0.0.1:8000). # How to reduce file size of images For PNG images `optipng` could be used. *Attention*: By default it overwrites the original files. The following command use the highest possible optimization and write the result in a subfolder. $ optipng --dir subfolder -o7 *.png As an alternative `pngcrush` can be used. The following determine the best algorithm by its own. $ pngcrush -d subfolder -brute *.png Applied to a set of _Back In Time_ dark mode screenshots, their file size was reduced by approximately 13%. Both applications show no significant differences. The visual result is indistinguishable from the original. backintime-1.5.4/doc/maintain/000077500000000000000000000000001477034762000162065ustar00rootroot00000000000000backintime-1.5.4/doc/maintain/1_doc_howto.md000066400000000000000000000071161477034762000207420ustar00rootroot00000000000000 # Organization and building of documentation for _Back In Time_ This file describes briefly how to the several types of documentation existing for _Back In Time_ (BIT), how they are maintained, structured and build. > [!TIP] > Feel free to [open issues](https://github.com/bit-team/backintime/issues) > or contact the > [maintenance team on the mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org/) > if this text is difficult to understand or not helpful. # Index - [Overview](#overview) - [Build & view user manual (MkDocs)](#build--view-user-manual-mkdocs) - [Build & view source code documentation (Sphinx)](#build--view-source-code-documentation-sphinx) - [Tips & Examples](#tips-and-examples) # Overview The project distinguish between three types of documentation: 1. The **User manual** can be found at [backintime.readthedocs.io](http://backintime.readthedocs.io) and is generated using [MkDocs](https://www.mkdocs.org) based on simple [Markdown](https://en.wikipedia.org/wiki/Markdown) files. 2. The **Source Code documentation** is located at [backintime-dev.readthedocs.io](http://backintime-dev.readthedocs.io) and generated from the Python source files using [Sphinx](https://www.sphinx-doc.org) (migration to [PyDoctor](https://pydoctor.readthedocs.io) is planned). 3. The **Maintenance and Developer documentation** is a bunch of Markdown files, like the one you are reading currently. # Build & view user manual (MkDocs) Install related dependencies: - `mkdocs` - `mkdocs-material` - See file [`CONTRIBUTING.md`](../../CONTRIBUTING.md) in this repo for a complete and up to date list of dependencies. **Live preview HTML documentation as working on it**: ```sh # Enter folder $ cd doc/manual # Start built-in server $ mkdocs serve ``` Open [127.0.0.1:8000](http://127.0.0.1:8000) in your browser. Every time the underlying markdown files are modified the server will on the fly generate new HTML. **Generate HTML files**: ```sh # Enter folder $ cd doc/manual # Build $ mkdocs build # Open result in default browser $ xdg-open html/index.html ``` # Build & view source code documentation (Sphinx) See [Using Sphinx to write and build documentation](1b_doc_sphinx_howto.md). # Tips and Examples - [Markdown](#markdown) - [Annotation boxes](#annotation-boxes--colored-highlight-boxes) ## Markdown ### Annotation boxes / Colored highlight boxes ``` markdown > [!NOTE] > Highlights information that users should take into account, even when > skimming. > [!TIP] > Optional information to help a user be more successful. > [!IMPORTANT] > Crucial information necessary for users to succeed. > [!WARNING] > Critical content demanding immediate user attention due to potential risks. > [!CAUTION] > Negative potential consequences of an action. ``` > [!NOTE] > Highlights information that users should take into account, even when > skimming. > [!TIP] > Optional information to help a user be more successful. > [!IMPORTANT] > Crucial information necessary for users to succeed. > [!WARNING] > Critical content demanding immediate user attention due to potential risks. > [!CAUTION] > Negative potential consequences of an action. September 2024 backintime-1.5.4/doc/maintain/1b_doc_sphinx_howto.md000066400000000000000000000130001477034762000224620ustar00rootroot00000000000000 # Using Sphinx to write and build documentation Feel free to [open issues](https://github.com/bit-team/backintime/issues) or contact the [maintenance team on the mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org/) if this text is difficult to understand or not helpful. This file describes briefly how to - build and view the source code "API" documentation of _Back In Time_ "common" (CLI) - add new modules to the documentation - write docstrings - known issues with documentation generation ## Index - [Background](#background) - [How to build and view the documentation](#how-to-build-and-view-the-documentation) - [How to write docstrings for Back In Time](#how-to-write-docstrings-for-back-in-time) - [How to add new modules to the documentation](#how-to-add-new-modules-to-the-documentation) - [Commonly used rst markups in the docstring](#commonly-used-rst-markups-in-the-docstring) - [Known issues with documentation generation](#known-issues-with-documentation-generation) # Background The documentation is generated automatically from the docstrings in the python source code files using [Sphinx](https://www.sphinx-doc.org/en/master/) in combination with the following Sphinx-Extensions: - [autodoc](https://www.sphinx-doc.org/en/master/man/sphinx-apidoc.html) to automatically generate rst doc files from the python docstrings. - [napoleon](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html) to convert google-style docstrings to reStructuredText `rst` format required for autodoc. - [viewcode](https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html) to create links to browse the highlighted source code. Further readings: - [Brief introduction to Sphinx for Python](https://betterprogramming.pub/auto-documenting-a-python-project-using-sphinx-8878f9ddc6e9) - [Quick reference of rst markups](https://docutils.sourceforge.io/docs/user/rst/quickref.html) # How to build and view the documentation Open a terminal, navigate to the folder `common/doc-dev` and call make html # to generate the HTML documentation make htmlOpen # to open the browser showing the generated HTML pages # How to write docstrings for _Back In Time_ _Back In Time_ uses the [Google style for docstrings](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings). Please stick to this convention. Look into documentation of [`sphinx.ext.napoleon`](https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html#example-google) for extended examples. # How to add new modules to the documentation There are two scenarios: ## Scenario A: New module files are in a separate folder (not yet included in the doc generation so far) - Add the python source code folder to the file `doc-dev/conf.py` which is the configuration. Then the `autodoc` extension is able to find the files (navigate _relative_ to the `doc-dev` folder). - Generate the initial `.rst` files for the new modules via `sphinx-apidoc`, eg. sphinx-apidoc -o ./plugins ../plugins This example will create a sub folder `doc-dev/plugins` with the `.rst` files (one for each source file) in `doc-dev/../plugins`. - Add the new modules in the sub folder to the top-most _root_ `index.rst`: # under "modules.rst" add this line add a link to new modules plugins/modules.rst ## Scenario B: The new module files are in a folder that already contains other modules contained in the doc To create the initial version of `.rst` files for new modules eg. in the `common` folder use sphinx-apidoc -o . .. _TODO_: How to remove old rst files with non-existing python files (eg. due to renaming or deletion)? Probably the -f ("force") argument could do this. Try it with -d ("dry-run")! # Commonly used rst markups in the docstring Despite using the Google docstring style rst markups can and should still be used to format text and cross-reference code. - Reference a class (with namespace if not in the same): :py:class:`pluginmanager.PluginManager` Important: Don't forget to surround the function name with back ticks otherwise Sphinx will not create a cross reference silently! - Reference a method/function: :py:func:`takeSnapshot` - Reference a module: :py:module:`datetime` - Specify the python type of an method/function argument: Add the type name (with namespace if not in the same) in parentheses """Short description... Long description... Args: cfg (config.Config): Current configuration """ - To indicate verbatim text (inline code) enclose it with two backticks each. ``True`` ``None`` ``de_DE.UTF-8`` # Known issues with documentation generation - Elements of PyQt can not be referenced. It is a [known Issue](https://riverbankcomputing.com/pipermail/pyqt/2013-March/032528.html) without an acceptable solution. Name them via verbatime text (two backticks) only. - Sphinx' ``make html`` does not recreate the html file of a sub class if only the parent class docstring was changed. _Impact_: Inherited documentation in the sub class is not up to date _Work around_: Use ``make clean`` before ``make html`` May 2024 backintime-1.5.4/doc/maintain/2_localization.md000066400000000000000000000324311477034762000214440ustar00rootroot00000000000000 # Translation and localization (l10n) of Back In Time using Weblate Feel free to [open issues](https://github.com/bit-team/backintime/issues) or contact the [maintenance team on the mailing list](https://mail.python.org/mailman3/lists/bit-dev.python.org/) if this text is difficult to understand or not helpful. ## Index - [Quick guide: Synchronize translations between Weblate and Microsoft GitHub](#quick-guide-synchronize-translations-between-weblate-and-microsoft-github-upstream-repository) - [Introducing the localization process](#introducing-the-localization-process-in-the-back-in-time-project) - [Transfer translatable strings onto Weblate platform](#transfer-translatable-strings-onto-weblate-plattform) - [Transfer back translation from Weblate into Back In Time upstream repository](#transfer-back-translation-from-weblate-into-back-in-time-upstream-repository) - [Instructions for the translation process](#instructions-for-the-translation-process) - [Setup Weblate project](#setup-weblate-project) That file **does not** describe how to use the [GNU gettext utilities](https://www.gnu.org/software/gettext/manual/html_node/index.html) to localize software. # Quick guide: Synchronize translations between Weblate and Microsoft GitHub upstream repository > [!WARNING] > Do not follow this steps if you are new to this process! Please go to the next section and start reading from there. The following steps are a quick reminder for maintainers of _Back In Time_. The goal is to synchronize the state of the ongoing translation at Weblate and the modified py-files in the upstream repository at Microsoft GitHub. 1. Press "Commit" in Weblate ["Repository maintenance"](https://translate.codeberg.org/projects/backintime/#repository). 2. "Lock" the project in Weblate ["Repository maintenance"](https://translate.codeberg.org/projects/backintime/#repository). 3. git: Start a new branch. 4. Download and integrate Weblate into the git repository via `./update_language_files.py weblate`. 5. Check via `git status` or `git diff`. The `po`-files (not `pot`!) in `common/po` and the file `common/languages.py` should be modified. 6. Commit. 7. Scan `py`-files for modified source strings via `./update_language_files.py source`. 8. Check via `git status` or `git diff`. The file `messages.pot` and all `po`-files should be modified. 9. Commit. 10. Optional: Check for redundant letters in "shortcut groups" via `./update_language_files.py shortcuts`. 11. Create PR and merge into "dev". 12. Weblate ["Repository maintenance"](https://translate.codeberg.org/projects/backintime/#repository): 1. Go to "Danger zone" and click on "Reset". 2. "Unlock" the project. # Introducing the localization process in the Back In Time project ## Some facts - A translation platform (Weblate in this case) is not for developers but for the users. It's purpose is to make it easy as possible for contributors to translate strings without knowing technical details about code, Git or GNU gettext. The platform is not part of an automatic build pipeline and does not run the GNU gettext utilities for you. - The Weblate instance on [translate.codeberg.org](https://translate.codeberg.org) do not support integration with external code hoster (state: May '23). This is not a restriction of Weblate itself but of Codeberg.org. The practical consequences are that it isn't possible to create pull request or to push directly (or automatically) from Weblate to Microsoft GitHub. This may change in the future. - The [GNU gettext](https://www.gnu.org/software/gettext/manual/html_node/index.html) system is used for localization. Strings in python files enclosed by `_(...)` are recognized as translatable. - Despite _Back In Time_ is separated into the two components `common` and `qt` the localization is not. All `po` and `pot` files are located in the folder `common/po` and used by the second component `qt` also. - All actions should doable with the script `update_language_files.py` and there is no need to directly run one of the _GNU gettext utilities_. Some technical details are documented in the mentioned script. - The current setup do not follow "modern recommendations" and may get optimized in the future. - The "compilation" of `po` files into `mo` files is a separate step not described in this document. It is part of the [install and build process](../../CONTRIBUTING.md#build--install). ## Brief description of steps in the process 1. Scan all python files (in `common` and `qt` excluding `test_*.py`) for translatable strings and store them into the _message template file_ `common/po/message.pot`. 2. Synchronize that _message template file_ with the existing translations (`common/po/*.po`). 3. Commit and push the modifications into the development branch (e.g. `dev`). 4. The Weblate platform do pull that changes from our upstream repository into its own internal repository (manual triggered by maintainers or automatically). 5. Now the contributors can translate using our [Weblate "Back In Time" project](https://translate.codeberg.org/projects/backintime/). There is also a [translation landing page](https://translate.codeberg.org/engage/backintime). 6. The translations on Weblate (as `po` files) need to be committed (manual or automatically) into the Weblate repository. 7. The `po` files with fresh translations are downloaded (via `git clone`) from the Weblate repository and copied into the BIT upstream repository. 8. Check the modifications in upstream and commit them into development or feature branch. Step 1, 2, 7 and 8 are done via `update_language_files.py` which is a wrapper for _GNU gettext utilities_ and Git tools. # Transfer translatable strings onto Weblate platform Add or modify strings to translate. In this example the string `Translate me please.` is translatable because it is enclosed by `_(...)`: ```python common/backintime.py if __name__ = '__main__': print(_('Translate me please.')) startApp() ``` Run `./update_language_file.py` with the argument `source` to scan get the new and modified strings into the _message template file_ (`common/po/messages.pot`) and also update the _language files_ (`*.po`). ``` $ ./update_language_files.py source Updating PO template file "common/po/messages.pot" ... Execute "pygettext3 --verbose --output=common/po/messages.pot common/*.py qt/*.py" Working on common/backintime.py Working on common/password.py ...snipped... Please check the result via "git diff". ``` Let's look into the modifications. The _message template file_ include the new string now as a `msgid`. ```diff diff --git a/common/po/messages.pot b/common/po/messages.pot index 6b690204..e7bab701 100644 --- a/common/po/messages.pot +++ b/common/po/messages.pot @@ -15,6 +15,10 @@ msgstr "" "Generated-By: pygettext.py 1.5\n" +#: common/backintime.py:1196 +msgid "Translate me please." +msgstr "" + #: common/config.py:95 msgid "Disabled" msgstr "" ``` All _language files_ are also update with that new string. Here the `de.po` file as an example: ```diff diff --git a/common/po/de.po b/common/po/de.po index 68dc7795..b6e07b50 100644 --- a/common/po/de.po +++ b/common/po/de.po @@ -19,6 +19,10 @@ msgstr "" "X-Generator: Weblate 4.17\n" "X-Launchpad-Export-Date: 2022-11-06 19:32+0000\n" +#: common/backintime.py:1196 +msgid "Translate me please." +msgstr "" + #: common/config.py:95 msgid "Disabled" msgstr "Deaktiviert" ``` In the end those changes need to arrive in the `dev` branch to get recognized by the Weblate translation platform. Create a Pull Request or commit/merge and push. If the project at Weblate is correctly setup it does recognize the new commit automatically and update its internal git repository. See this in _Manage_ / _Repository maintenance_ section: ![Upload to Weblate: Commits synced](_images/2_to_weblate_01.png) Looking into the list of languages there is one new (untranslated) string in _German_: ![Upload to Weblate: New string](_images/2_to_weblate_02.png) As an example the string get translated. ![Upload to Weblate: Translate](_images/2_to_weblate_03.png) Go to the next section to see how to integrate the translation back to the upstream repository. # Transfer back translation from Weblate into Back In Time upstream repository The starting situation is that some strings are translated by contributors on the Weblate platform. Go to _Manage_ / _Repository maintenance_ section. The counter for _Pending changes not yet committed to the Weblate repository_ should be 1 or more. Click on _Commit_ that counter goes back to 0 but now the _Outgoing commits in the Weblate repository_ are increased. There is also a difference between the _Last remote commit_ and _Last commit in Weblate_: ![Download from Weblate: Committed translation](_images/2_from_weblate_01.png) Go back to your local repository and run the known `update_language_files.py` script with `weblate` as argument: ```sh ./update_language_files.py weblate Execute "git clone --no-checkout https://translate.codeberg.org/git/backintime/common /tmp/tmpbbv11b11". Klone nach '/tmp/tmpbbv11b11' ... remote: Enumerating objects: 353, done. remote: Counting objects: 100% (353/353), done. remote: Compressing objects: 100% (163/163), done. remote: Total 353 (delta 177), reused 320 (delta 166), pack-reused 0 Empfange Objekte: 100% (353/353), 1.31 MiB | 5.41 MiB/s, fertig. Löse Unterschiede auf: 100% (177/177), fertig. Execute "git --git-dir /tmp/tmpbbv11b11/.git checkout dev -- common/po/*.po". Please check the result via "git diff". ``` The script downloaded the `po` files with fresh translations directly from Weblate (via `git clone`) and copied them in the local repository. In result `git diff` shows that the German language file was updated with the translation: ```diff diff --git a/common/po/de.po b/common/po/de.po index b6e07b50..f2b73be4 100644 --- a/common/po/de.po +++ b/common/po/de.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: Back In Time 0.9.5\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-05-04 16:31+0200\n" -"PO-Revision-Date: 2023-05-02 21:26+0000\n" +"PO-Revision-Date: 2023-05-04 14:59+0000\n" "Last-Translator: buhtz \n" "Language-Team: German \n" @@ -21,7 +21,7 @@ msgstr "" #: common/backintime.py:1196 msgid "Translate me please." -msgstr "" +msgstr "Übersetze mich bitte." #: common/config.py:95 msgid "Disabled" ``` Just `commit` the changes to the repository. Keep in mind: To make the translation appear in the running _Back In Time_ the `po` files need be compiled to `mo` files. This is done in the build (packaging) and install process which is described [elsewhere](../../CONTRIBUTING.md#build--install). # Instructions for the translation process See [Instructions about translation](../../CONTRIBUTING.md#instructions-about-translation). # Setup Weblate project The setup was done in 2023. This section is only for documentation of what was done at that time. For demonstration purpose in the screenshots the BIT upstream repository is not used but a fork of it. First login into [translate.codeberg.org](https://translate.codeberg.org) which is the Weblate instance hosted by [Codeberg.org](https://codeberg.org). Use the plus sign in the top right corner to _Add new translation project_. ![Weblate setup: Add new translation project](_images/2_weblate_setup_01.png) Insert the needed information's and press _Save_. ![Weblate setup: New translation project form](_images/2_weblate_setup_02.png) Weblate differentiate between _Project_ and _Component_. One project can have several components. In the first place there is no _Component_. Press _Add new translation component_. ![Weblate setup: Project without component](_images/2_weblate_setup_03.png) Insert the follow information's about the component. ![Weblate setup: Create component](_images/2_weblate_setup_04.png) Press _Continue_ and wait until Weblate has scanned the repository. Weblate do recognize the structure of the repository and the location of the relevant files. Choose the second option with _File mask_ `common/po/*.po`. ![Weblate setup: Choose translation files](_images/2_weblate_setup_05.png) Modify nothing on the next screen. Just push _Save_ and wait while _Component is being updated..._. ![Weblate setup: Component is updated](_images/2_weblate_setup_06.png) Ignore the next page _Community localization checklist_ and all the red signs on it. Everything is fine. Now looking into the _Dashboard_: ![Weblate setup: Dashboard](_images/2_weblate_setup_07.png) Clicking on the component the status of all languages is shown: ![Weblate setup: Languages](_images/2_weblate_setup_08.png) Finally a Webhook need to be setup. This enables Weblate to be automatically informed about new commits at the upstream repository. The Webhook need be installed, not on Weblate, but at the upstream repository _Settings_ at Microsoft GitHub. Just use the _Payload URL_ `https://translate.codeberg.org/hook/gitea`: ![Weblate setup: Webhook](_images/2_weblate_setup_09.png) January 2024 backintime-1.5.4/doc/maintain/3_How_to_set_up_openssh_server_for_ssh_unit_tests.md000066400000000000000000000202651477034762000307260ustar00rootroot00000000000000 # How to set up a local `openssh-server` to enable ssh unit tests - [Motivation](#motivation) - [How the unit tests access the ssh server](#how-the-unit-tests-access-the-ssh-server) - [Installation](#installation) - [Optionally configure your local firewall to restrict ssh access](#optionally-configure-your-local-firewall-to-restrict-ssh-access) - [FAQ](#faq) * [How can I temporarily disable the ssh unit tests since they consume too much time](#how-can-i-temporarily-disable-the-ssh-unit-tests-since-they-consume-too-much-time) * [How can I permanently enable or disable the ssh server (sshd)?](#how-can-i-permanently-enable-or-disable-the-ssh-server-sshd) * [How can I find out if my ssh server (sshd) is running?](#how-can-i-find-out-if-my-ssh-server-sshd-is-running) # Motivation `ssh`-based unit tests are skipped in `make test` when no local ssh server is configured and running. In order to execute also run all ssh unit tests in the `common` folder via `make test` the `openssh` server must be **installed on your local machine** and a public/private key must be set up for password-less connections. This document describes the required steps. # How the unit tests access the ssh server `ssh`-based unit tests use the [`common/test/generic.py`](https://github.com/bit-team/backintime/blob/f801b14a98f9a442008a5f514eec98e1b2d7e29a/common/test/generic.py) to check and establish a ssh connection to the ssh server via this code: https://github.com/bit-team/backintime/blob/f801b14a98f9a442008a5f514eec98e1b2d7e29a/common/test/generic.py#L43-L72 The code implements the following logic: 1. Check if a `sshd` process is running on the local machine 2. Check if a public key file `~/.ssh/id_rsa.pub` exists for the local user 3. Check if the file `~/.ssh/authorized_keys` exists (contains all public keys that are authorized to log in to the local ssh server) 4. Check if `authorized_keys` contains the public key of the local user (file `id_rsa.pub`) 5. Check that the ssh port 22 at localhost is available (= ssh server running at the standard IP port) If all checks succeed the global variable `LOCAL_SSH` is set to `True` (and this variable us used then to skip ssh-based unit tests). # Installation This installation is based on Ubuntu 20.04. If you are using another distro please consult the documentation of your distro when following this installation guide for required changes. 1. Open a terminal 1. Install openssh-server ```commandline sudo apt update sudo apt install openssh-server ``` 1. Edit the config file to make these changes ```commandline sudo nano /etc/ssh/sshd_config ``` Disable root login by changing this property to: ``` PermitRootLogin no ``` 1. Restart the `sshd` ```commandline sudo systemctl restart sshd ``` 1. Authorize sshd logins with a public/private key pair Check if you already have a key pair: ``` ls -l ~/.ssh/id_* ``` If no `id_rsa` or `id_ed25519` file exists create a new public/private key: ```commandline # Generate RSA key ssh-keygen -t rsa -b 4096 # saves in ~/.ssh/id_rsa and id_rsa.pub by default # OR generate ed25519 key ssh-keygen -t ed25519 # saves in ~/.ssh/id_ed25519 and id_ed25519.pub by default # Enter and a remember a passphrase to protect your private key! ``` Now authorize the public key via adding it to the server's `autorized_keys` file. This can be done with your first connection to the server (via `$ ssh localhost`) and type in your password. Or it can be done manually by the following commands: ```commandline # If you have id_rsa.pub: cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # OR if you have id_ed25519.pub cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys ``` 1. Run the BIT unit tests to check if ssh tests do work now ```commandline cd common make test ``` You shouldn't see skipped ssh tests now (indicated with an "s" instead of a dot). # Optionally configure your local firewall to restrict ssh access **_WARNING_: Do (re)configure and enable your firewall only if you are sure you know exactly what you are doing. Otherwise you can lock your computer from any network and internet access and as worst-case even the IP-based communication to your daemon processes!** If you have installed a firewall like `ufw` you can check the current settings with ```commandline $ sudo ufw status verbose Status: inactive # Activate the firewall (if shown as "inactive") $ sudo ufw enable Firewall is active and enabled on system startup ``` To restrict logins on your `openssh` server to addresses from your local network you first have to find out your IP address and add the restricted IP address range to the allowed connections: ```commandline # show IP address of your computer ip addr show # Allow the IP range of your local network (of the correct network adapter) sudo ufw allow from 192.168.178.12/24 to any port 22 # Check the firewall status $ sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), deny (routed) New profiles: skip To Action From -- ------ ---- 22/tcp ALLOW IN Anywhere 22 ALLOW IN 192.168.178.0/24 22/tcp (v6) ALLOW IN Anywhere (v6) # Disallow ssh access to port 22 for everyone else now... # Show active firewall rules: $ sudo ufw status numbered Status: active To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN Anywhere [ 2] 22 ALLOW IN 192.168.178.0/24 [ 3] 22/tcp (v6) ALLOW IN Anywhere (v6) # Delete the rule which allows Port 22 access for everyone "from anywhere" (here: Rule #1) sudo ufw delete 1 # Show remaining rules to determine IP6 rule to be deleted too $ sudo ufw status numbered Status: active To Action From -- ------ ---- [ 1] 22 ALLOW IN 192.168.178.0/24 [ 2] 22/tcp (v6) ALLOW IN Anywhere (v6) # Delete rule #2 which allows port 22 access (IPv6) from anywhere: sudo ufw delete 2 # Now check if the remaining rule(s) are plausible: $ sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), deny (routed) New profiles: skip To Action From -- ------ ---- 22 ALLOW IN 192.168.178.0/24 ``` Finally run the unit tests again to make sure the firewall is working correctly (= not blocking ssh traffic to localhost): ```commandline cd common make test ``` # FAQ ## How can I temporarily disable the ssh unit tests since they consume too much time Just kill the sshd process (works until you restart your computer): ```commandline # Find the process number of the sshd daemon $ ps aux | grep -i sshd root 202345 0.0 0.0 12184 7076 ? Ss 23:25 0:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups # Kill the daemon ;-) sudo kill 202345 ``` ## How can I permanently enable or disable the ssh server (sshd)? To disable the `sshd` even when you reboot use: ```commandline sudo systemctl disable sshd.service # Requires a restart or killing the sshd process to become effective ``` To enable the `sshd` when booting use: ``` # no typo, the service is named without a "d" !!! # See also: https://askubuntu.com/questions/978852/enabling-and-disabling-sshd-at-boot-via-systemd sudo systemctl enable ssh.service # Restart sshd now to avoid a reboot sudo systemctl restart sshd ``` ## How can I find out if my ssh server (sshd) is running? ```commandline sudo systemctl status sshd ``` backintime-1.5.4/doc/maintain/4_Control_files_usage_(locks_flocks_logs_and_others).md000066400000000000000000001040641477034762000310550ustar00rootroot00000000000000 # Usage of control files in _Back In Time_ (developer documentation) Table of contents: * [TLDR ;-)](#tldr--) * [_Back In Time_ commands that use lock files](#back-in-time-commands-that-use-lock-files) + [`backup`](#backup) + [`restore`](#restore) + [`shutdown`](#shutdown) * [List of known control files](#list-of-known-control-files) + [GUI (application) lock files (`app.lock.pid`)](#gui-application-lock-files-applockpid) + [Global flock file `/tmp/backintime.lock`](#global-flock-file-tmpbackintimelock) + [Backup lock files (`worker.lock.flock`)](#backup-lock-files-workerprofile-idlockflock) + [Backup progress file (`worker.progress`)](#backup-progress-file-workerpidprogress) + [`takesnapshot_.log`](#takesnapshot_profile-idlog) + [`restore_.log`](#restore_profile-idlog) + [Raise file (`app.lock.raise`)](#raise-file-applockraise) + [`save_to_continue` flag file in new snapshots](#save_to_continue-flag-file-in-new-snapshots) + [Restore lock file (`restore.lock`)](#restore-lock-file-restoreprofile-idlock) * [See also](#see-also) + [_Back in Time_ FAQ](#back-in-time-faq) + [Linux advisory locks](#linux-advisory-locks) Notes: - The logic is based on the the source code of [_Back In Time_ v1.4.1](https://github.com/bit-team/backintime/releases/tag/v1.4.1) and all source code references point to v1.4.1. The code may look differently and even the logic may have been changed in later versions. - Tables in this markdown file are generated using https://www.tablesgenerator.com/markdown_tables with `Line breaks as "br"` enabled. - Whenever `` is mentioned it means the profile number of the configuration. **For the profile ID 1 no number is used but an empty string** (why this confusing exception is made is unclear). ## TLDR ;-) _Back In Time_ uses control files to prevent that multiple instances work in parallel and conflicts may occur (eg. taking a snapshot for the same profile in two different processes). The most important control file is `worker.lock` which is used to avoid starting the same backup twice in parallel. The `` is empty for the default profile (1). It also uses another exclusively locked file named `worker.lock.flock` to serialize the access of checking for another running backup of _Back In Time_. _Back In Time_ does only start a new backup job (for the same profile) if the control file does not exist. Lock files are stored by default in the folder `~/.local/share/backintime` and contain the process id (also known as PID - see `man ps`) and process name of the running backup process. The PID is used [to check if the process that created the lock file is still running](https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/applicationinstance.py#L78-L79) and delete or overwrite the lock file with a new instance. ## _Back In Time_ commands that use lock files ### `backup` Takes a snapshot after checking that no other snapshot or restore is running at the same time: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L713-L729 If a snapshot or restore is running a warning (not an error!) is issued and **no** new snapshot is taken! Another control file named `worker.lock.flock` is used to serialize access to the `worker*.lock` file **before** a new one is created (via a “flock” = blocking advisory lock on the file). https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/applicationinstance.py#L47-L48 This table shows the control file focused execution sequence of the [`snapshots.py#backup()` function](https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L680): | Step | worker.lock.flock | worker.lock | restore.lock.flock | restore.lock | /tmp/backintime.lock | Other actions | Relevant code snippets | |------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | | Control file to serialize access to the `worker*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running backup | Control file to serialize access to the `restore*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running restore | Global control file to prevent running backups or restores on multiple snapshots from different profiles or users at the same time (only if `global.use_flock` option is `True` in config) | Executed logic not related to lock files | Taken from the source code of BiT v1.4.1 | | 1 | Create file and set flock | | | | | | instance = ApplicationInstance(self.config.takeSnapshotInstanceFile(), False, flock = True) | | 2 | | | | | | | restore_instance = ApplicationInstance(self.config.restoreInstanceFile(), False) | | 3 | | Check if exists:
→ Yes: Exit without taking a snapshot | | | | | instance.check() == not True? | | 4 | | | | Check if exists:
-> Yes: Exit without taking a snapshot | | | restore_instance.check() == not True? | | 5 | | Create file | | | | | instance.startApplication() | | 6 | Release flock and delete file | | | | | | self.flockUnlock() # within startApplication() | | 7 | | | | | Create file and set flock | | self.flockExclusive() # global flock to block backups from other profiles or users (and run them serialized) | | 8 | | | | | | Take the snapshot using rsync | self.takeSnapshot(sid, now, include_folders) | | 9 | | | | | | Perform user-callback calls | In case of errors call eg.
self.config.PLUGIN_MANAGER.error(5, msg) # no snapshot and errors
self.config.PLUGIN_MANAGER.error(6, sid.displayID) # snapshot with errors
If a new snapshot was taken (complete or incomplete due to errors):
self.config.PLUGIN_MANAGER.newSnapshot(sid, sid.path()) #new snapshot (if taken)
Finally:
self.config.PLUGIN_MANAGER.processEnd() | | 10 | | Delete file | | | | | instance.exitApplication() | | 11 | | | | | Release flock and delete file | | self.flockRelease() | ### `restore` Before restoring one or more files from a snapshot _Back In Time_ checks if a restore is already running (using the restore lock file `restore.lock`) and exits with a warning (**not an error!**). This table shows the control file focused execution sequence of the [`snapshots.py#restore()` function](https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L416: | Step | worker.lock.flock | worker.lock | restore.lock.flock | restore.lock | /tmp/backintime.lock | Other actions | Relevant code snippets | |------|------------------------------------------------------------------------------------------------------------------|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|-------------------------------------------------------------------------------------------------------| | | Control file to serialize access to the `worker*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running backup | Control file to serialize access to the `restore*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running restore | Global control file to prevent running backups or restores on multiple snapshots from different profiles or users at the same time (only if `global.use_flock` option is `True` in config) | Executed logic not related to lock files | Taken from the source code of BiT v1.4.1 | | 1 | | | Create file and set flock | | | | instance = ApplicationInstance(pidFile=self.config.restoreInstanceFile(), autoExit=False, flock=True) | | 2 | | | | Check if exists:
→ Yes: Exit without restoring the snapshot | | | instance.check() == not True? | | 3 | | | | Create file | | | instance.startApplication() | | 4 | | | Release flock and delete file | | | | self.flockUnlock() # within startApplication() | | 5 | | | | | | Restore the snapshot using rsync | proc = tools.Execute(cmd […] | | 6 | | | | Delete file | | | instance.exitApplication() | ### `shutdown` This command shuts down the computer after the current snapshot has finished. It polls the worker lock file to recognize running backups. It is implemented in the function `backintime.py#shutdown()`: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/backintime.py#L805-L819 This table shows the control file focused execution sequence of the function: | Step | worker.lock.flock | worker.lock | restore.lock.flock | restore.lock | /tmp/backintime.lock | Other actions | Relevant code snippets | |------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|-----------------------------------------------------------------------------------------------------| | | Control file to serialize access to the `worker*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running backup | Control file to serialize access to the `restore*.lock` file (via a “flock” = blocking advisory lock on the file) | Control file to indicate a running restore | Global control file to prevent running backups or restores on multiple snapshots from different profiles or users at the same time (only if `global.use_flock` option is `True` in config) | Executed logic not related to lock files | Taken from the source code of BiT v1.4.1 | | 1 | | | | | | Prepare lock file checking (without using a flock file) | instance = ApplicationInstance(cfg.takeSnapshotInstanceFile() | | 2 | | Check if exists:
→ No: Exit (no active snapshot) | | | | | if not instance.busy(): logger.info('There is no active snapshot for profile %s. Skip shutdown.' | | 3 | | Check if exists:
→ Yes: Wait 5 seconds and check again | | | | | while instance.busy(): logger.debug('Snapshot is still active. Wait for shutdown.') sleep(5) | | 4 | | | | | | shutdown computer | sd.shutdown() | ## List of known control files ### GUI (application) lock files (`app.lock.pid`) An **application lock file** named `app.lock.pid` is used for the _Back In Time_ application (GUI) to avoid starting more than one instance of the application (GUI) for the same user. The name and path of the application lock file is defined in two locations (which should be refactored into one single place). Path and base file name in `config.py#appInstanceFile()`: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/config.py#L1369-L1370 The file extension `.pid` is added in `guiapplicationinstance.py#__init__()`: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/guiapplicationinstance.py#L35 ### Global flock file `/tmp/backintime.lock` You can prevent taking multiple snapshots from different profiles or users to be run at the same time. BiT has a global configuration option for that named `global.use_flock` (see `man backintime-config`) which can also be set in the GUI in the `Options` tab of the `Manage profiles` dialog. It is named `Run only one snapshot at a time`. Other snapshots will be blocked until the current snapshot is done. This is a global option. So it will affect all profiles **for this user**. But you need to activate this for every other user too if you want enable this option for all users. Technically a global flock file ("flock") `/tmp/backintime.lock` is created (with an advisory lock to serialize access): https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/config.py#L1356-L1358 ### Backup lock files (`worker.lock.flock`) The name and path of the worker process lock file for running snapshots is defined in `config.py#takeSnapshotInstanceFile()`: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/config.py#L1388-L1391 Only for the default profile ID (1) no number is used resulting in `worker.lock` (why this confusing exception is made is unclear): https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/config.py#L1372-L1377 ### Backup progress file (`worker.progress`) _Back In Time_ starts `rsync` as separate process. To read the progress, errors and results of `rsync` a `worker.progress' file is used (written by `rsync` and read + filtered by _Back In Time_): https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L858 ### `takesnapshot_.log` TODO ### `restore_.log` TODO ### Raise file (`app.lock.raise`) TODO (what is the purpose of this?) Defined: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/guiapplicationinstance.py#L32-L33 Called via timer: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/qt/app.py#L389-L393 RaiseCMD passed in the main() entry point: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/qt/app.py#L1979 ### `save_to_continue` flag file in new snapshots This flag file is set for new snapshots initially. https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L2749-L2763 In `snapshots.py#takeSnapshot()` it is then decided if the existing snapshot can be used to "continue" taking a snapshot or to delete the contained files and restart taking the snapshot: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/snapshots.py#L1140-L1166 TODO How exactly does this work? Could we use this to implement a "retry" feature for failed snapshots? ### Restore lock file (`restore.lock`) The name and path of the restore process lock file `restore.lock` for running restores is defined in `config.py#restoreInstanceFile()`: https://github.com/bit-team/backintime/blob/25c2115b42904ec4a4aee5ba1d73bd97cb5d8b31/common/config.py#L1444-L1447 The flock file to serialize write access to the lock file (via a blocking advisory lock on the file) is different from the backup flock file: `restore.lock.flock` ## See also ### _Back in Time_ FAQ The [FAQ](https://github.com/bit-team/backintime/blob/dev/FAQ.md) gives answers for some problems caused by lock files. ### Linux advisory locks See `man 2 fcntl` and https://linuxhandbook.com/file-locking/ > 1. Advisory Locking > > The advisory locking system will not force the forces and will only work if both processes are participating in locking. > For example, process A acquires the lock and starts given tasks with a file. > And if process B starts without acquiring a lock, it can interrupt the ongoing task with process A. > So the condition for making an advisory lock is to ensure each process participates in locking. > the flock command which allows users to handle tasks related to advisory locking backintime-1.5.4/doc/maintain/BiT_release_process.md000066400000000000000000000316561477034762000224570ustar00rootroot00000000000000 # How to prepare and publish a new BIT release February 2025 ## Overview A release is prepared like a feature by using a "feature" branch and sending a pull request asking for a review. - Source branch: `dev` - Target branch for the pull request: `dev` ## Table of content - [Preconditions for a new release](#preconditions-for-a-new-release) - [TLDR ;-)](#tldr--) - [Step by step](#step-by-step) * [Create branch for release candidate](#create-branch-for-release-candidate) * [Bump version number](#bump-version-number) * [Testing & Miscellaneous](#testing--miscellaneous) * [Release Candidate](#release-candidate) * [Create Release](#create-release) * [Prepare new development version](#prepare-new-development-version) - [Manual testing - Recommendations](#manual-testing---recommendations) - [Other noteworthy things](#other-noteworthy-things) * ["Read the docs" code documentation](#read-the-docs-code-documentation) * [Building `deb` package files](#building-deb-package-files) ## Preconditions for a new release - Developers agreed on the new version number. - Most-recent translations were merged into `dev` branch. See the [localization documentation](2_localization.md). - Full CI build pipeline matrix is activate (see [#1529](https://github.com/bit-team/backintime/issues/1529)). This is related to the Python versions and also to the Ubuntu Distro versions. - `dev` version was tested (CLI in `common` and GUI in `qt`) and testers/developers agreed on "readiness to be released". - Consider publishing a release candidate before a full release. ## TLDR ;-) - Make sure we have sufficient _Credits_ to run _TravisCI_. Otherwise contact their support and kindly ask for new OSS credits. - Create a new branch (e.g. `rc/v1.5.4`) in your clone for the new release (candidate). - Update `VERSION` file. - Update `CHANGES` file. - Execute the script `./updateversion.sh` to update the version numbers (based on `VERSION` file) in several files. - Update the "as at" date in the man page files `backintime.1` and `backintime-askpass.1`. - Autogenerate and update the man page file `backintime-config.1` by executing the script `common/create-manapge-backintime-config.py`. - Validate the content of the created man page. For example compared it to a previous version of the man page. - Create a plain text file from the man pages: `man | col -b > man.plain.txt` - Use `git diff` (or another diff tool) to compare them and see if the content is as expected. - Update `README.md` file. - Build user manual: - Navigate to `./doc/manual`. - Run `mkdocs build`. - Run `codespell` to check for common spelling errors. - Commit the changes. - Open a new pull request (PR) for review by other developers. Before the PR is merged: - Create a new tar archive (eg. `backintime-1.4.0.tar.gz`) with `./make-tarball.sh`. - Test the tar archive. - Merge. After the PR is merged: - Create a new release in Github (attaching above tar archive). - Update `VERSION` and `CHANGES` for the `dev` branch. ## Step by step ### Create branch for release candidate - Announce code freeze on `dev` branch to all active developers via email. - Check that [Travis CI](https://app.travis-ci.com/github/bit-team/backintime) did successfully build the latest `dev` branch commit. - Pull latest `dev` branch changes into your BIT repo clone's `dev` branch: ``` git switch dev git pull upstream dev ``` - Create a release candidate branch in your clone using the new version number: ``` git checkout -b rc/v1.4.0 ``` - Enable the full build matrix in Travis CI (Python version * arch[icture]) by commenting the excluded architectures: ``` jobs: # exclude: # - python: "3.9" # - python: "3.10" ``` - Build the still unchanged release candidate and execute the unit tests: ``` cd common ./configure make make test cd ../qt ./configure make ``` ### Bump version number - Update the changelog file `CHANGES` in the project's root folder: - Check the commit history about forgotten but relevant entries that are currently not present in `CHANGES` file. e.g. `git log v1.4.0..HEAD` - Rename the top-most line with the collected `dev` changes from eg. `Version 1.3.4-dev (development of upcoming release)` into `Version 1.4.0 (2023-09-14)` using the new version number and release date. - Update `VERSION` text file in the project's root folder and set the new version number **without** the release date (eg. `1.4.0`). - Execute the script `./updateversion.sh` in the project's root folder to automatically update the version number in multiple files using the version number from the `VERSION` file (so you do not forget to update one file ;-). The script should modify the following files: - `common/version.py` - `common/man/C/backintime*.1` - `qt/man/C/backintime*.1` - Check that the version numbers have been update by opening some of the above files. - Update the "as at" date in the man page files (in `common/man/C/backintime*.1` and `qt/man/C/backintime*.1`) manually by changing the month and year in the first line that looks like this: ``` .TH backintime-config 1 "Aug 2023" "version 1.4.0" "USER COMMANDS" ``` - Update the `AUTHORS` file in the project's root folder if necessary. Do not publish contributors names and email address without their permission. ### Testing & Miscellaneous - Review and update the `README.md` in your release candidate branch - Update the **Known Problems and Workarounds** section: - Move fixed major known problems from the "Known Problems and Workarounds" section (which describes the latest release) into the "Problems in Versions older than the latest stable release" to stay visible for users of older versions. - Remove old known problems if you are sure old BIT versions with this issue are unlikely to be used "in the wild" anymore. - Update table of contents (TOC) for the changed parts. You can eg. use https://derlin.github.io/bitdowntoc/ to generate a TOC and copy the changed parts into the `README.md`. - Build, install and [test (again!)](#manual-testing---recommendations) the prepared release candidate. - Run [`codespell`](https://pypi.org/project/codespell) in the repositories root folder to check for common spelling errors. - Do a [manual smoke and UAT ("user acceptance test")](#manual-testing---recommendations) of the GUI. Create snapshot profiles in all (four) available flavors. Create snapshots. Restore snapshots. Delete snapshots. - Did you really perform the previous [test](#manual-testing---recommendations)? Don't dodge the question! :D - If you find bugs: - Open an issue. - Decide if you want to fix this in the release candidate: - If yes: Fix it in the release candidate: Update the `CHANGES` file (add the issue number + description). - If no: Don't fix it (eg. too risky) but add the bug to the [Known Problems and Workarounds](https://github.com/bit-team/backintime#known-problems-and-workarounds) section of `README.md` (of the release candidate branch) and describe a workaround (if any). ### Release Candidate - Commit and push, if no "show-stopping" bug exists. Note: To push your release candidate branch into a new remote branch use: ``` git push --set-upstream origin # eg. rc/v1.4.0 ``` - Open a new pull request for your pushed release candidate branch: - Add all developers as reviewers. - Mention bugs (and status) discovered during preparation of the release candidate in the description. - Create the tarball (see next section) and test it **before** merging. - Fix review findings and push the changes again to update the pull request. - Finally check the Travis CI status of the pull request (everything must be green). - Once all the PR reviewer approved the PR do a squash-merge into the `dev` branch using a commit message like `Release candidate for v1.4.1 (Oct. 1, 2023)`. - Wait for the final Travis CI build on the `dev` branch and check if everything is OK to proceed with the release. ### Create Release - Create the tarball archive files to be attached as "binaries" to the release: - Update the `dev` branch ``` git switch dev git pull upstream dev ``` - Create a new tar archive (eg. `backintime-1.4.0.tar.gz`) with `./make-tarball.sh`: The script will `git clone` the current branch into a folder `../backintime-$VERSION` and then make a tar archive file from it. - Test this tarball via installing it, e.g. on a virtual machine. - Create a new release in Github (`Releases` button under `code`): - Tag in `dev` branch with version number, eg.: `v1.4.0` (don't forget the prefix `v`) - Release title eg.: _Back In Time 1.4.0 (Sept. 14, 2023)_ - Description: `# Changelog` + the relevant (not necessary all) parts of the `CHANGES` file. - Don't forget to mention and honer the exter contributors if there are any. - Check `Set as the latest release`. - Attach binaries: Upload the generated tar archive (eg. `backintime-1.4.0.tar.gz`). - Click on the "Publish release" button ### Prepare new development version - Start a new dev version by preparing a new PR ``` git switch dev git pull upstream git checkout -b PR/v1.4.1-dev # use a new minor version number ``` - Increment the version number for the new dev version: - Update the `VERSION` text file in the project's root folder. Set the new version number by incrementing the last number and appending `-dev` (eg. `1.4.1-dev`). - Execute `./updateversion.sh` in the project's root folder to automatically update the version number in files. - Update the `CHANGES` text file in the project's root folder. Add a new top-most line with the new version number, eg.: `Version 1.4.1-dev (development of upcoming release)` - Edit `.travis.yml` to reduce the build matrix again (to save "build credits"). e.g. re-enable the exclusion list: ``` jobs: exclude: - python: "3.9" - python: "3.10" ``` - Check the "Known Problems and Workarounds" section of the `README.md` and make sure it is up-to-date. - Commit and push the changes. Create a new pull request with commit and PR message like `Start of new dev version v1.4.1-dev`. - Optional: Request PR approval - After approval or creative cool down squash-merge the PR into the `dev` branch. - Send an email to all developers - to announce "end of code freeze" - send a link to the github release - inform about unexpected (open) problems (if any) - (Out of scope here): Update the Github milestones and the assigned issues ## Manual testing - Recommendations Automatic tests won't cover all scenarios and possible problems. There is a high need to run _Back In Time_ and perform several actions to make sure it works as expected. The following list suggests several actions and scenarios. - If available, prefer installing from the source tarball over the git repository. - Use a fresh and clean virtual machine without a previous version of _Back In Time_ installed. - GNU/Linux distribution: Both major lines _Debian GNU/Linux_ and _Arch Linux_ or distros based on them. Additionally use a none-systemd distro like _Devuan GNU/Linux_. - Run _Back In Time_ and perform the following actions as user and as root. - Always start from terminal to catch silent errors and warnings. - Create snapshot profils in all available flavors (Local, SSH, with and without encryption). - Run the snapshots. - Restore snapshots. - Delete snapshots. - Schedule the snapshots using regular cron (e.g. _Every 5 minutes_) and anacron-like cron (_Repeatedly (anacran)_). Additionally schedule with udev (_When drive gets connected (udev)_). ## Other noteworthy things ### Gather author information from git repository List all (commit) authors since the last version (tag `1.5.2` in this example): git log v1.5.2..HEAD --format='%an' | sort | uniq Show log entries of a specific author since the last release: git log v1.5.2..HEAD --author="buhtz" Show `diff` of log entries of a specific author since the last release: git log v1.5.2..HEAD --author="buhtz" -p Show `diff` of a specific commit compared to its previous commit: git diff ^ ### "Read the docs" code documentation The "Read the docs" site is automatically updated with every commit on the `dev` branch. See [Issue #1533](https://github.com/bit-team/backintime/pull/1533#issuecomment-1720897669) and the [_backintime-dev_project](https://readthedocs.org/projects/backintime-dev) at Read The docs. backintime-1.5.4/doc/maintain/README.md000066400000000000000000000016121477034762000174650ustar00rootroot00000000000000 # Documentation for Maintainers and Developers - [Organization and building of documentation for _Back In Time_](1_doc_howto.md) - [(out-dated) Build documentation with Sphinx](1b_doc_sphinx_howto.md) - [Localization and translation using Weblate](2_localization.md) - [How to setup openssh for unit tests](3_How_to_set_up_openssh_server_for_ssh_unit_tests.md) - [Usage of control files (locks, flocks, logs and others)](4_Control_files_usage_(locks_flocks_logs_and_others).md) - [How to prepare and publish a new BiT release](BiT_release_process.md) Sept 2024 backintime-1.5.4/doc/maintain/_images/000077500000000000000000000000001477034762000176125ustar00rootroot00000000000000backintime-1.5.4/doc/maintain/_images/2_from_weblate_01.png000066400000000000000000003022111477034762000235060ustar00rootroot00000000000000PNG  IHDRt-*sRGBgAMA a pHYsMMgIDATxXYY;{{wXv&n$Dp'X`B@!.D !G"Þ5Kj`r "۝R_p.)/;G`r F|"x|<_E݀%?K1x#\I.FB% \\\r r r r r r %%% h\'H?ׅ69;B¶D1BPo^+ :H&` A"u&B$5<[y;mE~쏼^\HT: 9F.;oV#H]cW޹+)#~Km ߡj[7qAH@DJqߏ>o-|[돱{Lt7-P-ߡVT"3Eٹ5h[ei\ɒXS.p9Lub_{+n'Sr+o ~STVdzg?P.W'jFYjcM`WY|'r `Eu9g ${ϯW3So`VZFcrP b||f?E _ļ{u}均3G 9)}=Vqm<%~G?]>r'4T^!oy|)gSk@6;Pͩd;SlǸz3nlW4/{Ɇ5s=E]oCT^_./?)B:D ;z N003bIf'ʻ:dGZ'LN\dtfwFZ&[_i1>3 n:0;CXc1rrʚحkOSNtJnڎ'K/l=<ͩg*jǞkJjx.ˋCE9%Ëu~EϮWi r.s3$ta^nuț]4"7AdMSssq(oq ;|]^fVa%Gq1dm+|eBvR2oxEiLORPF{Їr_**~qrdFDv=?i)(~ܒKrdpP?+XK'Mk(;gӧ򳋪Hwi%F4.nLqFړ73W/5;9;CxsXligmvv\;O[D8a'"{-O7}?;^J{ z_m)F!ѷ}boiK~B$<3S<|"`CXRC*/)o`UˠqtV;,U##v|(Q4XuQQ)p플ʝeOVvD QIi)IVs t22Dj_>DtܙJcCzu㐘G."O[(J u@j,1||#|G}eT+"($!%lpJۛn!g{+?q {8ZȳDGĥ%6 z.F_Wv$2c9"t3%n+",*udמC:wߴ1s2-j:'d;R31 ²6VRihZP s<,*!66Ჺ 0#_%\URoy;ȥV7W]?;(L?56 |hrZ֎Myȡg[+Q]bTgk T8 IȈJnat| ZGWtCK1ſo?⿩IY=w9MO߸ly`߈hnx guo!Po2L."#HEY9FCT3dD!Sظ gm~Q^꓆IK@%qY9N9k'_V?yefr"^jϿ6Kȭ> &|vβ}=ZYH(R%$K, %{!f-ۏ_Vu3[U!6∼*جO\jClAlcf 0H)AlwMdX"x\E7l2ߝlۯ mIb~ 쁛։1tO8Qo|WrTâ9$MRЈ:V,HE?΋3Knע~UǤ͍驖B>}_<[~{jlOz&Id`fdtq{`} e|}c(EH@:߽ NYv(TN@UվRCCCccc###L&.)cnNq]5BnrvxfKQ_‪ { k-쮒m[Ds/)}Xթ o턶Yst}[={uA|hV/L&r>d";f6gc8VFC#7Q)T9w?E"}%xTXTEd|~[,u+*TVyأ2"*zm~^L<6vi9Z:c݂@eS2NImߣ=e&}xH߱wNt%O"D'r G/!ޔ;t8"U7y/8/gHg X\xHاW,y[ #V}%S`/"LrW:s:y!#ψP/#!esqI?:`rL]zJnMf\TcRz?MKd$Ϸ=9p}$A[ج'Z ~yD [~!!+1qVGJC̄'3Yf7fh6꘩b/5I i;g7ە9Y)vbM|\N՟%."u5"nӭ^>ٸX~Oy 墧3Ąm9nU/w o9Д|Z_6$+855g޽?wttDl e!A>w3Y_P\.#4HRpcȵظXw]RW,BYyA3zlbb}vرm۶eMکlc]G tο&p<ɏx^\:K +[E#%]v!/rIEk'mȱ?7ؼ9"rȟ4o=҉igi/pv)~ Xrn+"U]X)?sXdepnuKqu ~K'lzr|gHK#_TIE%;N8\dX':4މYjk$ʧ9R{{X5w?>6>!6 .[/]ؤܖ-[Yx >O\B}?yymeg{Cc|e laJd E29s}u!Wnx=6dE n+f^Ujt,[VZb>=_CoY dKsY&v?Zoփ׮2_^AQo=ƾ5yJ[_/v?l򮁤nBQAN4V8^WSQZ^]28 :4Z 䓳!Y*r9Ò^ʚ*ʫjڦ<)VLb{onwI[M|Mn]ܥh;Ar#3\"rYz|9hiEr}r[۸:8,PɳUYWQQY^U܇#΢I=|Nnr-g>2q OH<\j:ej遫w[K1QN ڬ!K qϒ>F7+\sjrRLNEUN\0`]!r)*dɹd1 v%+83$NFWD&vK;nn}\I. R/.R~ӊҪڦYtOa`?w=a+mP8p@DDl瞫b"ryB'SG83Lv_l9ѱ WE쇿_?~YA7o~r-i]<i)Vsc K]oh8r7RAwXRvOzx5pDVo|E;o8"].{#伞8sqƒN/>H/8sW$˽GM)TqH@*rmckmX ,G+j=. ?}L\Jodf5KZSSQVUW]:&;33eXX nB N1E =W|Jo'^A}s&kއ "ܖY㕺/zu]555f\T斍&Ҥ>E^o?`[@o*7cJaѾfree,~)Gw!\ܐU(=-^x;16jsT?=l*ڑr', Zz^"}:gGt-yXKa)+O? هʼ_$d ?Ѐ}x!{+lN .iMW}k{|?"r^!G _E Ò'Y#ϜErDy_O)w lc6ffe޲#GKfv55%F;ooxdNr,("j'On;a}m׏ m\L0Wet∈YGgk]RMr?яCJX!DekYqIA%=K z؋ҙx=7>ч_ڷG]p:$"fQ'{UԹ3^F M% 8ީx]8ktJ*:qQ3m ϯe`sN2$ )h5C,$]Dwwa+;ixP"(9?G,=Mm룂_.<'+uo|82i#4n9+еpvV*BhOπ;nd|=d{ 8msO,g_ ?(ifw= 9/gKEI?A/e!V >q+Bƫ"{D>]Ep':â7r j;{5yznr]#EαrIKXj5>yve#!u˚Um<\Ν B\EMƙ;<:%-Z|q"}ZhSԅӨ\<%xLK/Nv _DeJYY$.L O[@qm*~ ?lRW;~CunrI߾_E[>Q=JdIQ{(Xan^uS{+[S= mh iӑwAQMs7{np8;[8,nKK}^C7o8&yvb;hsݟ0݌T¢ܼzWK5v%済IxDj%rtW5rmyu{J˸u-A(Se&W|'ΖYvQLw|:}m\gs_qa. 7VUOKk&Ič55u̓7+9*w*ڊޱEΝ`o[w,{jOkk[;imݜY&Nv̰ of PM2XQR=v|cƞWW4?$$+}5e5-#­SkʟSq3}Csѝ0384RTӪʊ1 z&n<y}q{g411FhgsB<6~MN>)/-olRshkBm{u bYΎaTVczif6TQR;4G[a`JK* #79"-OtN[ThϞOsfbnY 3,zV4tމ.mqorӮ:RUZ^C45M}#[/vWN#ceFr~ ˚?=<_9PՋw]s|ڶv|Ye~SzY)y;+*nj,iC,|O722zQ/R;t=]y(O%|w[KmYeӖGuDK(ظظFj(œ{*aUOÌTU41G~-~a [8}]›pη<50όc ˭u%yeSd\(2YQ\\<Ȯ)V'{[J :Xs]>$7HS#ck։Icryм‚jg.wSީUt'_>.*?\rw;r%=roKl.!}rF^~ݻKwHOJ߉ &*:K'~˾&Lg8g~Yo'ʼnȫK8-u:F{=xBFKd͍yK@t={:"  <Ulޗy;`!a!_\yث 7BBo0% d%0aio_.yĮ2gWw{v{=]K/7-Ko@.xC\Crr %%% \\\\\\r r r %%%%K]ȯH.uK7BTl_p>/ϳC"Z2w@.J_X?*{fzK7<T45%r \%r \%r \ r \ r \ /].g&'!@ ɁQ@ {g`pdvn~@ @~`xpxfa @ 6`qX@ A.[p @ K@ %@ @ @ sr%DN8 Ó */yKdQ@ Y#ʇXDp?\.b3CϞ?kko'p7hŒkj$"73>2:y~0?:61a0@ ? NI '{G'0"GKN.p!fښ'5,+7X8f6󊷚˽y2H#y+8ORopG-r&$٤bw[o@ <8:>{9QBI[țظӨQ.)E^R^t*m0pyD"b T:sLQXJTsiF`1/IT&D";2Be,3Dh8,n'iDHWԵZax0+ F9D*Y"d2 ST /$"eB&Id:DdLKMg :": R%dV($0Y-sa0B^'RN.2.j@ s0K<HU[x DMN;gn㓸z>?wK B'1})n}0L&@{ltRi"'S |ӟ(:3@bpG#TMntc d H@]yKD2Y=ׄ"2v&>~! mK wTVS2v_GD1ѻ Eّq}X_"%iw0P;m0ssЕR ߋ5 9C21mNglbV/eLP/N$g6t 9mtj~@ ·`3p!啔'ϠNAٓIM.}+WX,sm6yG0Amu J>UVϭ}ΧmsZD /E I4u>Ϳ&q=Kf`FO{߯Iz)$VoшePIDG>έOj(Yw '㕾X;E&_n0rTZ=H4h$8,OYͧsiC%ŕݒ{&rH,e.}L)\VCW[Q2WLYIa#+ ,j qafC#%CeOb B yC *k?;72rۿy{̥ށ|<rY|YO_//S r;h?]e,kiŢVT-ǰX}w.[gP3mku('șv*J"QXb v 4kNgD_eS"D?V[ELQ@ŦunB"S;S,/;ovX":iM>nJf?4qq%VˇHt&DSVF+"Nص.S$%G]^]_YCa6>`[GXeWFRiA&JSVhGrrAA(22}zx2"2hd2%@ w<9{m?$QXZE&S1i3Sz;{\)Tx몏Q!L:/ͫ&*wgu!2jD!緝¤!(}yڊZL%g{\)iDچ\җhn?Cs4H[RR0IS]G FYk=etGueS0%1 ŒN.sz4ԳlcbV2jG@ y"#q\krj'/Z:z}ݽ.hK>چDş=vuhcPR[~ŰA+r+?&2I.kۢ H1Hd*}||\U;6E WDw7/V^=յcfO'i O^y~DYr!"/!áA?͟`.c,<݈\"6QiA޾!-*,S0X"~EO;/=r:ru{/&Vַ\w? [6D!Qȴds%Qb]$RWeK먲*EK0-шr?U^ցhy) --97HP$Z\ ǟ;o tlA^;eI~ws-蜡Ur}fFηJzp$*Z i8朑ս>n_06240vM[$ D"iKϵٙGe4t@r 5# 2R*<6~7ux q#w)#RZ.;\p& <Ӑyѧy~e9C̞ޒKIM$mȺctFajGX 1v*T?Jɨ&}i&lrgxx@ w= 34_ʨTT>Jϭk xQI}xt,㉤uO8{[RŴvq _r9)߻p-HsW&\PwM!V|Jji1Ə0sb+.<~#sPSZet*/QV [7s `]`&|u 8ةA vm%UmV~8|`~+ءҒھmT CM\6\L."gkC--u՗vmf`ѥ1]WXnKD.+kX{"3p ɞFڧG:Qq :USQ>9_xf$=uhrF_-2:|+& ߢ6>^YT۶T>SZ\P?J|L42:uaIh1VF \6ra1jVj,LWqIYwfk< 憚K{f8EX.#kP71K\6_i\\EdOMy;6F]_ '4WeXDIוվG.U{J.rrbcꐊroTT vTf+m7HFeWZ2 ={_*y-!ͶCm*&Wb"(esk;i]M -lb279fjɒq~ ^']ٗ,u:hl^\؎4wS_('ٞ@v|3E8bl?R_ַIe 弑eQA Ϩp7S2qX(ou̙tUJ_ hύՏޘTC=j2fFa !tXUG%՜c7cc]Sfw u ;cr7dq38>@GE"e#9K;q.a#tU-nfeD먨pgK( srMC<2ZNsOAf#4*M,#0sZ:~qOIko .H puе6]砵_JZ#E0r9r?< 7CF;ܣM!Ş4[ЇO|b!P{C{`_s 6vA+J<4_ WT;:\{jZ$wXKg* )D~cԥ 3{u{^}sEȶcoysBG И SxnhaV7k;غD\Ղ!\sIA{lr$Q;&[Kag %oba1L,hM;it U &#^SeU];nS?uBA?V~It:A↗QX#xH{砶: (w]E26ӟdd[}kw;"_)XNd 'sczvgFᴪx^Ŋ -M>F?{KMh;yE RX8p/M+@^ƪWpӾX 28k+vǔ("eI<{1bx]?/)1/7ywJ? nWy[b]or}V.>֮?Ll\g^K.'Kwm1'Jb%UN[8ښZ^4+Fo.D^bOr/#&6r&Ls6wAԊܡcbR5Up nSqj5^Gʸn2LMb[\;G3N~Hp.ā̴O|MUjQOlegϽft*aUN 4 / NU-qǒ*g.>NzazDT;Uʻ_Y!'/sMuM5,6b<+L)=+Ny:mNK8ZdK 4pWzZɭƗ;OcxʫjJܴ Gึ߬6½qJL6zwsr?LOJN5!J?9-tdI{2F͈B/(h*{.~ZGO}8ZQp YjCifĂ6ug{ \!7M*h]n{ 3s≠𺁦S OhM|$Yq.RuȔn[:lؤfK)z,p~"R76AkYX?1 ,b7j@ '-7E5#Q džT'z- D?Dl\}-=#}Ccm]|޴b2 (*ᓬI}=,-ޝWo'\o ~!NM.־Uyg2Y4ZhWQnuvvG-hp̫cnGsiV̮um t:YιƎ4jmy&snugghP41K+ݬQr}BN avy؃ulimĩg+.g```fbJ2r<)b_ 2ם~i'/˥y&f8s9:&8-t4rɚ!tj&!c ,j%de!(0)C/7_/nqy2Iϻ'5n&dc踼bvShyr魟>iWyY|^1r0 K#dxqLvNn>Id=ŲDm6Jn\fE#r>Y?V|Nc>K~*BL>bTxze,7mb_ϲ Ot@(sܾ+{Ѝ-7RȸU0F%N<+e^\e {;x1A{-Qrɖ{#K ˓R)3+siYȐ%R&ݶt|y$4Ϛ0ԕ}loNgy gA񮭦G΋ r \:J6oJx!ܵ !$i0:6< Gȋ7;{fkc#.XV3 HB˫Z_">5=EnV>T8mi6/W\ ԙWLI.] &XkWtI{Q.a][3Lg0_y>R,۳r9Ԭus|Sim$wΤ-,AEJJ3E.,֘|"WS}]nd˥Ņ_u閹ZkILejJ䢷͗[.Ms8m?&cъh GˡdK9kNC/?#R.umWZĎ]13~[|0;Z6e.tX%am1F‹!i 1Gt.A.n&7L6itV9{mgG^Z{25ln'#,_3W1eH'8Y#yQͮ!ӥJXϯsNx)__230m̓&<$ȟā,?5+u䤏2ܓn´ }.]n4w4h~i]oMBeb+ֈb{-1~ ֠T741>N_6| `9ȿ ""AwF߷qC rc_{v_X\s[Gfnoh HZ^^LVK'אKG]u}r,]`ZxWACtGWo7c%G!2`quۏ^>tVyȞm-Sd8Acjz%zߕ9ɏeTođԙ韘{ 8uAFLl٘.m4mfId[2ȶ,m1sK*13333363vݶktsRU_"C|\5ڨ>J^!RGirT-:=&!X㙰*.S%a #ٶ˺'HHI H@f8َK1,5,<54fwDX\7^(o_ _$kᛲ2M*F9pH7bCt;,\8W-8"zgtg\nQxórynJXD $9=1 !$:6"o#/(eMPRz<͍~ LVj]tnϨirGubY.Uh tҏVIc1쎺iE(!QGr88LbfvE~.YPBG!c3Q6sXjHgj`.'/!vJP~.%k1X.@)AD&+Y'vf%>yZT[54|J0㑱PzG"wՏ"?=2n[t6qDFkꑷ"rj~~!kekؤ8 wMCd[8!?4*.982N ylh(1Z9acLM|C"}¢u6uL}"\}UbVW677s #t#CcD"'&6^򞅾:Q=c _B|~;V2Cmw75.^Sܹ4\0H8[]@S漲)A chDjdfc\jDrZwf (hƮ]Pڳ2?؊FhژlD+znQѱ!!>FO 0 MjGYIJ ɝyebW+jYe1/$$*0.ooV͙DW䒼P$ɡRoL(K=)W'-F$ΡʔX BZU3 봣Ƴi2OZhA˛Z5Jӵٲ†Y;oMd7`;o}m$?(d"zBW2!7^2L;vsqR r%Mc}N9ЀSE >AuoX*`!;8("GbEc9u;l.H L-xm͉cl),i2vhlv&:.str(?>'(c78RZޅk @}raw i>282k_*J  Jm?hx_oNw|b3+#uf @Q2XKeU>e)d*eIסd?Cztz,*AzmX:b^MC*t2!sgt< L&&eDQ0hhns@$2>E\Acq N8u` FHLC;m<ЯyQ OЍ5 luǃt!EB䒺9`*:oFLS6&${ب|R7 9Q}tMasY-KcL4 ס3;0(FE]=2* H $+GU]gյ5D(}#bojQ44tXX\"rj5訒ܢRiU]\X:ItR텥².hryeґ& ^kkk*ix DؚoȍIJȫ]w_2[]3Ezekz{'7HA?2zyF.3rA3"r괁8-cGtuD |C"b-j  U SQ(Sӣ%]FU֒^TRCVnllY:ɥw&*:&Kc_\|GCu^D";(BN]_A/ C = MغxK*k;oooۻFb&\8/, TJ*eɥ^Bj\Z;{U Z][u=hqMɨ\%mI6ZЌpu}=)=/$jpxtc}ƹoxl;庽GUrr)滺F$S2/!1O]ߜ6A5&GSJĊYS/ C ]<ݚBN͍mlElG xGlez%M=A.HhTVyuoӝ%vLiڇy!/sw}%hH{5};ozv9 =1 i (EߺT1Uo88+kX+K83;uK"=@VUO.*e %{C$-q:氥oK 54+hxN/^Að HLa_bBWI8=er p@drHTNG@D~Z$IemBbX%%a''Bc"aNHP J -[UvS7v*8g|#T[K g[1 JZasX l\R&Nq2_Jrkl3;7%r p UƧdE$DŅD9).<6)!5~xt}o84@.KwF(p䲰 $H A LiP([[ A $H }`>5\ %r _$ A.`2\v JZ"iJmckfA.(dryu ?~B(jʨٺDť \| Z:z Bm(ݧM)7eB2 rC\^${OfFW^{AY]@`)Bq%-em)˔U3w4r9מa20Uos.n(K Kĥ %?>*wb{!a Uwn^7*Fp漃Jkn U+V?q L+O`Y[X݆2󁐘iYkkdXzjfrvN.#w/<߿62e=5t\#޼{]{+ qHjHqT5ԣ~6&#Xhe%g9K-&\ʏ霺Q]Ԩ")W4c6t__+cY -h~f{#V><YsA|&4 U_Y&%-#ck˥TUG\g^O޷Sg+uãټ$NOni&5>6CXq>b4;<&y{xtgk"-5V 660uY@NDk*iѤʂѡ޾׃͵tY-)-u;4rY5˴!47+k[6w֔wǶWgא5ɶbCC+Kk^RVW&IvnK+.24?'=kUQH5g]4ucX?iz \9Jp{rKU+mq*qTVK1%y)JKAF\OǧJsdot~h`nkDا[~Ʋv~>R/eUB VlU5u4NvZK4 ԳҒ ̌w|&n؜_R^+$B]^BԉbԳ^hEntt,ͭzr6ieU4JRLl,q2|M@ rKRGγa%X o[Ɉqb*f&}]Q)t3JdpW:leUm 3;]2d1tTaLb%+iJƮ6zB:!m'?PJL#e9è9XMĊ?ѓmgջN]ԖSuӑ6 Aр瑒6r}.OÍ41 =GKuE\٪lL=zQ7l7|iNdxtSZU uN+-EsSc} ~ 쌳vIY!58*zs9Pǣz> Ca|bRJE%}\^ *> EMWJ2r5/(Sx3DD69 -"&u7a]az~-؝`P%t=h@'ѪOMAj'*#*`a$]%R[$gYsKGtb{.ڛ1cevFe Jڋ\LBՓfO`$ǮY8Z'kE{ELf,T/sa򤑾L"r[ =ؙ&Jy?GmCMIz|ߴ Iu",=\Mr7j 7DsT,Q/X(0E8=b)د*~U%2|L R2TaK]S%-cɇ{drsDO+m:[rrB4ܨ$O B[z?ؙ`.h@%sz⌋M2S;'Xi~y-S*EtAc} UYOT欥PWsM"c{ C;!X p;EGX_Tz\+ owpO$vq6D*諑4HZx*RTD!u`ꘆd0r6ߌ3mx1^Tz$v)TY>t;sE^{kpI8$g'$9:o2b6F^T򴩁Bꊟ`tv e٩z"xB"ƢC<~1A(~_D{fZRBZ<T.K7B1.52 ^E9.-+'9G铠RX m鲹} kZEjzVZZU8uRK{B,v;A|a$ʌhG$3e-ZUCL' iZY3tg u$ȣ{!w7cSe~"~ dyn!pt!bwʪ$}y %%82RQ;("\gddmI XMR7Nnv!tXh5vvUrn9d8,aO./%YH~;Q5NPC_¨xxqWFb_KqOFN;J:w#"t㴕b*nuDUе%^= 3N6dz+jG+r9jʢŞ g3^i7˥ZXtF(r\\~;)T吰  !Ħ%4`m3DnT*1+aBUV((*qQH8dQ>_.EÓ jL1pvTx[R֡䷚hlF>Lf59'lVٚ7 :AK21R]-"aG(>Es&PT|c^P4ݙGaثgVJ8:hOv> ?ر4C6nG+AԶ Saʢ:7m ]9Qtd霷 {% sŊy095=5˪ӿ(;6np%8 j"[ٵcxmDL*+M-vj@kGN[Xr\~♿?ߣW㩿%\\t=\B={)VBDTӒܵMͪ 3{W: 2 Ӳr3 FPedYD3K`1P_0+3l7c}4`(>&8g29$)%3PEݿd/[+# /Ϛ7՗ ne+7fDFEu1@L؋f.dQ&; &dG{^/s% QL8ox=.+؆&Ƨ.$. &eبJJzkX_}YǤh/66&ly#!@EnH.Isل䌸Ʊ,(wOψTW\`oltg^ΗvI_LRGoWͧZXGXS_|(|0 %N7&҃]듭%7{yY ? 4Ҙ\'2;v{(R1GRo^v[$zsajey~"mگ6s2 f SrưBlʬV[qO|<5?rfW>ZU]jj왣n%/)Ya žҮ z#ۓ0F^>bkfjV AXI%T=S>Nn![]A>~AmLԆ& a! SE%#o6fE:VkC=}5yq(y{<פyz8y$"?V˴)zƕOM̴R-(mu{9f4=̕VHZX+Jj'dgњזXqwϼV!y ˢ*U}n\\+)uP(Ξw44"rYTZ?.!hhiiHOgWtL_[1ւͮ~ɍ7D5L1qu)}X勄\T\/,pHG)i\.oʫp&hSbJF."k~*ͭF}3-dh`[XaNHb+Ofxq(TJo>=;e{MTbVrFzXγԕ%k!O*+ƒ&]{Z"suరsV>]$ =7:>el+rYۨedIӾ*G?M#YU=Z&qEMQ986)]@Ì'>_Dy0"$'*gCN<֘LHyd`#C#{Y0K0pp}\M44U7&X;!n+R*M\7˨OM;!ۑF'P>2z\F'X.p:c\|X:\UҦ V6v ZYYuSPojmɥN[QHY7drJ@^7&:r) r pD\WT"κSLVeM?`Qr8 %&,:<M.ѐduCA ]Ҋݫ b}Z|Ľ+FQqJ(ݽ4$mcҲ&*zx]SKMqyRU5v BZJl!ШĴ,;䵑.cmbF@(ii[!'3EN7p0r6:TD:&kk eI%MWNK]7NxlT2V4T.Meg;Jb{w7 +hS#%C\3IhϚ&KOCFnU阚8\|*$M񠋌-rjM Eu}3/q\M 17%'CRY jͯ)ӉK" ݽFZF__&ŔUd,,,ڸxtL>zxy C &TY9IuhϯiJZASӳx; "ULs[7%-#v=icIˈ::>7r VSߔ RPD@!*>j`h}r  %r \;eu]#p8rYTV $H A TomoC $H A/U,R8 @.K@.2Ro-${%3;?-<`SаqJʛ84(J Vοͩߟ9ƣou#~v2 r A Z;_ qcnrwTeDO\b~'.+;\{/:x­?SV18sCk'O2|p$oo&HK/:;6ڞ+{*ek~r(hs2 I|mNǨ{fG׉č٘x0Szӂs; R>m lfgΑ>_ ae,0Zt~2se4NB͢p*c"geVbd΋_+-*"3v.\k>:. Z ]aTk4Szz quvpn}Cn.#BPS^!vZ/ҩrJ3=r_ u}$^ es9cP~mvP^c)}9Q]4R.U 5ewJKMsƍTi>vZk+zE+Do9%qnIY^Lf,m- ׭*ɼOUM AA$ҏY$=*WKdy4c*_[V-,JnѲ/~t'z*SOX[|?^B i|ͧ*5$dd-"J&UFS#ͱO3j۹#շQSQPHjZnr*+5"#ԌK 3#T>iiI<GX:;%#}CU.'J<9(k&퐿εқb[֎:F h? L tD2/Dvykk~ ;o3ы^lMvTvN!Nhmv[`+r8-T<3B6usTWfr&qOiRlJMc]U<^\b|OT1<:gl_۹\6љ$ãly ȻʘVe9̤FLK$!ZLT?s_:LQ2Jl p\҃EUu"an{fC9!A֮iZUBt2V('V32e(oݻj?NA4sJSS h4xLuEKn&ۂEڮebmcIC y,sS9<%xsxtLhCE E ;Y㉚WBO.up韸T&rC/DZє]X*qwGm>'X*kS,pj6nK 7^^(e{$\<-"=y;zD*y]6>(/]X*WyɉG4o.Vq)*CY GvH4|Tˑsӱ `[ZZy'qqD;\ewTK10ȳ:kڱWi m$9SEL6L[s)ѩ"ۊNӝĔwx r7UX)n >Pt`D wN^b,Ñ,__eWwga"5&똻ȥGuQ*]TJ O.i_J|wx-hx}C٬1==o@?d1f>4,!X\()4/Q?11FlRk;)V ȍ/jvz'6?+Ao dxV%F&8YKI),*\6ٟ㽣gԆG>qz\&iPA)en whT74A̮4x꟪ %)xCCRpˋjħG#tvy&S"zEn?{iQR-coN]=iy}:u3,o_dU|~y3׿9}B@_}%u4:{ r)䚃׆@AC72i^FcG.c3aWS mzEXrAxuoDNKKl &14||W(nWuUpG.%$bF ǽeٻ |VUy\ZWΧ"ѯȥ.}W./j^.rin?[۪'It9{.iGGMO@?g淞D3d\Jȥ>[g lEQ$;1^B@9Ըs?z͙AR[޸ b&Z;oTE9Z6Kw*DͣnR`Ǝ\n& Gaݻw=vL{:#MuP'i@-T3TJy@#0Mpx†%bb w#fZh10YG&޼s˓Y\&\R3Myq槒7/f3j%G&ˌpŠ^s &R +1y"J_4dՎA" ^~k% ^u}vBU`6"#TǢf:X_ m 49gnDL4edՊ9F}&_a0όI3xaQlGѝGLH$q2*6.3ґLS.)}r9w2ނE>,#-Yrtjmw"Zh7@=h;Sj+SxXJ>e(M ~".g)'haXo@mkZW0t("=hzSΗ8~#4+ grhtIdg9~.,c}*fk._j;==&cZk;WhzL8XpڢpVO"GҊ0E5$SZb'o;]f \W!aӎA6Fqն;'@1Cf<Zvҁz[2q=%٠{ wrVգnfb?z񧳌?c:GFoNgE{t-W ry&tgtFdSy+93 'ww;rw>~6?lw$FK?|(j𾓻U[W߲ٝ*eE.'Q%l܌DT9 l,ibyh@DhJ ܑBAUL>Fo?y.Uɗ-xnqʻw:f𒉕]z{>4ثp>=uJuY(bfE^Vb]l&0}Dzb7y;Oăf9ٸٵ2\~5vH-z6]_ 㕅qHzoRd|iWz-izӕķ:yJG^6$U*?щkߛ~ c^F6n%&41IiA|nqbZ1ݜ(x_qku2.nGۭBWm }~A|H^]l/7z{>10i\8*޾HatwGB }nfA>tY0<$!Uhv`3ydJ>-fOsdȤ0.#xҷrg6|mGҠ|%Y83SDDeo=xRQTN]XZx9NDV텘4NBc I>QUQ',hkJK׀_[ߟfb}).*+̕[.}Tw{PC(a|4y\RO$W&9gn\>LO8&7YUb?K;&N}t\3yeZeqE 7>sÌM$tK̗nM| r$̠C A=6lZ/_#?U#EĞC \G1;4y$XJwl.4G, 1a܇[?];?f,!pv6?3cr> K֕8{Yn8[|ы,e'.xSWi駳Ȗ~珿2~ ro%$S"iϪ#jzt]zE.gKrNmf;JhH:~$*u:ޱ3=yUdo.>b3piA{Z|؂腗6D-kR8E9^W>uad\r~qiVJy|{gW"cK D.jpΑ_pK.wrߞ -znpӞy^㐠 _2꠵oM J3:_jP~I)I?z+4jSp [^翎^xۏP.qD`]@OC_O\O 2r$Uof>#󧇚^h vY?b3%=ד,=_*жx go&KT"rYRs_:/h.`,WIZxhb}r*ˁ?r׿O;`r7p?Oܭn.3=kߝa:v a !ۏ?e:~󷎣9yٛ%~8(Ϗ\GWc?Yb+0hZP(K׹~1=o_̕x]?}^z71-{\1t |^a/؅=xCLx?%}ֱ,c!%G1=tʝ.fx+S3E~)؅[1-@KWh>sț DYFs[7%%gz-_Dߏ]T1]_xWR3N\bWڄ;f˓GYi('fӆ!=Vw߂OWPmGl-,}WW61N>TD"sՇp/U+k$[S ǖѲPie%K#3Eu]9|WvpH1ۛ8Pc%܂Q[_Ise]'}aA,JG~*4=R~K!Q}^fڛnL[&_"t@;-rIsl9(BB[=E}T]kY])XLQa\zo.jba>j eݛ8Yⴢ{>UF_xOdO^ ܔT Ev6WwR[~\ޝXt4D{alR>\Z fヘcPN@53@ sY'; 9VǛ=͕qITp8:^/USC3^*u1ߴՖPe]8M6&SCbjjꆚ^k{M˦jB<*ǐX'I1>NK*>ֽ@Y@!mj9{_`.Kv&\/U KHSt#ЙiZ` >qSIL#ֆ|x^F}Knƚ=Vr}$-x rd #{M:(W6E8؞>#+wN_ e$vdcIu'^ ̝=V/ddTTԍMZ W'(| ,HnMRWbvov^:IX)E'$L]MTlǯ)#| 6bևv3ɤ x7&b|yvĮ{I ;DEv^{EOs{=3H" 9G9gPdLHE1A@% s]s`={gyKtyYg[Aۮ{)(8E/$9 #l-ݓfN< r6(om(;5;pixṞcqI ?<[޶wh;VCRZD$OFc晚ކ\w{Cqfxs339H13˜Ϋ~:;Tt yk!~^A![ N na<,/z}LKxֽU9uշΛ3zؘŗnO{n~OGRȼ>+rv;nuX3N;xͭhcqXwEǂ U&o:xjY o*ү>!'0fK=l/03K~2!kOG\-motˍ'lΟ$EW<iQD.{+iȬrZ|L\Sdwp>(}S액cfEs? =_ԷRw=reHFQߊZvv9u$S{"rǭ۝FiC]ipR<5O_9euڸ0{Gۭt1'e!>n>ןM$Q1'Uy%MlN(b uKIzo UIv7);x1IϢpc{:K>ѦNZVP9qRǶ_ܱץVG7M8* hYwPV6#͇gKL\sqց-G'l<zG$1+㐒>iONX8J\*wI2z؇&]{ʓ0:3tX/=LW═}'sǗhMgbOa1zWʹ~Dw\4O֭qԷս$30/(]'I~K, swY>eavUzOVsZtY5K!;pK4lcnSߝw.n m!wn42oJu}&3+HJ9hrFh")J$T^LSэpw"Ǽ̣\t|K>j. LedUl);zqdCp;d$]/M *h jqL2 _xUbdDd=6՞U\1Τ1R2bRjlfW;0>rGm7qe $6Plw!ç:ʢ6E&>ܐm1–\tTKzAVCߑLp?!,rL]j&⥊x_}C3dKf~Dɣᕍ%1);Ȏ=xJk}y*W4fg{u-9"re[av?%={3HE 6g+X|zlo{2ioދZ;<9u_ކ*p9|E5K6[(uU|.RZRNeDSu[;ч}7{)1S"|uaLArۨҭ.S-vGO֘_H-kj%ξ{ܤiv-´M7CYR V$hQkVnT}{4n=5Åpg~5BTtbzR뭷`f7rY(/wHgXœ%we{1%ϓ]7lMÇSOE;ޛh.acW¨ۭU@Ael&?4p;AJ rةB@H"n:k,&m|Q9旼[,q0&~]17ĩq?g IY?T6\W0`Y-9~,u;rߢlN69tg iWO- qSİg_8& iS67*4nEhuȣnwc=ߔE\`<TG|<|e7킉VfLvZbyfƛ俕Diġf\ȡkI:qJwUMlmt,hS]h)Aś-pėf6='F@sD4ܙKUX ˯$6jx嶼2}m[Lyo\8pgtBxUkEiQBlr2-qL'?_"|iۤ\_;zl ?=dMƒlJsOHY,%x7H+ua<օY%ZoJ'ny9֦jyVL]%nA~!K.R#(췀˙'N䴛ѺJӿY(i+jY8Wn`l:&j2V׷$Q2׉ LݏՏ/b/~^1\( +B >~Hι'O,vTj'?N^=k*:J::}|)4ѿeIZoh+O]~VZOCO^]TPta ]?NdF B{_23?nd<˕{"}+>A[gj_k Ǡh ˨A.ݪg4oMl7Ѷ2[s&byQ9v8Yylv#NˬbiJǩDVnec.N&O =[e!HЍy/BDs NW6$p} hw5 5m+^'JG!gǁaK A]> uE5Pwmpt9F~dEqp˗&Ц.P1u7sy^Zی͐5ukAǵ $/"w|#wc *\^ 5^pI~{&VyvnE:C;U3m`/{.$yQ62ɨ#]nb7/mJ}+;R~FD\YppI)**IwvtrZ2KUebXv2pK*\VxOt_?@qOU۲uAh .|W}R8WP-F.6=f:O*9\N|s1DJ^'^c1 ?&8{G=?G5(VVEx]'DDۓDO3}, UMz>'Αg&/mO\>s3N+dT#I߂762 6M2£|K~+n6_@G\e Dһ]ϵ~:\F&ʇa.'j^|ɥ䱥У-Dq;ۻլl.қ,#ĔD^ h&\jd;2 \/ZwyWO>_wWkS,v f$|aEt9\&|'HK,f!R.e9@JMcH&Xζ72bl\a^28zyƛk122پ'iVmV>Yodp}foEIގ;y>@.{/EnE.j fp{ IFS|r#+N . AMAN+ ..%7bjcy ;0sUAr])I-oNJ3ۮ="چqvIOweDW>;RR{Uu&9QN_VǺD`sO6$W0jT#/պ\J61֨ƥSGAVҫ"іc[d̯oř|I]/)W4_ŕhjdiו1d$G^ ڟp9Ujٍ2ogg7ׇdQ:"A;K*ψj|nbLE)+d]Мe}NV^| \cp|S4%o~M캚n{W([˯{XHruDD:> 㽳wEjyYXu?xvGO/.w NijI sYڱew<ЈXGU/o>סd4+u87;Yke{fZZ#׿VwnH}yH;$a~2_O{Prd>Y#5T+ʋ3ȾhCZ祝݌3{{v./=(y7CwNZpIMST$m,ץ *Me ;㓚k TD!Οi4z%-pP9r'?MRq)ds̑Fa/Le.Lj)h u쑼*JS+"._4K]DF\CC3Vv6g*&v+Xi2^>-v^]MSbo"atkNii{s1hY \t[s;yJ`X7[bv("Vl"1ENy\1 P=,tXq@; G:mV=OM="Wm=3҃`/"HgWFrf(_17Gd~;ݭ`@쇯㻈4`W~F[>mW3M 5~ êFzc< ͚պK"⫛1s}{ȸceq(;9=lNoiXErӶ#dpçei.UՃ:356H**ɛ&_? a)^FAUt/EZݳT;g ^ ;aWtFi]O{%O p$S[|koV ]eiaOk\}G ;|])75ڣbyagWySJˬ!>V~CfeW/UߥXC4*|^z9)!Mל>۽ɪҋ#Lr)%Yr6)==hVN`|6)]y&i\`GV6wJp[k>Xb}GHbsUEXuS -5f*Z=ly_Fa#)f[#v+U7'co/\J] >SmWYO'|/yS3ݯjKbCf͑1>.DR ̓Ekg-wk:Il^ VIw{蝷cq%?l#14B\W1+h#[x_ \K 6, Xs / X%)W_~x4W3ڭaU9.ٶ\s]*#'Z~㰚>u3+Oh_̳7F[^?w] >)ZD$nlYe(ǜxLKUcu"+/ W0V[R5Y{:fABvf˭Ǭr_Hg:e GV c܈<atw\C п.BlHDLLdSLPlXpf%bYPKE4*v h}x[AL"En Q|ՖĢ'[O9E~01UpV=^{mꮆ gŃWQ; Q;/ڞn_uG<<#=fE<~e~~g`!X%tfX|7C.n=oy`-7={ e(^@ ]_߻c^O 7 "&;wlSWZiNo39P.w/D썟y=0ƽd>:# #M.<}D(rL+(K0 tGUP8f}*JRFgm,,},6f % T+[0Y?,,VTUUU<|H#d $q7i4A$Y gܿ|IxU{V<ۯuHQ4t,_"h zUZ${WV8tX c΢l̫m/w0֧Ȓኲ["%Q˃F_}{ڿu`#Gy@$F 10NC1T".|brd\㲷BP -*Q g1;DNhؠ2Y1fBe) EvXQ`,椟ol%HqΡ/F4.h ; ZWkq!g34GKiD guTVcqJTr~/),)Q3u_OwLxוD7c3V !C?FPSk}9'!( m2rhLL›0wge)L1ӗQܺKJGRWZބK& ޺fysD.O*ن 񙴵m-} 쵷'r%`{ΊG$|W|iML:s4 y}jpX:.LuH)atil6&/9< 4-Q6/.M4qJsQ)h,Fgq%pΡ-fݬ_"2q`nIYl6g.D+d-haC%l|6B̿|:,4:u~/MDB506Ip$Ak^}:ƦQ(=mM̩eсI7>ci0=DslSN+p2A()`0 uXB3.98Σ;}^( f>Z櫺ۻd#7?G{DyAXGq?"+y L0~vg'C/ExjmUXFe^ZfC 4ܧ~=/ݖ ,&Ƣv )E]h6;vcaiT&ἅE:4e%5^U,\fu?yI1E dSonjY^}D@(c+ryn@k&:^nipb" 5uG%?\d! ֜;ϙAf53+.|.6v?zGÌއKXʋ6s̹jx6o>馲N *iB!#Zt4 't8y&+=RNBY']s)(QonPp6jQ7:hL2H"T9b!l6}fE] Y]Y]i?at#5.J~)եn:t2rU EOkzZxE 2D…R}UktcdcH[OSj3 gP=ttTݡq͠ Oqy,Dyf6a _8w<*3?YUċd4+G\olyeb\A9PS`0)IC݇UwJ 54m1g3=M.H$"b7@̷uD֬Rn;ceT8J_aEH2R³EE^VP{C#@a.ޜNrMvLMB1d}~Pq7͒C%y!Y;t =v{ou?oko}Zb(t1^ˍ1=w8gcX0Iw ^N.nGeAL&gH *5Sb& Ǖdp9_)ng3,ZE/ЛT+(KGt)\ *)y<pxcpY4h&8~wrD2Xql@\Tdf`KH[iC%9&geJtL.g =Ƈ,ߙ7.3;f_yb‰ĔGʇ8(?Þ4.J%ueD#s+iɦS5 NM$\8u ϸZp8y.`0 &y$m˓4<azD" 8Fe*鶯Jt: E^э_Nܣ7AGēO*iMXLY@mp/cdpE8ct>Zs 󆗺UΠљ8oof[P &\Ril;^% c\[Ke,$8J00vyX"Z'G4:Uk)ŷ`"C=ec,Lќyڠi,[cZP, 1o^rJ"⎟y\&\gpt:VD t<+(b io0oXAuU.t+Cv?xu'x¸.3'1q<E0r@`0 *pY]G|9k'׌ ҽ߷rEʆ!+-Aa{m)EUkua cN/mpxs0ϼcz/F.mb,]O;(FOuxjxU{ a9h1pAcM8˱~e pY0kbs)WwO2pBrmEǚO¥n OGG\4W\© QJ|Z84kG _a[+siO&Ync]|IYj9߽'÷C?1(p]3pJcP1uj\8["ˉgHdRι__XNDszmi,_ \hZgKc E\N};xIoɒ\"C 8Ӻis6kdc8/VBvAcEXj`0Y[p9ޔs /ryP5Sp溑m1z ܸg~Q%mmPb8*QXKX=4j 0 ,\SԺh4 %%EeCyOP,bsH¦?pkGkOp2PPTR>j_ލ Ÿ:f:ޚAs1B#) t%-w\?VnY+))+)jUYGL =7ӷV^i群K8"0SClْT&6(?yxWKSu;Hآati&_y24TI|,ɠ3(yaqk49qZجnJ@YΊD %eeem.[FM1iUTUU5]22K]NqT9|XA<>.y=VRV<=DqFiqpQ͢8rG,ReO&nZE/YvWQQx(h 6ͺur5 '!Jy咾KD2M(u(h]g8c<؈.Ͳ8 ̴S%^QY5(~.`0 p)K>&r (48Ej.ఘtTk%!qXLDpF'W)c1 e$GcĞA)l2Q L -gXǖ5y`8!*q4d6B%O[|)/?$Xo"prtmNaP>A ~l%dm$Н|cRҘȎ3%!Yn%IۇEePH% 6G|.,fe<mG iLXB/E<A?%Y,qt# I^-tKlVDq8} 8 Vj) x]dyQ+e u)L(8 H dKs,`0 ugoA9O; =􌽟?\_Ia& `?.iȝvs29S:GtSL6^[̯nP`0 p)K?,7  _% "\`0 .`0 `K0 `0% `0 `0 `0 \`0 /p`(T `0 FM `0 ]ߠ,`0 H$@ /]=}b@ b\@ .A @ @ KM\.x_`& @b_l | @^"K MmC|>_$D%_$OL x_L&!%^ZY]\^鹅E..XL֡Bp.|R* X *Is\rxx\G_89'Ey(%qٜd9/scؿ\.8{pÿA 8~"˗ݯkѯj|}rퟙ !~ .?)o:_d;_0B 2ە}>!#OM*_$VhjGA%aP,[FU7EhMop@]qZۃ~Qwk|8Y 0jqPQ?q"ߦRT]) QR;VoI\|}^ q'  p'0L.m\yw7M\OHDոZoomwPik;]yڏ DHPH4ͷqMfNv(TH(5{[2K[]"G,K"4;/^ Q{g%ܿYSׂ;6y~f$Ng>7R ֳ Dp2[s 1_DC9 (GK79}X:9(l?ʼn#3&ROM>]sʼn#͑ӆPL}юE+LКx\閸;7:Խv:w$<K{&{vw]]Z(v{ " M(6@P"M'{OHϴ$$u?I&əsNN]_XP$nz#>2SYhJ"HavlTګeUAT|~.Ҥ..c)?=m m!,wDJV>5rn\|d'_? 1GrSD{ LS׃E):#=s=KE}7*Wlɂ 2"RA *P;2:=Ŧ>\w:?؏_5Ţ_QB\ӋQJ|7r%._Jv|4G3 z($zݲs7F*!a6LT=8_ WB#mjcrҾw0!G%HmjA{%jcֵ \1ssJq$uHk7!m(ww3eօpJAy'|x<cw_6A.9 xnc;ؾЉz9,eyWO]cW)J)m|atnr< fb~-q^<1^waMYFӢǗ/?/ tzVF7|Չg6/皆̙W}U Vʛogڽo=u'qN,5.ʜ[ݔ;]]sS:, _~3/wx#G;̘ ;nվ۬6Z5Nm\ޔ$#ۇMLȔ9Y7_d'g7xeai,\Q .5^S'NːN\nHw&z1+uurvܫtj&|,;k /J % ɷ VhcơL]i]sl5;cw1J Լ .ӌ,"V^pȩzDMqD *QY`R|ȫޭ$-qf%iԋ*v xAE?SrPo'2cW?:ΥzpCƲ^? &1B%ֹK~[dE S3W]f;e/cXyZ#1e*)NZ s:I (Zzؑ}F_cA=mW]R`fĆm}*ppoNvXsOrs5܍~w ˵(L u|l;ƼV2pQUbRqk֒}٧KhIǝ\PVpH"S2^#盱@3s,TgSRn,7|Kr]7hY-ܮ֊44n :uٛ Ϝ9 }N\o׺$4h<}\o=I"N}3|Ƣ].ϟߍ~xS׸>/N Dx . 5}ΘUb#D/;xc)cMBXh|Gơ oB=f̜JuHHRiѓcg@`]ϙd>wִ׻Y5o̊У_O_T4_N^{u,,-I_kxp}dh_|~Azh:ׇcr.S"1~Ĭ;yF#SL5c^\KEO=JEJh_ (e_3v?,jy{R6Z>weI'h D 5gl;*O+%!Je+.ֵp|QHڐ^p]f3"+=ղ -پ2b!JP yut=J#L26He6MQ levJk?ZЄ1RIODLt;ӔJR5E,6]8\ E\WƋy!VP 첳t&F.IDXsxՋˠ ~6DF˻nɶrJD_*.6搜.G.ԠRRozx^#<.o]]Fve.G\JK"FxsS5_YYr|sߑKmi@X\/k~G J.)Jpf&|gf ʲ6´R)+͎+8B%^ _Dnq\~9zړ)7RcC@ P.wJk8N9#f ]x?gv6񓵧r4!ӕw< J.X{݅\n4^U̯ƕc%uwٰjьgfdgmz'MK^l:׭v3ϒ..hQP>7;`PUU1k &5ck'.ȺvW h%f~hJ{`֔Y'Cdf<=jO6M>&gXLEk>ne }蓡s;<4FFKZ6dGz\?o빇Lp:r:K_1۹9;6L\bUZ$vGSW!tχOY띤ZބD-{hǒsm.5c*vN! EYAVEB Yo[&IM $W4Jb$Z&T&G be{kL*ZEsHݛ W:0S3CFߍ!$ Lrq5ֹTMG9*Ús{w)JhoSߩ$q;Ĝu% em()+g\:@5{lAݥS􉪗@.{Oqٷ3=ɯ qߠC F_if( NPƻF*I ^osM6%ͻrK\J}Th #RTm5W236Eەr$i2'$k# MU[ ȥK\zJ{eN))vb㨜$8!~OI?$ 8j'UT% ǡ!K=U-~MQB"*I Ebٳ;Eǵ39~YZݘ`FRݕawYWה h#80&{>XD+e\lp< 9Er Ƞ18ItUrˎJM$-|4tmn֜*Rq){+lu!\)|su"D,RaHƂM1$(p.RD@~QC_0{S0O+^]v=L˧\Vucŵyri<7¼VN^@H'͉,8w#, }%?˹DFtVs'CWxet%ɖ%4{ȥQ Ml7Y7vM{n6ݻuϡCQ-bjԤJ.l] ;v32;jLp' "o}:LA$qGC _#LxI']l)sƙ˃RTvw0{nٰ`2UѦxxְ|?a-oSLIf.@[KH.^130j8 @NK#z[ ZH=DRSNӂ FQ&fIp;^>Q/\q\%EprD qokc6g`֎h`Sg"Jn_|ʗ 9D#o<\]#j>\I_ZqtL3nhFJ:ˌ\ДdSK=jd3 B`Q4Kߋ䒙F,1{t-6 n_%TҼ,8[KbQ\Z.IpΗyni%),mJ rLJ˫oJGQ\ W ,r!/S%D(xޯ"(ITc 9Rn~;A{5dtϧn%REh\ɺ!37\zQ4^lfRƢL`Q}Ҟ-Bkyn2osd#Nj_!V{M-X:\r};4d"A }ri|&9;O.fJ'md@.k7(ckŸ<T|vK4?&wVxQr61!xo=eA0GghPLZb$d LGZa k5T3ktN iIvh4F.7׵nqT!WR]AguTrim:|wG5lλPd6+^˔n\jS%)#8~rNbF(Dy=W TeLS<)Ix_|K,ת/Raf^rTF+nA*-^LDsgﮯfeӒg(%'; 53a0C)Jȥ 򖴯[|:\֝?TKW2² Uq ,+9Xˊ鶍-H˽Z./55Hs;էJKy\DZQl] j(h웽:x{5Q2,Edy%O L1yH9&/?y=eNZ4uagsz򳘵Kf 0gtV~3\Jck΁F!呥7tM?AoX])\Z6Z[wĬF:K7k)Ul:w0?Y5o{;:SxߍooxSLlt5EQvs9O7Xi5Ή}cuZ>Ń'hR3[rО7jEO2T'\pdOIXPMaV&K/ rNWc:E ( Ϳxw#{;غsZ0M"3KS͙9U(OWrJy,Gdw9$YD*_ڟr>dt:AqZdgNEǝ<3 vn1fy"誧S>1ob/_s9dwWpfmLNuky8C&gM t0kՠk`;̙2R·O8oª^;ٜp`TۓnEj=yŨr&"ؒΜq'cuW7r")]g-p_\~$U(iԑ+ILV @*NfZ ([ܯGFJT2c#p` tȁnvdGZftK7f t24'/̲ AF`M:gih\*⢊`R-2hvRw2ҘLR}11 S!@q8ꘘ\C 9b$,Z0&!-' >V|"2 W*T H!}J=%S HPb@ U_їFPH~80w{+PJfI1u#-jU>S,.#q97 -KP{cB(2^JZF\)\.W*\S2I(%^B?J>hu}f&x kޮ*4FiP`W*C@Ԏ r`\$)Kx`@ r @ r @ r @ r @ @@ @@ @@ @@ @%-.*(~C+)CQc8JqL'b`S@ >*JL{YR)!~ ySϴJ檞⽝]b)Kr]cQ)ƭVNa*5 .`[@ gѰ 'Z2qKV;}3'|*ǭ'_2p.6xZw,Šk_i|6Vqo֕r!Gl16yfQyoAY|RZQFX¼2'$$7rCJr ^I[Y*JRRJUҒW &%y/[!>[&INeRRrJQ۠‘V'$gW71!֪!O ^Hf5tII~7 RZ:1DU qws [@ 76MN2Od3Y%sQ_NYnt5y=yӚӷ\dj56n$U>kMou}ڐjkCF&,suay\2f̪Xln_G3>a>થrC߫WmvacLUBsY+Yg1zֲFFB{UP0Id+᎛ >Ic[F?_~<M݉ No\upV#VӦMφߛp%F֫W;qˎzdGoj~R53g_*3gy>( ~F4k }N~+ rib8AP.h<\)ړ{䇜1dA:I=V-A]6߽r7d<%s3o@aߌV # qx\1l$ vp{ fL*pC&Ιj'ɍ&XwX4{j-w8 پ=,:OtR1X1}54+h*N`nBXۦ\sS7dÈz0&cz>ϩd>*dCO+3oX>l\xceEe]۾juE*Xl. @ \m36eIӾ9m$h7#{^z+y~9F] :[{n?fr?\rؠ:Zf0eU{LtIV?jE>rىk /6U~/4aI j͚ fZÅuS^)_1+c?9h wK F\=j`Wˎv*4a>c)ab4t`ڱKf _Y2t;pϑXn9XB@ xӨe^3õl#i6jSU`| \X #ȥ RĚOLayʅ3?v.M&͘`#6#_\s:s'f1Rp8F.7C{w>%ֹ/9rȥK&Mqvf_׷ 犵aJ$yfF^wu]4YC;U&W'Ǘ]_΄@ \6Zl2/o:+дeZo1~j诖Mk \9Zk_?<l:޴!>imKF{dZZסơ]VFŽgH۫@H} M=ynfV"x@ K*3YZNjJܒ,~jBR,:.1U/0Q(yfUOQpNub|ƒ E 2q{vZc0(lJ|MewǏ݋Mfޠ>|Uٿw_Sc~4dPIά鬊q [5ȓV/bҫEdD$$uHKbz0%-zS/iOOIH.w&+'xYUW+Ԝ+Җu/:fTl2۷p)Uq~ nrKHZdԵޝޖ#\s:@ ?^.y%.<+Rnm68wk@ \W$(H@ (@ (@ K@ K@ K@ K@ %@ %@ \R@ 6r:#'+7?#'&` &` &K-T(` &` &`L) @ o@ @ @ @ r @g8!@ P.!ȟ $L,Ja,@ P.!ȟ,ej:/I'gr)g~I/iV(97L4~DS9 ä;H:hԿ~ETw*?,OT*LG*(Ž.TpUU@TWrEd+Կk|4<)iyJoR\ƭ{[ B)ESFKߖn~ nx(h|p%Sv\q;2fsk?fy-/h')&NDi$eQUA~I*⢷u(gKp.s\RU'.N(iA? ŠREd7QSek/)PS)~$Ą{nLoR_oZ^~s`!Q!]HRʘ~ׯ\ r#rpwH8"YE!sݓ4wWU?Ep_9zŃV;4KNUGnP enPt)Jk#GD ˏ^B4;dfy /iɯGL?!E YK֟8prMr")M}s"(@h$uʿ1yH rP0g Օ+)DkñCf{}'#rT8Zz4(y< 12lYS?'#DTO J-D>Ҽ?'iR}:ayHR޿7)Wܒ@ Hs1E˥M?6/c7-E p?`+W`+(_wqKt-9(T\[yOl~'" ʢǢilTIyEm+<|,6![ʴ,uicV`Ώ>11o'Z<=FۀBlyhѯoHpȔ ڑk<*(PJ}/irwA-YnST;aQUrY|c>|0/KL.wD<(#D _P]U[n9"*;k:"cJ|n7Ƥ"mzT=CpO=G„ABcApZop:D/r9 _y74TTVVשSIy%+]P~ @ C.&/㍣%4SDpCؑ\/?c\ o/{{{^}^D˺}ϙ7cٰe=s i}pfS}N7RUP}?~N-+2 l7&c7i<>#𸴷0NnȊyNȈ.$ \ٔq9&Q4W/] y,Mb*)4 .*:qH(T[dә# F.k"Lsˉ-Ry<8>^k߂{%ɌjC{2(+>z^7?@%ven4@pGr_6P@>ִЗ*d:kc: Vݤ,3WvaףWX\цCgz_?/\ CY+#I\#Ҍ}r j8mN\.XJ}~?8@ %ΫX2-Cs^pE?L_8\{sn޸|’0IkjIBbm{>i)|ygSGO70kᷣ7iNNz}c1G~0 ɸv|T:aŽu6jިF\;ӝh5uM^Fos{`vN7t&;`pg.2n7DKFOןp9y2QWm]IK Q܀c!/ڵ{R{kez8T:죍>rpMӄvD3 +lH%)+0Ls>fm mwmoeȏp359{ū}ƛN>gtetX@DDZ-3wӠyL Mbp y}Z]w-,2nٴrڑ_:7Ҍ'- cFM2>f\m X(kYϥhni˺p-g`OTN+r8Z7\ =,XD8 G_m7=4yƧڱESuϾ, 98dN]1+ChYٝz~w' msLT>qsN'ⰳg|z{3VZt}\ǟ۪1}J uy9;n^aQF,*\LR4!|9~/۷oBk^B9ϚEWs^sDm. I-LN&T/ _b݊O R+]YbuWrZ7 an]ݛ\ea [.u \R}s_;9taޮBƊ۝i~./Ѹfk''qT`6l.Ug0?QE wpWsBd,xK$lw_JAϫ(te n5+A=]t:E7iGB2@:%vy|P)9ƁI&pO[/%P'|@.O|ƕY|ދR*1LFRt3>;-APнA9 ׿G͢ށ[=ϴ:=9JJ9IR"sJhAv׊ܟK>w5tr# 5&Ӱ𨕛x(K&V(5t}Njڳbև Lz,3馒KM&ڝ+QG'kCos`N-)SWG(m'ڕ(XẑSV N%qP-}4 k>59Ϗ|5f鱰J>発=N@p WLd۶=ȓtp{'y뎘,rˁ[|>tҍ:;`Șy;Ԅn=WdDR~@oGc7۰x\'ff@a7SWo_pVrjC1ry{ 9j,y[TryF *6;/魎SeֺCN=z|&`>7 LЧNM2 +TS;w9\LekrϣZuϵ4vvlD,Ιs1@.@OnUv_5p!T"mE NG~?F.,T0J׃κ>2ڟvܳZ,S2V=8Gl>wEJR1t:)L\ 3%Zri|:[d]hIs'j?{y 9 ,:~6ǒ?fBJ.= ]y8(q Yt_Jmmko0ݪ-iA;եUCW_]4?Zlb\*.}fi{`f+UYXZ ȥW'lub-C`dl%L9m<~\,9btL.\m:#4gYpԧWK[ Z.K,ZG$#.Xs3N(عz7="7Y ԥjO|od@.mC{Ur6XWDfֻ M^%\Qg{Gk{gg7,1K7pƾ ,81L 0nT޿hWrڔeŽ>6=-EuknIyU-wqRfړ~wOɥkt>gs"w"7+.Z1jSc9vޯT?%Dz*63017k.UȨTq--VtxIeJ=iOnVRA28.2 mO,3S{j9B@ $hb8rfW &4ou: s}6 ,}]ܑr߆+#GZʥO.W2 n_\~MuEmYfBr;6KL~F.}5}.ڕ٤[9k~U)w1j˩̑_&4WpZ+JOK,絧]5eډ.{ YK\V."Ǎӷt}Y#=G-j~~j.ʙ )ƮXxB5u;}aH4-dũw EWve1D'\ k AHZ24GTXn.Z)hlO 7_Vl&l(p-L/l%/$=H-a.ťAITAw_t*+%)f0:k)l73{杈잚ǭsng ;/eYXG{.{].97;NĽ71݀4SlLnSl .`\po^ !zv%Vv.w]f>>Sc|I; a 6W$VeX (&zL.KEɥm_?{wY4`Ǜ|嘝Y?N̙=Oun"5&swxsAL͘øu[7bscXTl9o|xXPަUyw~ծK]JK?]x 7˷")4Ϣ~oqLEo=jɊ=7-?2߿#\/|!/#NoVg4Tn0_9EpͼH0e.E]u7暕9ʎuZo,ZڳEΚ㩽3ClzO ߟT.Tc'[؃sXjd]&v~f.AMYrևpL^pUӕ3"RVIq;WG@K1[x8 ~ʥZ8B#msLHԾ xLޒep3+Tb*T'%@qD,jFj*#{y:%|5Tb]`G%l>1LQ|#q&dfTә$ :@ՒsAu k U#*k\XgA@ \=Ad69gY,'1`G˕r>}+*H%z`O(O"yP gKJBѡ>jYD qA!1Ƹ@?*aFzCډ]JD"2%>oTsǹݻ=?0<*5SY0}P3J9e@Q;ΠsD72k9ƓrFAE2R%ፁˆex݄q(d&k5Fը)OԷ6plWQ8GMH{A&O,ŧV"R{!TO)1X<92mF }*@f Q0#Cd )S)Elo"(\.K(ëq9Y1VD%=$Ш"iNYP`cjNN)ɑhZTG&v \ cqx /f3D (A$Rx JTg/᎑I19*x;p qJVRpG;Os4NM.`sTk/Xa鎨T`|M"MI $ M58}6MRIN OJl18Q9{tE$t_OER#bZ/lKd@ Y:[)xOEXLc]q|"|l\2&/"d&$â~'K*,6*ؑdtVN-=-TO!צ'N;,\(V6.^D?O$҇O_U,(K,D9:xƧ_wѮ̢=9BUkez3;'nOd;-92cS܏fl5J_]_I3vnA5[OU ȴu^KCPƚTozt^N6G@h+& 3>_`iS1i*8jJDž"3wN+w61 VF_s*5N2TjTUR:+ݵzwD#HGڧeN?8ʗL~ʊWk~$_W7ǵrrFL).v䤘"ns4/VNg5/t\'HIUTRj}W[X @ \B ?ʝ<^nNCtN^Ta=Mw.|B.<vmʚRp:z!kB@ (+Cã< C=H%bL(D*EeK^ ~߮jٖX>[.2!]T@ K- u_NO!kſE$n=dm1F<[  1;JP>hE2{Q@ (Z ccc4mppd @5PH$)drsssIIIRRR@@Chh+W @ zr]]]Ϟ=ptt\hw}tu-[LOOfMMMOOȈL&!L@ P.!attD"Qϟ;vl͚5 ,rjժM6m^lذ!&&8(HlooD/!@Lpdd-11yVXcǎ-[l޼YOOoϞ=@:wYXXHP[[[K@ P.!8(r8.2<00p-CCUVцn84@ (XLRI$ROOPL#"""bbb<<NQl}q•j Sʅ| ol1 C%B@A_ }O+jR DOx@r^W^⒚ѣ/^<}<22\\h_|rttt2x .2Cɧ&զE0µwrsMQɅDZiI <}n}M[ l1|DRdv>-"c=`z?F_K6,KW`7kڐ\ID!_E^N @ (jx<K;s^)1 iյ3g"Oz9*bv Z7χt?dmnq&oƻ\j5Æ'ը0᭘;L||Nǖ1NW­)~v;VTra7\.QԚe7 =vFP#v'RQq< ";=lo,}"rИ(䶚9c;3AםJ.}x{=a{ 7%qa&I.QQge`lY5ȩ!05 $¤W̍wo>dw<- hq|O{cGR`mڹxx%"9D}uwNXۘt=Unxy9;y;yE%> 01L$}lQոDxA  RIPr> 655knݺ2::mΜ9.K.;)bO}ˈ 3TzH5 5-b 5ܰ1asuxmRL~nazK{Dj7W`wB ~k>r#UC,@aH1N%ܷ&Yf%X8^Bx t-*dϹvq j.v-_GUur}53 SK527V΢u;drPŮ۔/X?\ܦPiYaza6N5v2"M&e/bcnSb{IhY+(Fv5©}SG«t[xW3MW|<{ߡ{P1hG^i]@%QCww7́ׯX }60NKKˣG,t8psf'ts.A:0Xuy}ZO}m5nVjJ{o]uNӫWxSbSւj1%e0YP ޵e,}Kj6;xpNxԲGWqhÊ;; UWd/Lm"pC'GF΅XYX$;/zI.{.{RLL=cjz"_Wϝwqt[l<11w#'fxX- -w}ЉtPts17l94^W:o7u5QLDH8[ ?`:>>/*nSk`gn70gl栣sǽ@ P.!̒L&SԎ;w<{}vMMMQQӧO{yzz&&&geEVvم0UXy$& ue'U'\.ȥ輧c6rGؚ]åt"vMbj(\hpZXuo\m-H58\.xriugÆꥐRў8$ 7'x.Rk fr/b׾mk=%~|pCl6tkbj% r#/`N.+&gu\&*x6KJ5ٮz˻ GBWAҽoY!7x`*#{TMtU!5Ɉׯ^{=#7뚎ՔHX@ _Jhegg\G~yϟrJUU?~\WWLNN2ڢA-N.t^$sLPwz=˴bA'WMefTDJ'5.wE9Zܖ)oV-9q6[K$F<̐/"{zj/Y(GzGwsn9YJBp'#p5r)u3-MʱơDR-"{RCmz~é L&%zI:2W+ ?0&ngQc֫5 %8O쾓xE˭kNl: e][kdp+ۏP?_$,buo@ El`u4N4"ɥdƢGɘ¬>8.'[ڨZ bvJ{+08@ P.}rR;%BYPPpɜΝ; V,++YQQ8e|>_+J56Xs!aq&_՘#oadhu,ߔrwRrSL*̔aMq:!+򺆳vvG,Mڹ{PJ2R᣷HX1cv1s?!F ]12a=In'd2I{[FگE44lhSѭ )e]|!FqULUD?mVC3eBM"ӭnϫco3v~T1z&>beM Ffz{-fʱ)+q]-0ƪl**zFV8z3n#-ḯD$"l4tFb<[OG1RC72!APv6ͻMp:[;y73 y4I[U?)陁6zloi#$N;ldyթ2vC EL&@imm :vvt===}}}## +W,Y666IS檞wk zM;21EbZUaǴ:H5n'"yO&UiSإ&r&Vyuc_*:1]J)!QMu]BqWT%4&gT^7[@7.JM#6@)ɷWN94TO@ (RRiGGJP(qqq'N8}#GO:DG@bVb!G>\w4qq[}җ @ _-ޢ";;;333'' 777///WWW###`@(AiLCO2ENma@ P.!Sy$q\988XYYDEEYXX}}}]]]@1V׃ J%l_ ;J@4 V.Oݸqm֮] ˃@.e2 [B r RHmŋ;vXnիW\x[[[R( @ P.!xR,ۛhLJJpB@@@VVDjnnf0,!@dddJ:88ܸq#777###??)))Ν|ƍ߿o@ j6kbb$ի.]*...**,,,LOOwvvfX*< @|?Jr||=*---))N ,oC r sH$H$@,d2J@\B~+6@ @ @ @ ;R @ ceK@ ȏ$Ϫ[:.p \ry@ @~ hhn@ r @ r @ r @ @@ jZ*YZ@\B *R!"9_(~ P!)b%@ P.!ٰZ/e, /!%Bx 𗣕3/R3]YTS  (@[zơB4z^'ڿRa.Y\/m9t*1R zyʟ}y$BeQ#uID^˿2# "!3~*Sz랍#;H'@ O-W{xZ!4j{]oXɎoj︃~l(9wnּCu/Rv~_,:Ţn}hVљ@}W߫12Y[iy67żrs.d\8:q{?)S=YYc?68T6]m `Q]˳[KxdMF^/y7 [S2, %uoh̎t8ƭ}ԗԓt5q٬/W擿W x:?Yᅫ%右]qmmՕ᧧?Jn9MY튨Ƿy(2!|NU#n`_`]nW*}m;];W3rY)Ecb蕙n<y #'/#NʥH*Zj?3ebx,%/xK kw)%9#"t_dJ~u?It E le1ƵG@~2=-i3/ܨԂ'"5dGf^x _.[y^̋vP͵Ĥ+іg++.fF_?-:shP+ƌ2@:P{L1\D$>Pd*rۥ_9|~-mR^+׋(xJֽۗZ01ҹҧ[Kv0Zbs4h$v=LM:u&][B6 *hn}M ï^h۲NfٰMt`(!s_zĢ )Ϊ#\ ߸t iIZV^ݱ@ _+̾REYw ЙЂ&gr$^)~‘EY -luZRjilHS~n^p%'isAj;(mzr95;U Q[&Mkj$PS5/*;~!U` 1{M2R 7 ˲ݬ~:'lbqQVLS9afH lYTE~wxqyG"7rFpDZT1?+EGj^yܡ$dՓW+xԬUέŕ䴊E]/2F!C}m{<:s2n{R$A5XP@.c/ S+2``b1>/<20p4%}:)f>?Dsms66ر/i3q, +qݲbwKW1ͤώ҈Iy̒t~|y-wk[㻥+颏ʪMKwy5smy_x.do g6s|pB홨3 NG#ILbC\ۍu5QJ8FelS҉e+gҲdUfV.Ŕ KӐ Wt}v\bӞRdzF&:ŽaZqWffat4W;kװ"W'K_M+ۏj5l[E._B^eՕimvZ8G^iEY9zuvXՒD{h~) XD^*ό5 ˣy굎Wn=^ )ϒX:_pd}p+68~ƘM̝^os,t{{|1>BSa ksFa {+%9w9Fc-(( aq]dhrLvħft?5W bܖ(>]z*0?vÔ_!cO9]j|\b'*Lmkh M.[gZ`AJMKߚoVք?؍+>c+&a[m'?e K;jV_b; X1fpx:IAuV.w~gڂ_8Ϸ&:6sFĥZ{\F!^vsgkͮ>wW2*3*#gjk*UyGb>(?$5/Nu7]J/к87}mqN lCA39l]Y"fjXk2,QKG»GnWk\Jdh /c  Ǖ;ךl{D &QeXTwL[5r[XF.!䧖˭V3n&e|ŒD=Y9niW–}3"*aK=X5gPvԎjw+uri #oeO.D$SùzM:\ey8Ƚo| 53>57\|x-&u53{KrI{_$:~ո̖:G5[_rhR 6t6^{~W.† )ONX5OCeՙad]:ze-]7q,%nh9W}Ӣ~"M 1Ā.ͲT8=T I}RHte챣9G}byxU`Q_}Jx&3ש X猷WYѩO5%z8^j(3.M4*~:]#u\-AA' X KP.!)q|(ɓ~k{N!U&kiW͸QC m_$4d͛34JN*f퍫h{W7ܸ[OSUN0[ǓKKz}K:D.}%sV}f < h)WWYm[:g_T8sz ɥ:kG]gwkz KpX1&3<C&kY{]4rIw\%]u\4cByQAFcԠ#O Ea7s^t/nyi7L70*+rɸdsUTHQ1~0[oA>D}&>~EoTJ%zn{D/=3xkj[V/GPܚ ջBǥ1P|TVdNVQ*P*jmpVCzJ/J\B P.Cyoeo7;ۆﭝ3 l}>s勅*C1|/ߞ4㵗Ysf"sws~/㽯w]P\-?_ Pέ,S oW{N\ʎ*A`;}ޚw\-Y7g}p³0QF}n[2ɇӄZ/|ƙ)B kw{w~obty_7򞻇, d~u~0Z}z+ݺdof͞87/ wgb(]d.q i)a6@DyV2tuv}4n|Orpvt-'@]w H h}M3pd˪]VIe@7FӼ NEx'Ti|RwHLXR53;}OG9{u&>q:xxZ,פ~S+O5Ncg[?y<\{E37ۿqK#&056;Z< V#GK9y*5RӠR?KE=;{%v<*EQXo1zUˉ(' Vd&0/66  \K++tpf| Nz@NLDxWk8$ٽ]G}bb3lo*v_Z+[z)5R3\oO Ob JصڽԺeޝ4\"35!Ic>QZhJȤxGt\ \̺UXgKNE4gJ_,X\B ȿK.Qh0 ,4r=ClZƢ3N{']$bNo4ȑ͘R06Dn' NΦvHDp"?JHC7J7Cx=}C RJXa߯)F鴁QVT!j{?Q L.1L`r鳑l`q,jIp'rkB"w>KL-rh?@OʍGkzdDpilv@$dtڈ`(%kp?r ;sP.!"/y‚1+?qm4;6bW&Q R:L%\FHdCw2hsz^z Hf|*ODK0m_i9H9Ȧ VHdgLK6{}•nqr H ǃw<6cxF.?þ ܴ1ə nn N.ݔI;B(y%gtH& jJki`ei%^`H;ݚ97YarrYs#@ P.!O E'u헵(2&(Sq@@ ?_*UJ+ȫ1K@@ @,Qp8^"ên!JJ%l%@ P.!DBрGݻwÛ7o޳gwvvvNNN||S.װjժEVWWwtt~)[THiP)$GWHT+n/mE\#R9Zbet{M%<"OIg7@\Bp\@&\400x>ܼyŋA45@1SRR>cWWWJN\线e*-*֫)?ti:BzyIya9BIl&96>fآ?RGzۻ{XR]lB/Bv16ODL3I`J`OWWŌN16b^ʒ@\BI\+{}wBBBܹ<===66655ܹsǎ裏K T:r7% (uLKD|BrrԅZv` W#|]_eד#mC" BLFqxQ@3]\O&DpX"{T@7t%'4!%e 09dP\]Ysk*;cNwkD8LV~zw'}9C.ǒ*u&(9Rj;O{;muI'S*:ND%V Cy}2dT{}M1Icq]l|[m'=~25A %d* 䲻IJJ<<h|{Ӷg2%&q> *ERd"_,JMbʸ3WDvW+fcmGZF%"w4_bޓ5mV|ҽU:=^xŪ1nqsu35||ߟ[Dc?yk=Yk{ Dt ߼ZsNY:xnI !k:oĻ:e]";mk#iCyr'pQ=Hc- nl>"kI%*ubVZuٗn9g_B*b9yP@mC\|{¹հ.x|o%Jk3nc0c*ZTT-8NSSS? hO{{{EEHhr\i;qۋ^+OR܏˄ژz;\-NOǿmdN̸I7-ڋ1ܚ `ڋ˘=vXO )]qG_aw&4%\sM=)\ gQ2):c=veUO6)LnB4.'GBoWOHӸ=Ŏ6e'qٚ#!>=ղSq#˳рKgmHH=}p䢜MǓ *y&_h k2. /T5D6X,̨yXh4h'''Q#fffjDR,.ԃ(ZV(X\dwes|CC֭ū¶{_-FLH`~Ä\2֜؀]2(kS6hCLj.[\[랿K> ?e?y *AMi[UϮ9eOEg/'xQ|+C\{ގť2G"K/Њ p1mxr0>6ۢs; %lfť%zLSSSPSD"E"JJJж x>}}}>|822"Ar}}}'ÎzqdnkY-b.]"s$ʧmRn;s9~up?)ko 0\(Jݻ#ޔvPW5[{+=;"V?g[rg'K<.qm]rffð|v=jl3v<ڭ[8OTfKj*ko}o}*4O  Q@D?]jz fޡs.-j}Z@"u}2odI*bu|Oϳ/AM#8駰nUf7vzSybQ>mrgeKoV`+f1Bd&M߀h<5\FmY(;w5ў/eĬv}DK~՞4aA&VJ&:C^.-&W/nj[%9SUͳ^hi|m]4*`KmtEF NEq¯Lrkq!%3Tez߼OH#vZ /J6 Tx󲱶7'tOF^Ζr.%-IwY hI+–%8f3,]p ?22 ,+V"F?쬃gG侂yq dwwwvvV`}%ceeeXX J%ɨ&I$HDMB388@ zL&AqG1IdI#[>euYYYAYC'Op8Ԕ x<}tZKXcaFZ2z %KԈh1ԑ2bbb|}}]\\N8qI&] RbGF@\;bQoc4E"QBB™3gPJ>}ȑ#h\Lpm@\CP_-JG6D"5{pppNNHKKtr|aafsfynnnrr8""fhReeeB~@ XYYy%"Q__bjjj=())Fۀßq ~۷ozzzBasssCCjJTl6ӧϞ=Y%/lnnY]]؀q .%@\gt&R.IENDB`backintime-1.5.4/doc/maintain/_images/2_to_weblate_01.png000066400000000000000000000771371477034762000232050ustar00rootroot00000000000000PNG  IHDRsRGBgAMA a pHYsMMg}IDATxXYڿ= ;3;;;8cV@TPs9*"HPQ$sM솦sTu V'[.Nxu2fՒev4N\gҗ'+}+BL B +w5xb Yx̱Mm?ݧnFW/Lʙ |Վ7BU%|'<Z`^]쳕:GRt~眤w- C|7r-$N|tж$]sY(nݳR{&Nq冺y9^y6ޱ5]ƉHAXxj{Cb>v1[%GN.])tcn9+i]٘jٖç hlvgƍG쳛Z?.lYLՐˢN˧uQ&Z s@"mso{qұ?e&3rD>=;x=gM3AKp<#$&fPfϚھGݧАږBF쵐}˖X{X@)6N&k~|Ix++M){O dWxɉ뀘1pys?79>3d^ܰCrIAUOQzDgpʇN,ϓfXnܵYv:Tö,-'B!"DR[|Xh+0a:[5Y{GFY]]c.u-~lPp~ v3[y>ʛCпCR/ao)]a6.]S{N]vKh沧?7Rt ߜCP{/\a ^foٸ~x8ۨ+va+{,'rW)>ޭtD,Sֲ@v}9+c~QGppTh}NJG$N/E?] ~6C=,Jgm?d4td?۠xिờ %ͱ&{y%N@pWWr{6 pV@/PwWIc HA@VrlŒ~/svL~3WEe_VM6;N0}?c9ї~UL1{ <4v⠯{Fw΁R tϾ{.|x<*ygv jhGX3%i;wod>?pǏ>$|XkCa'o9e*d+.bYȒp~+a  .e۩^i_9td5JpoO/ 42{{f}i0/\z/[=<~+ }󬰆Eh) Ϸ ]P5W˞Y"я|wieu+i+lMmSQb"+)oc6c>B5m?+iᓜ? _V0UVavq=rۿg)uzsCoc+ӚgסM崍/]zϠIb=Ol |{P<dKHCt`=|072pb;0`n> s%! \Vxۡ;(,4G ESgzo0Hev<{,7ܿ|Ծ#WImO5eL`)lVp<աv\o=wxL$lۯ؞Ms5۱`ҭwz ORL$Ƹǧ_;|zב3;e_.>(~L)4Dd|鴺O*nemH"B?}iZ6O<!#E .jꚤiY,}[3A"DYE"Dd!B,"D!E"Dd!B,"D!E"Dd!B,"D!E"D>dG ِ ِmM ِ ِm!BGTD!B@"D"BYD!B@"D"B& B%DF ?H @]y7J|E [`Ԓ߰gio?h 6ͤ#g,;:AW/N= v®p@\Id0d7!KlFg ;6{DI'W,1XtN.摥AXsW: `_}WɆ2*)Yo~EI.NSޝQicͣQIѡ,CV)@q&Fc_kw,@"HȂ504w#3pf$%!KgSQO_ֵL/~MQh"Bm K#,'FG?gil6.Ğ#r  O # (..F%Tge],=sF#ffYPdTf3!~"sM,{e~A܂9/ǩ4&ٙr.eHaߋt =lk q1X*>OnQL*u9dO2wܔd7SgӉ+6 e O2d99H$c?ڏ>W}çZbVhF\0Ţ0S}#h<`u1cmchrɋc(` N v y6A/ b@LvL-@vcY tH(5:vvo eZ[$jdkG%Uyp " u ,3AAO&19B9al 4>84`pzGf(ryrO0]-w@Fk"h /n,BdPhxy~|ql؅-NcPC8%':dukvOTnj˺Zڥ+zR[BF6f=@{zcԂ JtMWF 2aqVEfv\|]}BV9G`3?g۴ƽ'~ыH gYF |ݪW 0x|<\/G:kK|OvuI_ܳgwڸcC)ɶZX4OC϶O铍17l'DCꦨl63LF%tQ=l@ѳffXdtunecC ]˿Wpב[:, uȫ#))ӯdN_[Pcu9ݮx(K-IE9Ăk3%fǿ?xfב )3ٴӹG9%L( O6f{8٘ڛ;a^F8;B'Z^YИmfT/G+k'KKmad킢J lRID|^m}5gYLQ-۝*;TVI0 ,04}pNŲpDK FY^K8TEk+ |83;&MEpogC ]UK'mӀcḶaiY)Q>z:Ja8hO[c;+7ׄW#5e1eOY:z=vHAMjd;Y_/蜧1t*&WE>-yosYNaKkC΍k 1g1Pi!n69z3Vٌ[>fZ,_AeBȅVV!f@Ěkqvv66)= BWOXn  ޼j,dプ%dxÃӫ^uyz)<ȥ&ϕI4&0d'j,`?p8,F4pp}zQ9 je-ޝ5PS8xi :VIّdFOd[G! 6plw~ekhn u\0dXsuۏs>rTnM2ݰVb–ɯýM9qD%"a$S;@FW)g✔U7" {tC~8|39PE۽g?%QOzæ4$9y,+_}Z#_{WSEl1F>bȺ\Z3 -cs'~59]^vԿ6)6kվ]'WuRٶaYx7}m? Bkzq>Aiw}<Ih{%8hs4kC{yNײi/ ?cLgF\^A5# \Ȃfozo^?iN"mdܷeu#..rMA!%RCF=rQd2nեh;4 Cgk)$g󨲵|t81{bv~V79;YsOB50qkT.P+> 2D 3h$`ZA_,/v?#gVP=4Ώ>}R5FOfYxC~[W;&&*@8wrfHET{Iyd: ^5 UIRr( {5ZKaSO3SO$,V=I@,vqQjn6vYӘK<Be9euw CG^)Z0%Ab&o+IFc!˞( =M".< 0(&&#yП}x䵚I17yD,5`&_9f%)`0 |4:-4nfύzH;ԍM5Ƕ &WnsBH!6[M !M0h< *qYd6Bˣ:84F'kԃ;"kKPd݌kCz;c *A ̒{ fӽԌ79y d{?f+~R̫ؖX|niXԲA?\bGʹ;h^N%63;-|ZHY-!ewVة.D5ٸ/71{2 ֧ʞT6ȫnRoUl{kp^{VTip>|R-<^7_~O@]{q`]0) inr} Bp|I(O;.q4|~҄B2C\nlv_Y6&FYt -ʉAGq\.|is2[= ["t+v sDa!k˵V ~0pqy u8Qit&c>H-ֶy4:8xkdL|rZe:ɓ$ddQ^f!E?E[zgJ%/OS`B)MDYB5"!\'}ro.Yu8_JEwŰ^.:6GAȼYrB.u9+Z38;p˰2珄L)r`o.o~0{BEC#vd8tq~jGjI˷bUk2di$`llstŢ~ ֥rio'Q j F-ǎIjaE"Nc.ݯo0 l2 fpDIdh=jx Mj-_qeҩ eG'Q`Rj[πnU&  [VLC' N1 1_?sqa_."c e?pT; tz M17vI#2W<~y[83'm=.v_dω=fs3y.!&ٓo^hݕ!iŘfP3/}ӕV |'ogٔdg7I6A@ OY!p@u*|qo 8,2/j`*d\ec^'pOࢼ3) \2E\4U.n`p! @JU-'$% [mPI6U4v}%}XGL8>%k[X?1McTӄz N *J7@CM'W,ݭ#N%u2]95;=iѱ>b+[\G1S5yWT"OR7kI'LBwNyW4=,^1.8g~$Ih8\8G'>44=EBjy4W ctI'lAU;'jAӬ?V6Dh>!aT*-Ҡ؞"z#.ϢAˀ!kZ}σw^Ѳ:oȊKCLmS|_ EpI[t/i=vxBXwy5}GXi`>ҀAP L]ɀH=ؿ􂵐PiIIJ- ]FO5J敋 IwH Ywc+kz:׺c =p-+IxdJd;-Gc̼Էv3`~FހkD h8UUؒ"bзC*dlޙhJmu?vp;|30FvL%d3Azrr2 .dMW!K&dRȦ׊~d mD%4*ʷ_Դ-YwP=EAmZB=)8X9D`F~- ,|? Y*:NPΫgO cmt譠vӠ66{ƳJV-O9^,hhrq&Yİ:A:tЗ5ZTp! C"6=A٨hZ0F Av`8D#ҼzBS@D;හĖCD5}lLsG:tX/N=ֱ|-"Sl/uA"ub7n8ke0lH?kF܏qIESjlX#0i,&~vHu|R~F):o>ʰƥ^1ra{in}v+޼pox^(_}ʟ>]@?E0eͽ]nqJ; ҋ<哜57"3ظ;d(jo:,! eR˞sNM)X65IŐm7QOiy e~%dɍ4,,? ׇ ,PlfٽJ%R 3BV1I󵉢'C,uSY&+._LhZ 0 $φ,Uzi '(]syyHp+Ʒ#ta\S3Ƿ=.*=W@Ph .jz!/S4bmGlڗ(0d<מ8|l?&`Hm{K/<,tZ˳~ !N`? 1 ns\tiiv&oڟ/w3-JN͚~vٽӈ(J63˰~bm~Y{EJ|E4H\y׳ k 2itLoF]b% Vn]`PVu'j3t 4ӮV% _}H9 ڍUل֝r"F$1wj+^jP0ؿ< y~Y9 =o`ZZz3x+dW_z\?ZYesN㾡2X9f>T;J_@`k'ۢe7D$Y_n !rsYJeNc?s''lɳoN/{,܏/}ZښFg%G$hU|p`_Aŭ$UmЙ1sy1L+,?cW.𳉬pخ7i :ZWIcM/ǓŤWok˭'K#CՁL!/U®]ҵ<dp+f 8jP0Y  ]$πpb2X%g^Q%ZY}T{~:k~e>ѷ%Fo_=W?~×#i/-ޖ%V|mT[(uw^C썓io&߯HoD@v⺗Q?[7_;S9/ho=wpwsv~ fls'/p+NK~_jO{,"DL&??%?( ywa| ,?C\Kx &dw={ʦe{YYgfvO E.fzwhzf!_\]HH/vs7Ok1̑щܗwS{M}ln˿]fc0?CGl؟"j3L 'd2u'D }kkUџFdq} }jaaLMM-..#D"6B[D"*( /))˻{nDDDvvvMM .-ZD"nnnl zyxx455-,,g!B giaaa``1::ŋ`΂sΝի>i$!B Q4 Օ~^^^gϊokkՍ#yYD$,5<<\YYioo/$$w)U9KHH\pAPPk̀E!Et`dd֭[ϟ?y򤨨 x 8ѣΆڷgi_2w\FNoityyloo*++;s >nDDč7ddd8>٣G8qB@@:::ĦQXgOQi[Ѧ}kiɉ%, Z|dbhWŘ́@o& ؁HH???Ǐ >|x5`;v( cŮb}cn4_Vg֯M!`KDFϣ$2gĆ.ŘKS^2St&u[BP1sKDĹ@obNMMD#txx\ZZСCJ511 }ymmmuuuEEEQQQZZ2- u֘`cpzuN_$b{CnYKe~~e86{'snE?epH[io܋>&>7\,6k,Bz1/z1X y+MBK ; :1v, Ntw%4:0YbYJ] |w$ch?"E" ;22V`ܹ6..eeemmm~~~֗.]/===98H$lcpyHCop`9q ИE" (ɤ 'SL& =\hi\0LL&HDw$N$ITj08D I< A%.b _@@[ZZXǏoRRR޽]YYLZh--gsss\@v%1QSh0,\ψTL[rM Plmi^桝{,{QpPgDj f[Ɗ~h'6aƱLKˍbj]Pt=ghUVmh͠Sy󆣶wjI?S$+eF6:<鶑5U۠Z \Ƞ& j܊r.i:2ƾhU T/"d\2j&zTsHt/Ot.+#8ee88_8}[8y3Nk{uX.d{ZkjI{:2쾋^ 0Wko`mnlmc`c` v6Ѳs}ٍ2"E K`0@rrr7nkO>MNNvss322255 ܼysBB0`9sCklhYy'6 \1LBHXc泦*$,٤DW55;5 = d4S੣ng.:9_^"Xᒀѩ:UY.hiÒF=h% Sl|i ʖ)6{ꎩWnmhl<OL~L"#퇭XpMK:.w5uwhқVLf1ltoWϱԊ${Q%یɎ{z;n .@Xb5a& }X?0^hS5<9 h/n[BESm3bVS+w{<\ktP{ mEM5ukc,-Yj[C7w(UkwPC! Y:gZa+do-CXW¢uv'wv>i $LhȦrW)hnnodn)ܚm @nJEA@e"S"moo<okk󋈈yUYYYAAAzz: Ǐ=zęfy-+++baZZZd9N!M`Ht.j8[ss5ҖC\FX0d9 B4fšnkEipX;cN? JcO[ q5[)á,|( CyoBD2*].Xdw.@XD /))),,lMKK.// SWW!4z%40U4䴓ڛ*#q~#طCX{ <[0um%ољ&*Z0Sb,da ݔz^Q%lv<=qHt\}5j0M>G[ҥe)j+.H2L6eKoS  MKtTPͅ5C&RnV_Bh7$~! mK\mH= qieȒe`Zd7r% e1{F(_nj3 ;ozc%WCKH\4ד"ldCvaa&ZK600|yPPPLL 8,blppCC`g/HKT%q5%4/4rN5 z⎙󠩾vD3h:{*}^%xӽ \Sjbjݦˢ.$tEUF'a> EY񞑾 gp[^~7u_,bτ+!Ko_Ix.wUZIqy35jmi*dJYLD11N BBweCuQ&BG$h;\cZC_,kchQw(W WHV 6~I0Y DW>uL\aQ*anVw ?q*Q1ɐiȘ}l|UPBͺI߂X?[a&-zXSb/wV}pPiZL悌Qe$hU3W$={ OG|dQq80`;;;9_luuu TuvvvEX>}ݻwa lXS)h*7]6q0槦g0$ Ϧ'S(+^k) 4 Aag4:BDx,@$S8e :n59%XL:z_z/4t/}h)m5ƁPT9=p, ;9>3DhQ[}-LMN𜩩dR0Y$9PĹ 8n}q ˱$,&DY.N2Οt fff1S PD7A$YTto(Ddo aff8 pecccaajffv|}}U9xV?DgR溣Cт"~gd 3;;;<zg´!B 藋%եA,"D!E"!B@"D>>G#!!>G6dC6dC}F"DLd!B,"D!E"Dd!B,"D!E?B ?*aLD]S?bN7?"B%&E#(m9D[ E 4 NBE Dáο==PΠ3#. *HcB"Ý!bWITOC#=K#WEjZe禯R2rZ;f{d CگTDɁkq6 kJ Ə^'XWJŒv`~NĽ#͋Y~J^kl=w_EʻsI&T{j= a$3T7G4N&S:J~9Lpwcr_3#i:^d? =o#ti#YқAdo;)p^Z4v1wY,ֿ&--_U(5",յS Yz=L_9?&L–& F Q9/SiFEωw\:stH.l?jcw'1AR%z VE^ja=} r#)u֊H 5Q(ޯ2[l@0'n;x;:˪y_~ۦ?S۟$=i=m]숣ݮYJgy^*;|l,JJl!)8J!cf0 I 2{2EţfHA ?z4BzMLpM'V'Rk9d]}{ O-,bWygn Wjlv=/,{fԿerf-%{¡ 6nO>Ww]:Cq'N=Ww ;o;%shdReJBgR|M)#1pdEy9D|#Ľ1?︆߳/zjlW]c%hD24`H#(eM2zH42&3=^ڢ ³:3V}BJs L")ٔuW,kϘ Ph"]ɹG(&I]gP4,v_R#lKX&z7d=C! 64۸ڹl6~N_Z 4=Yް8=n]nuS쫭1L`cm?pf =G<7bz'KFa `2B;n}r) IV~ՒfOM>#M`*%Ϊ6Ovq'.x<@x9(iV`-P.-s߳h<o;W8ƍ^|v>Ä }D :=lBM{Wr'~ = PSwV17%׻8ZNBub[^@鳇Rw?~!m|cP9,5g}wT_:Ǽ8f8C3NmP-㥱[r RN#h$%(jBArcǬс9m($DSSZZnqTJ јbtS,W 6F^<ŏ*ՍZq7ԒQ1 p-[S+#@Wx-1u7կyЗWϋ; edrX?WS/w>p7 :o)w=]7u/g,-L TQu}0&_ݸ&Y욉Cz7̣ҲVrF^[0ZoO5%S1MH^ZkK͍ΫG]o4/K}Y,EⲔIh(-~y^JIaiUI5eh$3A\檺o|һ UaG# gY"0ZHSKIiuO1#bk.&HG[F++0d42Qe;ʥ9zC# =/j4FIʮ]흖{')sKYLڪ$ZDK=iuTF1'FS#d룣x ;4ցO/|A\TSS/ki9tG}jg?qʅϜuNMN8uNR:*+V>B1" mhj|ɝ/Ķ=tMm2࿢m{${Iȱoxm n;爰9Cǝltvᤴ6IBEej/ :u3OGQb"'(jnPoîRfn'YLC|G٭v-K!R -jO= *sO1CF{s/i:JCjQ|BNȻ/lpc*Irj#:nUt~vW̎_Zk+Z RږYY\f-diعأFMA:B#Z&{4ǶʋXReY4je=Iad dЉ&&F:;kw$w@~'b;܁=Iۃ3 .c&gYE55Xù'LgI4~ zA2í LM?oMJx3Ᏺs.H7Ȣ o9"ж}GCTsx?x0 +:ܥָӛx]Ӱ}ba>;eچY>@*ٻeH&gH>).EP!𣏄@ͭ?sI|b ?M.@uI|,9\T+ kf*q.w պ煅Eu"ot`QCDw8ߟdϳ ]ijK Y|(ɞ{]}.yAr! n}&w-sxPyJ& v= Xע) <` Ȫgw%p ;.}8x!!t\~|lzkIF6#Y6jd\<[(l49Z!k-ҍ[>g,zLǨ T EzT2AIRPSLa((eܭ@ۈj?Vk盍8'Bo[)X: 7,IЉq|Co#ŏ'k:0KU;,{'íuA2"Rq~ˇ/<| )U ]=պbК#ϫ~xW(vAD0_S}<ɢvƝwk„k{?=Z!zmm5_8MP@H:K=PFT>xgz^CDi?rqEX>}' CFB{[?䔐n,-'#hca-O3XYScC#`8z CTSI.Ȓ-PwXhY_R@E*}y2u [ԙxvVLA3_YIЛGNI])9׼6)el|r*y5%X d2_㱷Cv^6c&!TT/GgC6#hf.j?KԖ*b4D!`srkXzc+;eoάuP\5rhZkC#X?Ol~7JU--O1)JJ50 :nC|vYݬx& !hYZcO)$Z36k2uSCW6J׵޼C2$E{؝ΛᱝbJ&~ A+5RZՇ$Tǵ1锷XD*q} B2Z =~Ӵ% cƦN7kMc`XoFud'¥n 8 = ;6&=l8T/_#[+XAFqO9BVrӁ}W B?$?=kqI6j8 ‹GY{\Uʝ~sѥ.Y1={zQexp8ŽuO"9ipgBј%wc6I/[Gg_Y66˔W9U\ >Yp$愪~U0eko{uiqc4[,j|nsAt<B*P ֩X{-QM;+7BAQ9YuYBNF}\T) g|w<[ǨWhs&*IJZ;{O,:[]TR$SJ=/^窮{R1yRAE'kgߠD}&? ^Fnnƾhoz(._,'#шٔjM} C#:gPOO:j$XӴn >}ϯ6v;LaR&-۽^o.lVhԳo^08^eaӧ\yggJTk{ "֞g`=izA>Y[W_} ȒF{Fmdr*8ds][#u-]ËoSQ }mu;?:nroCt<̙ƶe;褆Gf3ġaxGzLj _i?qTYpѾJg.őQW*v. 먯ootOu O(8`W}cXfyW/[:;g,XjC dkskc+M-PwG}CG$ _ffp9;0HT_{MeMImG"c"'ϰS=}c&3q5q,TQЅ(SS(tPIW>ЏÌM p󢻹ΟN8?>6 zothwUYuCDDC<6c~5OAMBs脙ƾ9LI2\suX,s9<5^^Vǩ h_{IYmuCk& c+ i!rώ N.WVf}K[.dV>\Z?e-M5hL ni.+Yp%TU c(4 LTWK]iY}}7X1__29Mi~d*"L}~~G+۝G?Cc~P 2nf~ A󳧧XmmmPUVV`.**ʊ2556,#G8pq𧎎`דHڞo KL ڒ,Hi L*grLM <L݀ >0%7S;~">X,xc/^ koo /^êϿ}Ç7lC uT9K(UсUoM(Lb=ۮï#ǹ_ֶ P?i?{a.tsձ!KŴGoG>YD^L&sttّ/_3WRRJJJflUUg6X]\\fT:h2hRr={L:mً~ݫwj :v3Cݯ6tEG{_4ڊ/FP1 Y,"6 ٷL:}5LO!Ji{8UjcZ~>y;33s,4*4,F}}}+ JKK{ݸq# 665555!!!99ꫯ[hqqq Wk Yl{iL]~xZX󏪝&\ ɪyPY¯Z['ACF^7v=јu/FHHl*Xx'C9Muŗ:Ya#V%"4V;pE1$^H4 zZ쥬&ս q).YSCM% .s"Y^uUn浤NȈ32RT6]傆)OWu:ȒrS<4T,C: f棌ƊiEu wn++XqF-K`[Ix\VSpS^᪺Wr7J, ~#l q⳨ՀCz"bҺnnvCx >MSS \ߗJ3<4)ـL4F;ٸ[~lI馩ur.p8\7,AHccM6988(**ə߼ySGGGZZZYYMCCcΝ,]<==z;#-s؆Q4zGC BgX2gِ䡡jf3ᮣ-[࡭n{I}K loxFjp1Vu3nbv U"c G8So7YsBqbY ̲ʖY6}\O=wr[|BV9<#7Ugx*fFۉB/ -tc. i-; F k~oӖ U){̶57kDloAWP~D]9P> 7yIU k 7sUjښ=pC }r_tLM HkR 잌y[1t/("qx Pŝ>mxp[Zkv45b9H.*U=/X,G;vL__eIIIxx68~SSS3`||ggklj$B;uwG9Pt3hXFm PwG6d^ٍ'#Wŵ^ͽ+e%:($ [.Uu\: L_r}w>;OBQ/GHH)Lʵ4_./ÌyꠑfzfRsosp5[O wj8{+]w㓭27jShK}+bpәù2~خ{-}݇f*wI枳;P^`A#9 -cn{k9*c|sqŏdIZU4F m{Rlq}'}GAZ.U .[pz!@2(w9bf9%d6w1d9HA fbMg4\LNkOtlx d/jIq![8 ٛܵ{Ymt [{^%c_c iO ry681͆zI\.k(taZuUsfePzMUtkM0|6*@1_6Nl;zMQm?jrh.3g(IkfƞyB71͈gi]*Vsȷ"pr^F(dsssR ݻWRRC`#yyyk׮,Y:+#ӘJΑ3V v>\tSR4V\bhw;oH54l]z35KOLI m{xAٸW3ǡ@[RE5m,hB[N$|ske3'n^ ~ƍH_㤠13*⭶\_%ݢ`&!Y6\Jh*W΂!OҹS&v'uynj.nR8Қ'VyLL㖭vE.+#ߗXJ"8%JQMiBf"Eĝ](yvqq,0c[8~X`fffwtt- XYj}Uu]뚚Uu;{ tͣu.9?hA- /xf#z 0x*sQDFV.e.ɒwkju\:Wo7[uA%e=m[q̀5m!wHLEZF-s6i+/H_]4s[IyZS{_p"䆜i󰛴鮫ÃU#%(UI㼖[e\O9-YmKBqOד2||׼imL]6t*rRsSTkBSl]{i.{Rw(c~+br =U 2Dd(Dm0RזTTqi[It̅rz Iw}}c3ʹE*ҪWu.kAwy,/'!5|m,"b0xglmmDDD8QUU }%Xda9PּLbB2)4uivb5G̡LdҨ5t|Da(L6BkXZZbMˤagGGQ Dt tff+1?69x@PVat0jza}_&J 3<2E&'1$0|XF.@H]7$SV(dJ25eD( "ZNy:fzjdr4'we+2BMoGM$kRFC*ʝ .mpvI"B hx 1jCCCݪ lX'''sssMM˗/?ւ[uuu $K5YcZba|x$_"zT*a9<JNN`v>qKK YJy.BOD{譐[ <ݽ5!ق@яijjje"ŋkbbr YYٔdU ,b$3O8PyE8y ,!`rrXQQ_v X222ȩSTTT 9kllD'YDoge[---;}4'd544BBBJJJ% ̱d:!B@ѻ,@'0K4b7ޢ["Pj6ӥDZR>|xD eeemmm---m-ji=^cVcI}ӶIE]K/.+,(.Z100 --PSS9 hjk?2%Mp=#)ťQK?:yjz<#+anAai壢ʚwX i+KK p+@ތPSUQVQC4w_&6ț_UYIIYWҶ0Ur4t % $l N"h5j İ-R"h ASQOM[.I+٨+ڨ{m?&<33Ghj}[00'83"?ozM$͎t4 恩7/ĩ$+"yl86G:5@hijhmmkB:L*yjjilDGB}Yq)FK&v6.x2CBsSKg[k+*i ubRv SSUUeS+3.W_xHvR즢hmΛOMEYƵ{QiY5"i6hlQO+עoĎEi4ZFoƌ]i#4M4h$BДis4ioI3=)$A% <3'?Q2f4 .)NS^U?0::[XXϙVޗhYKd^cn]54l<=OUvR5peqw,?ͩnuQ[C3&{HC>^eu?LW);/Sjǎpsp?_3Gilpx0H3|Ҍ(Ȋ:"멈K**HIIJ x 4N.BRۢ(#gPкGQ2 jjb%Ł~Y}se.%vµqK}ՙs DhK@ԩגއYyy4?!#mtl %ٸ^]j2WzB8}RY**;g_c7a*ivvf~F>cMh8.ee} _#Sy=,LN.ä H8&*:&g&Woe^oAIϵVЦ.rvKn^bLP 獵9ЋLc8n2QxoczxkHۺw-CuE\%Kz(f=47h4;g ޮ*wk *O{\&u w[FKٮ{W++7hKskI3’ry4ONMVdfU=*,-!ɯk~N&#moaF(u栢 k/WE[+ƦML>fRKGJ eqv,SΪ|&=/sVGn>9, e zJR<~}lq-7\CNlTW':F8D~Deʛ_:v>~`W* &sN:*qy̶ѓS:rab2Dgb P^|X4ݑ{NYPL^ߋf*ϾIbn \\7M[o&d) h]Xl-b9V6Nv^QEZ96:"""**Okim|otQ0ޝG"HhGb-ju=Ă,[)9E w;*| hF;sX4P^[dϫ&iW|M{ZjK2/X8SWuME >F?Y`,&frawOV•U4"j}Y뤙pYA/RN}[yґu_p4||vEOBI6N5-9SlrN_뙸{f_C[*3&bpA`CNBҬLGNrf@VZHKPT\\\FHk/sIšS݌=`=6u^H@H<e$ͧeZuDZ5;<.q^#'yo. $<&-#N[Eu'ǗfZ',MB'ˎ;ϵM i2-j*s֪67|Fǚ7eB#-*WHI͕ |Tb2uso#$ͽ'\ݽ&cwt#9FK~QyeԖtnAɏio4B,//͔]>]9qڶvJf%h VK- vy6uxiV4FҜv&cTn39G6iF+e1vp`C^|u6LJX//WU-:iZi%,,fL@g:mdȹ.^[Iz֏4Go7\bzf\HyU,^WFKNhxOR6anl"_,{fddDPPP{P--%Vn^Cc#C*8q_1oPOS5YHTXLص`Z 㡿sӷwGw,|Vpz`yC{pRm=jWNq9LyoϧR pҌSTP RjAK{Sjp~%QTrEG }[+gbMyjTxi͵'ͧ\RTiГT =ixgC##YyՃ#2s˫k9%?hk~>)O[{n4JҖuJnu0pˋG5L`ZMWHcz i.ySiv kk }}:&3h$$ 5+@miu'9lw{rCŭJIb'=ܾTdᕧAh/ ST>8_k`Ҭ}%;л&#ŧ5 i&í G #iV` +)S6IuZ)9&'1?|iBl˯ t1}tQT\ 'pv"/{sJ&lP^m\x+ۃKd J,)Lt5dq|c,Ȗs_"lSǔ5ťں6Rz 2nIȬ&*MBآ&P#I̯,,3KF `)HQt_|Gdpc:[t`~:&%+PCOGCRI3zI ؏Ijsk{֣k~2PIQ]RM[ԅUx7E&|<%u*u*ɝ}ý=_Z]J?+M\UFn8O#5r9s'@Fƞ挬ΞEoZ^K)u dULtMmuL =Nvy"2aG BrtW|%5 ],Gaϒ dff %nuN[w7ޞl7Z`Xa#y=my褞OԆ}L/)&fW;"?bL_oY_+ظY{+ˉ3]Ug!]+msSG]X9҂E3r9HASn +Z8jٞ{ż搂utC `fz| [w?4w>I`b]Q=ǘ'gɢN#_Y)>1nrڇ܌̬BLB(ziT*NżV^7VO>i~}'+' <] -'ȉoBz5)c>ZC/_XX/2gNLMKGg }ݭ-3%Aml*+k蝘_Z^dG7UV7t L/mi"qjmtustaLMN-boSscCKkG^թApy12?:<6G^<5Θ BYz7 OԶ^'[Kۖ^.MvtvwwuM?9q4L|]Meeu%y֕]]֏b/ƈt_غ%4=c䮊̋4og[.5g~HKXε׏~U;?U"G?ڣ_"N b۾NQ5[x{ gW}V\(>T|Ł_ܵjWdi]r1#ϖlgCRaFzRҒ8qQQaiu%jUv tGas#)>pBR rRb8%픶7Ic/@*'oسJ3ӓ3;آݤDD=~-!5V g;3ixW\k[= o:!qpYVN4}nꗴe+>SnLOF2~41D4RW??f?>_6BS 6﹙bcl?a-ȼ~g~[vBP+_ߦ"o<ƍ'yUUcWH3ޑWLІDvB#JޯV]f_:WSnos+Nlb.dcl-/!"{*lbbiN8gKkuo;UCob/HC}2_6PnO/ƛG;756Y;L%f 1Y_,u%F-/[݌o~o>!xyun~Jf$K쭗Pj75+HFC{R֒XZ\  HC{? XM52j**x o#:_IDsl9Ϥ G?h"G@Ij5iS)R8!KdZA{rRxAbFq5jIr)])a6'L"F٧bY_}HQLO̿۫$Σd51.v%ʗʁKu^&:v*/)|N'c 6xQTE wO9()()yg PH x{#U8חN~%#K[,L4^p՗$7FI#T's hSLo#(hta}WtLK6oHnE%I-pXWHDHZc VjKdG[IKJ[{yyG$a+ ҉wHH3ф\}ŅK.*AKL;ހ0f:ӃBZ| fja|"*IVظ_>~IUa ͟ocX_Z'*;TК+.'CN̠x2Zbnb ~k$vuVOfZ*J3UԶ5;M)^ 5NJg2[ ]ssEmg$c'AV:\5$ڸy8:yNiv1f{qSvG7qK0-ŧNG`9J(No>3Y>mK%2Hm,F{ wc?UdyS/xf6 ]7tsZ1Ó2K{Pu_ْ!w(UadtIc?\x0u\G|f*u X_4POAAwr6 ڵO5$aq?ou"]YLOD NR5+4wYSƄ+PE뷔lÛZ6e&K9v9;o>*yr)Run5{|6 2p \..m+u.ejlmoG*|Ttؼ+ ,|2) }ݝmC4jI<Yl y4Okuܯ\|AEPͽ <^jɻO? #vi SuNlNW\{KxXc@̉뺇\j.- Ddi.hu.;eىǏ%בUqNJ; t4?Q^LIʼnfbyɜ}6TwpnAzPiupĥho }Xם˽ektNui~Nu-աF\qqug7jŽL"}˴M/BsIL9Thmv5R|( a' sbrZ2bY6nJ\踡.v"%lM.mIݼڷ$jOT <- :sxhs᫽'JP/a'vDyH61m,*!F{2L^v2p}VaoKVl+W]821;pu/tumI[E%~J00:1NMQ4l[W .Si3ve{Kͷ䭜+@nT1n ]sg{=W1-$xY\n5[Iw< 908}2$Z9xgf9X;&CQkh;a;]qCQEcB,4uiҼ9!lty/QC6%2G\&ڬEv13h~en$5&;.fECij$b5`eYr5/u4F|!iu~褌0\&YfS4f`:屍?w_'ceП-& &tSVe'p8vx-7iO\<ۻ9#I, 8=Y*Fم*]۷3 \Q|[S*(S\[_t}v=&B122ڴi޽{wycsjs/f tia&;p JùO-o1baf L~ЉA'N {SLB?l3n?K/TPvB?>}Jw*Pwe.X[ydtF9ǎQ)GlcNHqx;;j3:./þ$,U4/%,ea0C ӌ9s'LGDEڧվS߰H\: {9\׆倀/?)|uCKNN޹s={nݪVhgʬz_q V(cbaNsڎٚbl Ե#rf a{w *vRQQ"i< x_#4=ل?|\\^ov#QK.\c~VA޾%0kz2%tO_56 )]rqEv2QR2.8ٷWS9=c 7eNt0 oS6ؽ'q{N&NMSL\ 0׼Ku&Wܾ~LW{t}QLlVD飳= uU`sL8.a #VM+^C:V[~f_aeߜxy}EOZGih)O Vmo ӻ˩j$I&Jtc1sj>ogW|&ڶotAfk[9'msҌ;++I|!/;xI'i /V_T4utirf)N]uDRWKtq M |hFSDh '2x{{8p ::M,K^}+K*^|Rx`n:)tj=xzy!5Pe?|}RTx~;Ru(f3׍>5ݱ1u`C#f-SԱG,_t@Mu@ҌM! eևU[J1 ӥoֹL\sxi| #_̎v޴6ֆᅴ8?qCcgUIy5:# cގ4/Q)C Ǵ]NH9ݟDpa:lK6bqE5s@USoCI6KYJu8)Ƃ?؝(c*z6Z+OC'Қo0J71s+;.oʥkqis<Բ4 'K}LkտHJo]hiRںiܬI-K:Wvᅕɶl؍rn'/R|𻯓\%){Vi?Tͣ.WDܱm_7|C,8癛/flyf6K3 %9}GkW7syyy2h>KrAW/c#U4qɜX^%MuQP\n*ȮG3x iBJ3sNYzyT{>jVsϙlN, 4L#PP:Ji"ekjOnsĤy360Y$H.v|14csJ&N2/|g2iN'RkId,ccgXM[JTNL4i~Z-Rϟ礙 _z<2;=?uuu a{S3\)yRM8}eJuQuN6=n y CܾuǤyPE2D[a2\]X_ﺕ3[9<6|rkakJ $4c=77;<3VX7>-ޯУzpuYOzo}q<Tel%ʰX`l=pa>dD$U4%,ų(ˣ.y򋈋s 9\,eoe=1.>I%uEI=xΨc'(xDi+ˡ8=9{>mlW";+Rd[9<yv_BOr* uW{3tb>z#Tūj+[FcS#,6ZTbUT]s56t @LEeչ8{^N~9nuOE E]}]NV aC[?]oMv"U>߿G\MWC'e{D]he$&"m"&a{}\Z+ yѶl*|||SGVc˰ Hj*K|6gIn"^4_~VAHPQ@WUdyBHs,6TaX);oI֧@5JJfud*ǜZ)-gR +=;Eu,\ZQ+ Uuu4 x B~YM]U V";V{n;-!!.i_5 PYfr/&,#sc |X`ӆ.x&ڏ RnU1f؏&;l#ߧ] s j(*Yu6vvyY~1Km-R[kq!|j[ߋf)f1eĿIiy7GswnEzF-kxU͸}zNv> w"_ 3cn, 0mh!Q"].aCzo]9\J*ĻzRѿr|op|?;'{D?fs) S RCMY' >͎6I3C&B}SSom О;3AolPfhe#M Kl~1wuaǙVfj-3tkihi^XeA۲4>YW3P{c]-gxzI&L5Ρ K cˑ=sOqxvuR)VBm}<4ǺFaf}\. vշ/SHc#X{ER=]NkI!v, Mn?.ƶvZ3_ ,gKSq쪫knZ E{䜩_^~>N+9OlГ]եKɾ1F8^ljꝥ]zBYess86:0>MG'IkyblbvLJg}(֧o|USGu%C|[ ?[,ǝb-mLYhn',8v;E~,׬M',-D3rBL HDf'{p!fAq,aT##vw:&~KX"[>b3 ϻDRkϗf`xO]"{ҝ"(0 9|$]zJ:UX$d |`&*򾁡~SdcqG\`?mu\3}Wݯ%fy$ky[-˸.(&,A6@3QԱ212:y|՜WQP7;tc6( _y50ym>I cq%0q2uжrfvx +-rr˻Ǘ ;^ 66›7&eV-}ifx!qu"?;D_wy7VF"[ȹA. 44 H3H3 444 ZziކӁsq(xYȴUPj H2L7?02ms%O1|{tKj4 4H34H34H34H34CH34H34H34H34 ;aL^XX|[Q(.БLLNtIAiiiiK3}?WVVQDűJ}O8w"L&䏿W1?sxnlnmlnkmDKcK[=yzz-~Eaiehd+v@&8<2tW̴E ypxtbU6v|M=Ĕf^3z+^ ߽x51+mBONA*p|br]."^YYyGܻz٨ҾbK_V{G73sozW/h#3'Lt|ԕʚ޾ GFdzW$XwqŻ033K}xWи{s#꽔fc' ͭ`Noʚ~g 9;yZVHv(OWVW=duZ;:7rl,()7<==*k,(RLMϬ=5@\оb312_3qîW27>^/I_%յ~o۽O DyBx}b׋WXp?+ITut8!"0삶DVnzd~qONVвkƱI {{Y$^b<AyR[ehieϯc*Lm\k7;!nthx+ǮݼՃw51eua啵v6H NWM̡v ILBrQY%Zy'iAҭ_W\Vy0փ?RTZ66d4L.'$/-/S&$_й5^qm~~Y^Q/$,<(jjB#ce4&iurjpYu#;Xzi!FH]OM!jmj|r?)e|'L^ЪkuLlo=uuzMsmE((a?02Q$A568"u }ci :KhJ߸z5oZNyTTvu2mXLTcXΡf`i~$m+(!8IWosњwu;)uytlNZ& Nh虝 Z$a>GP/_S7D.ER؅]=}(t֦MNτ_Ps DWOT+Po|=̱Ivn>Xt]-5t4t&wv=g&>rr S3Q rYn*kcBEʼnH9 #kEy D+KV80!ʇ,ͨzL iv=]?C(\VVgd塌Ƃ/*<PJʫ&&lNF`phEz=|SaḦQhhjnGމB&*]3Sg/QViJWt/Qܡz{-.VkG' 'OTutںcrfv+2 $7!2}HB_0"9K2\d?C#(BDZ*2F jF֣EbAq9Ev7/4^208ZJ͠ccJ3>+jQqIӳhQ,t*qIP"(dG ,ofpv*,DE:҆>815mr,l8rD(-.-ٸrB;HqE74#T38mr<a|j GL&;q5ڎ)3[@=M#Ilřb1mMmj0}mG;&]4xTXu%elCkQ'BO9v)> 8֎|Y Yt< >o~ҭ4$>MGsg_DE*W)[輞**/}sXՕ6U޾~#+Gt>O(ʠt_ t0Di0tD'70Lݎ>{J:IRgi]Y: 7ں~ˆPT'tJ#E/WTJR/^EZGB/%sWVW`]e5|k\#~<>9ya^5(t~rAq9ϓӨI".A[.T$UQ Ge?*,,-? E0㨎VR~_^[أxf"QB=t{yX6꠰.F@F|. "{@|.Z^ukGk7;zQ;q] H&BJ,--=W)R~Uՠݝ#cw{t /i~ rZhe`hޣwx(࢘6䐁n؏oX"Kg|sx0*oOع7>+NjF}# R{E?=ywݷ{7igGgǬc10YQA%"A%# "&$(Qrt&sΡݼoեg̎~=u޺U_k KnT*(ۻp?)|Z퇚_5uP*AH}O"|]Ǥ7цǦٞfA$w&bq|rrfFewj&~חHPIZOyb_$3|Cs[Zn2ݼ~옡AOow_B"$ۅPNҝL:FI Jz{Q@8F?T 4LmfBzH{۴Akjf8= [0h@:a&tF'Y9]㟔H|AC?dB?I إk^o}8MT7_P(l.HJ"+նu " %䋱 p3*!mrq#W;w;|t~=0]GLR 7=Pc0B%+lusҠ!14!2%_ kYӱz/2bxL92S:G,m] ½[W!t7ئ]G29I _k,iCЊuQ>ںx{1nfC?s+yٹWPeqPC.sPϣUQC*޾C e#^ !E]N5PeG}De C9uNPd ߅1PGhLt57畲 !2m]G،4?A5'$e/`yq-TPouNy]g/"p7DSˎA|׃m6 $çϑI#%e4C'ϒ=}?/mupHVmfOt u2i ~;Nx}] ]p뽼্,t ͟5quҰ}.$cFV@A!3I?(#/> x1Cp"cT*P:PY顺ZOJ-mNnT>k_VGh44Bc +HIӽǍ@@p;\z~W&`|٭mh 8nh [mw@Q&c\j-/ R\^  G5#c-f&KB.NSKMX&,?6>IHp/8j8qҊz&'bA %lN$;ŅLMoG;Nē&!NTt Wwv q*7C7s47YAB܂ȱrN0hv #_uqYdHd4e@LTJvܒWT E\xͳCQNvE5uSwuUcL[Rg @.'`f=12l|bJLYY[7Bi{TWՀC zA KH(}j<,;?ZZ^U\Z _|^=<k3D0],%?P\^5e)+䘤y8Nس`&oPQ.&33 (f@1Ik-'64$؁zMVTAۼh#=Ax!\>dۜnߡ{@FA|kT9B{rMmpNjB9&ShkII<o鄂i::!V0RYWͅ_ _|moz/_+Gw|ieທw,0SAA~zZڭt 4|I[],yͯ<{`HdhTP7̒?S+1a !QvCãA}Მ]ߠ]tܸnT|2Ff%6)%$".yO>:Ehd[AAׄ\.6\F$;!(  Ҍ   (  Ҍ   J3  4#  J3  4#  J3  4#  J3  4#  J3   (  Ҍ   (  Ҍ   (  Ҍ   (  Ҍ   bftt`LzWOpR"sE),nZ'5IJJmaPCevcف:xG_<:6yy(gf^ͤ*Ōrކ~&J@ׁBP-ڋS)*J[*\jQNV_._/xFsU*^V29ke/ɤR3_ 96_rBP|1G'- gr|1#+sa 3/_EYA&x;_?3 UQNvcC‚}|CNc<6jqvOZmFORbvrthjF1ܹ_9X\@'+wka_?;.@܍웚t%>b,HW(T=kcd7(eRu-r݋#Jޝ<isв$Y^L+7t0TKw?cCl)ݴ,=l}֏Ae;@wg+W={V}5/Af Tmg}Ŧ?c%ߒ`o}ۍ7ZFȕ`g?[U[r;>館הl@XGY@IcQ,~/y<3/U*RJ[rK3Ӝ#έS29S%Rs`.#ʼn/rk; g3y,lfu1=P|ƐnZG\iCGV"چTPR~#lr5ӛ;0+hm?q>4wŤi%.K}>IsfJK"##W\illP_gr,e];>aAQb;kђK$6۶%OC&c$zlI1}r$ꅭNuQ<53w,}^;#ytsS[ZsbEeK|z'+7z+^pC'[;I3'gUTsJ+J*JD|?gfV5P+T6NVxWm];\߹ѕ7%͛q&ݿuKiZm_lxOp.RD"'^N' JYQ49M u45AzVY 99E#9,^fA-5zzL,⊩u98B!"ͽu٩Y6iF *(V,~yG=Hkz|t ouDsВ (v䇻[гGi~oQV[ӿȮJykBkf>[?|׮]eZcQdQlfzVR MYmXF W\B+&%Q}?Nge%|rį"{ni>_+ ϟut97GA`Qa_^?EK3`UE60G4KN" ]N>=fsG+m+Wj\q@(ZKD%-pғ>IVc^e*/۞(d47qS+*ͯ 'tRm0V/WclC;5|01n9N/6iI25JYY1lsz\&y6**jÆ VڼysyyBe>xDO^m} f+Wlm_ΥLYyu_4QQNƴsC7>ٱ\>vdhs5ۿ-7꩟hۍk5+19=$".<:#-\(⒖AaR",_9^#Sq@=SIY.g2'5(^l(rR]n;['+N~~5rl˩GU)<)wD&DŽ?z>a1 X;bvWȧ!O“] mv3kjڵ5koߞ75KRRB%Ռ2eX0IPߓdq-Čfsᙶ ~0JB bS q:Gۤ~iŬ6崍S;HYec:x iŌ4gdlAn~YmCG`{kSYIq6_UT74rx{L,nQECSM}#jjr|jF GWV [aQCoOUia6W-monQs\f1Y$)lBQW8䜉]O=M-m̤?im.'#9>E܉1c#E46>Ĩљ F@%ǁAIE6/23"h 2iB/j uKsZZڊ+֭[fׯ5C'ذsݯt݋ٳGrڛ\!/ s&ђY/ٰHUwtN*#Wsα, 0` |8uȔ" z[|ݻƤ(0` PQ1` 0444c 044X:!a0` |ŷ*^>o%## fAAyà4#  J3  4#  J3  4#  J3  4#  Ȣ1]IENDB`backintime-1.5.4/doc/maintain/_images/2_to_weblate_03.png000066400000000000000000000672431477034762000232040ustar00rootroot00000000000000PNG  IHDRL3#sRGBgAMA a pHYsMMgn8IDATx|g{t9xfIql`s9(D @B rЊ[sι+ݯ D~߸U]UT=z!y+36@@r JNS #î@ ȠIyEU=p:l7̏\yz3Ym6x@ #9N1`.N<34zfyU#Џj5L꺊vŮA 2};#ѕ7}?v)3^j&OH(i>[r=4{}g:lTp>auQk z2NpɑSCc>@ [7#Tן4FEV[`T(Z&FosX]% ٕ2Y7 M7 CY~̌Kq5MN3kɺm{442_='=~C7ud@Xiͺ͡/s)뎵 M1eǂ. Z| s:ސ1an9+b>奨c?;ܱ^CRM~܌SڌGfk3Nqca*La['icWlް!pWY5Yum lpܬ#|x}9]w 8{cUfzx'9)nՎk;7Lhґb.]gG!m93'//D?񻛳|í779p]޺fuT =z%We<^N7uYCpMB;NCxA-Z1+;qvy1;>ݭ2C:}GW߉c< J30*j:#H` X=ZV0-Im7#s :Eij\LЭ#>x5yC0"{Mº+nXz} f+3崨KRc#O-SUnz-j׮"ED}ꥤ䋜NJQ ~2#7qwOQi3YOi2 ͕΀sÑeAl޳|m{T7C[v :Iyŏ3Wf)cɪymk'̿\BKn_~QH.^{8v{t¶ϛ.Q"ɝ˦(|MGof%ꫛƭ*wkQuV40JZ?c\$9EQ\q/aӣ$屛OXIK @ 7sv31q ˒RZ;eq ɣ'ϻn2Y|?wVr+K&¦:Κ;lʥ6_rn􆮖N4{ f+p2R=H~.6'ʕk*'(?ivSfq7Ѕc衁tw孭#f(;ypՁ 9y%J4+e V'=0oLn_fʼneF.a?fQlrVYwFn2fݻ `US!t9E.鬭-j{?eQm!3kOZM )!Ci6]UʩS&^xı8M_W{lvcRȺI]r`A 9d4Bqu}S1H%U l. ymHkЪ_7#Z'Q:FgiTD.Jb:$N'"NoRʥƚjVC_e4 &k-fUSTr OF iښ&Dk5ј*U35tbX#uvKFڣL"djAwWB [QMfb4YЏ&CWJLZCZh;G9 &ڋZ٠ қyHMH/g44h֢茨z z &oLo4cJC7e=N7#@ޚ~UO3=yZjm?#M9#@ oQoO%'灏2X 4A @ $@ H@ @@ru "K!y+3C Vfo) 9$ 9H@r@r cI4 x5JR.WJ}L"]N[PG<6v6t(`Lru`k^<v5{s§S1',硷1[Y|䉫W&9 qΘ2QGgkcWivSxO]0bԛ܈[s٠P~cDV/+1"Tha@rN^u }hroƞ?sdK}79zW)n+=ψR[VEZɹu$:vQ Ey֭ =w|gJR݈\Jȴ;3n<uR&ΉŠصk.Uv3Q1j̵5}Ma-BnQ,b}iγ"vR%g_~V`%/L+I\J|$M$78y=3\;qv5A[zgE~+7r-SqEF-;Q,Wu3:zl%HxsΊ@ŗnUkۏ%|iE#N:iSI.j$9fS[OT؋5Qu*L*9\U`#goĜ /2*S$'= 9W/y/]/lBX;`6A9*.%7gcތ8sM2f-*9t[;ZX NN:Z eR3ᐶ$DET:X׾FOP^MCER.lqNU9ka1.!=^ d=6fc9lD*Ht  Q{Kenܺ]Q-[ :JcqC e7Qr]~mC3@ FP%W^Yi)$@-$Aʖ.c_ں\W#z xav p B7tp^*ArSLNOJMHNZݔ\gpZ❛wzD/.]U^wfܸkͦ[nݻ|=#[rBdysܰk͖=6ܐ$GzQo;vޠ3Z,?ѝo{-vnB[nO?+ =qws JGOxH*?sIfnQ߷n}GxI.?]7kv$5SPܨE:Y,n u!Euض/ê\8i(Y;VT1enH]#%P4muf;aD۴3cێ3\eϵ3̦]ኳuNZ۫L,D 1;/_ܥ,7aSbZ nfPHr&\&(gǚk&l=ke?|9 a:Q36DL ?Y"uBrKY !as_4zʂ]{Zg-)T)(}`vN=G^\iwNȭY 7*7} Hڹ7Wx9-We4[Nd4+VzUrNBItUg\/ crr` Už^LM{OA+;{r^pwOE 2f*<&٥+~MXpqې:3Bb T"Q㞀}[T65f[abK nܖkN%2AS^ЁشZ Wױ\f~sH)5:]/S(ZʘV%KnNR.+sЯ 팎<w9d>˭5 &z՜ʣvU+R&F=~rX{6<}%);ҽ͟ik+Ǟɤ"sOrg_ѯ .w>GO#d#f=ynذ Mm[YLK]>Is©mw$W77oQ퓜z1eZʩhGDweJVq|(Pvf* ʓ.ܗs#'~Ǫ?O;vэp"{&-8DrێwX ZƔM[B}֍ݐIWw))JT<+sYP6ż fZu0P/=eJ= ~ԬǢ-XUPZܶ/Er t_-r0_ܻy3ǯ޸v.:<: H*nC7lX2Sִчãw^)Rc朻|W|0((8򍫧=Uu4uSd|i.wȃ1sY67~]=x.Fݺ_b=)1~Y=]MAGWaɹs7J:XRלxӄ)7Nl>|Q]gևDv#=ЈGC(k3r1D^̪QdڡFo<-Cc<4ryv$`4<'X/+q t߱.9LM:sU@ZZ]҄J{з6ԕVֳezpRn/Q (&W̊JVW)X55eLWnUr$iU"TJ#KGc}iyu3W7$?dYb~&^/kc4VԱ8RڧEnYC6UWWR{1!ښRf}D0R&~<ß |8bWH΃a({GN|8N<亸8nC';$|˞#s ܛ >' 2E3|ß3_~[~l ,9 Z;8WoxӗndXY?Sɡ򮥢@#` I| ,iO)HxE{u_ZO7oonZqfE<᫑h`A ___` jGovttXFfP+zأűܿ.ΕSY:CJQC׿~ɩ& __-?vMtޚ(j_A2wMo[Ƽ?Nv~?x$g+,'9}9|/ JL: 3EVOK3F=i+/ɟS1JEJ^ɝ_Ck(J5/4}Ք3o7??Ѭ]<ⷋct!+G;;/nuSz^aW~͗M> PEy!AjbԼ J.(OMKnpnu 9@NNo'9Eō|' M_SIjYH:FA:JK_}&֡LJX)tU/p|Ac\d*KNБ!Q!篧[ ,Z$ӹh&5Fِ/s]"&.IVh!UgCo|`p%.;vu{رcH$9U[c'#5%btl zANͩ1n]uL;n^ԝeUΦJxJN*n97\r__/ܘ;e9/pE_VYџ&(cn[oFoZczr {F̹ ƒˇ$*Zd6: {kaٽ'% [.lWX'9^cxNf Iʎطtź}?V}Oݍ^pٺHq 'b6q#`2 ~%GvS-vQT7#n͇W_ݖP+D87̏#g}IK8ms"d?֫Hr~XtUr-E?tOxYg[6syJ-_W5ҕhӼI 7 J*z)=;7Tj/oH'9iH;k%w>Ems?VrŖr7v K9z"_&/sGe f[*9RU\*ӻ# e{UCtQ;!1U~uQY&J`W$ W=^•s1++?HUz XY[np0L#|u֨IJ76qA;*ObhZ#}xvhOV1671ߕ5wF>T =/H =^%l.­‘hټ:U1 @^Ӡ3A蜤E=KAmS /r{w9)2Ic,^I dn.|{Pn9_ q-6,R2t3LrvPЋN@^FRiLc;3NRCfz"%}ҍ՛HI]џ,%Ոn׈nUѿL{tL]:HqFbyc9XG2!N!3:LJv;N/ qpXͩ +*4;0p<练CH9ߣ&z%GheSB t6̓qZr=}7Ub#Q cHu34 Ajq@bE%Gq PY5/^gSw`N}藿LVمN &CVv\ej$&Ln`8OHr^_TJJJn `%2 2?iPG$GHN>'\W^ `%'2yfNrav +6䲎(k펈fOGQQQPPl!93&(9Laō+2kuL)ǺQƫif\k!H`o ֺNi,Fm/' NAr ^2Dɑ={59\v.:Wo6KRӕ8%ddH{ﮬEݳ{i{gi}6|-f[-]Su}#O *.f p,9s %=w mC;ݔ4;t= ^~&3[t{GsRFLPKn1/ytc;TroȮ z> (kqSRfAd S'}5lٞݖ I:g#V\+f:a) ܾEJ_vQacFϞ6⊅\ܰb[nq\ 2WtvGee:97k JQtO촓X9nWw3z贠-vJu59򴑟M9wu[1\:5eo| Eg_:yԈ_;_:e_,]{^זia崫Aro'9u}wk0{;胿t!Uos8G{\.pPT}[m1Iz"Mf Eg6 ~aM{n5%7hDMl'1vo);7ɡ]uf␲ޥ+4~eR^U} -6aո_֯9lZ7Z"v./fg+ݷ Vm߳,hphHiE*<qy\aB#\ڼ(wm_VpIJ"Ⱥ95}blwm9▕19=6<_ozt]KΞ8~:HKN0mR-zI\^DDB V67ʼnwƅG%|݊C]/9Y͵uPصKGdJA%zFaU9!C}˥.`e2*6֒<šM낶 [iW^m8Ȩ'PNoAJ7lܴPްŔ_; 6UvCQ]{C; 6:Љ%tҊmcMo?t¢LVn?k> ҙ3Rh}yK3EfXu ?~|f#*U) 9;t&I9\YywWoY#aG :)ҝ{*|:}gK7o%(Y'n!(S#`*׈$!A<,9pF<֎9Ě ^'ZZZFUU!!!nnc^e4v&HI0C^7FnRY 9umԨ\.3J-*ۼ67Iv!Or|e9ivv/ڨRkVC @ + f>} `XJd8*kX!18 s FKWIVrxH #H7:**{$9=^%nǍ*< @ Y,AnZF~+!C!O![y1ߓ9K(ДAzKnK Cwѭ<0+{.޾I߯ޡBEĀ!3RDR~oRQ( %{zC4hJ"B@$Q#Dɑ}x< (sO}$ og]CK{Z@ 71)Q(Kr K J뜂ҜBFnA)zE)E?2b#+7fq$;gZԈoL=Mq|sgӳt#E\[=Yr8t RSʐh}Bp{JC)CN[)gp4rފ5<|pV'6~\z1Z{-<B  QYSXRb5vtw DڢG~L{߶eR%#C9r#J']ݻh(ʻngK J ^tvq/Q.d?c~Ĵ' 9P_6:13Es0WYtئaN#pA; gfLd6Xʦ_ mM{4anEx3W.ϛ6aFH-Cd^9߮oXBv@0Zlrnf!#?Z%ê"FiAP6 '$(D;Q#XK]M~UEE<[ Zš6WNnsyjQ%mĞ477xMZd[9kaXF+C~{?y}0ɬO4o@>_Ω\1\%%fNzԊ!?q`w[/)!a8yx?"-J%yK/eQ]V[^ +awHrȪuC;[rIabT$+++KQVVE/"s_|]q3'E\طrrzBUI{8{wP*HbE؉cR9gE3ۍqѰfOv\`HѭK"VSE[ 8L<[Y=G9\S&m%/NѷfM T㝐a _KN];FS!R(КX*<^e5V59]p%?JY[XZQR,*(rƐr+X Z{b䤉sm >|V O ܽR բ*eTSTgb U-8L0LR%ۻ oчYjPQB36vz͏{^SR^ ㋏F1~֯忿1:?~ݟ> ܠx~4l'_5-?}D1eTJRi:@P2}TYTjRgAf:"/ʤ03}li9tI6qЁMob1mh%w;5뛱3~?1/ mO5y^u}O#r~DZ*_ [US"Gsm[~OiVwf[|lC"13^;~}W_zjyUwK5 ^IWy9 m6}sӠP@)T6zlg:8z P,'#@-Uן|;j}?+eux8Nk ?s^SܞwСåRc;>3}WuPՋ\ϟDb_>->O/baFQdj//qw?~`>>G/:pNWxB|{G9H@DO.+s,z|TϽF)7CI> ͗`c 4PVGr'yH!#gRC&S9V2@ݦNCH 'ToߏsI#{ ޘ(f5Mw`8f@ӁFvvc"H.P,5%6Ar]5Y{ fd9vbo]ep9@i MDeHP5@#zzǾajW9J>B|DArq_lLs `\ت=r}ՁW+mq|G%,(jLkW13N wM4ﱐNΡ 3Zf)0]pB1EOAq 5swW¸ §yF8Fs }(:~^䌅"Fv1afr1vV>S\$wL-047^nU*KEJzmG+ SR-i>թ*@mkL93HJͬ`SN@HJc&#ю Y3f*OT&9 uK^62 'nw熂> 5BpJCgϙs3j_*jqc`}AK8Lspg ׆ t-p둘&ͱ#wB^ G4K zCbKPXk0E9l5uEBMdK\`kWήjOUFcg;EjEnk@m8#2 y 3۹m#„~ReDU~p#"Y -O}!KdR{fHlgD[J?Zq ҉\02?yQv}SIjO_*PYoXG/{ݗ+T]͙Gj/͞{z͚ =ѡ/xc`Jh)=`qozu %H9Kaҧey7m8Qs8npc)-cmhJ,W drzf䑩~*胾n$8Za=yc_.|= eVZ|NVym)q@95ԷBl\] ՝FXdd:'ZZ '%cf#E[HEg!EEI'84s|p5\q v!AaY'|G',%ujRh J Pw Ć4먞jcN8!]n_욇MV$5HGϰ:- WIоr 6a_iFF^.&D;ڹ +KYc-P/tR;T{|vPz8ɺ |i/e⦗F;B,ת^_W2Iyp?a|T4]xq+s؎uD8Cs&ꜝs񆍓BߜEIk=LKq6M|4Z;9#j+|ka;B>bo}#)Q3__-WNs_׆(XX|2:P'mڲGνo4um r*N<44 *%ꃰmR(`@ iH:8TKN8&V DICv+#2aU1ULc8,8L |LE^6h!LZ8=!FDĴ9|=e9Ź}La 笈> a鍇Tg8k"Irk"U-  Zj)$WsM~>O&,NFrǟ#bXަE~ ,N~, f oNC-`e)/n ȅzZL|}|1|ygakoRR'z|~[igK$N|gg)etQgᬭ8 >zY>!5ӭϗ#e)Lrznt^&nd„G<ٲ%s ~o;EsؼuVB&s$M EPMA rJAD5Hu=1:"[U"*Y[jUǶ .ȠAe-̕(ʑ-!$Q *\Rak1Iu4)5+GF tSEdFprs@Fe( HM ~ (+ȴ7r^hn%i'..um=bPS ԂzLP.HѠ+8b5=1+bZN1wnе[^!j ծzR8VZc#:Z SzB#jhî]]Z"Ȕf#,峟 ȭZkq>_<""h߼&jKѷjJ]75-gzZO_\2^jL߃+Hjt5[Z:}B`[([AhS_hnuՍ8}lr67?AQ'm~8J; BSur&'swX,48ZyFXL\9d ~xx>Ghwۺ Fŋ--]g>@.r{W6 "-b/8ܵh͎&Motz]Skk^Xt.g[ rnsO ~n\<鶨kI" '6ҡaRRJ P/PWu@W3Mn%Pk +a E}\T-$+ȝi'+I$92tM@&F,6">546vMDOC|fQfნ3R I{]ju ^N0^v3W2`e䣮ԌJk`4~hi1[О^2*vv5g0WS@ :IY1ßsg &1Â*Z$4wM+2'א!%@ r!KF"}*&_ ^z]S͕6/e.ށY{?oW%8;/VAVtnݶS7u:S nsWU:y [g47;H'HkYTDcE8%|w.Y{Z?+~Wr4 spYMүC acB!H :u΢ӟ|ox{[*I M Re\ 2lqs+Əqcr#-"KOem^]$+C8L 2-A%p}7VZ7c;MINf."'ZfiÑȥ*2*:IH0Ylk̼؅Y5DWH+!1ͺRCxXZgQ%=f~-p- *~ b&V JY9>l#ȁ\i=i-]71W2@UpDFƴk! ;Y7jȝԒ¡o54 @ki!:fݚ(69Y%pV=kFWDd:DTf&ȩN!k E&$p)l]9WE9H$8dDN}w8ʨ\d˨L*VX_SkAÿoo9 ǻ\L~?;Rޒ/x?<%BʧKn`ҭl[ }p/ޙG=#< i< U'8,zl7?o6.޸ 2&~m{.ϙ;]}NSh4s󞴋RW}oKYR!NȲNv~'wl`X/ni/w$|7}Mp{n4(2p<@v-OW-t+ ^ PC~%2$FX Irs9z࢒r&A m&7\C;1씳n7\$1zAIB@2jS:FU î/i"R#+km㛗7Pʑ.R\nF#ijrˬ&z6(*sDRʉp ]PO^+뉱!'TGakȤ|z6(P*l?[OHT M4|z\iZ2Tex 5kzDwL[Pwqq# ulIa'rjg65A3mŻ[ (;ȳgxGz^LIM2@)#@O̓C{$zq\!IAv#r*hɭ+ϯ"Pc45 0TelCj {Zs+M 729|#PHp `H m; .eud.h" OxtCtQ#!*OK᭝׵A+脂\-&VpA#Kzs;+Kip-TBf¤jr@#ih*ڗUI`\ LL6Yn 5z&.qLs#rmLpw6q8gn^Q^q§ r 8 Gs @:n;0TQ>^7 8Dy-hbH|yVPc.Mg@Bɳ\#mA?aU~0ā MudLn#4eكUoC=6Xs$Wi9:Yכn֬\-8ĥt]<4@dɵ4^jk S6 It_֒ ǭt;RWq=ZqTXSj:yq3*_? "*) AһAa% k)&f<9PnfF%Zs9xNc&E3 TnХn^Y28!*n $8<`(ȭG9jwCLLN6vW{吅UD;H9WcOK4pKvdJLL ]k˵)m' #Q۷ hʆ2 ĊK>c1|i"Sp+]+GLp k;Mp^賭?-ΫR #1oKI}ib30kL$Vn ᧁ+HoO%ё(2fe'$[5:2Yxh>$>5vhu@nw;puyh0<A|Ϫ[crIOW> ۯ"]nN$okSY&7k(;o~=GG}yc,j !,6ªnEϸE*k>(ZDi9-tI~7ٹ} WW bk_`.-|z״Y_vֽ߬nŷMfp=دUr]<Os;՘nd 9_L9,ysQK8FNd.Oun-i?9U6ꗦl"Ko@Cl<_J}Zl͹`&>lg9, ,yz tm$r~sv\AL8ۯ/|A/| _/|A/| _/|A/| _ƒ_/LB$$$$$$$$gM8M0jRteXuAE8q6l$$$$$$$$وg#!!!!!!!!F8 q6l$$$$$$$$وg#!!!!!!!!F8 q6l$$$$$$$$وg#!!!!!!!!F8 q6l$$$$$$$$وg#!!!!!!!!F8 q6l$HHHHHHHHg#FBBBBBBBB8q"t\!g-8pG0"@Bg X$X8 q'E» ,w N&َG |5gL1H0@pҠ q=yɑI!=g駉,/}s َAg:dn"Fm$ψ# sN/z>P@- xZ3ІN Bo]H )rM\7Xo=Q|@P"zދ͟~  »{]vD?x=K ( =`uu&XPk/~Я2^A'*s$!-F9=NdBXcnj~g̘sߜdLlR (ĐtyBT:rǡH(pdھEv/BJ}`geON&܂m"S)\ro_:d{h . Maj)ܒ8N\K/ijg+ڲs/q >ZV= nܰAm A!A48t$\qd;RlZBY ;Rh6FD}jRtjF|!B U`RuaRАM-㪽㥮GuSC7^"~,ƄoEe){X8P8@ljm` _jU D8.:uƙI~q(@[H/m+iӦ͜9sҤI Lg;cEnq2!@sS|: |5" x6Ngo3m V^OLJɩ4jeY x2>)FECp`Wb^V]Xd-Xpq췎UR+<0g3uOXGh_9 CN9l'a_d7vFm ;5э%<ɠb] 5QB=K'l]cQl`[8FM/tQ=}(]ٱ^g:=p6Fgϧ@t6TDuWw R4rjᣦh^und>Y_I+^%40,`x8V&=Xȸ|%n, pEɲsz*!&co1TJY =;3\ĝI Xp %[jI#hj |@Yt9>8 q=8{ܸq۷o'NTp6BPR'///^Z |>}:8ɓ'f͒d#FFAG-l{x}ح ~-yP(yF,vn 2x/F\XYp}@Gû-Ij1L )-VPXaIo򦜬zjjC &q^uF\V+)9Q<)߇I6L|q%U˷ ܓnجe'dimvY 8̕EޚwCusSxAbWPй?Ϧb6vBvg{EUgr3]44* de CH&OQήt w@z 9Z17H9;$em=qW[Hpb`{۾zsK76: Ϯ=9!жa;ps9; Ј8Lmeoذ:NW՗p컰`s BNrH3m0ı`L3,v;q ºK ߲bv'zP%I] J 8{Oq&iwq6Vwh}饗ry =KChti U҃7"pO"?܅(_K7rU\_ qmoXՃ!U˛wbsT_9 њ3 X\>?_jLHTՏ?0wIb*hͥ;Wj]X$l}Kqnn;'J[=qV{w [N܂:blA{xn2a-" b讼 -I|qc,e iol!rvb[$޲*LR]gmiQ7پJ'R]W\^X U@eM ]T yUob&*ĻKhԶ4_-h Չހ|a߱-jkclQ:]?ؕ#HvvEE1o D˖* 8%(ӛz9E/nq dwc[IzS7_e>I}_ΆBrZ%;JA2 %oD,ҝE8Px^7d "BmdD"oJꣵr&x]@)T[aZB wYE-'o0 9IR^Z䠶 ],)$D@ tΆx %-C94ꐳ1򶶢1hw&#w'ɝ6Oؚ(B蚽!hi nzL!pϢB>˸|0 |y ;$1TSҜSj"3]V.^Ҵ/긲&'˅{hmޕ\ϟYgԃV[fؙ:m0# /476\$ջT'!hx0ٱp] RַىJP?w \M)).ǘZxvU{K|~e$##ȑ#6m1cСCWgIfYqay?;t88Lv{Prz,1g z$̺ 171G}6g/F\K٣7tMvfO1ln:5qScٟ*!F_˦]M'=?T_,z~P[c-z3.+^ źzܰTXqWӥ bbey͏otgZ ~ai=dQWzg$}?{L=8*VGrs8r&;;yn8dMilX J|` 9ƍlx#ΛLXa& Cq֝g[]; b Dy1gx)[l3G=_찐#I?k8]o`8 RG º7ρZ_9K𩜱)\})8Dz\#FK.R:5AϘp65É0.QEilA%ؙZ(wFU+Kzs^Zg~g/*ca=|q?V+NZ-E?q<^ BKOdpHSu2JY䟎d;wdZ'RУ+,!gr]44K0`9(@g/[$u]ЀR<zۜX g;&c (`3uż"5jj[wt,EݼYՒpnٱVI7tMthNݗNE݆ۥ{ygd6韍O8 ^j٭OH@#/P] |s.%:^5>Qy7"K ])Jw_#D#B.iM ֦J퇑$ ޡH[T{B &2wB=܎e!E4r)Sƍ71cvZkk_|1|m6a„_?'O8j?gas UUU]]]#""LW_}ŋ111>>>aaa[n?>8e@"H#c;@gsGG mXJpџƐrR9R9> 70a iݗ7.,`]W1*ףrv =5+ CH^l췷_vq#<88ҖWж1Rz&g3qzRRNirr?7V ÿ+|Mf'6&Shb^ fjn!oAx{P-oisi+oIg ! Wh干}FY AO)*߈''?iQVOP _t:a xlr5kԁI81}_QИZ^ɛ2Zښt:A_&iϮa mXl\uk zYShu17cK*|#>=K*G̉Pʫ%j4~ &9La=Ш2WQ%]@]' KRb{S}6caC %tg`Nz LJʠe=}wKR*S+^MwT\ʅd@u^>+[5p$(ު(k=O ѡpcӶK+wDXYꛗ&=VΆapot7ka#_͟8)$xEUr^ڏ5*Xx| W^T +-Klm.-Q/|w "KS .RE܄("RewjVkvQ>4՟0 <3^ nRuFٚz>gg۳iyy_zPm,eoZ_xa;ڔWy""CU P7˷@?mm}%-kwpx0UkPf:CP„[2:Np[ag͚`0X,2__ߜP腡_~寠6˗/wlFn6mdW'q#|>tV^_>lժU?|'IR-;Wk5&ڎly#m!eY8;t "FnQ^j{l6nA?RclPkCmޱ]܋qLJg}M^G{A疼m [oܚ3{I.[g/kٶ|#d'ߌ!BjaɃRuo1d\?@ ~%(3Z[e6+5l<†m~EcqǓo$T=W(ɂ9q“XJP4+8 dMɍRza3%T0㖆߸,s~ t-eO_bs=#6Jm=LmRgHD8/Fiy8>2C $ܙĘ=y΁ؠ-VkHfBp61XŶ^vSF 3TE0i!٠PѲ$e}%x|Mw^E]֔غM:6xrt$۷e%%Jƍܲu4=u'Tzo#sgii5ܓ;μJBdm*Dc.̶|#T+5t҃{nGJjJj4ޝL* s)|(:ٓ&Mz`W\9rjɯٳgx{{ُ=L\ȕ%%%QQQw>qϝ;w%8v؍7N>eЗHKKDAx.LbP&=ia!} ˲eC@= u8- @qфo߄ Xx=KNM@Comhy@5[|HfW7aOA'9bKfCNI~65i8zFyb wsR)WWC1mVk%:&Lkisvvݖ?ۍ!x9P"v^JIo[l-uզvAGc1^Z]nlMڷs W8EܬL17Tb'?noąV|{>eMյ:HgJ#{Ӝum>l3>dPv+8TT &f4 e#"I rq&8=gFvI^bnD>_\JW͎'{v,UP+zcoU5Dݪ;g v]S6ZFn!99;S;賖+<,tA`aKJAK&q9/nȅiB{("p}`Fߣzc7+ZS+p4Vgϙ3g׮]KHH߹sRw`S@ %&&_7õjO0ɓ Æ { ܏Ͼɓ8;???44Njj*ùz* .|p'|"Hd8.GovfDf'ˌm#ڟrZ͟x zg;+N`ab,Y 79ol~TGpXO| 9 9y;R@8zq~f-[6^p+wCo s6VRBVV8& sZu2}EsW~Κi4gD΄8 qI9pRvFb hvjGt\կgc~96z0DNΎ JL պQc#'I q ^_.lp#9aL+ۚA^^Wk)A4bȍtYV#;}SC|.J`re(pe!`Ū!Gw%޻E/ ~%_\Ht&GI7#xsj .~,FޑQ*TMz?Wrg/]^>s~p,| ra\ iC Q^{;`J]}1ٟ^ B;1%M:i*uy=0Z}|Ϟ,y%]~wa ][CqUypC„9s`V"UT^>DOӝsADnȽ|s练z#oaε4 p:>{6|T{0zNGlo-LʣP2]PH<8=w JxK ֌:1 foqf 6!(<67]!N, : l\)x;|)W@ym =p ϿiGJ א&h~j0bW/A/ C϶n =y]"\"#-Cz~ uhοkqv_?A(nm`v?Ap֟:'볚r2vB^׶fLԄ`ՖkENAM5Гy.Wi{JjopJ푯"{&1 žڹ0N33(ʁlQRPmݑGhlw$.SD@JĕS||E4z81q˨yg2,VI,rZ. trX<آ‡V4M/=V˔p>.+$!~$K$g+ʴo۶b-_|Μ93fXp5kիWߺu 80r(0;3{pH8 t&ÞɃ1 @/G.;6yudd7%\'xap;/bmSER$Sc׸,0^G6+xcxbsܓ.cev1kCC줡ھĜp!XGh77^J5X[w \ņ3bsa[u;a5gIv[VRbE]DM& Coްm2CbXb5J&Ɵ.KUe- MM--- gSC}0'jěS4S[YD]^{)V+ZSYeNZ^?y|QSF/ ך5umq\zCs- õ:ǀ앗uۏ𢝊ZF'S\X~Ǥf$arrZi^dhɓwyAjSIb ء&no,n[R&Y5ٵ,r݊Br َ0v QMߤ “w ;[uJ4K"0G6HҖr6vwC}iI/v$z.J577Pu Q<{`SmEBP$I[RkoZ$XsdMU ږwؑ$KI}KspPu9r>h{݂ SiԄ푸ñĔs'J=$@ҹV4>RVNvU-qk($'*6x93I ENNN@@ʕ+ Ɔ "##׮]xub$|>&+AB?Bga{-jslO}#Fom#~AŸ$s?g *WJ}5rp 5p ;mA޿r7o5q"vUjqڢ,i( G?cȚ;V(Rg S+mb)9)_S>  n1y3Dˮh* Yc0.ۅ.mݼny z9Clbd~h9_y_yxA|'S@V2ނq)yl.' =T(OŜm9 A?j..QwoĈ`?Շ6@^>kq e#"nvx~9ut; tEJ;yѳ<`AժɆI/{8"򅻥ytcs-LPKtŨ[==w|(3̎O ܁OdQ^'m5??_}}}}>pmF  `i/.A*iIĝ![ .;}n.G؏㤊9t8s)}1;3 PDT2kdݲW p)"|σ}&)ר^Mg:r;">TIcԴ2=7_|])ns{ #jC>4&-9.^T@{zrn½W` +fEit .UoNr0E7l%g>]A $Ce+$2 !!aK, ǷzkѢE;w8x\!v<ڎ05qh}.8 _#gz4dkL|wP`;#@8"vGqu;/r_ ੀ1WʣRo3/O]W#yY{>/XSV U9"a'KR+F$mHMXiR8{-ta)ޟcL7M)%9[WfSױt~g f\ZA(P^G3K߉v%*ڐTXS)M-IAKL^)ip6'dOWV}ڗ{>OPOOȦo n`r|nɜe`+f 띉Oؕ)dm5z!SkMaji|r}ʪ}yzc/kҺ5<Ћ뺞=,m[#|0vIͤؾDqO>uoɶZJz#C;rqۗgM8l*I @ڹiߵkׂ>ҥK'O&0 gLhnj.*}6;?'OȜMdʒÇm޼9>>~ݺu򋏏C}rŹ"coH GnƏ\\#5׸7`)g~a~!!uDm*b s F&=[G b׶C>92IHHK#s6B $ؒs&tٲgOߗp3gݳg݇3w޻_57yT >JB|@p!ȼFp+`n,!r"!!!!!!!~9 KvxkN\:y8}uGn!U={ 0rV<u¸YI8,rR4s(^"g%\-ٍ 9ge8I#L20!I0=?=7y#od$'P I߳ &j||DBBBBBBBBr@jR'E3-PjvNw/Gw&$g#8q6l$$$$$$$$وg#!!!!!!!!F8 q6l$HHHHHQHH<#r_ q6l$$$$RHH<å}8 q6_OAgg{=%+jag#!!!!Mҟ,go+ FBBBB{A$#!yHWAζweAw{H#ٯ~;mO=gӢq6_?615&hzc=BB7&@ qz'm&q6#V mNk X@LGhΫ_<{7hΦ$B?HHHHHHO n,K7ÿQߍ6):*R3xw;gN;}ڴ@C3'ym1܌Ezxu1 {n.#FtqA}QNHHGu=~׿(4{koCQKCZjh5V5ZkrIc O5_Z[[Tu 5po7 =#2dȐ!{J$2ANj |@eldȐ!C$4?477M5RPWW'PY!CMRUUUwKk}ND82dȐ=fwgEe 7Z]YYI\XbGmTV!C _g6jV l$ي#evΦCGg?6hu~ҍ4<\(+*ժR<>!LooK+6 |kQWV7w1ըB]Ȑ!Cv3gӃ i(`04 lmsZg6= ppD&Qxm;j!gF*a0~ Nn_O,(,y–l6;=UǼ;9sv=Q֦j;67b^ Ȑ!Cvζg1Sg ?uZA:d?[v7jtUӇ*" Vθ.LmԾ:@$I4:80xԃIq^&ќmfB"$6-l~ 55[[[VQ-E:J )Y73v?_G3?uS/}}|??܇7O>Mɥh#Ȑ!CvζLFgj:t}k|f }3HfFdI:S?].S?^gЛM5O gR̞r#;lqt60[{*z\#l4[[s$38|P>T}ezRmTwNۡ9feޏ{û/OC 2dFh04CMz+i߇&OFϹZjuj<#IXc֏_ZyY m(=i+k1h2y}5C.- qv,b](>J1-+_^U?mM]֞)GgwgWT4_>}JHkjo' W [Ryރ-Z2fՕ&s$'G DfS$j[nsv/OUErK 졳ᘭMZIv-4tl-jqv6-+tVW,a8be!U+ RZ-ئNG 2d4dt:\.lWSoY;eT Ig d^S`;}ܤۜ,:KM}./SF}{7gt^WispLOZT}_5F٢os ]K_]WiOl1!BiI@9ZS5p5vd0KՖ:٢ގ2Vj}.`;9VD'׶8^tPkbE ԓhhF&]6\ˤ-{hI35k-d v vjm{ehʡ}IjpVK}2kj;0=Ku]DV[x.OZ2ٺ:Sj\W+8iCԶC|`נ-9{|uKȘddQSYyj\M^ ߝLi2R%彆e[xk;rX" G9}j?ٝ 79Rҫkj@)60m_!_Y8%b>& Dj_ s#rrK@Qlϳ *+ժ3Q\Gc 4 mMsSMev13J9Ũ}\UCkg ,j/0f꧌UUYn vWuZu_Θ4ꜲRUYYIs=g/_yj۞SDAyZ]v)y6/>+ ;4OhI_vYyUeEavߝ6q62dȐ=n֚Ͳç~X;ZNYEUKg7[s͟9rМ4p4fث}wٲE39hl*n;>z+~ui6Amο:}>r^,Ucs0a싞7FXyūW>I*bᩥSn,Q̧WWe|w$ww!C_5be;53[}=iQNߝe]3&n]bƨՙż/gM|WKfZkLe9[osX߽?jq/ NNK>31|!=_>a/|\1+(OKlڈ13ނIN]JT ͍# p翷Üg5c_xӯY>X~Ң76UltQc.zќC/X4:Se^֏3~%`,2QϋOoϞ4/.4FNm5e>;IpѼN10oFv:3dy|}p\,a\ܗg~vҔrjmJyiDaKUot݇=o܃6=plCt,ʼn߬'=7 2d ?5zdoPen,zgҜmJѠ֙k_w~hV* ķgL&1ݗ*+?d:pvJ&⃟KO2Qois FP]qDuV+Ә7MuS}%>z"<5UWZ-AVJ+${:**ҚKR75qԯ*JkTf9VTZQ\3k[M+|'5::}8(SԚ_}%lVUEjlA]>Vj ֦nj^P(-)WM5뇌^~?Lw:AQh ٗ?4dufHu=gWӬb9yjA|SdXυŅ T_ .I]sF!UZN՝e-t^a6W~ش*cPq!xnH+ &Q/پx ?im|2׋RU6xۛ!g=J߷{޺o4wtm'DEP6 AA&(AA9tsy{C8mw;3Nw}wu>Ԯ]çjG$2 ls`ky{D"LnhihknGLl,k9'/0?(yo/e W.ԑYD>)\ݲZRI6p|:Ȕ}9^_/fIp! n_iKT:zvb-YJdcA7K8P`^D=sZ&IG__"rl:?9 @QsvmS8T os6 q6k9[1slinP}'}.Rř>d|.W/O3.g\]݌,wXǜzmj\ "C-䱀I ;ǷZbp F'.s)d5g߲\ip)փ/ońyy8m[ٙ9vo+F(± TH"fŜظ~OlZS g8 4u?/w3l}YX:z/E2z-V; %+5 lzw2PB}|63BSHL -W.gRIc'&ZZU]m%Yʯz{F&B*N\rZmSqnT{mݡqur=bvuj?;x7Nlᒑ|gt8[$sONND"m} /bgށ)6'r~;ag[nŘr̷VQr:"ԉ?9_JLKF98[zk7?o~?gʊKK+ܤ!@@@@T D8v;}'Μ9noW&SRja_ |g72;=YVǤ?8tlh~eBeW;##Ym-8MNքWOO.;fx-&6%B 7ٺ: '-- C澨O7t\o8[0RO l^M/M=uZS $[$.g.s JG.o?,\Yy.|5_ZBy)~B9 P9{3l@mN\wM B-":39`)gObӬwK̚5T-oߜ^~'Bg9[TU׷6i}\TlAkjmla>0>8brM=Q% :[C;u֯g_ڼEgU g9kZɂˎ&3~bA)Ϙ[!¾2GwϏp, N?f~#@@@@4戄5߻&2<:IcD&7U[ΊnG"@%YlW-Hf ҂HT6PQh-CD*ID$q2>gC?4&BuM=R8пp swݻ{Sq[~)uU=o`am~i:Jm,V%iµ1mhi~|']sۗiUӣ kJy8ؽGoն,>8 I Q|μDl&6˾^oVѯYskm|#b2{H|~|0gODJ`7}^Jd<&14Fbs? D,VҺh2$-i=*8[ Lj)qNJe\#V•M YrX#DOqvM.d u9BD ^_TF8Eg61HH"7'[X +Xtm ܟ-L*L9! lgKR:sӊ9H9 k\S29+Ok b0PsFTH ,l6O8)clX.^;Z{"KYLLʥFti'+EB jdrPƿEyy,@S.+{>?"UF,οgP?ΞUwihmhި E4LSi >_P,Ype}A{F^sfԥĨ)DݯyI<+M۪!Vm_hz%%9Ë 3P^~Ϲč 8w[gY~}C.E"ju Ccc.MNk)>JJV$,٠߰O9J̳Irps8'R}x!'9oYui_|ny*(<3_n4{# "B٪<#Ξp>vd#u!f"/TuyuM9kZ @ߘ򈊍 8}ɸW(ƴ?__εѸDJnv37rٿ`wbeM׮Yc~=u\>KijZhD/W hp#P/*Bġ:'C x\ҋeA\?Rs/! ˳痗 EZ=ЁNVH̛g\ܢCTȁs.rV>kPOH+|Y[ϭ.UVo/~0:k򠽔:Okk2?wPs%.z-Ӥkʞ7Å6mX· 8p '44B0wݠ^Zmck(n O8ousF@"0]Snb'JpِP\SkOp6d!#gYp6G0W""4zi\lxh:<{lHlwYCچ𺺾bL w2$Hl71H/ZI\=xp!A vuΖۜ-O8dvOZKs +l?V&hq6cx"ej30q 8733ӳSo'gT)\%"H yCmOv73g٪85N3.\) BX٤bGCi_uE=wQE܆S$w/ ͯCiLZ3R ;"R[dԍk] ?}ajJ1\8*z~I-%7:BI?Cݦ νxvn_ 1V /Rs@Dؗ)x1&v^I-l1 ,u;~e7>^bKF+`q3̡܄h[yŨWp9w< >#+|`@pRqwdE)CB.$w(cT"EPَ [Q4E&bPGC"w/H=u-cW>LCA&@dߎ <_Ќ[op.\[\蠞u"Au?r)4BA_8J[D{IXJG"L"˔JjzJ5f g߀?E0f=hv/00000G3FzP f8A:ɭ~\c]׎j)XCv-&[GOhԛ WXsmnbkg亮^{PA#]M^|6gOsBp6zݪo- u.ݎ \8ׯ20Fkcv RIU'l{hΑ;׭]kekhrpr0y س[S/&mϜ~ЩN뗯 ʗkK8|ᤉϟ;P8%;nr{HD8򎳱Zvm: %hg^C^f#zÂ[o9/Dnf+{*(rrcǕEitdǦqjh'ԁvpjwknJ?viѻwp6tQF#mau \X騃s@Xe_{7v~?*Fg~dB BDgx:shg%,Uyz>ILn$+<2s s/½1bwcI/[wPSpBU?}y A!?῾U=WSt8/׉_([o]s9")9r%^^AܻHMGspn4-YͫuY~A@, fߺ͇`OF,ש^񾋫XB|cFF  yz_u nV_i8 Jrhq6}A%9Z@ ;:~a?^\0^Ьս-_nݠ?Q>"l= k[AιG s ~Xoυ@J.WU33㺁0wճNPS^V&wG2kmssO|"g?:lf{xBn/d5MhFX|W| xwfdo> >{RL#ꩆ=5:pvZ K\isVb*:X6s%]}V}pz.mymVv]ƥ܁>!2&371͋vܞkaҿԳZ솞EFmXh2@;h#ͩ1nnKggb)?/弁k_99+C59VL>J\圴@ܺ'틩[?*gfs揃Gl "q6-B22\y&S͑=טPRPvv%;7t,[ ax|8H gG,nGdm8ӫ>1;{{;z >0ҵ.Poþvj5X ٟ7o[#FXNE2_mpSݭ lt_f49[?@ v>ggk*S?BLN=]l׮\QIΦ¿츹2QʼnJlUG{7o-zKwGX~\6yR wE{A!8lz9w}Qi37tv-#[:$Ⱥ9}Z4?+|MK }|ez:"H/3x}Gwgs}6{!Z`iS:)gӄ( 0000m6; s޴f[.[ƕ~;aξcMihxVvo6ڧ,{O}=Q1he\+GF578؇Ԝ}kK8p6l`````OϬӿRH8fdFcn`V4cMHk5^eQfET/7Vo̽r/zp@@ͣ6 ^k{.coB̏r6z[=zwlYh1 3#uQ97|7՛!|JCyvّ́k̂G*顓+mB{v SB2RϪb1ndhGí׻jF(;O:RD V(y?ٓa+tgT9[Xu ItZϝ˭CJ0Ͱk"~XgYc6^ߥ$P{㯬.% +bZH3?"G?LXxPOH7~jomj{q}G86f:8[zi uh>Y%$g+d':[zH|-;`b|_Lt]q:]m*bTK C+vշEsYu:X~߈ǯ3}=#BV:=˫3_*:3@W8ĨgtW-V7dfEnΜŜJ6z#3noڳ[:4)/ح6ulzs#q&s?ٳ#+Wm~659 8p600000'3Wg2i.tEj:iɡSn'$}Ŧ}[٘xDG}C9X|{^?VƳOn~] FG||N{,(0#-ƾr[?1 &?Euxc=!j(򻍩9\5]zgĥcGNDk&txk\O*e )'8uǣ9Dl;#0./:lq/"ѵ=?{D5ݒ_CH^TN+ *~g_f[qش/ȋ#w-CgrGvn?xe.fuT(`[a?w>g4 JI?bg+ς^J3$q:"BGUpJxϳb{2ga϶޳7 j"HڲLlp=O-7we\}iߦ'g8GQw+x]<`bqoυ)œESұ]C(bvJ¡ߍDz*j86 143 Qq((sa1`%?;58FUG )pI B]"&\%blBɴF UL đaA))e7whJ Տ#EӋ'uw (0ȹCu@I}FhZeKųē=z 8%3I֩:{zF-O$,{1cRHēxq#w'4[3r:~:Iڑ *6t 3:) ;7?t&8p6l`````@@Q H 8p600000l ـg8 8p6l u=g8l@@gLΆ! 8p600000l8p6l``````@@gqw8c 7ٽj?l$fǨjCH0gG)}cԁ c.@xٿgarE *lIR<]#~kdkX4b,]N U"~ة( OW~%2x2}6Άa٘@@?0QW1D쁮,.%E`?I&I0$sWh?EhCiȦ*I'"?-BSDT)bԯiuO8?d!'^q]4Yy7d#1%/0`ԆY$K4U$ppTAvccRGjHqU(rk̚$Ҥ_٨J?,Yr7?+9~gC2!Φ=LJR lxwP553 9ԃAϞEX[=yd"h*DXE_] ]|CI}nD ۛd}ebo JKi8׌^H2"o[ /GG8$/L:}}8f'K1:VGM`iRU͛l8n1` R4cI@@EL.:Dcq Ԭu8lv{oQdKVg/*jX$7<ޮ*$(J~g޸CNj1X/cMAj\oqc=_W/ *yv}ԟ챼|XoF#O ]LML}KKHOo73MS1 n=žG~w.M5 $Ds[r OT;ݹ$ %p}Wd`o`FGiO4z,Ǔu;jwHh)$;#YOs6)z.Hp/G,UTs66Dga+kˮcqSSJX JKDBOE_`?KJ)®&肂8{3JWԌ ,?-Φ*U96HT &y^h:>=I$ fĹ~bCAb+I s2CbSEU) K Lu"o!:ؗ41.ryJ2?IZ\1PGAH2<~0qӧbp!tj@ {!%C pR93|;xmFx&HjR9;?((Ms vh s.M{R꼑 "d%`!zJOxKr @kB fi=.y}P_#,-υ""qg2#˖=/.)q^8=eݛ~ lGWhtP([5;X*dn2/" ;bhQ7|,mx5”a> _(hY.[!zќvą@_] K3dgY,z!N"S}]]b,d~ᔞ;d`Q!04x|@'׈R,έVW:,C0˥KRnN)Ѫ ǘ$HYbuΆ.pͧt\nanMo>YQdL E*]"Jt(M蠃3H.*?2&Tw҄ &{HUhFK=0Э`]QD]2F}C&ZAylZ q6 sx8oݏ!^e[~QWYY]s:\/)Ec`?՗@NiYyg?5y=6RwTO6FmM܈f$O2PkְcSvTTiLcy*\L;"0*,BZkJ{'Y:Ћ/2cTq|EJ{͕H#$.xPફGGު)E q#'J~hl>>&^8H6忺XU4̆B 奈,GCQRSJnԑ!,z[vIl/w2L҇5Gm6&in!R3XY{3*?bqj f "Wԉ' ۊ8zDIн}9O eiwo#_D m%NU-FC(5\(JBRna]K8,AK$ d:s^&?qM˫o_-`ȑڢ<_mSKc3@ÑjxQy&<:d5#X5cܾףr^M\"A>먡(I-/dP'Bm8[UDCCUԒItv[N'ѩ UX)Q)EMM`4\Cy %c|<nN x#;iTTAlFkJ2t}F<"$#ϒʋBh"DkGF\~xĢn*tz3*ʤnfë1$yy35:?k nL~޽z(UGK2XV}>JJ݆y^GTe ((ŋ49fx ?zDՋiݾr66Y 2Z(3'2P׃q{ ]4\Ntl腻sSfiÒaFG ßD߬*ec%T*1R4t.UB$#^+ +M~ -xC7/HDdعʒ*8A61n$&9%JiiL {$|k?im~o/$_<񤳹ceeyv΃ ϟ_u#m Ǝ.TKыVs6<㌹x 2pM@8H+XscMŒls;1(k+pΧ5r~\$K8(%E]D}-aN{kCvZ>s{ Ukd4֖Dȭ޾_Bѭˇl)(Y*!K@1$a]/LIثsvgr fm}UK|{xboyNo;%H4qaM6 wqGPȫWzF;;j.@8:KFQEYw~1Q-a:aN'0Pjx8Ʀ!\tk O\&u]K#חg>8bs7/#9YXrᰥWUlO8.屨-eb3) QDkSFѕCA{N\?҃l@T!)%헏ﴴvhSjC;>A6:g:8ܳp% gSg}A;,;DxؘXeVd[/lf|o!+-'R44zEom?8G{1QѠsX|aוlyg}6G'$46v68%q\;z$'1/O0ktpn s$6|t6I/1cn/ܶe)਌~ =]NW.yF6^FRP(1fG=oz53xk4WF ޲# ~[_1(tj}>"v{lCdk&q6Q%0"_UX8VpFVN`cFA_'aL릙e9 H[qC7EN[wFSQ1j?CCl%9Id_RUrC: zVuCqJoWDߓXv"sc=I|7}瓊cM>9JUq;rSEI'd!PFW{TU$c5Ȑ٘}4 .SphlI:]㡺 tit)3KL1c gSdDp}(,AE;`y0w ÜZcWmȫ+h2X1'n Onzެ#z.7r {Ÿ27fKI[Cw:9DxJ~YK2{]{LDH"YWwxBHIwf0꠾Q@Bl#'#x$\y`Oy̨nŴI’;hDIWoV^{HF:(12EIQt1Flbsvwyh: tRaEl3+p9PLAbnj8:.o84#-\ O`x(?rCJK ЋLalg7^Y^҅hhml*h9v{~l{?A6<!8l {l3p7Ď}GfbLL6ϡ Oo BogIxb6*"M$TٽVHis *R#+&M1Ɛ}F4P,D+~6*A!*m 3-糙E[mI*'n@dpAqwFx_sV?ƭKdL&4(@+8Ś8W)2=mZeYWKÝmD)G.rXR9"~)08$aj⏩*fsQu|6;CL[?%JŠaI~de`W&/DEӠ ᰴDyBƁWzx Y_ynKlDCR?d}|?%DZhQ] t9I(n|6YN`(T n,Sf7KEMb,QTb1?ye"U+8;m69Ԝ w+,b !gedj% !}+4q"dOR{+g+  Ws[gCWvݺ9 @4ɐK I6%C\|H z̳CtcXuz]1ߖSkB+<.j aGp)+mlqN4f<fpp+B-Ϟz EQŨ4[pvg{̾s Cԓ|D=S [/^3Wž)/cx-lÝM@X{P,!ɰCM$ux.[ϕp=2wo5 IfPbm17BaN?g4]J <+eF:9ZƩjS%OW14 蒑n;Lc b$0ÉIc&&ݳt%y_sD;D򣃛%h(o(DމcDzv!pC=MS~@瘀jF$\98  K2tm͙*MA5cj?4Td`|t뇐-4*þgεPD1!}mu-xhBR#P?&S1T)m6g_tgׇ"H1$g8^p4T'C@350mp:;ˡ ,!ж9~뜇i ڃjSCvǀV܌~9֬3p'56&Fp7z!G鹖0h<;yiR*C0m N%rf1=M_l4}A?ܵ~ӧYX$g'+Ehru% sdH ci(8ZFk 5WĢv?,=o wSOy`;,ƒ,B @"o3~b>'2,k`(9îl81}\4]fV")xtlCERq lwIԑS@w: <\I'A7Mb3l#㑳Bo3ocw\$e~c;wd"]ys<9gg͌Y"b$#Y(DD$H9CC $nBL묵g|~ꪺ&9у9+ic.?f$kMٗnJx|cLsWW ,^Ǐ$'9w+t8BXc킏=*Lb E,( zt텷G#'S }"9E%EܰiO]C])q{ܾAf;PXµ vqЅ>4}jf!UKxYs=KS,~`=g<'PS$_lM+*~dnl2dwIlponHyzs-a*]fk?tKrxC7L Y;Wr%;7OLrt=_7\&?' )>V]5 c&ɨލf+"IĭqDSTM(ə7Wl#7Lʗ7dž{Iki9 .!ܹƚ4 2tA/47ՎlpNv5N  nF(q(m6v;I(.AOϘG mވ7ŸS07 Hl,+o(ҨVppgrzMfߤi]/\ϭn)޸Jfq 4ၦh'c^:nU ĸSddZʚmqC6ef@n͉gvv̇HsF>X#'M>`jSa>Fk{LG1d?DNm&iOTċҦ l|Y{hhCrv.g1ۜ`ȭ5hֳ`PAd5;YyO,m ࡶQi QD!-(QZin2FtJ[6]0NhѮgBnMHA*at͇ڢ\g< J 6vv7=.Tpxˌ޴sK7*鑼Mpv$$^D=0Ifj9 9ɘ$2)kgiF~ gϭ⢱|L5` .>1SMÜ`Mbn;|{R*-&4I'ed+:H/5}(9s LM9bG㏚eGU. uV}!ePF ~j@7>e[hv &JO&]197r #cqmONf̭cmn+ċ_Q@vqđj>i}kA97p6[ rz.t[K o$*gy#[*2g[15$+P㽖e}>Ƿ8;a<` !Z:$SE*?VšQ;W1hؘ', 2ވ?ӽN5&K싒r[o#W g)AL6~zgֺ~x,!ͩ` ro ꓬmq6Oha@ݏՙql5X9˶8&W]DAp4 Pū[Gk㋉6)ZŦ=d,HVcۙ ++8PxȁsYJ2n&nG/[OkFV b|9kMEx}aوȀqQ=/0"#]`APqxjtE&.[M:͆Wzy8dvWCepIf9xi0~( ]Θ>[(_+(a'wp6W?p{[^1{6B% L FR?>@FJ!2>J3:bwZ.lDq8>-E9/jR9) ζY,dgz/@WSq'!(g$d,~#߅Ee& h5 ] }K!N.o]#^ BDFR2_F)gӨ̱pz-CY0Oȴ>߻ȘAGn 8{ FFM Jza Yjek 7F׸e3E,K4s$,&&x>V>©ү"`azd´̻9c|1Y&7߼N$3*h+-:FdD`^_X/͟HTX]gU(m=$_i1N%~s `5>4/}D dW9O &zoeֳL{s Ys o1*t{3x#%lf0) V,r379}.xuYtYqQӗ)=4FdvqzxnLLLػ9UB#It¤,Wm5n곃g_b06Y0YR/rd `+Ql(ᙷu!/lxv;hzHT\I27q?%>P `ƚz8HaB=8 t6IQ!S'&F?y^ŚαFo=2pn(ATeŝ>kCoc*4šjtV>u6*M&xC-2y]ߗQEd\2o[$Ϯnq6*[ C:@R&W Ԉ?35^!,kQwphlXr9w8l;ȴ}n{5%p6{PƟ*4 pJPw`|I7}]HU&#PNaцKl:2)I2g=ijЄ2+}ýofy^9f`AT|vnSb&a#6"7ytI,Ɨg|\lC܍#Vð+Pgpws4~\7 j2`@mD?yٍ``jʼn{- ]p=OD .jw٣bɨdJuQU+W}%+꯬|tg}t2G82&` Ï]WP$+c լ9+iyv+#|%JFs3vi<8+mq;rcgÕ55Xngw<2~^ƞ!83j8Q:GcpUL1i|!6]B5O{l$AA_Q^0%2=q3ַΦ H-f9[/ $\_罚9E2BgЏ qbG6fO =bv'3uYW@s571=8HckũYN1_5Kt-yjM2a6K@["7C݋!94k92oy~t vo "0+:lP *zl0"y)5HA{'m<?y=:ةyaU?48j*ۑ!PލMGX<8d>&{{?f>~Vw@+ky* }"U#rŭ=w"cݥ@/:2p'p!19SFWdʭ+_y||LX@9+Ab$.kN#[0Xr1so'{!'o~Ș@5q3L srPcSi hs߽fnp6RroO5AvWl|=-m{оwu[=}F|7g#  \vW+։s 0p 42}foND*+?z$Cm!윹|~g{&Z UiN8~X'r] #i8b4v>=4%Ė T~#NN.7ϝ9]/}_E̾aD"2_434!d\?6Qѹ[Cl% h ~O}ؙ8v3<}XlD PKY:8]ryߤP іz?DTlg/nlP_u'T3kbx?%,Y "?Fr6׳Ay|\<Lo6$p /-Z?~NX!ΡF&O.& -L44?ah/#K* :Y]wp<ۡqN@Nzz6/c>I|{*"Lf}^ilAp*w6OcIfb|zZXɷq͙f: '(QJK՚Ӹ5 Wd+ƈ6b.dS<;2hU 7X29UC~lqkG{s:1pQd*dIXÔX#%#4B S4r'vmfc(Xg4HBkY84_iP dLhu}e*!0;|t/',S6!Ɇc]Qw6>? eӏJ ?`lB} ;ݬyu/\hfqjszJF2Y{cFE`+6Q=HEA-QsfDlM2NW-j/yD?/}D˨`tzQS9 Ɂ}b|2RXWX3U4v]A!q"3cH`EG  [qT8=8]^1@4rqJ ?rpiJ%;eWW R-TE 8fFS ;5 ڦ٤(ڈG\t73ۘRηx]t`o=֙Y P96T7Gbg$oy‘Gqlۤ`V,l6'87]QBa/o!"@1wvmyLDe?{:W8S^^_R[4aяJ4SVR[X M"Mc9c5e4"j7x9XTX\[Z M@d O юv|vT ⑎>yu5YYf`'>!M]#Cl??YCda`kGAqu^iKU/wfs}h#΍f@ksƂǏ[>]AϹ|aQ$qX-a6OZpqtfHК9cPޟKHU-yk'+G'KwWnqxD Q%# 0ꀆ2S,i&CJ:hU#!سScՅ9aFhU}аv-(Q+KwԊ!pօ0#?.gô$v+p%5CVW %љqψQ{z+vLb= ߱@m?Hb-q|]|H՞|pɕ\ߔaKl&SD\Vwa&g3;I'ٺ)7?rǭ1 \ٹ}N½Bs : Y7;ڞ Z]_{&x7n/=T'1[>ߣLO-g*Dh~;Kވdyho̎ J?d//ʯ@ET *Yz'x|+8\wt2My3[B5uu#Y 2ҩ<5:'0.]MtíJ5mi@eڟ ކ8Ȏl^"1%DX;O&7I3֑Ӹj^tNnbJx (00.p\OB)Z|3%ӜHWAll|;l\Nk&Z aⱳsF H1mh4+cI@ @~k)Lθq"ػ[[bESfY&X.Ok\ =m MW ZQ6EWd|SV[4@֩BLѤVxpCOϰg%3~a1ˢ|nwrqpq H_Q{nfcM[n]izK>n>]_ )ΦGm`6NNvÐ Q_\)0,읩(jN N)$w!a(UD fKSweMGU!x0%HF&k;zQX ~JL"4]ܔ(Qҥj]m,} l).mcr _3V :?)rd ĕ7yE-- h$\~l7%Jlѭ>o+NC6Mq6%J(QKhc{.nJ(JGtCt l)QD_B{r.d%J]gϞEA6ٔ(QD/E߮mbnJ(*j\WڌI ;gSDp(QJC6ٔ(QD(Q{QlJ(QDW%JE^SM%J(>Do5hPM%J(QDٔ(QD%J(Q8%J(QD%)QD%J(Q8%J(QD%$U0_*䊖PdRf_$P#/CGc/ /ϝ`L+ _DJ:A%Js6"`]0V>wj[ƖqPVRExL>#R6_A~J.OBGT Aֲ)?lL WQ*SaT~-Rr_lAGFQV'W @:ZWU;9QW[fRX1σ|Fy+@!_ڈM.)M&D@TF%J,0p0od[aeX8DLat㒂+>_;r2ֽ;yg߆9(Εr9sbZ_JB/?\}9a. m`"_y6|fF2Sw{U.Ky'@(퀁iGb!+bF}@(3w>T+i{hq< ^k WB_6NysJhJs y?79/'6My=_`aj5GAds@E5V4)}%JqΖd4~o}ÇF}]EiG͊z9;Hh elzI) ̔CgJa_;86ǚ$eJ_|><pifF0p (_c`K #A~z:GU\ .9uDfzYE08-5=kو Lwx('s6B#G9FѽbLlq/q6 V0:~2h? Ԗvq Ǔ8[h1pF)_)~{D -Ɗ= M p۰(StK`SMdtUc@L轂lJ(97;敩mn`mAUEMȖZj\u/_[$g=ywxg3Ǟ"DDPSIlUiFn 4*s210ڍo]eo4=hd:9uFnøBN.;CUD釭PS{ PݟkÈlx/%@ծo l}~։B́TDvp92RҝQ $w2/K$16ˁ,Lv{#ӹ[)"uR "m"B62ha]Æ=Nr z6a%J+9;I7h gz;O9+t%)<*pDi&=9͝cTFş2 ys}UmfD&55*BE*/a6&6Ňl ]DgBCOU~hЊLars}|Le\fO#C v{ycQr҉I;Qd;t13œ٫o05#^jxC$}g팄KĄU˓?|孉 y+Ň^TFnqx|ŻJ_DGgt72=dTڙ_aVMV6![,zZ3^'GŽMgЄkܸ&z+O}nŇfd%^-g̜S)Q3 O '[%F.3y$e;R3OUy}Z۷QQ)>e,~c^':@# ZۆH?sY|A{FJԻz{sScS^~hREcy%{a1޽}>iAWo"c92lā ^ƽI..Etiۆ2ʲ 8x(}4]LԛĊA|lVWsV5Ib$ !˸tT6PAű괄ב/Sf&j} 70:S` W  \6cYɔ: J*Yt! 6#f6.o`)="aoEѫW1%b(z4 ƊFǥ&tvl3&hbTcٛWq9] {VUMrPџKdtvjuzI**(|ٌl9l´1}MltE|N_;µkD} |nbIŻ78^639"EMF 7:& XNTf>Nm:?7g6sY dkDz!ra*_FE묝c᫸eleԫ!et>0^X33*V;S+b4N/0n!DMAx'jm2]uLtūZ4ȭ-l`JANL|詙 hsASLT %M)-eT1=664e!!_.I<;3}gŘ+h-U3CvP%^:՟P6M#٘}:ga$c+ tmocKmeTDYtVW@qJ(Y9{"JfwrO r x&Թ+h+@k^Y{'Yxlb:ż5536u OD%]|%0 ƙqH}h~ykE5(7WO\rrԩ\bﲧa~gX]GSBL΅tsICs*H -3$5%[{^vw 0 8Ω\4/)f:2We:ߋtvпM)s3=yO|˚?I+/> I()ݬa1I | q ~n`nFיkucff.p^| =,aJW{/Y^t {cm}5Vsm&lsdw1m΢*p?7]ϛ3QΫƋY07049g~UlSh]%uZON0:"#'dU&1.c~zk~15nl!؆.?l[COx^{lmcqlE.ciRm]~%1 ޜ#Wna;q'=YFv$.yBãtϫg{9$tMqLn74v~ECg$YAO޽Jy{*񉅞Mf+.|[ս!LRstL_K*j>E-C/DXؾ`BPWbgҍf b*1pťv/<ڥPL@?!g9eCg#u&0区r!>\:!U9q,&L{k] X\'> gFXU̱ W}"@LbAS)KO ju2gW X|~~S"$缧i$( a3@bGf*&TlӰ>"B5NV­ V^{U?!}L6AE%'GIف;7u9{pyJX>s!KԈϵ:r"er(}zv#=<9)Eowl2Wb!Qq]~Vm"gu/Q@` O.x*FgccInp˶nD!=% "¯HK'V0\ɕqUNWVbh^3[)ܯ_戦c=1f}D1q–&b/O)<VswF-etE]Su\٢uӁrQQvBha=Ea!TANSqg{_;q .=-o_6l;2PLJndNwey`엖Fi%2ܲ['_'l [_xscއ;f!{嬜4 ocHSv{qjZ.k"|}hXόd>@A+ DZIԒmq,&֌+ގ@^( RN?8t-<ٗHﳋۉ,&ڦpQ6=}] Ƌ ; m?B67c";6>d$3X廘YLԕ5 !U(k$[6KH]1͎$eaK\+Vݫ]?P}눷oߊPхi`&>\֏x]y:Ѣx #2,P@/bLD)s3rUc T)})grE˓=nr M??V hn)dp-(Q3rvZڅ={;x6(j xtгZs{8$fO^1,8BZ^5ޜqkN%ѿb"`|(䚓3{3H/dji|:Txct5bK3z{x [W.~5T`goy %X\WjIYwMCeD:[ak/6%hd8JАknW2 ƿP}I/ؿ_!*ؘ Vc[htͱc3]Jm8xEoN|er:QēDuxXό^.c֐HD4gu\E&$e ~BzzUēfsdaWg' \TdrIaLRU>4@_Y ݏ^ epq9GYbad@_P)&ƹ{fO*z:"8Lvз**v=&֠҇&G]:>IvT Òqڟiidlr# 7gtT'Yzﶁl,lY0Qbk`Np65X%猼@w۞4%ؘFbJk {3̀ ꑌGW%b Z?51t@kڽ\Spڿ|cG;r1 N1q׸HpGe:'A{WuX~98X0f/w $ Up]unasYXōos6gتFE *ۼ} n k*U!T`FY7N?i8MH!rz {%қ!1Hα Sw/yv5BI/LY"(;ťƋW匪d":e98Up.Ztml *e`L3Οe cCt8;E%YA&"q#t\}]}uDpshmHuhs\sHxAY7+}Q^x%R<]#N S {s6"9%9x"*a nrqzoO؃_v(ș]w:|s/.I[|V“ɗ=x51vr6v+l|o?(=ŷ=ug2SwTAGH-"gu\6}1CDا8>Y3ّ/߯ :+odc$6䞁OOww>ۄvfT FRl[Rn`t[äVKڤ8^SKzgys̾ msۃG؛;>Q5N {rĩ"tO4|zy܌Z[_Ȝ4u9tG]jT?ۧ~m`F}ы!trW(Vw=~N3Q|<<̏|ll=kOD +8{_T"qW⃁'w ;+BV%[]9< qʁw/Lǿjw1-?q6{nR`vvPeDT찒77ח`}!#mG - ٫<U7ޑD{[KJ4?!ʛ'9оGk`Kudig61MyK:K dp匆Zo WٹY[+(G3_O9wgt52vDقUIx14٬>g{qv+7ӽBdJGI-5Ά&Xِ󑆳_}ӒU; &p9埍{®sy]v^$yhy{9:=sz:ރU7/8+TfNi^0wlL N{ \4we}.ΩnT<ٖqMWц,_~ lfTg9R EC/yG6WӇFkBSZFel\aqjS=oԷpǖu .E}T;1:QmkAu[-'ua|Y)/dM :>7 W>2lX̙I?%!(h|"8{9{p6"y 3so/C{rqRâ~G.բg y6=jdHgB쌮.ll?Vwv5'gos6 9\6g8(U#7rFbO8 -sҮؓ 2s,Lfك?lHl`^ 8ԯEV\LlY=%b |g5SmFv{r"'k 21 un?-Nz8s4*e95&w;?jێOF8ࣀxc_e;xؾ1/s6inwDٲg69N'k\Mۨ wOb-YEK6%J[!Y ~Zk|JXUm+] Joowp6 S"*J>%buE2g疸|Wv 8 %8,;o s"o{-*6=jy"rdtVR(Qlyw=^2*|yEqң-X轗]һ& ""XAETzGz}]%{>o3g9gNo(~gwLw=ws4ywyNۗ!I*C jOl[mǦnةBX> I`} 螺TOEvy1C ?(qvstuUK`&l|#r7˨ؔmiK*[G5[:CŕGnologܫbXҖqv4OGN޸PU<~ڦ.Xds'[':_u{IzMFwk*{r➓g;5϶4?!t$B62܀+io)c6>ޞgd"gOu 뀣G~I/&@o46X>xCy&cOnDz6r;Uɦt7=;iYHc؀JH}hc(-L^C늻W7o,7>oY$uizc.y/TK{8{eڱtښАj6Ln+`2_]@UXCMÔ洼ޜs5U?u V'uFSNp6iKt9u}.%yNcx{ۃ'U=m#Mm/+ kS%M'meo;o卍]ֶrfAEc =n ZA8w7&gΚ7E]SZFgWکw46UNtƛ\$t|.uc-s A1hMk#+a_T1mK38߇ں'h2[e6P͔ .V֢i(*OPFn J~2tEeF_s澗uhQ~ 6-QQA~)ݯ3OetOS;'&XΞ9oETohoxtɌ(~ή6vf'F'{ǫۮ׳/倊覙pSQYI]2TgM&암J`atT]T xP J)*ɪ ZP>CkF_UqZ$w 49W1Z׈}g5;αAΒ'[fy--Cy[I:{>o뚢6yYh,.'&KS6Mώ\S|MGIV67ll 4c-l2LW\Wk4k*dh E8zRS>D=~AbGGpv{YzYSXckoIJ1k5w<{u3T}ںh<\teJ4BӢʞ)1ΎݱK`TBxK@efUc'!'{L=-؄u,mwhm#g'p8.M EUAv|=Qz"n8})M>Q%-uB~Gu0הSJz(i E-ԮmH^V?$V0Dm,pv\6, 11|܂nnxW҅jDsIQĮή>@m0잂sg4|V\2OuRߚt&wwf< u5]=y Jԝ#>gd,nU,trv}%)A2:gmS797Uh]y+IⰩcn;(3*'\9{Nm^n w(Yxd4D,;o࠺ U6\]:"ΞhluG]yhI:n (#eP s4ξ}I~:gSl1gcP3\_O7 Nܩomlw4nm YM(B;$c,ਖfnG\쏞5Vu+mncmkmq5Sk{7i])1+HXڸ{6uBNӢ?PΦ0svóEMdw8;#N ak&z c';s Lp+E9{3{rzE%u=|'2qҰuhu"3&kNvӕ--C { s;k͋rŖr6 :z c6a]4nY8i&yv͏B;Af{Mn8ݽ>o -.Ge@HE7ˆhP|as{}=#%xv<|GiI~c!݃w]6Pu9Lރ]n*a`hک'QOs`R8W3iOQʫ|S0yy+/^@_pNDN[% ZF-aOx;)A1ˤ5˫Þ-#uYj-P6Z_ט35aQr]?(U>{^_\y7rDH__4uxi][~IDt,tt~{vn$ma>Aiwj Ҵ0&QJ3v_hW܏$ӂ1XGȈ.)^7Sda 7dՏ4Q%ToEIraxvk>m95 O<-K~Q&m7R3D=QJ|P# U0:|(V{p?(8;=*!fD"%!a>nG`U2$'%FR=Sz3&R4),G_:}Q#㪆ӟ?c8(+Yn&e!!`xɲ#Ƥ}D7c*zjuEO H +j}Y[_1$YaHFP1{HeFøJlёwsC4j94vd *\/ ARK*{k\tЙ};IIO]UCL *~Z8P7 ^𰨛>u=ؘC/ N HT-Ć'Ud T&FuN:HiL ijE)U/ײ$~PM,2Êzk69ewn>Di! xɭ+?!v@̀Ԡ<*bPWP0APc`S+SZӞey~aj;',#( ?gӆ㴾#kmH}˒ґN}Q/[ۇ[t1ZFrflXܒx@_mց*#رsuR 4v4ueoƑ:5 Oؙ` [Hxk@_ŷwA]Cp5ܾlUglR[Omk] +;ǖ-RJ Ц`SplYweQ6VD$mPgckxz#љ.^n-K_Pa#_ X؋(·ϡ ~SQBoYInzh  ė bp!DZ(5h*Chz#(}JFVQf|l%O!4RntRiuYDNXO_z>MO0󨡅(]|rZ-KW²eh'~b ͿNxflzԡ?uL4WU^lo|]ĉ)*EmL_q!N(Kp읲Z0=wZ>- rdi^whGN6\ DC9~ƇIҺFa$oRB)Ŕ5/k)j4V9=Y䤈C6VPuY}jr}C?d5rl^{*׎4D`0 cƱ :=S;Z~kTtrݩkdl}fAGv[:47y []Nkv*erp]_덇myu5}PvoOZ]-m_`08o/*+i;+r TKn_tcOq!%}_UI%5 6 }5-Ԣ~hP` F[%wf:CA5Q!}Z1FGA`0p6 `0 `0 g`0 `l0 `08 `0 `0 `0 `l0 `08 `0 `0 `0 `l0 `088 `0 `0 `0 `l2p6 `0?20 `0ٴ#Uy Uu`0 `08~Up+ `0 ٸgf&`0 `k8@ _ @ p6@  @ g@ @ l@ 8@ @ @ @ p6@  @ A @ l@ 8@ g@ @ @ p6@ @ A @ l@  @ g@ @ @ p6@ @ rTj^Ih\ڣ`j%|VQ)@ ПGTw&(0HHJ33A Y9[%oTV }'F_/6k@z@ lȯTVہ?5 I@ ПwBK6lFICGm@Fζ_y||bRƖUWT+*K+&+Gc[Ar J4~`'KIAqa sWܲ$,knEIa;_F)CeG/l$Y >Օ}PQYo,.9;(5#W8+ )-Kxŗ)."詘ل A 8cWaDIq+c'% Ifc2"0H! ߾Tvůۼ$姆!rQfj#0!1\Evjc&٢o&$f_=jpj)}B/ԕ= $j6!oy+;A6 eD\ Ȏ{8lkC^uuQWvKBؕ>99My#ܴ!'z *r`s n'.\{=LkViK;17{Lϫ⮓}mObުW)\Hn}z;` {џ8D9\؅eYdDz,$c+?HKI)" S_?g_qB46F}18~=G s7sw D5+MA G&vt;!?t9Y?=[ ,g3 "z l|ܑO C.fpª@;p6U""C~<ݍYƦRS[qtϩUS]VWOЉs9=mX:Mp"m"ו،@/VdoxUV;b[MjfЋ6=ܱ{v[ 5AT.aއo!~/Q{R^|\'lf:g۟nN)HOKL,}gr6 u\E|2yT빽 +OlWf͗Gi("ʽg3lMLF+zqע:l< @>dny: 땛k٢r|L2BʜsEaSbi[Q7/]Wa'S7HbMɭou8JڸjV6QyMR̫V }.ޟH"hhh>F5uǬwۻ,C i{۷[6z&}AҽF?[;V B.J2(-!|jkI8¡.vtǨks#?J"\8*a],sd =®/)UIT >EA % ͩDGFկ9-Ŀ 2;gcKzCc_&ԿaBI"rصD LS a%!%2zx`CY'g$4~)nAV#\`SB%&"٪_q! 软߂;"<6B9{n{aE+.Q"ҷW 07}JD侞/ؤaUYQQ 26u[aW(N/yil]i١Qy9"goױ IolOvißgq`-Q0n&gxo[lVm띜B' ~"FqrM[-k{.U[wˏ3[X]]^ +"-8[aVeI-4Q;j+Z#6Jn{ZwM>>[UR[rUQ^+pl8Knjlשׂ >!j(d{=*+,S՞uh>'[VuTWT\;Qej SR:g{jI h>Ȩ829vzG$:dOD^p[]̷:SGPVE }[:>z&o7,y&AH03M8QKA@ZܲB/xtPy9gdei R#2% Z/j3c=YG59Zh\oybIH^5^c]p>L~i&kdD/?W ȩ!il(~/j!":󜽎gq~нli񂝈hl6G8d!O[p 0K#dl̒6ht6@ۍMƟ(0(, r B|eaIea*>y+yyygW30Hի nP_-G1N||M.wU%VCP $lqƅBIquB7ӑ+! "!+''+-)# G2. hlڱm϶ KIHJI˒$Etc_B $D!63/}8EQIKIJ q/쩸BY3HE,ZE=[DE%"<Չ|bRedąxٕqt0QkfIV$&%lxQ/ͩWuxxE4vڱYAXP)&.'w ʢ!N`ڕ\O sAQ1)I)IYix&KstDNW_ŀ0_{  v̔D%% \6pBq݂GPFb&Ǜ-";v:9#c/2kldž/Z>ѱ(y>q.Ol $- s*#D^q͝oR"p+-rkzҁJMf.:) \IjG,INMP__R$=P.QX#@$IedH"Qzv }uqa?Ei=֑)q>mU.b<"x% \D>64AGn z9܆u[m.K(]LTRXsqȔ nHVRV7BY\[xpǬB2~qߖb}g,A^$ݠF!>fgĂȟ2{\dTҐcEBVz8{J!՟UOx'Zev]Dmݕ "tbɋi'*Swb h"_ s~։坽^j J^ <%"ᕏ M**9ח2wO~";&ʙY7 0E8ת\KjCb*<$"jW>U)$+ly T;&ۊqKȿ<=wpKh:^+iqK< G~~#9Q*j\J3 B49I*VEE?7-YؤvFf;,OF{mdb1'{FSI1Ha:6 gҋG,Q*X"Z2C]`w.6<궕Ͳ+)O^'JM[ocezs~(v^¾&H[n 55?``sK+_r꾥HJ. Ė`2kFo!h-}DQI-/R8+KQlI"qsCҞ=IHO+ZcF;Iɥ-Uvrخ`=uDsMyT(s&&*"bJk6*a}=NE/εΎM~\{62k84gGlAUf'cCkDkUEqJ}]qWVcם\svso,Wq[N?^ɟzIk4Q:R/o ռRA)T~r$>I]^aw%Ytn¼N AQSsͽomnllLIIY?vǞ٘_JoJ&( qz.eoF#jR@*lЎcs̀[TuWd\:mܰ)ՌvST$$d7x<,KA VMMI (4''z{FFyހߖQC[Z7<}j-=ӱ椤H_Exl\6UGlqH' r_H^iq,oT츔AΔ}w!3Ex?s._sVDdwO HI<w7̲{RQ[Y!F 5QU_|s9[DaWWs&1g9~gnYv3''UU&wc@"4=ENU_r?GtILBsI=4Ӂ푵ҟs*UR7 욛|}ſQ@m>_{ 8g?dAFx͢"B:'x؊c;)"%ۭģ{!yF~~evIiig4R\[ld641sf#֚4=mqrl8x:^۶?ޙjX|DAhkbaeuUeMCE2W#q3所vgaru.=DLi$p kE80Fo=[| sb&e#&7vk)79[TPD_N21hÂG[ح}kG- \Si>7eq ]},8$zCOHpDz[Qh?Xi;پP("LcQEoutNb$|ŧ5t\n5/ɠKȏ"4kݠ!p( _'!l{Л^luߵ=lx%}Tij5'5{ܹtoWy7 BUaa(AV ! pN 6 kIeCXw_)Xۭ㻿líxwH+.9;f;ѱЬOoɿ-*0Al8unU _;\⽑W\D=@xY]rZtδHHKIbL?*(q)9)Q>9GV)fV[mN5 8{'%װqmOkI}l!s6#)l_ٌkP%m< 8{DU@RtM,L Y8ȹA zF[pζ)YRj adp;]7Q]]qFQQQ ii鸸Oܞl,w1&pJiƠeb#ˍB4+-. pwL4RCwZosn[X s:NX_Rq66ŕIaol[OE;6nS߲]BEgtg1*:*TuYRE'>9|ʈd`, Fqc0,7:bI+:uEXXqJPci eEEgu|_(xeďMBia6/A;Aa)׬?c{m"l vl}/gD{.ތs,br_q)"J/Wct[ّr>M^<6h8۰oϾmp*|NB6 2w6"BC̑5 i4ʸsI\FLSϕ8{:2hj!dPEV 8'q\);?5nݾx ߣM:Y^QPPARq37zj2]DYi$&N{Q5!JJE%.!]bB 'fku8ea:_YYRZRW^ZXؾǚ<,79ubmg>3ks{K۴HҨuKKu0?eH\;}91y#)۳2 쑔vR;JLn#}Ծm8{NZy,=Ҙ=Q/z&X@f_ wg'Cwd'Eٛp]AQsN+ 8_s*+֑ajvfQ&~t VG`Sps6 m"-lNQ)q$א=?_%} ]}|M5dy,oV>6oL 233?{Yy8W9v/ ;̺f69ӏN3ij$ztsxӛ$,rzLfc~#e~nL;;كd/%FmY8{vfbN:r;܂1VoyF >Z&0z[dؤih^i]܉Lg#W \t ib8xZn_bGq6Oljh^b jF)5Y#n:2:M3sB$El h|{ kj.X==zQt0B% }+թBi=YDG̉h9gAPH% XxvfVwrh1 BS,mTl}|3`5od||eߋ=}=6>p2scƽ!Rx9e'5R ,%gzF0^G@X2p/x$PZݜRoRP_"CA]MD֊:%3׃< , UQO/?8ROoX*@\?5]~`bH_/8)&)ZXdx?gTY婱^ziɎ&&Xc+x S.] ^'(gu/"_֖^KO{p1C{x B zHSYM}g nnx.>HƟh C8;yvic<\Z.`VzBAV'7_O Sӛ~UKG9ٓ"2u=]ٓtxٕ<}u$}>zQKπ{7pl Ēu%Cf'btlgQ2?9ͪ>Ѐɽb1XigYU)m1' ¦;ݽUKk SvRxO=K׃K;K9 Ba,9$UAxu- ԜcS_giC37b1n0DlQ,ݛG (!j鍑|:~tt5~bՒ_/|nIB7㧬ۉp)|/K/lKfEI|{,wǪ㜽J!VIhoZyw}bb*_ujrs}]؄ɯvvJٟg=(n5k׮YYm^V7Sd[kw^K)35ymVnoڤ]V3̯?7;vkD-hԍ;( 2qĄye\CG75G[ӝa' X2jXnF [EεL蝘&r/w #s;20q1呰:_dXô=δɮsZchrgf'2Y}wq63vn\u'QfI;9QGŃ[@T\VQLvgXt羾;agUGɉv Xh> 7QƸN~WПoL{JSkhNZFi#הO'!33纟Nw% 1fbfb'h >gw*)S(LYpTg3:VL&c4î Wx>P## Mͽ}X Sҿxl*ͣ27Z+ӷP8GXt^+"p*;ç-眪mϘX[~έKnE4<2ϘTS7 —*ص˯Ɩ^m`_ɯg"[E,ݷdnp(|-"®嬆.&%2bPWGU|ɍK*6rőg 0>,vΙ]ͅc]Tا!,,"/nQSQUP)}͆ǧ߱HYy/ KjJ)p*~ƆԷ^q^&'RΌ ,O3k<1KK0=6_n^MNN᚞Em3')Ԛ^w$ߜi*NsSжO`~7QV\U٢{ݘr,;PP$$A@J;Ns@of{!ߨ !|@OPa%hǥǜ#S-mA? 8Zv Mw%/JAķpB;洞1Tb%°sT< =2`M%'L"" c[ Gt-7 {y/#DxJL o丏_ۏl6_sLm.fHU[IWP(dj_XVڧo1@ $0 63zY${i" 1t/)Wbbx= [V:_.e<9ǧxG/׳^ ұIYE$&ܱgc-]Eh %V:nEyIQR\ ٤|pYuCk[C\Ix68~ ϶hٞx;Kl⃭ \0AY Ԋ7;3}y:"p8otzKҾ"$^bWx6!=D7Y{f m;gw^ c3ۯóeb/pQgO>^ں_-Iy PO?[9QY˫:~d7>mlQo*ـ_ QA0379?Ӌ۽'O{=5 ~C? Tـ7EI(O ? ; nx6lp|P i+` i%+t1U{gyȔs7^mdgoۘ}?˹7 utn? ̠"'Mx~NȟƳך΍?6XD9WZC)%jgi dpgճk$}_R< !>Ӟ=<ipƳLhR t] =ZrMY4LI(}dc8݀GQڲpxMT%rNz[Uvn L"v'',BS?jQwN 6E|3<'ОqtHQ "bokmMsZP-Y)LIѥcÞ}ؘ"%.N BbVRqKߛYm'Ѱ CU ,L4 -M5&TU%õq2p1눾 yvKEUm- eU:4(N'Y?:s|4 fwNJMWudl{-\~W6y7^{4Xͫ'~Gk)\4}"sG>]@ƽ$we| uڞyֳd yaZK.:q_Fi3kk՜:ys*naeLc`[9U2o:00rCtʹ u":³El>ch+Kmn&r2Qg,Z~״?3e:VQu lh⁡z&vwyD {:ِwUNʯe|j]f;Rũ$̢JpQG==Dҽs>bpa:A-7"ˢ ڳ\B&'`+YSO߭OˮK tGp~!j. +x)Ťto aZDO (}_^h" _m1PSL6|pȃ b2ioBlY<:> L3kVCؒ>Q .Dïٌt*D]$XDX7ժT/Nd*eW 0iU3aNXX`>>Xj>xl77"Xf=|?XRH_0{oK}$.2 kG3lt]&/I%6n1VM\qo"&<Uw=D*r[3={B*,i9ԽZkNs+=[gJ 5Py)ypGKU^\X>Z"*j)aa9Ե&p1 k! \Chnhq^9_D Rye6dzz﹘3p C=jF\i$9\M;03Ft7IΡZ9~ܺ >IQį~`T7Z4ٖfgFF+ egά\3d7 ßA_O v;˔ttm/k.Vi@ZbT )Yg?99P{M]OǥdDuݗ#!L!"b5Y4 ~)஭TR#?{o8d"UMJyLՉfo:%(O5t cq{^?y--%i:N!Y]\/~ :ֳ4tT-}EytZC++?u[vS+8 Քoz݌BTJ-´B~e/O}aܣa:1jBKmizVQ|[lns*A'|mDD#`rH= ' ^ܿkn*ʙĄ_e^LB_vv BTL]=qfڗk+NA-g<='/Ca_*@*yONNLϷEYKOh׈^oQ<c_f\PPGr(hˋXNSb/Ñd;M%:ng?Ihبf[]>^Hīt=qg}?yL`ӘGG-)0/ROﴚ͘sB!n uU!k L ɏ;n٩wjƶWj}gRp*oo+eVxjw^+;::'t"UAhi(-w- C.ZޒqRK{aڡ`vVvЂҜkvR6a=Ȓa7njf甾*@JD0:'3-'>|be&)Uձ6sBf/~D~qnJ1){~G![>1ѝV٪ߒFd5tVG*]"S$N3Ppn6wm]pQZzI]mBzZR2($<˳'ex67VU3Q8;q7[Sq.҆n67 )Ζ[]VK6*ti8L6$2/&ԑ^1/`9(hGz}G#p^y<΅Co71?g7'*܌ͻk?5,BJ ~1 mC[+ tLj^& LDSJpukc⡺:D5,+M}1gs.͌M2OT=2ʊTB 7r\ĨSPL/zyy˫iyM.j?vTerX^nD~e82_Fi߸1Mlk,'ٵŠ[VtL!m B:Yn9U->NHŭZUwUvmA.];yEgh&a@CƬråb<ܒA%3/ucwM(AdʝJKodc2O49$f2qԢ4]^6:eۛ$z HAlmh &>i& fC[-(_5}RlmN)lj˙zirz$e;\4TA "+EuH `_uL"-cLʵ8/ԁnJACS`37KF ܒ꼜M/ݶ,KrʋCEqid=Ez!VGSHRLPCޓFH7e>egsCb=Ĵ ޟk5fV(*vgcd#_QEέ@[8+ӟR&߷e;SS);tЩ a,B7sAFwgh8PVEsDhFPҥC,bnjm=,M5'rO"f1U D>`sE\5 ?AN"}GߝHmZt~yՑ$J1[JAS_ Ei 0o#QWVfȓ$8%i=vwcZإU[19):Rטa<:DTmXj}+_~6LC;Ӧ+#Ԍ`:.1l~Z?MW2e%h\k.X6Z_E @UM Nn~mHCYbOWD(yUډ LBg 8[M? 1PJO _hb =FVIWQ9uFb (xv#!ŒdaEA{Xϙ4TODžj($|Skאv~͇ bQ} Q jd~0&RmZ8}:|~Cs4ڑ/0i_q0~ FiFc8CeD;xC#`=빱p*wڐ+ymg^ 5A̓itp>\1JRCj$,qn9:P_` nݍ-ԨFop\tk!*f<.0Np~TSH޽k7=Oփճi:ŋϺWe -FnG3WCRTվ2`#-XW]g5Ds 2%7t\+XJw׍@\"n%`eiї[N6JFKC-v\6J:8z2(g;zg jݛe;|iᓱl&z |qICO莕"R,#!SBU$s.&YA60=07?<^~Rg[u\1bq_U?%4kʧ< iiKh5"O죝첡c*؆yS07{t՟+MA<]?^? lZGY*{rق ÏzvU>E5]޼j7⾎Ͽm-/Q;ܬ=k ss+wT4RvNy7y/ep@PQu)hRk&b iݣk+0ԓwг*2&: 흕yDϯ,LFjAdñ ը'XڝX[_^D|x~iwӔϽ Y?T'c%XT"{ye6Sݑ$5N˭م套 &27 -6HW`Ωs<> %.S5bL%m FFKd'7fW6Znqkd=+T S\B\6!1u&@Cdi5@%Ûha9fExL"zWWniwB&ʳo0=:nUf1uQ a<"qx6v q^D{ͷ)5n#?5ֱ5SE:[4~2vrNWsE'iWP<ް7V- Vd9RSJE/NdܴL[v>L &J@ԋqFx*񪇁j.o{ly")q`Z?:=ٓ`DB?dJ-Qn~*JjH^wSH$C(< _qw:__* gSiFB2{=GFDeˈU:j5+EF*Tf9m#K7M\WQlZ~}.Ϩxj6 lQU!ޝ~áRWWdc:d`QMT^ak_>J%| Q @؝A:QiteJNZ aiURY佭@󱆻hc'y6?I+b \qCb{2Dߛ BrWuCY6(dNJX}gB |>e"T< aEi,'exY7njaÞmQ{.OJU}܋0ս^hןIw$_7rݨDzv}vu֣@ Y퍷N>HP2UriX5#.l,.5'Mjg(Љ}#Lg}v0Dڇ<~qQ5 VRVdߠ$G<oj2+~to3C;*()#8 ~sY, NǛ3 N?~,Q~_e8_P s Z5dlQic p*g )YPX .anA.sCx6c#X0}4ԭ@w?ɳmx85-|lisPakS,3.gBr ٸEQ@KȃOFs#2ٚ, JX'F:@Q@9uQ_7)DPM&^bCWG=d4#^ }~4R"eۺ|t07}PeUg;c9b~Goq}"OPS<$ .LAK>ͳO7砢@6bv"fbd1gf(CƳE̪p/0G|muJnRfL3p}}SCDV<`׌ƭZyqDf%gE:M,*Qg^e==7<):4(1=_EVkZ$Q?ʳMŹ+O|:;+2󽹘.U[;>Ȩc!GG" rmM+4CAk܅q̌ɉFZH= td'SHh -):ga9j^R&l*0rKP&RΓy2D.Z s4`26g'Zd KP=Iah+E[ua!^'jcGbB9>W./b1=Zl; l 4TE& csY!Bݏzac=5=^BKA*SSi 1@[0sk"Z5~S*ʹzv w~ihs`j"4汞M}_)I4LJAWMi^݌ J/aTQ^v$S;1r<@ɷHϖ?^#YaN;- 7$#f&U)gogs=٣ΰ"ⶈF-_*ix=~#oB-2h:-ܾrDv<<1CY.+mbCDrjJx={\CPVO ³ٵOxhU8ܬ=4k!Ƭ9IyW{] z yZ>l0r+ݘ%A9F#nh<[ ո J= 51CI:Vy^H~-qrms*=:YχGGpnkƷMXVK3mDYsP k]s1+W3*+;zg7~S"- yIБ%a=fۧwX5'cQ^D^Nzfg5y4FdsmOXWS՞XMpg'N@eɮB>>hG#ֆǚZD脳GҭcOx6޾~OUp]$ր5lwAQylm08ٸ)Ɍlt뺔lB)i"sY> {{⍝uHQ<{Jmm21{|WKDZܮso!ZDr!ٓ^".h5$Џ쯆Lh>Cr8[5o[F|a;Èrc)+ҹ=eL"-_lI洪{g^ĭ )={ʪ>gګ(={/GGv8ó3uy 0%bV~Tbn]gٛeTyg~nl}A]G{g7*`={Yg"}z^tKPDFɫh:*.s2T)'яY}%IU]Y=(agՓT)?gCgFRwLŹ fuQ*-DaSۏd+?s :ʳM:NqM}fOR1o&[vvZiy!q0U4.>S5d]u/0 2l>Qg ~GZ0e`(3X6@mM~ tJ1`Jr{4QGƳ7K=q[v`sxl?Jrݓ*&}&O=>RwO̰ {gW*<gzwl hƩxA9;JH7NWn*D7}ԳWӱ]r5jI;]nvꍶ@^:*ސx=IJIT9m{[g+={&#vs|yf-3L=qο#.h0c$ "RlSi_ʿdz<q3:YgY t|`wQ5OcTWaTw*\ UrB<,%hѹ$agm X+FeކZ 4tXjaXY իiI==`"^ڈO%"^SloUSV={cٿsbJkGF ?ҳ_s Tޠ#\T"cLsè+\<#s{ \1p8sAZq~Im[&ċ k=g?2}G!*Ԝv%1?Ţыnd;rW_۵a E{9{Egz氷L`ӛ"#ݑjA+qv{Tmt=G-;!ΝoT4?' o t>8UcT"Vl˛Y6qT-qzuoTC83֍w(Cse <Ǔ$Ių'bec't65?Ҿ]ex? W7ɮdV<^tҨ..v_O 47?\- ҤS3< 3F죭IŵA!MFFƟqJ>C G K/K8`$~:ͧk/T32})ÑU'_ A.̳:C:ӫ-RXPu媱\+D~gEɲ_ mt'SS|߃(`K^[l/P2}φa<*8O&Zk2K<==|]SM!rMk\쒎GV"nL=ꙶ6)~f )S4=qi gAg=o+1KrY^x^j!M&2q* .\_]Zt6f\  fgV3_2BmtwZZ'9Pto&۽ qeX_Vàơ}[!hKhDԃQOZKXY]$uUfM(>l]+Բh F“YQ^93~p+G_Z.J`a#R}Hz8DV䜠㣩O1Rm-oX;ӳXު%vupwg khϞlejtհFʫ׀Ap%+;gvE-!x? j݌I܇_fl &4ϖ-A)˕v4Uh[{p켜8: 峌xMmZ#o=[j6sIxu"GY,&wF*,1M Jq9HEx҆V6{w<+Ȉ^nd"܌TȹqK'=^[]׌B=;Ve")wF9Y~³7pv72vt3$ElL}TEO&Tԉ,1V2R=xݭ^G98s&JQ]FF.zNaU CNmTHs1g#/bg<),"3;9Z:jl0@˳[=h%Y@?lb Q%>~2j6 H9㛑N[ʴz1A;*N":|*!c+ȫla:'` =nM"c&b'"a03bjnJfy17yT lLW;34o=9J`'abH>sGX0ޅ@ߝK:^IͱtS+FW?4`>AJiawI1DFY(%n+ܔ"gU+:1_;+0y=&=qQ'"q`KL((ۑ25P"%jz07XZO h*!+) ?D* w}{DٿCwVZ}h2@HY t h#X{Fp+9w~ku\d,騆y?xFN5ػ?${/NOFt=\t!"X$Iv@[2DE#ɞ>ct9+ +- VГ$ QB!_G_pKSi|M3yX ⃯ *_\JX; t\yuR>E ^LWF?~SQ0}(gAWTg>NEbbFm:}q㲿 $\YR<93fYWDip]w0G:&UF큲IA{"mP:~b%8GӃ'j3\: X(x(Y 5I9'b ׫7Jmq%T'~B.ٍo(\z7EKE'UT>YDžt6><Ƽ֧G7:j+7vNElCgM SUgWTw |1: _x'M3vtnSn!~aGJۉeln9o!tÄ^`B|l)#mi--%-msw`HO3V>aQ51nw j.BvA6 BWjtŵmm\eeDL2AϞe6YפWKo;mo"kO2pZ^]DX@L%vcvcs}`BՓ.#w *ܽ# eãvI>;o]˦g~}ck}e~#sM1^ɹeۯJi̠~i/ij2 7q@MAG+C!>N۽ǟue3ۺZ1OҲ[}^>\⏹d5V+9p5{^HR>~a+M\-wb#Woq\L6/kq|ny눿׏={7.|;07$\o4vi_}rg=QͶWf+%YMC\I ={-Fل*76 g23Pj s*ҳ<{6;~;GDtRxR3⭎d'IÏ{6 gݵ'Ӹ0Rx6X Dmȕ ={FQl2sٽs;3mQI2%P,( YDP$gE9z+QtϜTx>S~GL1o`PG;}GJ~0)Y>:,U_\#|m? ~9{R1gevyW-CIs6g_Cy3{I'9JNb[t_J2QծW?=~_ f7po8g/9'dd&f^`&$=9 T_~vW}# 8s6;^-1Y_YĶ3'~Կѕ~6?2^\ޝ,㾬k nRLxEz_>yl;2{?)po7g/o>fFD'xSw2ԏN/&}̧ϒĤ`G̩qe]VdLbƷNh{2ӄʡ5_ /Q 95}yӟF'FĤPCߟMV5 qR csrU/\!ڟ hܹ |.eclk[gC ,Λ&gل΁_ƒ궥Cr6r6 l g g9@r6 ll g99@@r6 ll g99@r6r6 l g g9@r6r6 ~&2q{uivy?RțK ǔ䪬*F6yac?냸box כˇ6yawyps,}svt}U.C2]"P}8Z1vg&nO+1PI!g3g'Ƨ&'iMNozVhGS9nGnC.}_%FN1o"u7.&"}RcOG Dۍڨ=n8Z]\XZ^\F[qeu~}cvW]BoF _v/e#|+-0e)e7Uawmu-Zz*PZj(/+/+)-)f ƅhVVۮbZ_G> C1.6//*bĆ ΆҲܓqHr6{Śh;>jβrd7v<w7~~#oolQ# M셑{kZ-vh?YNhce@P?c[ptU}Ko%uTN}ΤQlo;ckuo\QI\`ڸ{oxaM Bl+~:DHX4"yO)C罶՟Aw̕^d.K׸hyMܯ)& qKˊ5_Ю>Hē/>jD]}0*74rRvܴUR:N&olq?8kBǐUXh.Դh(;k۬Y+H9iC698Sdgjrjy<>]f@n.4kݏ6ֶ7V7wZ$q̙I$lcbp0RE>csI-;"qL[-uXq'#%]C2J\%,sG\c8Fk_eɥMX8=*IY#D$Wpwc}sr8@'"9{g@ۤz]Gx;?m1YvO EkG~wjmwum}::5JE"9D&1Mܧ}E9]_Qou{k+w wwR'y{ [_=Z9>U۵eEV-_qWmqscm̮$nl7~BNj1DAI𡯆(k[ iaQ0Hƞ2`g}k"UH&f~~9]/\vDr!ئ.GdfA cd`k}u뫱$"9>YؽA;EA-vAG}K֊^:}A+[5ؙg9 GhgcTc(K{_7m;+\N!w{*=JR=y!J6:+Gp b[Rv79hnghd3X8u97xokecQ r:g/rvFfjH$w֣[]CSk$sAޙĵ ?Bo }M,% o'.vO.w47q{ѾΆF,w|\Ɏ|_gkKuCF1VgLuv Yiww{xbVһ2kȻOF b0!,5j-:󉯝ޕ9{4."76gBWŵl]Qih$:_y|>o8W"ͣo꛶q[, ,px}Y]vN\:fG-/= -l#O{R]\==`c?GdG5|eJ-k7Wg)^.#YB?۫t-Ί -EvBN5s 06fEۙ<(/k}(123Gbi|ʵlPN)uH'tgF ;ڍoyt^trkagHs,w= {x?04<""2o;ݚjen}ż rCmQv;,D+dǝ^wMtFXۢ2ա2huo2ɇX lZ϶!fmnm J\`wۇC\==o`#`{)3HTyؓ/ǾFqe^(g9{Wz`E}O7ož̓9L '⻐' ߻6ru| j}vσVVHmgd.TZs*SRq,".dp\QN~Ys;sGf2\}KNvqKqpVREjcPY( VG<<_6OѳLAξ'+c+b- 9=i[n վx`lnfen֫וmvN}0Uȳ{P(SaogS}wMFr\8GHU0zZvZRüh%eA6%Wiz`lz=ü~=qVZ:;Vf|릤3-<˶E:ܽ}e|ݝgWW7BF~_͏ spqr{y@7q9Kz+} bir3?Xba(n1%,%8هgDښڢl|Pos+sg&+ 2Ѻ.#ov~d+Hթ^Nή޴ײܐ9{}33TUBIĭ:thc=cMvaʪzpsSEԏzRwsS:|u?1}@" 67tNoMazfZLx+]u&g+U{&Gu#*esf9&9Pߺy&uLVT4<{{^ wUѽr޽|'uMyolr3ss:1l—IVŴOظ0gDF ^ {W܊EJ }Cc7tt2&`e) zE/a۪Թiqbsx҇tL ()㼉1Dݼ^jxvUMpO^[2:\i[Z%VZY;^E$a u.Y&T{2eqɧIZvYKuPxuh惽 8?g܊?4}-ÂֹI?!]Ҧ 2u,%M9ێ6/ctٿ(gOB m!- 1l,kvt ٰV-,9.n0UQƶ*Yhj?f+{~SFEaC@_U^n&y.GEX;3} ^-}u$߄JmmTyi4F[m|pSRt63S9{1ǚ[1OZ57 ח)h?ڈK&v6y"EDCz'{=ށWޱ=[G"K>*nu6e8 a>}\q'Ӽl{g+9'&d%_:94 &Jr'k#㣕*&ôVRIXZXN^+xZNzjnqCkKG=HsW4H)y5-]C=͇9w-5əɑ~|}}}]7UaGsux/4t8l >[? RwFj[gX 747i;ʺҺ9[Հfv |u+̫Iݱsѽ K}&\nƍӯxֵ~}.[ZܚVJ1Bmuȶ. 5gn=L cwee3C6YM潒3~>\0xS[qŭÃd0~%G']xyճG^,]UdN}.:R>g"M;N$;Y﷌Y$O_tǼ}9}\ͤ)F4kt[rѣ*E C;񲼷OU*fԒ~~#z('57 PaxC:] 'x,ˑ Qf{ŋ}EK8|` 4bz[ԄTT^"Rvj.XOlzA,r#Gwq8w4?v,J^@[%Ϭ:՚ Pw2h'63l[]1Zy#F[cn3URZ P gۨz%ej 57k!ۜ2ѾZaRO# $ _R,eWcFTL'D=9e9:q_ v>ABwUF&>Hm q-8 (/UJp?9LV6-^+&rì5_>$4x, 2 e*_p~L]wZ R:RM7;9AFQOk}b$vdRC=wsvwٚ>|U-eN@}nlE фkon_$zpk uUͳIsm M}{djm|rtM+8QЂnnm`pLKYc=gWK[BZU5⚚qM%*娽ݳ sĝq1yTToUm6r2ejH1ӷT$ޫڝ{wC!U%~3DD:V c5M_/o?_7g==;=g_LzzNq { >tf^WSC8jk/W3Ken"yյ뀚om]urW<{yzz)h%tފ?dc2Z>͑){í5^ژT1Mf\ȲэgfyFccgdrpN& lkVG|sKݩ16Y$/f.b SbUU/6rDdUױf<04x1uԑS~^A;ѓSǰ^x:I-t lUe7pd쩵Cي6cqj@G~2I;I1NjOjt^kPz2{5Wtގ~5ous~*pu|a8$:] e2ZB'>ȓݹH{SM2im5.3sny.J9bW⺋[bŜ4J=lݷĺ8]^ׅ|dݿIoDw-mѷM4~ VyConVgkV?}MjjrrjrRJRnY}f:9r|*g7E*iR00癤'Bo3XH,j`?u;L802Q0[\ao :vKh׵w"sVkByL ;lkLʣ=ݿWʙ|xc{9ۭ:F>lW}ɭ7&;o큈`./}HwiȐ({B01JSR!zzJny*vo8rvs)~Yxc{'^zDudW>)uf'U^꘣|h<ʮ٤7y#z<: Ե'W#O{?<2}[[KEdt3mNNEI!ٶOߘvWߢkxr8@c·rn<wyq}.u8CNBIIg_YVFrl:_I+g?` 2n+s jNO^c)0spdԸOwo+=\,bÞB*}}H]EGkr'gx2Z $/lf-8'r6J^jqQ y5"jYr2V.[9|'3g:+k;$,S+RV}c̥'MrvmýP쯑o~qqǀlu:VbsbK fr:I##% R?MQ._l\ƒWR1%&̜MhwRqbՠSpVJC%ӻٷR*\=W#eo2DT*YhJRJB$.^HV#wa&cƋ#zA\tL5wO f/ux Ե| iguza#gS=5=3Ԁd=?<~xgSe++ޞmX@'Fͣ2_PGf61=I_؁9'qD3~þ},]uUѲ7=vܼX*i&WYײתoֳcc ^Ҽ!;玿վqj\~EK\sCS}7&#b_p}!$3O{|/r|tK^y/GU\9uIӫiM%mik)U?!Yk3JՇӂh!uٯs6u#ZGsF;j(I Lص\_1ivS=dt䶘R:QK]ߖّGDs$QJž j"ނ|q5_̙32~ޫśjQ'Wsn6" >^<gB|&j3Y 2ns w^wL ٽg.zlܘiEw3މ?+9&&2z>~T0eLsyH8fk$2fIT #ۼrt}h[w,NJ^eZﬕd ?=:)x?™1Q7&3D;s(Cyb Rrdhf=ua8?TQW/}awčG#1ts<m<} H>Sn/Yf#=?W~9n4 ӣtxT\2{|m`"OɲW84>:;82 2zݎ4cS !L[ȩ= "#[;Ct5F_jp錺z{نKEqADX˫!1j}E1_ɥ\T1Z4CkesN`zqY@#E𖺪Z?n.,]zA m, hJceQ$U?uIJ] b%tEqKh1Oy&m̛? @F)Ejy]?$>2gG^q񱁎4oe3si h̯!MVH8ԐKΙpc\a^e;r k)>@66HY݂>$0Mkiy0sK77dR؍1My8T_:~}SȱV)gՃU.ƼbTP9M]YC* 6R =(ҹBoQ¾0̯SI"Ԩ:VZ'lrBE6i*D+GX󇳣=ЬO~`۝ٚ"b^ٌQՆ>$.Z=ltK2[L/ⳕnjQ;=n(6x#ëG6Y磑|m1X,mK[,vI!^}&>׍@^{^λ&~:Ӊ667p,~Q)㘖Փ M1- -C[C+,Q\҈OП H%0M-ض񱡶S<=8:^R߂]*4 vT5v-OQc-n>b,iFGʤsS+i1![O,t=n*uԼ. (f9JU76?ח6[5p䱞 />fї^zE߲l$$;ork }M&[IH)TST{ bcUB0cr8b 27al."Z_PD\3se1YUPPXDL.2beZH r֞z2.uTiI_ZWdeWV2}rrw !imw$HX+kez:;0@γj!J,A"3u?ВAHݱa5FVDE" %l0HJ7n ]+P JGV{Pٌ9^\MNyzO-r ^nq''=oh? 77@ˬ+U{e: Ⱥt7G]beu"BB7nًQ^hH8oP !]q!!a_=a ` s]XHPg6᭧]DdEUS&ՓS2|RmL'Qٖ/+*z]TDHF?d'_v8۞ˣښ كnUsC !>^2Os080O`k/NCLXXJb t'Q^W$\'LJKK)<̘:Ru>S /x$*}d'PYˉ n .BLs y=7*4YsX`9@^VDŽ40H=<9R}8c=~&ꖴ0ARa[߽?םVTW)zkXy2 遱my5 (9챉$r6+-' +-%)aT7~!*,$*sGKYAnE_W[-r'͞ۂg2HY{dyC_qzuXƊJD}M+/wl?ыzQ Is7s5FOC1^C2#v´)zQ.cVU>TZ>)+̅v`mMX&b Amb%Di u4,@DŮHDŽXgg9Oȁߑw~fќoy?$;w:2?۾҈qc(m|:3T[݁gڃߑê`c?|0Yv0۶J:p Ezrzg}mi5? {,c+ZXQRz_oOͭ9hGC}hdlXTXXnTY*!-#/g8Gޅ4v}g%ޛTw||3/(F#>%S?E#ѭ/8,04ݔ500r k5'7 6Ow'הnabVy ȿΪ&[n@@KKkXT<'@aCV@7FUfй2wWIC&ԲMmVX_iMoJO`hh(#+'(,?::;~@xt<脔tgGwGA}_1CE/Ԇ&qnb q:-9I^uϫlJ W$.2&,bT,u_ HB В(M {S?4<',gx!1K q|.*mR:b?Ox.9ǩ^C_nG{XMqw_ͯ <ã߿%xl& 42$2&}C٧?pLCQ!io^]0RPb }d5&6ˠ֪@=]նldct!{簰85ILfW:fC= Nz~>rmWjn٪Iʯr>md >i,{ ݯ|@$a&IY%9c(w\ʣ?gCծM;(InS=ʦ@j*Zz*;Ƿ'ۉ+HђDyĸ.C W)_4'vvt&$cp%PihDAI)XNĺaq==s<~ksT,d!]]=X@Ϲd|K?*3[o$IϜ?5ta=z EVAXk5?ICfHNccmL6`*ͼaE$0uIlo_o,1_yu?hF5Xqj;]===M'eތ4+]~")vk I>P]IFRlz;*J +s*X:%Դ׵@ W1 hďKLRUSBBpDLzfnrZoPQ[b ئdQbrZo}Ft͝^׶w~)]n1`ɯw*w0J?îrn=Ky }z#e([aN=]Ud4*ǨoJ>vs}>Lgx|tP"NYٱw/e~7"_ؔ\)(xE٭b)$":8<\ʋ>d/ xrrM̹utOqxx4=e}̅ܭ.X"4GO3o.w~V&٦P"kvv'/X[{ux]ۦ᪉CT&ye,sx|I}>eSP륿$Y.Z;y+S"6>+$#QyPw?Q;>><:y`` .`sQqIh  }z7 yT~AG}C'Ώ#(m׼QVеqx^ZyVwǥЛA蒭$%f  ?$I BE_Pg0<\PC^]q'͔TeMd~=;gj[eQ5=?*Ǧhxˮ؄CM&i^V߼A 5/Nq*19y+<g\F8q5vY=W=}|h"A0x0ܐt_,.kg4ˣdS’J/?35U>Tu8#Hh_s^`3TaFں<GMJXC&㑽ciM?ؘ݇NmtWkG?yV=]2uvsw˨rkm)96M1:Fˢb> n$7hʷS>o`.|ʤ:,%Il?x3vO8zԍ$O|>t@[mQ؃bS3;' m!'?,260, TY]es/~";A030426 4?$"=+XF$L}}}%S>|υ8f귦 l낺# MM-iaQqBϨYAa1 ɵcNȮ~x\YlIm}qF!ygk |{SWߘʀ84Q~͓Sg=q! 9V0O@h$gť*1G~F'df / ?@ @ |wP:)d ?Y ҷڻN]0c1p}6v }i$0_#ܟ8dPH3;K+@_uۙIQw~Lg@$K0 }O 0 B,!Žށp /; @ H @$H @$H @%Yy$i!J`C=Lf&V,R &JdY>i!If||M}!s>hqRirXg ʛ56]£;`"=e${h})e- 8B,$I,i|Z^g"XiaÊ kf/}SW|z}Z@D:M F'nlڻ_7 .I&Ԥ̒ij<;̃0KџKJa'U沈RɿWW,1EKџGI͈C`L"TG6}0܈~m 7AIrH3zrU;Յb0f8+!ћd{YW^Q_ls-5]_5>ޤaYf,݌b{m& 8%Q~Pi.(qn6;q#u{v|^w"ZrpUo<^xlvfFϋ^zX.F0{o?3ѻQݐ^xz WGXd&)@#rsXnB#qRc['70\|FDb._@ڃª&)L[Zx}nMsy֯o.m8B͓8WM?,ȾYB_bŮ5~_I+&qݧ;?y| |vL&YDYD!䗳/6>H/ b"#ru8H,3< =J%ff%vXVцlS, Y&y#;b{#-$I";Ydw-zڃED2[. IcGaE3)?^b6=ktsGMAy~!99$IJФbC,4٬fYwm>v fF 䰢v+9)RlrXy2@1:']Y¬k.%0.k|,c#ב 5(?$=|GyKǢB<ԟuVIWdŶ9Ic18 Un+ޔh&@G}-Z}x%̯6\1W Z+I#F|1x Tn] 6kѻ$I)sڱͯސR5AYd孋DO Wb&צOTR8`bCj^EaucQk)YYtoSГ2p᥆Lv5V'nZ<~ɡ̢sX-L2*poG4wY'3MɹMW_b蔰\`ARXvHn?s$4BP:2-ᡦ»FVG/ٽ–ǖ*gGͧ';[C'EF8EVb38|2ņ*;p$@55:Aŋq#(O(BpUVQ^]mU/8.T'?pd줳<2AT{pjJ|FuzyKb&Dǡ@_ڞ Wӂf(/6j!ւqqe'[b}},$N}W~dlvz{>Ƈ/ic0%"7?8)/VdDd5t_Ȑ@h~Z'|82/7 2S`si灝&¬ĔA?j|uCMDp0OSl#6( ,Xu~Z~uz9<*ƞoWEW˼: Ľelݤ|OdQNu;d՜(#yѷZ"0#kEcտ9:$e -uemfem)(W}rAh.vi< kůuLl><E/"}5|Ʒt,Pˉ9 %FTN,;tL>s&%xK?ʵ,ׯ#p)~>qnW^CS8j[7ZR$PZUPgmNIyg]3[PvN50/ S넑Ws~6n!!!A^.N"*E~w՘2SnYTڻ! B$׬YW~% vV2Iq=3:"Wy&6v5,<\_vOZhD;Zf7ӰU9q6na!~NVuJ9sLp5y$JlUb\-):ףGn*KF6./ˮY[jz֔;xM<;:ZfޣUe q55{lCmsht{e݊Zf~#wOe՚k2rMF%5X~Hf44,:wS0p aWND!;Lzy}NBh# 2xOSH#qV1c=l>8vs]L"J: :!'S~ sZ뵈[5Fݙ,X:ݧ;$Lܥ2lusOmEVmQ|=Q%mn_")GHUcH?HW^\ƷRy9~]-o|E˫֌6"Os(rߺ6RUz;{{ӭ'KJPQJ!(KO-59^4S+R@H|xD%iWϬ$Jc1qΗ;*܏\ նnʭe/,sP'EW]uwhU'mYÃ,7<)'DK߀"NUUGVN&PUڂFa4wȳYsrqXO)l @ s=K,.M|πLO^N)hM%16~-VNM1|@S~w+ iMuO,It:v}# eu2`UUSqf]xQVǒ [*D)Yٙ)%X%*}WZK]|Z~ECpO髤ćB4L Ɨr.KWeKrM~em‹Zd:z6Jd Q~S:ZJ\\C:||U»좊r,m@]I /3}ޔfUgso"r󡪶6u q &6n^T{7&1.LT iV;eX9,2Jj B兙P"o Z0ߤrn-N-fCECmA/ATaHNg=ovMS-8CkK|(:'5ʊo}?g_@H0 /+ `!I vbiYX)EV "a!n17$,8&l7Xo 0B%WM#|n0RYt%ma9GX,QSXZf;͍Efg%3eh =GpbcKRxD,F!ڭs SF%!z2gK<9hԯd~FbxVud@?Z>]Tgsqs17N3KlwKCcdZ=e%hWa{]jfmW2j4WcТ D˴eeM:o{0EriVazbNQXiI]v'9Gh$U@']s'W0ac'(>բ,Ga7``x^ZuMp%,]Cٱ9ذǥR5;92ѥ,{v92r<~1AгGY.ix)tdeKd^Dhsh1 |A-$2[JȰJ[i,ʳ'"HAÇa'|,ka+F? vos k!2حhL vM_`~~xB/9{}vw׆_Z;j.!%J"rGa}YK(dvyd5:Nf&uo,/rz(#̝CXj` wG! 4hnVF GWXaeRE)CZ9. f~%\t4G6&H0*i녣j~AG| %ߕp  f(z;q ?8-e@մlҠ>U0Qt4zNVn{&%qM.="]44/F{/V֣ T5ViUh^gOCåuȺA'i =@W)~:qw@+ZZKZYtJ4u Hf7 -<,5XRѐO}9^&ʴ4r&wE&4'R& ; 6={w166$G(Z:`.ڝ.}c!H-†c, 9Nbބ@[;Q@GscOEUeUEeUU'$!kH|C>zH{ϼfD:hFݡȝ:̴8_:]BVOSFن'2P{.gf0-6Ҽ"9)uYQF(N~yu'g>?IhtYm'`KBY[QXﵽ~`T=0KQJ+KdEe1zQ, ƩU]LCm9*G/VէG;#C$Nc@ƜD=/|U D Ӌ|^L/N&|t4&$J^@`<&3nimn=*ٍ:0AJ4O&jZ'S u5W._t⥋]<#zU3}!}@ֱoƮgVF;~X2fƺPK!de>\rzʽJuz+xWhgn3UT{1Qd|YrBRWF1MUzC7o$XU[JoؾLHWɆE\Ͷ)KYCi:ǿik~Os Tcز!Z8amWq^^S/#!+$(M~%4<z޲-ڻVi,Sz,*,Yti[w`e7+| )J!b;?聶=Q"写NÅom`;vxw:4\ۏtt L'Rݍy?"̀ݽضpWS!c__G61z.so>]%o2+ΨhI(i×UǻlfWh*}_Ʈ‹&^ tv }$<%Ͼ\#%#:x3^DxӬsBGM_͟L( vؔe_u Jv _?%ш!4\R«&NM/5Im#7 !L9X&'=$2o4=zxH-;,sB[ZuP{:xp"f/|8:.NSS%\-"FWj 9牣-]ɗ_A !Na?IWd5g05~^= IPkXF=7V' 37*s7[*>;} v.웒Sy^3'fGL޷e/U{8WI ,ªJk`2 fn e/QnΒsmWd'KhXPZ57 6CC7ndc'Y/kdUMVqNZ;7;ul5j%. /Ͼ~̶FeǞ'Q[Gn @o('le0ZL,60OX9 yh\z.ɻc-ɲJ~}QSf-0'0kd])TB\ ԗ~I@dҲ ,,fk{1Fv,[-r_wi~Q45#4eBZ^Ρ3Ef̯r=r tz{qߴUP56KEުpōG `=+fyv_>{` _ׯo3[DxԱf8}W0r_1[ ?2.yDU ~*4ŻWf&s6ojwga;rhՎZ:{=|DMs‘G_UCo[\`c ڥuk rKa֖kX)e1{n tr8dl֍|.^۹?B] 5WC+#:gYf<*+o0ay^!7ڿOq>InJM˝^8Exݸ{IZM v9k^5ϟ9[_㩋g'< NΎ/o;D~m,-O hIy6aMS}V w;;I*i, 8L;DO<_ԕ*0mx'7S u>~ h̴2"_:epR~x3<5݇gPNulLz:i8.LdtW81K UqJ#L3c˰G8HdWNySLdtL@?5u1 cOX&6g,QKCG&?{2/-GQn1%9,dc,6%| HRAg͂?=U^&3Qb.Iq OqQط[e),6R<*hf2H`NvCD2BR\̧34z `ٓ@HY:ɟxU*Fυ06ˍ?,o@M%?&;Qr G>Ehdg0PZ§# =MXđEDoOۅ 22Y'U,Qȏ<93vy1UHBvTlX&5Y|*aatdZ{~zOo!ݓ> b5hT>V+^6#j*@n\ZAٕ'Hc!jw]IYmv)EkYg~ i}Ӕâ~N~AOOPcSs{v h 04*4"#_xHvH)S .Y14%fN*"]SGF];G72.\͹E\X$>m)mVYEdm mWTUQUoPT\b>ۛb:U @jkHOs=A".Z/7TbWX/ˊ᎔C҂k˚:xm(o ^o*$@q-K@E˾_Wl:/i9ރ2_P]Ph-ggsND-Q[$D9Ÿu[>y69ZYeZA;ͭvq0Q.xѹܦlGxtsZ"J}Jg#ڜUCQH|'$3J~-Ǐm R 7iE]%¿|=Ǧ^aA.Fj +ְo+DJo@}ή~KSsKd &V FTݫXq%Ҟz"T|X7߭D"zB?XS]h5 k$b Yz祀N9Ns,QpȁɣBTyV3lx=]Q($-P9i5*ζv:`[zOHD~v} xp+jy<]iyQjïty?$20,w,suaQq]c/F'A+yݞyhmS+ a%u߫%b ).'G-%qޮ]: uvl`<m-USm;}ͩp~IQ]*Q!3ްum'QMD>&uEؙ4J`P}ZVq ;ڥM-Fj' [3Q5u~AqIV~,D?a6 laq1X'ғoeEƚ"kH ?;.EW@oGO@OO6 u N2sJ "*FnJYO$ٖ+VD=W".ц~rF;,tucQcQ6Mw::+$T:.Bc=$DWa@X˺VLrcz-I^U 3l]6i RLVoWn+<Ƥ+ VH_Ij7?e•s%,ay2OR[VWOpEU{dPFV.MW&Dgn=Crjyb@Ki;7ۧ 5S F9;ػ>nxlKjMPFa3~B?wyuTRwOm݂&=)+(2 \daAytPǧ wLJ.m !}rrpuN+*}n.dOnvߦՍ}0cgo"ӧPvȸҾ޾ʪƦᖶc!: LG̝llO3sƒãц?/.-XX "߳?yoeX$K} Kp¢B"VPxthdlbJzk[TDw75حtC/.-C;9y埚[ )+<@ 455$%%% /􆆆6wF̎YrCsCIϕ@ M-m 5 `ofnfi/}[bhCS3XՋnOyye,7jhjil}(/Bo2۸滏M@qv M~$L^U)۫coθddTY|.ҠjR{\F>YA܎Dco%a3?ZO#w;KQ}˨fqq{3<`c4{"czj6cηFZz2k @]Xhii~{siMo<FU7vȶ64tOzaH˹h<4E;nR9"ktcrkGW\8USNWzr%V*?]ն/]"y(n8d𥫳s.P`R+0xt_ :sG^l ?$o@Ya!KqC%omrKnbaӹDUpLOɇ d:( WF6~T4UGRm؄ ,JOp27U `?鲄KЁޞAe|* 8#fxS;{YmԵVF={7xECG&R&H^[km49o궥Kn }tI@K[oDN>qQds>;ǜ JN%s " *ED ssΩ }tԙ9gϯZjUYUnunVm)Ң6ȾIZکE^oK+-lW9; UD-R0JAW KMi[ǟ_%!q 91Hז*_KH tt'r~^+S=/_FEEbz[N<;^4IГJD %i yTgU˰PdkFWMFs[6T*vnWĸ:o` %$ |SݵK[K#uqySזck'YfW"˓R[5Sȸa2z @ hmm000 zUUt9 P7o 1+/bQ_C@ @ ?¶oBSG3?"ƶCYWkS)1R>z0ٙb}c͡o0i4Ϗ5{(\~j{QWDvۦW͠?zJL/{ޚ'ĝnLKʓ1|rxTsQ\ |k56xH}y)|?:.N$Cº67Rߴ&g}^ڔu W?<)tUQs@l;eo&`؝67tVkwM oaytiV%gixe9gSy3 z5I_iͿ!QlXȾN~D0>Ba/zTF 떍M Vҷ&zLbf>3U@]t)2ژDh ^6} kDP:8pχvf@~ml՘Sp9&c#&W vnk2XJ!hfnl8; 9rlJ}0xC8KÔ;SKZ5(/;5=#5#8;pD'% <;zT-z0A 7i`Qߦ.ҒR6t$]ҕռr7.#BMsCrQ2$fO^T4 \G 󡓄^Dk8"|\rFwT̙{\"ؿ_jKga=a(vyI,7!.=O; lǛ=~fRZ *h cX#ag#b$Pb-f,Rfd}LmӪ&'5}66P%i>UoCW6, 0?L)qf#2Sߍ j[ln :r!s'W &58M.v~Psɛ֟ݦ걪O:s0~gGaJD-o?=m[7}Iaso$l~aw&f/hM s8n7 $d̂W7b紊!|IFջSPF6M_gc:fEŒ"yUNEran9T-I.Td o;_{pRsfLbsg GP 3YRo;ɫ@s6I|ht64oeers=Otqsm r: nu䙅A2*^7G^ .XJ*)_H_/xz?xgxfԎE]̏4Ȝ%Moow:;UJAGT 4© W 5)Z{~ݴG&s)lg\ZYvi-P*M&z_OL?AUpQV^rk"K.&L$i2Pʼ_+79˻~KMYiSp@ @@ @h˛܂?kX7P'@:DOܿaj_(?s݆Qf}m]HOM-((()-D4]h`qq߶*nxiv|@\jb׭<.#K6"4݀u? LX!2/4M.HΫ~S?2:evnqU,<;7g8H$cg +ɉ)lf1;'BWHLn7aӝx5e_HB{?aj <'9<K|"h*tr SⲴ7 Xzl9HQ ;ƉEVɓl҇ܭ( [f7 ӞF d?COZBN]]{j@kkkoަf546V"-,),NLFRs*JMuub{C-' `"ƄU6gW-4T){ Nv?;n8,DT>@x)62SUFQ339+D#Zѵ K5׎ޓR_؉,vȚ<$][qUy ^Vl^V)Nc0 4נWgUֿ1!F=2H)؜z-tS۸aPQJ=B}咉A*.2Fnrf.2&.2쒗7j\ĥUΜؽ~&TGhT8;nV).]UE:0Rh^P3W1ntOտ| 2;)ɜS@(%|@ T'g`#g6{A5g h8D,=7μqkqՒu4zqF~j6!*VSȋ䌒}8!&XJ>AM aCG5i]1ruqRz~J.RUѕ[IC=sN$4\I踎rb=*e!?:>nܚ⊩i*ff0Uo]!&xj/zwqjl|r|9ZEPp/Z=oW6 L̶wf!*jެ7G>A1'\<{djvx;4e㷀 7 m R~GqC\GT$=C-َ2sr K?>> ?~^g  |X]]~]555]]]p!UUU!+W000XB!&X"~EzG„ 74 <== [ \&@ |u{lw-dw*Zn!UK۷-wO~ї˾ 00Nk]mTsrZ܅Oeq|Z6H,mjov3dFD}J3IRұ|Ӈh|4N0;3:}JMFL\V=hRu#%I)) -6fܶ֕PѿYһ]O:?/^@641|^ԃI>N;b+- q eKAey91𲚂9meEl.tzI[ZC{^6W0@B9uYI)KW &J]Z]G謼gn֋YtTSPLjnnRM!>7E%lfćy^o+bW{ +ՎqfHp^򼱕LfzB#L`GEy%C{߻7sWkS73406+9PZP'%3Yiu msY-597 tlv,C2W-&WunĶf'eG: + Wv@ &]WwOL8˪>N8=!é_OSGtB%ڋ*DvnL b꽅Ō2GA/6\Ջ:7`5J<ҚIDPuETE\[0kJ\e2@!n)@H/_ ]bYk|"[1>3}VAݣ#*ܷ-$fPTÌc:4LN w^#ƁPkn fwC)iYE}k7-Q%ט#޾C~bF/H.LNQSh1Om]$6?㩩sJJ re%D&6@%{ (m w^>;WE]ٍ S7$]LU0۞ZOzb=)s_@+Q-,RDtAQ1!foլgV8ݍmRL،n`N;#1DGF,v@fk,Doz.*u@7^=8zS9̶)~e$>j((݊1QO"8yoȺw߿yH]ong#TZ)3W:Y$쟱3Le_ ॲY[MHͩnlXؾ19mGS}݂["eXqtwaBlr_,}S |ej#b጗ay+8%1q?=o/ҺsKMZ9I+N]߻]VGe/UlK)ZWEܱeLmXnOR>V> -:PFťc$u+.EyBk]6; (q"3Mj1ɻ&nR3iVɀ/~g'2di[w蜀zgdDٝ;p£+])tc'/7FPf@R(誕-[sd!?dZCa:556 j.{)l#J&xse7ݽ*ܥw\;02rsᬄm = 0;(f,OFɬ}cG`嵫2U*Ұ溞zcb9C.iп=Rgq)ɳÛH.^NB\-iMKer"|xZwq~]PYX۽´<83Wn]õEH%cߴOt:^o% =$hZPb.ǭsPm8'2WS$6D<70l)mi{jx\J  Vܗ 0ilT|>XRpLk{ioc^j|}﬽hbNkؕ+pu8蒨ɣ+ &D֧밈wHr~,lt `GR^TUZwICY,>2@>0 4'7á$/1|7Ql} {E"vs6݌Ѷ'rҔY$X>UH+,-wo$ hi6ʗ}d{ފ ~BCUX=0r3 #'yyyϐpȸWLЫө-XY9r_=3*.i>r\LgE#G7Ţ~he@Q\@v89-eRU_$|7pc,=L DA^>wCvR1l?,=DRk\eabپ]6D~ Ԗ+@(Hd'y6@)py{Ĺ #>.fr}$Aѽ`at(YRqX  Fb`$udK8)5+c1 Oz0نZ2#+A%7Fs6w#T4.q6WP%ؙP/".чE颬k YE2eǜ%E]O@־g; OL2[Nn9_ll*IʹOÒlK dV>V'*VG*<Ǵ(ބEk=jB\;}tNJ0XL-ճqSl*>]RUǪTIE^2P>kaLFQ]#/n}O+@OuP&銦rhR=X}8#\ZZ 5髩1O|"|V 8.l0a{\K,-xhn @3ߵ(xlxtwf7%tߌS- g'2@C%yG5v\m)@ |ܩl?_G*L֑>>>(8tH n!2P3s r yZdD3si+a&!JCӭ!b1 ;QPH[ UHnܐ-n>({ yH)Tôrbbb;dʏ$A՟a){ȃOZi Pf `R. D7<גrN䐠e dv:b3R`-W&Y rfee%d& /Z*[/++m%,_& D; ^(xXsSSL 7,}]Z'g,44jW˷}x'N*܀Ֆ<ےx.Dm<5Sp$vm*L仈.|kQ@{,O0nHTIľjc Ft*Nh@Vr9?oF993&jVepv,Ov.'X*2\o߱@TOW ]$D5Orqq64Zӈү?=lTo|f#yڂL(вۼl[BDB}lX#M66$1de"c c0ӆ?d-cct'Tܣ6}ے=9ORp*zŧ[KlboeyQ*ko>O1 e%bt&~^ў9Qau/Q+{(9I鹏sa^Xwc&3gDvn d#a=B/v-f,\tg_1HPT~Z^2:n.w22 uNJS>=̵5OT=+]GXjb8}<E|7s'\b\瞷a,Zlc*z Z6x9# |=K(?+ }1߈r`T# + d!Qs˹ sUt̼2.jDY֍C\@ @ @ @ ù#BJ&e5?35959YG̯_W kolٛAGYV汾<7:7\μ#5^5[ 󽇨 Ǽf01;Ekm|Ј7"ZPqJ.*VJ& gȘNrY>b dd`"Q:y=N/X]gHh/WY:?"l{jF ޭ2,,,V6dgg#/ D6A@7Mr805'ٝSK O:L#t]Z P0tTs\Yj"Na}cyEiYy9%o6!/ D6! G $pA-,Hϵ"Sя W(;KpM? ys_ЋƑͨ[ٳ/m6r=?5ZN#! x_ٍ|HOU)v.S/^缛Lԑ( $e.;! ?\(S1vjwņk%1"?cpH|wS|70?6mW.u)1Ǐã37BdSfH@0rDGC;̄,-/#>=' B JdI5?\ jFq+z3"5> vLͼ,.t~evHYyihJ+YXZ),@^ I$ pC܀ 'ot2 cвz7s| =xKz҇)Yw a/ XN(?쏞Hu(s|`k!OnȦ(SO9*>|%QnNZz>ʧ y(oedr WvKhA6渳pQ3Q|'P d v;I;J_ ȅXWSeJ:Io]Azr)꡵&s~Y>j]6# 1;{qoЃq|{hT]_4tE)t}|_T75&$ I ?R$ FG\ԕ cGqnXGW ,8tJ40qhzy˵ u;fv9q{)9%%3mJ3#t' 7WXRN4>3;yg}s~I$CC% H俎?dӖs־rs8;}dl?>=|D~<AȦ|~a <'YyN8I̱8KHJ{)X9El'GMXK` S+Yr?tL{Hy[QӰtaMð{i)Xy(Os"&gFZLg=tl6&UJ7 sEܽ3 sY0 d, f]K;`&#i\i9 j.rf^j6NrNJvΣ?[jlȷwe׿t RЈpC@8HN8~ش̼nC8reNE``c:w鲱rNU4zXsy\BΨ_"3:2'l@5N2wk7vр5!rnG6]SKjf^SKa2*y0]6$*10sF9-pb3?e/논1Lu#YG}1jmC@]n"b)yTڞ{u-<:pI~H@e~Eo$oS{d8a|?S@l  q}ήs33U E,:3${$jgp*>uV̴h׻+#;EF#e =*1x CG>QkSVBOГ\ SߋYIk$Y&'Y;zWb8]h`8}y++.O{`:pw?6uم-)'Y-AAwA, .6Ǚt* 4nt/l5C`,"00@ʥTZU慳Ǚ} U[z2snTTjW%t'24$~&` J*)OuU/2;<<]P_\N.d ;I ?L n߸O~8rx8}oi9YNc?忎2[LSt[]Y),-l&  !H2$1Tb0LfMѺ֩7 4$%f6l{ =R͛hHOMNNͭFmFю̜@R_cEjjvbrV^m6LUgVb\0(ftyl:%#{Q熻JJVS9Y5{u5eg#{%fLl^̪ơy ,O++HAV59]월WZ1Oǵvtdar^YY-A^4K&$ j0~?8w݂O9F/>LYeMz6M( ?B&$\%c00LʨZauumS2r3r YDV"pBo5k7;zkk=}5os KӲYDV"$\vbZYD^+@ w着*_@gg۷og_4_^^^YYA_ "u,0^ 477OMMe033 @ LoSo5^U8Lbyw'Ym_'~a/TgTu/_Zqo.W!g㚡)ѬGOw _oBVG '|(D/-.oY^Ac~bex7m,mpzw2n+e`K-;bF`N +ac_: []}[@mY &y91-]%c^KG>'W. mo|<%ϾPg=l8}hs{^9Nm|mU5\ _,ѓ/=ݸ܂k.6G߶Svyt7")@QtLo ~zrEio+/K6&wHDn #w^&$M~iw~>7c1cٽUwO먡WA6 YAR!_3]x;wEԘab<~h-+IARw;;'ioW>2hW~5)Bnn/[7{M/\S{Dv5u!0 -ݘ_/TCg)iy0w Ng$&N&?tzV`F{*?\EL/GX!V'޽{{AJ1sguҺ{K:"'DZo̍uK`\CznbRwxzһUM {䓎7Mkj`؛e$AWn\¸*Aw둣{]p=Z}ڭŜopB.[Hz!+@um%oF:p2IOQVJFNEKKY2!󚺪ʹ 0CgUeͬ/j^f" |y53!#q뢬Kzr f18:tu,[EnȽk픈"SM^g2˂]Ԅdnߌ:%xNLFrNf]ᗵ iͧ3r'exUJ6z!m^gUUL, ^ud'e矲dB{fy>n UzMa2YH='*aj!.z7e'6]ƪ*ݼj K?hcfwIOP-+iԏm *S0L֊R5c7M UM=ɈxUb ՚|ROVZJ^s%/ʊz>e{g;wci1*fx3_s>sA2 !RzKCI?pČo/}x8ĎedG /FNDavFƫAg㝴T/?#zBk.T2|sP7fb'sDmKLjYlN.`a=ϥ (van/zk}Oy+\Km }1P?P)WMn'JuyZ,Z[/,W|/eW"!d O*D[f V/K>4iVs3({}yxB$˼sn "+QOf0~/euaӋF3y Gm#qc1K~W8]Fv*gB)RV| !Ӟ|;M+رl|TMߝ\#-ڻeeMmDTOվ42MvPua^WM-\6绘9d 1>M%8DLcj'>"0fdֱ i׸n⥊ԫH`u9}}}Cc=i&aD!@?*‹ 1xi#[U;|lyТAu7퉍:}CSB_h%)~3تj~Li~o&53e B| aW G=b؄UAQ dфRnmŷ&l?XK]YT?,h" S3Ι[oYkBGW},}l=&c92\rWʮmkxNDD- Eȯg#ؼn)[`p& E^egP@_@|X-qP+'|–^8ɚg/oPyJ)d߮v9P+xe, Wz;^2y⩃/.{ִg$"[cTiXzh!u5tIMzs>r?ˏm8YPz ~\sOj7w?쒮̥NmmlHj <1\C&_6p}7tKCaD )sog U-^̭ok*aY+TyW7D|[=T@P)lf}}qKW8y\.quG|}Q-v kX4c31S:Tc4Q'о9sե=S$4Q"IY>rGEE=3z 6/ֱ53o.=iFgv`]"mx#~sIy5Hq목<+Z$*~8Xju"n&lS͑jS ?Vl"%R)@(q%}i}es.o]-RۦVggf|6= g^s H\ lGR7)K;H|C\2[Ƿ,$x2pC!WŌ=]ִtĖs!?Y1^DZH+~3C]" ,pP1|13ݹyV _CNk22O 31>)sz:R1+GkI(^AZte2o?nmlbf)qFy.ZͿia`aec{HA^FB\ʻ }EuϹ$'I+6PJE@))b)bJQD,hTA@D.30LihNr|I{aZ{ϐw+ޏPnz6:ZuΖ5 kwHZ(nr3-}rh%@ZJ1?nܝ(}5brP“Oޯv 7̚ 핣72uv9ii~I1ݹm̍wv>~~nWwܬ)+.rfXCymcPPI>l9:#*8{a.sMw'G"k Jiﵲ9dvf!Bbo,E=1r6a?:q=;uA[Dǵ9pG'GIֆi'qё3NvXEԂ3᧯f,袽ZҾEEα3-x<⫯7v Ҝ=f翯hC f:;;;;Xq'CȓIo!28 104%f@ bdNjJ*cz90q`@/@;e&H ӅB=鎐ײzM:凞jCHDse}gRX'q$ɓ~(*'LPH<D&pDғəeiDL1wϴ+#cn'@BOq7vOxmS zߞ^uq Dá?R* IB5^q{FT`T~ /qE_Zv(3m-鼸սo ~-+Ick W*v[tГ]_`8\q+X0n F Oĵ17,IDt/' nM!~5f_uƺ6{7[~8^5hJ;e]4c;Ki W S񳅡y#iduvʍ{崣9:]V4EcUv*:+(̫lQ> iI wǾݶѶh{.ĥmQ}"I%9՘i*a1W S'},D>uR@onnl4Tn?}9INTc^ 3Su_7'^g$%̣gnH_yXuكwJdps-'-66ݽEB4,;AyD+$Z4j7]'1.jrwȨ^m'|j]f^Wkfj{PEIpH0;ʇbH1-v_kj Ԇ@Euu3wcMÛf;'NҪ;tZ3o#-7iknfggq\AEIУp'["/L:]gF֛f*'줼.CG0T97SmnV7+gX7e4,mյz92"=r:{S9k /$YZI~<1D(xk0)5Qig;}P:XԻܢ^4P6*]Img"ٕUg]L.LgIg6qSo\wMbոkDCP^ 'i& R"ر9^2IT3 O1) }2m) : as}N=_ uoRz`F579aNi(F^vaɬ0߅Jia Hۧ5.?CMR&'Y;a]6>4r.g'- b>5.S4AWߕS>t#}pЕBn$۾}Oi *T KtBY6A"u8ѸYFK_oQ#`];_ѩTwD.󂾘A@ Ҡ@lWz|D(;#DD8~llLi&AUw]}&dc8ǎ?bttRS["Mg6WfeUaWH[0NZN/uHV}5XrI/ zYH^r,RK^قpȕ֛r7N3Sq`c;Ͼ+ ?a_@7{G뢵JI.:ܐ-P5ȴؗlPn"IbŸvfo5D2:)5kT>tlAN~bwXkǫ;5[.>>f g$/~>ڹ ^E\̙ ۼ-8rDW{kp0QU}8׶TmzS l:WM\O2 >Q))uy'_v[M#~ayY)P#  RKгJ&"5eW[Z|719Qk|]`+)Zw<^3yBE6t*{g5z߉ήP ^~j]*bVl|:_J ؽFMle O,7;46=_['z"n:u9v@E}?a1oxXF'2ԏ<3 =<,/swTxm1꤅Is;ᴛmjӌ )>OX}`] G#XS<ЙC9,ƫTve|$x#uE5SWe^=@ex2&)Z'ced$]"SKK*/:@sUx[<{:fkkm=jwߔ}":]<M=l`t/GR,)!a'!g 鉫Le@&4x.?Йhև;ekHH眲BC)I? IssSd_Tg~Y̤vúZa33+Okzuz=:BϷ}e0@89wz3S07rW4 z ѧE4LTf 7e5) JţbW-y2RzsL٫|$Qfɂ,tB-<;榋E C]eg'æu۸VkF3 wH) oQU=B(e;c>ݒF^'ޢiw#T"ꊳ{͖$m^sDꥺ˘_{7>MT2$= UG 5Ng fiuWGrXGͣ2ΏJEȩrn E8kKt߉ȪkG|g@+隻l"1/vEHs\}Kc4NEu-dyosb:*qΐX!(P&-c4tCn-ܮh?(u$sO/+H`FL"ɭId/_RA-I%<ԉN,{5S k42;!@ *޷H-qNr&/ClU0g/uӑh2T0SK{'[g .'36&9*9 5׶ Z[GfUx_QNl[X7D fr+@svzVՂĪg)y3hzS7=Kx2wJEƦĿ(Ni(km./*:91"kDۤj$E\\:ܲ蹪Nh.͉KNʬ"1p]ٕ3l,A%'=I~4ah}Z{n L{S5jMG沜/l(MJ|݂;,!نWE}sˎwV=jsrffn]e q4SqF_"prQci=nGuBao)KO?vA jRr hxb|'? rm-xPI螁!\}U@ @ @_)h4*FeO'!Z;'ȿnhŸhOwwvO24=99'L$2'  x,#K R"-e aSt#S G4\Y+F@5B֡5Ed7'Vx8Nx[fk֊K  No/:kh*))(~󦨤op|mc6&G̭O`f˳ߥH# IĎԢ| db.̯צ-AE/7Zڝ&m" =grQ%?˄0NLnnm/~W&+( + aPZQ3?n`/}^b&ٵ*^QeTBĹ$,(9$(^g$dU*ͭOEʂ]D'd*A<1PRXX7F4zu{f+Y2t{Ww~Q)3ޕ! A :K,  hWLiTyb޿/mF /}5^WP93CoEL67WU56u!yC-UMM-=C~l70,\&o9l38;0L :Zjqs8LOk{4w< &c.q#ʡVWm%"JZ$[=}d|.[#?[+L6]hmV6u"߮ߺJv"F; M[%oU,%=}ܘ|[V231t^aIvAq_?C0ݕic C7Y"jhi(oBznzi`t/bb$U5?mq7XGzuU2'BR_g? :-kK]dqg| !\Sn3} wKmڶKaχ^2!mbSK~)[V;~9[4jB{-A Bzv mUڠNHwd\D;xsb𑻩&)UqeS3'jeL4$%Vkz_/F2iIvŦ7kY'je7(z޸qe`~ieMLlmSJGe2Kl g "vHɭ:wFAauWٿٽwޣdŔ6Ȋ0_{Ž~32.9Z^ὰgW^%)CȮ>LZwf3.*k6};=6"=+MnY ?cwե*mm$0lYI[]P[Z3 [Zga7#~\}Sbz "]ju{Gl-}qL\\k’Jˍ\R:8roH[ޤT]o-rnPw){k[޶J2_RYf5?2kJg/<[YNʿf;}]ufg@Uv'ihw|𳷋ul)&vq^o EغfVA ݺFP ZHɲeOHA;^d(uRh WUݾRns)=KUL85=lfezb.^/d&())x=ar`zVbh$4뜂)"NE,(vw7 ~柯"jz7ۑu" RR;~ʘ BydTNܭ&gG0&ZLt{Hߙ Տ=f]@dp }hr(jG}8Rz7fӑZ1 ]('M0wq]ܥ;k|9뚨ט H>f\xɰGeR _E+6tL } 2@B-RDW|mc6O%fg>;c.Z`9wWgIp?i)tdddU=bO\~W,}Hg%IKq*%imWZ}V{oKX~th=^`w$~`2*)e 0p7{þN(*Y~%3qgsݱ\XaO92H0-a=1:@AVnѭ:f`?ܲ>ܖ}MOV[}Mski`- `d[XR^M&+(#+-htM7/N>+Mt%OLK|rrۦT,r]ەd N'U05AVƫDxC|{^bPC+sX5f:[eٖ⪺u(*5,ݮ)fcl7 ʋj(kA& s_n wg?ݾ}65[_v4ǽή3XBW]),/gPҁ!^kBn聳墚 [lk IĞXiDT^/viև~U`q8nLNUd 꺬V" uvbM{Ua_FaG8v`Rڨ(oj!q뗺vJs_s° e=֊t7PU'XhNK7}RtfMgօZ%_v$caVWK-]'9#J[;^&>VDv:6n?ͬ5ޚS:x3Г&-WD(QvK|%ߚzCOK hyyo d\\ԃ}/.Xue[3iVN>l*!RXn6j[rv0wk4)QFJa醭_O3Ȯ$o֨$37yNj}RdwkDZ#DXIX`bcbc4rXRӳ~꜐wlW+k]|:6FeU^U@$MGr֍s#7ťphS@/+xf8O[l4Ϣ=.{\ .ds\?e.] }Q9Q{ܼ#8Sa/y܎TZΞGgfApe.y\8 Q~sH\i?n\w;b͸{߭WsԃUiAW=}=/݌.iPx/u= TՍ=MF.G.#{مnћszj7A|z᪛O|ļ9ڨszx?9לW;7JXJ z>gۇ }876'B壳={BSp7)2C5i׃|<_|iẘ_YӀ fl"2H}%9ŭ :k`p89(~WQZZY5M`ʫ3s 1_]PC=}qhLGWoumCiEMskNy @ @055^SSS `ddBa|}z<O$I*~"JX'}ll .Eබ6 @ @@@@@ @ @ @@@@ @ @  cݮcIENDB`backintime-1.5.4/doc/maintain/_images/2_weblate_setup_03.png000066400000000000000000000700001477034762000237030ustar00rootroot00000000000000PNG  IHDRsRGBgAMA a pHYsMMgoIDATx@65|ITzKGz;"MPP, ( VTHRE?(hd;3gyY("@@@@O6p oD DxYW^]-pg>LOMLz0:>)#;%10_,!9HSI/?"c$$uvv +_;<؏ 'bhQSQRZNeGFJҢbޏM/.]s[r=kW] QT,RQ_~ryWhMw^In{ !L_qvDXWϝ,jL lR/p 5$eݏ}HAQA;W>HH~b7'h5*/ +7&Sls"=ŭ]d(1sUv!KϤ:w]7oɎbjnz~ȮMaؤ~_}YLW]uM-9$$ߏM,|[G=%6Z[]KEQ>}@\l=mI!G"Cm)p;G_ٚ%3󰉟MiO.{+qewLe⒢#uԀU@]s*=- ]#i?"p7a)g{*$$ ojFNRZ潘ĔCCC=OʨqI)U~K G] ɥ;.t޽>K֜NU&߽rPOSQRor4 ,*ppo:rтmN1#ČSէ9"-"pǽul싋O0Eu-QYok8J.-[{ڛ[z{]vY MZ%gO|;70:>~%keUIiF$b(z\瀨9ԶU?1RLCIig*E݃Te,mV{TQ;JVj;3ڧ =/Aw[`Wy7Мa?*0 :"/3; f:(ޤ>~h E@ZOJ]@V48_  I9-345$$Gnԑw?ayK`W~c \xN=eDu꼱PBKk7<IK%:UIʝ(bN1iŌhۿW!1aYE~y-^؇9EcEz{{Chiy{ˑ(h蓸oP:p?.p?)OJI{HkgW`ճ )+c ݿ֖0ABTkD.;k3^,~_ OL$bGt|R D+*! }~t>?8T?ivsݧ7 8ޭ񓲄tOttt}|AA?9p p p p p p p p p1848*1321_6N;Q4=f+~6")X1uQD['|Cޝ֞.l (vU>qFdoDtP(|b+(|{WmXĊ lpCQEab+(|k/8 80 p p p p`@888888@#դ4/TI,2Yr$.oDt~&/NU={=t";1yUßܲu5e'ޘP%4e?̭eQYYĦF+?8վ+YdׂZӕ\%j̔>fRD盷颺 ēS^Dka7LG7b {ߐ!yRNYċ yӏo&u:C( ^#w1󙿭.xz_2CBYSGGS§ӿ{j |B?2)UPҎkkysW󥙻8R;[qƀO'l"V!aaa0gRho]nsΥ'FzfW;>ͣHu܂r" =^GZf67o8h)n|6{gl}BASY!Q/U6Sħ6CMYMV!*x)$neOrâHOģ1KH(Hܪԉ*hX>oZFBb'oEħŜOM"]ħIb#IYJɐU ŗ/xUHdWOĩ5=.i87~!FbQ^{b>ԿD=\􆹸~ qK2$9?JXI6pج)a~ i/Ρj-{[snܛ1/Q}nU !ܒҲ;W֭C|lmd銍޻۽k+w4]ŧ8:8-s +ˍ4\dgoa֡)p vܷF6gio';Gf;^n..duΐGm }W\N,JMBC_WEnR[>+VF=olH8{Z6Ȑ#C`qOkn+ˡ6.wppް\q3pp  psppptvi/WG /˱ωvI&ԓmV;o Cpbn9D.FsOųbͩ'߲ٖ"*foo:8ጏK/.-88>y\;}Hkl}ϧL<<;vѿ\.'Z&sV9S9ߣeѡ]98p;;Wgr%%,ŗl~WD /j sb$~yn}j59Tkffń5$VES4\!WB4}uG7AX vHGGw#[ϦƋ,h6K6RK,Ueݳ$BuP[w(p-}N2NuO O-"seHdWߛLFF0d1>8"$w:jd(U˹\Wy{6Us2P)71co4RrEwQU|I׹AC~O3ĖH`GV~&->B+Z|:B7/eYˈmsd\T-:@Kjq]ir[>" XXBWyWxJvÄlIUXb{V ?J /c$Mk rߒ<)DSLmP} w2 zK=BWҏc"eŁHj8XAuQH9u.πeɕFn*SڧFʚ8̦mF)ܲN& (OkY}[.EFg&?LNˬbn3ʜ*pttW~ƶtrՙ4>ho y]a/L,8K(>ћ.KV[PN_Q <Kj8/L!͍cqQE'kUYD3ZNq;y?4Kʅ8X&Mjo M3! {{zz⬺LAimvk)5 XIseSkI?ϿYI$YdHe$I8њĦ%we0䴋mbՕ6kr\chUY=V8CUf)k6u'Rj@ t9xM*Wq-Ys7qYeqd*f7-Qv.g,/֌oTgq8\/xɩ{6lj3.v\"b+9x2f?#7<膴s4˪0NS.y޵Opޕȩ]gtoQ*'̕BNBiɑ oJKKԸiDDD>tp`ofNqv>)pԟҒ0-6㠧[mDyњ8ZcRg.MMzJ *:EIRp~飿4ɼŻB?xx=ppp0EMFզŋYTrVT_v⬎*kU_ x7YlݑJ„DTT( jTՔĹghȦ_x:,(*(&&#*dci[p){e7Oq0>l^!;)pxqo~Ę{K'iG:2B7+i[-u;]:9pk4ʨOqpK۪si#vRqi +łoN---%%%eddBCC?K*|[>,LO-|љ؀"#@h!_ٵ3eEu^nAE]˕ |=X| (p>K*quBK cN.w_m{q)Nͣ2iO)2CHAo򣱵vppuyfO1!jL՛&֗B$v]Զwf)O%,V5c4>ZtQH-~1pyQU3&In'mhO}㒖I@k:2H.u[ڳ zp|,p20gH=.,z7+qaq̤Hqn$-pLq?PJPxTI/71`eEiڇsݍEw_x 9yL:Vߣ7g (dg{R1N_C轚ќ9\F~Y7_ͳ P˨cDDq6v򞾥BVgmwTN7.Pt_io-2׏#m)MocebʐG^{WGzwR},ggQIhq%2Kj+sM\"+t0@CRQE~Sqvq(z6j?oﴏ |2'vá󹈮hz8e`ЮKEԚAk}h+"#km2#~=>mXu.I@O- V'l8~/v$̏O4󍁃]^K)]wiQΤƣYR&]O:Z`I{gsPY!m}N<~cOO 1wn^G[GcκvF?HJȼXsњU@vβ-.޻XPCXs3-p< _$̡pQnZgc(J]H )_IJM{V@nV>Q;C":rrܛ,]3$a^QQƝ}B 6NMh9c,)k|z4v'|>&@.^ܴOd+25'Bޏp,ql3wW^{_+F)Woش34* ,]GT[hMq+I^=m(tXtf~qnY'U y ѿ84eT47+U;Wt>{^#eKw O)*͋}~Y+w.hW cKp=t漃:%(j"'$,LTTU7"Zi i/+(&#[spl?xo:;[άU;ꮱu!>[E9Ve hTcIy2;;8Prdžsϳ[ϬYVv]~efq p Z)|l<Js=N 0\Z֓7|ޡ³عxxw]nwkϴ/M޿^%q9_bdU/tewaeE[-qE%>A#ףɍ=%9}2(+1ג_-w`lU.{ qqqkWq75GZAA]eҿˍ8W{~\L?ޖŜce'kNVPK#dBI.NaE N.qK^/3 թke9X98~%dLxcEWFȎ|lb:璟6KR4Oi}tZMPJQQKh͉?yY珷MBHkL+|Vll !oE?ל&c&ll%s&k%tQi"? 5{t12$NX{7ԇR%/\?/hcoʵB in" YKEs}ؼUlidψޒ\{b:҆ߋ/.=Mi$*C⽖\wܸm.z7}/F4$_ }]~-ֺ=;JJ}6V(i5MTCx!f}G{'ut&֦־lilmmlj{ۚZZ;{'֦WV5ԭkcLodbL(``l.i}h7a=km=Vv2a3q>E=&Q]N7w__+7Ύ :ZZ'Q=-DbOןhoGtv i{N?42H-~:OW#xտhEi ~u(~-k/3s*Ci~NPD.;-$^5+ߋ\&uZ~̈́1ٱgScvM(m濠jVth%B3}l4?."f;vQ$޴Zpaf՟BM}+NrH8m! Tr2l]?egDాKq*O?Oߔ@NTR;ag8i I.Ad1sBY!%/܈}%.'Mn'<ƞ ?c@×|O^G +Ϻww96{*mooVq6K]iU-9K>~)#)dCzuj +[#Y} fi"vO3pC@8888880 p p p p`@O>poڃ1bE`O6pl=HUQ{};  >q?)Fz+(|b/R_ io (|b`O9i Wi 0C(vU>Aх'% p p p p p p p p724Lym0530 [B7mE?*pT ;x)g³=egpn Jk*O,$ˌ_fsk]fv[zsp(3gv6{G:No3ע /97FqSrp>'cIN9 /A[>ӹVo۷X[]'9Z۹w=T$wF?(xRsi9ig|l("JzK!FmQ7[uT%d/]VRuVEAny3×v8l Lf޽UWAR<69J_TnwV,YAvKM̝|^H %^-k]ۤ-&d; { |H\{εn||j aF<'f GSՕ$UNac~=w:,;M?~QCP>~a9>_xdһ3tQ!;Bdq]l:Ɛ]̷嵙͛;w|\KMQqs 8?TUp~EUo#a!ck ---MҝKQYE84܏k\,1[*Y=8ss.uw_.$hx8 88d~{#u!E\^AS[GKAўV߀Ǿ}0 #*ޔez JXmvҚ2]88 }Bۧ Njs}*lعLݶ_{X[H` ;h?ڋ/Zpro kmomminimmkih}R:u 22XM֒a-jWsYמJWm8LVڱۥ< 7Ԕ6U?B-%7v}왾m#&,z$nL~9S9遃1]+QoF3 #u"J^3p$X[3=q[ ۅ UEEG_[JQxz!EWom J뺕$18FTV2><^Jo7ЯC_AzAy մ=JDZ =\Rjz+VKJ y/Da{HՒfϠpJ+h/Xfշ!W_Nv <Gn5]=zZ; W͑fz@x?uڗ8D_եX%{1v).nny1A)3Zܝj-䤼l.w:߉Kl{⻫=َse5Zd:t<.|oM>{uFjFbq3p4ryұ'VkmOXvw55 LLu+Lw=ڝkm8<uwuL<@}@wK 1jᾶZ`oaꮯ\Hws%kR6z;ۛZں33B#2 g vrթzω׵v[Ehj혔g:h=76jɣ]v=4WVOo9@q٬9gXU]ҪκWw,]P_DT Ɏfvǂc k^>%p9 uBus~ZwLXRˎ^chdו抄}.sEWOJýuij/8Yh7D fy2[rmT=[ wo:SDItV%;jNeQAa]M2K<\ΩoyߓNjEwEtw7dg<|!U'S=g=.Te=ݩ=zeu`sO.p첐/W>'-//vqUns\G5#CIdD2YhXqyAQ򲓴LIw˝TG6~csK0o1 #xEtn#Pܪw4V8=1v\*s ͼ1Nml,sSLEvsQWY=ka3-vFƉ ;-l.=?C9eQ#CD-w0+<9-,`DK#%'c ɬKb jbqcc^{o%u[|9>HYEf-sY72[;L(. ['ieK;mJ0ZumJ럿xZ󘀥lIKIIf&/,ҥb{O+pTYj~:㌺\B=)Zc5t]1ܮX=îLoJH3,Eoy|ӄ;xDmY m'ҙMvg|hv^z`i h[_PjؘgVz[n:ߝeEU1*B&I-MTCk&'nBI} n聪UĀ>\DOy4lڒc/*)v'|#CKpgڤ ם--mJ9R2 P@L %ʶJ渑w>`޼cVd g>Ku1]+m{v|&vXgӚ'JOR^;6?i;^*j}e1*sLM&N?Fu?i %6wPJdv<>ӌ) x'#f꫋CYp"M$VDO8z#z\oExT__ +6 #\sӣ6z]}Tgt<{>Oeր5]yZ\DWMU̩%OuĬa/~lfNimVv)nnYgkզST՝O$<-˩h}|?XWC\&wU^V{ԅ[l%EeI)aqgO+&U%Ǵ/OWqK8*_iՠh^gQ"#VeSYڕ[ν]^DU8V݌>kk,/=N|nb'ߗ̺euW+ ^\)yaOj35t=K{̱1脗ՒH8sц[NJv_L1냅.ZiD擡:\1뜭)fB>:ͭVNB2zr"]ma'kt y?bպ(YFrR'zgř[̱1ѝt6uWnf D d+{ԐS:gi ;*̈*jȞ ˺~5^?k3IgQ{Xg~N0`xò6׺y r# [ U;kJHqp)s*s*a=Ğ%#Jkkr pOdt*> 8Z[[cYsF)<"?8z8YyS&S Lp)8c먖W 9@}UcH$rR#dt5Wӳ:XGtfPMEGs豬"47jC!"`9w@sY#nF>{9zxfWLP!x?* Ztmm7a(hyWڞK{M/O,mdB RſMǕドO8M(ibXb:_rvۛgyR9KF;Kш="ρC{7Yz NS9ylJ3J֫<ؙ7aG@m WrIzt"YlkF ߯]hh6H ?6LG\fSNv^j OQm jCMݴjٷRkj"O1jB"ts^Izcg^*+ѻ% )9%;GG%ckHwNN~WpGdbS.z_ݣwvP7%w`;oδeixe3=嗢?^+]$ZWL0"ήѾR@OXy3g,bWK*m{J^흅n~)}?-,~_TD齿md-#2gJ ۿݵ{D=3E`~GؤAXjPEo;2E!Ej2_%7!\~hJ]5s!$S!H$ }D\"k1x2*uЄxy#59+tҴT>Mj-T P4CK54*R6gXo(?R64%R~Q%YQ~ W"?Gp0zC3HEXkNDՠR[.0gHjX*R'!3A//A) ZcB-loDt7إ7ds&HjA/D|6pyȆ)ѦF#t4'Z 0+%Mi<)Tp4ת]-rHۃc w ]bmO sɏ붶'KiR["ݷ)jJƺǗ&]Sp\R)>Z} ߴͻ/7).+ *X87US$y..:VW_wɬPBO*Wmؒ?%<KH[J6l4\F)<[ԥ%epwUPtR6oeuu +KLC敮\>gwWo)Pz3skj+7^AB4Pa1,sCYS<<R֟iW`Z"Os jkn?R0Bs1DƂS#I19;+7^5o^9[i2rµ;#Nw 6-.:_q֬06FBٱ#e8Szĸ`e(֐t#&,Z`/ lWeݵƪ_wMf*QU~.qVZwܜg7%"u*k^=c(o?Ğ"v@O;t+~?;;FMDp[Lu9Esr}m'dT{v]$ʑ*21I8(SONpPkx[ w#TᓧTP[w<7'Ƀ!D$`gUz_N޸x0ŝSYs[%cÚ%,9ѽ*^f<~o'vn?o8:oaիɫ%+z7NvIqy ,׸+/~e"byW8iѳwZ@:]tVۍ=3 %zϵ7]:c+QyZmۭS[05‹MB5Okݮ{ryZ=f١]ܸenHjOm=FvڞץZO-q$rmt7wuyڪw,(",ki^\G0>t鵑G-5~"FeѸ?RJK&x68)8r@zpP%}>V, mں4T2WL緇W?ivPD*ܝÌi7XPkS#vFN8DYP; ˽a5o{ۈh=v.Ǘ8ЄjXXZol<:j.꟱mj8$eѬɲQ H`ŇW%0_'hV$u w3|4|.TDhX1vبyOnppfЅƂӵV!WzrywSƦ/;뜟:Y˽|#Vڈtׅ3'4['8" [5Z]9akEywOvZ4"+}Ҥ g`1 7>d/"M(U[k$,9&^Db%n!5yp^bʒ7:TWŝF<9vvd9d/ LX|v'Xs{u!),jMc%ʃKX[X=EUógMM>]|H,vo6D +·L2?"EO:6z:z=ߚ#9HUݬp3Y{Z%dn?/-L[q[k; _[W8:j͘!Ԑ%>4;7}EPFgN3f?u$N/Xa3 ,e.Z\xXD~XP& 0tt ş ^KSSȍU40\IFI/62'@nN $p>eqd~{Z<-˵LUlk"?IaZ%i_%&,SC^.l$jKbB}5WX߂yQ[3e)(N1Ț? n-ltL)]jΔO|K+Yx\UBjTu|$`B!7ܢO"5$^G$@˕;X1Sv#.? a %Yy?9͌!3/چeּw Ԛ#Tw/Sh]qVLѠb0St!/M ֜. ;)CH?m 7dBj4xC]yN/p,3ޚ*{ mekf LU9{PmqTn¡7 7sE+QRZߘ2L?<>jk"kЃ!Cs,[)9J࠲?l1KqiR%c-إt_'D[rDKxQ]i =>s|Ĺ kΟ;-Ktj9 Ag^>}14_NTRkmeJ_QPʹrK JuiB3a7˫#JI~ܱwl}2F͔h,^ p(ӌuy4A(V͒+;U(UzKQ՟¶"'a~-}%&D$m~PjeghbrlL[LXJ i/XπNj)S54< N(_nttMPӷDZ[s=6Y[0$[Rq}v_;bŚ .pS$ :gwSP2eG-3Xr x tճj1P=Qp!p{jy\n[K󫷭m-Mϋ'6"|Z_s;h[5TSd.[INWI⸶;iWmm:Mۺ[@̝WvwI,X5;uXl%l?]p_knD7 !Xc8N~ՑSpQ1j qL\ظ1c'U2߸ݘj6BB^u^T\(DpW7TOϐ98Et[7zgNxzV>Qpb%C|}3%V/}rt9,WWf :#zy z;#˱֠#"ܯ?0!QzU9_٨)b5A~+s0ѸZ'w\ 4OyA?~eàlG8 l #vܾ|hCKB2-O& NE'GGkG%ԼӢ'8W(8\O^)$^6꽘l+_jóp|:s+-OލMtck8_YNn\-, N]hoA،-1[)y”G#qFNُN<<_ɧ&!)[V(1u"V u6_M"5% G_ ke;,8LYjBE!ScWA9﹆qAC,YgGUJkn?u/Ł؜wufM_r1;Idn#Ebxw]ŇQs- "OA), |O SL>[[35x9rYGdVtڍUΞYvfyȢEmٹK壂ݥ"ut/ۆ3S`6r]ެ/=!cM5/%l:we Kyښ;YreU \_8~߱'Ս%hS-1TynQ)xpcA"2#8\:$CçŎg=Вep荂jƃQyRM<~C7]eEX^I w!1B9uj镗F)yg'c}lVVC)"-KʹwN\x[QYy IX:6>-3>1EMb5xt CW)|$'.-.߾e{Y>ޞZ'(|f.ݳ|CZ:weqau t NhM,Ӹܒm; Teħ Fna/.(/چ4lDWΒh)*_<O2}̨@[{_ x7KLR)b-GelGᶊu˲T p JX"5}q"j\7.%KhviO~pJ\URX+o͜Çr^*(pMXbGQia^n6ۂ"Hdqg-^[|'qsug5nekаS㓧@mN3aue; 7ti~6_7CO@oHh陳́ k[*"OYWhs(iHEnGNE~FZG==>/ͳ#$![aN"yMZhߣH6tl:SТ\|- * =hWyOѶþq¯H(3~ q(ts^Qy?F"!>{0R]G OL#vDazEhʁq̰vǒgJxoasPf ՛ ;GH``=q=1{9!Lf#tsjtzX5=](s06qz\Zl_,Xvliin^-8>|q TP _OmDD9Uhz00Z(k|j)&iZ7t6Gob'UN OC@pz7höd```ޝ)@`yF{at,0^PW.}Up l۹W$9zQjH6*Qf )SK6 F`۳|z4N)_IU``djM6CwhC_1n"_ji# ώjPEǞ!yF; N$MsN-Xv$*Pd```׍&ҐJ+̂it66>d۷o\p\ְg/9KWt44"oF(O)3o߽us3_G_7?=#00Gg_45nmmn @p 8@p 8@p}X☱8IENDB`backintime-1.5.4/doc/maintain/_images/2_weblate_setup_04.png000066400000000000000000002751631477034762000237250ustar00rootroot00000000000000PNG  IHDR,3sRGBgAMA a pHYsMMgzIDATxX\I{<3;L2  @#݂  .ݽscwd~yOSUoUuUA*1@|b|9]][ohi;::U {흞Ҫ²vHAm>xpxkdlw`h{{)B1^]_mt:J+k˫{;; eeUucG;F}Lbpouqat^aSkg~qN!хH{ϯY\Zk*(,_p&Ckx'G$,?I=lzLѺE'MG' ˪ >WnwoQYttt^ϔ^>>n8_YUc#͞Ҝwnt7b?ޜJ0_^r2Q]\5rSLtUfvl}y坳E:^قZ(++źۓ5egM-B^m.()i޸|wa~aىӝե)NVjK.^}RS[پxvvki .Hyq~"'JH) LG;[:I'=PJCO_]?VwFyZy{{[IXhZR=񍩲GX! +5TB&fq`nxfnma)$ý|5$}Cku -y[ۧӆaH.|'ᐮxIHԱks{z[i.똲$ʷlC&VZ_!M)EHQ># fȔi&6h5`TtiXʃ(*oߏ Iwȩ[) ,s;FIB;JzUaщڃg@NyDU`͕GmQNbUcv3Ht3 -ņKo;gf^o-\WiCp 1KckA-64Cb\d(Jbtlsw X I"ѩL $lw{}sw; jvʋm603946<~vd|$^48K`ul(åxܛȥb )|LHtio:U4Fp),?y؇}_Yq*f ;1*B|t|?TXVU]߼VRPZYYXZQ31쥪f*: 1S k۠#sB5fhYzED*Svj:.QOq6 M]ʺFoΗm1' "^5*Vn'vK0ac%ʶ@+wbX;jl5Y )Q{Pqts7_Ļ']9U{w1 U켪zP3 +”T>r XGVܲ,N7J+k/1G5 } CtQy`[AOq^w/_,G)Ԟ7,ƛq|Z9y\R zj,ƩάT}2wv3A3KX7~,LPg]!BGb%ڮ<ÂWxHԀ~b|>M\ 1..~[Pڹ Ϣ.,Ub 6T.-*f-k*?VY\^26z,.CYTJn(}!#15Bgk.%ɝŽ왻qg%Q56FoH%Ktw4Xc+^ZVY+G7HN.{ɰx7/ryQh*xm3I+8KpSg>ιcS23`z>ؽ5(y&t#nU;NB!d t^ziEmgw8km4LUM?SfJCJ@L)dvǝt+ݘ 7d2#Yn?b&Ոouu<݌CPMBX'Vvjx9[אq3 Xn {L\+ݍr3G,<{MxXֵ?cm؀_5kĞ* >6H D2|SlPC|:I[gLwQ3,=p!n] GL4by׽6L{? /L!/Ub@ߑo6z6~y0foohd ]䅥GkƱc#_/}96 `xttbmaY}S#/r཈1(-)+.bBRSCgAOc|<8>UQӐ_\^RQG3cG1UʚӼ41Ʊqtx_M11 1 cb cd1^\Yp|`"qxR 4 j5p|h7TEgszz z<|b\ы1Ǘ\x  4Wcgl)D< =7c+J@xb  b @@181c1c1~}=_~h'J~11  7? U?2X\!+9%fQWz߬]׶Oq|q@cCuK!xuy{`se~yw/?6vO~4z=?X_U1ŅߐCJ̢WUVR\Z5\wQU=M!_ =tWr:JPZ+"4"/|2#{1]oYc=VbJF]ٿb<=OOyv7!aݸB6N^벵vyg~|b_c#fj̅ F~Ucg+'69c-H->(˗0PG: {[tw{_}BwO~nd0%ii\jpsirfGCu3UoiJ{r9;9 (\=7$Ĭ.g#sxxp Rŀ(]Hџ"@G8 B>'8>Gg!t ~}3/2{O9pg}thb6\-_`=/p| }JB'I҄)׼汭/̿$JʉMR\WYr~FWg?'b=*9tgC8>_};JZ iwY9A@fp 1|o>~b<c{N 泹_6G:j!CBASxI}Q̩1*Dg %( &G5Pܿϵ~߳9MlӳoH[BD98(ɨ96d5XdDD;{VFh$_;#$7Q|,4dHQVhMVw%U,C*1#+Q)o?'4| ^ٿ11FAҬ}aG"j"OHIЎC^AړYqPR[CTNpIОJ^MGAߗsPQ2$gX~%'m&"9ğ;0q\EK[[[^Q˥&jd4Ss? HAiYyHi={b"*t8Ĥ!bj-ovsB(k vJULլ<\!%񺘥tk22Os}A9Gi }U-ܸ?68XOFOdTjrGZWBJ[4̽G `18ޏ/yHo8prX#StwyeuəqS֝ pGMUy]ES3__SQY8~I*G03 Ep-É7ybaO6fơhynNsx̑?ۇߞw>YZZRܵ mF!PۚmmǖdwnIv`~f$X[0}=XYY=#[ֺwhʽwbq4a#uK޽s2? 9rxoi]`~:UWZVZ3q^qַΛ{}ij|*RKeMl++kjpcql w\SyyYC(n:R2&>Y@U8>wUَ֝򲚦ퟜߘjiM`V\*kG.idkmUU]*\͙u%'[c0v|r`{ '[*+k.F]PGϺ4\K]uPU =`o% :{|~aak}x oRܞ4~jӤ#/W/qaVqwFb,\jzfצƗvꨭn\=M4WTϝU+t֗V5od 2(s[?M%RGcEEu},),@z8V؂,{uյ b 0LMleu}'Jk;MuU1;'%!kJ_i9q s84@c>"ݴs3?fH0UӋqg_ ! ^xqûLsP+(#PoFj>~yrybu ykF#и0B魢Pvٜh:Z\hmmcW)e;/?nVe3(3gxߒ3<8 fc3qԽn%xן~#bxSQM}E16f Z .qS';'6WaY6"4dtbOn\:;)34Ҡ݈)gfezj}ٮz,f$)0^%ǁBsR *[\)X7HCO>u ӑ'P}J7f qr!EM޴lCӑ"Q(Fzh9Jb{o:E AT}Q83nZF.֦ BT$\ѕ8ͩPx(_9R102!iV1=z".b{('+';+W4ds GIgMQlaj(z虣 ,fUU,CMĹYiD=a[ז #!& wbA cNX I gMqG-zqcxu}JT/t"`vl\1'>2䭦خBO`/;f-Ƨa퀇~5QWߍTB0(``/apW-ܦaIZ.2vvCֺSń>gvHF 5nq2;B*=1O1T7#v˛ !:+xQNy$e]/re; ZO^N1f"v'ɽxknfJk]䦔m,F,Vݢu_ofNmMO*J&ztg{W?wLoIPQeݛ;ۉ&dRVѿC RWm9qrs(۳N(}#TJ9 ;+c:PJf$pZ;zb|5|dAOLR1zБ9t؟(qhⶌ_N_3{ pMN9nɹDX3y ^,)_OVeCK>9:=R.Y |ҫ[YpW ZBV[s=A|a(|i< J1YpEA&w/-@ϰ )EQ`8O"e|~he/Jͭojf],yP*PduuP)fLCm2ϗ6Gjm %i x1Czbja[.*V\?t]:uxs:cd:^dAׂ1KGٿ8'Ryb(@ vWك2jpmp =$Whh.,5TŹIRRKfzR@GGWpz(#,cgs?Ov5h SjanFӘg*jPv{^'bZC&q]0 EE9fOBϷ*D$[ڷѻr*68YlBu휋)fT7nhphY%]%FȫY܃ux#UHs(ƹp=MyreR-t~9^>\X^#`M 'CGG0NCM%U=9804ls2 UN ͕")Y| #7jBC(ۅK}*N$ L״qx]9Oą~jBO+g6>[/%Ͽ=W鍢R0w[^G=g7fC64D'o<.oV9ptKZw,֌U)Uo1*z=:Flw7dB~_8,':j bBx{ 1X^@y0Q%&]x妯w|ohP!k(46M#*hm[Ni6qbxNʉ+bOS|񀕩 FAy%LTrnyjOn3C`y~("q؜t93, 2iX1K(xr 1!x0ab2Z>1zM\N{'${hE\~khPIsBԌ)T@* r~,S^臂YĘ|;h4IR> 5Ӽ]hj=[씽|̋dFF_^іyfif®1!4A-G~6[n,5p|_0fx_d#P_+b =Rqd~v!X[5}c%!>^-`e2we'VޮUd Sde}j4O61,=t85EGO~kfk`dV|a3KniO3 $ǘݡ4[Ln /ĨnbTܼ,6Xq[.1L*"Ƴy":rYg2P,:زy(,RETNM\<~y3//a6>d0+/$'JQu!S2)Ë1Qɻ\g>;wc *Xsu %ln]3H83;ݺdFo*!1sǞ|iьP3A|d|o&/E^f$(uuj k^ &*Q Jكn ;ellH'1'K l)p1\4"6 Dr9.,B'gӵ[Y3^TA 㟑Iب GDŽɨ ~G"YBؠ&HxU `NJ0RD$f9xǤ<Wb< lBK)R^=om?'́za F ]b$9 -Y3Z[wߡB)Ty哟cxH#S4{ȏ_C5;\@KDv|x B,ەg!Ƙ ӇDR@tȆTŷM#p,F' ;nJ؊}Z55nN!%O.EG4 f;^FSЀj$ {?nbX #_nk$("~zK|9-dWjPf%@&>yK$C]2sW:`zN7QX1niUgAS~FR!1x=6nJ,6G4f3ѲסtId#׋FθN<,! ۵-@Vӝ W(s GBA#8vM*p wHp^y=&d</C)ct^JLӴcN@kjD",B m O}֏-^b>7y ~Mq=,]XëEAb,d[KRΏ9WטߣT 6km/^ v#L)h'+\ݭffa'6.K5>OqpvGZcaOUQ+(CbL^yOSkw4ӏ=u)msӮJ o- Nn]5`F0+a篯3 T[R o yY~>XL^£~Fc('P}C۱T'Ѱk"~&=ZuLKQbnoY9VDYkM+}B q5k`>_;nX#V":GOԽ0!K._M#OXf,zFWnON(ZWxWqkrfyϪsGI5sᱳGIIhşZP5*7am~4]A pLPѥ|[; ]ͨnkclaQw:h#k4SiLי R 5`}48u|&r#)_qC=a@gLDĮ_׍p-fQsOJ{[kRvK`j+G'õAMqm%l.bZmءy4gدK2Xwb\K~33ˋbbFCH,,H6EdH.W_<7-:B +NSRv(e!6zxs8/u*N|3EhrCvM1#_Wqz|q ?1: ~NrvW6!uR./"q=UR/ n0]!fCܠE|xc}_C O dqA$HR{pqנ?"C\z(Iʇ) tM+$@ܠQ\Td۬_¿C}Bh#6SjL #9U鄤7؟NʔB|@ ?p` N0w?<.Tbb_"JX@ g@Gcg^gW9=x(/~91g+䟃3"pMI^3\yW?%#~e]LʅK$ _E iU_(7dU@"1c1cb  b  @@1818?Sbo"&=>H1~$1!+PAO @t@ +=6A1Ɨ̈;p(llCƦx:Vs[Y>l1 cb c@b 1@11 1 *Q_?U+UozOaN fy.YU3c̺hll R!OfsRobD)$n;nwmO1FuϬ|`u?[:w\ys&}Geɭs-#nuwm$lwÙ̲ X0^hrI]M^RcP?;-2ĥ;HۄNx?x{y%Mwo~;񈣆D֏TR@%/wk ӲZdMNߦJ5ᖏ]?^W7}Yh@] %8i . 1|6f3#(~T%zxyu]#9&-"qswuԗZ=}{|K3w7Uk?ePjR<:4ŻR76V5NU򳠄%lvDE =sG@ yf H\9Ɵ[CK3-YNp{ sC⣸ڂxb.IE=~AZ5cy6\5Y(}5}0p 5i^X=ےGKǘĜ =ZϚ{m˵ pUev_ ASJL1sL+,]$;܎˝zm난5VU:jg{Л%>_=:kL(Y̗9D ţ6F(:O~՞7-?.u{xG4m f%+0 G}S;u9y瓕{B5UP]5toaN}޶ߦ,_㽙~^Iz4WYUí)3 V&VtC}qwL_YNU~ \|N96B=^`ODHA0Y kpol:큎=xpN]u'B{0TPևM'K}`<iGI=+([}^,dxVZ2O6$gVo7O-Ot5wwJ4AQV겊yP':*k9$6ς{6(WM"jd!V< zL/ bNIW֎:y=e1Nx)8RC2vj.OPNx8UX)jĤ;4co_v#uNǙ@侳ht  SfQ'57y '+rJu A`;Fvb5WS3 MHK2s- Ͼջͮa#`e-N"Hu}r C37W^SjĿ Uo \K+[;Q}Pg6`7=Z.:9'ր bNqvzqƣUQy;V$ ęj?> ^bw=VV9_W3e|%+J<k|tTTL|#TI9 qc#S]!>-PC4BjğX9EiS%5W`Q}&K>c$-@˯jd JwJZKve}u.}#^UB+MV6u2Tw q*ՐxhiƤrw{ [;c!k%dXԕQe#/ EK?cbr`y1 rX'+C6xԻISEZ0f]OGG==D >\'zG橣wz4|Qsa!|,go)c3bZHiXjګn)Kg2fgt4#T/ 2rRª&$M]Lӆ!4g(+a᝜"#Qy n1lU#؝5f zπ4) ~0 IEZhxvNi@ĸ62v>2%|B3%ŠaˎZm՞\^*PgILJ+ƭGmgBTBnh3NE4wA,:m8h}ʽ',pU Ļ[Y>lHgd]If_8؀AS/%4{ Rtt=7k!l<>pؓilٻ}ińn,bw83"9PIL[KP&Mt̉tQIreI"*|ݜ}xqkbA!6rh㬡 7-K3ەrq!u)'nKEnJg䍱ƊYȶ0uƕL~Z|]sï g& aS~[гVM*~^xa?+9=7>Q0i3P{XizT^9)3o^:,V´:HrΤ#ʂo=̲g<͸ױ:H#p^b\cq '[e8# =ϑZ506-e|jtd!+ ԼIx$z ƒhMqav?5R`rF䷮|#¬/E8/EZx i$粿ɳpGn(BU5rHxGb$b\NDEK!zlrj»OOc^'fD>=04MKQT/4MRl'6x%,! cV8MSvT #E8!Vq@U!f\wL`;ުdRx;.7|KڗU( _|vs+mdZڞMS7i.t̙0(9_T7OD+񳓫w 23_JKyk)GV>zøl7K]F>&:Afq/FC/LZa3(c롬vRNʈIHK|A)h^taiw֨z rl|X;&%6>%.5VC9g zw<驄g|~6.I3Rlǜh|//Td@c;%LZD.%-Wo^4b$LB㳋Z_q?z1ިWxurkH G.Gz/rʫbUf~ gK^4] UB!1K5X.厘xX{OM}Ҁ1n4,6ϭ/&$Wk8cR|WrFESVjfAK' <$Ór:PI?/Ƌ K"ĉlX~xjQq+l /v6c.ӵ+;w]݈.$[!@pHS!z"/!mC$_žtQW3u+ғhu{g؟fB=jcկdMJ0nf+ 2~ӗzTڌ7J,QĩmvOu 3v馱,|sk3>mٽZia]+ٻHХC7{ӭOqnzQKb\oesw9QqڦzN>(l&8ݿ#C qfauopX*,8rH*#|5|ֆYiSj4Ig'2&X>g1 Ϫ0f;?MuUVIYh՟1f:=PvΤ]?ԏg94إ"k)ӧ\zLգBR9 c ƕng&=|I3iUkǻ^hl{|_L9\t⷇!8j #anBɶB^ss^ ^o:"XQ/mvc˙ ==:J!Ċ7 d1kq L1x*"un[wYLqq- r,[/<M'bxu 'im-?B~06|0Y?%;Esa 9WlF*@#Aw(YxoLg(pH}WG0x%\1%L AaJϏAQ&U͓: ]V"TT/iS5D-ӿ唫 Փyk8 aoWs?wco#T֊1Spb\ D?-4$yDָ~qX{8i=of^tlکA !h3RnYfz:0b|=zT4s͹Ku jbM>VKjsG_I ~aLtG^?~Q%25DDV yq0FuZ_JJq`zJ*FXC_Rf# a.1:c;L~g{)nN٤tdtN*υ_N;W/fe5 5)9[ng_{EYfk'M_w O47G>y(~5Rzm%\v$ㄛHTXֿvUϻ$5*lI/4ܭV9ڑKmbΌ}2IkF#yvO_qOnSaqK5q&C[ .1JlX&T[ݽ e%oJd+hk:h&}I3m#ѳدڈ7q^Q2J;R"vPO(ëGK|֠4N_XlMqٴx̭YGp ^.Ok:!v$idًs!ō}C+"EK.I}y|qy^ȗ®^ȲQ;o:V?>F]3Sf%/kz;+)$WxF/(z2|݀Ƹv眛4^{ɓzY ־@m*Nї*kwv_l?}7uph؍FOG'59/ʎ%mÝR׮+>Kp dspGT[SjEkWPq 9tM:zgޯd|jLj/p!.7} ^9R#N&_(}E cHlI~tOO\NC\2XkSh`=qY QdyhPi&e,?@^^Egd4D*U:-Jɪ Y-HxZt0y1PI+L}]YMI~yKzǦ87{-̥or{mb '0`jI[~o}E#~-~YOP&[",d5EhsYKuȇl * 7zX3.{S%UTB;y\SM aY-A-\+gTnuzީl Wkmd7#)Y ̫\c Ɠ*=O =~6D-X0֐4r)Y(>rj" /xLwG׌3tg`xڄ/bFqso{4r h/bjkWΧT,7~RzSczЖ1bu㡞{R5l"7hstl/*= 37|CmD yDM I(;gtk]Qб .n#שrXfpwC"Ɓ3zx,{Dֲ>:bD?< =zn 5d*a`e$H>n]]X⯩-"jDGixiμ 0_ayGQ(&˂)yy:2|Ⅺ=`+=HC~'sF6S? vg&w~L,]\:mu혦)c J1H ?UUuQ-WKٿ~ˣelb14-vʩvpo߸7?̴֒ʑ_pwȭY#a 01c@ a 01c@ a a@cCDFʇ+m]?kh/.+()ohjA 0~_ hOwնVr>>ǞP(Ĕ̴7Ŀ̜vwSMhG;r&eqr ib [mJ~0.#ehuq8+)<-, 2-gf5Nvg&d .p0394>sk1;B)HKȨg)nFGW}&3reo-NH]:,Mtgo=pٍ9NefMR- 13Ud%F/3/N2r*E, O*"~8&61vKIʨf76&gUOLML V&gin 0f1|'DO;dKW_mOp{K>lմt޼Ήs28s[_'Cphуw>b9/e=tĄvou[.((ٹכ^rw}_n?9!iK!z<~ZĊl ^mjC:pnˡ acM?y^LE}WT>[c${ޏ7TuElC7ٛ8m~|ohHԵ6Zl >omiյ+dm}S}S+yѱTZQM 0fF_3z=||8m'w$ma37}nn;c'eOI 1bFۏn9Ӈ~U k/DO劼srOsmtQ1G=].i֥aS:l~ 2S+q7Jv{AYvGb_8iL$nqF^]acoj'[m~tY 짚_m;UK櫷޶D^( yP5˶-& ՚5Jbhd45+gc꜔i;*l\nCKu_-V$l؁kG^aI\K=?>]%:zCGōiA'ݶ%)oZs"|*fվ@O{e[_=Mˉ  [n{T |wD6l 7S/4-ޘarzvEU=,P(S`&,/WQa̰o_g@|ΧLG~~*u cN&G/6uu_I 3rxǟrL'~팴q=m;B)PSd_U%o muPĩ`} I+ߑVxMD>)UEz69qSƵn[ 0>'AvT)ϯVLam|[0/yǣu1תcgb!W%/qd~UiqiuZVe52^^Y).˜Ό78:^}/خ!xͯR""Hm>u$ϭϾ:!DoubGW^4%?+='8_sɡ5S<羽g\R|~lm伛?F2~ Ok0η:˽dcsݓrz:n߱*"G(ud;O+i%KG\.XjMN 9Ӯ *uKt:.Ҳ*G?~s񪲟}Uj~;[>uׁ\|}VP@M[I$u-,,Ø(˪ja<95[PZ^a5q~K&)O\9vMc!볜dDIR^qӨV@,pͭP:JT#w|*,wqk^p]u-NU{fUF!MrO\>$ge8)V3NN!;!\3Π?6y^K7ftvH7oP~PIa!WJ _Tx^Gu *]:Bȳ|[Ɵ5\/]rb9ф&YaVQ]WUK>ݽJoLL 04zv_]]{6553:6A/Q7=k N?U Q_ZZ$ ⤔7Eċ򪺬¤꺆6J_UCUczS(’ԌA jb1 0@a c1<}0nll㩩%G0&Rh5a\VV0@a c?ek ;c7Ǚ=uy[;8c2K_$d;:RjⱕC kzg= ]j?&$$?'/3^_>}U5Ѯ-ËlD↾{*sio K쥸dmߔdeVvN;QxO:w]gv%x{>O|+MJ<<ófW ڂy2A^jeJ]LxB~`dW^'ы ī:399oq[o,sg8^ ~<)ved+xAǶfV"GzY= VmSMaqK({R;q?Wn}l{19^g!MEo &@Vv>DO={gaܞ(+θ@B({q_)ި:1O}eJ-~ca+7Y=˜Z¿\hEw)^w2(QSLe"-Qظ( Qe)c|oX0AGL̉b3]=ȴp#>bcGQqCo cm/ny> .匂㶒{c ^]\|H[ q~8"sX0VKLb"|D2}g "Msԙb'EUU-5:plyה|k[kJ3CTo؅7'R y+:겞߹OfT4Ap@OMrTly*≍g6:^^+kNE"nQsdtt+{ZQ5eW4+B[ұE.7etGVP.r>^ly`_eI'cJg#{j4sd=yG<?0666n#%e6x70f#L;^WѦ9T2i\S.a,p-'ztk=Kc<֑N)A̯75x=zpY ~a c1 0@R0ǖ1gvvv~=C~c@ a 0<kkjW~@W$x?ob?vBHɣYlzw߶|e"վq+ٙs?d#cn|Z ~ׅULk#C#K! %i5p^&դეx~ %!gWg7^d_GFΉ&b$P;SRjz&}ƇNLiX#FRY/z ҫp48eι׮wD>uH!rna(RͲJꤦpU c,XG.ezKq_mmP鎖S8ѯD1Ɯ˽%Y"w, ~)ߒaPckkCaI AZ.EYy=qv׺ͣflDꢨiB'== LUua1">eq::d)gF*t􅖤u툿2VGxfl}d䘗^P2ƐC >\ǫ"!,K2vO]IbөJ7,؝no_$g_h$8D[lWB␥!NEꔧy2r5gnW.&&*MDe;ȬȧPceJvS*6Mg^}RfωVjnF  82|t[Y;-W:RoOr5Qؿ`K'i^v~3[ٮG.emk9砫ߏǐMJ}[wk/[;}:wawH{UC*4[pv a 01c@ a 01c@ a 01B^;fۚk ͝S+dXws[s[GK[gK. v46׍,}%Yiϊ55juuubrj`hx`pxl|biy{>0.>}Yk=fb%K%4+u7yO)-g`1EX$K;OU)HHLHH+)7 i'y=#_\":0NpUWO?զ}]q$F[x)z}%Y.xrЗ6=326&?)-ͭ٩]}q{O)Y608>#8CN lT*\GjD'ʃ.?l *u~-Tt{S"3{Ny*z{ohݗ.9yM'b}+˫99ųIJQ۫j*e_\36>]?0ޣ0@*Ж0.޻w%y=k~Ul6x.L?oWM!k[]w=m$&磻ü&N&9m,X>іΔ!zg[gWcs zjj:=;>0Vl\ǘ<$W6z쌸{v˾X%o >tG?k*f35-c-7K= $S{w" O\}rW'uy% %xf|brB>hZUSGqThWS޺>ڦK{?z~#vEߧcL+D^e ZkO۹ϳ]ίHdrhidU;kK+ȩS(-ө|aܥi:]6͵fDr"ힱ^Q޻pOiγ__Zk0߿M #Sslˏ&T[jl7Qv;jF5Sqae0︪):8W]tz>";=ںo~վlVHIQ9Ik˧B]C#o}5-+o-&2Ka<3;[X^Y]dm#VٌH;_'Zi[r>hQBs{?_a//N<]@"mOxǯ~ AGV "63Vӣݣs۴ΎY"V'Ɔ{{}o}hno= W&kkZǶ)}5-`o41ͅSó+=(Kj.M  .  N-n@<71 s|E ..x>畛m4/L-l}:鹛rO]F>:-硶=>Z.Ϧ?z묥,mTPb)ci+MvfF&4b0"$;7aBv0\x ւG*}dfM9o|5͒ҽM =:̎7irT4qN)m|E+]װ +m7Ұ xS75Pc&LfzSZhYtEr1"4o[&NM?ESZ-DWY0Wgt4YidK[=eZGCM8YLZV'o(>B_c=l4.pWel.@&zŌ}Q*RzU3s\q^>#ĞXAt;1 ;s9 n]UIkyZǚ/hmӫ~wfB5nKXB?cmES\V[9] ?0^}ge"T%ѹU:L"+^/x~_˅T1Xe-)D6 j_Yize^2cb'1nc׳M DFZj:.}ړHTI;qQh9 ?,Q'#Aϝcن18yn7IKj / {/ԫSꎯ;ioYLsRz2KT2T1z6LDҘmR^\_9 |9EK>6`,L6-^ЪIB* 1`[s c@ a 01cqcc$,kkkgfEaL+---_za 01c@Ks QfWfCo\ :Ý̓3k ӃCׅ+y [,}Tҷ^k[b31C[ކƺYtl$N)g퀞 Vuy3;\1M.kc!~]56䧖NqB5[rH~[8P4|{;A_Q'%j,E4 hediqMM4U"{B?=$4X{- +YNUHXal|T6y :qjyһ­uBF?[x.on  laSsB0lF)sF#:! 䀪'wG}C)u:+We՜;iͱ&/h[qȓ{niJx=s|Dk.2݊nAEjfZWsiNC0oM~(b2(ORZ۲-tNs1&/ҧBH=8,  &^ո z'S.2}7:duRW˾`hs0+/=Nb֯kUv7`5NqKέM7M"^d:?NgmK{Smr\:y crjx~Kfu0~[Γ9]ژ7vGN\Vrӑ\;kjLW=FYԵ6=^KK[vcW_ε'JzU)gƵ7\y.Iv˲50}zWݺt$%#w_PI2XӣquR%-ݵ3[xG|wqC/Q?-ZIv2&io-4l0Ym*іs@V+-j;ʮMW=eN<#WlgohF5t]CCE~wW.pv?+#H&gXr)|t؏%!}m'/jz>y׌f%I9e2;Կ1VaԨص)ףC\fk0>x3űF1}˿7yh8lcx[3{6d]'CLUuna(# 6}J-. cLb?5df*uX0%n22/g E;+(Q~kP2Zm ih;{{qɉUO.90uqҩw^;Sv*ĥ4>'bVp]ׯ\ :W/ Ikʨi=l.}b)j +kS-ruW -=^<۴NY.ݍ$_[q+hj V}w1XB&XcV9!6z2WmoJI+;;̫z=;m˓\m,o]u +e_Q) YIfUa$"^)R֒Wד2R-4ŕ 5Jy6i]=Ø:9;R͎yq}r:732D^b|em~gh^xQF6Z]VYT92yΎUTtM,NL,gFJ+j7]i+.mXdLznly`na~`|Nήg3?\ѡo~%yu`fcJks#=K4=3L[͕鶎Ζp_MEuIY]Ȼ KEU=3KS}#\"$ byzcln}v.NM̿fVfG?:5܃ me4N~(tykhNho c W ,/LL 8<02LXc.XsMmIIu}Gm͎g{z&pP"c@ a 01c@ a 01c@ a 㔔ooo߷yyyeddb#sØH\??ƷD@s[ х_4??J: =\,[YOHguu<)-;6)-uff,1 WV_/NNNzxx7G®Be+D կhD㿳 ~ェEO(;ۏV9vP$('^Z|ﺬ"Ǒ32yĚ4~mOoudӱ[:v<gެyo>vI%#ep /0(涄rֈ86)mqٌꙹ7K8vƣ5ؾ>DC3[Κ&kNUzM,×;%fW<N׃R$w;;_˱{ӃB }qJm&NϖL]IT+B[{{ק(+w()#j65ٞ>F[{y6YܻdH#&G%_]|=(( 9 (gUKk[JfNw/u1|Ƕ+"Oz<wI%Yw8VWo[{z/b֣Jml޶ݶJ]p{ ;{hNC-˃Vjʒ엉c fCerߟDō0&*K{Oq=gG>XGl7ia4vvu6Zωtu64Q9{9c !KQBtIu)]ӓ̵KLljng/QwV,-1'ZqX__,{ӧOB[عMrac9w!_={ؑKԡ(dd]ݷ"Sū{ =_whvZPMv 9qQv۹{ۯ9 ;~X6/2TInauO_7\akKQ{"̧U`7)m'UbeOxi(}GXE㔺벟briZo߳%K/t9UxI&OHlnwI0vC]]{UWWCJ btμ=C(#/.hZ4{N=bצˑvƀ7԰9}JoYU<ɬ^Rg'KAR-M=?YRoG?kr[䍲La,BO"Yɹu6`u>}pFe l._a\VUxL݇cgƋfff`jj:2Wmqw'W$tenZ9iӰP3u\0Z&Jpﬔos[5mL[7Na{E|ծ)q놎{Pp}Yy_(''Z.ޖ_;XvąEfWvFLڼ9G{>{/x?e]]E<76vځؘ - "H 9 0Lu{]uNssf sfE =2me%^o|̀y{ۚQԎ^u7إ2e­=D9m9fa912sH+*}'zc /pIX`01kX9kbkl{Y[\Rj9iYj۸n_GăzFZa }Jݓt{in.DN:_36:lm{;uX6s\J: tm)*U:$l>9uTKKt6ZGn<l]fe]շ21"-#膙͵zQC2AK!5zme0_iN),GfnAT\~aQ/FzIO͝»u࿼E30i+7476gJ~3-? 0XT?ouHSLL}{X /Oc@ a 01c@ a 01c@ ;0ҋ ˜[{e][?w/륶i7 fXͭeՕuͭ$vw'|a}b+/8{jf>kd~UcZ4IC-Ӧo,7?Eq>^,nG;0r(Wj9Gڞ筘r~K[t~su9#ǎ9NƱ׌3%ol] ݈fSbVɫ]x?|YRsv˖o?T)yJ'gdd;y<^um}s+i``@G[&̝v+6j1/eTm|rD@csqjkV'=׏U(?]㫟τ2(O-+kEaj{! ̈ã0* b[ŝvJ'm`@2eqiET\ՅC g/]Er-=/:Kuy}:jyDUz\wg߫q[8aw23*M\FaŠcZ3}cΧ#o3چ8f[ˉO$66E1LZxh30V8p#MK8j®C*68Ʒ<)"r QUG[0rZC3rʢG]$QoCp/yBrVn_%1 )xXVXzǿcAwUƊ/gwcg(>3nqgφySMqN"d?nx@21jxrP E &31%3%=[ƽ踤̜|qeYy}}\Z8i~z+y.k1qk˷;r}v-o'GGEMM w6恢QwRQjjf0'7f\-|ᡵ43-ª^,YlbiE5y?[R.Jq,C]š$XP\RY[G;:ťb'76xhm.DjwյuQqӳr Qz_:e}GH6]?%bR[{[{sb@Wང1 0@a =kjjr]UaL0DbX]551Lx|rM<3n@ a 0164SpdaØM.IIHLOH+k ԅ80TUXsrRRSجAok%{xø6찎Y.ǍmfQ2a\FևJunORv:z)4@Pܥxøoz9,j5.戀I~QBT5,buqyݓcE@oW85F潡B.{i|apζz_7|Fj l$w}us.wHN6&6gP#X;f60_ ~ŏ]$urTơ.7℟u}63Աt zMZ3<:.rOt1Z]:ms76=YyA7Oڟ>v̵$Nqu~]ب7O9Q 'g8Gvm|,ꊅí(2' D &_C')u R *U;6$wwHO?|k{,[<2{^%cǦDro\j6*ʯ%Eje"k80ιj*@UUS?Iy35\Ii]l5BX׸W78%9H,g XL`HknV4[v>vRu#f Aom^3k;M+ YocZi:Hwc +VmRU(VbFStHSuDv8hS>06;$C۝7,ِ0.Q" c~zp{LH*~Zgܥ'W1&G'6->}mN>p)NLLȩ7?|FX[rix?aLwՌ7g.ڋD?+T^YUMMu]ZV1Dy]qA:,ڹDpߥu=>YAOCK6>9@hUˬv~[نWi'afx(k84 )\k>H序$oj(*jgG__ګ7ؾUYylÇ1 0@a c1ag _P()DYOROUWWfgg;5#Fe c1 0@a c1 0@$],Vw aO {޲0c?L*mn%s8}8-¸9f9m4ŭ7#o7|J>JnKL͌KxOA_i_MZ=׵[\L릒ZITދJn8|aۨna2EOFE+7=a丌_7ѭT6u嘎t|)hz.&i9Đ rQSϷw 7m.^=o>uXg -6e?L̥-+feR݋τyK ^=eOR7KyeQ&^zAȉ2/[t 6ve&YT1"Iٹo$>ة9R{zq QBeV5UPdįp7gqyJ$-dLGcm0K">a"6>lqityF/nwϝT?зRK< m<ٽ7qm]=k~σ;'7ZSQgiKV4}mRRSZRrֆA=z?~\\(*~''({O zk< tÄY_n`ĂЋzS8TuRn=i[xL]gȾ+-ML҄\/b`@XDL3B/cE\3|) fcmýlϙhћHjlLa fu(02.taʼdzEJ{i|ë݃LضNQjMj*sHuܖ8ø4&^UU]j;p~v6se-OG7 ? lr2*-Gj'j++~N˖Seo:æ(,wC8rmϺ9@3bKr\a5bw%aۛaufOWi9 )i yFM\9_4=é\v$(]˿YptüW/e7(Ԁ磄@X% crJ-6>^AvŖ KG-(̷0o۶\QEu1+eJyuO(/g1%|Cs7#;7'P\GD,@"^Q|r86)~:YqߥdQDe2fH}=a.HaLRdt0l4*]!3jK/Z׮$8\Ec yhOcO CCghye5imIX)Svwa ,SnoXo}J@I<ǮVIA%LFn)\Y)zPA[mCFw⚅`fo_Nd_Zx_XR/ c^v~a~a)_<^v^QL|2B/;N`'fN=Wl8q'+jZݰ5y[ K_?gI=*J#l6~M N;>ZI{wF./eWSX\=}H)H2=V~&~e--аsUzcG7i_i '=_-*E K;{?tUcӊmC\9}N˞.aQ-A3UË KrIf~)sכxuTtн/V+adu%fe,@&3?o&_c&:&ґ:~;i6$Ž;G|=qĸ#~$DβWgnޡٷjG{֛>v?FJnþR( V]8u|IК:wĿ|5qe'#58-z:v2By3j0N~̼ORvuX-+ZI#kjzG+Oׯ'S>} Ɠ5FGLɯW5 fvNo}_ҰJ)":Ux7e7Gŵp :cV\q<(dPH^*IwڜE[YMg'_PU3D\7=+/2&S:i4:ǫo|[q ?~_\IT\蓧&cMl~xN*3,2鳨˾_W˿bgdqZVnUM]eu]Jzv^|$q{ 7=mҋVR7sK"}AJIs@u֊KP-IL frZVum}/~Da,eu>q{4fsrB>!?c a 01^˜ab]kjb2;0#FE>yf0@a c1|a<+ih}̪6kb"}>%{7-רq_Q7-~ᩜ׍F-sw>W!p4>qpۇ->0WdS_[$SK]N:vx*ݦ^/A'Ug&&g6҆ %%dWUW5ӹ!_QeL|t0y19iqiyd9iϧs2;980 c5]Wz\|渡Αk%4ѳ>Jwi[;t/¸>쬃Op&O;K+7n_s?y9FW\t>rµNvFf :0&ԆofeeayHf Ig; _b_Hj"ztn.Wjy{0{[\o!>m65WuRZQy~GLjeAMoHP@c__Ja봀RpvϬ0=*atG1I7Dax567aLM>{ߥVFdAR3瓚{E' q8agD;&:ON xZqڣ07{ۻma,lvapF2SgcjoS3#ݍ|p8a, c_ƥܼ,T=4N%ioMq+g0E= L cƸf۶n.i:-t;,ϯ]~d=EIY,.i{-6E;K&H=CYEEEUdxh6U|Jcx$7{>swѵ jg{~_no_\vy0y60Š0~=u57J(Zw#v.Տf8ՉY֝y9(yGvM?S/M|3>-c:z3Ϟ:݉ a|EkGk0)-$JW=#l2[]TRSkb\ek\:Dj>AbmýV2gUE%7i=CeZZȌ5.F"18yo945c w/w^zb]Ow.K|vF +{K+-uYzйMmEip?u,[#w]OZ:~λ#\LllLww=Nx3PqFo琇rodkDnXq[)2S53ұMIos=fǮz0;BRM9mXjsp쮈>ncbpPb䶥39(C6!%+ucFzG&\n[#&zvߦ&7%50 ue\Sc)Omy܆gOnm/9ghInp9zxSA.兀I8qa³ Mw>t>2xVꀩ:ayW$9 Tw߶K‹R_{σ6F墶VPh4ֺI#jc[bQY4-(J٦CW0yJ\1NJ#xqziUDî=s쐭W2i=`JauMO<͹gvx22XYVsHTSphR*ZeGJa`! -]em28faq\YT`="^/H%VR[#߬z_JT5;{M݂*G}[ؽlrΡC-Cvp\fdGpCG%GRa^ec,}87 b iۆ;U5lCr;9jm1yY{ o?oc*rs*v+zfXꘃk['ǯwYnZx|UmѳMRO &l7PHf[," ۷a\pNk󺫢iysVzgI;W-4) :knH}ʋ"VxV6_ (~c>qVUҏ">&_7%묪 5 rːvߔsk/H^Kw弨374b:AFbQqo+[y-7 |ӅT3js+B7ht՝U^-{ ]jDUws2jI#kEo!~_~!-w3M4'ֻ<&VR,lΙU37Կ|T"ZYK4wSFU+gr5Uܳk@%^qohkNsr'akiFrNL~՝e4gG/qI!@ /Žl*S ji7+x${bV6ʛth$?n*Ckc䨴]t4Nxˬx[~dcuZﺕ# ѓh5d1q@07VU^6k GIS,Ɣ,m-jJ aaZct:4Qya!_CøEw]v3'Mt#lf;9pʤ5F, V' 1VPPjNW /˜Xj&,W3%"䙳bEk,P@f6U6e[2"֗_#h !o0Ś.l!m=O5I_3؜f,XRӏl]6Ai(ɸU&N : c"S6N)~rV*}С %FF_Z;U.>F*ʘVwhukV:&p@s=U5<ۍ;tAq 1fuocJpH!;V U!ylfoռY,%nqTwz5#k^Y'*'I3thY퇢s&[W$|fܞQ*R]vL5ܽ&Lrf3/,6,~*N6;)ԧfm^!ZzO vz<䪒&Rz>cX]KYBhqf`PsJ$Sƣ*K<9+8xuכ{m}]WG7~lY?fx{~[xbt!ٍ^3j$TF 5q@ά/sWHZ6vES_jc(6¼—P׋KZ*e$ZDxYg?!c^_*7s¬C=']i&/XMAjPQ`xODf)s7?*֌Խ8U&,E{arnMяPLdꬑ8jzXNZE]XaQ#ǬY6)>rg6.<*~T+:1[aUSչBQ੽٪HR}kŏ xǷ7vS-IOm9g/Xl|+?5Pɛ/jĮ'GTW:Ŀz#l=[alP֟}*hoAO W>m6SGƽG_NrYh ,}9ԞP:xjQhg2{.`h_DGm:GFEmN;nyCTosK#:ǝO_ J"mmL-;|ԝ'i g5gzPWQ]m$V6кq8,J}]]EM}1=szWa c1 0@a c1 c@ a 0?^ynVwOen6E2l8?2RBx?)x1r8=q|qsɡ.%IJ6ӏӻc|oNaⳙy9eg-T:'ݥ#>]YV$ĩQwqD6r ¢b')8>0YQv[=3/U"lJKm~ߛN9ij跛t磔xh=h2c&=S}GD/IiYյ M-5iqu8>0^R|*QWL [ĵ)Nap;]2vK҉c:ǓCk:U&a5I t8oEep]܂;=CT \e}Dk֌{^wj5E-‘˔w13킾K70WDK>k}eWk^.лSkK2ݭapjRចBSΘ_a7yJ^q}K52?x<ܑdo͚yFϋSJܶ]Щf=^ש(S%n&RuRb@C6z&ռc*j#'Wx<:YZ^f9̜R{,Mw9_0))cGby_c6q*m2-#+*̟pp뼙tBZ(b%.Y8.bSR-%)Y3]t'DT3f;Z8a-}ռ[ V!ҩSf5>A3~_dԙ_Kd 5GM?i6YÔ96lz}U'RYv|@P+TZ4EaÙpgY?-PQ\qDQ;\I7&ҶL4z{*,vT?m?j3?r=B)+(m2uS j[-V^AI;^䠱 UK6/\rݰZ>iԘYK[QJfEK(\ygKR_ޢ0EIw$gXb$+-׮Oli0Q/Z;Zaramωk ^Zq僔f:W T9CvE\0آwj:+M?@]1cW-OZGdET}ONM=U 9LNSQG̷㖎7=\$`Q|sCu4,I$i鋶^tŤ 6E Txh7s_j3yړZ5qr" vO &vR>IN* >Ƃcs?]z89Z腪AD"*]3q͚Y+Wzi$ǞXٸ^,$FξzɌ뽉zom QS _q`绝_4;GCm٫B%b(Ku4L+NXҢ.q@XFO>vDϋ05_;3;ӔJUgZE ]0FF Qn&N>p.#3I+pI5AO@ؘ.jҊWf MX3rCgD+Uݲcğ&*='_P|p+B>Yd_&[[9jېf^v 5=;d;)PR[;N},f_r@yUrfª+k\~UMdKcUdX~\cӏ櫺%pc`dj(׺o*-!0/WyOȾƽɚ?JR [֍'S:^f>O8/%|i:n7aL4%xnE=ڄkî?l'ϋSyhi+y/اuW¨.nvXQ+0e3U ܾ8͏Io_:̗FfSt` y͏gk;2Om2p$0(4ṩJDϧP' z-ʽJWՄGI6BI 厎Έqd1uNܔsc?6;}HI7e[:SГeyXOH6af+Wll֧':_b(r57,|'5 _&JJ؎0m+A (Df?Sia;7iL5vuCZ}=axĨz?6V~X+g35n>;]f?&7]uFW9W1s\J};QDr$o SQ~GY~_`z?l y00yz#S*Yt;IBۘ+ZLb++$ʒ=Hd#QwbA{ˠb5_i <䍲p_߀{ C0%2J- ј@夺9AqGA^ŕu EI^wC$GeI|/v>ƝW6:4A]<)bolSw! cVOk<ܽf@Еmǖ|%? ~Tv~R4$_oQJv>'uNԋ>wWzYL~0\6v.eh/3;+cF8v>cYnEϋxo|ʸ+vH*v>Ag=g<Þ>}DM-޻6^+BjG^d\jcw°J/0$A=U%ς}%0c@ a 01999M3KKK[3̊>) U+C{w0@35 0@a'TZE~ϛ"$:Z2.3!ʞG?_ۢSj[aL;utNT3W ;~h'F[w,ym{T.Ω)nmT? .w_WnrV GLʬ h㚐Т?O֧3$TwO287Ũz:~9͡7o~KRh EsU*W77!h?Iͯ𑳡e@l+; 񚵽SYwHQEgw3[Gqg2&_?G7*xmxb}V~ L䒮i`X8ѓaj[n,z}u;+g!1ϝL/+gGZϗʳjg?%|aǷ0 {+lc]&w垳 1?Zw6Y=ud͟/}x}(te\(U4EבeKRfx^qvHzQ͗U75^ %ٛ~$aKQ^T|qivWӌ]Qsx'K9n. i1n/"z YqJ"o<<8z#>Ք&=iIQ_cZNTv]bf!ܴ҄/^ miijzG'F5kjSW}%lJmeS9Gw?cfÔJg-Ȳ}gggfga0:hLbǎmlA&AdffffdI_U ,zz|sHUu{K!uXOd[ooV { Jߝù;Etd;k]ݼ*>!TɥdD ƄzD彻R3}}R&+xtѨ 1a!,l^OPi@n/Kwߟk\cjw{2R鲤 { 5%c h+kG`n`ݜQ͉ͬfu#"XMBՁH,&8iPwvAeˎΈؒ}ֶl%De#[fZo7:u,r=M|@iߢ.uG{*kZlwi401%4ucc gwϮv@74XXI]|e\_VX~QU&\کl'`)Hȉji.߽Do~qZZbR*{K5ܚ:spOcƩ-r[.;idoװ0P1Fݛl ĹC8 ń;w&y;;hwi"}⒲qfF&W=XSKb~e3m9-v|?nt}K.x$ kz_ 1Z=2G]`s!tK;.=%^ Cn{3:}r?;y]N\yZ+?.1^m+"{Ցs ۓ m ұnM414u('{gTlLݽˎz%X&d+|9[ sw zW`^amGR7>%wJ%ɍx1ޜ\ݧoO[WEEgV֓ 0cԔMcdӤqqkc1i1 ׸ӑo鞴Gbl5mRiHh;2Ni mJB26_ms 7th\QK)41ʜ큀o3͖ ;gy3BK\0'њQ i6)hSQ6QH׹aan`}Mҧ,-1=w6 ?kwӱrSVj\S"(L\r}SOig?Ӛ㦒eXNN2ɦI]oG,uK[+eE+`+?:j=HD$JJv*?qhd /\OiiYѧ((L'8G3k:g5k *a:z̮{%f_p[E=T#}iC.!3BRzO*<l{g \zP!W}O)@5mF77~u_("-®dCFCi0LX F&ky7SޓXJxv,ٺHZ03JbHG.NVzZr`q8'~2uIKO'9KI|Gi tmx?ۏDƎpeWyFFEspC1^p4T4wOJsu GnVS!8!^lګиgrσ^/Lqr\$NţϤ#igᅊ<g̏hQj0O9,mA? {r4->*Q3HJ B88Is#7"wMOuW>kBBlvutս:vG cO"RsY6-M&V@o~\9*ݮX#ץ/+bWJ VzD6IE^ X/ L_=5tԓ=Oru nJݕ,DL@3Mj38ݾi;.$5? ~DEw+?s`$M]1TW*aиWvB>)ư ZhQGFM~GTXHụ;FP#$IzȔ)r۪E~8Tfr䏗"@eϽYf"leؙ ZzHPǡ ]j c3e$6ҵ$ܟt_ٍ Vze] u W1p6u}kLX•j+J)ixbBdbu$(F0cZ]Z>,}(gO`Nٝ0Vww4F:>xRidM7tƋݾp5TW4^7/ƮTd' jwSa| }e?Ș P#t$%eOkIKjҫzi^OGȲMB)l<6:լR{akII)~}&\r$|lS@R?t bULhpj*GB㧷蝮ѵÎ,NYacmI% S_{b>QeUL%o0/WMLJ'$SIF5~n-'h,0Tko vgEHߗ .ξHl+4jL.^uΉǥXȰIKMq]b^>ݡqP!K]: POZ]^G{yN38թr-)ƨ't1nV!].f߹cC%DGĦG`/C.AU36fs.vtJfQKPo)גr jdl,kB/7Inr3%,Ce*Zq&?f[hP1Xb q0SCzB>PMę@yvwh:*# UvN]("}Z8Lj=C'\jm :64]NSiլ&B AٮMkءG[+'ãJ%#~CSdVv>Giy+\bi;xn:.>>"h$ïmXߩj4l1?P$y3p}FB}7 ziɘ7N͡ +_A 2zFJܪh7mVzz#JַU].yKp'Y uqe`h5Fz7;5>$&)UM#JQi@b^ /<9tf,^bjg[cƞ&6KV+ 2]~wy,վ-!kٱC1c㊞`~6MRԮ2$r:ظf2bGd%^b#rG y ĸp."O`<+U/cpa HQBԏŸXXױ9JE= ü-mxb8^z]P/.ZjR2OĴ"t_r(چ%.Io(j0ĸR ǡ؞~Z ٯ)"~,RM*U.x|',b@XQwJ¾SU xKTDӻ]a(Myqeğp3_bfs^+ƀWJ/Oݛ`B +N & @U;^⫭M8WFuUߢ˨&*%Oo|W*f1VҞحceA"nd$Fꨋa6|?$'$C J(^}7Ds캙8}' wg$G_eZXwW:MCbLGOR*q8!>,&Tlij"TCH۵|;5 ֪BVGNbdEݨ15nK({Q1[ڜ%GŘfquw1Cf3c3:%e)ʢ+Z߹O]e 4h9Օ* oS2F,>R9o:wI:u lDiA^__>Fڂ^u: G*ãȱ+o:j+x'_}}(r?ri{K-i_J2mB0kmivDFqfe:BC)^R+@"e&OABY'z~AS098))<ɹr{c2d$j+:›K넵s߭kCORy>7f_LQh9H~%wU*lNWf*&ޱA,5caNk<̈ztĬRܹI#_`dM=ﹿU3ăJh\8 b0MTʤf kx/겐Vr=X*IF nݳe6ZCdLS d]*X=%wEe`Ox(ݑg x~S7#ﮙnD#[lMJK9l!cq7zEe]hVo;HISTmJԷyc&A;:e^x$7# ,ik\a:M>5c:\MA7XTXԪ爧Z/|3}S[C)#\΅=o72+,׍deQ s̫=G ^hK#S-ZRk4!16,e=So?ܝǰ8#Ja7;3_O~* d{xLz|]'j=]~:?sAp?i~@ȓ =2>0a-uo$3teSI]жA" 2oUpux4~DX7V,Wm`8 x3*+g"VF-Ђ5zjJ4tx*u{B׻VIJ~bL8Ώ?¨m?兎m_pSǙ:m_w=:W o(oHؠ[ܿk̏bd}Y;1f&4Ԥ W ãƇrPs$jJnIDmt^K\/@{2 gG8MI|,jd 7Ř\{Kߛ1xES Tx! ~{Su M;$U!5-~2DٿΕ@ r%o(MQY/9P!tl)+06P+{&J  M Y/W!C.x Y\|XV(*Z\ 1;W|٫mbqmjo&+z7+G:’w'5LxȇҾ`CW_2x݇,F*wRHyazgo>i?@^}G{l?ɻ11h6r糦!ݵj'28q Ȥs3汱 0iltjw-9GwNW.sc>[`@HI,X 7Ի{@dTFۉ'vfr+469Ғ.ç4n"UpO|~2lBS)̹Rr4߯Q:L* :kۇ4MadFOaZsԄ5{֩}dCߔCt}WƷ{b ->1k񶲜D3;|@6x&࢙q摑JW`YpPͣEXRsDIs)>VxcTxhMid JSq6+1ןGFJoݑiI]گ4>Z($nEtb385k&b^>g vZsEW&=D£.qCcXk1Oy5 r2v=ut|@C'Dlv߶<3Мc.GZ#uojMNvU*2?Vi0vTq+UUD7q5y˧&ӽ H9!ٷV&ޥ[JB[X#ݢ k9%[\ĸnۛYK*$̂)V+q^# m(Sбod…+ug8xȌ%tCk--6R Z VAtfR1H/fiR>)%V 0Fz (]FnVm>Ҋ(IMkB-Z4yYJ)1d'-ˇMZSe`[ߋC&8Kk;%ʹͥVo+Pbv=Ƚy@]EmQEע)CYMdM0@i%C2h&5VVIGB^8 |8OTit ";T-lQ2JEPIx|[beu$ޓ㥢#V4n?&mPhb(gX7,\崥4ltD1]. ɉt'2u:\Z^  j87JKvtBM&jXiIpʦԟkX)ړޘULs~)DSp\ H˭DlľTH# F \\a4#s:`%T5.Fr{˥aPn:6vĦҫIAAS/w~2_ΞvZoѷJtcۣġF=K(Wҡ7xs.)گpP9f[RLh1%=]f2@LV>Z]찹OKg?]#\嵔,zcjy1;T'%Vbr( qJ=֡.xjcW'9{5a#o]tjych̋K JOT|ŜYeuBkR{2'3} yUBvڲp hRrJ`[!hIEmLx$ke9CRNKاr ҜFV'tw[Hv,DQ)=mHZiIZ`9-LUIS6*hGtpBSK\m9ׂe킯2d$= *⟄Be4Ezt!8w3θok}-ʋƤ'`'\ԯuok|Y3ֽxkȾ6O}_\iZ6A͕u)%^ b E;wAMSY H._uc"k}}JIOdaubok^Q11 1 cC9^[ ƿqWP:h$1&؄ww(֗I-v*Z oL4{Y(pXJ+q2 g\1:h QvI%n/VmT( em6ݻgiQwR}uEEJƶA_JGOp+yBۦs b"f13˔$gyqd_ էy޾{O>I2 T6C _\lEWoKk%U 5oS4Tk(]]n%{Hz  >rq=?[.-)g^eԍ\_*?<#|V?u2 vxi%;??,k~DeKi6M13™, _tܭgg?!Fnv88~Kgx[o=;wKsC{3U_<9.R;E;OC1®N+=1̙D_ɰ~ }b_2WqJt1&зNǞf m]m@3hc#{G M91^ 4.gpzۆ$V4#XDWT כ n!Y(nvL }>uwevl'DAչIGTZ :TdGFA*hC [`6MOTQ^TV]! yh-PW3|͒7o=U0R4% UdDSNWUXR0B.ti)i ɢ+QFׯVd NtŅB+\ϟՀad yePosCKc2c`gW]sfC\zSZ){ԽsLtv7tt.GS:cGm[{g67zZ{h']Nn6{ܓΙ %{B&k,Ę:3G^ &cb c@b 1@11 1 cC_ MR 5lU7~oNʼ~6t8&OSbZmxu.>%OëOm3(/a"k %5]]P]>(1Dŵ' -%1[Fs2[oYJp& lA+8ؼ&xx[pX)yk/Ԥl Q0_Ckbe;=2o{9zkQSKG)gX:م&XuXgp>ߡ4gXZalCސթ67\h9 o]!@qǗ!GLzEv6M"YαӚnf1rw'G![}#BR7vۋ^8DJ˷l9~*c N^G]E#Kԩ''pO^zɇJBBI'~ŕգLr__^ʧg]|Qמk*O^:=oϓ=D)ߞ?}wy3$G|/.áM)R}H)`ja Rg/9cΥ_| lwWܣR' qOo\DwD\)8E2}O7= ݱp܏ELK)*cKc;Zr~̗>ԍLW?>H%mz~~Sǿs큜k?gd 5͛C sfMCsem=!1RW?n |m^">ˮL ȨWxΤPײ?9H!w6]?s-Zrx K/0b8臛 ^rO]z>ػK;:EdJW)dZK. 鶏i,,ԥ|d8+CW?\1? P O <9~Iek{5,+Jp}qe:5Yᓯ#8HNgiA@&?ͬ@:.`18vOBfJN_7k[Hy݊Ux7(,p$ۍw6)O_tfm֎n\-߁菹ѝ_z?|XbLÅH~΋Μp8Z:ez'Z)dj'=2-sKw!Ʈ}6Tf.K277,NNؠnZrc)榥dYc+#oklӐxէ)GĘJP=u핁=Y9yD9G[x2$XU*/SatEόrx1T&y}a܉(^g|}A3R١$xն>1khnvXĸ~xKK?L[>~iԃ"i,(a?Q$զ}kxXR?.6!Ʒ_hδI8v˧zM w`#LOܗlgn Sۂ6JƌQ#ńcJPR扳wrrG|qw;..SacgybL:h;?qn4Eܹ+TjMхcg`V=v'ސtЧJuhӇ)CqGbܫř?2@z8O.>d+xs~#˂X%EFߧ.#GޣfMS5v@41ijx,Eɩg?qy V_s 6Q"DgW ._驋 +no)n|s_r~J#]%n#~ɟ\k`̝Su` 'KWCPX:?zWn|P+:68yBj.叿p(t>P _?S3Ʃ|rrh/)#JiMm>2hL*ÊD'{];[raby,AV>ܕ䡡oڵoiBhy*ރŚ#S[!-x(cs[ +wo{І6Fașvz=P(39L#yA:PCkqΞVmЍh`0y,"4ZkJcbs T6,H"w4>+v66sEޏ)Wѱ-Ebf_;{k7u,ݢHwc-dyHi5%|^mj6&Vk;ܥ_Su]3V[ JҏVhhHb[37eɯZNc0_01>LSHdPcb c@b S7777Eb<33.KKK[[[u1Z\\<889}~1PY:b 1 tf =Ӛ:\;lk"-mX/iZGo4fmyjo'X;ZWP=?zOJL*lX6_]4 /8A7@;4YsוGEl]H~2uaw;5@3!EW\æ_n 4R=ܪԍBko P$e^Oh9 ,Oo/pc -wl|b] y(={!=:=pŘ'+z en|njEڙ}_z:;(Z.j? /R62Q߰/&ҒR7KQ.om#7/OSsZ,s^~UJp hmf}g>֛)f?7X[s 9|b,3II lFpmL]M@@G}zTYumumCn wlPMz_pda?k: *M)=JSLWU[YZ^N٢, Q`1[VU9JSs43=IZY=m7F'U[GKbCW겣CckF[ֆۆB5#gP7/:z)P%HhgEƩc5] 1,^.4DŽ&V 7v7ݓmi^S[???V^R\Z^VQY^V׽Epc c͵ڔȀԾCE\'@\@fbSW1 5&<2>G.h^F*ligSVN٥ o'GƠZN$w#e6/&װ;iQq nиA:{HٶӽT} J˛]S՞ںa¢}t!*OP3uɎ{'fT H+i53Ԕ8#z9KIv7șN3i`ɸԸn-RʜEF#rĔQ^؎5VK{,$9"F.%PH.51q!xXK ^`dHcrq a^Y+ sTP i &*̤D=>>xyG*IY| sD}vZ\@,{ſvAc%Քuc-DMi}+|}q|.H8YnbajiIŪ YC1fK_P`QK5e'yDT pO|Ju4Y{͉2!)!z>H{#AJejmcDau\tx\kTlYT%I,Jbzvv^O'buFjl=EeAgB\8YD R$6*=&Xghh 6J`S*ݤd<\K!͂v+ù* ]\"]O&) Ց >؉a e ۍ2DK}BR>sJmѮgG;W{{uUa-Fg qjC bLc9{QI* R]9LkE6VN T,~-;J5<1i(@T+tAmtזofj m;JH_%O0e15M+]U40k`޽q-4#Dcd82kkЪa5~v3Jѿ4hktѸ6sx unZ<`R:qi$Vt:)[O,b:cMI\#Rj^c)j *垭d55Dzhmۨtoܥ.*1۹lFCb* \K.|jA;pq" TAh$:aBWV[lznU}m6 `kٕ1kW]C ea3ja;Cةk7VɆ(C]_d3u?mhTAtց#S6ZTü=i~c u1+KnP i|vV>Fγk'/3 xje-Y1^B['2D 78[)c5zEXG))ZRrKN"|_ ƓA3b y+F@56iA{쯋~Uah(ƭC۠'R8.W05><2:(E٣]ECxܳ4Y,1[ l ?kFe3R2jf4๚[6ljR Ȕr[G`OK# ,Cwnh$yb|bn>p.P؞FUQ,$,y(*c2)',iQ=4_9a U ǧrj!pCZ8O5S+j%Mz \=Y)b+yi iM2$Eq=\Qyȵ'f/13J@P/eteR؈lwFHrK-)?C"5L*Z,p!gZqSL]ۘrT`׋loiu&lZ)Ɇ4_9I㪙=rMd|}SIlZ\=s"ؔb^3T¨RZKΕT/|ܡgZ>ZXLQֵkGR#%^ 6#h} |TWg-&ׅ5=LuUp{:uxblov !b #I$Q1AYXdJ:ރ`l=AJڠgxzju!B]%#*YhKeL ĘŔBn$$0s~:hᜐw05uH%%xk ssskdV\Ion?$Ren-\rvpT~+ !(#kK:u<(6jo-11X.usJ !,M\BsZ kaüURPeojjA(Em}5W:HKd[Z[#2ڕ` ݋keؤ:zȹݝ]IOGS*=a"1eWvwyYYM0DW"GʱӓIn_m/ _Jmk&3 cl, /ҽªO15rԊP[_Q8A[s c% :EOu%*fۓYi9s7环XTY=gΜ{N l#&DA("9g$Ar(b$3HNs*r"uUEnmmbkoUц# uGvu|fJF+6C0 #=z4ӵ5=uvһIini^&4O@g ?k~=_YTN:踨GUiGhEj_uSZ3dBU1JC_ O#Uӿc݂jOq|>GZytNVtQ/KdXF-f'߹ʤ;a˿\$K՟x'F>|Z'CE/zPՉџvPUnX.OOM/Rv.觎gh/f2|5x %}۷Kcˉn#cn^ԱvxO=Ŀ8|}C˽YE㔮6@_Wۓ$\}eS?A\uvԟ似q'od7UT$vSO|g7eYCSQͲ'2_Q=50IOfenl}nxpD^..n͸G7 nof,5Hc5%9E;8Z[ԂߝK%dzzh j`k+I)lQg#I3SS^Z=^c9%-C+,+UDwMFVVUE[3.;QSx&yy%;;V6!&y*g cY][ɹ字}uYijk)ʯFD]{ Xl"Ĥ:;**{o|ӎRys4mrkUn^}V,Ḽ&s2vyn.Wdl!inhIzocIZQԮN+H/ߪs#CsHrj)\!%H<ڲRWEPNUo:Z 幙uc͕ܤ2jǪ@}AVIڻ6YW^v-Sqm.4eԏW/3hѭLu_Mj_"whĩAjbIKC3$:-z47b,pUpv哤ٮ1M6Vg(md0ZM%mgh yo.ÌԖvol]ynZq ~ľΒkƼʆkyEM}k;)=(Ubɭ Ϗz_V]ٜm),>#a)zk2 ڦvxGYZvA(s)h(J/QjQ/+zz'oVdjNHƄ8ois[CC=ۄ&̙=O3_~\طu(!zhYp^ jVभhZ V8XxcB)þ}\!қ ;[{&MdY#Dh~h(|[AI7rp=3kں)+z/k0 M] W7g{L7c͹0gMhy'8 "?4n;n>aBN'y!,|H5e1,N/?pVB>a`hЌjWoD٭]ELZJ}`cpG_M&iً5tU.1 Ԍ#.ѳtgnbz na5HqbG΍h/cno/u֗Ro{Z])F.6)\=,\Ag;:_' *[jvAV>ET y1v){o{Yݴ \>ZIE̽2}-㞞kXi<pERJ=8.A͠[RPx Y37w_WyyeJ/t&ZyiXo눥Rz5Wp u }}CT51y̔޽v]ENN.y>PE RZ[ϻqWx[Dhu>~Vz.#]Ezcfp;?mO/9ܹi!'d@IlschQ@$:&+Mge&/++@O;ֹ]⮼IR?&3rw y4NS@[%( w4K:gܗF6,YKLll5(8FZ+^5:{X릯kc"R :4d`0ɒ\:w%D%uFgMB}}LMc)ZpZfmc>}hem-;;-H[N50 ЖD2s '!HO 헓u+J#JD`pPM\3(6sU6Ϡm~Q܂,T8d7u+^F6ыq k(j!*ebs#g<qYWLF_y2&6<`bX:M>b~]hW"&tN-#؛)͌|UI 4=vNF$Le!E(6 khyE~OZǦ N-./PEOK1MyUΓ#_-VWv 7zr^hmjщYyuczTsiz`y!؄MOqm9EU8|w _Y>Fa-]%({.;_+-#Vq_[hH ʶ~6rE cGVWB\HWr~!7Pţ]sQAiff{9cΠ:+ S=cX'?enl0)-&"a^]k慗 mJ+ʘˁErnHX##6۬x o(衱,J&Z#9~nZ*8GUMeO7SX#yRQ+ppul)F577f VM",BoVs,H;HFRftRVMu脝ĕխٔLq[075djzlV%)wf7?:՗,tbؤ빣 y y6йiqWY" eVx9峓iW3ɒhdoq(>`$sY м\͵ӑ zoqZGVƛC9ʆY >&;VLedʺi3>;t JbWg}cN/:ͺic]kjwJۇF&*D_LWa 45,z_1dR[ާ,ҐO$ʵ5tjikq2voC^8%Z=Vi6=/>2Xu"dq9eQ-fr2YHs7FJa3E_z;1#^ڇrV]x!n^0dc*3->y15!ipccbz7;z^Hm`H۞1s)Y0=$X7U )ƍ=@_qZ<)/iQG) z4̀"?/":_7'z[ڙ\C7ּce(qVt4tq6ve9!ffh堃漝Ip\k9 /Ӵq޽H 1vˤ.fzQӨݤj(F 7ʽ[2FQuXM_LZsћ5WtPV0#Cٸ3/{ɷ|״mUU[)6Q[X=|`msva0_$=Im-!o} |[0đm Q$9i=E2ګ_2p70CJMFr%D4fV*F3m-Z^5y=JJ^mpt+CebP!wűޢm:saBwI_\T`1 d"2|b}DOE@\NI+ P{XaG3+lf +SNQ?nx5-YRI`+#;f\,)RI&l+<HB;943i.s 7m4yM{Ho[k}z. L}e)81y䱭"OW;(@[3}U$bWzﶌoJ-5[IѸt5~dLSѽ]A]dq|OƴQrl޻[ JJ)uj-VZo_-:fd '^I4  6ٌ 澧˓{F?vkcF(t9YO/ng#XP=c$?4cwH6`{ |֔3^E"Oi}m]ytJdlltF2u P-ux[Mشҩܔѭs)ʙ;B=,2ɧ2k}Қ&yb2aɵh:1CS)lKHzc8s߹3탊[SqMoR3:‘RSdtЪZQgR497蘼q521FmNf&LNΥʸٝ+1!JK>MS"/){p*Z}̨y؜jГހj»2FvqvwJ(6*b1*c[5z:O~psGoH:v|nFO2r^ <l!cKu I2'|2ӑ)GY~DhU0$!l5"wk:^2Y1Њ~z$g_:=s/Z٦yVLc}#tg -~e<]'h2 dJ(Y(:}O!pe45 Ķ_9Y,(tLJ ,UӮ.i/U | ;|P⮉#۽OykXyYX (TQAlNoJq6gˊ(KE:ziU=:(ɩmCm)cOOvb 0nؕ0ϤzIoϽ1S%{ibɣomбpE|N?e?e}Z:)XlM'ѫ<6yhsjI wOkZy8ꦥvlh;]Z)[O㓺}%2 5"4 -d]o"lJ(c~l!}:]^X#8 icSwJv1&K<ƺ(K/кEZ t`El6{%_@1߭*yl33ey3a\8Me 2 Mokf%oZo<dzfU0HbwYZ=q>d,^_Sìfj@kH:` by W^ E!gnbRL®X7n!Ȯ~%d)ʲ2i!zFbSi-XtN1aWikOλ͍j(+fNiK.nbj>Ha4DNʬMq_ {?0RҌFθb,~hdܝfi`p\‘2[[ڵ+J!ݕ?#~WlxN5Ҍhy>d{ KWr, HXʸJ,8.\.WĊk5FCV2\uW+Ib-Ħ. ƻ~r-JZbCپt+Je &.SWMlhB1(j#]P0,nFEѫJ7AX eZ {vYtZf^jr0[c(;8t8K'3 >(E <rhm<.+NЕ#*p/.عo"rX:+L03MZw\_`y##ͥ0rbvϤv6A%:fX72mH -/zطWzS%."I=|N,`%wǟTA:, Y]E|['Ɔ^B%];חn>xcdDEYeuek e`1g&#MX72ZOˌ$yKawsVInqT;g @/nҿNa&SBqT?I$u-(a􍅳[첂 nF"N]hzgG1>tSg9+{RK ڤ-keJ=p M& %7i-䍨E%WzkaXMݻʇTiHQ\V |:֊08gN&9=m DE!K`"e]8r衟$5ٟf> as׷V++P!u?>[&GoE3M$]fWˤ+;/4Rku.jgLZoxR)&"}\3ޝ[(xiV| Sic 'Pv}3I&xmyJZWvG,'.eaC RA@/ܕXB̿Rf!@C=ԟSa^bQ[71rҪќcbtV/ɸ&L3ZIC{1h(>PdzFec`Sh9%ˢY9]Csg!,4_M>DC'v{1E5;a/ww4y G 1ʟy'o}d&܊nHEsok=.;C6,Ċ]v/dOmJ}o+e3FN> l|;e{2P;so.9Ñ:!?Aw?jHwuSMq;t1|,rOT`Ugۻ>Vǧ~Gc}~aiucs۽3ĝJ;/ZhL]<] !5z{,^wM\j}0A/1VLη&~@i~~@MMWVv׹(/)+,'uM;pb#i) $l(P$\YڮtC^?;C_$~ & ۟v~eMUFnaFNa~qyeMTP1JHZ99xZ;Lz W-5B$m~)MO#ZA?CG`-+쫉aIaB!vsnX}-Xa|e>{coW$+Ekw\Yx89$LMpC_0 ŕ.Rc3Ԥsݫ23 lׂ:"Yn,쐱+1G&sZ`v\y3a,SW9Sq}m/EMV=otGeicS9?lbu3M-/IQ9{ȅf/߂RD8d䍍ɩi *}LL.uS[SOaNB2^|C-(L4zXrDc_]01P|f#h۩Wek+_й_N"ӭLw[N$kLNS=v^F*{3i% "G2;za˒N \ BhF=l:ږ$-oOS4qrݽܢ˖Ίze痴u/qA#ם}F>]Y hGW\Q\ڏ;6ȭ!;w0KoŌt/8E oϥ ae\!Wznԭxq#MJ@E0bT`fڑ\ue seʈ?%\0NqA9|QڱvۀXd|N&`Y{ ")I |G;69J&J1qh!n1Gd, 9ry sj{{Lھ:M}\"Co_<ƦʅEOLM#a1%8mh.)^_[ {$ݙl|!WF:ȺIgdC*m!=.nU9_c g}܎=r afZϟs $B wbV**]Y8;P>f;H%-MwƤy+՛ö| /\u+ܹȍʘ$Y*j4B[y62y2_Iw/[ڑk1 EOpc8xO(jǚ9yNvzDGIe=j_;j[GL^/Dqhk*k֨kݽuD"#pgO_zN*T߻2ETLd2|r 76:G2??QӗcH/ybl58ʺ_8ef*~s@)m<-vKD6Ec8 7[2 >ADd|ͼqG",Lň]I2bZEʞYXg)zqG "7<Y^mGc-tG^Tsѫ}Re󸸵gby([U}iWwYO<#R_69zv#~x2GYOqCSҾYok}u2U^":mos([\^iR\\q3MQ^]G"c4uLSK11E_?ڧqJ;ԗ.^~11\XN{U;=/X/G9uǬ7X_陾KHz yةoCYYJ9w0m*y$V?&e=m{-yiVLX Z߹ yq_~+h K`0(UR4A-l{鄈|};o;#Mz#/C{#d>; v!&?7ʛJ;Z*j [ȘYA$zpӫCKؗrK:ipqwlf.6Cݭ3=a|tmG{n 7 C}8.͕)pKsgT II }_g^C?jwDS3"@d @d g 㱱n>4[[[FGGc m2nll$ȡ0f͸ @2d c@2೗Lw>24 C{ kx䅐Kd-2ޘϯS%dݶeAg)W [$ kP x:硿KȝڊTu?uusu?}oYܙuʯnˁ)mdenJ ~5?mA1bzdM$In*zvw>^*ok`b3EB3QK.,4#9'%;Wf}tG]:v>|?&opZg"k\A֢p1ܱ_!q C>?rg3{U՞tg+ ~cs$*Uh!#nKqZ,d oʋJFS@_|`CUY1ݛi[xmCqiYm8"5/w=ÅC3m"=.DG)4ujL*{`tQY=e=d ϨG셖^7[>} pnk?YĿVUHFU#%\jK.l|Բ4⎓[J;KIskr¥e.K;7Mfק_IK:%V ogZsIиʧlWKĶCI6nAA/FVj4Ee CgK\V1{Jg=yź{zRB^ꖰ̤tCeK3S-r׸,)myu'nxm4HRR\v:ys.>{J ]aYҳחmZ5VvOL85R%)\+ A;Ddچzʜ] oAߞ,Җ5+ 7>)08rPUXi~ra#*G!uHRan~y4\U(olׇf3X͓l]g^0RUz%7_ sꕯ8x鑇F,@6{ ՑSD.jZSVz7D lf7+c/wNSWtFlP<\+tWJh95잷i3-Q\'8O~i/9RWv:iK[?-D~edD{4=cUd<BUt B9G&<oOhH4q]'7 h-t8ttkֺ9([ ;v8pu9FyK66A$)^.~gv W]/t`]z!AhW"J-Rϝ][;OjSCMh엤lԮ\]6'"㵎$I])t`-TZp?ƒ\?ʁC gZW$W%p GKh9"wRt}Vɧr%܁8s+xg5!oW֍nV-{ƈ [2ubA]`B Ȥ^+e雍e=XNꀇNbU ZQH?br5AQJ\,OiUY,w }_Y+w]{҂ݙt eM+ 1=˄3.&k7i2\o!^1We7k)2JDGEƴĽQ:x Gb mGeRp5=*]1'ݨu-jX>nSIzdpYn fS[[ȯ\KFyT)Lνn;dUNuoxΗCewbU3E]yG;vs2o*BCƛ]O/(ST֚w^.#EƊ( Rrfv ?z*/u3r 5VŧH3&eJ2VR} qymnh:J Ǣ2e8쵈'͓}w@Z#RCz 7shae}cZ,@ lɕ Zeچx7 iEc'CSÐ|kIh5reA^j;ߘhialcb-a[%Jۏ:q[Q4xd))gЁzkzcL.$c+N:yн9.QS;iO5s k19UG$y I-s%2>sek{VDKCm/c+hF98xCV@PB? %yM-ePoE$3p)bC)C\Ofw4A {ؿ:>u7++PO&㾁!3{l|{Oc?qYLӲ@qW;qw|yn~*;2wkV2jmqgpt}XHFW'. 18i^څ8f9ȉm?#l'~G:n%asM ~ 2h8Ĉ|( S80ryy\+RxQ.t 3_G ^q䣧Z~>/]+M kNe`珜;"k3[[I[.tL*6f\*ڎ~N^A|{ĵmrGHd21u "{~I +/Sc#,FD_w%4Kps^-G^-Fcc丨e7;Щs,t TuQwsevR9 a_e!;vla ܵ\g-Wl}E'jrmz;"q>|?#Pi/^7dϯN$BWdpyZNd+[8$P^hR긲#t|`UZ/_s |gsFwyc_p 0tvD0Lb.UW`8~kaYX?~ex:wLzb{S?e$a1ᜄKzlUs,x7:,A!cqEm:)c\&BOpkƬ{AګΨD=:s᫽& Fh?~mK#26ܒBdMSN^Yu}Lu^6I8{^^NJ@t)0-s AeKZL7)jj(jSE9aK D`Ι;Ηgcñ{{JfLw/r^䞵}̤${Uut2>weNilJNϩӎ2 9|S}wKmjɄ^ Z|J\} :K rQ RX$Ɠ ^ldLs*΋*.q 57Ԗ.K-XyG fk}L 467>YSӂw1*-F1,q&ybʙpJ"2CQQt)!XeHqlJ(qT0CE-T0%Oۂ UD`qM(<< U_KUFdžF)MB{?ݭhԴHUl`J9alܰ'g19~חߑdS 7TO-Bsϥ75\eop*o2Ƃe#LO8`Z{̹ ,c}{j;Hm-~Ea|}˒DY=៳w b,8{5Z޻K2J37ƂGk)}'W|wZ_TL$ƂSώHn"4,^lpDZd} &q7km#aՀʰBDo֌N&< _URzDc Vt!QJ.L2}$4%uSY<8weg/>Y26s9Jh_~-aIjrz;+^h]=<)1}+oB,rAxb\zOf1b 1b 1c1 c@ ݽqjIENDB`backintime-1.5.4/doc/maintain/_images/2_weblate_setup_05.png000066400000000000000000000421071477034762000237140ustar00rootroot00000000000000PNG  IHDR4`ݗsRGBgAMA a pHYsMMgCIDATxSgBJ}xԸU~!Z%ڸCB*;'Lbƌar*%L"p0JpPd22`q&"Ȇ; ~U}_Ϳ_ $ $ $ $ ~$F>B<ށ[C+ $ ?n T[H)B'OVwe S2jhPШ"j Yy=Հ{ccAcARpqc9H,#9MH5o}{[N$ZvT2*mUֲ<`}-GL>XVh@ ,bFHrldTfT L)l9XdteY z 2[PaSXA;QC9W'~p3:ԑm[-t[K'O谒/ҟzZ+Z͡5XʂZ,Emف*ުʲ4]^ 0q!ydEw ZB?nߕ$_$>(q~]㌶xͤ4])uRi룹_ِf(Ks̍%=m(N-$s=},'` ג@n BG}i^ϊpE6KaeImҎ 5״V/i9gJK{C3sJI5zZM:! FR,E[w/ï(6^v4E[_g]!+P\\ !RHh.sNȣk)‰dJYiGc IVzy|["X3K+_!K:uTVp>G`0-H.0t۴ n>dD%)!-h_ va$GW^E g[LSW,em^V>}afxcAcӔ6E U矕!ww$J@HBΎT44y`uX \BAHXJיZf-EXK&~ $ PL640(Oⱬ5Nw,!Qz[uZ}e.ؕߕk*>GY9аtj5 J+zcB"V56AK e, $q!wKIu$w:^cgnRJ $7ƢPY`G[s#6J0!,BxR\ąq2Ebr>|r0 OZy[sR(M[f1@AL)FkxBCRY ɘE7LRL_eDBv+Sp~aJ?5.{ihB*'/kNˁRaoɶ\r|Ŷ5 R+qe.%lB'$>{c B]nS R`eu+/Gh_Kķ]@wZTcp uBh&N6D&*$ Zt,$y/^T!ᄫϗ$}wKm$BQ+^iGD$ ˨yI<}I- @H    !!!! $ $ $ $!?qn #`0 %;3 bX!!cwM`/("0 [B`0lBB`0  $0 `0 B`0` AH`0 !I|ɩiVxl $Z222> /~׭C7l]CK`-$ӝvۺ/:a8B}qÉ+ʕW3c ~/ҏvAHikvg2d~> ɽ S׮sFpcݟb$ 3W2v|+T3k+ BH\~2#iڡn5~GFun޹cR'⮠zN|"Nubo}wG6^vkYvXU rz@U ZFH'[Wy;-W^A*v~o[}aI,IK!iG^X*oA!9s O*4!?𺪅D*MPxTO{}JZe6[N ;:}Q2Fr ^/}i#i=hڀOSr)o,Լ}TT6`oI0V-C?"?4|}oK:!u>vG*[zƭ'i񧺧e!)̀ $ke2t* ү]!<}}Ywkv3of,(fhM_-0?{z[,(wޓj=WE YhB[le"?)aEg^q+`FʎCajq[yִ"1uQ1`*!aMa ɧo~JW=̭꟒owNFA{,= yӮ șzjPـ;´^z1FERH2~[}Vr:MݡzH g*]uCݶ*/5> : f $v_}^ݰү_oqWW$M/;f7ߔQqRN.B~?!1e(@-<ӯIH.^%Α hxBšHV i]{Zv3:+?/l /Zրghz.2,ףހn M.Nß2s=)yz"Y*WX !Ykק.vv_cUE./ů⮐0(ŠD++aB_I\R3QDV'hޝ!"{B07\:zYuB2=PQn&d1/|n$KZBBgEjU7 &(-Lj]HoEL| !6MHyB8VCY/ r|0d~xSGH{L=}ߵ3e"S ÎbOjOH،0_^D!aQ0!Q'B2Ua!QL4U>8y4FVCH` ӌ̥K:O)sVHFHޣ34@\ar>KT')ُ%#$*  _4&yMEN'!$|*-Vi+LPOmؘd;9X,j\-I,N]Q1 !Y!aUa0Ibw\x)ktzBB0>⚞񹝷~T5J˿DwLb5tp+o]瞜r~;w$*$cw{KG$l: &=)]- $V{GM}tՙ M2UtߝO_+n:]6NzZ)$; iYN-Zqֈɻ~OA}05jznYaNbBž3uyayr0ϑ0vfueQՄ?& C6bN#5?o)U*!I-$y4+,?z.+(LL "3HdhO $1fXBBa'Շ0P~d==qJIjƙT"jvK؇뼾= $0Vs`0` BAH $0 `0 B`0  $0 AH`0 !`0`  $0 `0 B`0 ``-!!!!!BBBB@H@H@H@H@H6YH\@̽6'c5|+,ԗo(g?] N|e.ڷ~Vm8?l0xaZV˿8j>6b^ m!1^el#VªbH֯[j urY~L |ĻoRKkK*SPW[vf%u- G3f>lбIpkZ:QZ1lqbAbSFoO JQGKVw8ksvMkBWG+PT hZ=&2HF=Ňf,VETaWQ/8l#E!ѧg*_yM^Q'Z bb6IVCfiA}v͆*6xݱ/BKk:pɣOV~vW~CS ƣ4NyѮ f=HY D:ȷ+ٻFjy R$e#"HVFi -:8-ôEh}I 4s]`:K3Kb-.,06+ N;LKt2QwfS&DW3wg{K_P/fG=ď5V#W ƩY.{H͵rU)Ijo'=^piȭ!/%$Y0;x T)QlywcUHP}F?k'}Z>ob(CIxJRF$"-$*U^&/ݕѪPL#heͣUr]DHW9\e>'971G;7rm I R@!Vo@H"ƈm#u̖D9(*v?R )̑/u4H9,FlgŤ]M]Qߺ} ~}(Qpsx%$f d3Z!C6kDҸgqe$ׂ} Q$!#ќ 1:fˋ;̲kzmH#zPz$<.$Rh"i{4;WPɳ1ݙsYQJBP'Qpk1]읐"Z͇"$oڢ?cJ{V |goUfLBHf]#gQשq5l揁T(E0OFfhb61$$U bǏ|1[^R3,òn^-'y,kOx~EH,]N+{'Åv!Q(҅;V 3Yh^~8J/" gT.҈|R>M6K7]a9 :IԘS%! $B[q|0i@5˱xz _b[I:[b0kKy:i&}.X0)!QY9URb+R)By /m $)F{r-|VB6A  $ $ $ $     !!!!LNN~嗧O>z'|R[[;22VIBcǎ]zujjѣG7nܰZOG=`Jv̷υmϲNA 5w_ $d,"2ϟ퍷ڐ&zsY6yy;Jr[fŢJowP )Xgۊݾg;$j3Ưv~y.ՀR s\z5 N̙3qCjp [,8\]l!t@HxBr驩?~<ƐEQWr~WK)砑 &Z&TcbsBSy]tT 𼈷!dhU6Ovت*]=, MNJx rWD㡲Y *Ո[El{ +*m?eMzf}lIr4#.=(qt=ՀZ#5tH:XdYGOD~j-8ZM*K1'H#BJ%XYjj^af2+Z;Jmq[i7d[NJA|&,pI"4 p'B!9zGbcZnwIRFCԧgf7,eTdj6zze,aYmYYj#MHlGWkdZ䪿,*\ʛ2+}fyIW}-tP@2ri{ d"|15ZWo{ٛ0\zr9 ?#bVlUꭣA-[AXܽ(75ִXm3&eC\*7=79i]"̴݁ȡ-V.{B.@'T'}KKȆ~ԃ稗k4o=t# I>sWуHqkޏ/ycxKnyUdB^!qF^' E94J9 5,_ [t$tBm>3\ڣq>R>fˣ5OA J⸶BⰒ/:O'"$a e{T7r$"$ lJ$-#rcdcVHE9{BOKiW1s$A6N<BGdB222bZh+|嗗/_N|}:Hv壨W Po}4"aFR"y6mB"'K7jk,}ڇт}t曚@MS"fsr;9!Y1Ј5/1!Q?C~BLМfmk%!?@H6,$O8)\/NR\Y%-}96ò Q_ggm=}5EY[E]3&qTXTpE@O@ 4'5 :; :zS/`KL!ar=@_V#BI땛tB£}!$$|WN͒j;Aji"v.2 sk%$1kSHּl*j2֧g*Zaao(S/2fyeIjCoVъ]́6-&8T|X>!vo#!VkHDH$_E'>T+=Q0+ lPhK2}(Q\drEM.ZPl_zM !Y 8vֱc vy;-Jr-k D(GdmQ+eAJݓzR)Pwfj-)i*M1I d$Q? /$(gG"/ZN*, bJ+U]=i>wefr2%c+ޤg"s%F=cXP+˗ `?g Y]¼JeS :㰅( } ɖqFmo7XJf\ .%Fj #$BuM} Pϡ+ *mu--@H@H@H@H@H $ $ $ $ $I?öSFNz/zW!$[2:6D^FFO~*d+owø=w8 7@OFO~y*dˁbz2WS,$_~ӧ='֎凋=!I~رWNMM=zhvvƍVɓ'xSPyEVfº=j-۪*g^"[iF~XW-Z>fC 8[KاX\r.Rk|: )-f $j9wÇiAF'/B(6-.=iǻ6^'u(}M&.v|?i:=sc㠗˿ߣswX%Ffa^[xXwZ7b[^MІ>b_~5+zڝh՛7̵xv5G= *ɣnbOnrx֯/`DhQ2 ㏣< +?7ީ*z=Ͷk 9?:{p)޺e"_! WHѸٕ[ M*,J+3A]ۃdm~+~Lof#nccB؁Y-T^7f4![qٗP}B1իWpf3Qy̙@vDaB"ߴ|G+Q:N*1.{uoDK]?ĵWߺg.Rϥ`kfɞ $E!yncө|[ǰEC6!墵]SSSG#O9~8|X]GcQduj9_2Іz-5X:KZظ+3+mie] wެ\Po/۪a|TI13x4nb3tQEQ~2/{%[>6*o~hsݗ>B|¿yNrέ}>?Vfm_Pe46DJ>={|@swD-W2+~鎶a홈Dm$ [1aq_f:zHE0IVܘS~I=y>Y[BBѣG#uV^idRWG 58a#mDHVFi {xag ҏ\b+ætNze4^cІ/\"|-G"^~֫wGx֯ ~wO\"G5WsYFwaZ}D E7 ̴ѯ#&7C'ťm?\d}'ǚoDȗ;ޡ r0kV\r"b`A=lridž&h4o#fId,$<BXI]=t95 CiSWjW.iEG$,;ŢX='ϟ n~-qٹy)g8t.\"!GDUyJ٬79=V0Rvv?;tXqĹ|rw/F_ ;a='$հWON(x>j>_fzJ'oOp]^tFmB Ώ1VO>dvvvrr2\vs)2dI6/$3 jٔGj~pmUrĮz&aiLSwInCiǜ;ΊPcnux%xg8@Y. ƺ"EfFzCw}ÉBɧswև~%.ֽ1rK,*=wA\\||2uĘBLJ{n;KbҢyM[wS⢕$ m5HL!I+&39<]٢ |X59R}8Ol4/v۴6V//%uhkV6Cc9^hzOmBlRA6衫1!yxO;0xA~]Bc:Er Ud&惱 XZ>ǃs4*Q77JtM^ o\w&*$Ą1rmZ^TP9ڀ),ƍCEEE|>{ĉu$XB*e+\&J[XA3Y-_d=K:#WisDv :{kD˯!%#טQ@!$UJ7֓WY $4C_?fa Bqdy Imd4:!$vu}BU*]5_8&[ )opE˨oeUs)嬠̂yGM}YыQei =!a=^_9WOOF;yPïrw[p7Dc^=uPq+C.7D~#V/jբ\ُʪnHZOƚw׍hkiT7sB%׋OJb~j$6߬I]=)!ڕUK+GK:߄~VBbGLD4LD;Ƣ2̵WTSlPK .!aW~s'+BkDZl=K@SG;ڼf?D1F|t!Q> %UݢBBf?tJy)iJ(hg /-ĝ0HyL% k)"V\Y2e3ĦW,-$N\ =kL3@_v\T ̏?x=o}_̧}nBy:{RԦc_/'0+]#4?7]H5Oʭ~hK炣ͱd{]=!Y=t?ˎʃJ!Yt;*c&'i#dH}}HџV:{\fy~:Yz1wwY {R&ni<[zr92 K,ҍf#pYf+g<{ jj.nLg|Y%9.Ȼ}RR[1[<V,^-PNaL_~aspSr= MQ3+۪oTw9^jZKZl'q0:iꝄg3"Flr=T!=2l ٔ!ymdci);vl>O4%}i nz;9:CA=)O/{=aU x+26y}={7v=*BBBBB@H@H@H@H    !!!!!BBBB@Hl=\`0,ÈB[ $ $ $BBBӧ}5u_4ۿHeH; mBZi%VI[?HH[#톞 xم°n#G2 ;s'PiIҞHH:7!)4ҞUq/$#m xW7H ^X!Xdut?3C ;3νc}.sя/\~bxV ]Ͻ+ 9BR|Ҳy^rGeeⲒ{\+xIHH7<}tkjKVIUlpewVYIAG6{O09B)*YXY+)*ٹJ<1ix|JUvn خBRYSzx09;ٓR:kaBmthvvƖ);<pl.Vlq1l[ zMz'$kzg/,99c.kOisT@,lI خBPoVD]>ama:L⊺"T*HӢ/hvXU#'Ű&/AQɤ]}(F:4` }sZ12 撃{G =(eQ=~T!!ΚH5T04F:4` ɿ ѿ{Cr,(z{hVXr`͕ĄDW&r%F:4` ɦeڣH"j@UgQTVibDb9V>ɏ H, xՄ`V BlRhKWdhvYUWn+ I86QyXHRle9P4K4xX[hۓh $iV }*\5;rM\.:CdyYVaQ.BdkˋI4 ĄDW'jOY!&e\eO7 =fd L@HD6DQKeEIwm)qK\MFl,%@k|ܤ$kOc^މc/k6a<p6) )x/_Zq)* ;/)ڐ[Oh'C%@6X^xd^K/lkax<MV0c+/$WWɆ^a8bѕ/\~bѕ/nisc#$&33ڤя/:ߟF'hBB_ 3z0oFBq "I hB=uE/y\™x鄄s]SZH8->i{z/i1G !QӾoʚoWo@3v Aڄ iJx3<BB@H@H@H@H {w[tzIENDB`backintime-1.5.4/doc/maintain/_images/2_weblate_setup_06.png000066400000000000000000001766511477034762000237310ustar00rootroot00000000000000PNG  IHDRv>osRGBgAMA a pHYsMMg>IDATxWUǺ\0<| C.f ! hb(6{{QQDiId}wvNʜs՚C`,֜fU|fͪZ Fh4T7fFh4Ih4F#bh4Fш4Fh4Fh4FĤh4F1i4Fh4"&Fh4Ih4F#bh4FhAC>0i4Fh"fdz jC4Fh4?&|Y/%1Ci4Fh> w[\~ǎg_x;Ǐuև[wZ?M|?OGOuh4- Ĵp.G>aIYm~gS?i%Yf&tg/65k}'"T1/ݾ} >zj|ӅܯSAhc~?M_2?lh:0Fho)bOV.=!:]V㿆]KtFsO~T!&N8_ڟ.w"1 7lEW0y'm!ELNqDL3ry#&\g:zn4̜ᑱsdCh4"f/-)站X>j7|0|L=?!Di޸ 9`9y;Diwy̝-byrdb @h4㎈\[f^/o#¶g3wX>ϭg_myn㖝7o~@ȯ^8{0ꈘwK&1Y^hAmU/p2..]HmV3o:d)2VA. b~Ǝ}//#]Eh;@'/^7K?#z'\Dl-#"q&U.(5  d#ʶ2Qڸm ŗ8dJIT#H/^~m(K8M(8oKh4ZݤBƆfx܎3/p@>ьEѕcznزKL?Ơ/:Zz?!kp9Sg-8~ŠM+>!=9 &r'ۼcߤGN"Yw/ҋsFẍ7OJ?Didqr&,,"=/-!C>M:iF{t pB{,XB|%SNQxqp8=#DZx8Zw Mzv &b>yxAn (}8b,"/Qҧ.H/_iiWE¼wOe iGz .4dgoe[4F{hY>ςZ?R# _~\̯ 7~6%6azW_ \K4ѓeZ|ZMeXsWZi b"ˆŒ!+Ks h3 ̀j.̜X_b?O#$tLaO|n#A{z`) NH ~\o},O?_9$jꈊyE U$_("2;Inu5P:Nfq r֐Fhl //WÜ̏N(߱@] [vV$N YV 4K|z+ O YDsoTX{_0V9n #qGds(`dӠok7qD|8qB$嫯'NNzZFz^Ks®:|;87Y/t㿆W<&9#1=i1%}%\NhCKvXDw˛_~?GH5ٖ3rt2-WŬNwmFLG[O;@LKҐE/t(ouL$_n@ḷ1KnCn6?ٓߺ@5J 綛†"Tp>iߓ pnUiFOeKԣ(Us4CiZ*FhG_^/W(G,:áEݟś;ѕ?t|gڽURk1!U:k,ң20SI(2 Gc?R{-GLvx]7s1^O?\V7<26uv6PO|FUlCFYO_Z6zF_ĄWȔMYbʄ3yp•O~Y7Pǧ<|[}I3^_=zǎ]=`˵7mH=E샔2<$8r4ob HO|Fn#ݜ+bZlܱ>x엯ƅ^N,vYd^>4F||Q?7iF&HTjyRvt 't)to bWDAD$"qxC^D/-A!`SgF~BMb}I}_U%2'ezeZ"ߛ1?m,Ĕ(Pksѭ;-xLBiSY,e_egNoci4F{r7fGΚL"ڍFt dzpYx7imCLÉ3OL[\ϦIxs9?>}m5oO.˛\G /_? Eyʎf}O "%JabaqY[,B%KܩN9^fh4OYsN?GL^OP78gorO<ŐO;braSC`P "7_fg0lV,g]TߗFh"_^m~I҂E?:>x|~H?o-\ӿh4Fт4Fh4Fh4FĤh4F1i4Fh4"&Fh4Ih4F#bh4Fш4Fh4Fh4FĤh4F1i4Fh4"&Fh4Ih4F#bh4FhDLFh4Fh4FĤh4F1i4FhA̟~I[g[jSEQEQK/tu~^}-EQEQEG|DQEQE1[w8~IQEQE1/\gPEQEQAC̟~IQEQE1)(("&EQEQEĤ((("&EQEQEĤ((EQEQEĤ((EQEQ(("b1)(("&EQEQE|mC@KG%n5yoAQEQ[=/85c rؙuj Rm?T}РAeP_}5ޥ_̻-Cz (a|S"##.]zM9s87 =yf?z n71}[%IQEQb^099ϺOU~)"&EQE1\8\[XX$ .ii&NH  r|9|'C;M"͝]Z#h{BL0dgCT2FOAzCdBj@N}R|ł`_}Gv0rŔ<3#拗_H6 Bj'G1uoʅb/=ɓ,\H`@L[PEQ50+(X/a <5iO0Y'\1nwу5qpSMS%zƌ#2zfļq~ZZZ8>j8a2gN4YM{tQj*1NT2߂(V>ZxI˽Mg͞ e>_c.}$WLO,Vt=XfKMM#y~Y4cF̋.GDD8y r!w_vLL)Tы1#g ë&''#RǸ@c^~>HGL< Fʊr͡C~L8!##sРA8 nڿ!6,,LU!$\5 1G[H&GFF9zL%!**EE]e(w1G%s[`&9:yb_sc"ʲ<}(Y;s,YcFL:kbgBn^QڬrZRR w˙Gxʾѣ8 8:P\\QxD&---S` 9_u:u4 ٰq:tQ$S!fC-0%YfX[z }pOQEQ b*wzm-:(pWr[xzp1B8Shハ %prr{{<Ut9ow4"O S7o 8.EQEQo)bT:ʍdUΠ.(("bzUSSSo׿myOĤ((}DLUkO5RnY7vذ }zelu(EQEQ(("b1)(("&EQEQEĤ((EQEQEĤ((EQEQ((EQEQ(("bREQEQDL"&EQEQEĤ((EQEQCQEQE1)((Fh4w#bh4Fш4Fh4"&Fh4IĤh4F1i4FhDLFh4Fh4F#bh4Fш4Fh4"&Fh4FĤh4F1i4FhDLFh4Ih4F#bh4Fш4Fh4"&Fh4FĤh4F1i4FhDLFh4Ih4F{ǟ~:iᵓ_^>HQEQR(U PEQDL"b 1("f"W_sx ENⰰ.>.ܽgﭦ;Nhx6ujʈ#n7a //ߩ=ڵÇڎ=s3PР_㏇:^^P2,, 'gΞS= >Y)\!&&m9i[K 2fS{ݸYXިڥr 9$ђTH6"zyWLNNF˒pT2vsXTܴ]e8W!3 쀋or KX+Ov!oWC/V%rE|(у]JQ (r˚@.šD!T .xHՑc"$Ob_fKF)2܎w1U̵ހn\n5(zbJ' r<@||<=ӥ_ٰq:G4 &zDM DLI 9OAL6zhD, ! [V- ;;7/_CN%KV@._(䭏>3XV|֍^u^ZyXll?ĴE΀Ap >l~ T!sg9Pÿ% z=71ݸS4_(wo̢ٲulXT,<<\: :eyEaaazb]-G̔#""ϩM[@\Μ5˲zz#,QZ*nTsDLQ(662*đ$, G_})7Q 9*gȺWx9{.6.nry`#9I8Vr=v$KRx)bLL ÒX_S@ CV߰"])J ׊7:aS`JoE'm%\C##+~٨VHiDƅGFFFꈉke"x'::ڂr2Xfw/]NNNV+|~]1UG+WZOSYZ(w1 ;v^ٶ9"0Q?TE_|Fo.q}R7pKmZDHy5Mv%nU9g\WݴHR])[B94r(<"@Dg\YY% M]`"&BlZYz˛4g L>Vx$Gv9soF1q#IP\\Bzm$PዲCBq!(ӂ2ܮ23"Úk"&*7/_# z_y۴^̮w(ɞjX('|GDi>(CLM!w6lRў6q~ʔr#I$;{SF2Ծzzݏz>9}˛djU5'WE6/zjKyY_] SכKi>(DL8iܛ0q;3NKF=- >>qrB)D̷E=wZ~}~qCL1wMw'bREQDLS]/]z%[oTdey[nk!(("&(("bREQEQDL((IĤ((EQEQ(("b1)(("&EQEQEĤ(z7Azћ'!G6BAOOOey^CF2--uYYf]?x+3s'Ϯ][/X?Bںm;_sEQ'=mk˙gΞ;>{|BhʔAoB- zE  ѯwuΞ3kȽ/rr]t٧q={ lԔ#F4n?xze"]Bg/\ Q̧O ⒠ef]r5/Q&Lcʡfnݱ0lN9=^Zg}h{Ϻz**))):Fk(XD#k q@+"UUUgeoR ި3ܑ$D f}C#@ALȢG 1A'OIO~Ih܌do߹ U>]9""’v5>^B1)}DL4K<^DGuRt^BcHwm/^~ =p _uk_,THg9|_zoNpJѳ;v;wA,@txr8BB2Yyr %J k<+˙v"7x񸼸le4H?\elDF! ܓTy:$భ۶ 1`MmJ#n:aꃇ U>}ZZZ#&rꌌLU$<[%bR99њDFFFD|^^SPh׮-DGl˽3kȪ—˗5wnFGgW( ^PN@1hhncZ s #SL](AUUGw#b5q⤃.:qC7RGPGH}& j1 I̜G㸯b C \/Tԝ'Lϊ4) t € H%dڏAwO/ݠWĴO U:b 'bRҽ5rvs-A|׮`/Eۚ\N4:BtT|QBSeGLVGǓ&M' OG1ѐ31qk QM,$'`n1)/WX4'%W`~ߎMBL4F6nC81ћoTP bJbeћZ^J14MK8w [VS WcHxɒ=D4= 1=EߌC7-VחIr_{C7_|HYzA's2/]2b1-E'α̻u!r ~ܱcQs\oRl"t.B>,W$}PZƧS+ժ Vf9G_"X9gD2N(lwt}Kv3} <-Yw&N,X ,CDL"b뛌LcزulXT,<<\i}&lYn^aaQXXN҅)))2L5Vk5{`Ր#YC^2~c =GĴbcc-$!.݇Q*v9MȥeK*$NGĴS:ޜ1 3n V.Bz b sP\:>Ae>f_Eysl$Z>1] ٗXbJqʽ"&-#G!4}ŇQeUwThVbm/B$ ӧ֍x1;T+?Qjf7gˢ#rۉvt?z&C) t2Noh b{"d5w; r+D1}rbO)pFsԨuo]G=> DL)Odn8^ɛDLzSV B;&OkBݼ(Icx1-샂\g9>w﷥M m glOC!=- pE9} F̾ڋK>rj j˽V"כ3(O)vt^;(S 3.1ku7l݌UUh@ft1#1܃+}ZlgFLoK3bzrӎbWn{~!f\ܧ._% x|hD/^: Y/e9ڎ8(/,,rbJ+VH^ |BL̞|j7-v;Yɚ=vMҍI-TQ?&&%"Z]Vf߰=7ߊrY#$ V|$_ QK 1 .LBz3bzRlUFFnT$''3sru JDЁ#k_-ő^%\n.Kd}yuP(m鈘}vAuFBVMj.37hgFLАK+K bREEkv@C>"zMZgIhnboE'ePC-WbhWĔq5M7XG9sڗgZv(!E᯼ C#GRDL(U1T b\m-$@.^'˟_o! z5L?^;vbUvriQ]1t=rSb}vP8裆#HTy$9? w1pĔ6a߅(EFWf/pՖ+pta?DԖ[=svӦ`X{dz+ iOϫKYvxLŶKE1ڻBv *..k;M=/@ o::gǙEQ(("bREQEQDL((IĤ((EQEQ(("b1)(("&EQEQEĤ((# ŲxxCGk|ޙ O2gS&b[T4߽ Ƶ+Vsp##]wJ1bJ}hkTdRmm/\2ǡYwVUUg O4\ uxP{ɗo~!@7D ,/Tn++Fx{@w7$:: 63>1n+WW!DLTlvq /66צO &ܺm[[(@}pbhJJJ+dNzFD=d3w' >h,>š>>4޺-'>a׸YtKkn"f9@"| >* ҎL@T!fMu'm]FB7"z [xFYCHbL܁)FlgDSnK;("c !+Wk"!f׮ݪ!1S僇@WT4MU;.WG1Q-툉]+W0uN&q-NQpBO[͓'O9kgGJSLĢڣBhy|P%Kl݆Cjҋ?6LA)SZ潙EpɢE9x>$> BE#7>!f} cRPTV:yG2_(;3m|ͮG^^iV55OA 4 Z!im_ ]椡n ‰_;+sQƹs3$(n굧%=--]Q>B6^D=A@NO>H|}onZ574d2b!U3&B$5W2y~|Y6#f9(%ܹKhGZ#Wu72MKeG~īF$˴Kek_*#j<\'''҈sp-[%I((s1p9RU ^0O*ㆍЊ929zL}E+ SQQ4 Ҡ/4je}ڢհ_ |@dR|#`TcDQ裴t!ju_4]7LK+>ı@2pjx@zMU P8/>~+" W<#+zELK1RαntfB☏JV6!מ*8z}6{ E?fV57@pۈ ꗼvرcL\p/emO/".@샧#">D37VPZ e!!8uOsQՙO+4~z?UZR\d.U$ba׽h EEKMRPI9,,̑ ̕&pLII(jI_JjtӞXȽ *zi9 ZF%8vrv Sn:H b7'Ĕoy* 0Wbpz9|'g[-Oǣ^ҧ+}e\O~T7FHGti[Gf<ԸYgo 1]6bXj"pkyn 4|g5hXpj̒ poŊ+Wk,Wګ\)4/=[_{zRR1}*Q~2&1o^.z1uNOGqO:#&jѱc'd )C̴t[tTsJ6T"&qB^]o;=^p?DC׵xT"RlB>7SrlsͮW#Q7^kn@ACYVwcܹ@3@1F7@Lu38jHLtoE9HJ׬)AחE?bB Pe -XNJr{pՀoK7n\c}xE95>W8E|b:(7n굧e?Z9zqaj9ҋF%#SRE~<@S-@+,o؈UWĔyo"+eBy~bʚ4*^")xpE ʗG e:]kO:h!2Ms 1%Q%WȊrמꗼ]ψsAjAj$˛`!K*ZvT4TN:4tP)0K ?ϝ cT䤌ر+))i>mRbTIJ72/'(4\)3=f+b"(p˥xj}zbDzzKRp dSk :*_! >e3f|݋ZŽhv[MwMxx8*0/Ћl"/>  ;TG\kbg1"T]z B݅EEɂP̙;S+6-(mk;J9J{ 1Q++Ԏ6WDȖ0(/..A62#=HdEDDGijE| [w @3*GALDi{:tHwꦹg)2S PΌ_~T"B]/A7ЂAr<5暫Hɲz>J_rUj,uR,K 1QT/ їeyƘoF`&UAYV{S%:P2Dr$"CKqd,'g-C(F1-'OVQuT#d5J1l帉:6nxk[8R0w=m6getTW :BOkϔ2ͧFg\ʿd)ɞaW}}=}\\@.!CUU2> CƓn.CT{lyjZݸ| і ߀>vU0vtWQ/Ϳ}WHn@>ƳoEĤl<`8mѷgC]}{gڈin_ksRS=M@ 'OSɯ,[9R> M,?,-("&J=wo޳jA GaaQRRCqO!WUUȅbȷlC/"눏oh`3gG_ I&/\_|7.oÉDLjਧKSx՚ـy;.Sq5e@: W7(C\5h})"&(("bREQEQDL((IQEQE1EQEQ(("bREQEQDL"&EQEQEĤ((;\a#X5䗯WQ~FW%벲W5U64̜~Y'D?$!Aľ_%(FHד{gϙ599.^Sp_Pmx6ujʈ#n7a //ߩ=ڵÇڎ=s3PР_㏇:^^P2,, 'gΞS= >Y)\!&&m9i[K 2fS{ݸYXިڥr 9$ђTH6"zyWLNNF˒pT2vsXTܴ]e8W!3 쀋or KX+O"bȜ-8vVL| ;$I,8qҡGLQ,>СC U ?_(*E2u{Rr=8ojk\/a˱qq(QD*OGȨ)S.Zd4VU_TyFk}ii`xB9rR\7ךGQE)FH]•5a-Ϥ޵k7zJ܂n5?@g&/<|8XbGLm9"ؕVO4Sg\e31q<\C?mH6 gJn@̎.IpmxYf}ڢ|y%[n!5CEw˟us Ce^ZDL '/uFg*dzCw^.*pܹAx@CiDCΎ2r$fb̜'O#x!UGƎܓ8 ?g~]/*(zGS\ p*ԩ) Ou|}EQ;?S:QUIO.ʆБ81#oTP bJbeɑx b"ѣG > bY0d)kٹyddR|*"b+2sG|bC꾝ϺKb+5_+4v{ݽi9ωN}hĩB19Ϫs,-KzF!&H%&nj#b"LD<1їyk}uEQ-Y1[n K!zACg,7(,,lBOxBLE"boDD9i 1::˙fY zz#,QZ*nTsDLQ(662*đ$, G_})7 |IG#FFmOp޸YR$a`.TOP^=!&D :Zcu|WQEQ1e Ϝ=m{ b<8=}zMmݸq-G̤cNȦ-/{sôE3--]q1 w1G]wWFAVg_xFd C}l{Uנ6YƿzS3b@A@j;U3b%bRE pJ8 zj /ʁq2A  zY}%JiyeD߯OdtE^7 7iW,cEy_U9AJK YUUޮD'I!p q_\DA^Zݍs. +K_7"^͈:bdOu|}EQ;qq^|EÿPFK,g/^:Y/cyl+ FL ŊjA1eOjj*HG-k 4GDAz? 4:|DvJ$WTk>mƐ7lDH+bʼRӿ叟rj\vH#F@@]HoFzFJ# 0.D&>r422RGL\+;42ļxrrrZ! z7j=-XJz}tl\ Kg=#y"R_v!%!9٥Z(w1u4ml5ڰsH6joF{l)S<]mnr?޾+/0w|\Q}SױI&{ )QU~(xSK\"zj,8\2MõfQEQ$bRn9N[|GuބߡYw_2iMHQE$b-y^^S {C!̘WQx a1)("&Eή.{H7m*]dܼ-[k} KEQIQEQE1)(("&EQEQE$bREQEQDL((IQEQE1EQEQ(("bREzꛠrEQD̐# Ų!A4eԠ7^sUlVab׊{gϙ599.^Sp_ ox6ujʈ#n7a3+@TqT'Eu 1VtW}P>0/M%QGu9BJ$zsG񥧛=ٱc׹sĒ 8Hw'y!'$X'ڠ^$q"/i'rsng ˋK6Z0?\elBLђön,D5u*҄rs>}`ZZZ#&\juFF*1)B̜hM"###"> //ߩ tkuO"_ѣv^_ <866S19km}:Aollһk VWMZB5f*g=OC|}C+W!||iu[MZxɐ!Cƌu`qier!dD%%%! =yttt!> q!WQ7/KpT2vsXTThAzњe8W!3 ,],ġظ-|5hQ)ҋuE# $AAM lVB>L@n pP\Rw[>0>+FgҤ/ƒPg)D2>!AoDd^&yB:QP%?P}y#fpp"&E_):iO_Z#Gn7mLFv R,6mk~r9S4UvDk8|(n`|IKKWB8KR51$=z4Y e,SQrSdJ 륄#sd@9rJW2$ ݬo>U<(wp:rILs1W(T+U2fg33Ƀ(|tp2yn^CX_ݧzM!1Q=|̍)1)/WXk;4>>^E<;6% 1mظ iƏ'Do~SAU)!"$G Dz)h7-5+oZM%P&7/_!CN%K#T(f C7lo}/Jn܇ s2N&d^t1rUX]_:^'qǎ]:))(B >[Rp\lIBo B5=̉w=w1QQ|]1(ڍgjb8>Y-SSSA&N,X ,.E7Ae6ٰ(Xxxt?҆2 `ɃOi,s"TO`h!::+.2UCb`d{3TrwtGBƪLF~#|7!.QO;N!xsƌ/T\XX -$Aq=ٖA,}ziij2k"b*,6 @/ѧDL9ӏi^۲DQG|}ŇQ/Td۫"&EѬm^.-IAO7.o?b&%%;vV:>>woHKKEAGL德1A~LdSF7!2deZE@ɪk;v,@(W\bz)ŞSyBL7T} Q4=9z1}2w25$9L҈3=IQ/bCA(yiM8it O!}Pl6GT 1=-U߸ ?Vy}:denB^(pO߈ٷ[{qɡG\AYm>7Bz3b)Ŏqx տwr^5Z1dku7l݌UU lvKH8"WĔ *,}Dw[>-3#&r 7}v[O;_"bRqq^|E&ÿP:]^YxIXX$d1h;?ยqޏ)XQ qCT{6` 1e2{jjj{ݴ, @8d%k>Ԃ6J7&iHPEtjZvY~F wp+eQ*(X)  {!@S2?~$D7#f஗)vΐXedd&JErrZ:#y,,sru JD!wڍ\cڵ(pQ\-/OZ K֭W\9`L/6 &n|Fiǣ)ZK;bſ5o=:)dHmd>jv1F<JzՊ+K bREEkv@C>"zMZgIhnboE'ePC-WbhWĔq5M7XG9szZv(!E᯼ C#GRDLU1T b\m-$@.^'˟_o! z5L?^;vbUvriQ]1t=rSbCŗJA5DAb#@7zQVY:`G(iCpk/R$otevҎWZmi ݾsWnhշmo101LvCL$Mme|>3bJ.--Cf#ԛoǭx ۶Tje$OU߸Y?eTO9˵Ӽ=_W]{wpt_tyw[d$'%Vx]/S{zgO!K@?}Υd{yqb~`y2qx#Q!{WXQb/ c`FĂ'/\s~,I E+p H1qQUUO9+>89d^jOQGN;N3M-êa+K $gG/**qvҕvEI#C36)T(b*]maE*z ]͊_h~Ɨ%/]ٵ{c|r&ؔń?qrƚW``O;/],WTU Q55&ᅥ(J1b* P={ej =cC9pBP(b* BP(b* BP(b* BP(b*T( BP(T( BP(T( BP(TP( BPP( BPP( BP<\~H{y^YT8nҲ?oVU1cO2_T׮O6|%CŃ'NnѠǾPĔ)S͗75G{0Ç/fM@ G.Ң EUR̄)/,i/ϋ&sܔ>J7xРAܸ 𨤤;= mZUU{hlŦNׯG͜5hax*<-865@"=~B5[}@EŒ ^MK ~<0$W[Byve7cĖ{6騪P(CgDDGG'}<<{2C kll-c;!sZR~AIYg;-g]oj?`6446l*-7<2xZjk7qA|TorQU3æhޯ߼p5q2j Iٟ+Nn27pO\D0Q T tϾK?P pyq_dKqCx ?4vb}6 7ns^҄,LV5Ƀa59nev^jqa~ JI7H~yzj^s]ǵ/ɳ #DbDKWd1GU SKr=T~QjdeiӦj,WI?7/6   5]go=DRCSSSۧO. 2{P4Gd \ M$3f2ظ@m YyʔqyݴsWU#F^JE&m_r Y%<΁=pV=nTS~ T''ԲAjZ'nMq5YRW# mT`1%(G7K_[K1#=%j;B cF/^6w>່.U6~u%L: HbAw)FU+!kϨ-y&Øn qp铀 Q5_h5sP"O;K#f] I~b܀O'"3)>g;p/%+Vv>CO}=f駘8B׹a<,1` u×IPΞ3jk7ey̘'MH?ax/FRXF}h<g ɒu[dfQ^?%߿#8бcy9B1Q: ' %W^J^:iuc/kv~9+[ݴV=~ Wp_uOAn0!BaSsֆ}]zMoj(Im YrRӮ L*bPXc/2i>o1)UoQ³=$ RT(C!FpP(󠐤Gb"7?3[NeXZ1rd;mEÆ jxeˎxM K,ӎϞ;oU rWϝ;%z$U=bҸLmܴN2'`?S*7/fjci*qx@~03=CISL),cG)A|Xgڢkx׬ٳp ,ZdN*o>#B]潸{s<b=YB8[ p{@rU߫*EVQQEP׸y@b/ñ(*FvئژJ0Vj }UD! ؤ']ٗʡ2RUo:])R0rSaBcbK`_2}N8g\69S̈n9}t,%nvV,jy(2Xfk[;lxt9dP3tJ/rV'U8h5 -Y**Lr׽R5iawЀzvvXB"H/ќ :,..(ƴb*qH2=;0G,1j&-H4 77+i$0y 9kGE Q̤V9C !M{H_U7c qIx^K1=rŎR)oY<0tWDb#"@x+iW(vf_=ܪ7xfUA)ZZn-qmSeSG>T'ӦM&MLfE1#{1!̑!ji7z(}{(b* 77U@0K q)fhTR ym_,,,DOس^B)f~P:dymi٫W4F,8zO1Ç4ON[LbSL(3p^F1Mc'.]hq)f\ՓkkjjNx'J9&G1kQčRm2A1E}Q:̾=Q[f8zn~)BkTMv=YS@&LjOhLP̸]5u$ M E񓂂sFVU`O1ի1  ?4hR?$+J1PIxn<4@9AHfldRK(g>- qCN[Ln\ΤB1Æ̙(?-7Y?6$ܯzb:(fh9(zهѯ&A1]1w<9Ɓr9 (˙(vf_;rݪ7k~wAK1evٻ`ȐC-:\k\5] h?l,3 ᭵cQQ@Z붠将Qlz*Hh$ף/&N8 y7j{{oݶIwþ”P޳+,w#ve,)घ;ٷo)t2Y}<2K|{+eY@yq:,bRƖe}\eH*, u7Y ӍK1e[`?;F,]VyiVL# y~Ŕ5fBw+N3E]O'O% PLG#E p_Mb21/MwIb1s*2D D0aqނsXYV3E\EB?49YZ+kkǎcAw&G1/_YJ1b*z^9s{*7Bk[UUٳ!+vt^P1ҾOML4:0!]ݜ"i-.[bƌW WS)BP( B)BP( B)BP( B)BP( B)RLBP( RLBP( RLBP( RL BP(b[<],*_7wo}CiiٍӛOn\Aq+ QIIIO$nݖ3T1'-³/l݆fnhmkbSNq)PSS;b%Bk5) RςbJ@x,.wtt|5y܇f̘c򄑟;'D@kdLJW=_QlS)BP|FBF87pPհ S̸K$/0Mj;:?q,ᗇ ϾK?P p !yq_dKqCx ?4fb}6 nݸ{iQ\`yK_W #F8(fܹaR2gK7ջ)qml\) Sͯ۷o,evvm; !YSWwb„{ꕛ˳eeRx(& m:j{ z׹Z\\e˖geeq=q|_L rl{b$YT8/.-[9ɹv zRXףOBt eEXaa!E0r@)DddqE"r5} "]fW]˻snT <0++W .gW OXgTn§NƃfώNGr Ťd{@c ~fe9} 'J]Y[TU*gڥ^7c,9{.7/D"˭z5v츹sQLjcc~~y mT05b#C D ܶ~֭>BP|S F!V3tXiwE}\yab I)>,SLbCdXc:>O4O1 ;J~Y)yA1;sGkk7epp̘'MI?ax/ IFRX.<4 2t0{C>u[dfR^9?%߿6Oq#+u<bt* z]wq)&r+-- j2eQ KEv#g\zHYM⯊QC(iӥ5.sM-F$3@V kvj&wacnwPLSy˸q0t?VBP(>DV7M+7l$K$"3/R"ŔJ7ő| $aÆ }11"Y0䟶oY{Xp+L/_`!"  r_süGavy/ RظJFz>}6v\E29Q*r]V'ISLdn?H ͚{-oOd DL*3lԜB1J#Q|MS$VSW&3kO CA y/bRQgϙ{S~CƒƁr9(ŴM1؈%٦Y BIR̼oΞ;/ kP(F ,3 L5l߾+++WǗҥ$od߃(Ŕ>%%%p#"{@i{+eYBy9 Z)el9pPvJߗ6Qi|acb DwtRLW_~#G,_7NҴ(w, Ey/^FfF*0"צ<+E;Y޾m?J:IP3gr a_nGIv йyy"1# 1d缈]mA٦Y BIRիw[m#rhMdSy_0\RfruM 9D'A1e򊕫HMv?`5)Ss"2_%KC 5#RㆆFWH^jbg;̈"myws䩴(w,}k׭IrCUU5 魵=\*Mv#Ԥ&>2=3)&|qS;omZ/PLjrB᫯YnDqBP|Sen\O5z'!@ݻ ???pr{NsT( J1?zm{SKWv }q2c2''go}k~+T( RL"It>{q9{Uƍ5 ,\Txsݖ;w}+WQ BS)BP( B)BP( B)BP( B)RLBP( RLBP( RLBP( RL BP( BP( B⯷M˗ O B)f)@͢qSeo(--qvz3^;c?tdBajUeCC]:::'NopK?{^>m_\;w^C"Z}\S*&_e+nS37mqF =O:'O% !رBԗ5aBC(fV?7W̛7?++s σvq|1iq Ǎ[PJJJn޺u݈wJ-Ӫy9UUUϞ8iҹC7jhؤjk[{,:u}\_'#?!-&LߣFn_q;ɷMT}¶i$__t#۶o`㚰BP)'hxYt̐f̘(J1?̴{^38h@%iL*?[A>딖AQ)_ڽ&n#.(Ѱa; Aٳ/S:AQ+" $Cp˜W`>6J] 6y\qU!6bh=ڡ6rQLՓ.g"n{ +n9p̿-dPRLs[۲ux ;Dz*+>rdc?~YXXx3T3ܵyFiiH;48)&c ȦQRݻ…Hz굴POXjÇFʐꓣ >pJqŔmaӳ ;?ń<_VAt2Lb&ebed:\P'"O*/"{zXyb*/ŔBd^T ?qʡqt(g>- l@%=Z*gRaLĊ(aCt9lY@Ν9pS(ޭZwދ. M1Ӣz@,388PN+>v~i{7M)&Y-O:)fcc UQT 7% (=Fn߹*Zl禘HK*o汔(b"jk?'eb*2z- L]q"/2GpRˮ}(\_NbJK.WA%D1e2{IIɭw, wvYɚ>rt cRFErrr&J1K ֭@d5t' HnE,ʑUb"e˖|&/D MqS6}5:PLiY$>d!ջ)fꪗ)~":unR+9,MG * K{oL?A8xo߾ %.LQ$ Q^ClŠS䊊%v"wG$#"q^Q[CćpnYSq{+ v\beXgrr|7y 'gŤhf-P]>љJ^žQ}~)b,!Y)T(>#i;-)Ƕi9[WƎ<8EAN{6(Ǣd*7[av zƭ'ܼuGHZJ>u˔Ho9,e1yc#,QrqqF#JQ=((.OˆسF;}B΄8bRLsħ2c/l5ۧѣϦaհicByrͳǎݸy;Jp"PxȐ 6)T(b*]maE*z ]͊_h~Ɨ%/]ٵ{c|r&ؔń?qrƚW``O;/],WTUul˚Z_C J1՞uNUU5\lz 8OP(J1 BP(J1 BP(J1 BP(J1b* BP(b* BP(b* BP(b*T( BP(T( BP(T( BP(Lb[<],*_7wo}CiiY 7oΘ1'N ZUckקMի׋[8Ԍ?-֯܂=~B5[}@EŒFx5-&LȯTOnW^ 7n߅ҥ8No8M:*b4)ٸщm}=yxeD[?wқ}oJ1t- W/?} ɒxr R4Sg͞-g7dv8lذګW/[<2xZjk7qAF>\TU( İq p5q2j IٟT|}utœSG?qD%P>r4Ёv?.@1@FIJA\+F WLn3vRFd˿\"R!Ka1{xiiO8 '$K7mᒙFyq@o1)UoQsl0b2ͧSqnMb:LNPb4n ¾! I:|(+l~e7ŌSVVYcNrQaðF2MeG&%JMigϝc Νщ_mVibEEE6rwn\'uԓL|Eϟ);lmF4@Yxaa~FX tCڋ!)1T# Xi,ͳ`(pڢkx׬ٳp ,z#p̘A *o>#B]潸)* 8DRLeD+WU**r]_Tn] {z)gj\ ǢP sGKajc^*LX1UŠ9i(vf_*#eQ[lS܄5H1Ä/(Ŗ69da2pΜ4MemrBir*#XKܠXPL!dֶv =sȐf, _4N4qkںR]).UT>k/j60l4D2,*_L9+++3<&uY\\,QiňUf X=!@eZ{vaXcMZiH1=WAnnWI`A=s_s-)^jC|HRW͘?qRF<#WRLlBG[.*w+6&؈H b^T G0 V3ĭ B1mrhA8nz.r??6m:7id(4kw~(-؋ aEf WKC1m۷ߣF+WX)7d-]VOpK1D̕½HN obaa!?~žJ1&[n]MP^z7rdc?~>!8}=%zໄ6LܿjUeNN6n/|1  ?4hR?\}u {$X\c7jw $36p 2%]3dyӡ¦-&1P.gRamLbrkҵܯzb:(fh9(zهѯ&A1]1w<95s4r&8PNU3Q:̾w666UowA+HƎm rxءõƵ\Ј6q RfB+0]\-5ŌbHףPAB#}=5qn/I(w㤾UT,ys۶S8rWJ1{y\UŞnn4qL5%!b'\Q^Y?4Ŕ.]&y#D)+/))1Rd3=JYc#P^Kg@}>Z@$i eq̺ƥ2SL)9s:ི*%]+e<{jbʚ\3q.ӧɓQPar^w ]{щ H1I\rئڤB1=!X\ ]ٗ L/^Ƃ̂.H( :hK\iqq, tƵƵ\cDZ~9:_/AN& :%%HRzoYXX8i6Ib3rR-,'[F>H -8&w,aRgM1n9.$@yw;77R#4T(&Y?~=NGRl]mRg@^0mQĵk}uߙvz1"Rݺn>l0ɎTbԈkǎެWlhTIq\rM|1Nq,X63\_eT3g@%>n,mJK{g2"n⦘?OҸ)qK1)ĔDb/=# ͛ooː^L5Q޼3Vj,V_]VcZ`uU(ŌYW&uֱpFaaNw6*LmH29V؉)e[BNw⤲\d\+YjrXpֹGyؽ/q5j]R2 ILtEKþL8<0m*Sq/dVk.%:2Ж#G\p6;&'C8#=Ox.UUUϚ=9oG#d_M̔J#ЬP8)r+f̘z}J1b* BP(b* BP(b* BP(b* BP(b*T( BP(T( BP(T( BP(TP( BPP( B(@͢qS7ݸy;xmU3ffjUeCCcW]6m:W^/..nn9xvS3Ⱦf㉓&oۂ{'ږ?b~cg5) RD1Sn^|5՛ygee9{.yp=/>|>n\Aq+ QII[wzL۲Q+ܵuDg_nٺ ͆ŦN46Ɖ@MMD -m~XפP(J1? )3?qӿuҐ!566͘1P #?wқv=b9ڵ?U60(fTP(ńNYհ S̸K$/0Mj;:aN䩣ӟA|aGgߥ(FH(bɞUN7rOb·$37ܹ{/" ,})2Ō;w",W_J)7ՋD)z7t7m:>BP|Js޼UU}ž޶ma0D5kbС#v@Lc^rssylP $-[G}_:W~l,n'N2 ߟI_yO$?}åeW>999׮ߐtu45{vn??ɳ+GA{y;,ǜAVCA3g65rNrʳd+<UδKoY6Y?s\n^5 #2Dlٗ[jqsΣR}2V_SSaekF Jlm[} B$)p0!B fv槝%HܹHy]zr`&qΦ_>x8O1mDR]bߏx"<~?,(jx+IGg?"P7(fR;{hxm&ϴŎ1cN4Ix'>vRFd˿\$!Ka!0$"@С(*[J7mᒙ!Jy DvM+7l$K$"3/R"ŔJ7ő| "aÆ }11"Y08mJg͞]q0o r`* B,!0-U87} lwQ>{鏌;O1! r㘋)8H>' BTNk= 9iMiYs񯧱þܪEN(''Q>b&H#6rb/ MOP(rc6m0-CQ/\rUez0i(?Hb,4C1b9i q8ig"ɆKqLɛP 4 77+i$Ix(&9kGO1MӾ'Q1dW8_Cv;sobzұ I46m m_n{(iAQLՇQLN(Xkm>BP)l8y*7/om2e3(W^ee[G,b>l"8};-&G1KKdG)Q_8Ckx9.GA3f΢6^tEs&(fUմͶn۾b*)p~(>9iblSuPLdzJ1 SL$C(QW?;P j%EO $6m1r9 -5gPLҸS֯BH׊zBjjjɌoړ(sZz)&u9_:u7h,i(3RLc#nfgS( 'I19{,^˿-XP/2C#pRˮ}(\_NbJK.UbSV~Y 쭔>f% =|(KhA)~_NNSD)YA؆!u7 ӍK1e^bJaaN^^DD5HˊvY|JsРA{/^FfF*0"צ<+E;Y޾m?J:IPLxQQY!V}id-_aޞMCB$fD!L س-0t?VBP(>Iz{mDN>Mɟl"1єƐKOLb}aCM 9D'A1e򊕫HMv?`5)S¦-M$K˄R~eP. 2,HbeO"y L\IqSLS1䥤A2(`)sb]^$ UU0${U.QEm&CjRIaW^g}{vUć)m˭(}Y,+iv;~I346:ԧP(Obеsh٨9ߌۨ+cǎl i" ;{')#W_`o^$V2}$ o"0QHEu:vPO4Qd#x%Jސ0BJagS( 'I1Qƹ-~Z}ѣ?Ϭ|޽ NsT( J1?zm{SKWv }q2c2''go}k~+T( RL"It>{q9{Uƍ5 ,\Txsݖ;w}+WQ BS)BP( B)BP( B)BP( B)RLBP( RLBP( RLBP( RL BP( BP( B⯷M˗ O B)f)@͢qSeo(--qvz3^;c?tdBajUeCC]:::'NopK?{^>m_\;w^C2gnVZ>fn5>xOOvdRFd+-{b6҄ CQFU߳%|n% )/Lǟ3|B#|cW_}?۱cͭ>딖AQ)_ڽ&n#.(Ѱa; Aٳ/S:AQ+" $Cp˜W`>6J] 6y\qU!6bh=ڡ6rQLS=$E8# T҂\9TeɁ3 6M-xKɒ-*IB1b*b,U?Ob*:P+ *7ibG\J߰/hjδ_lHUS +]DnĄM 'JL Ӈy,Xȁ=L6!G73De 3p#3%]潰1°߿s>id68!L}r DA'2' .1sVXO j̻_qFToD۷**yNSSP v"A$$&0Yv]mYVAt2'Ibl0#$HeKbS\ٽDi.5OM6]΄Q@ߒѣ-_%؅RLB)g쥑u[ d eggK tE++WgeeI7! r:,..~bfs =yKkMX 1L]ұ&{szC=y5BQQ?J55K* B=hs„d~oD"v,eHiZA紨9k>9μ $nf_,,,2?aLbZVA\ Ŕ !v6K.;5ʳIL++۞>F1~Q\ˁfn!b*;4M|Jn^ޖS' իWYֶ# ;SL"ÿRjӧSsגef"Ө㤘v-d 2FIw ."xꕫB1=}Rb媭۶>"+COb&)aSQL7 8H1e"ӧ'ʤ@kx٭dX%ԴjUeNNοGG2H1ejNV2EПbY^TP= N1eP(czO܁rh8{:EO !RW\y*RLsW[ə~O>CtكlZ$1w(fwLz]~Kbg\r& 0\GSgR+cQ\2dݟ"$4444R{(3fk!yl"l dMbu߸)2(?|^z?dBuk7ǥ)Ô\0|1jkPX1y\QNBnzO6Q.O՞/v*?Z$r7r zm'+Vu|q֌Ȍ}}'gŤhf-Pa3ń) wf J)BQL}nYnOq8m(Nݪ/]2v81(Lt߳ItEޫlq.60~I@K§zR <,&6~l=6:^' i:Upރcw/IO b*#TEUUu&>{a>u@G8865,I/ʓk=vIWڅ ?6Mb*J1ˮ۶)z]͊_h~Ɨ%/]ٵ{c|r&ؔń?qrƚW``O;/],WTUul˚Z_C J1՞QUUu.=]ܳA>6t>{Ag) B)BP( B)BP( B)BP( B)RLBP( RLBP( RLBP( RL BP( BP( BP( Su7՛Eo(--KCaxmU3f$#)!U*{LziuzzqqqsT㉓&oy~4/1eTUAi|{}_|E߾}׬75! jHd(*b&L1e)H{y^|5㦌7o~VVV_]8qŃ ƭL(G%%%7o1Un֪jܓ|ˁ(hj=M:M#臵_9k_ ֯| ׸n'NKĎ[^MK ~<0Փիxͭw!} ɒ*(C:klnyboj?`6446l*-7<2xZjk7qAF>\TU( İiw7 0ǁ]SL7$e89b)::aN䩣ӟa9@}~A ]y%{{W9^"O?MLKHv$K~ƚ;w%MdPUXrWfEaFנtcoQ_楎-}b_fggo۶TzӚ5UXl}w!ٲB)<l5z{ A_=6l~qٲYYY2Ǵ/|&~96y=,Ҳ+Hko O:Ґݻ~Ka]? +GI]! +,,$Z"C(암,A[PTTDO!>qUkҤ9./G(/~qO!~ƙ(S1l \&VAC v}O:]7"׏R#+{N6PcJyy59?h ~7l<={4瞚>}pr(W-FO*gmR'1sȳq?e Ł0tW).4Xi3Ն{$1R/0QmnT*yqK Tu r+7kڮ̫ݖ4 ekDA(V`x2)A׭`=jTܼy\r\-̐| ,Q3\Tv|q`' Q%klW]^h_nF* K1\a>A\+F WLn3k/j60l4D2,*_L9+++3<&uY\\,QiňUf X=!@eZ{vaXcMZiH1=WAnnWI`A=s_s-Sf\r̘3sϜ{9xg}gבWG\PTDfdPaEqA6% B@}3VYd vo/yRꮮt"?;9g_l~QeT0t%!$ #7SnNI\f|3)(1}}7˔)J|y"+"UG,RJ̔F%?JNWR#<,PVd̠mӚyNUgU]9yO_8=vo7UzG=֚$ffJ|LEښ5Ĵfs]gǟa 7[:t }cFqBRb!Wz{7m.ܹ2WzN1% c;hloN󗓧أFs{+oZd2;Als/λtEb\WQbZ]ñ%KVذM'1cS e^.عk„ϟ~ip[zos*Ru U&1شĴRկ-wӑ*CG37ۦ5cm9ϝ7[evYټek.ճg/T xVgߴX7sFr db!HJ?d#<:7l>~D]iL9Q.eoWt+x9\g~ RC0Rfܜ`̧C֌5 w͚5G}Ix"+aUӭF|$tj&NRu$f_| \_~8y}R6tQL尣jh9n%J%{FLĴGѱgx-(z9+}`Gw){ԌKo#1W^靧S(DKMW7ËMs$YO'U0~NMKٛv`ws3M%mEÆx~EEfu,0 0 ÐHL 0 0 aa!11 0 0$&0 0 CbbaaHL 0 0 0 0 Ðaa0 0 CbaaHL$&aa0 0 Ðaaaa!11 0 ð6*1o@gy $&EHL@b1m4$&3osZ$&3?sZHL$f$4HL$&n?D9>p'HL-@br: 1I̽{"1 ɓɧČ$(Sb(]ڳgφlݺ5'1Wl@X`Sc6#ܧSʾ`721f:?$&0߻U߃5?B[oSEEEǏ3N9eR5yrͺM?2}΢WxbPo3Ɍy{}p1$f6nGR`R<'" k@f=͛7Ϝ9#k{.XJ|u/;91/:VEōm;w}uMM=qꌂZvQa[B/Ⱦڹ{_n}ޱ>qm'Y*^0X_}6 UU|l%+rvǟΥۿ#) SV[uޗߪyvA) ݞ-~dB?=y[Ȝ8<<{6=Hm '1]R/7oFPZ^y?^Зm_C%ݷZ+lҚu<tE[P3q?@lDoRevfw?z q+2}ͅs/8ļS,^v4ì٣} k1;zu$f?W,6&1vYU2J̝;w&{J t|qI?bϾVz.8l^)1P$fUu[?ZmͰk҈ILK'_qU\9iXXsmyMb,ܲ7`DƟ=555MzEMXeUCrsdTydYv4QhyKcׯV zS$fͼɷj,Ǐg϶ݷ$UlTc᭨1~>!=:}`$FuEw>rz}@'NiRDLn*3];~OܗOv7?ey$t-[[E }tpo7|t_o <: OJ,^'_Pd؟r($n+]SՊA4 VR ƊFYrIOB]^zͮZm.JenU$|+w$e!dy˂b K[ڕsZCbfr9 mLbQY JL,**k֬kfʀ^\xYB[glkRlW^b9H|I{x.=BIÐ } OćuKܼONbOg Ĩ:{Փ_Ҕ3I%V?Tҷu]s+Q7,pI5(K) .C CKY: -]Ys/\3'`y1at׺AQ'K7GI(ّ. 'J`m "'eO r*Wq#?kkS$YN{p+VVN.F@6HQ-U-"nIӳSU$3iuznWsfe2Q7X,Iy#ݠ\7 }+_?;.U*gKqWL#$w \ڶ)eOx)rxb5묻n;IbХ$O"&h. Vp:ҊHoj̋ 4],eM[w:ywqpT^+>兾RIa` R{Ӽ?wa0( )f=KrmT3+"5&UUTc~4>,\76lqN،հI$$a-L{=5Ly=UsḯM"bT0_oaE+$eMz?K>,w󥓼sd! {_olw>ԝr`F*\Ĩ 5i= oʯ&[r%h=HUfSQRߕƸ'^c=.Ul, 3#6_b̸)nJ7D:*o-DSnO3,QC+>O M'mݺA3Tm7\5FCm:ZǾ-_kr\m޶Sݟڙr.8|V%ϲi_ㆍS&Z0s.3iGvהbpTLZǹl|+߬,g ;8gϸS*xRɆ-Y\Ín}9夒ewxʻy*ʃ۬R)<;RS:,ZHx`B^|斴֓w--1ulk٪Կj&Nd9o%>Qb=aSh4y'ݳfF]2ri,> rrPC%f%& Ή(O煄 &՝9ww^S?5~W@M)uny;woJ5 G_NecĆ%N^uI*7,صכk0S=u"7[e6䦍JL[taT4u:hSeYMIϒ/zzF9U+皨^ W.V}?1~EB)eZ +`Z02JƋ]rHbH̟4YrP2q\$f߸nC5gĬjl]iiKR 5iu2_'ʝvjX~PUmn"1ˣ}˫׮u=hӷ:g3J̠w E^)oN#_7Wr_`_%`^gG_]NtaĔܑ@ .y"1S>e>rl I .&qKJHR䋔m_[HbzP4[fT~&O"1%e$h'=ǹ` sCqQ$f0Xȥs>羽{xפVuphYّ]J[_ ͛nUr9)Ӧ6$%xj.x4gw7Tv%f#$jg/X SRn,؞OwL1łȞOϝeI߭fWºXsnpB7N,YU8lV$1jw.q zd'1Cn<]Ƕ/Bӫj I -))%O3An3TT%f;UlmDS.%+ת#˸fvX']bFێr'|$3S/bkPϮ#$5j`TqB^3sڞ >xCFYvQbvv?#Ȏ&qRp7$ =q.Իݧ~\60I~՟}XfvD{o-m$q 5vM Ą ; w16gݦټpVޅGǢtَ(&N8h蒾|mLD!ZB“ 7 %C2:XJGG)y0YOw O<"|hti;ж[ameG_!eH:!evJ\cgNJroe s:F^Snta٪;I*PqТ(a-VtJ.wx|w^I.|t)eQ}+U-[J'"JL˦W^ӌm!gy$h0E)8^cD^@ZMu͂/ 7pQB' 7'ILMmw.f2JL~n^iSҾHW:ؾVLo ް~E*~TNY3}ygOn\嶐sb﹘&2nFV,d$v]{}WD J=Wnk.]ev:l^%ѷKÊ]/1'i'{ 4[a_^=2;-)r5i;xƷ#s Ce.k6jiFi^G%77&!Mfů_IlMaSv|lww-ߋuKmme}{>ۻԏGǗ,nLϤʶ} H6(1[ͶtȂ]Tz9+y 狂 jѯw;Ok||Pshi._ !^ew;ʣN^=qxuԞOV,U駌7dpYi<^qw[rیQH!9$6ǚ|17gM[S o7^uoSp/4jИ7{=[*Kd%n{ YWV{ lV&K#}6.^mXfۿJ:ak?W,Ƣ8$  T#U+4SK6*0̙jD۵>k3}r[ T+KJX.>'Nݟ!/7{i8 9Aa`nQ*K̈́e7E^ZB*1Ř/XRkd}b H M%?R3w ˬ/N$&c٨L21/Eװ+=_#VZ,_3'N$#͟Oqxg9Oq@bd{BWq8sf p: 1tC`w $|xބUX֣3jkko/~].w_Q-mk*******íTMcw.Z5zPenatX۱n+O_Z9NHL$& 1 HL$& 1 HLGqR_?0\=kAJ*?kGɕjk***u]**+u{ݷ/|7;͟*O7-yN];cTb}JS6Yz8S>KG7VTyO{{*M3)ެ~#gL=zңX<ь^wwxKAp7g11(ak՚Q蚲LnǗndǔ6w*۶`.UW.7  ?oE2"~?9pxgv}ɑoΜ)JYQ֭qjf¨Fe:yUTVϺ]nmz;pE!m4or|^VhT{Pb[q9ܯm{vJVPz'V] &7ݠF T;duժ՟{tQQN*\i}=.^+''1>vYӎ:IQjٟ)m3L=W-ڎhXJtF埉) ;ےgD.<;?TZE;33uclkPڈbsC>rF979S{"=e"ۻ_P KTB4Rhf|F)ug߳E>Gokm+{Ēn+,ީ,cFi;>e[[C㷕ޱd XAbf<ͪR}?=~X}sr|zL=׫ t*֠ol>Rdo)SN6۵7 DZցyKGG?0ES ~Q#蛈y䪞o{q%ʁFYɖ#W+6՞J>3r-Wջ rޒ (ܹg7jy9Ok7շe{lǸ+S{v^?=]dE-Z_t;`~dZmgۏnYn,bD ީ4::ң?)m֚S۵n?=\ L|rFSE:sI{NZ](84?D#ިM薢x_ 7o*W׾?u\z;w@t4^J/]vÈVБ#G>|8bȺ]OǚvMqJ[MɎ٤wTLͅX#a}uXiq[ǃKG#"r,:.d{v=ޕi㬩/DzT3]de3+dzGYotj,K45#N|Sܰ'_<['L.0=v?f_|}0[fL\ ?ru]ݎ!x"tOc)Fyѷ  qم!m= j ] N~w7WmKI:fS#MsF&78K{Yz:d̳μf]ɤǐ#oWoPצJ}a1 $:n9%"jDR|!;BI>➫ Om_CzZeǗ:hSs/-n=-XPzz}|nKuK,Iz ,ӣqS-|>,0=fSv`&>=4z'=EdzwqmĦĘ {fnj-|Z I}1RC-SQ3bN#T :zo rDSqnxi*م~hHZ޹Maǻ{'|zi45B-(=⑫sQ5jчTr}a1duݒŲѼ[Ǟ@z7̡cF { S9= O'}ZU/`ȓk$Cd5y:Lzkll|HK}={,.K,wY\h|vu_z4~N3Ebf|[~jt6DFǯ>~ǙGh'7 /C܍SЯ _g㟸ȩ23ݓg\v&xڝjOkvx8?j MQ lzlHPz *Tk&GS f;|z9y3>*9QfH-O,<=9]sUhްͿWaңy;p2XͷC'տQv̄_;)=jLkW]Gxü==㊻?7/c])HÞ{G{.)x /lQnןjj=]'}ͧ_}zUCOvqm,vN3{ky*=]0s(o*qT˘ڿzG5s} i Ź'}W.~}1~Z xu*/Q/4<\zfJm5.ǿyLYX/;>ީ}֝;o r*;K>%&uW${8ut=<EyaҶW:Fzq꒼IOҺk-/maO܋5{Oux}]qE O|rɊջnrtv23wV:J7'[sU.b箶8ZGң:V\X/.Dz T:r?;Y/Q{ezOU^₺'?ӆ%\UGKP*2dr(/(|qegftJ^@zmAu;J>qYw'j79U7&uʖC=Ia+(;!'Pٲ1qz)ȽeO~^*#X\*@Z|Jz7jGoq TjɧǞ߰zƾ>iB?.qQ}hk/Mw+ nYg~`]ԺI5 <4]Y+OȱSWz͛S{<#/{􊟡/:?p{k3%XO chΔdx*2q2n37zI)۪ 9޳󱱠Q*wRρZ~}fgGd'i(D ti@q #޸q:)-orBfn^,n+M]mP3}tG;" ]ɑݗ{T˵jW˖nߖhlÛo[F0BF:aY]Шl{ŗGEn4I[Rϳv*X~aA֎O7tovdnka+->q)|%\I4bl1nv.xv)YoB_~)G-2w(S)'7$o/a}5.P~ũ˲ĭ-?N}<lbK3WrRq-uݚwݞCJ,=/?{7oe뜤!9̾lǡK]γ]UX\햀^#5(Sz\KSez*~eqKL]S";+S]rO"i)W˛L&8UT1i3b$9$U^KYqhfN9 =vaR햕,#Xw;gJQ|v;է>SQ=3 H(QjMx}EGe0XHŗ~Q?|Q85 H71@.Ry#+ R )-B!=G )#@zPHH!= =RHH##Bz0=!P('./?B¢lɮ DEz|/Q2]ȏWRjMJG@zG@z =H# =HG@zG@z =H# =H#G@z7N"f?>8O/+IY [-+G2v]P᫡WεƏevC%x9`U;sb6N©6ouJ˫wMy|೤kq9g#his.YGPkadMX0%q}ƶhG^<sҋ8vfLg]@lWvn<7gCFꆭg& mDYXعf9pw]΋K̽{;ϔe)cSށK.j\@z\%%&ncnǠvā!=Y; ӣh"Ϗ8ƕ8wV*[g?3#p$|-ӣX]R?=v&$fZQn-&EzqLLG_qָĸM{w=vdG0q%љV>゚˹,G*5L q뽎hJLJY;h8F51ޱ;E qiPÈrȻT!=zlMݐaFJWx6`݀;u!.ֳExU_"ž#l]\Fu cbLӸ/!B|bʾ? pNu9q6}f.au6Ĺ*vWE1,=/{WÖM0c'Nan4{hfmoT13ﯺV-MndQΨ[Nm\=+uu4*D9!1&ΖsV.=1! ]jhFŦ6bzM۩r]o/la[$y3CI+[?rrzRb\ZFNIz^b?.1`{&n+}G-c;-X1`WW;dbR?+AzTLq-n0cϴ#ӣrL`?IAD!]HQRrPh_*1RBmt{ewoD W}" I YG˚ZHb?7#6.1.;H[T 3Zn}vjѴͧq ]s>Fw&]uaӣQ]tǖ;ߩp] [/ҤpkA1ԩ*T.1n[*ow]S=>:7=|z,Z Nz^(V"ͧ{ ])K_Rς"Sd)=DsزD0Ol7,ңL~ߠks5^ WRC'RվD,CRoq'=Zv[;WbRO GU`Qie&Yn Qx1ű:=16yc'L= ]=#mһX`6=Hs,ׅ@2 [إKBӣ婟 ң6^pz+.GJC`Q>[Tuq$x-ңej9-8=ͯ<08| Ük֜KSљ.cL ̹#ntEݠpUEJY2)uh9]QW[Oݘ7klEMþaՑ([J])@"vicp'=(uHtAJh*:ӫWhb ]1 y\]Cu6v0)6,aceAj$fG`G9 LmDᜤHlB(3vzukƖ{I>viоjX(Ѷ![`Is y ~WOIZ+.wi򇙐'p,-Wht7GɎ8f{ۨ?Oc1w"e+bjQw7tG-[u<-0@R<I[]{MӤwz2d]g㐼pf+dbQ7Ig٦3oC T9W!{"Sn+uZݩs]i7I =36p(5A YإILOz|qn@dqLoLqz=c hUkTz6t?}ghωSydKJif*Js2!–l]$}meAA%OQ`NwQqwG0F{~gun xr%٪w+"j^wjůN0`slVvqpL \g}G#c܈ _3=S8o>+>8yRQ.du-69ȷ/0<]I!ԩxمY=~c f.'ŽZYX1*i']y |25!%D~SL{B<[jU^Z揾c|+"[WR Y\yr1W쨵cBUЅUg wy (Rq) uki >/Ɏ"l=W|%=zlO;SFzVsifXGVqg#ƙl;۞*/sKV5 "x =H#@zG@zGH# =H# =@zG@zGHs~;6=3;LSr~URҰLG|q%:2o8\_^r(gZ{g/7Z{\bډ/s9':][s2<=q>'F-}rRn\1 G[LVZܚKrWˇe2R7dh]PűHcFs!@.7zBk}S У,TC@I] [tGks7/-GM~7&)΃`˩J[8^{cse-ܽ1..;΀G.ݬԶu]zZtߒr^>uc{ 9,~jr ۙo~7;%)>'o{gA+z3h91q_ҍ= 4;vҸO&OA[LAӬ)gizeYlm67R^5hN{wÜnMH\iT[#Q\~7UGBZ^~>?<7/?}xp9>iGųG?`/N,ŭS_j,;<ݕ>ң_zTj8۞Av}d677v"?V:K|֕sm*ґorrğVVĤ8ß\ÍUr&m/) .Ol`WCl ܪ6Jc+3zHn[϶6,φX?_%W啡c]5">h|h`phyP_L?x8>F?܋,=L*UGfGxrZOQw*IX1Z,ν3[f!GΊjYbےuW-ED 8vWhc<[l|Bـ;YyWZaf 673dk{]eң_:iIJSg>&mwa~2muL)d,Y[7n #ŲdҔL[+Gni+RiAhi6_-%*3VZJYodx ;>faWZO;NMUYU 33r뙕۵۞l/<ڪszs r5'RwijSZ_U~ήųuG>IS*JOZ֝9bGjgG5)Ъc0 "^{w"{ݣ{ȥ$^#<A>=ӽǕ/+Rewbn* =Q$=$o0s6?aS2_q;*-l5uVAHIw59)MqN1c#v7?u,T-ao˴z1ryfOK+~tJSi%cnW"N2F=rg$u g}6S&[^-r6㿵uB9r{o\Q{\^ץɢmuySCǔ*U?69=ƿ--9?LM KrxN(DgFIDGǍ{v=zJT̠U`uǽ{*J 1&!%9gbzDn٦[/n=*C2 6ACjsΌ[EMZD, aʼz-Hx Kz[z+mYnE+RiGZ x<1.U Wf§GݒԏMt*:'@2-\(S-m'-V_VS2]!l$Ƽ=GjNQqf\sgtBRx8:iDDרqνQU-vd5*U|@ttuvǨ7/=*hO,[ 3=e٢ZBNVH)('B}cPH8 69>31ֿQՊ,L*AYJ Җ6=Si/L `]Y5cTSj=-dŅG׭-) ) wo\hzTI /5ǡGMrLf/M yלf>qSgw3J&|t qӧO[ǜN#h0Z-1i#xЏ4)G ӣҪ}HaG-XS2=%L˨ pĠ)1q)ֿMQHoIzlŧ>:t>̘NMT[`ߣ~WbL^+xңE{xl}\ڮcSG%lzG̐ZߣsXg/^xey6}[!+[%oO?:qqƍPUy#WsQ>8|.;~cJ;=-V"=zQn0*8mAy-SZg]IyfT\5s5u>}+(oҴEw乂#WVKmM!P\s@/ʈytчGQkӇ߅LS#zԏ/d m[jDdwל{bѤǗ?At%<]]ֽ+{K;QQmF[%%%˖7d??/]8'Vqo?9h-ܤrSJcZ δ:h.sunnFߍ+3=y.3\jkm;{cvPpOuRe^8'!1>_yo45)K Upnq]{&\yiCao>]bMmCK'rbzs fǀwYb [2ge_aDqYmjhU~>3ȥfR\3;)6iL sန$L#WS .N=v1eũmI\Doz4u 3wzF"Om*-fgkH6ӣ5BoDWz?uV+*%ica82JlrFZdD67V%%VJ+RiKCWڒ̙8wp\2=k:S{mTz6wPűHJkO4=Á+G3>C( K5=x2ڢiCrECQͭRRi_:* :c@#+|f]ҵcTĝE6zƕ+'jy>Z|k`9дVōUL#W9,a$:@z\ k M1 07-,: =.Yb9"Bc]X]M{Ǫ|8OtHtt~:otT^"=**~=#),{ y#:.1XHt#HDGG#Gtb#HG#IDG =H_P( BP(2ox~R)G#BP( B!=I BP( Hz$=R( BP(#HP( BPHG#BP( B!=I BP( Hz$=R( BP(#KEzG@zG# =H# =HG@zGyƜmmߎͮG 65/ԧ_Tw#oZۜ#ȃo;4DgQMCVjvQ=\_^r(gZ{g/7Z{\bډ/s9':][s2<=q>'F-}rRnj.ߛ!#G;'|6vfsbL\Ι}zF:k춧JnX$1js W{tܸqc|||]]18 P:F?=FyV- ˒afPT#wqFl?]3_Sm1Mpޣij\<;%jr>XMHSl1i{,{G}g ?VM+41 u3ܐO =z/~wſ3.OOy~{YׯAtT9NjcG,# 99T)C\,rq[Ѧ#%*k{]aHÁ9׭|9ځ0YNNGDQJcyV7*p^Lj{l->MG>˲)Sss=e)Np2)GHa_E2]<kܪWosܗnϭjpͷ:H`qYHʔڸ61ZR\[..3앝^[ /b;z)jt(UQe,غr-aVsFYDO;ݪ+DYi۟?U3zW?4Lzlnϟ>wy^<4勈ޙ0+25YzQɛi_xS~ 񵋎{f =Fuz9+.L?;oK)/HHQZD ;vWK=<[l|B jJ+ L@z,Q&>{c\->3-NU,,=ʉhXiIJSg>&mwa~2muLѱd,Y[7nqu9OW =e_eRZuь =x"o{`2ˑޞ4eE7'5óW% rIUxK[r.Mv3UFLJYo+Uȥ֦ӻ2m^-)Y%&G6ޕ[Ux(=!1Du^ZKsH;<7 ly76VsJޭ7pf=6Ζ{9paPc9À!#ʳʿWH_pU 7?9`}N= ? |ͷϔI>y(crHtoxzT6m9~Qӣm˒)q}~È0&HM#q9I=(ei3neX&ՅVQIw{Pqpg|izTQ1o r ş:.=OX$F}f墖| G*c\*"_~FNB mǻg[[{4E6uKm7u<۶76!~ڼ [-# 9gFLƥ7M5Vbʦئo2ŅO9,B?H{o:5V:vkZTg:F{ K"{8-ң̣&z?<~OHtojzT(cRrz&NfmʱE10b9qFSDweАEGрW "(Iaʼz_XTƙh5mj^9cL˩j0:W."~buAϨsZRM7I=Mʿ9_P :2Tpuem81`{4eQM~k5l;v͘_fq~EהZށx\ퟴHr̸Ψ*P/= =/xyxz|PSx?;'f6% =.ФXfzʲG6VAީʜxu0dBJ|W7ZF1 6FxFSz4'@Su&$%lWQgk[[kQwP1^<ڰ+SFkK:tp:6ΖU6 :B݅H,bL:_ `b͊^S%d6WdO̊ M~Aly L/,+]sz4#Gw͙N yל1ӧ3FopFdǧMUO9zl~#ǥ76668̭H)K}u^DWRL\FPX(.HK)&} }nzۭu~H2_/hhiԴ7סj(ے"'kdOglOЫ#=lRYnqظA={ `J!RQ^>߈b;Y\ Yf'wYuK8r.1zz 7H#ǥ^62d%ңwZ= `ڵj]ۘK)jU &.Dizyӎ~KW!ӣv_L[acMlͨ7ו9.ߋM1)O$6swګ67M{g[ӣvOw,gv^Q#ugmu^GwQV3I~Ǯ &hzǙ]W"I~C 03jO}= _<:$GG#@@J^m&sb= ;1'X5wO\.8 PV1SrrY̸Ҳl3/57-ӣ1V6to~S{{_zH#ǥ4,~/W.VOݛ[l&CL{c"e>Yū%@rHt|9vehW٭>^ ~Ώ. ~:otT^"=**^#<G#CSŒPY4@*Ft\-#<G#`#G#NDG =.&=8Oz$:qHt#Z9 BP( B)G#BP( BI BP( Bz$=R( BP( HP( BP(G#BP( BI BP( Bz$=R( BP( HP( BP(#`G@zG@z =H# =H#G@zG@z =H# =H#G@zG@z =H# =H#G@zG@z =H#,'tyݣkWZ{`Ńzr=5q\ٴixMΚ⛯߆Tȴg5[Gk6L.^kڥymU=(>t`WU\o:'ik59QP]pxC59oY = $_i90uLsގ4fMAڵ_\dc6aӠOw~Ozf_ar/gMjL9psկT2(gY!`orc2J\uz*g9Ɨ?Tf/띄5 c}%#ܬԌ6[VOzW˹*XW |yseY]྿-A}wZfM]k.9]z-Mkl!*=[hb]}Je:}KO7?xQ|ĺp]8TGZJ֤T[2++ 角")냘L雖% =7 Iu^UɞWu i苹vWOM744uZZ~PlZoZNL^vzS{z޶+]|{:=64=8Ԥo]n ^o3a~۩L-tT=pT.7Sf}y ]_"${|w֤j Iysx݆UOI]󎜸8(Hw*U_f98WN3ơңfq{'(OsyRC9z4{;_4}!Gԡ *ݹcUz\Ehz:_Nɾ=\hm~S\U+cңEZzTYq.__5&u[Ey 杭U"4ޓSqi/x;zӭ6-??~ˬAQ?} k Zb+ox2/WӞ=*ۛ23hY"xP52A]F֮.iloXwaR fbҥGk+ժS˚9kRuG; acwڮR{8sE5r&W*-xS&3x5XA n#[X̽ab)~flckN2g{bǍʾE8]\݆8RYTHJOkqQ|W~Ʈ̒~pֺ%bbYl]'7VǍe:G`skWv[-Mm{u+9@[S9[nt5^wwu4]}϶mǖ+b]TA 9rQ5[*3yt2?m"\.[[*;T__EA9_MFTd}hns\+^tCxo )HAYťGܵ틿G4v(`>nO#@L ߘҧok1tZ=hz'/);.Ʈ%JOeR5Zx4}C1zMYy5z-ZP-6-95?eXm!ңէO4O<kQulJ۟3 6|o#+o 3'&Gǥɬ5N!|}K-vGݕBbr7#,/=xǗ8d 5ES|M`uӗH7W+!JHq^Ю#qek^ }VǍ8G`ңq˜׿},bW%1Uv-}#z+aR{ݍ4]388 ˝-aY_6sZKcc#qZPkoiN|o/Ho;#rfghq.quټqaja ." " ]Ax!(.Q0uQdƘȱ%]ȍsW5!\]LK'V=|#K[y4y{̇_Uj5S)5~:.r1M*=cJ[-|!f|2mY{'N[jsIm3djVxi7 C=ތ6_=J2OѮCz4JQ.s7l\9jNX]st'kbk6(LZ*OKY ͑b(IV潺z_CoZc!ΘuPr|x( o)bm dz *^o=]G^$f*7\ "Rl/;\/f`ߣU ,Ӧ1ԣQ&H ٞUe>l~nX7}P=/sRK=g\4^6, p٦8%{=gC)1X-U4>O:NEY2:Y%4^.B^ܫ7^*g x*Qy+uZIަж"B9s,W] P~Տ+ΛlE#,1p7գ,u$mfHCBWĢBU]m~,.l6sxu״#EB ~BQ[LTR;2=}0W'Kn݀h/%: Vc,iJoٿȱ\Y70Xl 1I<ζyy.7ta?tjk=zP%\G[+%$dԩD1ţh6z mt(euް1M`|1೧b<:JVRD{+dg'3gGEͅ?S"(qֈlAoQ)>rS\5ߔ%HMrL]<>Nd y.:<±nb;qo~]9$6ӟE뻹=aTF#GY*sG'{>^+s.Peyiڇ23ע3ҮEfCemCM=kSiL/ Fɚ4Q8C86s|St\5.ۥlފ3*[Ch(dffÊG'geߠ_n犫qu6b~Yhj,QXGt]Cy#v%6+):x] vդ7}SjB+'ͬ%xfC+'"G7BI7VVԅ$h0*v-ݢUvwR:qPWb5[.r]uPr9?gn6>ûF[8'ta3;OU]|✮ѩdYgTeˈ4LxRɅGR!&WނKwbhNmK^Y%tz5խruR3oTڢt ^$FeYf3|c-8K)@=㇏~<?<Ӎq.b}źlnǣk!oG>4sKMReY:s 25ğn/2Rm4vM hVf>NF/8?Oֵ.m!]+pZD?dH/ @t'.zسg?:qa\z|s=gRSN|]vfgŹnGRX$_y"T|ŏв#\ZX͌22Yzx j~Mͱ">|Jox߾}؋=0N>ow:r^\nٱUc޷]мuȱ#lڴmd"o8v-~C3=[«[Ya?#tGMaՕKZKNm/:-91+0-+pG8fT*x"̜qc ?v+,up7/@nxwUB7s[}\m.9NGjX P>n{U;! c+csYxz8E~[l7"E_S)N7.Ї+k_ֺ͌_,2-)u?X,^;{ .j%7\/3;ٳ'UYݚQ:AE_nQw%uEtVf7#[žmm8PUҳ{YR3YNpHN9G:\j ($38xZ۹g>Hrp!kNOVo\KbpkAKxv 2{X𜯸GG[Jf~zmIn_ŦM۽.C,=4۶=x[yj[ᩯZgޛWvۺjhִG'nm 586>_TJ %iYBiz@ZfS9 轢6>f8@ѭlQ'p_IFZୱf{|8,c]4`x30-M6S'ɂ? 4VXR"Ô nʜx4^HUh^%Tk0XIq\|DS%& gx))hy]U~rS3MksۇzZvd>םZΘDMu:n{lk剦UIʫolƦԌr)2ZsFh\yƙc(bYZ J3pV&?_*[f">YoRdsGEe|EYٗt=ZpI"/b;fomݺ}M_ܱeۿz7;o߲u[ضu[7}CέpCoܼ(-=9ƬVg<Ƭ=gjG7d"go4߭n ~5bZۉn3[bYN~ќ͞wkk5nߟ5`}񿷟êiwϟ|Ov~xzOv>ėf.u['^Fڛ~EXAūh^t@Ues8i#'G, nxEw/ocim* ![U}mZn[d͢Zo_׋]/+w8^rG>ݹM >X׋?}>Xok[gfJ^jc=\]t"q~8nqfoU;3.A=~yFVwzKZGڦU5w ,}_rh'g4aџfJV$;fjt|)B6CQ4izk q0RE}~-G|+jfel1\(+-kEFW-z}x֫uvx}6 јںrd/_w::uO;B^Te/CPo  xzImuh`Ź43Զu+1W9♝edc嚬 v/wiw6g:|C6zY>\w_? 6hrwx|/; wgغE0N];{ ~9܆GIs l,Vقs(nB-mZwWv7AW8+q^|ى@ r_]qp]9m~AS}3Ku-ߟ!=?ԥ{Na맯

>`&ޑeoxɯCzʑ[GE]ЉlWV-f٬HqCn!SdA R&kX~)O5taukzIBz_AuCtu޸<|{g29yB 5ڞ:Vluقߴ$K'w"tl?zStOzotwwPK7sJ,-WܯmԳwKNG$f=YFȡD0ak!U_m4}{viC/t::ژޭPM/ Q%#DZYo|t>u&mjnn׀+aW#z5TIyGfAW}x  sο~×?xfjxa /Q Nh&=?'Ξ9vrϢˑAK8njT|&59Z^5 `pກKR{UWn|ᨧvDŽ e]/e8?9{|\v'+i]Yh%~ʷ?{O{_U΁:k^r-A*Ԙd`hiaX۹vPmVh_#s& LfݴB{0찧sd`)'}o%sûq%ORarL` tb<"k]4A۽zĐ?ߣP]oCIث"m$GIuJ!b~O~;rcg}}k~zbk$:y;Nٵ&nN\#G )_~<=‰s_\ s'k\ҔƗV BW3DڶY* }gqm]Vse.ma'uVh]x]56d#8U$55ac}3rAvq/ꩫkTڍ2bM#ةx9 LP]t+SR݇BP#^x=!ƌsx$F92RNL\^F~*d1ي^4{1?}SJK:kLes76M_O}\qlFm_'AUdZK6_S4mb^JKfP\d܋XFU "L=l5iod< C)0s%nXz?$tn _p"v \YIpPOeLB! tB"6qT2Cz&;tE|>n_m.gQ$H K-^>ݱ_.Zq4 O.)Kr^E[ަD`Ӿ1=8sO߲H% Wo;{Y{L2j:.)%=;##?fdBk|!?Yl޺Erⵋ eX#5X#5z/zonX{payYF4{[c["Tcք Ǹ0<,[L݃gQ6Fk9+}fZe}K[.|SKIyԌ'h e y[Y-[P<<<Ös}g\{!jDe/ɽ+~+,N gAtZE0..;/ck$x "ƂZE\96fHV_ >fJgMLLg;OPxzGw_UW]f- &Og9㿐+*X 7Iq>?_)W 9ipx:``iWhga8M&:>VkZݺgvvX;y_TfGHx,(.u;Ͷ(@"?{<KlA"W>/y5&MmT؈Bi:nP*N^?0ddTTZQ\VqUMUeo*Ҳrc:s>s+FQ G^5aW`sKSR _zn+*-W5Rp9 ϰuupo՛ ػ퍻& *WX9wK+0e`H|zx #W?^#Fa꣥9凑qZ- KzxtBSK+nzrrS?4 Olx ظLF>{HO< %蚎qߠr<$0YWUe<Y|s{׸IN" I8KOA|ZmP55 1# Q7bbrV)I ~)qx/69g@y;xMժ g5ⱛꤙ-W(#o(*Yux/4N[P.mCKEm/FHvmq㹅\w%8)/al0s9y5ʋ㓙cSKgbZ ^"Ұswf\%^ixEt[`>ى/|<»/^NK]e<4JK1+O&%1u&1`h.v>\]#kxM61yGľ {ԬJ3Y3 Ύ.OP܁pВɦzh{jsHZӓ mxZgdCC|x򈧇xJȜc\XӠ6؁mxx;]D)XXZJH.}bre=kZ/,^z}z`K$ C@#>|cu+Ɨ Piy%'>xs {chY\ZEIfgf W4x|)UBe_ۀG]XcUHtF)e ;8zutLX'a09nuk5FG$[tF޴/Ca螙?rp7֨R֯_O\P_#7Pjjjo(=Zrp߿.?ɵsߴgYe/^T*7 ݇dPjwۮ"] Q٣6[g&[}sުظGgpȹk1 -xI&2XOp{'''Zĺة˼FJ~zr3r/z˓g/K2m˰;lánO@Ho z/:k~};? א]x>sX88OׯSWlܱEBrd2-HGPcu,&;=oR(U)EO%/IUKbllߖ/_`0,YBdaaήIp 7BkҥKWXAoiyc_%>O2_bD7 #_SE`}M$X^R"inU}cSkks'bgU"UGOPX,ƗH^^^,~g_XhHu_#':[Ӟ3zV;(X^YT'T.69G@c gPGRq"}*E\!Kּ O\~r`YL_?kJ`AYcCC"ww%K/`S绹#TBI= @ hN ӬY#;"*@sJ؞fЃ.@ S4kH.d*@ S4k5X#5X#5`0[8јUD=no '!&O`SIL#x4&3:[H<8 <>4+%0*[Bb8E9U"~LjU7Qx/)(ezx{L{A݂|'{9{/} ::RVX^^ zu}-+*7kLN[Z)\)%],>XkaCbM?BwyحI* s)ZNIYtBwnZ%D8_.eHlGr?f^A+k2>V2^U ]OP}>Co '2k7PjqVF15q13N!s(P؆IΑ%"czEN^W Q#?[䆹y8a8ںt+V)(.c<qpM}( Z{;[RL(e M--mmYbORRנjjn,*nh(f |1|8;LN@ > ىr5BHu_Cҳ򌬜,ݱpG'Td U!Kz$xylG䓫S|dpZi*21u7T xAk8 5>}ɒ%Xnnnx5{}ϰ@ м~L\ - Z1Ũ5Uу*x8=&zj`%FwMnLGkJ@g6u egeW֩^V]+LJ8- %2$$@xgMJ$vDj푆2\>g1į%!Yh"+QBj{18`iC\Jv6d0&niQ㭱ލZt yH2ԹX@ 8jn[U{&&Nk*xpZ;MLSe(tC>Zw?lʼn&/BLavjn&Ore^Vv#W7ʋ{k#6s,4C6Xh;$!%9I0A, o;ʲd'@,@jK\z.Nvx1D%@&w=OG7/$_k9,}qa9N5.[lJ峖\kߍm=?NNaXm$8VX[Nba;^v9?e},8rڔ5*%Cx,+/S2DE 1؂z)NB,֏4f*(_ xLQ:i%&_j0@wNZP2I[ uMs}8{X#c֬Z]T@ 7+AUG#@/MuQάY#c8``X#5XDMm,ų377kX_2doԉ"B5ANg75%oe󃕡QG]k*zP_K WYӄ+UExTxba~yia^$j{U?~gthFimCHUYR;41:x5HsK2EI,|'Ļ+&rƗΰ Xh]OLպa]RqyK)p /<]>0ܱckbz^8\ ۶cAUb}=b !J<֥KXt׌\xTRI cky2E`OyQnV ?/N ͪzy)'(,olT[s˫ۚhE#_PB-r?_l9wF/UvM~ C 4Dg s*u"OSm,A\>ׂ5&6\2miU [J㹔G-sMHV0v2 :!֛Ju̳OyCB9BC tԮ7gM@X޹i|Y+1(>Υfg7^k앒FJ~zr3ròo n=E8a-/;6-t|#_~Ӂ&\bcv{3;Jl`i.agx pF&_?: 2JvL.+Lå픦UUeV"4.,(EYxUK@kHX$b|.{kj}5G - \8:zN&nڸ['o;VKpZuWU (pێ|[Mycz砯n(ek+#Q>x[Hsv^DWt}<֥KXt,\ϳ_Yq7^P\yT,QD~(s$ʶzUPʗȸ‚\O/W7ZZ3 ;[=juY^52&'f`*S4f' P Y#֭[v|fgk=vN3rttE3P1yL*|*|'jJeOjL.< ,L&F~LՀƙPkm Xݗ,Y5N׎PYX ' + zA&\ @/]gvGD^Pg9&= tzKgYze^:@V @/.5fB zA%jP\hrQCE9fX#5X#5X#`e}eOTU' ~XK۴ܜ""CDCCL(f|!-LD%2L-$=Nk$ ^:~F_#w"I%/;=mNZխ zX[%g"`ƛ0iy>*Qu24344h}S:guzojl*ZA4P721ufьUG 1M5gYފp83w>cT?8SbpJzSξuRT1>35ᡴۗy/虶dD/rԕr7|~c*$MAPMR4Zɒœ$j c[jKܵ}-Fk~%*O?9bs!(n~cVۆHU&hQ!*Ɵ/r&x>聱d~Ye/^T>c5^7 Y>8oko[8>'S)gx/\"_e}{ck&?oU 8/~AAepPݙM<%°2cn٢ [J㹔G-s,sZ~v"VfSC"Ɩ<۠fi>)N~u2 x8}=2JflcN1XYN^I=,`7֨R֯_O\.f~s\yܠb; 6NAkj]fKk N4x;?-'֎'6q pTc ,.yML|NbY|ING L~'#}uuꑆᑱZGiηq7P"QWUmr~QscMfg6߃ʘ~wE^W3;q;VKpZ{!C]JqR&ѽV9?몐{ݼP|il`D+lxVlXqtRt 7^9[GX2?uҥ+V uWX` X|1 w+"+x"4](M狤L͗DQ$]$MԌl_w_PB-~tc7݋eٟ (Civg]+FmN=q2z]OxQWꯇy`Ρ.ti3?w .֏_=('BW9?Zso<'؂d_:7ɩ?:KMs'6\ާ~d;ʺ: VPTq%x-;]Y?T_1B1[횟S*@;"E݂KN9ΠԍڞЄHD $QsRXbFIS};eDe'):LϙxH4qw"du-FHg+VW';bN?5qٲe/V*ϸu^7a*RKm mۡ..S6*;O)Bpý0;n:G8{^9PqQZyު r$ʹF *7|yN[dGnxRnك+7j7{O[t;SPnue+1*įM}kw? _ѥFa*+lj |yZYEepzFh2#+RXAc9xfXMkp!ynT\RJ/ϥt4 R(Bz:2ֲ5 y Nj۳#j}Ԏ}_뗷Gxݧ7Vl=ٵpx՗e_|fb̭ `w:i ;S_35v"gbCg4hlhA^X6_RCpn?) F1@o[qH}JFGګJSxo6n^F7hrTƋtĐ GFd?Rڱ&33]l%AuyWm8Nqwv譖\9ᴖ$BwNȜBf/;>t;.F" j ZL_a5ƆE K,_wsskG,ؓ{Jw-os5k/ԗ@ StFΚ5]E@ t` Ђ`YFju!SQT5(.x49ZrfFkFkFkTɕXzE]ï uZc_QCQSZXxݐrCe?*k]; !Srnp3>a *xwo/ަeў^!+` 3di3B:hlW(% l-Gw_`oI#=) \yaQ1TRaܢD8T/K422O!4gifhh0:a8$^+(H& &.IU4f,lǦ驴@U|#3;;[Nng`m[47amq8׎.TO߫!m *9*Ԗ+55 :%&&12nY`[2 yVZ_1IAh\*̎pwkQY<`h\ǷO F>Zݨԁ C|&قQ=o&nܵj-qe;䇞~oWlڳrn"}"fVfw"_6v\$q^BmLT(M %̓hŗh>YOAjm>o /$6}QH.KkKX[GɆv7ڛN7-_u3ԓ3jg|@eDMbYgPYF/{l۰o|^%w,2e?Moowr'xݽn-^]ݿg؈Z_)F!7kDlQNqTͽ@’r4ь!/ Tel33W1_[8 ֶZb&=J}B"YPD d̩҆;Vl?'6" !X{[7U#7?ƚqRxwk;- <'c&y{Q%@ߵܼZ>pR`Q-[xbRF&tHl{(tW lmxŝuFpRpbvz\*lW[ֶEm838b4>, 񥔖hdd$ũh %Jt,z ьAkt2O(ʺƒiÙ~~06S-.7|V8Pwe^/jNTy!e:19YV-UY]K߹u bp:`gh3 ־nEU#jsE24&DžHvTe'^=jqXFpE,\䲴d5c5ݧ5~&Iu)E#zt##E('_FtfY FL𶵘~zD|f$rb`nb|ƪgO|btSEv"﫻)P1ԞԟV}*;ksڻ֖F"}ԓ(n~Q{mpKO7~ kw"Vl>6%j4“Ub+b(5ͬlle $Z4YSx^" /iHɥh;$!%9I0AƜ*p1Mܼ$3ikϳA(.Ο/O0Lˣ7k_5o1&nb Q,@Ty%Ip5"͢{a0Oָlٲŋ+glz݄H-u1nR}7֕zزF惓uƃхpPo 4%nr+GnOYcqQxuVW 4YU㸼"'{k+R- 5hDFX+@ab%C1斤 [J㹔Gsuđ騅 idXckkҥKWXAbŤh,~X0X<,"6L.08B1:8")'bp^ Pp@0j)ju-^;Vq=,,ݱ, Ќ?ސ+s:9c0U^g"Co5644/`Opww_d "8E~~^;Be`/ĞD30:1ӁA jpv?YF<QAg게N0<]}iZ;kxt=Sg T'݉_ @Tk:=fՅLEL++3  jE Q̚5<```5,UɕiOo}eO|oDM=Sqhmk[&OH,$3'"K9"&䉹BF[@gSx2%DI_Td.WPGhT ''dbO4E&a XcRPOu٦̾b`ackmŏJ`m[:k 4[^5gY>ٜmle؄ʒkzv,V^ ޫ!e'?JM/9z:Nټ(bp:`gh3 ־nEU#jsE24Eh!UyG$R;GRe'䯚Ѣ` 4CĎBt=ù=9BTf2l:F$"kMdÛY?=j5ֻ1[ 4[^jjj2H7I9k|; R~b1X c ^7a:z.RdW`lZn&B[yw>+_6:4I2'LTMiqyEN"#V [kшRc*8UFZ W~Z7L$[J㹔G-s.d`b5НSTiuiR9ɺ&9rgdh 6kTTׯ'Q.?3]{}{ڸ<_W{פhYGgP-kŶc'uQC)>ݢCCsdJPA$OYP+M|XۄpKfT@wKk3'j,χf7g7sۍS@h\<`3!v0 wO=mʂj&33].EYTo7'(>NfNݵzČRԇٛQܢgfo֥KXtWʿ?~폾#)ɲXL/¾H>hl#dkáx(~W,X"ep1Yere/[oqV:re`qz?^5EZhklhh_dEq|777v_=gXa z3um}cbW Z#]ˬ Wʷ6lDJzf=B333F,xW*ĩmU0 oSwסu-V e+JJQ<&cC-/RlrHUʕ:5Dh,RǨ 6!*3eiskkph@8ѕr7|~c*<ӡ9)=Zr#α /#i 隽hcOƽm-ˉSTl{%8ƒdUUU55f]q#V ZVY=ͨ?; POꪓΨ0.ZLT1Q]ycW_т%mXVl[)8eVP+-ϩkPՖbkbl)lnfe`c-/U7WI,>+c3[Lv=lzsC"YPD d̩;ɘ{m!?e'\pv[-9FySzg$SQۧnTtK c+N Qw4Xe˖-^XT>W"~Z^1.3mDyv~t^]tRǥO/Ξ^^?W-S5iD?./AC*XPBNbJV T8|IjD^FXc-X㫣6*0Y#=G\<5T*.o)R̙7#Y3Pւ1yu4,OIqo%GdPߚ׉c涒7wv()N@6s%AeN{:3Q{UBkjP5Tד(˟{ };uEc6~jvu]+g =Yhnm!db GgiŠz\O>4}9b51$ιoRF}=41BhϬFg555כ7bZ:GprܑdsvTjd,gzRWyJ˫ϟ:rçl?pX5̒z4ĖrX OVML1RWS"[SrZHX<|wrjId_9m"mEYiJ$6m%FxwHB$K" sajiDY<*ZX 5@{ (G&wĝQWR4!nb Q)RN5_y5E!t!?m3BٸOKȜ&LrFFFo_5סOZW9i 7rdU򊼤^S&qd8L,btNBQ`qܼ@TG#Ą+?^&J-\ʣ9Yp'K2~R͂ju9 xx>IWزA,R\BW>]?k'Hf0 k]tiΝ;{ };uʅ#߮ځ/M{UۏqG knD -:M-]=::GF Վ4:-$ˬB&tKɑ~)Oc `cVUd5!6m*Mf7g7sۍS@hn~QsZ_|n==SSC,cMfg6ߍ9v0~$(:zY^xckHO f1Cp-`plMrDR.OLgĩ:,29u?+Wܲelu7zz YcPPᅬ׋*tkRK,OO:5"WW׷z͛PYX A.d*@ )Z}ee`2!t49bD Q̚5]E@ 4Sg T'݉_>#c֬ +쎈 @ L]iƓ綫/ FqnFwOX#5X#5`5@V*39uwh7cM+{Y-_9Х}gIi,2=k=3wvO}LgަegMG18B&M͖L:[\W(%l>3 pW3;[F›. PwhT ''fͥv۹Ep^hdd䟜1~ i>#OH[J0;XYW K>l7&{"  zX[%Vqg Xxؓ+d>Wcҧ&fn۾UDTnmFqPZ5aB'qX>aoM u (_tnj_-[w-EՄ5děxl9xiwL4n4rp/\~Ys&ӂ]sV5ޤd St@409:F;lA*O )m$< #>țܥ&j[|>ތ^ӤIT|QH.KkKX[GɆvG&XdG-E#b2b؝@rE XXX&U$꠹/nITE'1~ZSqsIzcTcd_{B r>.0ĉ/^|Z[{t:9*5\N$!k:iq/?^4oə*x͏ MO~TvuM(ـ=fuYbԡbY2bC|#+,QqK-(.$xan[#G a  QV_.)B/gQmh;$!%9I0AƜ*mABq؈ zP#, |^Be5$8ňcݔ:rܛKZN CU<3~ޅ2' dw[Jbg ֘.66Y{ӿ}HvJ*ѥ=:nhcHuf=a?n܁m5+a7{:8{[cd[ȚQY>8o%fctf Gunv7}׽73K)&r ,ֈ1i}C,gvUsEq^NJJ`pڰA;I'b[E'miUDNJ-\ʣ9S&q$tx:jeeK,P9k^C<|RI3˦zs;FIƹ%NQWK\<-k8m !y]z =}?Ah^7—gz8щ问Lw_{ggWw(Peq%̓hrhdpb䋋x0ǩyid&sκ:HCUqh{-#zoWw8Ie>^Ñx1?j[jqUnmoGC}e.z{[-rxi-I$SC31~'uE`aT9G(R8B^ض;cydO(F~nK3!TYֈ} gϞ}49y{XWz=s;/@IԒw?}/pGѓp,'2y:&ꐁ6Ry"dtLN@Tomd' P Y/ ~Dg}#sK2:|l2Eq wwz |k|QՅLEh^V_Y)LM@,j(g֬=2/ 4/tF@uҝ8 >#c֬ +쎈 ,<'mW_@ YtFΚ5I:1ӁA hkpv?YFpFk9k Ax$m;T6~8wB] )e}鍿ek3~6G9JC8O61c,߯Z?Pqd u-O2tF GV\1ޞD=DMz{/t-B/뻟uֶvgjG465[!'d R22\1)tXPJ,&4Q!<1rNj_؊MlS4ՎGDD";Jr|/ pIxg7;ifRKƺ3uVnO[0Hб٭tO:O;՚Bn}o_ןڎMNVWm9!4ׂsʱ2yb4'vq%8ZTjY,a~6S9DR ѼآqȊU-Α9T 阃!ކ8ҥf^K/X qoܙ~ݭ3ӜܦÁx=j1]?X|'N\xs|xò!e2=nۑGRoM Ǐ;[_%V k~M1pi\3M^?58UC[=*k6Oۻ۵\[y|c8~g+TO"T;9k}u6h7/L\e>|?\M?ZY]Wx}ْ좲tL>j%ݨSCy" /$d$Bi<1G @%QT*(Y;f]'tO25L{vLdUU(-ΪG͝w4mAXG]anM ZVfP)6|N_,`dxG.3D۵{,]]Bxo)#iC\?gqWd*ߌFY֘.66Y{eFh /$VLG&]N:Jt<"5z8%guW^kUc >Tt=~ ،\P!zK3Bw|1Paϼ?[ܶ%>"Zcp݁:h_yhMXEZO2L畄Vz>HWݏP뗻,]EcCxHWLYW Xoɢy{b|QqdH:ԓu5=ujVJ1D:n,mMIL5#'%xh%/.tkq1-J>1=siTRF̢ŹywU Z%Vrʉ&m]BzZk=GۻGIkey>|J9a7oOP`0clz1s۳⦉ɦLF^wE]@Ko*$cqcu?y S0)}+Jox)X΋Q#~l1/Y㷼lokݻr!w)mYܟ棪μV1q+ q-"XYiOݓl!LR'nwDj#H^g%L.}pSyq2W$*n֣!*%7Td1l\ڒJrTTDTK$]2g <[`hc@y4-,YPzo :ZLUMYx NؙL`kۄP_^S*`L\M3fk5+s/~ٳ/򑏬߰53Ҏ)|]_uER(:9c;XpgHx*+t/"<1gpL| "0p%,>?OyjxAkEZ{~?P(f.?XP5>Ç˖-_pww뭷Z]T@ +AUG#@W%j(g֬=2/ _GSAW$5fgXawDTz~ԗ@JtFΚ5I@ϯDÁAW]gFkFkF(kTjJE]}NlxzK6G9i!5o5GME/x$ӉV2p&OLajV/`D43b&IB[@)| a,_=E(f8\Ћ#MlS4ՎGDD";w:Pu& źky#Tw1$ {>7xk$ӧ0\MTb8yPF v9[rQUgu,I"Qqx[j]=ЁcǏp-5Q'kqymqB9!znZ8Q3',;ymQqU#tܗ'!䚶ц`=ㆹџ>:о+Sm;ood>wPxuB_۪ZN)9Pw{ǘ#{PWmb)E\QP"cK bVgsELQ&Jg gnks2yE(+Z*#snǐ#rZ)RcIfǑ"㟞_=rfUQzw*&D`"72Xĉ/^|1o·G>,G փo6qɥrOo;i[zgNQ^|^̎Bkvڂ8#vmZ.lê~b0N /Z:\iAn^~NeXSLzU}T|1G(e8×ȪFdu $zƋr?8hw{8YUU*JK*ssiCX!M4EDչ8:<5T8X S91xoi3'8]D77f1X ??w]ll3?epKGB}mCwQ?=~dc7 !$8m?1ީ?s(=ӀZ-{gGn>$^^?W-S5i%Q\UHF^YN-G\ ͗VFi5ւ50jʽDR#1 bZ B$AGOLϜE{3ǣ"\3JTA"UfEQ`Y{FlTj'C? w*05۔x}X/$xOPG wXO6-{gPX^1iC^6wܴ@H/3'sV+ gQ18OQ_VxY)Oyd&XUS#d"+d3FQog`^bAA<| ј<(TYѾɢ,P}1m|ٙdV_VNtQa)k{LJh0\̉ kҩAAqz%>{I o"VTWo_*קv-9]JOÓt`q牫?`Oχtrn#+Mx_^IENDB`backintime-1.5.4/doc/maintain/_images/2_weblate_setup_09.png000066400000000000000000005766051477034762000237370ustar00rootroot00000000000000PNG  IHDRYTpsRGBgAMA a pHYsMMgIDATx\Wmf}v.Tł. (`ﱛ5j41hbK]rw]""$/-3ͼ6@ u$@ .@ .@ .@ `pc L3 e @8;3g.aAR//wx t!ȯQA!­8o{p:b;F G ՙlvwg(a}N^OXt'Q6Lvc:1wL@;up\;ڌ3# B _s2۽.oT":JoхmX'^jK @wTbͣ1Z1Z\ &}"X+)}!ȯ !T, Ucn$8R+F2&xhS{p!֣0@2E[)ّv'u`; FAnLs2ߔ!?~ zI &Lјl*2sbuF&Gf~=JEhqD1X\L pDΝ:#?~M$h^]]pDo\L )&+9VMSuAo.NAgWh­՛v(zS&$#3䂾?\c j`U<*f`rj)Mbts~nzw,,>DDP3$li" $""D #nb"%dݡPt *Jlb8sL`v;_Z B&k$:7ĥdn3dԔv1;*_st c1Z32fQgeuy*O'٢i2EekXbqDuJyϐUw]ZS!&)lFXw(fMOYm>l&hDxmpyR?raA1qBu[Xŏ4/2?[diFYdD+esA_0O2FC&Zr eqNH#=Y[ѳ(D~^l%z՞ă(x[Df9 %<ʞcKſlFpe91<Oԟgwl6JiAaPz(pSbmAO Gy,n2-TiMά\yŠjW͓f-<:#m DZ\r~:h&w|\Pc zTbR~%2_m $ͭhL^SgϝoqEN^b򊡽4lԸeX,5?hv8 !27.mE}CV 5/V\pE r2Dr<1iZ$譙̘>$:{@Am?? ,kyGL(6w0:*յDzU-Q 4۶Z*c`>в{ +7z藁a?\9B*2mf>nrܰyw;3]P^|8 bBNŠcxpfeλ IQ9{iEP6``  !t@0) zY!t:P vۧl@!J]>Ya &;$@v#'L,dϥ¼i5}/۱:nO|@@5.> uF%/^Nј y&Z@aRec@M̺on-Q2EƄ' .!ټ\Q^tP%Bƌ>A @R{:r;w?*=4KF;]0 ;V֕Wsz}39E6^Xp-O@u{xxq_1ܶh86a:OEk[u?͓YJCҤ 7~Wn}'zEio/:{/n\;Ud s= (f? 0P%k'Y%@]WI}ް3OrF>x% }"RUy+/R_xP:-E(Yw\Ujj9|61x3pxDBLgPN\jʵ}M;-(p4.ઘ 뇺 !ƾ D~_w(0ZhؕAg[BZc J#4 rR­@ξmٱz %)NA m{t ?!u֍'m  u=ŐNqAP =z=(MuOi梪7n|${o-[:r/#-綗J2X4"6T~\m~hę ` pF ?DSkC%C}Ui$qeZL-ǟ~HHy/_ PUJbMїe}qXT ! EҤY{畁V&Di-{8-ۨ_ܝgirx;NP.?H[\Y',S\*,G D2肐'wA`x5\W7T$J@OYaWm5 .s>Wbzo^QtҁKGΪ3рQ"rzSqA[L3VLS5Zu #&.0q械H9= _q37M.VGYt߼,mxn8-<~rΛdŋ{uZS{Ux3aHDK3es-<ڵ3NW5mw!7F<8|>6,"ߤy&U_{D-MyJ.W턴 I.LH6x$  m{yKkJP+@Ŭ9sE&Xb9a F_5t쬥x{&7vtdʄ1+^x挶cͮa^Ѳ1qZ׿;t+|L&X.$.kV4gt-ҵ؟>y3{xrA_p)sk6,:V0y;:ƥYlbWO0 L T$|֯8u3fȊ1d'7s}#,:kk>F*U>xŊ.h)nz və U[y'TgylaȅogNҤ]VwAXt2i=T|,7Sp*؟xk)uSSϫ1|BqɱMy5d.<gOɩ9kR9qցYFqlI3F, hx.>f޹9/,HĂؙ>3'P$TQtYeKW_T`5vЅx9CGEb q"oPU/[f53SQL~hx{Ȝڷnz/ŝ[Rji>.BYPu1"RkpF׬^~Gͺ932q&Kvi\wⲋLw+c޽BKoZv祻oݑ%s 7Ku3}V]7|[w/[wtӴP ZcL;C\T_1:G %ʄu.N1ca=G6 v]Á;4J4{.Z(rJW?浽ϝy߽L7=}gH=gbř^ޙM[޻&ק Bnm1Fs] Ym{ۯN,nrKDR`k--̮'tA6k6𤋮Rf 64+c\#wh`cu]Z.%K#cb_z _eT|;^:s~!}V^tqɒ7x"sZ_kͬx᳼#m.tSo?TUd(u[8kRnݿxKW-[a*\~K}DẈNŔ$Qd7X t*t'30pA ⚮-.w 4xӇ yc/el"_$lRMOU˨sa=Gm:eqܹ^~i]8Ym[t |r WZ]w躉V SW6b!"㜕_&"R'T0q,j1o?a.2S>끧5/dR:E* D`H3$e{釈uF7-뜕DKh{ڿdU.v=8QjXHckٕ"1$7gq)Qy*9LL tVnD-1yhosV|UrЩLa>6Rt9i AX 6ab&bz[Ei fmغ)۩SgY: @ WU!g0bmX_,?#œ>0-JMÅ&*Ϡ B:k1beVUvxR@!ט"1WIE 'x;jjxmG0,i/Ċ9[ YXU7lt~ 1a;dw+ݼ;93^R^zעYνsa,|ꕏ7NH;5mۭwoL#ѳ1yxw'VO y, /y#4\x׏Heڶ\06̑2x=i{ a+]dV킭]>-ؙK\«/]Qaǧ〧PZVm4j2)A|.أꭻs~|HWMQuo)n=[!U*9Ȫ3v/nj;Kdl wّ֙.3ly飿-9n՚&O@1+.Z~'pe5mv/AD؄{R2|ST_\U s+o7?ӭ {2t죷‘ dzUxݛ?vٙw?z)1hR!CA~B􏁉J|&>еT? H3[ *{AE} f'+\,KЃJZYswp:ߌ܃}V&] ~{h˦rl!'zn+3xߗ!zy $3?Ty!l+#!+o.7>p𸊭fS+k|.:e1E8bUedQT`#!*YgbVtA}ʲ"emű"J肐\_jVQgጞzťC tok7]m]UX ;"qR &Ӌ8ʋB)( q)YNj,Θ.doZe\r֊mM4$e.sSۦbEqhxloogȚ{WΟY7_ N^x%3F  TTK%l^w_nE.ز8kiR˶-qFgDAR7yԹ++֘,n>Ul& % ~vʞ9l 7_f]n?zHA-G|[oAY"V `huNZvMpcNi(OG<ZjcTbGW)Q!:1#L:RC#ƕuvZo뇦i#IĖ6=qCϿyQ˯y!PH?#!-!GK#Da$S39 x>\`/2(Y<{"#>% e h>,8›Ȝ*jgܖduC)TC]QڸL< # X*9JpaШBzjQ3_M~_Wj5DN R0&gq0 0c_˝ Y't G0& EߊeZ4+DQST~紹˵&R~f Y~ƻ7nkȦ7.vڵb"l{XW;r[H(ݹ$X>ZEr6.['<tVsG޺Kw\3ѶY^&\uA##%@y% Wub!D$ ۻ,ƒudޠ.8+W-okpUsG`事7oH8uUs獝`_vٖKN;T6w\7t ѣ߰9+fwUr3U͎"Wi8 G([|;GwobHY^QguL`rsG\;_4;< mɳ/ ۿ7^p64i"0JERi2;ܑj.O Y삫O*282oŶ-^>FeŽGP*;/JC&"?=&Jw=OT|W+ىn'$@O##=D./}J ^`d_I\"6?'RM(xXʻ g`Ea `. }xp*p}V` (Ι\]W%`Y\pdú|6}=# >bg <ʗ%&фb;\2SЧ~ꍻTqxiٲ7;D|x' pAK\.<^#'8S.4v.VtιU+ [_Wzm=GLZ\ڽ+{%VZvԬ7'oHr Brlx󛿿zrb[#W?z ڵV$N'\pɋ[ʟkÓI[k.5etM Z5JLp?5eZd`7l\Sg/[1 q$ה 2Fa.>C$NHa'4 G{k of1p/B *S #OnQ)>?w$$ˢsu9L Ji뒭oyټ~"EĕΙ;e`VolrQaab%aTy\(U:{M>}L@2cQUia\j{{:Ԇ,Hmu#6j4b@zWo*:+5ƈWm}\\7]0lzg+;D6΄eG.?bƴiCO=9BcƜ#B䆎5ݨ6>[kM7:0g۾Ls>ePHg0& e_@+QṜ oH*19@[q9ATzRhU,5@}34?u!V k%6pN !8蕾GuBDt. FrNuD_}=G|,4N0kʜ O{(햏g!\a"` .(dTaJ0LG@ .K wBPDwhT2% &kNilBa6R0EYb)5Ma\ODŽbhY"odQyz+DĐNwA>4pS(V/$A>.Kl _C:HbU,Ν;OڰLR2?+>LxB pw?/VӸ 4 J'.×tI|qݏ}_ ^ 8|S&Hؙx(:Hm2#W[B{CZH]q-׀/s9<&|{$9Ϯo EsOß10aS|-Rc@ItJ\9 :JLKC ;OdͤIdߔLwA\bE"g&eɢ$&04"VxfYxPu 7/%_$2',htAqX~bDD,鮗[d`Ne  Da!/Q%ct!|dvZ7?塚-!G !/q\02N<#:Ӧ $.m}T{m $7Fƙ"|V.N|vtjG=vs PIťeT]PkE8킑I>OGT[e;2Ӹ9. voN32dDn-B6xպ3 7!T 2[@]ih% [<4J,#@u9\.b Ԓ,PpErG*- _4 )2k™d X=Cbr1eqغ=Sl_ Y-"gcPp|kzэcL\ٺ9Y|A!<=& =1Q@LBKܞ d;H=ؑ!&8BlPT%NXRDz/F~%lFW$:-VXK$;_P,"(tp =~f'mbe&~v:>NP;ؾ=`O[upl>o iAp" n1wkނ@&Zx?jx5 lځ0Nꊱ8"iPrq"a CUGEJdE hlo^ٝ,(Z7g`lTeb3ml`|$?( #V.d}Ɵcoʋ2\Y-$U\XFA?!]2L7{\6W, w0'U̽2[]: e[ p0kWNtlsͮC#%ݱzWSLɗX@@~E:H Zݍ]Kv#n:"DU[O>v 4N̊> $j'>_  ȯu/6-oq^MFhw>y"/ %J3[Nlrs \zW÷J߯13 c>x$|oxpn<-# )?rc, /' @ ȯ@ !@ !@ !@ !@ ap0A`&=ys:xؠ@ nE`YP:S1Y\z G4*unEnfflf 8N DP&i J q&?0h@ .̉ gտq3um AS}ae׎ [o-JN<ټեc] #TF5 AY7ꫜE;PQ& j [;E891~ǟ% "6Z,R[~"h(kڈEV:R'5Ne+we u@ H emW2$Q|+Q$ENޅ]`fP0 h ܷs0mAW;X{9~,?*9Pc(ЂQ>ؙA#tH b@&%zlw2p.![ d98k X1H2|ΤP ƣR)T<A S`j0tJ 8@=/\E *Bh8P隬{|7^^j6^cbB zx%fmߺwM˝_?L!uWItѦ?Igˤ9^7{%Jv+Bˠ OI`K[S4E0]W~D(@hA9םflW=L]L̒zn̕ݛAa :Bi6 vq[ Aq./[ϚTIsp4 P0:y_LM)t26*{+Z2jLρ4ĶUcU]P}YBE{vvd ,rRE(I~cㇶ◺ogFb$R1sQr?{n>X, uG9@  $Mϟ87']@阮gf8ti&0+1aҚw_;C/}x"|CVUu>3zŐ.l.ݪAqoyG g\?%ʯ~t)C^q.ɟ}ҍI\PqJ tPWZbP͉ ֎=Ehby_SLRo .0t:`"ur >) ¶WtK FȄGCr<)T 5u3tVڗA:r qzmH0:xlr" t`f""l2T> 5z=ۉ}@8s.Plj+1Kμ ҏӆN&,MjR=|ugAA k5[36EJm^BsQ u@  %ORb{y^My8mn%tWy7=mKΞ|(/wq˧v#;{`7Bw^yY1 L}v 8N䆷U$e \v4k.5Ls_r+D;cՙA4N J< $ɸpJ 4HU} .DitvDc1{\%C8l$twiC~mQxJYA{xG_Q$۵dj|'qF%0BQ58=4L=On(5sN"j0FiȆy@D*]3xz•᧟L-`И8&vj6dPŬf\0v?£4j[r"v"y`7T&{B HlyG.+j@weDڜ8 ]@ pATa8swXa.UODft#'`Re~;,l $lGd'RΤp`$0z_dC|4aA LTntA}ct-暔?Jx)nlg`;|!*`ǝ@ $zrHM~JMםD;bf IE`7f0ҚjKx L[sV$ gvg @ 炼ïHtTlխSg.^y;gmޱ/"+^8RՍ>t%g| Cjy굲99x*򚹠mLljs+ W N:h5W6VHUMU"49kW\ $@U2krﻠ,:f3ѥS൉RGWR#Y[^3so/S4HfΦ/Nc0%yI.zؾٗ$F7GSHw?.(Uz%q$}-A8yf'^&u˟<)]f{3Fmw*Ճ26g6гi βTSEtr=DX \+i{Id;r&RlH7V"9荄fS$ʞ0ea3Rq3*= / @ 2pgP 0%ӻRS2l~0.]nDm3TLsE')D LnJʊKJr2@bNH͎+-p:B_jkQãX g cĥdG1*dzD F6BQF(KH GdBSG]8\!q! `Bm@Hf1yq9ĕqbqK#UBU×{pU "%dq"]'zNֻb!dl)4<(O`r[H% B cfP-;pEdI(ڊF5[,V1T/B8{B,n61M"gƕ"_LUB Db,G hq ]R/^N;!.hd<[-\ơa\ٽ(BY<-vehe`^>[x.(M~`}DM_:xJ-#A#~P ^7f"ؤd1K/>5C@߷X ऴ f.Pؽ=B&d{ x:>FA>pfI8T޽5+V|5 .LpAc0 @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ .@ .@ .@ .@ .@ .@ .@ .@ .@ .@ . e v CH -  3L>b₱ _ K㳐(OaYP0>XX-,Q,$5b)7IBZp+ pD?+rUznqS\~ہ9KV7\m;/9#5&P濭Z9≡vbY 9\\i-{W'׆0/8H5tF&懂MlLeY:aɣa\~c;d [or-o DɠzNgmؿe'pRD_ ZLǸu嵛խ$)=W`KU.]S_½h^~AF8DAH0;AVw⪺UkSUwKk6$uٿD#'̬X%# C , `WokȄ@*N}K[`B.H:cZݯ'W x|3;&( AӺ(Gg/[qƂ*na"_(;tmÁ@ڎs;Py[ fg͆x+Tؠ;n= 죲RR^&r= f?m"@{z-tzV1flB.,Y 'k\y;68#ɋQ 1ߟAGj0ksB eL0Y3(_bznw l5hM6Fk{G\.8!tL򶀂AxvBywD9y ?A.R0O6ZaaUҕp{lPBN %PxZJ$fU T-$6gˠRN؁!.hK pYU% :nQ0ATBVEQ[UiEw{ :.{19O?6^sĘof׽"X(j+) /IHPHԈՆ űՍNK9zjG_%+x<\jڭWߞ~=Zz E{/}0{ lKn]|=9Ln}{4p؄}Ǻf,1 %F `ʇ:{H{DzS0ToA(VG2ge0>X5ȈPY-鈕3!,%ȍme A]뮞^ p-ߩcnx,5LEKaGѩ,⑸M^XNTß A[OG[Fa'l}\RAR ֵp6s~x2'"躹7V3p12sj[>(;r0MPn=`BtoXG; tc s;F?v;䝊Et²oftLZ9P :u@jcCĔtٜxpدQ2z{R8>|&tRa@Hg7Ghҝ\ EPfdeanuFD]W"l 5%lt =#aihaQ$wt\Ja3p%+cWYxrB7X ,kbe߾_9 zɚDr|J/pAJ=cX)4l&>ohZ4cZ7}g25ִ߶: )&s+QO^a-]rfVP7M4JuWAa[w|1)~x?دTI/"nӳ^]5p|wхCys]MwvAXa{};L::+Npׁt'0VHjQ X qfGzBpxBL.~Ts12|`S̅.l5 t>CXyu5IĺZ.4 -~lzBbBGP Ě!.D(qx(BD'[8hVOn>vWk:0𵝣2s`Sܚa$<<4eI~)cbrJ(cկ!\gb^NnNL|k(]m1m!sPXv-pLB%L$ry (qN]% < _wA9bj~}N EowE` @Vd [V&<-\T o u l޽pzLiťy9ufrm\$cDR[o(Vi͇姺K0RBW$n-);vFq}qVJu//e5?RanCGOUfFO>zpƥ>FhFt`L'vulIP H{'~þHέ.v=lԲcݑSsySz}oo.ϺtD*fqnd9/=OGΓiRܻRkt :%) *CJ-/[#`Bʒhξk+VZMOhj|pUCc[]`-Y(/kx|*nl/W\mۙYO_'Zm%+׫|~ 4Niywf>\2x3[*/35_]p |!UͣC=l-V^~{iR=bŹYf MQ" S9| '; a6 "ǜ6^˯{:sJ+Ba *Ϲ";zE=L8 lƞl@0vŅ7s1[T|ÞJnyXXRuhSjs{ӻ 1⸭{aǯW`~C=?hG}}dKŕkH 9?*V\:3s%+.Wm-*;]^}c$@SV]0o|/޺SuΙ\]~Iŭ{ϊBEOPa#.Y)',v:3pa*BãmKI`s'Vh, iAB?7Oz޲ G>u/o{^<|XVߞY!fUo_t`𚻯<\vv%//Ϩ~ퟟ>o>Sg{|웗/&;"D.k1!βf$dKrTF1y-,0$ʜRؿǽgz^l S+a:n8[]-8ķ9z Ng7CFR$a1{gAؔp$&0Cmd#TV. h>C W WеsӖnâwZi̧e5ٍݙnP/3' YǤd V7. aRa|juҾ]IɄ@ z~gSTvC)b&e=W)JI+tސsX8/P{vL9lb bϗvA!Ee32qXxY'nP'N/ q G>.#ݛӃa% &8tAXd`I.X^.k|ZcȌFm1 khhGCur`@z@+ ؈0gB1$>߿&لŧG_ʝ wЌԻ= ud>sXqزޟu o ĚI[mK ޳.}~xTp | JRxphWk`͢^vF Z _ڲ ٝߔg$^|jqA(%i8c@*f2=@b\_~?ZgpfMH[=X1Z2N9Svi喝ynLccβg_n,.rs=f vۻx83pЪpf>U(b붊d:Sf.\<^-XȤȕwN]،yKVo"s$InӮ4~T_i]-|KȺl/{{A63sYzXR~=[rNSI=zM=WT3 -oxZ{!fjh䄢o.Egw"LUÃ&ϙ78m{1b|%䂿aQkJәBϊOg<2dr+H\WUui%ۡG)6[$hLbMYcpaY${Ҟc^.g=9`ǭGU d4z?LKT3ե=L,;i]p`WW|vZ-15CKn>Z;.xd^{vpBs1%:3D/ңG>Q #Ś9bQǰdqpM~ ([#U=,VPZxٮhK\ saSwop`WճC41}5ܙ$U:+.7\݉ ^ɵz/Uuqj댇 Uu쮬I1.H$3Kտ V hdLV]J?u7s'`o);,}qm4O4Gd5 悰y5C3DmM+8Akj@o}gk9QV=  N_?/vh(U]CG -iaiN,ŷl\iY)>sF *wu1B q0nIg.8xﭷ{HGx.M.a|'j[ O(x+T ]6q}˴ %XD4v}(w\#VͭP7%dG(kj3jL.c0tAKLiڀIp"[:d_9:6g"SFU0\E@;/ Z%9(^l#d?ŻG̹1͊Iw~lL={G `y\^PyхfLsf|xBV8tA5rSyYwKo޺VȄznAZE N^^';hG\{G%vF~1d68Mtz3.h ߿γWOr/e*.*ZXsrέ=Ϡ+B-!T\ 6/M^m z)*ɒ)zo(UP Fg3F3JT8gK.Ȣ)! @__^;X& G - 1/vPC_`ttzxSf.:-,;ݺ~bnQѓǻ= yxs@~; i)i&%J6/`V =16&]]|6G\N~d$@[v tA6bHY3tAعL7hkk5JcI/A)Gj^ngx ;Q>vl3)J$.1ګ߰䴳rmFaM5/vYv]#K+R,[uFt,ӽhց-8;͢bu/{PE[)q$AS 3 4i\p}p@(;uA>%fɻJ.nkmvqc#N>G 94㎛ivzw]Y]a2JjsÃz1K\zo>YV > Q`5O$Dyʧ;- 9z.o"ssx*un}i(9F?F}Kt-_?o:(XsqW _f!71f4- fl*hoN#ufw3c”gM>6t! )i|5,ͣ}?+ ҁ$'\TزeaZ/,cT6ʳol!<2dMgS=qg ju|tH!r߾Zgׁ̨wH;wP| <;v!5U W{̼AWi);=IQ#,Hk黯WtTA]fCt,8m6l~ӶP |Q\f3ts#X -$O՞#`ec/]X3˭+=t#rƆ|A>[>gƝl7lҜ=oNL"e!a _vHX'<dž#YI+\`3 d+o6lޡ" W(^]5]g*NnpX|u9WeReFvs%\uZϿ(<EpB\~~Tf@1ѫs橦9jikWG66@s O 9LV-6d0:ƜjH 6l%CX8 )ÖܒëcffՅ0@A̘U=g@ RU%1|G 0kM:;d9|r£70.er9Nd )sO]:)Dl3)Pb|#On 'tAMu\|\jEB(9XNȒ<>ɡ̼Qwݖ{ˆ;,g'ZJ00mt1 eȁ'kzk\em?g.(1s\Vnãd$ΗIs)~YUo>:S柙ٸ`G.tAZjriQx~rRtA ̽ uIAN׼6Dキ;hv~u T]3P 5 Eb1f! {PG3dYD7tE+78mEqN"v}hanQWm? & ufY\زaN S3Rr %-O0Pcq'AEZ+r/H<}!ev%D%W=xn;_l0:[hbdKtt8"X" 6uzO $% m]c[fI<߹*.?jj'?@=)i~!2v^濵h~x+>2P>a?AӼhV8 ?u-Z[w4"}iWg.8GqS]y2-cئ_rw%;b[Q_D.sj"8lJ#~26#bƀ6QI,&]{Y]5+šl_޽%stlbB {L]2Ygp+/Sg3;|ع/7LLI ȠSNłyIy`rEp̄i+TG <"=Y@> \&=G0O|j]X\_1q^Omx!q#O?%j#YM=vkXdtBht 8ˋ\GB8̃/mCvY](|xi-tg˨ć`3N$.$ ⶙827=Y W&<;AA(CW&Osi=tt*te9̙+Wx_^ޢ^,u,]آWg92׌OսXp/Ղ6Z|ѺNPJ0B$^֖f p]?Pi+T;=\PゎsRk+BmKK9i\zG#zAs@EbQC= RA >)1u t7nΛOvָ7X#,}V8ᆰ^lHRisn<9r%7)K9׼j'fFL}7NfdK4[z$l1s oܪQ0$v;Z_RYPѰ>WJ +G=ʪnȏYȥH?/_,-/wE` ?Ib}U0jhf3"jaRYh5y#MM W 0蝗2Kb `n.)< (tݩi>= Li0sQB“RO/[k<>oޞE5+?)JʜrC\) v+= #+`AaquaeJ77Yv :xhˊ[Ncfv)%naC*ϥLU] x9hx[vr|\SvN hеǏlq(@[K:ӲVwwhN)u›`'N8k~= Cʫn_4f>E٤?p)"]9GsKkO$-qu$2z0*?Qa\)jÍ,wql%<}u)AЦsvvr9wt6bbWj= :\gϞ˄CJ@oزndK%2K/e^ϋ6f֌ [7%53k b%i[KY^~jazJ{꟬ԅv ޕw1ŋWnM#[B.C 9e>nPXqq NZzu<'t\6w 1]);`[+eN*2\:1XI(#fW5,5$o'PR{H1'Ty3kt -ڗf_@s@ؿ8ŗ?crFn_t\E*dZ;h / [-A^ɌPK8V`qh=5x̷ N[ZpD-){?m NݦΉYy7K o7cRg~g]xX3 +T=4ר`¦)MOҒ]ɢxAG{.0TlHUmSatYx1RPazF2?Gbx ̖}Ǯ]bQ$ )o$~^q#35 uE1yC4%K@`jBڪD-dMu!~ ^I;\Qh|ųw~^~5yClk@DΆOg8S 8\{T0(n@l4G@R\9Bծl?90Q;N+OŌnVY0Bh`NGshD|3!Ik*F 8L˜ML>0fi2*\nۂNj>߇fel >l"DIEsG]#KR ;ʻK򤫮>mghPofje[\$yzYOBk2-! "9NJB-d5A:Z>O/Y,Ŭ#I\iJ-)oЃ3#֮6V >xx][R.hJDG.`9Ioi`NO<ɐƅ(/!FY&AUƬp'{>P$7s *Ve^YE̱RዔOyWv)q븍眻wդӤN#~U%m3!D.@ @.@ @.@ @.@ @.@ @.@ @.@ @.@ @.@ OsAZD 񏂋,JƢkrM D ARhnSƚ<_zFV@ !zfQb u,Q6H@ !D =]GS3{)z%9b@ H! Ush @ :S@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@ \@  -Vb%S"|@ A/!!D _qA(P'M_z9M- 2!!>K~xŽc( <Ʋ~˜?0ν=(}: 5IR6ߎ$7W AP.9tP,'8PO@Ah h͠"X(\DP}Y[@SW A~G/GB:@|Jm.Z9[wUDǬ`KjN+{c.6"ί頜OX(NrՔaYAdۙe A ެpk wo\+tXqVRn)Q{u9S 4ߢ?A(2[Ԇ|_ R{HNu ٲ;^oUY yv}_)spJ.?deV x\-_urX'sA>)Pƾ#gv8~~oF+uذ@ç>5v43bv箌f!S2҇g䂈Rۡ jFP?Y ᘪT֊?I'h}A ? [˸#ݼ>삎TG"ԋۧ@KSIc\U,hg.(HRs|HWֿC'w!{O6B.>1vwN Zv~eE.(2Ð "5C}KVo ola?p\f,.Id~8y7l LP :;Kxu{<-2J)%̛jօ2RI+"JLs)lHO$̭2#ݐ "> C 9%ϧv b U3Uc|1C%wM 8plEHb(|C= M\GJ Ny-$c8Nvw] H\FI"ͭr\C ~0\FEJIeE>L3+~mڝdSF*+/- _)=Gw 9YrwI+*WyO]k~3RFyz %HIPB62Z$6&$D?F%N 9֛L;/j]Krxsx1߹L"ͭh7'#r)>0 gnHcm #Aw]ECo{`ON]CK3!uL ;ǗrIѾ3kؘ@;?f31D~C`oN<8?vOI l7Jw6G LwJݲ?/:jRlqtU9\1R]/;m>req #E~ƍ#Ej :rl0q-kmݟ]~m!YE D|!a'A5>R@ nGtޠ U:WJ`6Xe$Zo| fc#/i\oSf-]GƊu񰟹`WkΡ\m5iSt\B) ƙi:$Q4s {Tw, :w պ]8V tF;-|h q\>d |fE0:g3^aa%sWMuGz:k v0%F*r%Qыe0 7}9}Ob1HJ0Ss"g/$rZBkԼű{xtz91}>3fe8N_(TfE60Pj \8e=x+/5ppUL7 ;>+&*zG|O.xrV ^5ƈ^k8inF+i.MB w 8ub1aB(Ycв5}sٌ9 BGЁ_ Ī䬘sgMA:@.{GZ"b"=٭/BtAsz!Qu>A KoȮn\OE I_䆪IN"1/)zqߍ9R(T]U VidDBS <7eBsMD*P>(H 8(P]QI]T̞ /&Ta̭䨂OкC,!Yt+TcmT$f13qLG9,*}sJ "$Pw ?~.TYzRJW! ]K=dkn$bWWX 黰M=WX_{{#a@@A1NOk/'7_W_}qb.Jec7>|7?wzt V4 }bT>7}۲s 6]|C ')xA/+xW5e1cBR zu ՖG8v?<>&2{@XlwO,I!.Rݗ-_' ;wBhs]}ɷo~!󓗯r.3\1悍.]6/*)퟿dn}7GaT nчxުoY f ]n>[V^oLt'0 b2O?s/u$HBQ@.OARib#BgM==i\oG[ؙX:@)ُG:2.qA-ձvۗۘsgcg~|_چ[חN#ϪxP#6pĮ|<},bO4gxȔʋ -=]T]XVP?rAgeΪK y-zUN?&}БQgT3Vc\hq=RT7 >.T-t 9H UrCJH3.7$ɤ(%CqgoUh#[]0Y5!3U18#3ԚT3*,Pb%MzWM:w!30ފoqqTKiCWd;hmnUEGPIѴ #P2*$^ JB\o檆 ?$7IDZ-}Z5"v3|K 4gYa5^a4CњIO ^uy˽#=WorAӒW\5H=Xak^ܭ+2_7 ,iQѝܬ {r?X7u QhW6]td@ws*(R(4y{:7=p0|UݽG% CIٴ-ϞK\EAH29]~l|6p/yq_!6i]CSsMhQEY/A,  -/zb{o3@:1)Nse<<W킷fyd>]0qy݂+i=]ߩ5Ϛ7oދG$ɲk-O>ǂdnEX[{gb.h!e=(VEHKnNk]PXB`;_6?7 phR~\T"D߁A{ܶHsedQ  :ceЉl. \=.tcތ{Ůٸdպz"f_IꙆ\SA+&^ٺgxxkNp7fŠ9.;x䂈wvm@`*h]*T2~u`j -s>j\.FhԽIWT>8 ˉE8ԏk*/;" Zay" : ~pEe2?'(-=y]pr){~ך 3NG|za}( ݯ`Vl~Yq`3Kh 0?yesd|kad.ByW乚WEv{A1QcYA˷U[,)XAIU2K.u$\sI|Lb9xqsҖ9lR Hð=<=;VC_I#&B@xBVV^ aZ<ɴ/bc2߉(vI8- VVE8hlj |_ YZ7_{qS,P@" ~`֤&`& wbO:C544lX,3ApI10ZsXO.h>c\#؀m\ >(q:Akmt.N̸ %aLoZtAYj_䂈xX'8Q;JóUC1?rڭ 9l`r pa M5f_.S 8jP,/z0q?h;P, g_\Vz)ӌ ܲM&?{I6ygZ1nȴt;Gx*aSI.8dB[]m I r*-q/I]tOVM8+oodgPM8 -P+r)*xw@}'fwtAf1DUS}Dk&qe7zé㙱Q %dlVyi4o hZ'N:t2%՛u Y<j⤩srbUN+nR 9_u~Fj}~B@j 1>#&'m j^|eCnxbagW?˱}9~ 7DH~CUh? 1q!'ݟrE:0U)_阑鏧\P9DI:z$aTN&_gxY5lQz/͜; HBgl *1n;rQa`ֶ ^c36sD09 BlnU~f,xu&~wЎ?l\4.蛤y{U.<Vi(i sKɗTQ)=(N\ סN":g5ػ.b\vMo^Oo(Y:g?9/ﺠHʢu]{#Fy7}yĨ2V`ų ҋL *qB&ҳv ٞ~>_vat珛nw gjz¸ 6V54>l|?'oj7j츞RƒzWK\LUP]t3\V[ymg?FU{U uB>9sP$bŒ99g1g3@QQQr9ggݽ}_8aμwNy86팊W!ߴW<bι#1qU,o99 hji0; \Gei P ?t*kv{6#NNgG'h<1Hw?ٖG >oxG'H#+1nꘉ3{3xĸ# ;e$]# ?cE[lo߳,_ bO^s'y5 i떌e$+3ujzkZ**i[uā#ۜ#M8g\?M(%#Yv(MW9o̾|ҍ3zM@Owcݩ#7d;&tedΡ^;E !W;_}n'3#Q4׿t4`28aa.}б0\W7WXxzn#."ܻoK3cg54K u_f&퍯}>#3[}]}$񨳩y:]p㓷mQj> nz#@i;+嫯6fXt#Cv"kvt)\&?k=p0b^Tf9 BtĚ|f!(+̋{. |>$?4wFV5/_ͬjޔg?QiW{Ʌ̇|HadqG6Xv/pWq ϐ" z@Slu8b{ $h)Je5dPE1ٶ:lnу3l*lѴjo}8 h ]Mh;\|8 UJr]Vq#[9s#չTPBvWxǼh|wc$I;cqm=qN4sGD8Auw#+!b2EҚ@wR5:fT;Iq @X;2ZɊe %)CfoiBw j/kӞݫ*n3=1י 1s96 *(Ȃƶ_.h>˞4|2p2J HӉU+yqAԖ_e]kFܘ97\R}}kV2}ܥUø/0b¼|>UVz~ߍ7yI}x124& 릗J)=aSJ㟲c (4/'JY#G#Z낹Ͽ,L9)dD%+7=duAF,KotqZpX0U%< ]^4GYלj|޴e+'co. N{kNRbt/qACcљu̺h4$E4g$%93v$ `MIV~1n=]Y|ݎ/h ig65|8l7B{𴲶_ꂦ8P/l~ҡbc>xѩeM/ 9"wj|th8] _n7jGhRzqsUSSˆUY<=@U|"j.FI|=pKF :r!10nFrǜ{[^줎gdj]F]Do]vcAma R:)e+ִSdj\pvBԙY3Z1=667c5rDcj(|%#}\p  ;9%˸hSb0\;ZǴynB-(`lg`ũ節qA1\9_mP~eNO'$C"ϺGH^gvLM"ݱ꿮.|2Qy.8p_J!X@9ؓor=}XWt[D/.qAKW~G~ ҿkY>Gs+>V!Y)1QqRNW]x%1)9Abr뺼KOԴ^^?5-UBxi~ޞ016ϯ ̏E{^|YM̚ Iֽ{.xg*L)._^ʎ~S/ZN4Qr:rR~P]Y^\AjiEw-E#Iu\ {ﴽzw\te뿵.3FlMkW^gdRr@m]qo$]v=}r/.Jp=:-8A 8(>a70@\e4 H1Wza wOb'B#[L1Rܻgd#J}IOj8lӍFhL+xm8qBNx4rA{AaTJb|ڽJ_pNh۷q.r+p)ZsaB|Pq>=DȊ螇_%f?O u!|g$Ass/HfCF4'Hn?|% rKG ](V󂓞7׭zaX&NvoBj4c7OsXa%3r\JӮg>k[uPljF$ ɮD<臱4#\qGA%V9Ԏ:U@" "ĿJ)^%רYdeHu$09T_h$˧T#ѩ\SEKeDP4u01!)keJkաyu_|j]@S#/ =6%I̮];lZ-8:E @Šrş?om-uWqQ(h@.@ :(| `p @.@ @.@ @.@ '\P9A @ w A5@:@ rA@ P1@sG@ jG ߝR}c+]#K@ ~k "CTFr!@ 5ߩ"@ h@  @  @  @  @  @  @  @  @ 사TMH dE  =;t^+i@ ~~dDRkIw" 񫴵:&mͬu\Hq8RLgQq( q I p|.RFI %DM1b[`"J p%i#Q:,mYLU@.(Uz/D36DD][0ƍ'{?t6<|}cW"O^\6!Ŧf<o'C#mtGk({u5Dr@ ߆_YL;[.9f,՗O>_o {w;+s΅<IJOWW1Oh,cHӑ/ܜa=é~_WWm+|1= V#hdfkln ѷQa7hTtoGz^6̑IVO'ϧIFʓ 9raGB.JX;ihK0 |F&fPu# ĪW?R @ ~.JdG+_>~1THؑK1]~C5.(- \:g:]py(VA"X}W#.hhmBR-e:}h1@ ߻ iZf0`̝^;:X:YYY^xr{?c}#)7G[]>#ȍz> ÂCV :n!H.ث;%R@ J\jݨRE ͆sRoLe賗Bg+$>k_wKGYQ\u:=s]X5}0e7^:3!*Yt0 "xA& YH|JΘ24(Xi.2Z"+ 1CI)J:mq$@^ @.@ " @.@  @ "@.@ " @.@  @ "@.@ " \qA>HO5"9*5U~f[bDM1H׿. *Vݨ1wX;F$Xyco?C.FI<=Fc~ѭ0o$ sᮑQŝH!-eir&)e>ADXBJN!Fߔ8_7gх?)nPç!a`b XfXyV“vJ濾?|pBB.@q]L޽D"Eb{r*f ze嫪^6*qp -zirk"ȪmAoRMB$ŇZ<oJuAneP 8q"HV 616} AnƖdg;R "]Phi`s̃ﰴT )a omīڧa㨈%:cҋu 5?L}-&_,p-%%3 esi\ V bJ?w7-|]3=Mƿ,:Ϻ A0lHBI0\eFe J>b`\mA]/RB LV>́7J(sg fKA{E[/`?uAӣO$??rAVwzjSxӽb]İ׃CdNj^FMI~|횰K_9}Kԃ6o1`ug` ~vA肴bNJU/a5~) '6^ n/l/6sA$fl\ϭLP"Wwt0epv6yt/cn\ЪἂV?pTYiU9gk+\ݯlJ<Ĕ$C/U:,c]$d1Zl6`|lI#=u܏vʹ^EMp!U8`^j' JUrEDaݻzeN LL}[YTzh$\pndJAEVQ١9U . 20_v.)qBRL|~zQu::& #8(t6݉M V ٰʊ.EZ& :䴄\C>êSUBiR U.2GBH?bx5y\2ALW(V'e=^\X+vAi* eA(6 kbNt頊)7?kj/K,mxS8(~ Aق/* 5ɬĒEM+IxU}͎|dܦmL6'5f}'fʲkYUY "|;t'T]z QIf~e~mIJȌDRYueRq[ifGOIE CKs#UfpAnX-x^R]X]qkZ`mJ1IҼ ޼[dSofWW76~GIw3^9:,6]Nɯo/)(]##11y:? hPo}cÜغ[f|ʪ_t͗GլFi[eCB[3Poތ?ŬrE 'w%LXzq/b]0ZM| { m:uGdlW$?g!uj΢׳ktZR}{;ٜϿ8ŝ w=އ22Qr4}_M[cro=޻sbl8v./#fVփx@le[$cǝOonŸ'{_./߁暃Ov0˜L n{tdACq{R7p!OܩGx,]b;;A)4 4}ۼ`WJVaW\C~\j&V?x8rIB[b:@ ҥ D&o,3²Sfѩ@iba%acCօė7nou?$n4}{(?vw=f. TW͐R] 3p-q>߽:nS, /-UbH vA?g&,-2:KrtAgSeQp%vVN!`tR\c ]5w"~#f>ܣ]j35Gt,L>&#kkw\ۣ03@Ug=lui59u50u$=#2%3"J.0|ۗg\[ҢK1@Rf^>Czre*fw_^Ce8Cs}Oq]hBC0uWko$f ZkM8^x >[S2HJ{MT RNǫ+r'!u9zؤE6tUxI1pBkV人Yponm봣Ǡg Px|Tue alK~J"0pr˜kyO3b_o:{^nqA V{匮Ӯ{'6kNmG d֣fBb]yHƮU~Q.$!/Th:Zf)K`K.hk8mϸ0kUosMfW0viΏC lLG,8wȝwmv4s4B^]'\P*kTW%]1P2˓fOfScXG+ Gn(~Y7P6Tz^~ wU7uޕ2>b5s9ikNzxN.c=> L=b3[Z>﨨, n +kFS.Y_X uGl]&Z0/$SHW ed1\p vsb $ompQzr1C`~HM,*d:`Er6zBV]4giHm@2}uǍ5~A `~ Il*-+JLOyga+SBfS.nCyV>doai¨~^^'LMʧap˽Y@A}2_ U,)Q5{(==L DBʎ9J '+3i<Ϲ;o t&W/yQ zFʍ4sۃ3mR/wYT fN?͋+aPA"䦪 N杉8?89 y r%RY_\QUUt^ 6˾k=>FEXt8Z>+͜X5:-PRӨI{sK3I ,ON-N+|sw%_hXdY ) ;s*^b }q3$ 7 I$a>UiVj]Bo{%5\?g$B[e5LL,"Cdfޞ*z9 T;KZYgF>in^[|֔T~^Aؐ:wէ[3f5CϞ_^c?hzZI}TZ,>ᾫ:bRy|> #QAmz9[~hJ$eL;u@ ]57mWvI\IEqrn V'6Wk 2rSs SsnkqA2˚E-o3O-!TT&g䔤fKm˹ `ѥiUKUFhvZsu_7ƎʅbV 3NImܒԼW/j_i͜베 ޟ[tƐsAiK_MO`:&&\规[E #DbOi7/&0K?sUVr}P׶|M}?Cqί&.H[WU/n\B׍qW -x2rM]OF t, '71K̫GWtiKaeƌ> Jس/UfoYAȻ[hH\h|sKMs.C >炆T[Hg!?| gFG _DzJ_'{Fro I P ߗm-X>U3>ng4{o L 9XǎORz/xƼP6+͎0TДX%I0LM:lz ,XAg ,MuHnaSe_5ͩJq옍˞삙(0D]}dOLHw^v@i#+?D邽y`Kq j ~[մߪ|8!"QOFEO<5|FIB)d$P0N[d0ԟP@ `mik _@p ~.ud.Y}-~|= uQ1ϼqȅ;*=y.8Su%e+ιwCИ©><#Ϸ 8SU.[g5ѮJRF|-B %\+I_LSwٜV^*-mY3qi]ER Vܛ邤G.6ǔ }?c̝vX5AΝq \t*5]0rо8!5e9Q2qX嬯 0vp61LRE9WTɤk;&S)k@fm>z,lg͗bj<rq^QtŇcidGlH(>Y¹*R`&qo\53.8I񵊯ոG PM8EIg38+UA+̂$:/|XyTO%!Ej[bk;U8\H#6,,u#Y~й5 eVpYC=`8'' Ժ MKEO^Yx fʓ5 ս4MRBI$5lYz[,C@[  ;uME+7]R׸yc?Lpy.*陹Wy}VI ^l~ Um?gn {r0ߣ rCФ[T<2w~E/Ik (>x/nVI`'VGF8S^`ck2euAXVZenD۬yE'[h#\򠺼Z\_e|ڙ9u4c?E#םolx K6f@@Z{z덉k-mq_W> o9P;spRZ]}.?6uR}LD䨊Sq%J?nmHη/kLIE.5hݺ~`XHǜ.jϸ s*n{'Ck)YoW/MHM 0"UxAdm7v\p. X=n~s@㶿An*CE.MmeS<)=m܌!']5wHe{~4^Z}Zhct),ZUf4gcz^(k^<@^֦橧m JytL[͵lK7V (ǟ4Y5](|[Ljx3ds~^d5-z].3)`Ɖ8nR8$/a卾C4.=99tvwPhÍ/W |yo6|pOᷣ9榨]Xg[5* I1 L~:#YU;Zp՗ݿpfXHcÓQ (ce.꿻]3cFCy\=@Qe؞.UZ/сʢgSR٤ڇs'vmE{\ ݯimϹZ"A-K5aYf vh4<N8D397^tؒͣXxNm0S~sqwޚ &vϕF5.z.}N&zzW?0t_DXbew5#(]wt(lmN\u{%0/.Iy];w확 pbN0VM2QĨ׳3PʃHos(dt@̍}7}a" *Sn3̖09y_in847].(0w]z-#+,4|/CFfee s1&08YX@̽3q |E׳>[\UPr{ (z:q_yQzQuVّW4hmL.dwl0dgU/&f_\ J*w e8gc;q,C5){q.)rV|c"J*極BSM-(,=vIZYKokT]sl3W WN:[^X t<͗Ӌ*S*R-jk#Jjkkq{˕sا_N-yxy57L~eqMWLP=b>B!WQTz1 dl4R%嗥ee7"|̝/,&|P_Z5WKO)(K+OMy<9s/4 FegWd9:bU|7T p? q8<+ ?\L0\ X mj7&И(fRYz^YVab P w(6524nW.g "ϭ9x".280wBq+tbםp}(!Ev\ thkܻarmO.(ACFQtJZ?&sDoXٸ?.ș5z m ]9v>y$ F/.M]6|6.O)OϿlʙKg(%J+ļs 3k#z}RX|7.ɐg\Xbay6:…YmC 켗]S_ 4^y#BGcX6W=~Y) |=J]qY$ :`v+%R@58r:kx!)2۸`ޏt+xh]Ƌ{'+7|9*F<=Gϸ &u }}D8|Z ]0/n}w?eH-7HuGwxbVfH jtiQ 7Hy`a?:KDGA>8i6SuXBX|F{bit~I|v OйsJ( V?A]1>-U~&5ܜ.psm9LCh2xPc/e$I}`G@@O`u;R:Fh7 q!:/$!43%E8)xtW'2\P]x4j_쉞"(깲YAخqJX|\DI.4Tb*=bB3qy]Χlw"nwù~^pc[J8IOq30Gݏ*O;Z|ÏGu8Jsu?8:( v;=ku?ŝRځ(B6/LK{, >C{&|m= |ki+:C6Rn?#,yͻ}twW|ŕN2|ÁY"e*Ⴎl/59J"fK!^r7sA}ș(*K|c*r9$Eŀ $*3* E9g h==vvvgv*@흙sO=j/_)MDiLoVrQ%u]+uP{c7fݮ:oli;u jT4=ܢ˹>ֶ!:* 4yV7V5nrr3[R73uoKՓqn6֮鸹A]׵޾N~fڪv+ϰ0w4N+}a(P3q0~<3EP <3~SSkˏ坌P7o#ͧ7F.I+ t Qȏʂ R]zߋG+C FPᗇeS6J:zngw`BƑՑ #N<9 _lIr/(2GљO),b_gB_ ~n$8Lցys\5/~qɚ'ŲV^+g?߷1"6Oǽ廃.3fӀlXp`hmu Gn#GUVB,iU|nY! @Pyޙ'cfQB,B ]#;2-q4o M;DJn[wSM7 wU; 7GN@>)Ɂ{v\SYPp\}f~ܢݞ.LLH`o~4xW١,Jypյ,_LvJWk ~KRsJ=W?s կҢfShoK: P0/b ĘPr,qw q p*}]RPߑx1qi:lB)GO_5O^0\ MJ Ce֦[/;/P, uV:h}ʂ"*8T}YeEoG\^Ke@6;in#I 魼nQdBHse6{ >2fuUj,;m d6I族H\b .rX;/({E5k+cbI! TB BͬO\Jզn S_R6iQp BO74;M9@@E*M)?TO-L`|BrZ\G)9/|w{\Ƌ=\=On}˥Άk;@ v@'wl2"5+{|! @s);Rk_ Cc+g+X7On`zW !0bHGSS?վ 7d(D QB"w\ q* 9zƖ(A)yٸm3b+Ypj\O^e¼Ĕ=ʣm4 Y_٭y0|P+=;ꞿ,sjT}SR'!-Reu {&MS̲szvt<ݒ4Gq^xEb8wӖC); Y"u{mI{?xX<ЄNf U)YGP4)D QB=b@$YP6Ity"N1W,Q* OO4utSCZq1܅z W}o:.T59yxϰБQ1 9.ax JHTIR"cG~AVFz:jeqW*W =|}U!vvRB\ 7*jMuU`A(D! Q?8W타2i(7X#26$S:u)&=P9'^RːT;, !%c 'b!Ddd䗠)b0%2mCO$r$ȩ@&C8!bAJ2P>ՒR#i,`~(>;;0. 1YNi?E+2?qǹtQ --h`8 *F(Ӱ D1%-)E 9!37qӜ%^aa~qF5rlpm|!EnXYK \ "ظ7hZit%?`8GӛAʌ{|LD{M%ͫgK d1 b=wP?A SJktTCOiҦv&O#%S6 !E0>j Y@簰o38W[\U5^@l *D!  }˱G [GclL?Yd+:x #sp0w^:aHTΌSyjK,g5]&mfʥk$XmIp4KCL(|A y((@p`]7cW& t垖C;50N{mrpR 9q&cO$?_y@$}bۀc8z52X u}M]5-7Zh2s:7t/ +bԽwU62q@Jd ( Lv1I #L|M.J&Ȅ؏V8&f?ӋS< վ+"!}5,!dg1&dO$b$Wn;AlPΤNPT|q1&YQ2x IDŔ P&dʢ`8=aeGy"3eO 偰0jMQf4vUP L&Ǜl&p?8[%A#Er-DIUVxe‰R`|EnӜKqF~/vyE?F3[vЅr!xT9˞?N7n|8&2Ut/{'1ٙmZ BK ,Lc0dRSfUT_ESyu82823Im= g;S-'Z>luP-{raM ,9UA/nkz;#ĉ  }#(Kb+:$jr[_&73B{ u"jyyd8APCoʏQp|h88(?6sb|Я Ly0QVGir 3|av*&?0Q<<?zzuLs:*Au:POY;d=>7)XP! Q_ǂbKKn1g^@W#ޗ{g2@(ml#b(*IIJa[qҲDG6O]L8iWҜ>7HJe|q=wfscCCi+$BQ X0K{d,䝎%:cy$oSҢ M<ڍ "3s!379=;5 kn(A6 (0ǁhEL8GeLaw4~|([s&:/:ʧlM;wwhXP0$>ְt)4UF؄4tєKRȔ}Y9 1%"Aj;,}aWӊYf Sd50,(5j9smĪ9~Y[b\5Z yG,dJQ99ənc0) tuh(b=oSL ],v6Xw ,(Ό =dwE$X4I Ym)iYs&b#ⅧF˝ !&[hR`K߾\v!d"bs]'ߝqD"+;f&xOyN:xgtg Sï#<"wY`sۏ##1#*쏌;dKkto;08y\zۚĴ:ӕ,8OgA-;5%o.&4%KvftO"smYT$ۼfjiBe]rJ摸5,`A(D!ߟ%"}fD]?C144}{ڀˮ- _ zlڇqJ|phnU~?r{jOXj[;^:Ȗ8(dx㻧iԪZk/u 3Zꛌe {otF֑L/G+B e?7(1t-eE/^XZ:Zo_Uci.e3i [܎O5:+Nv6><7_Wm`ՙ-&s;F*}52'T3ZszKTv7/k'q7x;`8*98_4M_ExWqjsNW\@vL{с{Rr]]x|׉'Nb3۞^`[ Vn"R}اC1;v>]@wΙ_vjt1qQ2Eb8hWyUFvwޢyrNEDm'9ɂ(gdճY$Ƙ}HEwb"^`1 lgV0\UɍJ, _ĐvUпe. 4 ý7c0N_<&Sc n H>~؃K(E'^ : Lb&C= l4 nV66h.Hn]5aal01ł*d&NM B78aYtbhϳj9Ј =>ҋ{>-чƚ*zF+h\h2>*%/&AHWk5G4łK;Pkw,}cshF=if0,b˲(;Y$f?-X D>ǏW/K:@7vw oާ{VgMveq@, B\0^\0# õ7| A$BR5m|eq} CIm絮'gGk&o=;8WU?z҉ݞCr=z>nv3w}͋cg=os 5gߵWʮ*>?4/,gATbCmc=F[}lI% Co^%zB`qzv'"n<=<0>c;8Wuu}kudz2 X˫ԙ>,AJ_xU#3}S{ {[yT.v-Mзu_J_Lޚ/GdN09Շ1ZRⓣr|8_ ')8Q#wmװeoZbZ֞}݋Ɯ4Ŏ)koL:w%J')`+-}\WEX2Y̿5ez~ZdXjZs^d#'AQBf@I}Ğ%H߰0lm7ΆR.. n[,"}d.s.vlpdT8:&2[/ӒwGξ?Ԏya?qEzG;4%VW-*jƘ2 Cݽ:g]:O'1ɭyTeήʶ{ l}ݼ}mMϨ{cQ2N N SYty0h`l{#9+J23]WU4»ȂX޲4 G\6f}Rpҍy(,d_;g=B/:OPxm{]caٹ&if4e,(,!~[yו0) _K ]]L dŃWS"Lٍ% ;*Qj"`(YVu*kL5XrENG`@edEc CL\awwpv<|=b'[ whx뼢)%.>ޞe%pFduX ^C-$*R뛛a@;`Eri`)@h>aA  * b-yxbkcO᭳RHD˯)MLϲ Gly|u~SYϱe#CN4QSwg8Vo:!Zt#ZclQ9{aߵ.2Ωo>fBbyˋ[DQ>ͻUJu 9zoB~71Ei,= wJ,L5,DJ ;NTRƖqj48iL ңu%Fn{۫ZEfs*^JZp>kzfV2iGx'[t*UP,͆Ҟ-nLg+1i[1CKv[^M $BEnYOjY@{ "֍7::ePl :2yCeT3+ߦJ#8xnH<ϣlΜҶј-+ 0S|Ǚwz{oXTe19 rq.$.;cmfh ?& JAI\>:RNVդrtں @҂Kyo?9rM]g˝'\r \V;tMq JVVj8H KBJ*.-53[&cUa@q }:\U-턤!w+OoV!PG_3=rXpw ;U5b`kq3]`s^`j|X5+ƻ7!e݁bb!(||?1Q[gc|~,E8^;:oّt^]j"8%Ӏ̈-w'%eVܹ !4aϵK{Rsr_k'7Rg]x=r1E-_;]ӕ\.XY2'gv`Թ@߿o9Qd|Y΂G^\`]`ՙ(ijwnI:W$ ?\|z]ne(#t0;Rs/mf9Glۙb}l˜<԰}x@W==c;u̍}s߼]hƦ|+Aٙ]IGJ榬fGO3~^flעX`վ  Zw(N놛o;[\ts||2ݭM52#,=>uCD c vRvilLphܤwۇh<:.(S4bpٽԌ z:,< MÄG٦|yq9>mgw8!9=6V*( N&!cbVZKsk:nÆG$,0jKǍؓwne`ױ |-#0`gٻ2 }9L YEؒE~hoG6"@q\d|gb3T7ƺ'a(>b%Ĥ?yZ \[|wU8.vu=ɏyڛfj.0 ؆=1{靾t@ ,XjwWπ}k,Qn/&Td2Toz\RdOl*^l(w/ AۃdWk +F+w͋[Qݶve^|ฌu8#=44;^t՛Y|>*+OLFm{"hwCGayM)sY8-2o {[xt\T(@Ԝw6M:'=36,&.''dZ!]_Y'e_=l=G=I%mQBӍ(?砟C *؂/A8CڗN%^,O6A@\:*fz޴3y jwΚ潑* :k1&"|x{u4^mgLCw;DAՒu؛2 JCY{ 䘩(< *D! \+'Fȇf׭l<|\,8ә6@m6)qvr v೹fE5+;;%p[DH$wTS$D@M\_ JpR(1r \53s<3 rusR&S?vvB3Wjx;Sm-̗OXW EHo6J,<-lNDes{Ge$<)kN6*XB 8)YYHUVwBXj!88{, u ܴ4TQRH,l?jXLl#;2;VX;hAIo6HFq7s6̸m<Oz 3%^*8&P7p`RE?l}Xf~0 #uM)[8y`s)T1r0P41jS!c\1DX 5tE =ܤ\)8B`g;&DDڰ}jHP.l"kf,RRdj&1qZO MճNlk8)X:W[N|:.$! hY:P?yi4,[JG򵬽M|ŽP:HuJ|,"#| *Գ6| {ok&WmE}vWkm] c ZĘ'7J Uc;@w@{3G 5-Sw3c,'YY|S+G@MSIVBX#MҜ*iQ.*隸x:z:zt\O5X3]L0nbe)TҳB>-#(?fl$T miv0++YxxziZY؊>zS<%(ISҥxyiYY+(nlve((  =|tbl6B75$KI_<;}.H$<%mKgM Fga2twSWSuU<`aFT\= JHZ:p$:e ):4  +شGCrۓw'?.[dfI n]% \{D"A [)C6| ݧ'Qȕb|H<?ZQ./L ʕ)2 1ނ2#JÇzJ҄U S0J./}Ld\>X4)~0' oQS!i&͸S u*dY>GfܧpP^w{>d}Q>bvS߿m2% j"Y|dBM2Yb%7,:Ÿ*[M4A<>Br; %cmX ȋE _(gdM>%.1`dzeY" z/ ?zBA'(06{>4!>eH>:YȄ]i/ʊ[i GG'sŁP7ժJٙzK> #@EZ=󨾉MnIH)+ӻT4 *D! ޺?cX/xp"CzH>riOBUXQG?LE|u㐘zK(X 3گ?YEH~J3cQ!?PƂov0gFMtd0[E`A(䟌]c%+7 [l'B5g<+ZBJ4,1]H9<|CPWƸ Uv*pZ\! TB(Y(oyg,XztYjCnjJTuB]846⛀ƙ_hKU TAmA'frH,&Ft % T(D!? YqC2 `&N\44{%GO.,ޜs 5ue =|gƲ E4eM^ dG\{BgZ40GAn]Fz(B߼/ DqY TB,Xpъ#ghL5?Xοogd#!=.5>/\cfBvN%,m߼/͚%7]crAF/t=8-gA+%* BȔrQ.ɷ4] 뻮 W@ 5]؄8s ijd&Jq%ȄR%J=Ff&h۸ꪋS }p(#L!~Ϡ,p:``A@SD ~K%z-߷84JSf~*Sv%p0w((a o:"Dy?j465P|8A|''O̓(P\1*$ 9Yṿy̩z]Wwo5 I>[m֞WA1CZ8:9JE8u+d~V&{ YGqD;/DWB 4s601hcJ# }=|ܼ͵tT,$V ]J\C;3=.)FSܜ|1%='G ~F>h8HGiHYLH8{M\f{Z]s#VYvL/cʝ> Lʹ}ݜ"sDY7;XGv}[Ѹ&4oIޙ"M=S¥.+-v,G#ײ Acߥ#]fƟALNXϞY8HLSFyn O / 'mpF`X{AͿԨ9S8AP/ ?!î?o (q8o!S VGόA8O ?z-8,h]*2)w hëe5ca4)EDkƻE͢ f[fd^vuqPJfۮ66%e;s7ٌ̲޻i}oc '~R}sxK|7ߩ}QKuG&Э+{w/u۫Kc"xƝ39Qpk؍Krn*2סMi$y>)|ɵ3qٗ;*e?ڛdl(Ն}oS;#CV!׿Mi憸݉{*]m!4hyYU'wρ[`0qu-%k2oT=>$x6b5mӲO۱1>l 9}u/ Hvݮ=jgk*!q̣18-'ѵZ+]SXBW1|*_I!gv bA+hGڦY[rU& "l( (Ŧڪ̅ä,e]X4:@#a~ɄXsok: NTGńsRnNcNO D"emWNSaS12L0pF|ʂ_n[, 'xB&ϐF ε~1vr:BxBvrCH=3'xÄ?WeAyv?*>bAu`({ NPqi΁>4 Rݜ+@% 0,zBf098Bl:UȼG,(0&Ff0p 8,d%C0#"fYlX%XKA F %T]`l"L<,.\GHY2RH0&i$8Op2I9 TafjUD, sMp.d#dqBFŅ9 8lEW89& bc@?Xޅ<LJދWJy* YPt9M1:p"eIEK'QpsaA.w=rIE!fPtQˏ/f"\8څX`7mA KR_\[) ' ;5I1}ORL5RѶNoUKss:i{,NJDb]+#c;;뱭Mb oZ<Δ`]߂#,v#& uF$pȨy{#i &s31K  `/N"cu_܈&eՑY>n)ib0 vobW\yu \X$f?5|Tw`nr`6oT_ 22փ %+iɋrϦf3b 4Rq[=?Wqk>0]˻o[gmh| $`] _ ьbBi͚Lumc/6I&])ca_cޱ3#ft._]^x䷽ E]]VMoT͙A) T`,Ȭ!IgG7 > iG}?yќ_>PS7_3'DɚA 26~Byku@e T\e׃o/) >{r˒uڞ6?GQb$B|3 ='ez724WC|d T¯}񮧪~G^;_,R ٯGj69 E[Gw!T#1 w>(a,oC03w;~EcPv~ RDЋ8dעu"lUe!~ e_yt Bˬk,Us ߇^cо;RM'X m཮fF媛0|w0́$Uև߇Ғ?9nÙLm¾YpOK`;  8ϼ>g~yOtLoBJߛ:$1E?-%wۻI6ۢK|6/m? oU޻үis:5$Hc9'3KEWr?2R@ C&)z?VTw A8 Tτaw < 煭߮m`}|K-Zw&Y£_X&tS(cAۿ adAMj~c*N=Axc)D4ItA'ł*AgHٽ`bzv|R:X<_oʼn֢wurqW_GceA>p*gl`bE n4ij%DH? =MP $thš{x$@ 3t9`*fAeZγ>Γ1_4XrqX@IY[K8zu?e B* p@$e(=|Ctb5m#uuW^&հ }}2زl1Im]O=v"|dKy] [{g/c (/oW}l WXj׿y:t={d4yIjBi샩ԙ@>LWkػU='{S yjɺ)C絷5ܪQ|TIn7-͘I, '9-EC|vL6rasX~7OzrIpϸ CPkʮGگĨ.eT#| |iB*6U<Ǔ cY2Z6 wVzۿc6)oϵbXsKwv:) to<- ~lDK#:brma ut[-[x;r6nd,調?}E2noWS0 ysF `4&wa9F PWF{l:\y a1u7y/:ʣDFqQ,F4qbZ*=W\IްkrOwOa9g$+H%(bʪ`ƌ("Yb9!YrFv.U۽=+~O@-,&񙀍:gGc|uq+YT)3,~}ޫx키y|eI~F-eC3T/+(WHΗE{xa&ZCJ}EԳE =WN{*$\#m_da<欄qKٍzL<@?)C/Bu-JpnM9L.p_ BmMur%թŵ3\b( 2G/itZ"O5v2t4VJBǕ+}>%^8B Ѓ=* 1w&[)Y,,/`pl3OL?S៑]йK ͭrFpqҹ$Gri\vXJ-YYy#vAa }0x哇28Bmtug=}g _Ef Y,8v%rZS 6lrO#&\`L&v+=;NH,GZaŦ/ rE<\+(A#?_baɮa z.(Ë$ -umnSPYaښ\q95O,o-mwO3NϵnB&_A003 Ӝ 7"1a0pՈC]1Ɔ ,|~ `3p"+ko_h~P}t0+y;T|ȒΊu!&PÙLNL`Jf͙h68|< CuUw-k mKOqq)APXkzݰe)F޽ao\0C,*xדGȽ 9^\͵(#Ę]5&B@`'$:K Zh8@dFc>z5Gdv5 >?63.h|-քtIi`7)α׍:t~.O"0i?Wj.8 Ns_h=ȟ -2<{wOj^?;x6|R4RH5lhl̤uWuH>[w>FA` EvLB(ĸ }#~P 7ǐI.l>'77sS %A$|ż?G0Wx3e灏tUyja{-׭5B@l11ucE<$E"+9z?Mf bT?LԵp3]PMrq7׋"í0w# .H 6„#f=]z!|w^陱!>{  lS߬oKW͔2o<;zFٶ^=>[;ՑSk[_RF9Vw%EN-wԇW=Ū- q ^fi4eN<]FOn^pA\(JCw.Yd+(3 qnsEvKn0u|5 l-XC=R,>yզ;'{ǴK#6͙h2~qۋ;~2W- >~ӻ}pR"/Ex\plE}| 0Qfxq 4fq= ?psZo@ U.:IVfLF}pv(cYţOs͠mVN tACB}M"*I ~;OS90<<~PvA5ﮯ;hoj),Ǥ5~&(e]p٩K;=7B=9,|x #X@ m]浶4_hYTV^}0? o=gDu;(|XDbWQں-8J6k*]puEUJ%,x֚Zua+kR,/Ao|].75R;"̃[U12I9\AczڂvWe mwA(^c_ OlZݣed+jHHJ1_'|UHuI\W:v&6Z޾)E_M"$ˉY&n.LT.W.3FYDg3FL ]0H21R"F[nǨ>zHIMmS\]=-M][ȁ.y|ϻ`C9^[B pAS}1.nx%ޅO@6w9sU.m$F1>%X@c#X@82;h5pg4`qQg3\dם#VF*F \Necܝ#kz^]00ܝ .]q#N?ype:pO?]0..+e`agfgٹd;zԢ_eNb&wq!j/+^O >t@㈤W/QU6|溶Rkm z']|FWwA%)ęٻ6F};#;sd_lC== -}#-yER.o,(7l#Mʹ-#tozi$|>79l$G4Ҹ3BCD[ $fCw q4tTC՘2l%>O5gt&L-g><7yuZ(tH1 vAR ^i,Wuȵ>߅+ᓽtIr%j㶝{[iG(5^ ҴLHIm} >dv>~\~o.*=3K `ÞKĈ! Ejoi4L 8gBMbKVWsqz[yUJD\ɞ}v)D'oL[5c-!>5{k] h>3/? ]%z| b{G.h2>PzwtAԡPOSe7~0 E ϺK3͉7#h*+6 7OX^Vx;m7`lh^`Xf:>~'Yxn+=9=O L:qaE%;WٰH( Fn9D9*67q@}#[o.Rl1ß$me80>)0d=1HO47vo@;"|}ksћ?mç>$'Sg\r6.5Uַo r9H 㻢v͚5hHtlw6_J@mJektl%%7cQcwf'¢yJ!/Qp8;Jg:WLJ(=7kUP2@kc н8ؘ`ɓq1% ތO%IuSxw4 IIvOx^o!؛&NkΡS18Gm~XwnhM_$b8 > 5svzIIQ\9/Ђo'e4X&lqR7U40oW9!wʂK ޖI1T!z[B Ǭœg>Lz9!X膰txr]Dhlp\BuɇA+ø@KR9ŧ g&bjsT%qB@R U6b" L"rA@ D \@ D rA\@ rA@ D \@ D rA rA@\ލ@ D Hm`o@ ~/~"D rA rA@>b# h@ 䂨@ gorATb1@ xx? Jtj@jt #[A};@ rA @ "@.@ " @.@  @ "@.@ " @.@  @ Ho]|Rpbz!iXX41* \@  1Ocfof`f=TOGO yσ$P7jN:EPndlc/"9Ejʸn!V* ArA@.H l5vK,ܝWpXLY;1qB95d &j"(ֲv?FK Ao@:Gjpf@>)E.@.@ rf<:f׾I&&چF"ɣ`\RHl 08巢haLLXÄ́P|Ę| !Vc8`L.AI҉<>,):1( ᤘɦsf9ʘ,MHpͅX+ anLJLCPf|. Ϥy}LVvd2Mc.Tla3Ί t"" "j8!pH.<&Å2/(caakv;B D *;>kێy9;u\# ˭%0@g(AE'x8hٌ[n:. /N_4{ؐvmn%I\a8ܕds GݓL I9v}@\汥V"m4h#C\X98X^swgnƋ`ZaEyB#Y[sKÝ R#[bm,̴; ԅ8i\ Cy'7t9 kE:GO]3GK*[73A YZƕN^qC=3)Kuf&i5/OLpAR,8"\ alA@ .dOfuSz-H\5E1La1ww][|0ok&`JVa5+7o}uv$ԽP0k2wo4Ӗhel-n͑lF<''Pz#&@gHܸw$Fdo\P94(k(+wH.hx,M;%1vYuIج˟2ĔK IX7"4n`+`e҆ d SD[c 9"ҜLuX<Hgn)Yl<+-'لOy)Ig9BqB qH9DsvN$ ٿPul<ϴf\.NWd "~0)Q\* !(JLdJ)B%&B @ R$2qKG+.b0e^ rA˹ zzY0$S?v!))E|a)A0=IZ'kvу'1_QH`pʞ t8tAm׈.H_['aQ킙 LLkؤm%xj! t z.y.*7(kjooseF-tXu2eyVV#u@v );޸`e]fe%bW179iL rAĿ8 }O?ok^m\I{Z%#]Xq}e!y-#=oGP<75~SZ^|?۫ʼn:J:2M%;7/0Ӷ_ydx: Kݽqɡ . Xyp *"dG<}9[f00KCO{ GI-flP.ܑ?H͐@\oo^ݧM2E/ͼqvj 6~bWdHm,5΅/XYXȊH?XkCԟu uS}vX5{d:967'y:/|$йI^#WX2(<74#{tg.KlD]P}̽ʐ "Ml˕)nxV:k+5U9^d%#G;x|@p7VrW5%|U X|eG Bqd&Zkǎ gBa %^䂕@o hK/ BhŃ89g%Մ)F.@  =MrL.`O)<: PqR`QK0, IC!WL*@Ŕ{,V"q oP_K@ "TqarUbR#gRB(ex Ʃ[2· `P6c%_gʰU_T9U\XCj#2,> SF5RA wqyT3BOguG/hY M,nΩerԙ'_CϺ"%*D@ "߸`ֶ-U7- LЉ;|tֶjYRxJ;Wݡ\0R]XGg$N"psX\SŹW4&uIrHPa"]{S?/8|OFB4pw?-H:zE~YK_vAbk@"@ ?#n*M2xBK'|/ER&Wm8⫪}W.[ 3vިs~s5eRqQnz0Vbٞs*CaᗹkFK~W;~Vܷt_FL%G|/01OKɀ@ 䂿[@ lrllQ';G%}Z{4ЅXº=v{d|洬7,]2kawÍ'k]Q/<^0\ p峞mM闃 Sq3'EbSx*ܿ|85X}mvYxÊ>_xIPyc\"rA?wA O_Y=j)[M/S;΍0c|ͷf=~~6n뫏>:0֋".eϓ)7컾3BS|wx(s/w)Wؽ(@0N@ D  te @ "e.@ rA @ @ D " @.@ pEBB9@;bV􃅪 µWeglidnghn@ fچF!#|]#\\,i0ظJ!gcB@$gct K.HIl MRL=b59j |]/ۥ/0yHO@h:O^&0ީ >j⬪lOWt0SՎSf[ٻ\vHt "| +Lܹ攵[v@v̍YƄd3fz,IdVcDb ޒ)|n~\:˶mo6 7fRD 'L)5w$\FڨQv=\<-%"3TS͒1.lN)dXF p~q| ΐ=!`HȾ"-OZ܏D0`w,S?'d]A%>/ AB#hN6FNO G62|i@\vAZ:eBIɗSYʣ.i[o5,ެŽ+[FBc0WvN (I^.csk+N=|=z ^_=# ĘG<ˋx\LR7Y)k;00t"Nۚj ă]31ïV: ]OyR:~ڿjeB}IGnsiʙ`fZ- ?υ߽0 4>ߩk=c'Y)YՌC-=& @,>3rv>-nHa nOIᧈg;c:HbV9m_v^Do(m/{B4|[zf_Qg*eeǺZr޲>r*@5WG `A)M,vc8I (6f{Mǩv4_ 0wAZ}^Tݥ_vOt<>{qS}~ލZ ,:+Z&r[)Z. p/R}NQ^:-m㫏>eJ{ڗw&7; `1i{7s 'njk(u=G-:X Nn'е >W6* &fwmE-.|:{;vAҰ BlUY.AWdW\H!V2ls3S}yj+j{jAĉ{n];n(.9q.̹t/vZ\>bUwFFubvE9]4_؏UV^0}&Nrjh?GL0/S Blۙ)u@N惿y9i6ia? +K3k}1Gtn-uw.qhm5)_uFW!H,O>|y*-Ci,n%} IWHPVLd `8:͞=ԋ/r5?vԡZ^QУw%΢’Y}͙Uuy{˕V׵L 'ɩy–:MU} `m>df}W} Z&nm!"ζ6x9m"㨕VnJ8vg?@.`=7 F 7.谹` QC/egNx=Ϣx'Wyk7 l= [o3cY䂦 ^eگ&QZ[J9X8N5IF51JSfB+% hIxS7k1o w^qZeCYC/[MSjNs6>Hz Gglaӳ%c3nt[҃ʗ]som,;au=kw$PkxaGv|e*=VpvM5UjSc\@+C<(4\pL|IgÛ7U5ܸɫ^oLl;{;< D.xG]@sGg8.4rB~pZW3[w t ;H߁V92bs{ }#q̑˲:.nyG.,#h>rR /n9u*cw-]gzVȊ++L$1;.Qg\xܢkGم)?Q+pw+>RG".1I:"cTGȁ[rG~㷳Vj9!RY5%kPOWO ;yw б;ma;{U?9 rfQN췤RPιњbG_,яo\-^%h9lfbW˂wjMƏh$ےlS =1oQ 5dvZLܝT]Uk^vG{bĄP)_VSK.iς֯ }0X;kP鮞Atw( Poc\MgiqCgݹQth 0-{Fi .[VVԍ|767HAi4o-ՙvM^"(19R8,T!Q fZz+񡜉ٵmk U&̂3* dW$},6=mg_]X ?ehLkjt G|o3C?YEm2rArw['4Gs_<>3CB𳽯[[g{'$~|Kr3/[ܪA0QYXKq;;鲋)2<.]# 5!.1?+`G,[uʶ_-[9]>M5BoO6|]ÖkͽgSԁtD{Ūe7T&"D|HLFΡ~x1!c5lZH {4BG}s͎ӛ)tyvgESj=HWb]{o߹#^ EBsϭ²kuO聕bE9+؀VTgŎ ԁ[yG=&rϯW6TUN%6^0:X4O=muj7nn7SN6ܻn_~Ai8 Fyv-U[Ӆ 4}vl3w rEHC=z|X60Hn𳊊}[EƮG?XaT_g䂿NAx?O{x[A?_7O|A0R©ϠǍ&<@|AU 9ۉxa zY,~:qx먊?\~b6oG:oGgf[?0},㝩:Iě , er.?Zxwh9{nٝO7ӏX |~AA"\\@.\U`ej wGip.]f5wiwh?+0;1Nz~dY*U\r̙L6uѲc-Mo&Q:NSIEdBC Tns;Տo. 3a +wl w_+{̩spL_hZQC @+P52yPYvT@\dg,JLaf.,V.EL@@Pn$ku{{_̠Ϝy{ \\Aީ_#?YA9;Oqギc]&_޵ )vp!D  )#Th vV$LK.rAi6pœ+h!Xv?`ZpAޥ C[['OJ4}|8TU:+G7_AApAޱ Ahqp1X;Z|.H]R\i+)r~. 4 \c0a\Lw?iߗ s[>axn؃ͧ @\L8p[?14}G;u۾N=q/E|\?B ".W8\oK3 >S8"n{nfE.r%_lyӗY"nIL/!p+6)q:qwRBZ#.SBo-ZzXqi@3Zyp">!R\ܴ!) H Ƥ+")^&bpG\<DlԴgtJv<*+koA+@7Al . ]a /Vb&t h2+Ikl}ZDk)jA\<q0.5pd`H2#Vrؘqv!)c^3Of[;}O-GB6H9kђG["rTSXTٖAv f9uA#&.Z>\((Yͯnl̜-;toUW?5~_ i{=O $Y`B=e19-$ark7ZqA\PNeauϱ WEЌbt-a_rAjc׭5E3J3c|eB$) Jo'`+-g~pt?o?\#uA@جe-='I_qtTtABG&FEk1~g%mGLgKٝ-CxSKj \Ǻ ]z I˨.)z @\<4ߐ񻏴hW/|{e}UĭtC6d'C,$To>N FѩdtB!tiA+4Za}:"䱹 Y<6OW64!|ݢC|X Q\414rcb9ګp.&U: LC bB"MuL0OsC'r$ .h,Q]޴#c_+oy{¼}S>Ep pA\\qBH@d4|Ѫ.\7;0 |.2@"Cy:`c?P(鹥HIBF)(o=`%NI1MIsAsz;/f^ͼW m"1Q, :H %Y;[&4g$ \$7zB<!/PgfSXL_~הF| =?֒~K8*K #!39OS>Of6.Oψ{eT 됨0Bfn[E HA=zG_e7hcU=GIU_vx [okK>V @,EUk<ӯ$q:.{VkKoQAܶqݼ7 %BN}dXO"D.J+OYڮی/XţQ=8W_ߪ:) k]Bg}~1UO<W#_U=^y޽;u6`̮B"{- m!<$W t tIh>jbmmM;,Xuwt0Je H7CFF;~X.3髑FMɨzRtܢq;t8 /lҳ#{ٺu^.sT1q'gJ6K6boI]vB|$r/Rn~'ww KS2ZN!WU_eH=dNOwF!k2/ V06?hWȝBSks1!eCCJ$c*KStrVgц[EI8vpƣpf^ՁfBV޻ymWU׋pdFz19l kA1o|yse#)s^B}K;۰ .Z$;iz/̪y8޻_3ksS:A+8-ͺtރ' 91z.횓Ukx#~޸hgy:U>#Z1%W )ˮ̫$!;raAGJI=r l P;d7e-G6ީoBNcEZo5T/D]In7ġ]w~hL,c#u?Q}~M]G^\.7dY0$ <2gu9! n+c"(mwO^zvzKG ^}M]Q裷_?֮,{mf#eXbJx0\u<Ҳ˂ _|Ws={vːbˑEU|ܺuϩٞ19 ]𬨇6?~X6}ٌ^uÃLhգh/k݂8? .)VN*˗-nOu> 6W[ʫ[ ̣mtW,.ncƥǥn^po/o䣠Ϟe<2-f֖.'7{u\KI("I$ A#Q~z.hA8->qwmZfpCI?}1+5а,;u75sHbŴ .i1g3sGFtlgΤekO+ls{pPB1v_VzDZȹ# q>TyBCN]9w`L{qQOU]k[=bޞsmX0RL+C>3W՚K).ŠH("CluD]:*7CoQlԱ9CỜpAse1SL#3ɩpR"Qe?<7co8iޜC-^Fbbze)G\ 3 BnjbE"/2D<=;VMVpK0^pkLyA&gʤtyt  RLv1O.&"-OXA]|m׃2RR2ntC eQ$r.))udnaY.hkNx>bdb,Sѓg8'8J k<:j>:W!1.E H;$*,ei'1Ub䂤)0xn ,2!F5N#G,w@]P@JB"4sqFL㧍:/vkgF="oufU5PHe:7Z Uim}/p?D MbiD"ѻ 2nʍRJ%!R譝6lKvr{ └vJR %o#46P v;D&~)C2onw׆% R(!E)X9Y: ~.|.7z屈%Lo밳fEηe@!-#C#]l JzEe콇%A?agB+AZmH?*P?AZr*K_AL:%8?y+6GM7.GKPidN nh.%(ѫK.xl|ddC[ ϧe!aȥlw 8>8cŽnO:/Ի' %aڮ=p),.{rvo1~D%%xP覸`ݕvw\ 5=[|zz2h#fQ{V=J#ů>Jz/U_kc9{=c*BG?HAӥWNqJ. s+p1)V`'d͖]`&4chmW>80=!1WCfrjr.舐زwvp`&?`/@/>=BH;6k' 4\c{. F7=ﶛ.y3zf蒾G ȿߺwEzr(<;Ins};1]@Sq'f_̾ dB6~k5;9i[v]yXGl\"9.aosGڸKA?l\Cd*[6~{l!_; n볿*/tуeŵ>./>]x:No'XQ ?x1sQ%r0)Ӊ T $TsvN[ 뽧ѺemDvq:v|[ EH;F} tvƳ>i:/Պ흽=>chLе2tMqxxDž\77ɀC\׀wZ"nΒuZ۸z4Rk]eo \^ۃe\eoYhSkcJޕ#M.8h.Έ-?}բܒkRvx!"2՚omҪ-(tSi/hvA!Nx!f,HuV`B J.UyG9|yɫkobO] W%sB\}TJ53X9 eA Ph-|mO5|GWG:8< W]l|q~ JUz'l7Ŷo5VV$G<\Եϐ-;78,"eF{>4mr e-R,L6~c٭꽰IEvеi_InA/7[^Ys+BX'Oz+"ivRkM1[1Ap? *)غg;ViEI#NB,אB etYrggj V^Q;K&87uI1GoX+Saw,G ?m麄WnY!qٺj _tA?ե0 )"=b{}+s:iĥ~|'>߮yeW`3_.(RXD%b\qZ%6!!E'Ut"iNJMCO̫B%^PB )|E?yG̃8A4+UnHW>4BP(Q+ ьLs®ÿ81ulq(\0SC/pH*%D,o#"ӫq&fRA7WԩLhP2ػx G/H?JR=r"=v>bBE+Tِ8J(D -%$qPie1(K>G,}eow@#>K pA(]-.&~kt$6ڮe.ݥNN;d.H0#O'. |Z. fqv UFe9Rv v]* ..`P2EI1DQ pQ̴B_].V`h:Z1-K B=Rk4; 2) A N?[lpYЯAZuA!"Qw )H}}"#Ȩ{4aKύZyeNk?_AZG~AoAP!7O...A]ܝҮ͘-&VS(jZuшˑ׈sB\o=ZwWkdCH1|ENg5Bp0 :tUxoY$]ಭf]M.RnS pANLsqM5Aj_֔HPN !)Cb=`sK< ŠNPqq)c.Ei FpBʶ8R 1/b!L4P,%WTN`L:[DIR"IDpP`<~R% S3 tB8J ψ0M1)bf?-R?l%/‹8sؒ YpY6>A1[A~$K X\~ƉxYkhPft약cM{aXE_B(|`q]ק0SR$6D H9\(n _>X5='Os7肸P5;}US箘>h+.&pAEPb|dj⢪;)Ƌ$rj`*/]qAYWN@ҷ;VXVT}7e#BtsD?HB|Hn<"(=Qcl,uRvͭN-]Sԗ߸[zd )ޮ ݽ{޴jEcɅ&Z]ِug՗k|ZU\턄 k%ے^pGg=gЗ`'_UEGufĵ<[_/ՉVK>E~MkOZ=l4`u卋<݋+%:8? %DAӳ7޼V\h032_o4`l>jۧwήi>j;[g=yX5+e5+)fr^Tp=kӏDnC *PW ʿف,|M IJ|qDbb+uW3o>9Sq9(q ). ŔҪˉ[Ei9.:absW i%e柼s<=Ҿ5̓~\߽ B6LF@U@G+d4풬&lѥ-ȳ췿ѶAH䂖 b'$Xx:k4ԹmHЮrTS,^jrX{|znjHfU\=nWNɾq;O:Tz;oK{d*+7pEsAiɬEc^rZ(O>^8ۍq]L{A1b3.8uLh~&ʍ`J>O}NѝPDFMMX5݃yGYM˩Iq2)f,Bk{ %5Us [g' 5Od}Okl;gґ(zo鮳ijܹ[ lۜ^3JK+[!{7evpgqnQZltp7( }QioM|׊9)[2"("yCݒhިj~MsorAiW׹PLdn/wɿU0͐{ym7'zؒ|J)و8j' J TqYKm,"JE_v%Np>;*j V^bapCeσY[#3^WGl>^eaYχpA|.H yFz{1d3K78!%k%"6VW< T$]pTa[yO]0WlmƄL$%ܻl.{Zz|1m 9wplBKIB_]NI8jRP-Z;GHB& >u;w"|mS2K+.]/rNc򕹶7[8ZA+SfZ+G=(vs\BV_u~q Zjry(eny8gDkve^)>4G}i,.; .h?#3|'5M}G@]TIRS[zSC;"߹=\lL&Rvo{qc&2`s]\[9يKb5IW9u[_: bNaz(ƬŒܒy. YEPLߑwqA]~od4:f.mτ\\]X%)Dy"$ه$VׯsE  o"u׫OuGhCIuLrC gQ;̖: l)bKvHn,e.6zZ"5#P|^߾jNU[^:jEiV,B.IykV,&Ҹ]s+6;0e H;)%ksSH=@u Ou Xliۑ2lI}_=15;s9 z۫1-kܝ!$B]3ݘEWT{\mA۽ₑ?  ^zkt[ēImV/gv ?0DFLVfa.*ӍǸァnڨEۜR&.HYĶY^lZvSyo~JGڋ ^3Y޴#ӏqɆsӚ#LL 1$ MXd LrJk'pA|/q&GKpWj8p2K&`*Yۢ[ҋ꧕QV2tIIM <mڎU)t>rH}cӇw2|Wƞo31]1X3FttAHi1}R{̳5K\+]=q []y|X娃w߾A!άGɊd\51RjKcs"f{ʇ8!wvNۏP4[mLw]O[ ܏$l|s!ғ!mg iolR7 *FqiyK 9zfL*|:t;S+y*bsh-G6C˞}f_+>삎="N6Lz3#5Wz]{[-oq qAznQ}Vo~q`~G2fOYy !jtSZR`b|.,V-gr ˯^@;Mtk',^x`; 5!r% VR';sZ~Z~yV~YH l>0qDInu\{"Z15!<[r=-4лsxlՓUyf=WaiƓ6XB5N_cgw gգm*h–fuG\1 G7 抈_OB(4M{pMښUrra奤EM>zl[+{O)x +S113o "hl"z'%dF#^^:ç'EHLz2 SCI 6)˝<.TK+a`ӑ5Ƹ3̔whJIՏWqI^EʘEV/9 i@hR+@Y LgJ.ysd\5[D'+ ~y$O:{jߌbP7?P–lpEB w3~Lߑ?R)}#ÃytAs,P5iVs[ذmmNmiC>(86PRX7.WD".R"`͊qAhsY;y.߽mn;.&2N%wMn׶d#}ϭ3\m[D4ʳg84)oWtcHy~U(oѶu6NOH=y)_ [;mI1OXmqA|[&&'EL]@WoLZ!˿O'R2oyl#br.Ytj3>3Q̂W+ضpۥk]`9/yDŽaQ]._/rT{+%OU(fS7'BArENJ+_?{bg ~VmLQZXp1-t11 kz&4/kF[UT KTN:KGb ed}7'D\,}'̕YXA v=  ;wD, ej@h~c I38n4B_ 2"QW=Sl+e!TK!A^ wL~ͺArA0SyOK'rqb4사؜'f V9P-unO&f[ x``w .TbOf bBs+W,O4r( 9.X08\"rז+y)+EH{ezf{ѱ=B.d2I-vv>󔌒v^ N+2Dtd"NK7oOmda~sJ .|4.H]l>5bm{w1.b@+vޅ6,_W9l瑇neaH!Ζͮ۽)Q,; ŗrg''Y7ey飜]UͲa|{Q|^z"i<*]pGݿ, XŽKW .:oTL؄>&40Q7&۶wm;;x5[:f !T` :ȥM6!'E24 p~ID2"(`qSpqԴ&1E$ي+$j,đ)ͯǀg,tԹKۼM_  ) (K:R3b/K20@ 9\\\\D\<.|.h.DRXHyW:.|.uDmtvVV1d  2cd%!Ee9!1؈Wd4\aaFoB=+{XY ..HP{Λ ͢lA:+zk(-hbwAA SM)k V :џ=poC3f~)4h'UZ.q}3/^9u1ĉޝ"yƎ]ZE\P X;󾇞>£K47MtAN\]MiNⶭ+6?|z Yd>,ŧtBJ&T01#B M\J;KnUFM z_L\𷹠ZoMbFk 6 {uA.8YG["HQHwisOnpJ( =n֤ Lt0XG>iTȎ'/ =NdY|2ǸiqGwࠃoF5mGNp:K\= !lwE)ۼ,BS" $ק9}8B!/߹YuU;/MP!=߱]wfm)c;ŕ UONE\|n w`ܶ+↏rCUݼ_^/ke(:`C\ Z- Z(#՘叞|"LwV ˺F ~P;"1?\_?:k!Kߧm)Cƥc wW|sIJ?aƂً% `3.Yw(Fe-J{irjB$ R"XgڸzI__:Ho9hB\"s9e }~AM:B1+vg}UW2Y~ŒҌ+9]<9Ը9c}q.OlpÖ___iMC^ %v7ݔQ4J}&Zr΢zt!vZ<KEGKn?ӻFyUC:s0 GbJ-yxZg`?ם'ϯ @lh2. bZ[s1jӎc+4筘,Vc&r\ChIo=\O>xcq՘#ɐ|G-gc}7fV6=zdᓚ Cl}<{Ov틳<&eWde]/*Wg<yn>獷oJt&U>jyIi/.>;QO`ŕ0'oMnjԎ+OJ^H;_~rRcЀ  RbXi'R*)J̗ۺ7 1(y/k]W+r{ (/ٸ35wsvRrRI|[;Y@\\5݇ 6CFMss=ށre}ž;x搖7e랪G5anfIu+s{D[ U5On9+mԺ)#>/K!.{fs֌ӱY3qޮi _.͸Vx6(yy׶o.RQ'ks$ob6>@@WJ" \w,Ή")kKw'l<7\yXWZxazRm>ᛪ3x:+tя,Th-$?Du)g@haC5Fۥ (S[f޻S/.t =1.oЉŧNRz&7n;݆:\-\,-;vg{LCTe ;?P.=rZ[}N::7FO]seM iU-ڐs5`-QZK+]q:NCc\ \coȪMI"zL^:{lߗa[=woؚhFf/Y+Qh_3Jd?peyKZ(¹ᄁ[w7~k~_O*xñ-ɳK<==L;^4js ӏ8UDzG|/έmZJ׎,An,կw 7hBnƙiw^s):>n *?m6( vA28,"aבHޚ+Yzs`V~!>A-RF&9Ho54~Qs4t>ZrI/rg~ k¸ϼg,*\^Zr4<"aBJm[5>ua'[+Kp|i;-8R_L+u57k i0 5.]!zĄ 0}eےwWs"6q-k磳m]CZ 5Fwam[٪F[Jwm۬uQ>:&Yd[7'v[GUk`6* KGxx۶nN*QmѼuTm=]%jfNZotk2yvB--:+WaZ?]Vm|{oQyvM=YYis!B @(,"g9a'LrL68w޽ߝI6xx5??[ꞩWU]UQ" + .J킔ږa:#z4wgYe}#렞lil&l !Y$|ZK~qVv9Y9Ll""d"xߠAgo֠`Nl3uvsB*!s,5h> pwPm+ .rk>F\pّo~#.($4T~=X@\XCTf/7 7})VeqAhowQj( jk֠vdU)pAZX1*3(w'bՖE+{4#8:s Z8 &{N k^櫵Ӡ*.hAbq im[h&?8t&@DN#1 ׂH. s8_Q[;@Ț?)grAаD2A%8 kDFz0$KSZ[k{5y 9kbw;oRn-zx-.<62.1zzʚ8i%F)Q`NGsZRTIe)0OH*sZF)2K 裖? Ai5$6GPP%H'i1q `i\O^y`n ǟN=QJ/J F]05kXpA @"l)!i[Gnアsu0ٜxTy{{%D m?"QcKrZU(VξYx8E̞mI}XČisB(FA0eo?'bLgJ"wuL6=Ά>cNdlښdyT%Z|`Դpyt p 8-rXf13ąKC#"T$e>cδQA0\\7rOLߝ_ZQv,+]ˋચ ~tɐ"=Rش`GDyso|躸#r!C+/ ..#^1WV2XP8)=GLj/(ڳJl%5g>x+!E+^qu5>V;ه.h#p$"A){/|3VA$&(Pֳ\G(7/IB=uy`Ga+Fʨ{\<:=2v_W>jFI}gN3 IŌJzO:BX[d$Y̍ohNfF ܑRXcwAwΡMJ;"/{mZƐ "_?ھQJK0*8߈Fd;s赑Y}/1(nsl$8wXzHBY1SvI, ~L".w2<{&3IowZdSyճH3Tt5k詮BK|8IZХ1Aߺ qy\2ko2JpAsG5ed!AqfU֑sfY7 \NY߽bB BrӗbJbcR鷟1}K e UE.싏BZH$?Q9]P{D \K\7nt5z<&o'O WxeM]K6 ޴̜8JZò )HdZ}zalAt=+yT >櫇. =C޻TΘ]/nEh+5.w93Bp?~$m{B"j:u_4_, jO}aI:uAT6F8D8gqA+W$[պ g|IV_)$5Սvzmvoî܃浦:j]mlSW'iI%N+AkךHPKE0V'Tb-u̮:jsq [kwop јϬ58*<.6؀kB\䤊r^nA*.5UQ ?w('hIHryR79ژSħ㴝WxqpC}ܸ΁涆RV~qv%(%cuA$89=(%q:aopw; {1% FB*)oIZ)'ҪrJJ 2*Whq6gH}'KdG^i9ub+cF#x{s*lRB U9T>J8d@`2C\Vur7H 7t%2?db@K.h$ۭ, wM^_\7"7BxX9Co]p*`7nnZ[=R .85Ximtv_ #@\pj"~d.sApApApApApApApA\pA\lpZ[@)a/j~.ȷ^|5#12vw5C%apA72[7!ܿMA. J0pe/|A&W) I# ${9HC]邖mM.)s.XVY`8$hb93k}z&VhIEH:I";}<c@U:~28I\^^'4N\\¢~ZG{ͣ'_?z㿎M$0w/_.%:F /??$&g3;~ldU痔 PJ EbDgL1E/|N*,ql"1p1Ld( s쏔KpYT)fIJZaeNnML9善RѠ2¹# .XQ)H# -H06. 靈7ˢ,G+x9КozoY+ЊD'^9m>B )bIz:s'wGH!6xg y/~to2m+O>pZm2=qH,K;?㯽cML"E_>v;2E6ak;[/qcz8: wsp k)dU@S/7NOZFiZ[1[/ ;p=<[S3[G p na3 sيKoIzdGp%{$aµ2]bɃ! ŧ"hs,|d!LIS>y'^?Ϟ *2ozedJ_D+W*hgHל8|+GtœiTjˇ۽m1ʃ%/_S=}?Sb6}˟󕑢da)\\#:޷wCkAK VI1p}'m1EeԱ;߻H'ϟ? ;x0i?~;!;4I':eDO?rCjqZ)bt!՗: \ؓZ茐n;κ07N?aMêHv`EZ΋,3忼m(A\{\PF vli'X|"}"}|R=J!TڍFJdH'kŏH_U¶3y b}t}b, ֊o~O .u.8?%spHFڴ!_h֡{6޲wLK(h ҜiKg<}ȳBHv(:|pB%ΜpϽt>)(wϟxkSS˧?g*4b͗7w{ϿS*VH* ?'Q"k?sKg]z_l )~^Gqٔ(>tݥo<%DQqk*ʹ֪U{/]|,3uĬ• 4 br"ԗv`i5EP 1z|'s:\@w+he!iK`Q.H0+(*ͻ20a_B#ɄĘTi c}>~q}_ ͪbd\JYyScLL.a[6D-A17EKH5_Erx !-EH\F$YӧҢD1rR%Qg5\%HBiRb٭]Aq~eY?ٟ|)!ۇ~g#Yt}n_^7}A'+fϥo޿on|rS)/t"ikϿ^y.5G}G0ǯ}zӗ>_P?15ӯٿS. 50WJ=w__G ApA\?ѵM=ՋbEP> o\{g[_!8w[J1 :__Sn|]2}wߺ#`~}X87]?v@{ÿ~jކ mzݫ<2v]v>'!M|~ru&% +7QT^QO֤ K?Y,7$d߅?KOg=T0_{tȖmyksm'|qHD.wg5J '>_}T( W˷Ջ+Du2 .=kr߽SfS}ʍ~УO?|ܻ_ q菛+̓g]FO]0hS|t!{NNRHL W m;ȹ?:Z$C{?\|EoU^~7nMbys k8'o;Y{l>W3}@WgWyL!pA\PXO!#X8u! '%8!P3~|2=ۼ/I5䗟D9?G[U,lO.\&<,g.|rcE gZtA 2US[(\-E,{{;I$Q 7 $uXA2/zA.3^z$3+|%^w:\.p񈛻Q" +] RVXWG@u#f5y^)ѵӬ<"d瑴ﮏ͖=9 bM|iǶWƒ8<\ႝiHhkx a.ng}-}8bq=pI'{5BjK*dJxƟ ={{^[åg=%9 /kF7[dw:IqjRKؽuk|qM/|7w>kW_͍w@h+;suՄ*"5ws3tHgJŸQL 9V&ǧΈ1:,œDHZN!S~{urNX8Få03ڼg1A %\]pfW@ض} ~a?d~H< Z5n傼V9uO>7Es27:ַoÎ{h98=8|QpIy콣WC3|DŽdvCo7g<9`~?|&W>ZdygD_ liniksARB7sw4 lvE* _x!YN1ܿc]zՍ mc/P7E@olYkBb4.ZƈLőh^p̻+;[Q)f܁*c˧sDSyNkĦ"cTc ^^=O}ΩEn6.^4a,1wSjuL_3Vj϶ Q;N9'!̝g_> [v22ü* U2 w9C[y?b@HY=r;yh(L AP󚞿hK{So|tDa[޸R}sgƍ]zⅾ#}cp3[2d(+ڪ?qꑰ@)*.w7ga)YKKnGjv!i5M"LZ̰z9R;',,9GOP ie>#1ɷg"X =-nδ{Kfa.? ѴQXP ljw[OuQKPJR`gT8!UvzO$_YߘdSc IaO-->Va٥ $5Gnq;fTpNkX;>~?B-W}>Ao$`:\ћg/HM\*Q4|F--j~AґShD\´9QZjidB9?0{[my(>1IFp,t$ &8A\;CzqsK7'\#a~Ӝ/*hcV-'X9~QG+RIq:F%&kON A;x9J\$p#+Sc|WZc N)cg/©m)N艗ԬBV}koX}ijI "âc#5 /1dAqnq -*P7`O.A4=tH{̲3o:9tnVdHYop1"%}|Ln|P';{T*vzWpgaP+7%ψ5]LnJ+$W;9{x+:Hgц̙$"0Z)#892IRszJ$( A>A|m[Jm S󪤰qzL!ͻV δ`pq收 ] k/o3T:CtwcXeTYS m-+0FTI` Y):z ~z{k^O^ޞ4urjmo ԙWHihM>\ЈY'7-Jq `T-0G;;ގn.>&VgC)ZW`$_ Rx=lC| &OҬfԩ` 'Z Sز65qu篪h.*̌3i|Wvnk_17-qIVپv"錎=92RU__l7ΌNYS]/vAxi"Wo_; Iq"q@[Ԍ8F)HZ޹y N !7Ě 2flqͼ҆3WT,wahͣy+bgĤ2.k_| gT͊H h]d¹p]]R#9G xkpYٷ4kiZּgaIvumigLj޾)5cEY{*=h;o,H&w.5gfK~ E/*)]tuuk '?mMXkC݂qv^y995iN[[zIqEa~FA*xUmZ9%k}sX$DXbIƊ-ݐTUVQP=bykQP*9sӖ2pB#g|v4d--X_i@׬5m] Fg>a{Q 'X1iz`4[/XevqQiCaʬUUv "t@[ֲHM+b [UV'/-[2]J7ԭ)L[޹qsJC;eq*h^sHgAAAJVuS[@{Dy&-_nY ]=0g,핸m)Z*w|¢Uv18'?r" 0eM+s*;Q^s˛ed5tr1pA ; |x뾀hgw_W)|#7ힽ`nrAw؆M6w D:HBd T%r?rMR!-Ҭ4`օ3DUdhzaG%~mM5+w̛$0 #E.EQ VT,1 nO !QF$΂4E[_5ٗ۲quˣ͓cDfI(-/2R_//!9rTy2={JZv\Բ4aB3EsE}* #Ę;KǘQ]P/uNS_#c[:bnӆ4jb+͕ؒ ohGEN!~fPAh6'ԙ.U5.`U@ sb}o.]78XaR sJ#D\֠WN/\(B.eg͏WY/jvVKzK*2JDӴB1?bkZMJ.~[/CsR} 8!JoB .^~მZ$7.9PGdJqV"]`mo5eF~CBxH24$2>g/sk֤ȶ{mַZ]ڽlnѬ)6r{xg҅8j<)7`4 II+R6oO1- ̨?ؒԺE'Vm&?_<3[ v梕2Z6yyT/\V /k[tk6` bAjWc\>>7uUV7: 43z Bg ^[+auz56Еzz7LulM`z=:Dw6Z>NooȊr ,,ψ#LhqAjZUgA#ŔmuZnju.:qFv׭'iE;XqĊM׻֐Oky뺃TUJc_.aAQեs)1jֱ;8+G7;dVFtDzT z =4y$ ? 9{F'g, ,M# ND$Vv,qsF)dۂu*7NVon_98޹jگvVR XֳlnTbӽ'7օ'۸%3P&!5yڛ]pw)O&f Sapb~H*\ƪ|d")ᓵĩzzE_4V$_I >>gPuf )U{支Ȱa٩|g8 "fV"W*eZ=N̮ ;̬a19Vjd&BUr\pis[)*"*z9CNrM)H @H^^?M$\tA0+͗/jLpk 8NxvZ2{aW*+?lU ;ǮpSBrցv#Z;1_iqAJWغvT KUذA+GƢ(˗")a;iF[V嶤< UfH| eAG+i]tR\[ZOjYk-+;Zo\$IwVgr+b/mhT" cɚzF-i2p&NBkqBbMn涚L%-EZwlBJk5)Q~2 I=cR0DrZFiwޜ8_aҐ1㭷Y[ϐ'2#!BmO ֦ijZhH,qiyRdp BMN'Dt&\[0Y; .ظ3g_ Ik+'sMByWsjs𖾍#Ӭ0c檮Y9K3NFL+lPdH]c$!~ڲ.:G+% 4ApWzŕV͔!2]?iNZYQΗ5g{pKߦ[0ŕVrb8jY=$s[nzRϯܳqOjm)*\А4L jUx(a <9[* Spgj}(Pb*eIA^.$*T %Z878lM]wƈ+ruX$i6gl|iIYeI-}`˛6xmɆ30h3r$YXglnSL/^_68F߅巀 a$wi Rs.ɝ1%`Î{#`eeIIZ!6n@k.徻,d8Ja:]FM%2$M8o#S22;"JqZNME&ZT=mR`MKJ ƒ }ltR_((9~I NY,' 1Ÿ^9aC9AHl/U7eW&B&E9/8\Y)LqKLJJibLQL$#!ܼD33nʐP0^45@ՓERӜ ;"Cт 5gV`aUR,k|{vTy_7qR"SrN$U'Pr kyrIA02|w"Ok^iRJG.N+ !k]YV#n\W%L&nc$80ݐݕ 0BXԐS$R6-_2&Å8y5W?Z|N=E4'5\PXApXº}jޱ]C[Ge+*[>O!(C{=|lT_f5ELYV)oSRZz7w omYW3)meYS&dqwO|UIRaR:pߦΎV8 ܭ.tv;OZӼKIqI[")N ;b_JgI}cvM:H0$CJ swNw``SA%Q+܎bZ2)  '1Am:1%-N5\=FN܃Pfhfle!D߀4R_/?ӃU(Оs{Oo kO SsAB"W+ }B9RR)1mAiWR$ ={XԾQ&hcO&]A5 7h-NF~^> C;`0o(+/ooK+kSha s^=5)-Fi}{G`OP//o!vA^aAvVu 6Ӓ'KqZ8zxlOkhOR^C} @m1ɨ2wi_CCCfuS`J ,⫠$c`d%hxٲl%˨N6[N F\0 0vc(>pAN9 eYoSH?$ 5R|HJE[lo$77}̌;t~*y%k*Μ.{婕# Y}~yvIc}S?rm/g$ޒ0B{FvN a'?vIv /g&fH>c{̡N`){%}Ia|Z"=8<F[¹qF+#'y#7x<|l]켮/v.LO83^j%1=̡Uv ~OIwi#CbGzf7`qc${yF1v،;ʤOӳӐi^ʹ`R}u.~~4غeSRl!:gʝzjN^PgCCCϟ_TTVsrr;hР-۶.x K.lvӎݭ,6,vUZP&a ]Q_q)˚X3,juggAG__٘` nS+k\9 \x?HGH?敫+mPæ;_54f_9PB%1stQsV!!'ʾ500jY]B.y^?##c_'7 sM;U`'mn7\="PRXV 'ǃw>xhblRK u6J喾7? (\O8XdnOKFx8=\nNQ3O55~4]G~V% "h72KzA:=}g?Z/86QNk9@B /f:A!,i!@2PC3Nnr\ WP6:`\ J5[7Y:ڱ)^MNC#x}㥀2 2y: z[!^"dy` M >lyALiÚ+.̮n)/۟thgɊRpb l܈j d30v 0vc$k֍ch/K# z%,غu2ĄcG.]}ڵ۷o߹s`۶m[l_Éu.x0.ʙe.]}9pqPkͤN=U>/M]Ԙg++ksKz}^n :ş` QIV~}Aq@"~72~ޮsE\ 5Be/ԾJB9.Hba硻^5mTɣ27<+}T^R^YwdAߎ*2z Fn#?}Y=&>;._~}vQ +q5'29fsk7˛ >99U_Nb"Vv2U~R[_OQ1ʯkĂGRФ?_ݻ5z/=0>u#J}٦~ |C*g1 t:ۑә,+QT@㘾4sA!ԛ)Ldm, ;;[3b·<Z&MG^x{Ѓ2&|E'CcS;/31&F5 a&0w*þgē`ou ",wNL`h!ng*3ǖF[~PO&ti9錳9,d|Hwx'BS8G xf;`۳)LgG?IFN`EӁ&n#tB DakIpFRFE(Sɽ,DN e RaoǁMԈ8l=mܺ/drbWd\Pw>qDDDDLL̺uN:uر :|Xg5HۈO1ƉWvu zEImڧ5Mƽmyz9?vD"75D (%nGjq`v!}C qNc4K&8`ƉƖITLh$b lʯyqo!G\8vղiQ}7Ve@?>BųpȠ.!fk1 %0sv}>xe\ Meo/EI 㶪 NާWxc<=sAm] Nrs!L nd*3Nw3c{$ 8QX \O6-!tӽ}|^} 8== wNG e7J ubsSX5oKa/bfMS4}x?*#\p\Oh ;1<'ڰP^/hn/ĴpKf#!f AL(QDpF8?H z7|~7]{|0Ҋa}>q!׻@ҍ!}՟9ٶ{`Ëz3y,Myc3wgG3ٹ1lEcah>L^"$x5 / d<(xx*$}RN& DbW7lY=֍igkֹّܸխL1.ػJ _zkj<1mMo rh%npx0]pT;Krݳ=âWTغgNN\햾ŋ W>xӣ,_<99^of,~ PG\?.0 _yΜ93<,lܹb#'cG m`pC;sAS O1 w~ F3tmg0+lں0à6b  {ՍmtJ5pf[  `zCa tӃƳQ8ߕՕ];X],f^ @q=Cf. X2ISX e:w@st4t2*Uy<2aW4Ln R8S>|np7$ " ~Tz )D\ r/_|'Oڳw@B|9eJsu4TMUH[)U 0꿳˚'V) fߪzpvݻյ^]>@˯~ghJ`6LӧO}~/VsKyXW[XWOnL8w[WUST'Xd2p ?S{|+9bb`1jm{X*Iؤ^|[r3Bɳ[C۴Ͽh?+^c<:M:P%V:+|agu^}\賋% 0+ܥ+U۔sс'MU{qYyˊ{uO>dzWzehzS??~xJZ/sA~eF>mȑ# 6nܸ)S $Os۲úuÙz/o.hbOƳQl7O6?g[>eFw2ᬿ ^4)),=9܃f|Sݠ p[ %{0ʙwA3KX7 `o 0i9e;\ʜI$5~gpfGb\ .@aN{jҠW$2+ S]u.x$nΗ#,0+?f VM=t.hk@cW fta-٭t&\z#̮]p8{aV6" )2hPF}xifnl(k_+Ǎ?=cܔQ3bRi>pQLKK`/ƔcҘZ9sJnXDeN/e%qB`2v3MNJpӈ2}]-dZg2ezF9}hh@>wv aNĴ3O-ЩטɝrX9rฬ)9t7~|VPHI2&L;aJ(9NHF.!Y&xhZGqQJ /ഖ;va#"ݽ}#\1Hh(+%TiPV*pTӅ0&r΋eagh I5Lfl6مP ]8z8.n1q1삮l{(+;hl ?ZчÃ*ʟ rķzoqg?yۄ2\Z"yQ#bc=t§uG$!I|MHfCc3Q|f ;&|iB'5#ɧޙOk~ˏpL8t х0+]؃lzvZ>o~E1lkE$g.L:s6Ѻ+ ؎8Hq%'o~[h!!hDFa4WJ*FS gYߝ䳡&(nQJ>\j,k[kNZcfcn]]>:˛ZD$ҥG.\f8w_&u LF Z'ۗQg 02+[L^$_2dkoi]R1#N9u'DyS՜c!tD[>J7%g'ܩ'kɕhs#n^xDt*vU{OΨb9Y72&‹ZSK[|9muV緩NH)tSf!K'+wD\ n?l;4ôtۦf7ҺRu͔O(TnA5Ŭuã/rA? [`hɵ4+fA D "D rA rA@ D "\@.@ rA @ @ D "\@.@ rA @ FiPp%w'%rA@ wH5a*hmdn'D uA^ 8|e?ٰM{»r.ZTrA@wXFvYi+|:ZٻYٹ:{aBNJ!,PM@,͙TmH:q۹kwd]y?II짵ib\ovA=|`or2r>S .H1mH⮲[ \ @ 20Rmj^G7_RN&^&*pձ}pѪA\&g~mըp70CBPVY(ߪLN6&4rSed?HHmڂ)LQ4R&!?aP/r> |1y2㬸DkR >SIJ*BmъFXJvX{3÷TU .l?d1鶓4g %ڎB[obnsŤsETWR@s#EZwVp\qm\@D$}[=-nsEroqGzc]U rZuMMC6ޙy8zYɱJ@Hq&8nՊkws7%WhLWj3lNɀYn^]riB['u%d2]ӅsK/t\xBE WsAg& s융@)EWm Kl¢ۄR#.(AוOv1";Q <9Rӡ5lM9G#50}v>b2jK3⹠#&%MI7{X ]"oD8s:mZ5<L6KmIM*J5B}FEGM[0.;֑^NͮݜRE`ʢ{9[N(:Y6'C"TGjDGL6_5A5 Wwxr?zFx0k%=joz}uT!v[Sאl(i}(]]2_mEHh=%;d5.oNF>FOMh 6]_K2̼]>D:5 J@  wx JqEqwi5τ@=pͶ1 oI?V/(e 2π @(S }z&kɪGһT*L`:[rQ[s{Lw$<5`I&tه;'۵'^:aݩ)\ @ʂ6L|wo@4O>xk}8hB& d(z0'a3lٺ]R}$"lL[:e=kN߈ w."Bf…mժ6f\&-B.6dsa׌E'[rFg8VyQZ8 JRcecLLJr {OhyUy0gEbʥ2\fi5/n^l/. R=6_Zk 4o՗/5 D ^#T~w#,m];׭g?R\bp9!qRFfI0.DH D9͸UrVѻ2\NFx?*mFޕ 7*LO JDlxlqXgc,zZ[X|Bvܛ_;1(}N~"mx`t.g7R-\(;+L)ɏk͇4ˏXz+VkZ;ar&(zۅls9P驕q ܔje/ Rqڙ[mX]w%JSFa>kx~AH<+9˿?#8e޸{3Y kphqoP,:P~%8$Skw"1ӸFmέ@ZG,-.دO*$ۢ ;p `z ^^K.cљg<νyuX/p/@ ?rAB* VO%QRBCCs)q"yϧvN^+:y?(Р ))JÅFJK0Jj&%x Ln)jN^rmOV9x^B!رg݉]q~~gޫ=|eEGå@HAeeg+R✍Www\В=]BrՇ.vrJ)_WWMty -ѭP4"W꒶.xfuB Vzk-kVBBFI?~炔m-| y3.}7sAZ-/h;Xy]]PAsooį/80-iNJސk*赅 8)HNK lE)"D u]~!69.Ӻp/$bܜ2PazAa?HN(eP6gYNF1pZ,Wq .'cl];^9$J%į[?'U2BM(`e'7rAorARɈ@h1RHHj>FS1iL=]lAN:MN7r"(l݂C-Z$UwVN ,}B >ANm#A z^TB"r6t0;ks6^vU@ݛO0U垎ذ~;Y{Í__h-!$rB{n-b"L6ycxZArA񛹠D{O_V054˯?yR;' .&+c׽k yK@*#2B+XR+\=!f7+H9e|`ZJ-jk*u"nm#*ޏYN T nnwTXyR7,1 I.7{q*5־*~eLWө֮Ilzg^Sy s5)vfo]K՘m&%ݧi)߮Hɹy*7#{o''GR$twtDSK~!pH%s̈7G ;;]Ηa釫w@蚤խzvN%_^z*莚Zɼ;|Tu?!zhZO^?'pW yP$l,zja4D nw/[#Ml -оڼWWJ5RoK;I5A}/K _85is.a^@BA*sA7r\SP1iף+Z|UpXKD7uq NkE ~mJVnʾj\m DRqgKJ,%sغ;^&3p fT Nﴖnzzzrﲜx8X #si=d_bAV )c{`0/#mly4 [??= SW@F*T#(DmihI4zv3ݟ(/; ƒVj[#-\ÝlhZMjm:xXKpi`Jd4i`w+UajknARRkdf;"3PK#ͲsAN\#\j5NkH}+gvFBpu rJJ [P%ť1 vwx+g cDVt6s 4ӗ5Ǝ^8wJA5i'soupT) ij7ҜS]M2l|}=&N>&Fֆ6^N.ZB#'(Ň+{{kkp7'SiƓ+//S[O@3Cέe?7DNє=8Zz;*ynFs+o& ~] h)5s;/;Kk޾&FmGkp,H8{@c9e =L(-̓˒kt.|qw#}@/NĻ`}¼m܃<}M y"Rُ;::((J`qRI:8yqX\r+|ܧᎶ!8pO6I+,hwDU&VVb""AAi>"2rĖKvݻwm9˒ޣo,vYgvjjq1Wqyr7'DQˋW7'e^>:ʚ_ՕΊo/@v׌6Bß/mB >ړ[_J>X6j~'_UU\d@u}nuSQEݪ'd>{nܿs-X~̕ߔ`:i:kwr-KL']u[^|qz,{39#*|{S9͹跻 jST=K}Óʲk'~Z z!wQٷoVĘiS6]ny/<45ވ^oMH07n-B. @ -ws(SMS~qWJ^vIA~Inm05|u#&e]qaEmqի !0dѣW k|{~fBûB#fl..m,+Z?ӵE?/g=`uMɱ ɇk]S7wEszj(:~ۊv7066+N@:,yR9[) 7|_~6̤GR0ķٚenUᩙi o}ej' n7,x|z9m 5uͅM(^ 6\"jS#l-lR>yi=,?˖ }LiڳS޺`Oc2~{z0KS+Cٷ{]L&r;ux{ 59ZËc5͵7",\]i)NͣUZE?ϿջylOkhz_o\ S97?S"~eY9mh0zqs+~2{sX_U$ %z hщby:S-j.2hԱ毮oI摚ڛ lb(,qn@ ej눣9;?@c8A]YVLu[ ǰ&nܿ;ckݝgN1i;#y罗6pT( 콝\ۆC)U*~|yD+ixup|`Rra^]d~!dc䊜9 4ԳxٝĥV}Q7ڜTyu?zgZEniX6oTbgc3 ;x}dmW:29\* FӶ}l ø 'u')u 1Cqpp(\ꠂO'~QJS"\C+悔R#$<_^w۪}}IKKRq{eG'aw~yO; 1IT }T@LƜk 6Bl4bIüږʚE M]&9QaEmYMKie]nYv; ~:pJk)^>7w01XI+<5jl-bromLKޟVyb~]V/Ό%9Ō(kjq/x?₥9dWj.Igs᷅;:}cKs=q|z+2L /#}l฽+._/ldeAd8zWm}>:@lRI%{ܨ[> 1|H^{Y#& ùB7u")A\ G(.y4RŞҿe B@ ئo~P]9%=pƢR.U \n Ԛ,}_hU7BP$l,|"eLnCie S3>@Yͣ{984esyM6=wܱ݋Z}mƎ?Q_0^=_hkΉw;Da[O{7i`ņ( (ҋEbXj&d{/9!I2̛ɾ[˹gӿkyë?MDS@m؊m\M㶴\pӥSƪڏ;Z$@TZXїuOlX`b8)RSvAۍ+;b`dRd8Λ? {rAٻl}7hu#ƹp̄*eL};a j8F$[ R"(vjP!j.(#\ìe5=%Kno3~}sQ2#p2u}`twJ wUu*<&"\Y L H[wdٗ?y E\xў<;cD&.|G\T*`@_sn#Fx ]4JKKA #6<;b&킳+>7px@7j O|ٺrr@Xn_LsK?۷u[OǘMU5_<:O=I?(NEE$!@Nk w1@v뮉 ~īM!0Q~㌺'mӬ& מ\| ߿>> V=1RPRvu?{{Ui8eϣ´is tQoPoQ1"Nn[;/ґ2Qд>Mf H/9uwF _,5V99s nj YXenj&]{L p,y(Lc2sS__ItWe*~Ǔ Q&[},C;yh!`b)@e4Π P@+zw <[-B5 Cd#w߻16u3CG- ^~v$܋{Yӧ:xPY71qұ|HLyx `ohxU;x/MUH)ac={8.gwKkQ} Ϯxqnեǧϗ3 Yq xnlTD;w |4|XEޕT4Kl J'E0;Wk״ެ>I>OL&|r4 Kbs^P*.WsA KG5[Zi2vkSkMoGFD Im.IFnzŖC&`0SSd%mzEI" eoH@̹Թ3M,J=wAX/$+B"dr3W˭.x IgdmF& }]0/4S6|tZs՛͍Q@bt"AbDR~VgJ0j4w~u!> [~d"co!!!q5G w/Ģg;a#G.2).9i߂0h񕷯悓Q=^ŐrNo]p#n瞧hCoVtnlvgg UjgZp_%Q=0kOO+9\pM*s j+ &="V߽moN,wx78uV?ĥ bυ7mvbm_=}&N?y\C0 9ecS;=o/5#q_JSE)iu3U8,o~c ._nt}pAOky/Le7zKMϋ4=1Sk揧OS.hw獻\PPp?6߮fJ]ƞkL7 B^/Jݏ}r Vѧ?Z;W{=wi3oTͅ:¡lƨ\őWu@Gfno>yև޼~br#AmGӃ Ј\PGӨ[٨u<}]m}ݍ5}Zh7l|AHҳzVI2ҋ=c%zV!aSp0 PjI\WfWZã.uEevP._52`M nncc +) Pb J+>pʂee!ԝMLv4E&NPRLߚ *.q6$D\\`ʅsW=ktVJ4C AQ3rEK%P! TA1&lnVp>.I!nV/Nab}rv V3uz{GIY)sL 49nbb^{gLCg'eRBwϾsDLJ.}δRaݘy0 SS UIR̼ܼ6&{h9vahƧ| %)4m?uuMd[^oI Jéͫ-_Gg_ٶKW+<.P vWݾ0>ӥF0ŋhW ]{٨` ^*loZȁW+|L]Y6Q%ha0|yL3W[c`p?:ȣFlBlO"K$l.DEr5.J*pˣLVA 2o].>@ʥ~BƃXvN=Y 118VB,bsbApI_QSB` SQэ供4LE>G:,TD SC"Cm)+USp:?P1p O '\ AuQ]{Y%jXt(&bY`Z{)(S?HE8-]'WlBJP;g蠰0JHSfu~&?=@<+LcY1<C_<ǥ@3([E#t|@+Ó٥ amC+SGPq^cCCSW }e }N*,Hq@n\BPRlaqסtL14W1 7"2vc*Η K ̮;LEGj"Mipq,_8\ȗ&Ӗz@{,CSf8JwpH l>3` 57jcS?jWp]hTm׶js\644]Gۙ !Pq4M`PڮW߼=3_[]F{?|Zݣ'y@ ~}Xt]Ea:&`#<MGwM\[/04?9]FNY|jivqk=Kp\Ex*,[~ \gw\QJ UVz:5bn5FT.γ].h8mK}mxk"bI"ul_WXƽ SJJeuB W||ۑEuO)1|@A%Yّ#y"̤Ey)q1M\\ Md%-ap8d,]pftmEAZu#Ps]nub;G 6t+.(#?&]zpowGL29@| Z[ΖOP R.h1!spi$jG85㜺BfL[~Lƙ~6 LqΪ]|=FyzX:KP@>jև$ ۸(XxT!}u1_׃}y P!E.8d/5Y"/QD&nw|S\]O, cs)]p[b #%K.w\ZD08 ;r|.0Jލq0Y6?P?ݿĄn 5ŋy&wcP{r&`8^|5;d]s'zNZHp]3Ks.)erW,*GHy³ ]@ `1QvUd~.,24f!3o֮\`2PV(+tsg]c7or6e'T<hx{u{2h JMfy|wM(`aYz7gΉK Fnoj^[sԲPb*l ,ު^\TԵ{yl+C B w1oG:uZm|F0Rd`aW]Qko2ͺr{_ۈ`O_%TPC ,6l6wQa*BUMKDFN*&^A~z*tA%[}5\ItFxQdo¤  @~G.!n;#.9cQɶ}'()y)D wB Rt'Ɨiֵ&J-m Zq@*PNgLX{-].ă3;ɉ<D輔pl(ѡlˠB B ^Pm4mVbnұs~*eA}ϥRK Pbgު]_͎ecd';U[}\EJ.@ ߻ %pD R"efajD\~V弄ԾXy B AX54 qqq#ٻ0w+PRרʻw69u1,v ǭuvAԚ]z~[LR$6$)11s//:Z (-\;1`yӍlk?wbZފ3.))j`BD1))z/J(*mA(gQ5E ]Wݬ'a"BBW'*'!D9% Qo.??J0A6b|`}1 \BHwsHcĮT`o]]ugB# [-XkL| SP/{1$KzAl䉫_ 9| SXUviNS*$On%u+5o/8gݣ届Ǿsd8\yUPW(?+ZN b/X6qt#QN7R9?!3w2gں;980`֖篞Tg9[k}Z3ː&bO=HwQsr*9փFL-ךƸiZ׺Ieywi3T¸u;鰯ʢ8M^@k.Hy%(=>2v^F\&1qb.l!D"MS/`g;c'$*(#FyysyrMK7SMS+Ow;vA^~!vVf8`ꘇNZz0;kSKmhmpA!'O ;sU&F%z&z6>!^>6VH>m3PdT5`\jdnM="mC?j=FZqPvd\{H{ sAO@Hul pL<K**PQnRQg7o:yZ8.&T K-?`qI֮@ΦW޴nqG$֟iKW^hhJDPKZ]X@D=*vs͂]'R)ׂ'v[qMxʇsXF`±3 8p-ԃaƦ l(N9SpAC#rv8`A3W/pьUXXȵkc8l K5tM J6X:pqʰ%25w1.H_b¼EK8889rRŧr=AL,ݾPMQ%.#]6543Veshj;k7ꪠKoLԔ|w.~ă.sPwmB2K)]&'gSNčqv#S6S:9uIwNP{g(!`a( 0؅`\%jmݵ ǻ$NGnkRVBC} {(\pΝ] iW7M=⚶+%@c%NݩtWg;+՚uXGkI =h֒Wnehn9Kʶ9f,)wػ\pqiii{쩨5k%{Jտ7#^-'i,cMW\ϧRY=4k0F}m~$ =wn{s[AW%#>'dRQww(Y _Ev^, wӫL|:;ot36|h4;X f|I׶*\pO뻌C.(,)7ғS^''1fkve8RD=g˞,zj'W ەD }y  .80ptDž%mO[XDazn1%?^Az0,;K(C2ufW7˯2f v \L{2%3v3fk{yy]a"7ʾxF NAKk޿^>D򉡂 'ꘕyrz7G|䖻8Q5kvqNeYFjκdx{A)hGUsz$Pul1CEZ~>kx|ZskwW$3`q!ڇ2F)KpO$׋z˭)0 d2n?햟TmUUXvٙuG8x;{OHYzO"O9vLDeNtRfmK6ذ"EcM38+Wsrr]\\݃׭[{QumC5 pW]S4MD؁\q5U5)RZ'~n fѾ e?]w[jLױ,=qF r0cDӕV ~E ]tn;wa傳+>|XuVSEEyjmge ޡ 9S-ƔltɁkǺ+B2aû辖fi;wd]=Ml kT0`tNݙOo‚e ֓-^Q3pb} 8,gf|j^j ]&Gϝ#fpI3+wP_'IUOb* "#l&e(V &IP6 PriN`lQP.83 ePGPp vcM+3?xrF¢6;mLwhBzTnL I(EvE:b];.tA..5,7[Ybe?I?8FwzEI Ҍ=mp\u:+̨u.A=`rK% DaFZ/ A5M92|6=,2޾!cm˲_@mHS'حo;)xr7*R˸ G;;;{g(3S l{:Ltċ/3(n0QwD9,yڕy8Q l4מ,0\zy6^ ; Y; -չN.o|_$G'sc½(tyK`𣝏wg';9{޹dAʑCC]GYKH@do5}/sAe@B >S|ߴB@ Eb17<(ShJT~XB3e̼L&? F JKss-t a8o23kEA t<14lUTwbtm/G Qxr  NMB-efG*mNDc<@v\ʓbNe $/ syr%ݢsbCU0 I[T`LD %4<9'IP%I`|tN:<'C3fGQRh`pYY㧧MLj_ KWe$%aB&0 KZBŹz+`Eâ`>_/sA@ .HIYڼlΒUKVm$ls삓ߧk(T>GO@G."t$'Ur8pMDH dc) yPT$=Z5 JbV,TBO`qwi1鉰xt *Wta28᳸$:\Im"rT\*c|jxRFL0Q !9 MjE )dCm5(!%` tA@.HK!TCƓd s->> ?~\]]ǎSL vA{;_M b9 ~zZvE^|G_vwڒ_Pb}5@&-/p4Bo.S+<U~y/n~7pP9Lߟ.AKKjaG~[z t-{ͳihLȾ^:xE??jhe Bw<{{~.p B sAҒbOOOwwO`HHHvv6K~'P˜՝_7B0+C-U|>۴UM0AqZ_ܔm uիJdS31ɗ:֜ 73yʹbO:e/T: .@~Ӧ_>8RUݞib˄6iZoyq]:YwáizrpCnE^g)x8hL_ܕA.dgoa.x=y ΞbFNŨ9l'<1!tA49266{EԿnnnYYv.j-ʋ$.k>*dcɔܒⲼe)z":c޾muMEʘ|G]pM{ c.fk67PcP٥+0P筣3K M7cn(k@kּ)vn#Fx:6W4Ҝ{~Q-?і^-(4ڽgy6-1sCVZL+ϬcoL.#}GR Xh}6p{.*BjwmsueL՛ci4:LL.@ B ߾E~AAHH۰̙3SRb1Bؘ!H N߯1*om/`29̔sX]uս-B=.xgҙKo5ߦ(EnΈ`_ښk8S]<,-+Ҵwb5}sUd9<bOv=t" ~s}.r$ Cȣj>ZFP ws,&F@ B  v>>>#F9rdyru]QQ"h0=aA>n>SU^:I+Kƶskl=\G?َZy- s}[7GSa[s\W|ߟm$G:a@:>7Q#.盖C H;pWO>mhő@mLoYʆ:@ B  *`BӨ)))iORR1b'k D&:{e^QY^qy,[CR'((.+\b!Ȉ)3#tQ!ʗmb2zhi38]`Ҙѓ#3si;?ZC]RMg"y+y谹9zyW-, 0qy!tA ]Ǔ|ru )dq HdhMzHBDWbME2e?9N28 *#C l.; |th?q&= p NXTA&ڳ76EM|:,:h#(Q{'& ʕzj[z}sl+C@ !oʰ*!ww%mW?{79d9@}soO>ܳh4` n@ !?!?tAk͛3=8ENŬ731=/%+/9#'jH1O B ߡ L6ĤU(iįt$)8N Q@cDHڑS: bP!AtAJei[eO0R&5VSSuARil*E1RcLѾjP!!'%@h}&&$ pٸ$I +Qi@7ҍI.)%ʕ%XF()l&X'O3AH- FRMݩDT$l@\HX\:-]@ _uJ(Wdډ@:3g{KnK l =mth,)XqJZdgO*^F<8>oŦ%e1A6,ʵ֖ORg"%Ed/*]OcLݜ1O./"85bVnyqcP!!]xbMk}ܣ*mSWwnǎ0}5eV/vS7 J[y1a۶ >^~W;WeCjX|Yj8!"fϜCx K6K袣&a]YYqN>gYޮVn^%0s"+zD1">ZC B F  6@|JwеyQ~|ɂ Qf_om{ٳ(S=>6om!&RaD3h'Yl͟MsFe-_dmPv81H 0yp[ܯf]wWw=O{t_o&`V|[iNqQ~Jzl5 dqUZgx0+u(yܼrB&ͮ;#Vֺ:ǀOҽJ^VwLD5kצD8 :sgK%+m)I6 H? @ ]pV yD\FQ8nWGY'FS,{鮪Yx۸򥇛2ܴ.rySL[S#eɍ+ODugD22uT@_:~}gQLfs.I ǁguS9 [lecdi j \/pAUPоDK3u\0g('4 .\8ɑrLۼpQOI]]q2Wعr[GGwQMc IL6oqH^P9uNU棳IUZf0}|YԂU+{<)fp[woOMm6c:vȈu.hdbB{ekKKTșd]\@ y-31s671 Y#c;O+ SZ$&֮# 2SW{w?ksc+̜\}},,R1Rc{sk#s9熺Rkg)IPA*Y!S\ejaRniH6v.:&>]K*iG,`Y 1 tqD"J[ÌTIp]ѺD&IBfaEBF 0Z Dʱygt.HFG}ߔV@+w]3RF*ZJ6P`8&QQDWdBVRU~_x4YǮ paR,_W#h6N\wAJu7++kzF~TI<>wƶA<ūwlȷ0 A [|ց;;sEVxt؍~(/@ L&n9͋7jUPy4؝ׯ_|h]@(N[|Υׯ^z^p6@FBOݻuWN$GB*Ms|խc{M&7^r #7w/kiA>? y㡮|qeNůLRȬo86M'Kp _42rȋ3k]qc8Cʳ7?Z&H<8uƣ qJã?C=Wgcpso?1?j]PM*OX~[O.X* 1Md3FO3WL[k:h^_;㗯]+1t^\r-cO.8rSR !`kkkXXۍoҲ2!.qd23uP\ds?z<  _ÅW_ Sm_x>6eۍtYQpk$O`* =l \0bSu^yglk&}w\¡jۓEXy(pڪ*9._/ֳIpߕ HYgs/v÷7ED?ws|L#D  /_SQD ~EMMMll,Ծ_zE\Psѳc.p}xc݀]pL(( 2K:p} P ]siw Zܾqs׆G=;}g:xգRURՋSGN>|ᓧyA3]}vΉ3pȧɱ%o/utgG~:Zm$f~z,xs. o\I-|֩)UZ  y)H;OJ6(i 2.xc[.8 Y;&ꚠe M q{]s/:a%6k78ﺴQ}BC4&,rwW3ȴ<.sdk0 laYpپ|7$ |Y.(4v;…~c~eӴPB$06nȯ?+@(L<`֪G*lֱk4+5rN?xtI]=2ӆ.:d`X֭̾@;g6'_BT埾!>>cZgΜY\Rɍ?Ġ>k]ܳj{ukZ"b_M~뗶\0 zp\2|R&4:*~ܒڥ׶-X4 q_?IKbt cؘ=B S<3:w?quxs׮j(]s囧?0&p姇7}1IK< o(%",*{%y@,0jJE)pR`d񵛧/:s|0[ԫ$I0݇Ϗ:u j "y J]>|Wnninĉ=J7m]do!8poz}L'@ Xؘ _sg@ W{zX("Z>1){)$QτaB ~KݓNuiQNbZFmpɫBqYIbB (=.:{Ӓ%$(nz͂{ca./:{lM|5~Ӣ|k)8Rl{r'š{!'6w6W01U篟qEAIuLPZ/H;}uݿ8'yɻqP9Ol=\@ɥK1eK"JLJq[bŧkqK#S럺)DZ""78T!1s VISVG=S~Ri RE ʊgqA=ś[;ddf *~[op1 C.N߾=vA5p"8Z{DNĘ8ZH}S\45Skң] N7SbfXy|;L)]H1 HN?YIIJo1 ˁ@įIP]LbG &#"PR`QO"r\,y+ kop31+Q6oFp}"E}|nA7 B"HqzG@Z;v Ȟ/}04 6ڼ[#O_ LOGl<."vr]abRP93-AK<}~[ ?.pvzOHT1q^֘P"tAxQw>`QcR%N4!9]2~#sw^ޠ{/}~u=zoBڎڱFZpq.(sޫ?m FD?$9t _WlK5=xy@ GGa6dȜ"fb_lѧ:Oo $pA;y ުXL_Z2aņ]iY}6 M=Oahй86a*Nq?5,%g><a4zɁI^R2'TXP绶mll*3g-3=5[ZqAmXn8*ޖq2,iTnhhbܳ{csS~\mZSqj3 !>~Ƽd}=6xّ}9v'/\;q֝1KC}t.\mrׁ'i'Y̢OQ'`ލo,{L_zfoL,cGj S'Vu3 ebQWduǾXՐLD\@ .8!yzGJw VQ߹n΁ޥ[RDԌ܆w E;wFD"V4w_U{ޯnwAĬPv`J[9M_uk?VD M3wdmse}[ЉoL^;fA$<(#?e6\7Z_ͫ2t! "_;WiS[ڹ8zXٻY;_C Ffy r,n|}ovdT)L?Ҍ1w7.ۚD7.8uOWH@eyoUb&:k[x{z~.O Eɑ 87&9KF>L#/Z#q 7ώBZ:ggMVArA@K@L3`x#S레Ш DNC#%uA/]ei2}_6gGi*uAAg|{vJ=p=]~I]t<(,аRȮ—JмH~xs9|ܔP+O:s?q79ޛww8L%il]FR$C D ćdt.aP&NY~g߲Kl)f7uI]G/\TU^ͳ {" bXLșO6Imw|yk-NRuC{'8ԗlڸ •~Vb,ڞtQ;d$4~_p7ݣۆmuvP āo#q!ccƄG:Y0wR SWxtXDZҸxS^;VƴD.V ilo Uc`5.4b?@kr]pL˯цW=Ӝ,:tn{W)''h IXvi[ؐ7+s$+ DRa]PBy3-?x hP';*)VF(ÓpR* X3 tPNdtqX9 di{ rmXyy5BuK:`BR5H8G^uM`ߖu]0'dlLhX -@"(uupr 3&(Xn@KU-8pۤsL`5nTa_ꋕE;V`-m%k>t%&"(Өu.ZPVuљ-Y!=O^^~$9T}| ۖLQ5.p6Ρ'vw|ha e/.%8É[~o]oyn<_g9q7:{nQj \3O8R>VHH@@; WTMs Lܻ'略_<8kŔߤ'Y0 ݓ@ | WR%\Ou%. LBW[晉)Y&9`,ip.@svadtK8kh1Κ= 8yÃC"Bbeé[` w>DBlxƸYrL|wGc]Pnuh bјW@>`7OYv$ #3uvk)A j?4;'9s yE3fICd%!7<&A:@ )iBJf{JO}äY]?~[Y;_lœL *;D5t;fSv??m XV _d y%C( fg{ۣt]yN.hr\W)L炧Qbۣ 0]'\ݜ  #!mzJP2y5F;vun7ݻw۷nU.*#.;rUT΋32vA#▬hvAYna5ghR[cĆ)m띋]ZJye zzoT w喝wֿO+o'`CO#|juA?|>_(aq! ص2^hcw̜6Jɥ! #m[[k]0ktu=RYyXsڑdŻ|h&髮L 3Wgnty9J!+xSÛ{ .%HVL]-qط]BC[ sW ~@GD'.rݢoܿq^ޏ.־x|e` 3`rhuHV?p졓*"Sz>vw?;x`{\HvѲ}: <ט#8*v lC~'F[G!ՋSh]s/:uرcΞ=tΝK.y۶xp哅Fc}y~[;iN陼7O\\7ؿvk]rE]zr鮎&_wu`A#_\d/.@cBnߑ7}Fб~(@ >hD .#h- .& >o_gwL jsʹy$SȽNG.~z~g '_99)P ,|ۗmSg_=[5;aun/БE q'9Jx|k/~{ܱG3 (T"|Ϝ y.)wNa1SI2S ^bz^)֍ V.*1f=fu}4_=ap6b[VfEZO A^mgam:(z A”澻!A2tFWXiUМT)z`y sSm_@mFxW 㴅 3~MeAm$%/1>UN%5Oo쩰f.*JEc[7Dk@3~!1_ec<|2-3Jj۳4ADB pB1%B@3wគh#!rArALM* sy )5j(#ov甆sS2.Z'ULs0M^־ K(sQR` wYT<.( ׯ80"vE2p֊9\ϬېlWsAH]\-,GfVsSgX0)Uf39G/WpT2 9#')y$/ͤũ>6YHb#^p{nƮs5B 5eS\2Mq-L\f49^R)=9sA a,e_Q( aʶ ]3vߨ ڛj{;B?#baZd[.vvjbłdLy[2 t,0-&,-Ο7ez䌪jL*s0yDբߖeX^Z_@1f?a͜H5 yʖ%ԮNۻ&âyNE׏)/YEByte_̾h``6 Ŗ )U&errU6 ,Umb-`%ܛ;uTy`"ҡݤBJVYd&ۿ&]"o<6ej\mSI;(]f\ػ:''{)MK5J䦡_XY^\ʴJƖMw#i&VfwA;Gj[ccpQXLoH Nl]<ΐ͏rs pr433;&O^?#tV[[GDA,Ct{ JxSb{O 04:vyylŊ`kg].nrqB-b?'SkAS{GK~m}Rm5qn0W5%کs`Zd}jCX2RCI5VFc]Pj>$P*YX@4lY2eX{9O1F}#=*v}mVPػ<׆Mb)R1vFOv[ǸT 1XӗSeԂ%> CS9Mf`WݗK`Y?qS DL(X68D낳Cyk,&7mYR?ܘ=/X=YKr {ewRrV"fKgp ũpLZ$'La8u` @>O'x;Բ *34 ΋ջ`ɒQt.Xh*(SDqL2T`<4uCɕEFAѡ~RԺ'_X;-\R;,pV㪠mAJ}W%rA y9=zZ:Y p[fCHƗw.HŀIHЏ>ð0o {XIN h9wAN. 'K`@"~p(ԑLn#JN)%5uA v|ek !Mr[A]o]WRʴ E!0P!~Nt^8b 6̈w 2)[m4-׼T%EGF"SEWQȬE 2\S;7 XU2Css1pO5e҂ ʖv~iC!%kg%xiH]F:MjjI rR+#>.X=Е6 /˝745ʭ'T}KrA+@h]pV="gV/X_J2ڇ*FITv^ʖY$ Č:0<5+ q2bRxȬ6Ʋ-ƼXo\0AbX qu[2Ǚ.h[QK%C+.Xb!Niِm Osn8kkvk["[BMgu0Y?gЈRLwtLfs|5C!VX(&vִ)?P(5rp?ItAxeuXpFƘ{<֛0@8vUsT8*x !L\}|3?9w9kVrI,( 1;TqՋ&$mضm4$LhTЦə3/ʘp $>mݦ{}4MIəs2?f275y`S'Z=mnvYeˢ cf$Ez:c2/tg0jn^i" SXS8S\PhbkNBd(8cIiH H7t%3ee/ɜ}G s|馚!aa70-v7e0%[U9-yE4Y efݶ9m8!'n?.(6}pM|4ae'gLϬXsġP~zъe3eU_pn8'O[fYK掏e5)k@1x # _UZK9j$"5sNͩËEC7lK¹ .(eqlbB&OSMz< lF1WAKN  H'uj %)X.Z.'/ ' jx2:W T*axl5銌':SU;MF=)S٢R!5%:"e2zÅZ#GD ' '&j|5I™B &405ɨC9b1'bJUSGP>G7X<*,1TL-d^}D1qBk֛m0!"ȨxbhV.GBj}$,3:C4.NΓ-T$Խ Fl51<9JTGh2l<L Pkp"#E[)e2zT+bǴPOJp\#r1+[wR" YBo6ty(sAidfR-Sl/ląQC =] i۟3jh7%d^IuT# $ Cmase-?9=g^` 1u`_mhsu\\Rmb#W^e2KIß >c/(/q::Ro}G`LbP"" YtFdx;m桩F~~~mp"a . ;,~tjJFw+XC"5!xNZܴvOpA`yn`m%pApApApApA\pApApApApApApApA~.*2Cn r ob0,F=~!+F] ?.8C#JiRFWnU,{+c +"62&!"&i"c0ʈ\PSE×SO5>6Mi? z^G'3<O|J".bh`vD. 4Q7FኌHTpAqy&\e_*ŴīYRu -kILtx"5֘cz 4>DR抈Ap4;xꢺ[ u+l*viM3",ߍ 54A1!pXljG["8.)mpV6Lu~8[5lJw ,v::H,ayX؄Un`o0Y쌊o ] 6ШKhJu.xud  ]) x ..  N,EV}wBZ^DU%4sk[HXE!(S݂Ѽti3$Q ̄H(`"4fBD-L6㜯=4L5%6fB ..O.Dl@2/A$ʢ;l^/u`=> ?H˽qkǬwD"Xvj UO=?Ccބ "2X\Ѷۇ!D:]FBf$?"4Mď?Ha" _ˆһH'uݟ@ޤ"͗iUƟ.|zQ=V i46R-ڈZ/]0zpe߷G.0<W=p 4lnz !=V[ԀD}_]%fS-iVnMZ"u vAZ?Gmv;o$ہj;]p(JɪsEz oq釐\cM9>_kpT7'38}k{|G4#=(2=à rhnD Jusiy;s>G[C䅴,,]ɭ+e%ƆGs2p"Z WD e]p8q Vڿ6-GHX^h@aFGQ| f{+wtLWBclvvBa< RS,5u.6\YqA͹zJ1A.PbiI53| H$vlj3I /nSQ nS`u ub(kh`% P2n͸ G28:DW\ jH$#]z^_O}pT 6WBXM=zߕ?;nz_ˣG=]//-"Lk~n}-YkYWӸL.x%[q J^CV51O5_Eu7[Kkvizê{;ʷ6h<2א;{s-}/Zߘn \*YzNM!E͟\\ki[-3^O禗[lEom )__8с0NXLw:/7[C{sA>{km>RФ6'_j$?jq)6ME/~4Ѯ:vwL2?_& ]pR:˥;OU wtR$<*K|O"GsNΉtcTh8\|d>D%Ӟ/she&LvJ2Ʊy 'STj,ݲ)+e[;keuo[iHGeݳLYw?ӊ>{\E[AdrT*6ՓRpA~i\٭^U|[>uw@`;,͓)KWΣ/*0<̲kQ;6|]t77fZu('{}Mt-7\Eޭ2J0PPXZXbh삫DdKE o^/֭6.FlH3R:}grUoʍIRoZ'=Pb(-?2Oq6{dődbpBgodT=6j cug*DGxjZ.~63譖W utxF8.mm<`rmI+R-zن}ց  &\M= YUwA#rA<++􄦷kuXxiIKr zGO`]u]__.8X[ǃm.O@7ua˟+y Zwx?5wETedz;7l۴7hK]-;Xx7,nXw ]bF+$t а˾9k]mz.f+lNg_}QxrcrWm"QX{ihn+96삫,䌻4߬V>,᳎{\.ښ+r.B9 ?O bYѮH\a"Xm..iP%tb{2G)*˓m1c9asf \&]R"Yt61N^%G5 STLH DTuWl%2cK%ocW½#./傞_“_19;۷_ly yCU.;p;~U+n^d{a܎]m!wq~i캐dw̚&}WLЩ/_|Z+/.oke6`'͗CBf {,qߏjU%$-lP9>HT&3iV2:pnls,$Cr:td`jkĄ5QT ۝ìXD>9^+gɩP ssk*=Gs:dz,u~l6!"rlT OrTT,PZ#G#&vӹxSCȢ{ԧ*T)iE!bc̓a 6ݦ?U%v_..o{M+ ioNuz?Sx/ں_D${,k>qc\cMo'uG-6 /;~4b3~dz;{Wץ7tG:ÓΧ4T4 F|jk]?2{՞݊?UWwR rl&OUTP\5Fn&>/OQjWI79(fv񶵓 4v̐*_L2FySUgW1Z$y>^LGe%)+s,5<^{Jx8MGr4岷f+ǘ+To:m,a:CYHաF{Jc$E&Y])m3GkM뵤f?\p4_d wU4O]i%s+)\E\!6={si4+<5hᾋ{Ϝ~楆tZ]it׼qTcj/zj{|رeOIO g3M*i՚4ݳVW9KkIS)=LýUKE<ۭzsỮ*\\\ `@s`{7 \7 {:Qkfab ]: ԭA].Y,aa `WW,FdqDT.8.h#Z ~\oTh,r. Z+/X?'FT:9t[Q#Er-+p zAC5%4xQ+.FV L6͓G sEơ59N":Dj\FkuEuV.NTJtL&}eEjqD:#P<n] fD\' aCΉ1 VmKӑn+-* :h%6 әB l.d0~dqkb/@appApApApApApApA_ tAgT< ߤ $vPL䊡CpAm R@fSLx.A 838"$0 <"ȗZ]DTi bN~\~ HN[_Ad0@7otvj_IENDB`backintime-1.5.4/doc/maintain/_images/REUSE.toml000066400000000000000000000011671477034762000213770ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = "*" SPDX-License-Identifier = "GPL-2.0-or-later" SPDX-FileCopyrightText = "© 2024 Back In Time Team" backintime-1.5.4/doc/maintain/_images/autoremove_mockup.drawio000066400000000000000000000571641477034762000246020ustar00rootroot00000000000000 backintime-1.5.4/doc/maintain/_images/autoremove_mockup.png000066400000000000000000004056541477034762000241020ustar00rootroot00000000000000PNG  IHDRn&sRGBtEXtmxfile%3Cmxfile%20host%3D%22app.diagrams.net%22%20agent%3D%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F131.0.0.0%20Safari%2F537.36%20Edg%2F131.0.0.0%22%20version%3D%2225.0.3%22%20scale%3D%221%22%20border%3D%220%22%3E%0A%20%20%3Cdiagram%20name%3D%22Seite-1%22%20id%3D%22QbO9OI8nUnqEIkdLsoEd%22%3E%0A%20%20%20%20%3CmxGraphModel%20dx%3D%222200%22%20dy%3D%221164%22%20grid%3D%221%22%20gridSize%3D%2210%22%20guides%3D%221%22%20tooltips%3D%221%22%20connect%3D%221%22%20arrows%3D%221%22%20fold%3D%221%22%20page%3D%221%22%20pageScale%3D%221%22%20pageWidth%3D%22827%22%20pageHeight%3D%221169%22%20math%3D%220%22%20shadow%3D%220%22%3E%0A%20%20%20%20%20%20%3Croot%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%221%22%20parent%3D%220%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20value%3D%22%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D1%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.containers.marginRect2%3BrectMarginTop%3D32%3BstrokeColor%3D%23666666%3BgradientColor%3Dnone%3BwhiteSpace%3Dwrap%3BfontColor%3D%23808080%3Bmovable%3D1%3Bresizable%3D1%3Brotatable%3D1%3Bdeletable%3D1%3Beditable%3D1%3Blocked%3D0%3Bconnectable%3D1%3BfillColor%3Ddefault%3BfillStyle%3Dauto%3B%22%20parent%3D%221%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2210%22%20y%3D%2210%22%20width%3D%22890%22%20height%3D%221030%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-22%22%20value%3D%22...%22%20style%3D%22strokeColor%3Dinherit%3BfillColor%3Dinherit%3BgradientColor%3Dinherit%3BstrokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.containers.rrect%3BrSize%3D0%3BfontSize%3D17%3BfontColor%3D%23666666%3BgradientColor%3Dnone%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2260%22%20height%3D%2225%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%2210%22%20as%3D%22offset%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-23%22%20value%3D%22Auto-remove%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.containers.rrect%3BrSize%3D0%3BfontSize%3D17%3BfontColor%3D%23ffffff%3BstrokeColor%3D%23008cff%3BfillColor%3D%23008cff%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%22110%22%20height%3D%2225%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%2275%22%20as%3D%22offset%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-24%22%20value%3D%22...%22%20style%3D%22strokeColor%3Dinherit%3BfillColor%3Dinherit%3BgradientColor%3Dinherit%3BstrokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.containers.rrect%3BrSize%3D0%3BfontSize%3D17%3BfontColor%3D%23666666%3BgradientColor%3Dnone%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2260%22%20height%3D%2225%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22190%22%20as%3D%22offset%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-25%22%20value%3D%22%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.containers.topButton%3BrSize%3D5%3BstrokeColor%3D%23008cff%3BfillColor%3D%23008cff%3BgradientColor%3Dnone%3BresizeWidth%3D1%3Bmovable%3D0%3Bdeletable%3D1%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%22600%22%20height%3D%227%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20y%3D%2225%22%20as%3D%22offset%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-50%22%20value%3D%22%22%20style%3D%22shape%3Dmxgraph.mockup.containers.marginRect%3BrectMarginTop%3D10%3BstrokeColor%3D%23666666%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D5%3BrecursiveResize%3D0%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2220%22%20y%3D%22130.67%22%20width%3D%22450%22%20height%3D%2289.33%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-51%22%20value%3D%22Remove%20if%20%E2%80%A6%22%20style%3D%22shape%3Drect%3BstrokeColor%3Dnone%3BfillColor%3D%23008cff%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D20%3BfontColor%3D%23ffffff%3BfontSize%3D17%3Bspacing%3D2%3BspacingTop%3D-2%3Balign%3Dleft%3Bautosize%3D1%3BspacingLeft%3D4%3BresizeWidth%3D0%3BresizeHeight%3D0%3Bperimeter%3Dnone%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-50%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%225%22%20width%3D%22120%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-58%22%20value%3D%22%E2%80%A6%20backup%20is%20older%20than%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-50%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2213.5%22%20y%3D%2247.01910447761196%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-59%22%20value%3D%2215%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-50%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22248.5%22%20y%3D%2239.33253731343285%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-60%22%20value%3D%22Year(s)%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.comboBox%3BstrokeColor%3D%23999999%3BfillColor%3D%23ddeeff%3Balign%3Dleft%3BfillColor2%3D%23aaddff%3BmainText%3D%3BfontColor%3D%23666666%3BfontSize%3D17%3BspacingLeft%3D3%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-50%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22336.5%22%20y%3D%2239.33253731343285%22%20width%3D%22100%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%20value%3D%22%22%20style%3D%22shape%3Dmxgraph.mockup.containers.marginRect%3BrectMarginTop%3D10%3BstrokeColor%3D%23666666%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D5%3BrecursiveResize%3D0%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2220%22%20y%3D%22240%22%20width%3D%22520%22%20height%3D%22299.57%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22x8gMyu6OwGuHP-ef9QG5-13%22%20value%3D%22Keep%20%E2%80%A6%22%20style%3D%22shape%3Drect%3BstrokeColor%3Dnone%3BfillColor%3D%23008cff%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D20%3BfontColor%3D%23ffffff%3BfontSize%3D17%3Bspacing%3D2%3BspacingTop%3D-2%3Balign%3Dleft%3Bautosize%3D1%3BspacingLeft%3D4%3BresizeWidth%3D0%3BresizeHeight%3D0%3Bperimeter%3Dnone%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%225%22%20width%3D%2290%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-63%22%20value%3D%22%E2%80%A6%20named%20backups.%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2213.75%22%20y%3D%22259.57462686567163%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-1%22%20value%3D%22%22%20style%3D%22group%22%20vertex%3D%221%22%20connectable%3D%220%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2213.75%22%20y%3D%2236.86567164179104%22%20width%3D%22488%22%20height%3D%2230.74626865671641%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-33%22%20value%3D%22%E2%80%A6%20all%20backups%20for%20the%20preceding%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-1%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%223.843283582089555%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-34%22%20value%3D%2214%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-1%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22333%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-35%22%20value%3D%22day(s).%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3BfontColor%3D%23808080%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-1%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22408%22%20width%3D%2280%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-2%22%20value%3D%22%22%20style%3D%22group%22%20vertex%3D%221%22%20connectable%3D%220%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2216.25%22%20y%3D%2279.57388059701492%22%20width%3D%22471.25%22%20height%3D%2230.74626865671641%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-17%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23808080%26quot%3B%26gt%3Bday(s).%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-2%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22410%22%20width%3D%2261.25%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-16%22%20value%3D%2230%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-2%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22332%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-15%22%20value%3D%22%E2%80%A6%20one%20daily%20backup%20for%20the%20preceding%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-2%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%223.843283582089555%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-3%22%20value%3D%22%22%20style%3D%22group%22%20vertex%3D%221%22%20connectable%3D%220%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2216.25%22%20y%3D%22123.57462686567163%22%20width%3D%22490%22%20height%3D%2230.74626865671641%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-19%22%20value%3D%228%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-3%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22332%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-20%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23808080%26quot%3B%26gt%3Bweek(s).%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-3%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22410%22%20width%3D%2280%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-18%22%20value%3D%22%E2%80%A6%20one%20weekly%20backup%20for%20the%20preceding%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-3%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%223.843283582089555%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-4%22%20value%3D%22%22%20style%3D%22group%22%20vertex%3D%221%22%20connectable%3D%220%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2216.25%22%20y%3D%22169.57029850746267%22%20width%3D%22481.25%22%20height%3D%2230.74626865671644%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-23%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23808080%26quot%3B%26gt%3Bmonths.%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-4%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22412%22%20width%3D%2269.25%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-22%22%20value%3D%2224%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-4%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22333%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-21%22%20value%3D%22%E2%80%A6%20one%20monthly%20backup%20for%20the%20preceding%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-4%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20y%3D%223.843283582089555%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-5%22%20value%3D%22%22%20style%3D%22group%22%20vertex%3D%221%22%20connectable%3D%220%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-12%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2225%22%20y%3D%22219.57208955223882%22%20width%3D%22401.5%22%20height%3D%2230.74626865671644%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-61%22%20value%3D%22%26lt%3Bfont%20color%3D%26quot%3B%23666666%26quot%3B%26gt%3B%E2%80%A6%20one%20snapshot%20per%20year%20for%26lt%3B%2Ffont%26gt%3B%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3BfontColor%3D%23808080%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-5%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%22330%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-62%22%20value%3D%22%26lt%3Bdiv%26gt%3B%26lt%3Bfont%20color%3D%26quot%3B%23666666%26quot%3B%26gt%3B%26lt%3Bspan%20style%3D%26quot%3Bbackground-color%3A%20initial%3B%26quot%3B%26gt%3Ball%20years.%26lt%3B%2Fspan%26gt%3B%26lt%3B%2Ffont%26gt%3B%26lt%3B%2Fdiv%26gt%3B%22%20style%3D%22text%3BspacingTop%3D-5%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3Balign%3Dleft%3BfontSize%3D17%3BfontFamily%3DHelvetica%3BfillColor%3Dnone%3BstrokeColor%3Dnone%3BfontColor%3D%23808080%3Bcontainer%3D0%3B%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-5%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22321.5%22%20width%3D%2280%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Iv2SSTLpsfRosrK7ilRP-64%22%20value%3D%22Run%20in%20background%20on%20remote%20host.%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2233.75%22%20y%3D%22709.9955223880597%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-1%22%20value%3D%22%26lt%3Bp%26gt%3BThe%20rules%20are%20applied%20in%20descending%20order%2C%20as%20shown%20here.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22text%3Bhtml%3D1%3Balign%3Dleft%3BverticalAlign%3Dmiddle%3BwhiteSpace%3Dwrap%3Brounded%3D0%3BfontSize%3D17%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2220%22%20y%3D%2276.86567164179104%22%20width%3D%22450%22%20height%3D%2246.11940298507463%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-6%22%20value%3D%22%26lt%3Bp%26gt%3BComplete%20weeks%20are%20counted%2C%20starting%20with%20the%20previous%20week%20(date%20from-to).%26amp%3Bnbsp%3BThe%20most%20recent%20backup%20of%20a%20week%20will%20be%20kept%20if%20multiple%20backups%20are%20available.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22html%3D1%3Brounded%3D1%3BstrokeColor%3D%23DFE1E5%3BfontSize%3D14%3Balign%3Dcenter%3Bshadow%3D1%3BarcSize%3D1%3BwhiteSpace%3Dwrap%3BverticalAlign%3Dtop%3BspacingLeft%3D0%3BspacingRight%3D0%3BspacingTop%3D0%3Bspacing%3D0%3BlabelBackgroundColor%3D%23FEF0C4%3BtextShadow%3D1%3BlabelBorderColor%3Ddefault%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22570%22%20y%3D%22340.5122388059702%22%20width%3D%22350%22%20height%3D%2276.86567164179104%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-7%22%20value%3D%22%26lt%3Bp%26gt%3BComplete%20months%20are%20counted%2C%20starting%20with%20the%20previous%20month%20(monthname).%26amp%3Bnbsp%3BThe%20most%20recent%20backup%20of%20a%20month%20will%20be%20kept%20if%20multiple%20backups%20are%20available.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22html%3D1%3Brounded%3D1%3BstrokeColor%3D%23DFE1E5%3BfontSize%3D14%3Balign%3Dcenter%3Bshadow%3D1%3BarcSize%3D1%3BwhiteSpace%3Dwrap%3BverticalAlign%3Dtop%3BspacingLeft%3D0%3BspacingRight%3D0%3BspacingTop%3D0%3Bspacing%3D0%3BlabelBackgroundColor%3D%23FEF0C4%3BtextShadow%3D1%3BlabelBorderColor%3Ddefault%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22560%22%20y%3D%22440.0004477611941%22%20width%3D%22350%22%20height%3D%2276.86567164179104%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-8%22%20value%3D%22%26lt%3Bp%26gt%3BThe%20most%20recent%20backup%20of%20a%20year%20will%20be%20kept%20if%20multiple%20backups%20are%20available.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22html%3D1%3Brounded%3D1%3BstrokeColor%3D%23DFE1E5%3BfontSize%3D14%3Balign%3Dcenter%3Bshadow%3D1%3BarcSize%3D1%3BwhiteSpace%3Dwrap%3BverticalAlign%3Dtop%3BspacingLeft%3D0%3BspacingRight%3D0%3BspacingTop%3D0%3Bspacing%3D0%3BlabelBackgroundColor%3D%23FEF0C4%3BtextShadow%3D1%3BlabelBorderColor%3Ddefault%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22547%22%20y%3D%22549.9986567164179%22%20width%3D%22270%22%20height%3D%2276.86567164179104%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-6%22%20value%3D%22%22%20style%3D%22shape%3Dmxgraph.mockup.containers.marginRect%3BrectMarginTop%3D10%3BstrokeColor%3D%23666666%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D5%3BrecursiveResize%3D0%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2220%22%20y%3D%22550%22%20width%3D%22450%22%20height%3D%22139.69%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-7%22%20value%3D%22Remove%20if%20%E2%80%A6%22%20style%3D%22shape%3Drect%3BstrokeColor%3Dnone%3BfillColor%3D%23008cff%3BstrokeWidth%3D1%3Bdashed%3D0%3Brounded%3D1%3BarcSize%3D20%3BfontColor%3D%23ffffff%3BfontSize%3D17%3Bspacing%3D2%3BspacingTop%3D-2%3Balign%3Dleft%3Bautosize%3D1%3BspacingLeft%3D4%3BresizeWidth%3D0%3BresizeHeight%3D0%3Bperimeter%3Dnone%3Bhtml%3D1%3BwhiteSpace%3Dwrap%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%225%22%20width%3D%22120%22%20height%3D%2230%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-9%22%20value%3D%22%E2%80%A6%20free%20inodes%20are%20less%20than%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2217.5%22%20y%3D%2296.94373134328364%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-10%22%20value%3D%222%25%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22252.5%22%20y%3D%2289.2571641791045%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-11%22%20value%3D%22%E2%80%A6%20free%20space%20is%20less%20than%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.rrect%3BrSize%3D0%3BfillColor%3D%23eeeeee%3BstrokeColor%3D%23999999%3BgradientColor%3D%23cccccc%3Balign%3Dleft%3BspacingLeft%3D4%3BfontSize%3D17%3BfontColor%3D%23666666%3BlabelPosition%3Dright%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%2217.5%22%20y%3D%2246.94477611940303%22%20width%3D%2215%22%20height%3D%2223.059701492537314%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-12%22%20value%3D%22512%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.spinner%3BstrokeColor%3D%23999999%3BspinLayout%3Dright%3BspinStyle%3Dnormal%3BadjStyle%3Dtriangle%3BfillColor%3D%23aaddff%3BfontSize%3D17%3BfontColor%3D%23666666%3BmainText%3D%3Bhtml%3D1%3Boverflow%3Dfill%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22252.5%22%20y%3D%2239.25820895522392%22%20width%3D%2270%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22YEbgF9xkUqgCyze2J2hk-13%22%20value%3D%22MiB%22%20style%3D%22strokeWidth%3D1%3Bshadow%3D0%3Bdashed%3D0%3Balign%3Dcenter%3Bhtml%3D1%3Bshape%3Dmxgraph.mockup.forms.comboBox%3BstrokeColor%3D%23999999%3BfillColor%3D%23ddeeff%3Balign%3Dleft%3BfillColor2%3D%23aaddff%3BmainText%3D%3BfontColor%3D%23666666%3BfontSize%3D17%3BspacingLeft%3D3%3B%22%20vertex%3D%221%22%20parent%3D%22YEbgF9xkUqgCyze2J2hk-6%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22340.5%22%20y%3D%2239.25820895522392%22%20width%3D%22100%22%20height%3D%2230.746268656716417%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-13%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BdashPattern%3D1%203%3BstrokeWidth%3D2%3Brounded%3D0%3BexitX%3D0.744%3BexitY%3D0.716%3BexitDx%3D0%3BexitDy%3D0%3BexitPerimeter%3D0%3BentryX%3D0%3BentryY%3D0.25%3BentryDx%3D0%3BentryDy%3D0%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20target%3D%22Kyt2Ybz1KD1fWm82J71v-6%22%20edge%3D%221%22%20source%3D%22Iv2SSTLpsfRosrK7ilRP-19%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22464.8320895522388%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22560%22%20y%3D%22404.8768656716418%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-4%22%20value%3D%22%26lt%3Bp%26gt%3BThe%20days%20are%20counted%20starting%20from%20yesterday.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22html%3D1%3Brounded%3D1%3BstrokeColor%3D%23DFE1E5%3BfontSize%3D14%3Balign%3Dcenter%3Bshadow%3D1%3BarcSize%3D1%3BwhiteSpace%3Dwrap%3BverticalAlign%3Dtop%3BspacingLeft%3D0%3BspacingRight%3D0%3BspacingTop%3D0%3Bspacing%3D0%3BlabelBackgroundColor%3D%23FEF0C4%3BtextShadow%3D1%3BlabelBorderColor%3Ddefault%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22540%22%20y%3D%22180%22%20width%3D%22170%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-11%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BdashPattern%3D1%203%3BstrokeWidth%3D2%3Brounded%3D0%3BexitX%3D0.119%3BexitY%3D0.144%3BexitDx%3D0%3BexitDy%3D0%3BexitPerimeter%3D0%3BentryX%3D0%3BentryY%3D0.75%3BentryDx%3D0%3BentryDy%3D0%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20source%3D%22Iv2SSTLpsfRosrK7ilRP-35%22%20edge%3D%221%22%20target%3D%22Kyt2Ybz1KD1fWm82J71v-4%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22460%22%20y%3D%22220.01492537313433%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22552%22%20y%3D%22261.5223880597015%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-5%22%20value%3D%22%26lt%3Bp%26gt%3BThe%20days%20are%20counted%20starting%20from%20yesterday.%26lt%3B%2Fp%26gt%3B%22%20style%3D%22html%3D1%3Brounded%3D1%3BstrokeColor%3D%23DFE1E5%3BfontSize%3D14%3Balign%3Dcenter%3Bshadow%3D1%3BarcSize%3D1%3BwhiteSpace%3Dwrap%3BverticalAlign%3Dtop%3BspacingLeft%3D0%3BspacingRight%3D0%3BspacingTop%3D0%3Bspacing%3D0%3BlabelBackgroundColor%3D%23FEF0C4%3BtextShadow%3D1%3BlabelBorderColor%3Ddefault%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20vertex%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20x%3D%22610%22%20y%3D%22259.57%22%20width%3D%22170%22%20height%3D%2260%22%20as%3D%22geometry%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-12%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BdashPattern%3D1%203%3BstrokeWidth%3D2%3Brounded%3D0%3BexitX%3D0.906%3BexitY%3D0.494%3BexitDx%3D0%3BexitDy%3D0%3BexitPerimeter%3D0%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20target%3D%22Kyt2Ybz1KD1fWm82J71v-5%22%20edge%3D%221%22%20source%3D%22Iv2SSTLpsfRosrK7ilRP-16%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22500%22%20y%3D%22598.0149253731344%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22601%22%20y%3D%22538.0597014925373%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-9%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BdashPattern%3D1%203%3BstrokeWidth%3D2%3Brounded%3D0%3BexitX%3D0%3BexitY%3D1%3BexitDx%3D0%3BexitDy%3D0%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20source%3D%22Iv2SSTLpsfRosrK7ilRP-23%22%20target%3D%22Kyt2Ybz1KD1fWm82J71v-7%22%20edge%3D%221%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22430%22%20y%3D%22512.1044776119403%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22480%22%20y%3D%22435.23880597014926%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%20%20%3CmxCell%20id%3D%22Kyt2Ybz1KD1fWm82J71v-10%22%20value%3D%22%22%20style%3D%22endArrow%3Dnone%3Bdashed%3D1%3Bhtml%3D1%3BdashPattern%3D1%203%3BstrokeWidth%3D2%3Brounded%3D0%3BexitX%3D1%3BexitY%3D0.5%3BexitDx%3D0%3BexitDy%3D0%3BentryX%3D0%3BentryY%3D0.5%3BentryDx%3D0%3BentryDy%3D0%3B%22%20parent%3D%22x8gMyu6OwGuHP-ef9QG5-16%22%20edge%3D%221%22%20target%3D%22Kyt2Ybz1KD1fWm82J71v-8%22%20source%3D%22Iv2SSTLpsfRosrK7ilRP-62%22%3E%0A%20%20%20%20%20%20%20%20%20%20%3CmxGeometry%20width%3D%2250%22%20height%3D%2250%22%20relative%3D%221%22%20as%3D%22geometry%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22400%22%20y%3D%22624.3283582089553%22%20as%3D%22sourcePoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CmxPoint%20x%3D%22492%22%20y%3D%22665.8358208955224%22%20as%3D%22targetPoint%22%20%2F%3E%0A%20%20%20%20%20%20%20%20%20%20%3C%2FmxGeometry%3E%0A%20%20%20%20%20%20%20%20%3C%2FmxCell%3E%0A%20%20%20%20%20%20%3C%2Froot%3E%0A%20%20%20%20%3C%2FmxGraphModel%3E%0A%20%20%3C%2Fdiagram%3E%0A%3C%2Fmxfile%3E%0A IDATx^ ՙ.. "nT8b܂&K\2A_t;8!1&èq'4#qAD%Å빜{nUWUwuwU>p{o}}9m۶M @ @%&AZbt@ @) @BAZt @ @y UGo̘17UbCa>Wk @@$H]q6U 46V>S,  @X҈EFb҆_du @ PA *#ҌLŪ @MAѽ҈2R A TL@ P݋ *#ҌLŪ @MAѽ{5B!@ ' ȰAY"wȐDޘ+r3;FAaP @+HU7Pdڨk.rK"gm܈+&Z]նV6lr~G"֖|K_wPg^Ծ>aVC^NeV.SDmA\cG"H# @("iD RW\0Ab/e׈+fe-sAmvlޯcmj~r{o(WmC"2 jLji0V @# 2_AFD݈iݲ~/jin$n86{.*Ele3cxoAmԈ]k$\n]W|cb"DH# @("iD FԄ|"69k@&KAٵk)Q_د "Ho}A 4"|^[ *vxm*LJw fk *$]Ri[b @E$ 7 %RjŌHe?{j[Pi˶o%˵Ri[b @E$ 7 Zis7XBAkH{ڻ J ~]א擲g,Il?5h-j뮛҈> @HAn\A1ݕ+6]fħ8kBwuא~mm:DH\.6;;u3' EF)@ PD+VQFI޽.|Wr= '  ^eƌ2bi߾}PAQ@8WAg=5M]EVn~]&Pؕ\@"Z'l|Sv=PJm~V!|.C @ ZA6i{ BJ @} *#ҌLŪ @MAѽ҈2R A TL@ P݋ *#ҌLŪ @MAѽ҈2R A TL@ P݋ *#ҌLŪ @MAѽ҈2R A TL@ li8c2 2/"AE6 % @ ENCD`2 ON9D @H<]1&@h H52z# @QQDJ 4$T`A $ED9%h@h HwWd # @&kJ_Yn+@44N3 @@V |{W;GV4bt\ iߤ0 @D`0@ C\j~O0'Hm&;Z&ku^L @&fR9m$AO{O9^'HUO~3fL9mo@ @Hc뮻qҤI vzt֭2tPi, @ n*H_HfͼMzTj9Sw=Aj*H iA @E@ 7 ͛7-Z; S#H%J Қ+\Ka@ @&ꫯ-[JVUکA=Ae6lO@ @E"T[~TjTSwZ"u:A!E @ @xT*F۴i^GZOjtDH7h @@ OmDH˹S!@  RA@ @* H  @@ H, @ PUv @ @@ @JҪt; @ P~ @ T%iUAC @(?i} @*Π!@ >@ @UIAZng @OAZ~` @ $ J3h@ @' - @@U@V4 @ @X@ @* H  @@ H, @ PUv @ @@ @JҪt; @ P~ @ T%iUAC @(?i} @*Π!@ >@ @UIAZng @OAZ~` @ $ J3h@ @' - @@U@V4 @ @X@ @* H  @@ H, @ PUv @ @@ @JҪt; @ P~ @ T%iUAC @(?i} @*Π!@ >@ @UIAZng @OAZ~` @ $ J3h@ @' - @@U@V4 @ @X@ @* H  @@ H, @ PUv @ @^>rI'$ZnڴirWO?-OgY;ֳcǎ-<[j%?Oe]vn,]T;<0`@`[of뽱uwK˖- O*lC g2W6 {9(X\h @ RX.a&iܩ|x[dT MvFrϕR8͟A!@LAxAZ=Yd JOy M] @!HG)r|G^nA WD4xޏ:GSD/q_u~J>n=;M9f̘2avjA6ˮ4w\6AT/}osJ~s9E}?()Qa3s宻klѹ)㦭{,4յ^+VlυD+n;=ӌ3ol5iv:z[7eD}':W|P=uwAW=k:kfҤI^a {ab\Cwk׌[Dl\4m={n|}asi?|b>Gjymqװa>}@@ HEH~0Zo֩:%a?jAiaa}E抟1b7;}`سn:߹Sl:?\!$NLw!l<̻({0u%7o>tkހ̶J)t^Fs~.(a QVdQ)e @ Hc Rw]WH>RiMa} +Bk$n&rbeix&c+_:]Tqec6q=Pk/'s (A~'Hp0Qk\ Z3银Rek `}$ȣK?1~1? rqbMtѾ磤i2(3jGa4lzoB?;Ҡa&j4l,F"Ş+A"݌ɝ74mFQ]mAu5Z$Ѓ(_ ȧ;w}P?[ LA'"N/Rh} R]CEz/~!7p'B4k_Q1_Q~ǹ}{A) | H H94iAy恴[ngu'O z`K56ilň8jMB_ \y}3\Av&h|B"Fw! U? Di(mĵIFH9/V{~NDs |}XD@Hi‚4(,,WȄ0hMm5?֐4(wnvBߦ:n[QEua\Y}aet 4cBbb׮] .ۄTl:VwGҰ v҄>b1H]E 9@[p~ж@Ѿݍ {w Aj;GN/אv*`ίjYKZjeFC"-v ێ+T8_6DQ擲w9VQ2(O{/#O{G`;5S~_XEWGal^32ȏQ\;yn2 FAZAM%H5[4=CQs[@Z0Mˬ3(M\6ڶM^1] f&㎞-zkbM;f3=s!5Lõۜ+ E9sS|,8F+.B!u75r7 c u_s/}̉̀e}PgĉvG[˚![ s#Jʮ1}TPXGW݇uwv=s_7a!@" -yM@PzQXzpF`EPKX7Q11Y"& @Q1ʲ /u65e@@:|PF)9Lw P=Y)jHdfx5髚@DA&o`  @ *" "g3T@ @i" M7 @@@V* @ 4@@ @ H  @@ H l @ PEUl @ @ Mi@ @"*r6C @ &4y[ @ Ti9B @Hi- @P!@ 4M@ @UDAZEf @DA&o`  @ *" "g3T@ @i" M7 @@@V* @ 4@@ @ H  @@ H l @ PE^^dG"YfD K+!D:A1 @ TC&㿊TaޮAdwD~ا ϐ!@ rRA/9{ bx AcW @ PDR|i,(2墲tM @@__̕J%?|gJ @@ H-}='bq4he)@ btz([M @@C҈ӋD<&9byEvCojFd"7.tk @ !H{bة'Ϋg )'"RJ͟OZ H  @@-iD ^8F5O/5O.5È!#ТE ҥtܹ΀!@ [~6qT!5tG4VmMemȈD9Gm^S XKi(8Q䒾͵˘ܨSM״T\?v/۞~nӚ]ruOJF`Æ 2|iԨzrqIJ?A@~CW^I&w[jvhŝ cvپҔ͚K[d1iڟ~[v+M]iZ{޿__.5Ycr@;w2a93O1@RyGeɒ%2r߄$犐 h_y7W!A|5Uނ)OW|B/Z$  P5,X Ooq8%jԁ*… w?1&@W\q=Z4iIfȧ@AԀ PKF.wH @e%PTW5e'BAF* À @ZBfha*4hT*b] dA [BQ4J( MRi6gnV#HF@b H+ֵ @ H-w3:3ED@wHE)@ H+ @& H-7=1MɄ02W>yT  $ @2$@$ bHߋlٚAObrNM,*Ҿ9 @@ H R -r[ip 6$I`Q"7d@ CRO^Tǥ}E? `@2 @ ^{OMؐou["?: ԁ P_F@ +!ZVd; N-E @27 @ i6@JLAZbt@L @@@V2 @)@(6i > D! B2 # 02@% ͨ0 Pi! @I@&Ev @" ͐0@@Vs @ @i M Pb;@% eb@UC`˖-_ʬYdҥvZٶm[jolkԨQZuұcGٳ^Ҵiz:u|dٺuke~2FKfͤG]ey7 !@ Aa ^|ңGիtp7Nѓ'Ol;CCmT1{ѢE2sL={O<кxW[nҤI|zDvP~RKȌOߗ-ɹ0/~ҼQ & M(A"Q &xѻ?܋ f#H1iFђN4czfgT-[/kCkQֿ ?qR9묳bA @EJ@z ҩS'9#JbiÇ-Zb 5j,[:t#FHW 5;^:Aʕ+U !M&!wNR\8( @" -YڅN7l8cJb3Fc{G./6ʕ ~栂[E.^T-Y/۾Ҽg@DUbkҦIQB@@ HM!;w'\u'HU>3P?HQe١};qy|]v)߽69䐂۪_ HtlY9_N;X8pQDAZ$4 }ݷ膨O媫W_}U/_ Bʛ˸(tg׮Wp.},Aͮfwݺ`MS'˶UFQ2i>88([U]a HcxO64J?~t-["Hc(%g[d;v Ҡqv '!8OdɆgZvh.20`۪U& uEvsSueEn>:ڸk7t cM$ޟ4s#Կ5[8"%%:RiI]@g @ƀaz|>kt>!ȓޫY- 5w޾) 4lZR&":l^;Wʮŝ-AӨ})FRھAwKV[w}]*kE֐:whz7כ7m:scђ岵8B44R4;(*Bݟ"tG(*i f͚i֭c@EHJxTE6MDNMKR矯K ަ_ L#pͺ[-ɚsUMۺI,mgȐ!޺]MkO$%UBi"][śY<{unAAOi[jjdɒsBHݎ7nk dz4g}i>}oMMn5BڦM |=A8TWn|Xjcy0`oiEbFTmGvzՉW$%}vcJ4moᖭ"wٳ]&H\=fƌM{gb~Տi5Ts߯|';w9";nmv,eO,W4Rw}- sB>J`ҢySiڴ4kQa?=4T}i>tڴi\4 <џ|̹ے^L7:r5EҚ"[6>).aT{v#v2Hb3׎fE_8Hؗ~sn!m3:F]Sޜi49J5tDH &J&0gٶu4oۣdvĩFJB$i zjg}|71r#i}?m!;Eiv^4W@UϤǑT{QÌMu'[72b1m˘0e`} 9kD~ˮmju}Zdޚc|>Y!vcMdٲ )kI K s9e51^$̈R;u7niE# VV\Y'H^;cYG]J:-}rßN4ݸeԨQ⦺2LS k4vnԵbC~p{PupugM)C;. noxۂC4eW}̚;?~th"I\ph>͝PɊ&%Jfp@G:=¦SNdȗB7{*H62r;8Hl y ~=3Gut74 S=7LBEPFaoի&.d~QRM5kI24Ї0}H{c!/]v?0^ʜ5~ݔC7RR/sCHALΠ:tc9rލv[5K8e+I.]Tz3gJǎ JBݹ'B1( Z>6l*үHc=źn`-ܾl kH/bTa~I4E]@Gb}޲0 ti j*s=i/, u8tYuZAanԩ=cǎfwK[R(l|6BǠ4bRH0m(QïOIV UpF4 *HguQtϘce>W|\owR{Twk%w-}BL^*Hw@F[N-[x҂PRDTk^~񂺖JI4J}SK;}t,@:(w*͛癦Kuzk>mAk6Z12k[mtmVE9װ_~u>p65 .Fف r%[&3HԺfH?,ߴRf\sUhj~, SFS֐F١WȵR/"!5eߝG|<L$T]R R[d[mah"|paQ v+F`eSB#vb\#Q-oVmq+hR«膆tk,Y/\:9{ƓU_ɵS/ƣ|Z%޵}#B~1=m m5a zM6y)|IRT7΋ 5mWRz AQ64TiK/ ͵l"N+(~Ӎ Dwme0?S/7!ETqփ泆4Hhף>@G=sP갻R#YLa#9! "zhV{6鷻tٽ5).I6$'ҙOU5FXe҂ Қ) T.!O=l٥Ko7vMBn AW@@;B.-c[:f=#,a봴 w͗n}I3.^TQwS#wfZ1i>k]%j_D&Bj6v(kHNSvLѤB?WXDE"Q3=֝mE%*ʒ 5 hzkq?VZg[~/&KuDHFjTw,%B/Iꕒ '|{4DH}%AAzCX>WA)ARelc RwTuZ&69j)b/iډ!UQ8_Ҩk)i}eCBTEҨzEIu x)"n5 kܹ:O?=&F+L 3Kd7G8'w/e]"T(KƬ^&AA[ۋ#HFG2PAOxϖ?2: " O61yE\C44؍ "=}^#W qM[Q>DtVkڵO_^ȅ rHGHW~9Y HҼQeO׉@@/v-Fڢ*H+intS &ME5"+ ձ׵hR{H(B;XB4r HnBA>.ZHzVmYfy9RiCRM׵~.h+EֳE3<#֐ziJ>gY"meDKHeŔפergIՏU #H+ЩU0$i8 l#H{Vmٳg#HcS #̙3s& MS-̒jGZׇ^t!N/P} 5aZWKҫS9cbAZ AkP8%)qf$BA>l,\PvujΙ3GvJ469*@0owq R]7{)uQjncǎ"rY>'jHy[qhݫ[׭o>-sI A 3_(.tk # O6,X ֭4oB )Q`=äO>I5[v ӦM_ojYwl(i7J҉Adn[[7ٹC9cw Eƞ4TH ij\! @ƀzcoUV; H޻~w&c*Ҝ{gPvQxMӔ8>)֥kI?\S__i=_ѶmyBGҭKg4hP^!HyM*4n HcTA{lj/=A k.]*֭֏ڸqgZCMTaݪU+t]i=[n-ECr:iܤIQmlhغ&X 9o{*Ͽ6ڋvO_fءvyu,W&''+f^D4(mԍh-f^XoѻW`!k(VP:ݿ}k~ &BfGmavs/w9!- DA&o`  @DC/=ËT{J)u?'tW~; T/ʩ4߰M`cUt4k~ avk_ljT9 if\  H/H0 N \{]-LpǾ ^I`AHmfR_sEHâ$Hsg'4l~5@V; T-izIٵ75QRv,]Y&D#G9}K68r˔K)Kٵbn4N} .W3W]u5JZhQg P6l #F{ G_۶mٴinZ(8ǾT'WP߳75RAjodvµw5훍LZnMܲfd9 IDATڠ]S<͛r ^?۠MML4l*ᷩQݚl\̦FR4VVqr9H޽+Э  L`ƌSO__*HX3ǡ~*mdzogzݱ/{*DU]w}9wնݣTr#;vE7G2WmRmsoV#}v#iG.ZVpMֵcxem88pY[8#PtܸqҦM9S "/ʚ5kdU5n[f F2fj]v=ުӧOcȑ#+Ì [dȐ!{V=i袽nO@A@ Rtʾ+ 0a|grWfuڍ ݞ(x+ |TNs̑o؁)@еM7$kgAiR@%jA|w(X @&bt̘1rgGo H Y$ ͢װ9@ R#Jz!oswY @hnw#F"H+mWxj%OkgYx_#ݻwj' "Λ7OM&tYciM* ]CE:Nw?.\(G  %-Z]z׏ts8؂TϾ|>Rϳvr~$Sh$}vy׿=3˗/虤WmI i\bO3im @i1a*i[m#H%G=t  HBڑE/HTsO4 9ouniXk;j;_Z^ǰhrԱ9^;\hFLϹf5:`OyۤgƠ| BeNAva @E#P NFHQG;w^*'`:ul {?Wʮ RB?88;}'Ǟ ډUFdPm[tmQL~4kDhTW~V-bwi7Ln[i:;lhk^ ;L/w^]ӞX'F#@AZt @@:tc֑sM.iFѳ0Ae4B_}r]4Dx"Hm[֯BW߭'\jX6\h&õLijiDb[ch!9?{u0(BBi# MG pn?q.;5M% )&3IA:3Eu~l>եNaDA%oa+ @?~޲Ko ˕k΂KmjR]#ĦF-agMUmdۛAZjmmjd6fmnB侯k HI߶SN҂?h e)s@ P<^z<2l0=ztT-uň+:U`tn0F'vu1"MSB20:l?5ڮ{d{K4(kRrȫ9]Gj̈́r+(=NuǾunpy3뉐ơEٴ@C@@bWo 7 CwYjjjdӦMҺukٺbRb}!w٧  nk R ] ʧ46@'0e9v MMܸK%9PB&Ռn^ "u)t0&LAZ0B @ ~m9#sVT+55m2j}FhkYSj6mï<$(FZ H  @ <}ݲ뮻ʸqV&FRIAJ`Ty @$0m40`Snv4hP!Mw* $(FZ H  @ 1z\s5Ҷm["Q@ؑii X`t-ノ捎e$ -#|N4q4@@ l޼[':qDyA7:*:qđ  @&l2߿L>]xKA6*D HIc {Сs9yw H]tKhB4i"7.ut x9x}D9"ǃJ:9fW@H#H5UVuŤEp }ꩧ/dTvA,,>Q俾Ȭ_Sg?-2x[4  Xn1B~_I˖-A8R,znǎSN mӦ  H*F'2mY򰫽>D&FV<`ugy\nᆨU#CFFEPAsyR#J[n-͛7'e7E~”h'2mWJ#Ϝ_]jA@x套^+B< HGJ% _{tv#Hu(kHKHBkF|$14@ YS tPAuV5t+rPAGkQawv"5!2CAj\1!3ˬ zpfp@(7|Sw.{ZnAZRtzκ*H_M6E&ĘfJGAjȭo~tQ"$uU87 [eȑ2l0=ztIc-[ a?I@ Qhw֏6kK%B'X4 "mk#cիg )zel;E9@ t詧mZ4tP/RZ AZ*$'OĨR]?_hA$i*iԈѩKE.~@H)SH "L\ > Ҭx; i1ߍ ͏ T3gJ^R3)7n=tڵϦMu#. NF*HUV*뒲oaG<fLCC{PަQfiTvE^%r7LAmEqxy9d i0 @DV^-|';ZMiڵү_?_#H5B_k̿e1NFBUFF*FvU?]2A̙#?0Uqj֎͒'U T 4o]F!{\AjF8*D(w;0&7h~_|mqC M@45wر^QV.FhYWѬxג"͌kThZ{イzkZ 9fwΠUP!ۍ@lztK߾}A Tج\;uT+DEfŋaju`FjӽopGYӸT+KDꎹRnZQsk^g ir@eu-Ȑ!Cd=Ț[HѭbWЫV&mڴ_>lVKIvu7+n|;Ta8^")YBN@wsʢWKE_|Q֬Y#N=Y1rVzn%K:/t ([(m۴=iӦ޿*LQ蕯 4傴|Sx=#Hǖ!$I`ҥ;Jf͒l6m!H [x]R; YFg;ԈRAZ -9r: w-wu 6LZAs՟M7˲e+fuRWݳ̗-yҪU+_DI= ҒPiɑ! t~Wxlj 醍eU )U1jZdUmݺlKnz} |E^gUe zpq@\=;@!H ҭ[z)\ >@ڴi054J Mo>Y"r#uVX"};Uh 3gH#@nbTwյx[WLJ.M@?Z~mOkNڶm['HYGZ\ u}QR"{R(>HiU#G&ɔ $A/։{I46͛aU1=ܹwVFI5ʯbAi ]S,Xչ1f4 F@ e!ݴi1 # T7΋ 5}WzA^` @ OxǷp&@t{T74)&+TUҥtK5G!M' VA!0e۷/,'tR"Vj#T#) J5.O>5DH,Ri: M_  oۜ'?n[ !H8eL*H5D#?{A~a! @ ͓ݻFTF"HeW8*4~j@@cǎ!C@RiӇe& -A'8A@2֭['yJ\yyWk̙2rHyG .WT_RiEM* 4GfoX @ tiӦ zgy ]{?zl@kÆ ^]vEk/y督T+̯~+? :)Z~%AM/"H7 I~ҫW/c=[nҬYTE_~2hРvXBf͚%w@y_^G;ʟAf HGǍZ 믿.W:ے?+W>G} ځJϞ= FJ/xejA -ԣ HX&1Cmr%0RHԅ P'Nr;t /ԩSe9SmU(>rUWk[ThSORy?u]'[JAR@t HcԇM5Ӄum&vZ>U@ 4BrJIƠ"s̘1^Jp.AiF\-Hu3f̐w}W:,iڴi^,.kOzKyJA쌢R@vr}!Hc{O9j.^XKilrTL`ڵOz"k(n3ydY 5euS$WER]=ozbTהƽTh?ߓ{'&KQQa;^aڣ/BocJJ8i6 7#H> ӧ#Hc e*7m-S7MRqꫯ#*y9OD8KdV;쾣h׬Y#O?'FIfU3m8Η_~8|<;?)W 7D9'7ˡ#W3>{/grrWdyrue֟Gr׿-Ն] AZ0²4 |,Y"*HO?=R@ u;w.@T үʋ0:XCJE6o١i4n?W^y[GĹ)Hs='gqYz[/j( - tJvr~TOx[0rr -'A×Fy1jUA(HuM#1b6zhi.]}Yĩ`?8#"ǖ\e͚5-&OAOGfۀbEOYcp:ol\qfM7nq+$HP3.hVٺvMNdG'ȪUD\F,uͩ^/~a|P45\d"چϮ'4)S%\}kSvtTfi4Eg+-J IEMMкukٺbRq ==ף߫As#opD@nrx_;\h s.{M/n=6Z> 9o{j&7^{ןIc,;lWQhrye{2~»bƣzvEmZ__Z\a71wK/z O.Vlebg(ݶ&B핹1\%ppGĨU[T i\#Hsssi4ʔJE䭷ޒI7^ uPKBN^,wjO>{͞=6yR;!iC# =|rEuWZ6mx5J;ZOYumNJiic)HU %V޳h;AMԵ͎sz_& Bo֐J<1AzaŨU[T_]ҡC/=פ曲coF iѶ\~YAl2miӤ%&،ɴٻwo/մ-o:C&h>`-cN5ܱ94ib*%au}67͜ _4ݮ~/m{)gxwV_ʮ^:? T7^ڧWrb8Tp0U̡ R?^5,ޠ *ـ6KP1skvZ'@\!ן l/ZLmi-rFHK"l&-՞ vyO|&7դj;F;xoGCՋr-&7l&7=Fr8MZ{6m')Afx;̦FtKoчwyG~U]9/A"?~)j (#PTqk֬eAl>

{f[/b*it7q7q-x={S#If'\{XӾɤt-kv JU;cOۼ)c஻ 4DsͦR~٭iljTOt #H>jCܹsK.Hm!hDF|ԩS87"fd~ik R1ӴNsE7uamM'K9Y/N\R;|Q[;jkv3Hک~|駾QT;ʞk F577 X!Lxee:]L B<4Z;=ī[{ n… E7Si.ߙI*G,Hկ Ο?_Xr]wV"ߺJ{,ٿ^w Qbt_o{9J%:RcWts$#^~k+6=6A`5m>F|}deu;Ȉn];։\vvj/.KQЇ~[Z)A;&!UsS)UAMQՇM65 ثB.i>g!u 7Q:AQB":/ B4gcPJQG%@/" ՎsHwۣ_ؑLw^ G^7}͜9ATޔN˹bֈ`ל}$\WF*U޽~xʕҸK-vn \X*2&0 %N]vGZ10AzƨU[TE) ͵Pj̦6DHjt/nkvjblē!_=#R>mq4e֐ڛ7i٠5Qc>) E!u%f#lo~_|4lgf֐kP 9{y!tomGGh{N8 oJ,Hu7_z饾=0z)>`hAZP0+y lzAoF7Fڢ*Z}{[Dik!oFPi.:vwaЮ&k5mqoT(k e7 uE^4"?A6mEn`w j>%ؗ] w蠵ާ\\+iBM{ zؗzЈ% EE^&:V> gYޮ9SYR0Fi6= 7}(y뭷Qk յ;A4hݡ_*E0w=H4.FsHu+^v)c5nQcOiaNj#>„K,f_\+wޘ9ǹ)9:|;MvMrMsa)aPE*]n* pF"=Z֥K^{nk[f֙իӠ){W/ͷw~NַD^C>piA\&2/[i FCzK,ZҸ6Vr#p*y̅-lBr]#u=sRYf{)W-k_\d/͛[Þ+K!L\7͂K.?FbD/H`,4`#Hun xbi\p G o8l=q<ʕ_Z)hF| ȗf\ܱ6e׽t?PfK^nAf͚y05vX' T AZL],b-n|mAjԨ=z5B;+r iU|Qi<#HoBe=vP<ʕ_Z?^y*Fۘ1sl6lvsQG$ >w-8 kmǶUmqK-Yq1:6k+M^!Ո9콦A)O=tѵ=ӷ#DHJOYi _AnƽA!J /J=$30T\,FkjjOqҳg4 |*H:3rLQ^ D(d$!$⥡010c0&/QR5PTHڄױ4sLcǎq@N R"6i/_e@ :Ggs>N^CCG3 \nmbbȒfS]<|\P?WW}RmŹߘxV1ۿ˳B9~xEZdqa13f80OT< OF2{s|IœGB~i UR U ӺS@4=uizUU@PT"VO>7|CժU+SĈqԦMD@@ i$sibB @T`ʕj*ڼysPR%Q5h Qֿ\ |GҴiޣN:)UUiZH/Ϋҗ_~իg 6422H m* EMh̙4o<}!InzH.[5jDt> g5ۯtڵLy_H"@uVcޱfRA6|* 1bխ[)~H?H?FBU@PJ&OL[6?{gA7ޠmRӦM#w(СUZ5I=#=#Y 4}V U ӺS@˼Oͳw=P izfjҬʫ* |&*B:)>#驧Z{iw]ff͚E?K'ˡ@@Z,s<@:fRgV)^ᙏ)BH+T(=/ (_7ŋ騣R ^ +@wRZ}7q^Nы/ظຮs50@rLBܹsVt[~K^{-a=?]z뭼8OT4J̍RdƶR*+W6R܌CZH*HX.g'N>Z4z* HpC9$k0{Ŷ2l"N 8д_~DJ9⋥U64 nID-jUd<cDh3.䒂U U zBb"Gm P$M4fO*2#EBȶmgɘ~UV &Ҍ   W`ڵ&碋.yK%߹A^Hg"ZhNӛU-xht '$ ݛ&MD =|>vXZpa$Dy8i ߲ zu--~Hb PP 4`Sܪ;Ҙ2"{W?V * ٳ |u1}`k(ftו@j/[Hs'Z$:#o=z4m8H9:u*}&4`Ӿ={~2{] rp.Hs0ٴ+ LjL`ixG@Ҙ %•}`M!0vAe\yKLܲ^ u,qAϯ>k.Un.5CRΓnhJ!(NR׎ &݁b!^@cyNZJdî.H+V :)Q=Mp=3Bb āmڴztILׯ7w$33W^@Nj}yK'\zm[}R(3\ @* H%HBtqTiI ju-Hk>ɼ s?pkr@7}t)ˉ(Ehn{7p /\$~mOЅ^h`q5 IDAT&G+\mjuxd%z=B_P͛7ӆ ̋lٲaUzIQ.9DF](~UFH2Zۡ@s\@qo)'Y:2q~P4(;Ylv/aK iׯpyKٶU+Q36at+:ПRɅ~Ç=zϥ[c[;7$*OT+Up]}wii Rw+75g2/,Rd_{dҘ mѢE, R,~CygM|pBvJ*KVۍj:ז \?ʲˋͮ]jU}G{+;vX\vD.31ȌZ,Ybnϼ~]'8hи/<;5F$ؼ+)31XSC;vEƋ#Gycn7|Nr^D|X]v9qgWTr͓O>hO0Q2H)/¸{uG%-6.I"WC=t~'k5jPi pڮh_"5@%$]d]iB QH2tڌr)p37`Nh@I@s\͛77b&SCNj/,$3݆8y? mҤsK b\@,9i++\ .Z/ Hm¯~~szQ/D8eu$k.aʑ.Ћ_p/X0Oj8 l>r0do=+>7W?&J*nAtFs7=g}6n:>s y#]ctb,2~Qƃ,.3g(_w*fnmv) `(u4c`Є.Pv/a73G4H5k H+@e0eI ,li>u2HPR#Yfd%Jv{P˲"uA+[+K XF%,DRXOޯ19⺅Tjn)ᚇAײaU |ynʳ1{/OKp/r~q^&dZ //^+&SZHK.M%&\ oȼ۸sb1dIBi[%qBD .mU`wa0G5~4C4H#ٿr ^o% ܮs\eJHG 3f}(-W^VۇE-WZtK3G N륈}Wmޒ ~z,/25L9؇+{]>kYc> C]+ qtmcA3@ʕ+6|f/U\P>蠃ĆCX@팹 HWLW6]R]dH,Q4[ZmJ,\L+H;7z< (ԞrQ/"@v1x@ BLDm@Ui-y 1c{챡!1Wt_.`V0m c겋p18A ]´koW e`1vdI^1f!3ҵ8ɂ&ZHb b! <{N\$"'-Iz<_4jk]* {K* *u,nG@tp^{5uԉ$lK )6nP0#^B j{FREQ5`s%hq8-cd].XHY?Xǝ#:\0/d"I5,U@HW]us;@dE/ EL H9/Xy_6M a]d\LfYV =&MJ'd&E=ʱU2Lr^hd(2IxbC}H|$>a7]W<- ` e  /k_9pct0a^xę_|`py%EF!E]oà}HeR#\ڇr?\}12G~_K4kw)sT ۾_v.LjǘzՍO>).@* Z* Ji8B6lؐj׮yyq,4r01} 7B[ԶeyZ^1)},v \V*ӈI.K+@ ܸi3m޼B[4#u@!l2x{eZem{kTBB ҹs*`B+AmBWHơb_R^s9c|M]{j3^@D]VR5QUN [F( KD5;\$Gm* YQ/݂gQ/SzuR{rjAiz H1Lk ,VHHsm)&:?$^|Y4?YNT{3%BFOiFT/uY&fF(k B @l*ګi-QTUq2YIJ*(i!XHjR/P"[f|hTU(K҉'Xн Mۉ(!D*[谺.,ǽ{.hMR$oZˋqNiTU R܄+W\*oA))IS MV@X~=1@Wk۽9nw IrRd)K u?[n?Q iFP\mޔH.)B"n ?iOp* V`„ &÷4 %Dͪ^-[3 x,7oV-(YsC[ ţ ߗ,~60O[0.8W85*P ]FI=z d(/#, 1#ۺS @ s y#-RTU ؕzH/[I HO3UQ4- bU@(0?gi+Cy E Lr Q$4V;LJ *U@PTu:ɓ ‹f͚v[RTU ̚5f̘A;v-ZdL:rJ:S[T @FpS M|V@* EHB09VR$4q ;3U@( |4e_>nݚk$"ӂ  СCA<72W@PXHpS -ϳN P@[o[VR|֩ @3g!8@;lױu \zX7֭#>cz$_\)2bN)&nh UU5ʬAZQ iqFPT_6nhF%(2!&_rzRd]ViaMm* W^yŀ(?p r"`* *P H[ i!m* җ_~i P -㬽TTU@P Jl'|BO?4qԯ_?ڹs'aR6VPH"L* *P, SN~82r7uF]vw}WX&CP V҂:m* *P ?N8j۶-M6@՗_~=PܹiN!*  2PLU@Pʕ+iժUylW+UD5jԠ P*UrVV^@h":餓Zj矗#4'x"!( @VP ͪZ* V`ӦM4sL7oT^ăw}G 6ի_~-[F5:g*3У>J_}!*T0L{ҍ6nHҳO7_BW\T:V4{SX5qA߉cNY$ԱS2v{P[ : F sG_smEg\/w\yiIB=Ƽo_s \˚zYuḀqK;?#,k;n{SZReOO91 KؼY#g; 4~R(ԇ27=.,fK1?7}yop݊=tz*  T`ƌN;#wqk֬zĩ[.zTNH* lΜ96zdVJÇwZAwnq_ycvqEӫ|,xZٿ@U nذt@W^? ʅlʅka}D=lj`Z'Xn[ v2-^.E|-Njht|Y^خAK߿R߃ԞMP0zs!~5p̮r^r;Q6Ưee \vys;]ʹ19)>(D({{rgvYHyq\vb^ wy7=߽~6ۍ|ĝ?\[ |7:5n89tQG)RO/RTBT`Ŋ;sVZ9KW\qg5nQ4@LbBiUh `/Odc*;K/D^xa$Άn]ۗsY99nԘTow6[h/,ێq>iˆ,x<5||ս3X{/;ai{qı֘M5=iA4$I]v`ï-^ƌ~28}_Dqa\v 3ҋ HXbݭh^*>H`=;8XCMN/%\vBbH={7c!kk5V^)ϗ%vnK gHX.g'N>Z4艮@(;g!>"{=SI`}~=D}OԢQ;0Clq'~͙8u%\ Wׅ :w4dvK5ɠѷo_zhРAu#P-bw˒ʠl}ŵ 2"-6 P^iJ$]XhvɳdWF/F#]yYvGn^v993J^.H3?IH=7\P9RKX۪Utq$b;) "XCq@+Ra{מv= rL\4ed.'ܖ^V1cPVb)}HcBU@(0H̋.(-5\E`-юD7'H þI? hԳgR?l2~xHnu-P5/[oe)d'l4n/{Ri6`AGyF8?( 7#sdži "`ˠ+aC#]2Hmjg b le_hdBHy1#hm^\p4atսJA>WRi ~{^_e H98Ң8>cҠ;@?WTQ`:v>y"ӶiXD~Ė DEM&j5UaK_꼞H7nH?e˖ԭ[7~4x`cKI^)@뮣;#/NiJwB +a\v,r?]W%xuӾ~Oy%ƢK 5jT{v1I\V;QN>\e7v3IsjqƝuXaR~kQ]vo[MWZem6R\)ݻA/¸ʺuL")?S.6?^QQ)W)2o^]vs鞇/b,VaG0}Snk7p@Uq^IBkXvڥͥqۜxwL+)ӧOHr~'z'LR'9i%4(Y89 @nm"%52n^ܳ ,I _W a'[ ~{Trb vLv߹NNlp﨣OSSي%xI1^ɒi'mz2xKꗄE1eҠv7ɤȞ{BJlr2I{qz&.2ɍ菌 ̾K#L|e涌!&) E8@ YXExHG&4`AbU VLiT؊>_oN{W2t&3\@~]vq+ ~r۴iCȤ̇ #Zjwa/}5\/YcLOv?]z47_~iu׸pƢE9)\1Y9mȑd3qS?߳.]{`}յ''u.O6u ^Rjw*^@"o.kQ#kX]$q&&MH%'˜Ši[9-nb?Ӎ7h`{5 g\n'8,QKkĩfz~x@:XDS.*ڕ;dQR噩Yt9k϶m[l]eH Vp c9&1IRi/"r(\W? slS,{ö-`_eʑ"zo_qCJ Sb+O~g~Ћ,sԥq9jkq}TW6L9 [n4cHɱ~4f^°Yt~,sW} QmAtFENW_5"z!pۭ[-ǎʚq*Q>{1}S@/h+w]L\iiglm岽T:X3)hJgsf]bxGnWZ`H H+Hw.˲'raY*ak>س\ڋXsd0P$wڀސX/6ZOgi~]Q |#r סC}B]^RcPtrOLQ%Ʈt-v\|[lM^Ƹ8[:! xE)7̹! yN]8i,&K.f_UXBbjƌ A1 6аahѢEe_kNŀڰ8w\ /v WcHq^ @*P.HHOS w-]H p,xVv /CCZ<\lMbAeܘ r;ť+ˮٙ?Q7(O~@*˽ڕ8<Rc ^/b>녌|4ayrCRmG\zaaW2']]nava/LzN6ddžr(?:,わmS<-85/nvS9fU¢OJ 2yTa/۷Ӗ-[[s,aۮ*P  r(_H.*N_W, jXp q0hخdvx@1P8Gct6 ][Cn#ڄXN!,^a䲐2[/ 7#K:5&5r)!rCmo_#H+J#cPey(sy. H%Ci1! 7Fy> WٵkR % c2,p f6j( 9n82 q HvYg8G 2`C;8A ]bL6|ER 3'/bƙZH 7yBϞB 3 ~}&NN@^C 1%ko9o6!w)NgE3*f3~ YnkJʔ+G4*k* _^{͸mҙ3gH}z eŔ9O:M c 8`@?7D[,⬰H6 C /d0`@*Q>qβRWYv&k!;G@抴>uWW { 6+W!ǐf.W@zW8x\~eϛF"pu밍Z Hf En~c<$QvbdN6ڟ5NQACG tԎe!#՗$lPIӫ[(-D`IJ&do>Iv\HE=E.-h_,AyX~pWNtmC#7V n%zY\`w!qe b#jk;ErRpI%9i^|Q"$3/:l"]vtmu]g4Ri :?+URԵo˦Sr15Hw]If/K .޴p@R V-IcuG :\)\)EJ㲾EurqBGv;ע/C>}1 #Lr[?+yLX#>O YYHwҤI{Ϻgy=y+1 s'Q=YjLC{eIv5:p=[!;92bG=H%ۻX{3ek7ڡ+UߍtːsO<ą!{>η)ڂ܎8 ]QR$)>{ .1ۂm)>Lɠdin{\`{nt}SږSOjO-7M( JmC/^wbCZ-cv>kz{Ѩ1,mk԰.M5,Sm~+ж8V =mA}As_ncCy%A;X6o(K_gr,=פ^ײsǶt O''Xg}߰n(q_^F8{sztvZm+aoQsOnU׼u@Z0{Ϙ 6_onK 52ϓ6lФƏzm+EHT 01}W;øZr=L"(ӹ^ 4^ED+7RdG=ڝt&1tL#&~U /;-[FB%[~^T bX`T^RnpaV%bw豇n0@zS (0)炴HBh GxɊK+ { gr)nM.LYLq7Oj*T9~i9 G; 14Hy1 ԓ(=w,ypZ*RX ;^TL<<>駡:ksƾ'~@{ ?u_ͥwg^/RQmB{мgu`NVGgǹ?-rm{rݠ R,BH cÙ_GU>ؗk(ÛoiK{」\scܹ3M0s&첒.[zه]ө.1E Q @ 5W3g7":'[*ؖq =XZk (ۆG9".(rEX=?\3 ^eOe{0p:b76e 57\@,KS'rmY ]Yoܐb8:J6]a5yrU߳:5% /+a.~vYx xje_}6+~q9i8=>PoQ)2 ֪Ul Y|Z"c-yaVGo鯚)µPjه.1|0V\$:wvMd9Qz;waNiFT/a5j,E),X8IC,p*]by@87R[Mڃe[1=/1kaOK۟}_v`A.{ [dtPq!]ڞblRۚknlkHƑG.et f~5< rmwTH^BoކR>C/XE[}jh߹]n* E:@d47Tt+* dLx,]X r=޴荒|R}kVc?,ǽ{.dIIR^s{_zDϿO>˭nlO\yA@ |( +TZu&X. \ R\5S:@f1$ êWR#9׼`A] 2X1*< 2נ6s m /,\4<Nj~7w CG33-NQ)H3u(FUNWTBT`fLlnbL|h]u7'#iL * HIRo߽iU*ZjZn#r1W^V08rL A.Q0ɆˮK )f17\vÌ# Ӣ)sٕ[> 1ˉ+~ǹ6eHwߨ.47/rm7 ee=R~}3ļh{7,5jT{v1/”:sSW@Q)2캀]wn+=sU@(*k$pm۶-~RtfՈ-[h&,@V[!DR'(+!RX )ܐmc&u-ÞWn ),<9 /]ҙԈy+˕ dr Njx$h캒W_)?'vr#׳H(! ȕ(bE]缿`-P i!U@Ȟk׮#GR=  A}CL-,%GHʅ891vL ̴\MQoՍ aٮq5[/?oܨ^z!cb][mp dm_10`Ŷ>͎lҪ*@ v]Q|[m9ƒk;/Ҡak;UCR3$l9+2J4+IW둽sf#$?ٖ݂@w5r~ں'[6Zl\p箹lg*>=oQdUT MKBXP L$tóN<UwѢEHIҤ)dG#X( dClYe<nU@PYhƌԱcGjѢE>tt4ydZr%r)TjQ@_gX22=)Н)GNixHkg*PT |4eY[ګ Hi#\Cd+@?>A~=m|~//+iZ陪* s!d(u%pI=u 3nn۶֭[G}ǀ7B5H #m* P@4*j* H(ݼy3ܹzDTR%Qm= K/m* qP ^ * YS@4kj* $JD 6FPTU@PU@Pʇ c* @A)@o}=Gxzhrx5ktk>v?pnhC;ku5զn~|eP$r3chĜ(2{ҵϧW-qQ -mTTU@Pʙ xyR[\QFQ4Zy{H s>kUU@PTV@/V&?f.R }s᯾g8R{|v!h <mͥw9=:6mܴ9eĵ,z~-CdsOn`o^Oy=Pק6wSO)Tըa]>kcE>2z?f0D{dR0}MWiRGFۥ * cHC_peҙ@!}[bϹ.X3nذ,y+;&L knr/.İ ۭmFN) pEG. ,^i׉6Y~choV5^ eob'` w[/]Oj1n&K2C+W-*HVE6.m Q*O} |(&e$* *R@M` ?9V孿4Ws\+*`V\IV͛7'њVR%Q5hЀTb=;o (MU\SS ۭS+jTU@HOM6̙3i޼ySzn}5ldE :A_~e˖QF蠃}'2< (yP}[O47MT@Z$PTU _}MP ͧZ* yTO?ԩqg-#.r?3z4>hi&T2TU@H'NLK/*ԋUU@H3f vi2f@=mܸ k_.Ӌ/x^@̙3}UYd)@֨*- H_ujܸq,}/^LGui,"U@(TVXAs=jժn,y:3{ԉg6@Xf =C`5@LBܹsVtB+@_;RPTBR(tnG@ZH3V۪ i+;!vY^<쳴zjׯ_*AoE+(s)+mKj ݾZ jW߻/2x≱_nfMĀ,X@|]pF3=x`3ݺuW2ViƤԂTU@HcƌVZҏ>H4S V`ڵE]c ʼn6wXTGI]v5VLXHg"ZhNӛUD$9̝p }H Cu%\@ܹy˖-&k5(M/UTU@@i>=TH=_P Zٳgرc.o) )ǚ^|ŦM!e+Ѹv$@D-j呷 [Œ= BҘ‰H3 @\V¶sHmݐ {c/ ;wcڶmyLM?7q[o^]v35.wpd $/L >Sqma{KJuԉ[LZq, A/iJp"WK boLSmJ<Gfg?&L0ϼ<0ņ* Il맜/arٝhɆ]V@tBSzExgeX,Yo{ZꫯiqַoR|כs*WLz2'h0vXv;~xy>}L?T+%ພ59:)Af2nݺUҰy* dH+Bu5L(-8 ŗp E2  ͤ0LNyLh4rrQgP\7ߤ?kV $Gh|iYyCtєD[w"`Gr9$ɳA;#F @ W ~hy͛77p9uT( mI,X.Kf6%5T4V @5ʼFflҘx|iT2ti (&@m, Ah wڮu7@ Wݟm[劻5Q(0^*]ɰ 7iJ9ڹs e4vd{$>R wY* R|B)%[i-b)6χg,9Ay{=Zj9m@ddW3{9D,=g\vaBrmm Pߖquedڴic\}|$JM6K \\YG%p98. |xmeXk,edVS]v4i$3rz?Gx@T̩Ap=`h:50߸]^sYngb :t@nj `QJ&!P1Ks|W?۟ZG=*hQgQtqY)`[+)+v̲0ϸ<,.wLy%", mܣ(S#*N)FoP sLNcHe /ȱx>^6x%غ0oe/|W /ȱ8I. !f/H]R&q[F|+ ؚYm2ʑK7H|b[˽H~3\˱ ^9 S/J2r[]saQ҃-}|ʺπ 0߽eJL3QyMҹREw :y~:)-{X Ź6R.DT4;PWTU0~&CڵͿX BXH5k HMS u+,\ \ei+ Xcz HZ H텫Njwb6LOXmu"eÐ!CJ(& @]@?$A[y^nR. sΞpm |f e7kqnynj/Tle! ~]I3 W@*>Wb=lҰuE%Lwkśh)&@čx^4S#*N)D <VX0"9G s ^ - .rZY]PHIk.a2dRՃ Xm˞6!>Z-^E.ڇ6c'-EQԕ θ r>%wA6Ԇ(>z A$H&M8]u5׹4yZ\ۗ{e>' .ww<ۺ- HBLa:.p:)j.]bH\v(eE !۟+f[a-_PTd( *u]P m H9^-_|EN4b? vkpee /v?A@ZLaR{qeٲ">傚cv{i"|ȅx E}r˖ŻfPaas?H ? uH\s]m.]{is0 ?4rQq*k׮5_T8*T@'|rց4l0@j;+[ xIaLN۷z* ^aQR8@:c :cC-@21,@g|ZH!U:$qY\@*]$L 55/PcE :F* w}"+u6@:2zasNS B Q EzY\<פ23L )+۷פKL42$X}H]{< 5|]OX_.8qiG8+ɕ֕+{VlvS-7P5u\녈G•쳼&N+}E):~euڭ1T+Y蒝.?Hm]Qh~_kUT+}/"lR!P`jՂ!6h)lq>w\k+gEu%xy(P!WU_=lWo&va{a&gJ?\%wgDۀc9x r 1?K* U@P5\C_~y*-\w9P6]vѣRjbHիB_+foNgdWe+S a rIW`|Cs>ClLAOdyOiFT^z:,%G25)j%MƜV@voBWr3;QojՊ%qiA 6RPTO/RB (_Hu* E_LC G}n"i vDPʩ t۪* S˗(y>.S(iSPT :3TU@PTrʕ+M6l2/EH f* 8P Չ * sΝk{WO>1Y P -v*R* *RJ3֬YCf͚%FG 6DPTX 4lz* *P~xǩ_~tӀqD 6FPT (FL/PTU@PʟӦMSNt~ܸqfΝ;\ҜK*QH3* * ?zMÆ z7i.ֺTU@ȼ TKTTU@Pʍ}u]oӷ~KkiHs*V @P ͸Z* * [n#B>U@PTU*FW; V^-4FW"WEM]رmf=3tp2-(/ GѭJuI p/CyW\qs{ /ҋ?p(k|xM}[WUP`ݺufS$E8p`N-]7nvپ};mٲWN;Lݖz-<T;{>S,H2?SKkԓڧ;.8ih= ,⺇~ʶpP9{>zgL%KM]5ro.A>{nKi|1@KWV 9ؗ=@·tF~;ۗ MQBRtz ko߱5Xg`?\k阣PwƦM X҂&~V^lشnk鲕]|~^œXj䲐ښ#ꛒR`!eрz}S S/8gdk pL_ ƏLJuy~.siE2A!= \vyH|yS@4oӚ5k衇?wh͉T@4RPkhȑ /駟ac^DR1xZƈJ`ϱh.q-[X7!/J2.Ԙ#RK}\vmxۖӆ))o˦)h:`XK cN?XO DL=H3drxUN.\&nݴ0QwNpⲆȘ\ ư@*!OWVǙ&hLx|xbOO~K5hl\. ui(aK\s,*&ay$` D|r6lO:5 9q$'5BxQ K uv#sX ZH-^m@\@K]ݍtF$(.rSۢv O.lj޴l*cчZMm$Ze7w[H3Oyr&Ac\%8􂉠x?^LjrwEowSڮo^g,ymb oX ue ug?~+۫]"x^ l (s/ɑ]&9|d*>*1aYSϐݻyc N&D`wV IҍIZٜ/a˕Ԉՠx4N? /2R?1Ndr%Md%H7O.cJjPDIl][HHmQ͆.*Ij"WR1dȖYy2_~/=b=\#\@AtO ~@%dۼ`b)ԏr*"RZHqt!udM3fynfJT0 "FA#/Q4π)ĈIcD7`&hD| <jdg;TWי=}{ o ~Urw7 Jxރfρ sm :{Ϧݟ^en.BADa7gE,4=BXa95Ə"A{1o T!RVvàBe\Ǿ C+{ϣi 33ϵ/}<,a:ʼL4٢>V$hY| nw^`\P8O8}QO^s$]di'i2TYJYAkõq$ ǶL{~/˴,O]XÆ ty/_3(Z?L Qj1L]Pi.!΃EEQLBo^֮]+O< 6#*H E_1$9ڇ \VOA,֢d"UÕ6%$Z {Hq,fM.&~Y]O>te:]b- 5CsE\i,_ Y5\iM(9Lʫ*[l`, ?P~iyꩧdΜ9Rn] RXlZaĩ)H}@s=s5o{Fhn+W.|< c4ìzKeUMlQgSPui^s4v\6s 5ׄjkㄾL50w/Xuzyc׹k=q碋.BD{j6"v ^6hРJU|w{/ a7g4 @ Pv[\:~AE@&HLVbxf'ti7$(=75" ڟ6K@q:/y*&+sgZV &@AZё ;vxᠼ'PjuVajE/t7K5u2.]Jn295K׿wp]\)í}֨ٲ߹W-Tjy罳Qq&g!_zs:o5d{_f7i6XHH"(//(SJڵ#b8JM{MBBPxe' } l |$療4f>疂4|>XHH"駟J޽N:KN<1+!H`v=ʐK~YsOȈ!u68G|үOOG^uW^=J<*rp>+|׆}܄ٯl[ɶF1Ʊl̾9&?tySyV^r~嵥ڄ>Z5l`tI^ LnOr=yoWg?\yX/?ڷ8}OLˈPg ٹS{'/|/|V0ˈD^[vfmyfN\B]]sï3mMuXȮ~w4EctE[$ s奈<>M޽& ŸUʛl羵ʚRo R(/tMC{W "L1EmQB!  (Hم`t Ca3f'APg> Re&Dl{qMωzKR݂Nf'd`ᚂf+\}g#H5i׋s-/ js͹B4&" مMׂm ?l&;%=DPh{fgfTYSZ/9 '!H͵vp d;9 _03 ҂F :͛7{ɎxFPizz`޿ż\%I?I 8!WA|̾C  R~.݉R  ӓG +] A޿,KC,~|)`ֱD"4l5s  (`8n/2o<9 7-_4nȮr碨C.k|ElCv]B5x=q3!zH )d؞lk^6Sq ҰyTA }AǾB{dk?Q?s FbѼ;wP%۴5J.߸̽Q)Cv OZH$@$b7>g0Qнhб/Pl;vFo/1hi&22Gb}e {/AToW&u1=+,ʛG`]AHÇb^콂cMШ4z&ksn ҆ /3iM[}h7Ȗ]sJM4;e6V7򻌀/f=?{(H; @ȧ 5-0<۳4K`9>5 80Qr - Ң wV✥S%RJd" |>A4HH0nAAY԰rKe\5[_T]}t Ms$@$@EJ`^#d2dH"fCTHC!kHH O+B?\i5H KIHHKz9TS,ii+GE$kHHJiM)D$2)pHHJ@M R> 5\嶛.v Hl)/igIWεj{X9]>ӳF]炆se+ͳ}dPqݞ8cV|bW15Wu7I i1"J$@$:۶mMnQ\XK 4RswwY|u;~zEs7]g%WWl#SF>9U?5k{0] Rpקg\ ڞz[gywSi;~9ZS92䒟xM*mdhڧ2@|]vWj׶B?S&?3#ek1l4qcP1{=h.|46w{4߿boebs o^̙ާ0x{;ӑ|Z/ku/lCX jzY|t"ž5V=o4ko߾}\pYe%  ȕ OvɬY,&K~u R<>4y[=ϖs~=mֳ QqJA46Ν{ BF;vhBtk߶梱}YO#+A [T}?l?g$ȓg>(CAj;|F[þ |@~|H %<)ʬmRvo|{.vuMI*ECO$t^̾sZFtES׆9>ę$zWx7F֚vW~E?g}jKF;se_Ol 9sHc~z裏(Hcc  $ ̝;W=Xi޼->\2nnЃYQ1|֩7]=wf;wC'̴m!3^ ߤj*Hw}|CˈO!^9B \04*Hݏƞ_5!4LoC羵ޛ|]־)~ѯ!|F~}>M;kZקݾ7{(ȶ8B~7c}7T~YW^Y%KP& $@$@$?%HҠB=oxfv7L9akOeF%Hu1BG.mn1pWw{mذA/^,[IHHDP)DTMD$H˿!{ߒ_Cϕ;{@l R3\5hHg)t\l"R )^Z@3Qk>s*6Ul fTQ׾ܩC%dX]6QE~/M{Hx ۷oؽSsҥKR yf;vtEJgg}VfϞ-cƌ-Zh=~я?Xƍ'^z+~A$@L{Jwe„ Yϔ_R\Cv]qCv<5 кO۱m떞cC";wGRٍZiΡ2Ӱ]{/\|C'd7 ;9n.^HEו:l$H֚o[͚6/ջu RW(|XrPȮ_ui>}bGA AD IDATCittY$ dK`߾}re ^"OB˖-m$U ՇlH"dWalAGsC,v&3m4(p)(Pmլ 2B8]yU ۉ웩<:FM`gi\I=A^?]a p5k˝IUEI7h>]\{/WJjdiKכ^oL1}R7HIٌ0oaq%"S!=o@ZjUo-[FAq4,% q^ɋ/( ȡZTE}>@!>Eț)"MqBv}.¼E؛gfr,(l>ˣ {e(c]}n~GԸaf071Dx<; &C;ku Rb6#i/eY5)ʚ6rrJǾc7>{>A,194A| ^s(k_:_fȶ9;D'kq 5b?O{~/K NW$=&Q7_ _Ȯ=15iP9Ǿ%SO$8mO>$T0^ZYWVj8]2ሚ?Y?O9SN#G㽤M9=z4h BkN0\d3~#2sLxjm6l(]w}љzLϛ5YBvM3!Ķbi2ٽ{w%0ŭ8 &i&{/d,djֲdz/ٔ6dVIZ)yA{ |[#dht {{hUinCyR<ږ`S0pm} zuVYlR~)Ŀ7?ly2_0苂IH TILT޽{Ǟ+VԈ ٢ bj p8Sv9d~!f{Bęw 45d^Iiڀ 9<Ŧ0tPo_ UVy_S _?Ab2qDo,es $@$@P `+QF\R,!MCQҕ+Wֈ XPfZ5I5 Xt FۇK.eb ơ EX/Ӄ.mj+ĺ@wA$P]] !i! xR!HO>؂BHnQQw^N !./Gt|PeϪ-Hw^#f\lQC/XH {O>5J{993ojRل\  }䤓NWl)~2Ⱥĝet=T˃>oˬYE2'^~3ڶW蚒fHH O(Hݐ @5 4iI۶mM6ҴiSnݺRvH=:XqɁd߾}^('.G}^Yv!.֭[WiRN\d{`k$@$P}J=n6&m<߿_+7gUde  *\YfR~Hh ]~=)o̙Z! B'xboO_,/ ܬKJ~gҨQ# ҬfHH {<)𒪇N:!ѣGF**~?2"집5=Im T'7|;Bygۦ 7qG$@ ~}-fM' ȅ@)r1sȺ$@$@$@!M R$:1cF2e,YD @Z^n۶M~ʱ+72' _rYgH߮N[>#kiӦc ! H DٳG{1իWZ$  T?<^#Gzy 9!hҽ{wi߾4h IHH'{nYf,\Pڴi# K)A Gkڵ^xL=E$@$@$Pv% 6NG#ڵkW}q  h(Hqb)   j i&2dvasy" H 5GJ$@$@G!}ꫯJ׮] FD$@$P}(H-[&  @?͛Kǎ#f  R"@AZJɱ @ -ɢ$@$@$@$@$@$PJ(HKi69  (!7o-ZЈ8  ) @̝;W:ꨂ $C4lHHH AÇɓ'?.ַl9<{#lH ujժ1G0iJ,C$@$@$w3gΔ_M!jRԂ&BA4`ɾAd"wĺ1i(cTbQ  !~&ٹk7 @d דV"j׮ե(=ԱV=CE^k,XMd @E$@$PɊҹJ- $P@-_%mʚK:u?'Z&,X@+DG+(Js$@$P j".dʵh  ҦKݺu(b)HotIZjr@  <ec$&MʈQ|cyij` TD^uyGecd.&<2.k+ bsΚʉl->m!b~UCA H޹F>}5f RxHq\=56 RxH۶m[C㤸RO>3]|} ʲkyMxl A$I ) U!k]'8 PꝮ6؂h i8 B['L C ((H#b1 __3RR ٥ j)t˘1cK.7|+tފ KzTڂ{Gm;ߺ$@$P Jǎ+rKɆ33{lׯ_֓EA5:V$iRH o+_du\4èb{,$=jcU"`cdFBA~c *~r59ۅcZggOa9O  _/{L l3A1BoRCj',r ҳo:b.A{EA~c 2nMFYw_̙3G^~e9餓 Ҭ A4|9V"Xze#HMgc_\YvdAzHqΩzfUYvOT/::βLU %HH ۷˰a ̜l,Y"'xbPfI>'@AR+Hn⋽ RWiMjAj R=4/~~ _UK~m}:$@$PZ?-%< ҄9H! IO 86 GNg )EBqˢ쇂(F@A R +(d7%K: B!G$OM+șg{ HXH i 5Q/b.AAZ̳GI&FA:qDo[o5)i(" !@AD(H)HWI -0H!FA_Zny"{CARc#$jOAJAJJiL$A$4 R10_#1F~]?{?2dĕw?LɖB(Tq\嶛.v*|m<<~9Z6_gwxYB[eڋowG}ݗEj1}n2`۾1_ዂ4|H HH iqe#H\>3jY pR4a<|4[ORR+U~7Pٝ^@8* T Snaϐ&?tjlz?כo_wʄG!'U2ְxmڽG~^YWh϶ PŻ'6l{qWN#ӫ5hoG{/xm^R\u1U˲k<[mQdg-Haţn %߿bH)z{|ZoL/(C.snUkz1Km{ιѾ}O̬!{a\SڵׇM`{1G{VFo\q=^A\y/u-"Bi8% RѻDph,QmvZM$@I =Dߗ;J˖-+anAڹS{O@ء':} 0 SyׇP-wgO6jԠR_ڶm $?ܹ;0de?s٢B煃i SBd6byh *#( ltdJ~ n]GxwyOmA}ts]Ĩ gA [V~jG0gw+wyUzEy}\ABȴWMu{4hT^%7>ROFAj1ZCddDqJd0^ZI$@ @AZAwߕ}駟.?qAzeBf͵~j+[.i~0ְq[!Xť᪶CN&!Hmj}v m O{!K[Ne0Qnd K~xAnTC֫_q 5__(F h! @ P">g9SLAMyH!HM\& IDAT6\RӫG7Bveu Rg%#p 8A*DUA,F"C3j (R!͇ 5|jhwsÆ Ȉ@H*Dud7WyB 獻4L4 /s pRt"wd"ЦH#gf֐  ٨)A8qiXȮ}4 8 ,)Aj~3{q 5EF uyOHm떙GAL1nb4a֢]\%X6iH n2=%\T 'EAΈ%HHHPOiM R =4=vžF08TOL$1EB?0?$2m u |Nmz5k+%=r%3%K y5l_+/-5PyjōZ;&dSw3rug=b&7E%(/Kl)Hÿk)H  )ݵk I'${ƍˁͳb=a2A/BA ORб/g^9; O4G~GDž?3І"¦&MfilTl{;vY1Q+=c_ a˽'yhQq1 RK~;Uj6К9,d6|׮ K+o|!PS g$@$@$Pr(HtϞ=2h yw^#<2+AZrV~ ӘC3mcVOeq i g$@$@$Pr(HQrJ9s~%wހ ]{G£Y8Qi8#   #@A<ׯM6I.]-EU+B¬yD5NA>XHHJi( (u3LAΈ%HHHPO)i8# &@AB(H  ) g$@ \ > @QؼyXBeΝBWCMU4jHʼ -ZD7ŋ=HɢmmSNIF/~ 'EAΈ%H(Hs]d} $vZyK:w,mڴhBh"ϴnݺ;vx[l7>خ]к??^ڷo/kζڶG}nUW7d·C}-? pL)H3 XlreUijY ks#ѯyFf(u0qʚ\翆h%V4p븱?laQ! Cv7i8# (1or)qW4;wg+{}={O>9nd9s=aKd޼yqHzWOf];䝙I  PD^%n؃tu%] Ky9W2H/iZW6νV8柂8V $D#ND8}2n8u1ѣAU,衇]y啕>۽{?vz]pr{?"HQӗ^z ۷oBD{X /-[&n7*iَ}2'/M6CAN9>VCy^|3^xoaA)lUwzhiP%O>Lx^&?tj~~@w[[vO*Nϓe?I-}RgxuƇ2 5lcϰsi=3lFů/{)}kz\\ u[={g6?)1Zr!8?Y7=ˑ0+6Miz'W\]U7Bv%! FAΈ%HJxxI"LuĉruGJgSz^NSb/رc=ABV.B`Q6WA  `+I\3 [ukC)zosҮUS߿tP| [~v`QpF=O"&~QCvHZ55%Ha{X=|K{c6u*K FȮi87 pF,A$Pl"'OC&~PEg{?mA'lٳe̘1^ \a!˷Wک{ ~|I6l4o~4v<;&J"GC |I(]ti++{W ]! wx q 2R(֪!Ȧf,¥ÄkWæ(4l>5 n۵po K]l+saa/FAE^S$X7AK4K gDAȷMzիW/&XH GyDȾQNl!tWZ~8*H!x.]C`\ >[:'/<"n>vS%_Ε9k4A W*^hVܰ=.VZil&H5{5u TOL2&ӫ U/xXFdS &fuXUC_AjaTAR>KK"B#(HC80OGm !Nf+H ;aӅ}a{HwynCWIa]L}u1'.t4'1+JA9s\Xfа֠bBĞ›f{*b#<O5 =aE(!~a.~v򬌇\e^9UH W^D؅Xatz=g^vj*rjcIroBrYjmѢSm5325;DBb +?+2d7̗ *b`;q#I>c{@©^<[Ԕ imo|vX)~v&pKɈYWvg&? JcۧU?o7Ӷm m^Tc-HDRl /s.|a6Jjw_٨6(HiR3 ;wZ6jԈ4JQ ۃbsb]E AZG_D|.F39H١S2ؒ&H7npLĦh ;*GC!P bu}TW9BAȴSL.IizcSӽͣ:nveΣ\(YvFSW\ݧ(o0i I[L~f7=%h|vH =/^2Ʊ4Xmo4^K;i%l>cYw`lj7;/ )D/s+~ti "yFOTl;!dK ?^WIW4 М i8= pF%}X=zʇ~ecnlt@ yc7R!AU8 njU"݆5MK U3URB_DL٭.Av}XMz^vt!?گ?f/|̪sirNAa!]uK}|6㴍X>m MA(Pn߾=+A`  .Ҷ{c_ H6 Y;b6=:| MdplH /(H1S3 [nnݺneѢEҬY, 0Cu,jq=o!̙34jyמ63! ʦeJ]t^xi?#OUڟ=~WxNAt$ ĤmKP60UoqcGYĉcGFsK/[s&sڎyR+J_Y(//(>r"H;}tAq wDjA յ }-aV@v;%XAS[" |ٽO"^n"]`NiHAEA&@A>|K!l˖-rn壏>ʫ Um_*.]2[ :p;t(Zs߫=PH; ~ ڶ XSړl R({mDaJcfc_.!M n۠kl>g3B) O>I\GuTի32 )< * 6IuQ)\-3oلUkAFAzO{zyl̋H 'EA(PB@@?-;o͛ |?AjC?1f @=a/cua &7G8ÔuCa7nGtkSL.p͕-H0^KTQ˖ Aj_ر=?.wݗ ؋1d^Q\O@+9~Iո%XwliCB"G6lm"o *T/+(HF D0H5 g[R$@I20\7~wx9rd 7kOa.ڡCP'w$ZgsZp3L!zǎ논(-QăPa3^kQ܊rAz>Zq6iK9I !bm"lk2)WAwǣ|icRӓ[4Waֽ"o!rϨ M&ib( iS3 u5vRŋ{޴B~*H,Y,&\$Mq Q EY 5=*ނBoDK{;8iTi\[r&C38l׋0qYjR+){moKU.RG;(rr1*8T%։EFN-\ﲭ"I4&DԶӹ*Di͕;4C} $( H7 g*H1n.DG! ҠPIڳJ_)U"g܄(Q=H^D/CT %[A}gWȮc9ܚU&%)1H{ĩL \pTGD~Yvg9:cCe5??iT"\7N=r Ҥ41lK4|)H RMWBLWR? Qu ({DmCj=A-E.qk/4=yjU$ <^ҽ^CaEzdKD =t'Hsiҭ"-z²nFn5q\iHi"KD0H5 g(HZOI({HѦ+k-]a]Xm]BK15=~v&\WV* mێ" K%ˮ%,2` Mc-(e}lC4 Զ5+;Ν;o߾aE 0+E6P Prh$')H ҵk GƖ/_.ڵ ́?@\'FjA*HÌ9sug92-c?}RE anibxH5ۮI|C2p@  iYH@(Hi8PAzG]biY%ZؿݧOlzI_~b@r)SȈ#vډ[ aXt)/sz/K.zHg4K  E HlkڴnݺSK?M4_~OMuȾ}+3+f͚B>ؾ}{zHPC d鞧SO-[FYr6m9sx/ϐ &y%uMҶj fofH]+(U~gIHH x1?͚5Spef)ա a6U~!m\4J٤8Iɐo-7n\KR&u޽[Ə/K,4y_z>ݻիiR4K/7"%@AZGIHP؄r8$@=XvPaرce˖2zhiРϸq㏗+k2qD뼟^|޼y򶁹 Rwyg裏K4sϑ @! -٠-$@F`˖-2yd:th ~L ٳe̘1^nڴQE02<60D˷Wč'aÆIͫ9.l=?HB4-3q@ ̚5\f2[tӧO<1_xUsw )E-G[3vxW(H|i>  &r޽9ԮZ^`$@y>|xFz]ti*{E.,?7BKOO_6 ~^(HKtb9, (29Lzκʧ&kCYU<6x<'LP)qR؇s$FjذaƳF ]D[.r %N" 뺇=e;cǎyŽ i-! 4 apk׮ x aX"x OՄFzHMEԩSeb_1E"?z`Eoȩmܠƌa$^>sH iÝ;wf-H5jDAV%̀ ǩT$F]}CR&9v,A|ȿV\j_kQ~ɥ(H3c   Ps؇գGح|^6zHccM ̳A {1T񌺪@tBj#ӯ_?/Ӯ%z&i8f)6GTn$ŗ$K4YlHH ;qjAn߾ UԘ9G>nܸ 9`]Um ĬLQTA70vX#QI|/xɤ玆I൅uasvJK~^s(Hk={& 8D4Հ9ݻne…ҤI{Hsc^(H7iQ&9 Tk358yNi=64==>ݺg7 ' BD$@#@AÜan۶mY ҦM]JAiJ }E_v uIR~K,qF0$- n/+=%A4 lHH W9֭[=Aj!!m֬YCFh!3gzó jy׾8Z6b;T=hH[N&{'p ֖klQ1XLEVdxMfV?&Sݰvԫl̹m7#kĉ.X6aq֊ɨTQ^^^I&XeeeyVMiL" @|ej`-[[n U'H-ZWAj =VR$,* T\*@pl =m/H)klժ3FZh "^$\~6a@\S=7.*gS`jzhUv 0ϬyvTp#\/ Y=q1GC6JAZ*7 gtCJA.7 # f sk?/^X H Y*H|u8m#8y.'ڀBf[ASAk3 >J{.Kbe/e\4j;ũ4L"H9n81=~T׊+YW/q,*VH]Ae"4JK_㩮JAIH`P0*H+H! YsYlի+ m;[i\8X=v9p娂tپmG>*<:o uymίձڞ(mQODvUWJ:"U9PU)HK`9 (9L"򈽈q)VRQ'%Q64ʾO$ _~IXa(ktk'Hd{H’~KozĝhQ>,iUR?Ȋt7m+{Wjj-ҩ["rٶyi#& B$@Aì Қ8n!R^4bϕe/9A W,LZ/(.3LJ(nb!ղf(}FɲkSiga늲<8~Håp({HmܹS_U0kFl=˖- ȠArkj -#j:D Һ^z!;wт ;rvH$@$ @AòPA9?A۟9H` X 'M$F .+Lb\oYbG4=Z|'=r%km2 PFgŒ$@$@G4x8\~w|=8ܾM6yCpYi}^uMWy QHHs9,<Y y۷ ́?@6e"WQVЭ[7zEs_2%iIM'C$@EKh T}v>ی"Zi*<7'HH41 i @A -i$@$@$_HH(H2HHH (HS82   D$@$@M }  ((HPb  (1%6 ) "8M$@$@ ͅ $E4)lHHiMM% &@AZ“ˡ  R   B ZAzWB@$@$@y' 8Vp r뭷Jf͸0HHH Un*wyw}7K$@$PxR+H~9sN(YE$@$@$P{=y믯^4 H 6m%\N%HHHL4I+Qq($@$@H tӦMr7=#M6-ƹ$@$@$m䦛nKZl>+ @R+H'={Ȉ#dʶHHH` cydr饗J6mHH 1/IwA>^$@$@$PL@ .$1BiHH %(H`Yx[KzċHH^mVv*=z(&i+ @Pl9\     (2HHHHHRF4e @ -$@$@$@$@$@$2)pHHHHH i       Mلs$@$@$@$@$@$P((H e&h i&%     B!@AZ(3A;HHHHHH e(HS6.   B A$@$@$@$@$@)#@A pIHHHHHPPL     H ҔM8K$@$@$@$@$@BPfv @Pl9\     (2HHHHHRF4e @ 1Vg}6FE;t \pAYHHHHHJiل }71jU]~,Z469V     (U1ftΜ9rgĨuH.^469V     (U1fVi~bԪ,H.+ @) 1*HVE 6Ȓ%K46:V     (Q1&7ސlҥK}C=$sɐ?f_t2~xiٲ\yY7˸qK/^zeNԊ`i&=z4h j*yf;vt%)A0v2o޼(gDCýiJuƘF%  H NQhyyC 1:fiѢE:uTdCO ҤHjԟiR/RCi^$7E   R @AcUz1j˖-J6Z*&ieZ4t  A˗ ˗$HTxMgϞ]ɣj˳zLHpVXiʶJ aÆ{yg 0aBf9J/  zCCvuoY/n1qcu-rױcG5cϵB_xJ}b}ls>m[> c׻wo/rA9m;$_sS/V    "#@AcT!;l>bOzHSڲ'Hc).˓%xRq (ZR2c 1UC]%9/;ɍܢ){D#`%!! a.@B_AadΩ/3}wJ>Mf^R?sZg1 Ժ0z9ru裏 /p/3X^|Eoe֙ =x\N-v?Q=hPH$9 Ue>C#g}. Y=F9z3;f_??,oEj ]Sr7;,O>ݽ|hߗs]89߻[Joy=2goƵ3ky_lz޻a ?=PH9 髯zYw: ~nFyzBzuJE7Y;]VfQLҲ]r3#kSnܳWn4ݭ;)_:.+?]޳d#]{}ٞ{{#\tqJEC+H @D@!=(;|+rYw: xS朧0ϙ/׏ך!G/n4\ z^vt}޵W=B:_9ӳO9B:^y[ _<{粹ٗ9/NG x @Q@!=,ѯoBz<uz}'D @R@!=~;=Bz=ѿSN<< @ғ>hg}*_BzXz>tfQݼ @ (;vB>֭[oF!= @t (g[\Э쎻}ˁ1< @ g!w=ߟ%T!=* @ (?{'Ξz_y䑳z8u֍luϻ_g~ ) @y"O裏=B:Jov/g??w9"@ @,qt }y<7~tqtП~鼔_ǿ>5͊ @f#>cet:}L!GA?-GGж @t%׍SuG}{GHy(F::F4= @,q4t(7}HF9OݝEtQEzږ @.QLG)tyM[!]YN];F  @ZyכԸwtW@%ɘ|o @\M`}tYPu1o @ @n| @0~<IENDB`backintime-1.5.4/doc/maintain/_images/badge_bit-dev.svg000066400000000000000000000056261477034762000230200ustar00rootroot00000000000000 Mailing list: bit-dev@python.org Mailing list bit-dev@python.org backintime-1.5.4/doc/maintain/_images/badge_mastodon.svg000066400000000000000000000070421477034762000233040ustar00rootroot00000000000000 Mastodon: @backintime@fosstodon Mastodon @backintime@fosstodon backintime-1.5.4/doc/manual/000077500000000000000000000000001477034762000156635ustar00rootroot00000000000000backintime-1.5.4/doc/manual/.readthedocs.yaml000066400000000000000000000022631477034762000211150ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See file/folder LICENSE or # go to # and . # # This is the configuration file for the Read the Docs service. # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details. version: 2 build: os: ubuntu-24.04 tools: python: "3" jobs: # Workaround: See PR #1554 for details. # When migrating to use a pyprojects.toml file switch from this # workaround to the use of "python: install: extra_requirements..." # See also: https://docs.readthedocs.io/en/stable/config-file/v2.html#packages post_create_environment: - python -m pip install mkdocs-material mkdocs: configuration: ./doc/manual/mkdocs.yml # python: # install: # - method: pip # path: . # extra_requirements: # - mkdocs-material # - mkdocs-material-extensions backintime-1.5.4/doc/manual/mkdocs.yml000066400000000000000000000071541477034762000176750ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Kosta Vukicevic (stcksmsh) # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See file/folder LICENSE or # go to # and . # Project information site_name: Back In Time - User Manual site_author: Back In Time Team # Source files (markdown) docs_dir: src # Output directory site_dir: html # Needed to use local generated docu if browser won't open index.html files in # sub directories. See https://github.com/mkdocs/mkdocs/discussions/3847 use_directory_urls: false site_url: https://backintime-docs.readthedocs.io/en/latest/ # site_description: Back In Time is a simple backup tool for Linux inspired by "FlyBack". # Repository information repo_name: backintime # repo_url: https://github.com/bit-team/backintime # Entrie labels determined by the the 1st level heading nav: - 'index.md' - 'quick-start.md' - 'main-window.md' - 'settings.md' - 'snapshots-dialog.md' - 'log.md' - 'remove_retention.md' - 'user-callback.md' - 'additional.md' markdown_extensions: # Boxex for warnings, etc. # https://squidfunk.github.io/mkdocs-material/reference/admonitions/ - admonition - toc: permalink: true - footnotes # Syntax highlightening in code blocks - pymdownx.highlight: linenums: true # clickable and referencable lines numbers anchor_linenums: true # Highlight (and reference) a bunch of lines line_spans: __span # Somehow ease up CSS stuff pygments_lang_class: true # No line numbers without it. Don't understand why. - pymdownx.superfences # Configuration theme: name: material logo: _images/logo48.png favicon: _images/logo48.png language: en features: # Load content of main page only instead of the whole site - navigation.instant # Loading in background while hovering over the navigation item - navigation.instant.prefetch # Unfold all entries in navigation side bar - navigation.expand # Render navigation path on above the title of each page - navigation.path # Back-to-top-button - navigation.top # Render sub-headings in navigation side bar - toc.integrate - toc.follow # Highlight search results - search.highlight # Footer # - navigation.footer # Link current document to Microsoft GitHub - content.action.edit - content.action.view # Copy and highlight code blocks - content.code.copy - content.code.select # Colorsettings regarding dark/light mode palette: - media: "(prefers-color-scheme: light)" scheme: default primary: blue grey accent: blue toggle: icon: material/toggle-switch name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate primary: grey accent: blue toggle: icon: material/toggle-switch-off name: Switch to system preference extra: social: - icon: fontawesome/brands/mastodon link: https://fosstodon.org/@backintime name: Back In Time in the Fediverse on Mastodon as @backintime@fosstodon.org - icon: fontawesome/brands/github link: https://github.com/bit-team/backintime name: Source code repository at Microsoft GitHub copyright: © Back In Time Team backintime-1.5.4/doc/manual/src/000077500000000000000000000000001477034762000164525ustar00rootroot00000000000000backintime-1.5.4/doc/manual/src/REUSE.toml000066400000000000000000000012121477034762000202260ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = "_images/**" SPDX-License-Identifier = "GPL-2.0-or-later" SPDX-FileCopyrightText = "© 2024 Kosta Vukicevic (@stcksmsh)" backintime-1.5.4/doc/manual/src/_images/000077500000000000000000000000001477034762000200565ustar00rootroot00000000000000backintime-1.5.4/doc/manual/src/_images/000_btn.svg000066400000000000000000000037501477034762000217460ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/dark/000077500000000000000000000000001477034762000207775ustar00rootroot00000000000000backintime-1.5.4/doc/manual/src/_images/dark/last_log_view.png000066400000000000000000002512331477034762000243510ustar00rootroot00000000000000PNG  IHDR4+9܍sBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:27:36 CESTpIQIDATxXTٺYs=^{ՆMQ$lTŀ14j[1ڶmjbb1+""Yrw 3!B! vK\oZIEtrc鹱KuoMMRH{e,eMG R`WZ!B!5>p &x]"6T4ޚڤ!Df>Wc_:WWWB!BDWAt!F$A13R^h~ir2 M6EƍѨQ#B!BDWAt!sDb15bCjcj*;c-3132#mӟtg}D!B3KN!uso6zLEj,4fY"3q0&ٙ=1B!7Bt Jj,LlI=蝑N`q6y=]qrrbB!B 1,0sHF:Qx|"6b~L&{'B!44kΑl|"50Ftޙ1nSt6 `!B!m4O74,饱;cI5wo?^B!)er85sf͌?D. gvꥩi4L3O>F!B'kDv=A.bzf饩.UHۿoEqB!0-L|Lm"cG%y1߬zi,]fֽ34M~ qB!ã2cABE>KcI; Ovzg!pN(B!;>=3zjz-:ElI29@t3f3Mo!B}ySPۘ=D1HXlӒvf3?%32k܉ۢ'Zu `,?INM !-`o___b;q"^vf7ݬgBy4e)PKqua;4nnQ8Vk.<0HTj5n/G&V2q)nV>ŶNhK\*ϓ<Ј!4(… ?~IMmS:$kH;xt3'ܑ8^pFJaM$5Fe)(e& Lf3}6|5eLc#_YӘ8"3"nnn38*gݼ4̝BC!4ŀGƞқXQ [bQeej0ߐB6 1|cF5MوV8&46nyŞ%m iZ*?Mj^9Jh> )u=MŔ.X~[(!ie(CI1+zsHaI9avq4Bh,oljI!Oh\FKc/%|;{"O^ b(4L3SV,QzT$\bhBЄELuO3*T~!Lo;0L.YZhF1֧*V`ŊJƦu*MXRعK|~S"vD Q6ByO0M]21@XPSɄn)4 McYp8Wɩx1^(+;1%Y?aIG{ ό)gxrbrv!(e2/F`({e(,,1俻i2;BӸ|\2 3:Ŝg +4GeYULT¿T*$FY#mav7xΜ%Bs;BޗШR v0*d cdxt ~**{h^t+xpoK;ULhF}ʼn|S"22}=>wE4(̓^{X|&HBZ&Lq} OaU<1|CJe!+eʗ*y;uXVfJEK[^M;$3EBq[|M80ә?X t3/ !O.gB8Uyq N}ĉ[OW\&|W쇗̚cTd$.~NX=0M|1d~\~R9<9Eȩ8w~$W@q4WY;z[67ǐE?|Z^ U)I*Ƃ,GqF>KОYB*R?ց"xYt&OF:gμ)4BތFpo "T)},!eF,ÑB-3*_lB! F#/LK#<3ORPxq}!#ã2#zl6_(4BA\L~w2PPRH=s7=!Fիў&-B!B8MqGɻh>7M B!RWwʈ/EDYmS3ŖBC!By 4B!B~sBW8Qh!B!8IB!BoZh\)4B!@h\)4B!ߝxRh!B!Qh<Dh>B!BȻ B!.B!B(4B!BB!B(4B! B!B!B! !B!Ph!B! !B!BC!B!w@&MШQ#!B! cMRh76K.۷/G!B'bL-֟BQl=zEB!7D[)4oKO> B!4b-w 4b:B!B1ƦмB!BHy C?؅BlöCВA!B~BkҊw,|dдK2fޭV\hz ???bMCh B!u@?2Fi 1!pwÜě80͜ r`0@h:"ƶFѿeϱw_@7@SG0+)4B!&40a ba0:zAfr M`` |}}%tZĴ1c0 ~UG11#;kY8.&_aӡ$lj_AhR96B! 1(Fw9mm|/Z0F/yM&{.AjUۂI]M1bUR2W~ tlG8Shtח?^}E* ZfŌNi(T`){n ew?ff14:öRfp|}& ۨ)-ۢ/oBwEYٶ%-BqhQA+n`Jv1 6)A+_ 1(4_Wdpi1g8d ƎI#/3;1fDL-|Z`T4qjlL?_p E<)By㐬ޞXLS&cXt_xJ=7B06z6Yf?d3t~jAhn/&`ęX{& :U g^ G |LlCLi#m `ƏDH+5 D1еwey<.mRoZ7a=_WX6e$aOj)EX  \4m1n|7CC0b ĄwWB!͈Fbbb5Fch4IQrڻH%ef<՚{pʭOʙ=Gw_ %6aǛ1_R^h\aܘ?9K{ YFSZKà+9x9&4mfƐ2 M e!.itMaۊ l N-0z svcLm~*ٮhm)xϯc"Gw+ ߎg6cv#['B!#If>jلd_'8Whq ^j3oQhicRX,G: ?UdDzkic^{{B^L ݫeLF+nAS^rׯr -Q3<u!}Cg}{2QR@~+ /sdvE%WSB B(i*B>¶^CAWx (q7 #Ah* YVZ>曄ff9s+!s{j1(8C 0WLA_vm 2 |?;txq0a|s!fx&N;KvDLazomƙfua;}-5K B>F #(Uxo :.B!Ro8̑~BJ%#MB~ixTۈc >fJU(4DVO'>U", Cj 膸 b'!{Ok:C'{0Oo06>o5u\h|:y dKh2GǢۗ/H{ ;C! gj 'l{a"e GbXDtɥ'(E"<4ᑳxR 5{f9ٳ'$sZ& #ъ+-/C7܅J'VN1Q 89|e BwKcaС;5P]^n>^V\Yפ#ЌeLe-C<ƔE,|FwVjo(4Z<׻(!DDȐ!ُ'L3._mZpZAhn _@_`ȱYy\(CAƶ`(Nxa?L^cW'p,1aC1tD,= }ψnSB!cƩLƒBNB$Cu8!У,';{ed>1wW2AgС,?W7fqt3{Bcft0N\(;fGKyJˡW'4o?  qZfC9exzM ڄF{)ӡ\"/> Y3BhKy+J$5 >}W8_i<OpcxWB/GVS&[o !B7=z@ɇB8Yƹ9 B(cl w7M]i0*,a1Xs*3śC!B&4ݻw'y4oq[qv:=yxtyklB!1Ʀм#AG!BH!w~֭[}h֬!B! ck1cm [I&hڴvjNB!BH]cj1cl1֦м7nlGKB!fu]eBC!BB!B(4B!BB!B(4B! B!B7B!BG%4JB!BH}BC!BPh!B!B!BBC!BPh!B! Dž"Ux 4'幆Aumm6'50ͻ!ʓcR$GsY 5!V6}/R^BW.̹] {G(\l6<† []S7`ߩ<-uyvsbNۻ6qq֝HKZe!2Ǿh\\zNFB$c]\aS #+oNd 2b˻=[ƚ"=jmz7Y/o Xp)Y կ-:սʑwƔ'qQZ== &v[=v6~(pՈhj7h{r %d (8<n ];lBkzLBoP yTE":Rhޥиby\WjǐxRtd■G"D]~\]ťh׾:ڷ-4ޘϿ`Gh6?a[lc(Aq0 SblH)'( e 2BW  E{y/q<06/_Yш]yi  Ѻԟka.m qw_ ̓o0Ƚ.9P9{7|_`uHPC?Nd3p47˜/h+.ÚXg,dPݑd1zbT}DdR!dp:&ݮ]!BC3.>{]{ G*42L:Vh'NK!.o^ta}%}q*X oe]d~ *eĵu?oP㸗 8~< 4tX|:M2b[B <OH_(:dԯ 2 C/k+tl[uyϑ{cP q}<۟u]Zh?YH;!Phȇ+4)U@UE^2B#k>+Fy*RZHJ&JZ(sRq,>u|.(V.?".J ૨5AR-"T{2X ͌!:dg`cz:z?3ܭZr_ǐS $u[@*3X\puAJt_葻km}q7uj$Mm^mv1ǧ}~鴸8UyEy m/`o*X|]}Yo> iIs&~rqXF߆1{rF?2*G ](&J!ZgI0-"ǽR.G8vt , ,6 {qFw @SyT w}G7cɌ(1 8a@Կ6@qs=Fw1ؒZc('j8^s8S$܈cwKux={"WС B;5>#^i.a~kmm-BUyF:7L]#x* 3n[U*1i_b>d|1knk/4uW)Qahp%4B[;,Emet îrBkסYAH@xLC0 ; .A }=&n>m^h C=+%BT ~r]C13!#wgs?8Q<R$ OE80F؏2wx6XpUmrl:R<9 gBI-L><>k{) n8`RblwK]mm1Mv8Ѻ껿ެ}jUb\!7BV$2o{h GP$FJhQZ8WwY ͥ&|+! _nUzԜe֡nAd mq.B*:>8U$| h+G+R+9=Z=B>򤴡RLksvbБm]9 Dx[.-hאrVäxƾ1' e.Gtp8c(+^ʐv{WDGyO9:C8)G(4nP7K1\ZA*#v#Om[ %uo-CgSu)IVY$-+nPze!Hi0Ye7ةKz("0QW}| м D؈a0ie`C 9[OPij779OBčk/3dcdUzc\2G-ԥX*kc`t pv3 fU2w}Z9;NPvRiZH7 J9b"\Ӛ i}ۢr}ZϿ$Y昚Hːx{̓\ނиbP.-vnεm{E'ʡv tvw% m!rDh~7 ywLAn^CuB%i-Bcor:^A@գܐm!.oEhñ+Gܽ0B{hrwa ޝ`pDWr<:휭f:E91/b9E*4#!,ïEP>؆| -\BUY̑g@|J1n0MQπݡHvoMסM٩-3!18hr SP, I%:QtA٧~m~cLQ}<)-z:4.v8Fn;h%L9#L9cWrC%Z\[^ҳⅩI*hFW(XtWjQ<)\|m 18qbE\@cY5ʒLWm1&Ơ[W,ܤ]n}K |UױwDh\Ss+OSѪUޢ=X+EjΖpcq!U؄ql]@k:nPjNcקFj5 ~Pck4xfr\\jSv. 4Zu>"ϷzpJ*OV|߮/!Bcq8ˀ3K0,'Z4\]B]c-9bz=4n}pG eJۍgPhuPHڗW} Ջ5݃ZL=e)jW8t) (r1l:HEPt(˽3'Sw7UVxZT%4$m2hTW"yA\8g"JɄB#OcnrTЬ/IEN'y?Fݪl#BS/44:[Y YЉ yҩ={-p/ZwqnmvoC*<\ׯj{s"*nh Dz\(zJs y d^Zpy*4%ȼǯ5[O拐O"=_{M-B{Ӽz 3p2W78`!~Yf|GQFw٭uRs9WY\Yu9 nq ۫Bx]0f>/#ԭ=jUK;7|B(4|dz#( {g:oCj6)w!  M۾cN&vyPhޒ4v_+.|1OBBCf~b,۩J t^<z-! !B!BC!B!Ph(4B! !B!BC!B!Ph(4B! w!B!BC!BPh!B! !B!BC!BPh!B! !B!BC!B!Ph!B! !B!BC!B!Ph!B! !B!BC!B!Ph(4B!ߴиbBCcՁ[/ǯ/JV+*- E̲Xk8no{'`ܖKxVEk@ws ::|M j)LPQRލpz޹] {G(\|bS^סcR$Gs[.63{ (2p=q&lY=ouvM< e570hȹ[6h?r[{(wV_4:*CY#kf$,*\#y`q +]{=\¼ֲwWo6|\1/Έ\ԗ !f*Eޣ٦r\nHANu3\ۿ$ YmԱ=Z{XCG<" aAܫwĒKw"4Ɲy#0((FP|\/v/̭}.._nm#%@[Иo y.v`ڄ(L_i0@|_zY#(K2MBG1ScPOm Myj,429&bʣxPVխ&Zm&;:3̹DLB Ww%4oכ!4.:*y6뉼J3-;";`|[.dAIdž y!ט1 _ ڲX]^L"IB(DE؈{9\xf+45&LNdr5 4sr\hZc[e,1v@w/Adrt89]"M%8Lkvcלuۿ#^ǿBdXc6jE'4vImMUߩ>GfpV`w"4OCSzPhl_G fhީ.hg06L[!Sh;.Ue| kI.aؙi4:/T9Şۂf >Xo%[h96=o߆м#\haĮ,oǣ[M@؛GC . m4}2/wik[uDD*L92:+4c-Xq_#=!OB=&)[1ԽABhM: ؄ Kru*_0GVYgI\"4Xrf[h1x) ߡƣ6&!5DI?1#~R̽[7bΫTh.|kG"47|~ĹRSWEDR"V2f8k>f?rTױ|10n$č8z!rЪ_X<$*m0K  :U~y V c,s/t$<=1gHP9bV~LER8On`EH=c3(݆VWp\ىK}Z v#Ig5p Peh'=V\ð+2ְGVa8>Iű8;|gf^l"yyT: 󳓾2JE-ؘGlyw|xIpT\k]" [Ct9?`G)Udž/bplxB`ꤩCs/BXc}tGj07ڎs9uZeS$:ɝ,Gn@8Hv1D5WCh(Ph;`/JEQ>nŹ#*R}:B$$:-{BS^FHtB+qH :Jh xy$VM3+8ę"=rcwKux= -BSd@NbDL݆4plƤq 'M7CYx|Gi!,<&jlCąnV<ӤaUU&FnBI!C33%=ni:cmmFxGMIcwey͇bC5 \\.6geSh3 jJ#w}G7cɌ(1 8a۱uw$vU B#{zRСcOZk`(f&Ģp{">E ,H2!{0oۇTa:[BSC]'ĺ92 ¦KyPB_kÅšg cx{Åk#˘ÿp너Ol1 xdeCÿU'B \5/[B#'CB/B# IPg0 #1!2mmw@ո]aaJQ*G 7QAح7JuU,3r)I1,<q;oXqq >)`T?:#/nCSGbFؿCW^,*f\iGQ'4#øC9±uȥ)Jۆ=vZ ~"[_m[PLgd MʠV"&ČGDdUH)÷sfuo@-\ǓVaZD8&,܏{ \7 l{Nc]'=: mm|+eNo= quS F Xwhb; r{H:s;BmLfnyÛW>lO6 BOM(&;Zy싮 er~EHvV8\NI^&(C5o6|ɱQyshO6n)THMgN9wAhMRs{kZ,(tЫrq z\v tqL1.ޫ1("#WJp%a:x7P';LE!N/ mXu߉иF`lf'kXq ݎ,}6GxW9drkzңQrfj;gL̳)kG;|vɮ& 4?U.\t%'0տg]gbYc=w\zb/"P)Ĵk$+ᦁLjy7jP|B9-%+ӹSKŊzXM"[fN&"TmS2wY9H*yZuoCzgXWm~Bl*ɹ*᳅h,K_q]/{v&qP\Z%ͪWB4Sdu1Lt1;Ԧ{ŸaXxz}W< I#^[z"`a qlrKt6_b|d匎ћm,Di8@: }] 4u,Gl!yTEbd]o(ppI'&S@wweEz#t  ±+>H# j.[3b0MJ=T2o-7c21vtVyb :K*.ALh?kNdN] ÑnPh95ɘ;m2b[*K)܇Q9&8c{̓\)g;= .-p+|j\@'ge#ʻ,E:[(ӳc{vd_x;]Hhě V*Ǝ#.BQh#*bL FV/\t:;\Pd6>цjmXe3KfR|.NzMrw٘^NuS3yLN.F!6d}.(]:"d1& jZA( YRNX^ !^BS܅l+JVt;L]Fܪ=M6W\85vGA^=VyX?k4:؝ű9ˁbtrvиB^m.>DQM@O\ۏA‘kxS Z r=! LNJID.}]B#[U\k^bd|bpFkK2jjCGf-K] %45!}]*il&WkW"涔9&4s9ds9uojC [hLnAS)'!ޤn<uC ag5 %O;_"4uʵ2 AwQ:䎰?]Mn=͇B%Z Cdho0ug GQ KR\yMH+ۍB KuɘfJw_u1;Av_`9N1E }i zg+{1qo<e)U l̈́Ρ_hvq?T{ :*EWӬsX

4mbq&x0QиO<r\[DI/ӓz`lz.5ݻ[HLkxϝvwؗR(45%\uW'w^Md]1 ]\@QTTUEDTE tłW` ,X."@($M$Lbϰ瞳x߽n[=]̯e4fLm#;1Y:ㅛ9N%፥VWȜ$N(~ Gp Df)uzL3)4ᦿ6#x.gz^rfm_O&]Q4fq\V2s 7Qg i{0L%2| ˈqok4"<:$~drАE/AIt/Fih&g1nXh'Ip_TވE;ǙaGBIdU95uhMA /F֌1 h2OmR:Iw(bY74ִ"㒢0вf6){XhLMh9  hb!n]iԍex 0WFMgP7GZŖ(X{B^w٭-4a'Ѣx_#B{FAӼ+jϟ1a h|@C[MVDܖ,!7 XnoBS 9Zh\VTm3ɞ.R"˙PPbGCzLhz-\t "cu@cBUƖWQaOx2˕*2(,*(%s”i0ڑw@HOd2ragt|ۢK;$ 7Uݸ74tSM`qfӐm6cJ8F")9 ]R1Έ<۪τC3|` KF*$7f9=%*"g3E)!yӄ_YXACFJD6Ftr6=t#wWBRchj6jNy_.Mhr_7Иg{¤LXɆИ Cip!&bhL]o >+P{3{7ЉvpkW[m 蔏U7/UF7 .Q YDgC ف cLZ'tqIx=տ,ƵPA@dbq ;l-ߨ 羸}FMRbh<MYnoSUE2b?`{kzp &-B?MEV͟m.0Nl/֒?.7d@uE3IEP&WdrNpc(keɇP(g|jm$(7L苌'=p[q:q8:TY1sмϝkh,[LOtU%pdw@0(#ohibSҁop1kVĭE x^b:,go+%}+y9"B±lK6hr=(L.)%Q.#& =(3(0gV@Cg9[r& ð$&Y=3˙E@CBCЈ$lAa$:;G^=N7)›#ј1mhF"pӟ嬵0>L;`살x s1Jix%mGI!.&kVF-͋YXsrIrg+3@_lZV%Rl(\Z,ḇ]hO hYdP_Cflc2PTKܥrZ%$/cm|GHb"˙ S'\X W;G݅GMw4BwxYtYp6QdN.^\nq ̥=ANY y ǹaԕ8U h8G`ixBmAa R|v7qsguyX]Hň3`el5, ZwΙ;+Md܅q{tǝF(x9g^R}@=5ٽ4ϑ5[mp︴CØ -P?DN|/JCae;$*54\Kw`j/}rցMg9{t@#mg؂MU3$5'bDDBj)^٪߸`%,ĺ~VQzt%<< +#8h!UՄS >d>^nd$"qC&6AeY^ kZKUش.I[sqVu#lfZ:f_~W +{h)q]%족4v~H<_NRo!25N* ;=> " >)k"($ϑx,dCRy i"6r3q+6ؽ-èТ("$ZY/Թ3-O{@J:wzr=A,h|8MA|MT5ZS~F`-@#'.i=uA}Ҝ h4Z+\T4@"W#q% T0'zk]q8^suhXz\ 13oDic2i&R/UBԣBo,쭒FtߍJ&qMZx^~/H8 = tQIޢM%3c3 mMLF8%'Zڂ7%{xsϛУrSN*ffEuWlVQ Rf|`v.>Rk̊[/k9"DP[G\~KAHK87&`T| ^5nEYǬG"o;2[H gQcS Ik:Vs_QܭnTe;1[0;**j[>{sՍ p!4)2bc_]y"ҟ *XSŬCf 1ྪb~b<~.M6Q`O);w\CU7(P̺lN.HMlj2HoW'w6@c#"n܇-qY#np0R!!, ~09s:z(TlxF6@a<88kW-p@>cn461'&^}CTi\cm64#rpM#:(%="(Ox_?D_FjK1vld4(ld#F6ld46@c#F6ld#hlF6ld#F6 X(7<^}EIL|6qI @ᇨRh*o-Ϳ 0i{Sp7YXS[?no{"YC<}S!iӢMuX1a҅OWQY}}K~d$2Lg׫?J)_:@|qQ^x ً7\Vp",Pۀ.pʫ nԏ4lk=},5r-kI05 T tz܇D݂{ q٥hVK,(D%\,H;vV˖]7Zh;9PG0ވ9ܯW%q@ѧ)X7B)9:Y(|*٩ X'NfGg>Gk v]rT\ẂcQq&#aU|O'z&uhxpLG('gV?[mȻ/aM;#㯡CR'CC ˼tF΁ȭVBZ2 ~&{oF痸_a k:"A WiVX̿$~>r|<Ȑ?m@Éu }ѐ'l2oˡ|lCCu4<^[ۍ,tdXZ9uw_ hXi! D*4]9chpި5(ty'صr?a* ț!oV膲2 Scc< qCnk`E@8JPEe Dp"OW/ǠOq9Y!= 9(q n]0H ۄ"H\~Q ( 7R@^WգUJz|?^"C{~R+[3I "AFp6JwAuuꁪ]8襊>\\W $")2tJcdy-(*y6Ѷ1NO葓{*zW`c=[ y> 3h#Tu^L D(Fr 2`l8TYGw<0y N>n -H/YR_d<7!*@u5Օl,/`@>.H 56 =ʐ-{DD7n#ʿB*y]K4ѺPeo0`Z6^ ,DŽiRցƷe8*D bDH# ǜxLWWPhw `(,?5uRPP_P<2r  ؊yvu;2k!yQ{|6~Qjg&B1ũu+i+"%ق"mi;} Znߵ|<k1Npg$f TG-.̳" ɖ^h 064*ETT sox⎂1 3d#%Snk;2„ޘDD*՛Df$3dxqh}gnbOԒ(ks1ʹ/6@C7 SA4w@CU%j/#=&AaKqeǑxhÅx9#ٔ rwC\ _st+E(]($=Yv|p-NA|tB"bH3x*ɪ:#q"gf`aO4*Ȼkp)9dd=&YOb>Q92rSB;.UCk#+Mk8Ӌ2,kѬDűdDG!iwʶvԔs81EdȜ勉kCxG>^ k"lYAC0kB$!o&sp=CRD, &09'gSwVj8`GC5.ڤUȋ.1qq.^HD(^9N7f] (нS@:ǚеLelQ h:cpZgM889m/gM^a.(*~۟@Bƒ,< 㷣V0j gBeM$e`@3qtDiB3= N<=::3b2'r$FDh6@c|fr3`<i_z XS]δk\Ev:(b74m8:0weW1s:R]?Ro];OhzPQs?*0I\= -i疆iHKی_C;0o<>gkJ0oERu9s E5 De~:Y @c7/ jɗMPT;:_M!m-ר~@d$:;u/"<"J2d. X<|&|TlCks7=9䬪Ult_SPEU!{@)ݙ"QH"`}1\@ hT;^hv"ߺ/Q"y3] ;Q{:cxø@i fE5pY hx+PܩBM'}c), l~Pa C^iN;YX@c;!6r!dT%g 싡7EGL3S:k]fL'{3qftX;>u0 Ĩ=C\:V239.%# ָ84;:|jtP: ʪD8%CAEǂ> :ٕX8q'^1Ik y-;~f9n WK0μf,Jj}#ݤ+7gD=M00$Dү9PU٘;g$/=Q'rս*TeM1xե29(p$Pv8,# NUƼQ`֐K2k*@cfpjS:g۠Q̽cp\hx1Jp-$ ፊCX3 ]BtLLS:8W㯢tU {3 <䍸|Av4)?axt!co4,AJKtp?E`p Cfa9jr "=q[Y&,Šz2- ڗz@侗CI,?ɘ<5+O)7qc_02' rI V8|4fL2\rf~ -5} 1;f:U(ۼ &=A)/Ac88T>N7~TZet~j^!s:RR%&tѧׅ1b#p"d(v.cHփF6Kaşe\/BA 5Hnp[gFS9("VGx%AE,X[9Xz =48⛌y׍5΄Ʈ/%@TW8 TQZ'@!YhnlR$~o@Bc h^'Ip32ވE;ǙaGBIdU95uhMA /F֌1 h2OmR:Iw(;Ⱥa mц/FfX+࿇T_D ӈ`(9QƊ/r֕vAx .APFg`})  3~eX| uq Ul-uG0ϞiBv-W 5-Gi4ͫsFh4Dll5qKmrpk1-4e0e%I(6sB++ \uJ e)|14Wr\W\eƇ֧P*a)+ OEYa`33&b5:|T7˟)|*auMhU9L'rА5]q ;.r =4t`]M`qfӐm6cJ,8F")9 ]R1ΈĻ<kH$@O;ݕcX>yͲڀS8l|(Ǘw7n 4flE;YA;V4&bht(\vӀo{ (Կ*>wŞ̞. =t(ZDAV4:Eg Kn`qn?@2o"O4q8 _0ƤuNC]m\ eiQDq-P"y] pkaoo o$k*KTjF0YUdosgsKt$ X<9f:MY5ʈ8-m''?Ԁ틡./ꀪ&f3BȪT0]qVL3Sb514sZLBU5XoWc* 7Zvt:Nrmؔt\Zqk簘N1˙JI_ o^p,p%璍s4Zc3 ӷ~K @gIyEɸ:EʷgoYi`0,I=rVrf/1D6Ƅ#4" sPXvWO+M (H4fLi:3zi \h2g9k-&+; +y7^Bh\[<6>(bZ9|/af6^IQ&kVF-͋YXsrIrg+3QoͪV# 9KP+U9sò m]6˙ kȌ@xLj)PYΜWqILd93ݗЪ }jh鲜)am֣Ȝ\~ZH{(.ųFAdsȩ+q Cqa ,ۂjDo 6Ϡ-(>仐7g2>4O5.ְ_L0&8j9g@7qvFdhV&cDZw:Ǣhe{َJ#FdBdSߟmc l7hhW͐5f- @C5Zm(_ .ky%xp *>EB҄T7hOE墬 E}c#LrǞ(˱e7SN= G^8M zx5+)|} 84 d~er-="rN"‡860F~3 v>S"3j2wQ5R(UA}G&`>^P+-c0q./Ε㝈~PC%mEXOmeNl7ÖPì[PB`msZ])? ~ːuGYe ~_?O]W=*O Emd#0XLȆ5D8s ο ZAq>!U416w9A{w/vFLw-/ hld#F6ld# F6ld#F6ld#F6ld4%0Jj$,ϹW@Q|(GaF0#m3_AMc<}!mc48mFL^"MִCf'~m/@28Vs5}j9$xZ._=< B 7j6jK~d$2Lg׫Tܾơ;R>[+6E]jkNbe^z[!UPlxsjXy'(t7@ c\mŲ*4eP?@7)U9Yӿ/ئH 5 Z`bAaMXxzaC4vAШlɣh4G?2 T^]X;g {{cnvfC1/faeHؼE;z̙_bsG̥vmj@B?X+Sq~tQ4 @&oϏR(_p\#)2B"-M(b#><6G*].WAܨh{;UgRԭ\wZLB%ՀcV(0{rb+wFmg#进}oDx|׫Y o۞7v!""^)1~̖_lKC$ls '7Ü [ޅH)ƍ+k 5[cH;Ѣ"$z x5 3x_ b +6uCUv 1ɢ5|HCRաqKM%,)<6@Þugd5tHJ4c(a(w9JHR4|(W+,[aMP7!* 6r kҖ4v3Z h~8O8߼ r@𓍠^fb7nU`ko$U.X\A}=!`kP!oø\*PhɁP}C"1Lbхpd7 7%셺 eeBߤfohis8NFT6veYQ=HK0t1S\t֭gyH/GDJ\{bw4 +Eʻ *Pc)aNs7_lF:ԮBax.+ix-7,ٯ&_JYߖTkU.6ofx#r< )'0G@9i*EPY~k ꤠyeve^C$2v:l852Ei3/ބg&byDũu+i+"%ق"mi;ƾ\-ey^CZzZb>֊5{Q`io}rYdKj164*ETT soxǐm8Su)Z}Dŵa}oL"nuud՛Hn/kw-Rx|lV\o,7JoqwSC_:>!L~O$CpgJP% 1)G2s[-"+]f(3ÐR(v+&͋C h^X{ /8%a bs^8uGDq)!B ^w1?ؕ.Bu~ &cAuHhӄKM/o`ךh,M:'_h=9p$C}HXTu+Qw7-z^s}QQEAD"= dJP c6}J4a1Qlv,qN؋4rKD\2ǒ r~ P#3\ G*Y @(:' .. ~۟@B˃,< 㷣V8e":'raEGBG'8y`FPo"Qۡ|k(7tp(!&4Ѩj(7C;K\rK~˙vԒs=XE^ \N*>b×08euď[ fWA)!/w܏rʜ QzPg:{v%B8=v$祁zm/s_ɝu7o5dm%H`{1`h]ΜsQM}?D߁)aeCZjeS T1}˙vk1XbhlWggEGDOkd. XyLƩ':U %2:ozsYUX0dBTR3#D9]( 8do]_&doe $E17Zh,e*|>~BuST{ >=Cb< {tgˋ%PV1]|3jrvu<7r/;Oݾ6;c=q0IY ?eo.%fC-jn1E)f6]4?h/( -+PQ2u/Ѹb%FQѼ}r,(./,dǡQ@u88Nr֎B-Sa8DOaG+ sFa+pUڃC^O*fҦ3vg_j"Z%LLFox2 hhMQ; 8J &\BF1Vs;lA~T^AV,/Q|Judfs\KD0G5Gi:/-j4 NP@ѫnı we;kJ,8Ǔq$5F ⍼f n"\nv i7K˫%gB3IP5un2 7gD=M׼pZ h'!R৪1UwBHd_zNH)9{UF (. GQx>8Cy@caD ʚ˜{"Jl rZfM_CȟYSmJT0Plg{Boq4qD)0$"L׎èWIPy&AS1I`):K8177C KjukDFTA2kHžtTgϼ2"}H9%h~s`碢2uM f\<:f_ \4;s<,]R4p/m $:ʫR9Xtšz5ű_ h6n}݊rl4F.(",!tAA #Z@#n;+ex2Fhɴ:7>( Snt b[ZHXkO4kU$7֘73/.gDix)"c]{(q+;A3h\3ʠ_E,g@cM;4.Hϲ,gUy1X0ogΤ;E,~_@=_D> h R25D {_nGT8dSBRѯ|iJMySC45o4fs7_YΞ!g|,YRw~^)C#rԊ#2sE NSE{$^+++y m5q[nl5,4*@ca̺z M6hqYkR9ʶ|~&{bJƊ,goo*BBY!u gv;Ncf& c_Q(RO\n bU} 1&{E@΂T7T*#CA~|PqfṴs”i0ڑH-4_XjƬbׄ.ۤmwEXl4iMҾ4HJNBwFzCȳ'xo4LCc ko5,xDXl(eZ:$O}+ k;>Ļ<k yGz8Gﮄ+ϋ 8դm=HaC9]vo13f+:ۙ 1C<8@CMИ4~@N3}W@U /,g7ЉvpkW[m U7/UF7 wY '8CbhHc:aK`ie6E 崨"k?ak.F^8ŵ7Є7jj ~5CMh*Xpc~#*%:`{kzp ,ܯ-/ꀪ&rs[} XqC,C=p[q:qR8:VTY18nwH"I:cD\[&}\C_;e9m3B`PlP:ehȑ?-ǖAV!v]744)w7+"}5h+ޤe[XsZlJNrg砵fVj+1sǢŨU 33v8Xs b"D>zw#ƒ#b}*FA qSf~TlKG8`$OUv/U60Kd.Vgvu2daTTC$uck E Q0b^öY:{ "#x,gO]PCb7S`@t E5%.[ H:gFħl^rkvwZ~$ C` )E BtҟxC}!\u{oXe0 rDjb<>:ezV~evHsH]Suh1@8a^j! \+d<\W~. pRqz~TH4ШRˢ#u s/+%LX3C@cb,z≸ WV}6@AMxɉ]!MWf&jc[94Pء/b~ۯUBn4ՙxF?-'s]Y17werE "տuMh~Ըcx;;Q ~HEMxssA|*"_ oQwr4:J8]wh,L>VJ=)l_6nR{PT~/Q2 Fyp\bJJh6>ǩ PC8т5dhf^öl_˔d4q>ic%Uuh gߺ&9 uh@:)"D=EcRQ/)>-_:kf9jС t=ʣ3/B)Q{gEV@vs/88Dw3Х~/@ÚRdJ߿T@p!Lmދ}(cmC1z|np~1)]$/{*XkS:#} )PwXi8⌋n܎U ~־4rhTY$x*yI&=XJVcgL0bAN~Pw ֹ[+Ұ?y φd@Ri2wSh?7u/i?d4,ˁ}Ղ؎lgo֭JV5g!2Qn,;Xn_@3:45A+وw'j)yv sgJV@+YJVd%+YJV@c4Vd%+YJV hd%+YJVd%+YeI ҁ}0 konP-5(HIא~<D(C}TVVr7q,ߕmوi{!+~o@Fݾ 5>td/I9L܏~ Qk-f#fWƲĘGVYڍ͚EB*} r|_I/t}rkQ~9 F.e!v#܋e."]ރ5]\!k.VNz?,f;A)Y8n֟3D*\r8/;ү Z. `7I5EF_:5-Scz$gJӽ_#c:o٘wȔ E,ٍhJ WT;1VglN0E7 "!s_TDVY?>AnS gm;wFOyk i7w[E Xvv7z5y.ehT@րB+Ш~LWe6e hr޽8I@c.pKh8·]Pt@K)_@#{1\#fD\xl}a!V~W^D4Lk>K=Gؑ,nYJYp*aоJ~"drdY!Ƌ_7G" %~1G{Y~!XyymnUg7"pOhL'Eڕ s<әzO]om$3Ԟ3ڗLy݀ܥ,q`*21hH暿&YZY us&z=.0>Zn, z3z >z˙ƺ"iyhѠոwh7R-@s˷jb_ʏ#B=ŋ#*j<8> DY=C+7Q+E D']G#tՂ;8\\ A Z//&cA:BP8 JCcX0!8 Tz/;~^N |]#0K3/u'oC#{q  87Q""k(F{c5t14[D>%'W]QZ ND#~ZdUȞׁΫɇ^{]B![0M}0Ov~@[R7Cٝ]vmh[9ORL=ǻbW> UyQex)“SF4 !^MXx:h>ls''SÈ AdTPw:X]^ h:!"JyúU{q_؋_*@zLVdf֢ NebsdM$Yj,IԱd^8Ju0 /lF@/? 5gu=e8QMl(\l!kx2YN0ldC| C/ދ g`o @pf!/_d ED¼}qX5RTǶU!XzdL И苀݌|do߄Xj3rZ!ylx1Yb(ipF9Ea2ϳh3q+Jx@ih2e| YXg,\Row$RwjFL.O[AM ˤDN>@Lqav[:-.gk'k2ucfQEF n{hM7?LግUA=аS H(\2s&#M݃8o燿j*"9g MqZ[u4eʐExr)|~%Z9DjC;F}dD9\ag^oSl+74R$ Ĕ2‹XR[LAV]/CplVت^ڳ*%(KHK?l SrQn]^F:|INpF-'@dEI ћ9輌*@SW%FIeDi)rŅ`̬Q>,p x;Pq~|lG fHIzLvkpM$#G|o,ѵ`]FBܗO HÅ*4 N4P)q*fНFgmSM܈=$2N xlЈp%N@kqtO[s7_YԛEFxL@bIqxs݌&ta:#ie1 > l`k|D*0K;[pd]{A qE@Q "EIL3iC3t4۱ v2g-%R&aj d-4&lsm2TesT? Nw+g>Fx;@ClA@jڱ@1Ccr*.!:`&8?4EwW16&_`5f X_⿺6$3/\?D֘QT?c2n⓸ 5sd>Xr#%5oаSz$nMt`t#8s, ^4H0uDV,zE_ `indz4ny=r4.(p[u eC|Jֆj@#lU?oUH8y ܒ}5nH 9Q:$_ct=9GfS*] )Ԟ Vz)x+&#&e( z$#J͊A*饐7Xk ) {rVeK/l CsqI~yW<%S0E=%x- s0}fTH/5XV4 z ?TJf$`&k dXeA ݊nxAU9iޜEE1gEz⩹;F@Q̉nOb!1ݎ}4ϲHՍi[C]Ly4&lB Qw{Mz>.F^H{G! 1@Ù|TBnp~d )SNYߘK @c߸[ф"3ex[ -6 3AC7Vc!R3mO~g^7:}2]Љgu kOn_(}ĉprr"4k : =WG,Sz$@Y&swl$+q"> pX7,4" R߲f2)~$,4R'ZGj h,b!nsI7<>э_qc/h:@[K[|$1ꚵ,?kd0-U U\Zu`0'?(&BCk<цVskBî4fƬٛДb8%Q{3m-o,rsFB(&Q<|^c {fv(NOv]L@j&rو; ]ω[9Ge=c. Maɞ#97XhA:@CkMPl3uoGK@nZ;{@ ,6Lup|(GxAtĤDpo4I'H8!R^7 3И4Ju 􇿰4(%(t2Q2g3LJPs()FqcFt#vGo2T@Rh6K*9Fǥ0#C1[Ў킣~_~6FdhSlG#14w:~>DH?+a?wŜNY|SыG[5{tpwWeGa h / 3n p/Ҧ9C,bhFͮN܎o:aKJ׉S]u\[q k=9 꽰maoo kT%k,۟t!b7dosKtÑR|TY<9N7Yٌ!7$4Ź{.gz3ח].u(  ( ҁp\`Xt[rI1Mu&-S6z$T^=n .lmyCBrtx!YRw? 'l=xr]w"e%VHohib(jfI@ڑ+xY`,ghr!sLphyXE1w4ױ+&ZP^T 89㣇ȸ+{7"k|LTe0ReDBouq߱i3QWZh/CvlLEAE;Dr]706kPT˭Xk} Y'oAp$/7Q^j_f l7hA݅u+)YPrc`3\S6/UzkTNN. +w& uґK $1̝==? qE|~2= 'e(9pl*ggG?f93,HvӠkc<)/<$ǧ p!\Z<|&">z7cF UFKsH]FeXL~D Ohk4:4p+4tQQh*CAv4fk5qm}0?crp¼BV(yHVA}:5]Pq7Aig1/ QYRˢ#u鲟s/+TԌ ^L!11fp=SD܆+]zQd rD[&+]3qezUX-rЍ1P*!}7^\DL<.Ƭ2hD\F :&{e^4Gj1o ֝(Fn&HݠA>ѯ[7Ө;[@ g#+W\h,L>VJ=)l_6n0{PT~/Q2 Fٷfe;WUB9Nm؅ ű! @æ/6}W+Ҿ)k ht՗|<:4 KPEj? uA픁.AYs"jX~&+fl|6DfJduhYҷh!SBZs l1a=Bb8_aԔ.M=g, )w\Cþ~}wq&]~4qvw7nǍ?k_V94} Rd4F 'b"2F hq'mG9T=BT~m@c ~y}CQy)p>֚e)fej@t)Kr?Ҡ>ljlOE|YlcA_\x%?HтGbl9bJЬE@K5 ^xX_܉Xf~{qEKz69nDZr<6ĉGU8`]jNH-_> S}eBWbȄ[æ3m4nDB?͟\+u`CÁ[uȏ`Z}:4q@\j;c4YwB8#'Sa^@#սNȩA\< ~$z@\L5נp* Vp k*+@k8TEqkNk7HDhrԫ LYK)qAu`dqG#iZg"RʤЬzE2gx^ւ +r4lCDH6<\,>-BJLv,") +bo@Q{ X a4}DYAPg}5]}* 3uE. A q S;qB1݃/WўEۑ]j<8>SY=C+7Q+E D']G#tՂ;8\\ A Z//&cA:BP8 J9Z,Ʊ:`U.g, o2^M߃"tps}^2J}P,݈7rOJ^5BTw)i(iXP,Qe. 8P\8 8:)ݟJ0ZMQ+㹴Rfg-_`;~j~$h|_sq8t3yV7 KH#m.a h8(<*K)uJܭ=tQRnAdܫj'|Qa-$M#b;7cU(LS ]]\:vŪ RVELi ޴ےx7F (u4חy ߾y()mΪ*u;)UU90YlKV`|aBpMXPs7 /et—ܥ:24Z}>17>wPABz\[/`]/h<|JґO#,9fm2#!Siy pVs!)-F Xɏ!!Ic}4ێf?NS([a˱ = ҷO6ߎzO\1i<@&H؉oD14\/$!;|Ńk sҟť /x{wŮ4G}02S'ۧOhB4":u(z)|s''SÈ AdTPw:X]^ h:!"JyúU{q_؋_*@zLVdf֢ NebsdM$Yj,IԱd^8Ju0R /lF@/? 5gu=e8QMl(\l!kx2YN0ldC| C/ދ g`o @ɤyCZ/2bރZUda8,)z*c۪J 2&JhLEnFa>oBԊ`,_9eݏy6ZI(W@!|}]%78DDC;p{yb?@V6~1n fl(&:Ң|58¬@۰XL'mÕX9򜌱L Iz ,h=~7%zdlAdhr_CRYq.g%#62AQH{.c꽼.ys>}|gbE^N4r=ո2%=tJl!m Иi3rqA|X( QKIϘ1C:-"|x?6Eb͎Kx#T=~u;הp&2&w%( Z0Ǜ2!s2 dA'QTi:0MХlCqƓ?~B`[*706}q11ĕȍ1Σ15,(Z?Q>Y/z>K!|/B&ҵ)'eh:4ԣÃ\@XV):^lB^O(+\=g)H@SVmr@ZmG04*)V[Z%C;&+F_DOj…S5w !D=>kB&6]D 2 / <_CL6C93/4D 2GP!P`:[/*c9+b IaM@^˂V!9xU&.GFA9j4RáCԲQlIx#DѺ "P}%H ˯?r>9䕋;c:ϊ?RSswʍؗ: 9D>B@chŸeOh{^CdI_hLYWB@no=I'ňu٫iZ+*']LP>*C!78?2䯑1g~c.) q'q =Df:` fZlx3 gLo&t)t BGssi+˾x~F:&d hdCrX r|:<iiPDNO[mwӜ[8}6ylciypЗǮ]~/@M iK vV_C/i^ p[h^0FhhFаИ4* aQ"|u_T4 Z7:De&$ARE_SfL?A9%͸5n69/#I|P'HVfCE} trkKzqVoY3R?c}-H[#TGyFg4~1Аssu ފRxlTƯωƱ]P4F-s'$1[?ZhE5fB*M*.:s UY͓hV5hC5dgap3c[hJuK z(=oѶ7d99{#p{!dJCpPwt)C +M h` ˾\6-7pE#(!q bdtβr,Pnhy5.֪aSL%fΞq\ ,!|ws:+v YhصZhN17TņiÞ٘(πѳ43‘#&)'_"C6xo4,bh4ib(jfI@ڑ+xY`:,g9h-Jo lܱhG1jEb13v8Xs b"=FШI PDU_12^FBR$/rf/{e3lL ޏ'MJ4nPf=d9~Ŋ)GYxb4Je.LJ@l?NtYq. ѲbLۄ!ZU9@ې@ǝ`GÒ@$,B4%Q|]11A9o=D]ٻ> {O䠆)3Qx*^6pYW#h0f**%2z3PsVM;E{cte* *!뺁YC Xnb^öY:{ "#x,gO]PCb7S`@t E5%.[ H:%kkeS6/UzkTNN. +w& uґK $ov_Lz:W!6dbL׮'e(9pl*ggk0c{}s<wN'174˙⌎ſ"&!Ƶ(>sߚ&HBV##5Ic7-[7-Y9ؓ@rպͱhfN*$%: ^FB@öݬI\@M"DYo{{0ԡq؜;l&}Ey `.@Cpx!iP5(g+ШomF]fx. 2MUe(Ȏ {5C[<&\#ΣT?}L.NZwB43 8)* 蕣_v0%!&x}a1/ Qi+mEGh?q^WJn3* 3r{1gĘYLqv5=lF̛-nCt9̌MUbǶshʱC7^Ĭ _CE(hxq)3~@[O cbn!q-6D?z*qNw<)Xw !uTDJk;(Gn=xOo%鏬^z90,J[+Uëۧ}@\AYSMBGcC0U>!q]+*6BQXG ֐ay ۾i_˔d4q>ic%UuM gߺ&!΂ AYs"jX~&+(>s"3 2w:4<-ICA[4Ő)k^}}f/bt)?g+-胚^5 ؋uH{!B:z/ҚX` mù দti<+cI\]xN# 6ܦ@ݍ3Z3.q;nW%xYSeMW'RvV@c%+Y'#{o;1Xc>ܢ(?.K4v# TbA*1(+` jЈ QA%*QA`mpl-y^|N{eJd?٫`[ '`Ò>!aӱb9ԅ]o3ޡ5: Q2qN@~_`o";_>ͳruձWwuo7FM]/gƣ/M \z Ur<8^>o'x-S b)"4  10M&p30#, I>R#lmV]~I=*hMnF0DZ|V-m(oMšM36TB}IEzi5mnDAA?p,ۧv2.D- 7mFӔsҦ9_XS^ә76Q_Q?S61%H6bp7V7naͯ(?_wyc`MX3ұ4K۝EW$Buܖmu[ն\@_pkx0hz/' L7h+Q,mD/O8Z_dQ!f+1*Ee~(`qVzy].㔍UqrpY_l]zScᅷ0#1c>Vl>{TtC,3|7^Jqr +$q?hvզe-wк 4n֥h]XsL$،0B0*|wuyK@Gisa2茋i@m*+Σ该-%`'_]}s95R?I7z,lh@E1 4R_Oh<1fMoeCkݯZAQ(bw'oKږ˿w9t(= gC[w 6A75^\Δ{bhOw\]Ayѱ~C/Pw'aph\}x#x\3Z-%0Ҳƌ2xuxqgE#:q;+ :nQ^Fq'QixJ?E>:4 CS{ӼauSYTrUסF,Fköb4/h;s"|&mh0a+w_R*,|}1L k'pe{#,ոQb/Ыc~Esg9o@ğd+FȺ9 ̭9(|U#6U(/{C,%w[it9ݺ}(Ui T>ߛ&{ 4#yr/,G/w nE{1ZKQ-hxK;goӏ޸zJ\=v%:IXFEDZÈw4l)ByK>e_x}0Nbuەt=Gc3C-4~H~CԸR "@Zu+%_KT1vKzMw51X?^TN#Nϧ,{$~'#@h3BmV+ 4: 1W C& Q:Tш^{ (Xm֟.kںr+7_Vƛ,,[J5b}%DރBy1Ҧ TYglf rKP_>2?c~*sM@˙R\ռDZu) jb}xGP 4CdxϑIֆrp:kX:tSW<H܀BMčhbS\})mFqUy.`s̏6 J15c+N?ByoE݂˜[wqLeY$_ 4(ٳKSQa6śWoo`%{OC|o[3%&v|*}vt-vܸWK*M״uiMwVJ0<϶^7 ֶ%EDA)jzC~Fq.J*2eX:,ǥ։S]t뚈 5șkֻm)m29j WJިkQ'WOMB9QvlsIMuG/S&X?KqݟԽ(y=ۖCx+FPuރNuqv)ฝ{Z A,NraWz]!G}1kE&.X'CR Bコ|Ů,C1n=UpmyO 4J9 c1mNxo#S?.Dno6#a&BQDW7*sRV:g K=j:{2&NÙgޞ-ܸL<dž2?ZK22 hQM7:腠0l@#.]y'[Q{[ڏGFxȫF^r_Y$x}E5F(/۱zLL)qTQ߷}v=\`NTʲ~F9\ ېC'xF@,LOc[9i> i 2s N t k.ctLM>BqTq-1eESaշP߀a2($!n l]wŲQg,Vby1{J1o<֌NB, t6d%hsP }R~Qt2-9(ğ ;=%ķz BpدWà^?9o r-*g]y 'x#$6jubcy Euwg&nK8$ﻃj${4O.3C1qZo 4zhjDR(zwb#k>Φz8 4nGb{+;LAt\*NW$8=r(ۖjGZ_I;o؝uVSc| B=^]߆шKFFA {SUoۇXlhL_qjUlp׾Cg؃zONz9  =:ZÜrfStBP]\_|w9HъIڶ˙_6 /1z UԽ츜1(5;}iuYl7=?˙1Q6 S45!`kbC?[֛Cqϱx)Fn cowU o1U^*8ߖd 郔2P3^s*3&0= h>_^{Z#6lx]^/K"?w@sq%cUN~ îZO!ܮGʡP,ncg>(:©j=me}KΟ{/-jS_; B$DI笝 d !yߣybRی Zm9?2δr[&膤<#b9$O- 4Wńe=߁0OD5TnVJ NM]40CN;^ :I-%M&g[uoITqߗh t~ o85+XʜDc[w6 T)0e\8bSNFu!Ft{y]a.9r&{mKu(Z?q`7cz(Ev"xZ}/j۱#x@c.tbphw瘺b%v6I]ץT$S=sۍ05@uϰ8&zquYwŜ5^ ~] |pq SQ =8~J8:h- j+cɠI'428KeDhRlh4ZhbW8V1>O~n%(<8}ڵxkfĠN":_c;tP`C<g$oʟJޖCy(@++lNԯˠ>=>~S-r>Ӛ@±Xo@S#+]^/YKғlnX[ ؼh2B;8+aSC}3=ڵ:xEG|YϹ!PAk Oj h0nh;4*̿mAD]a5r.ׁxEB9J WPάeV[5P1Ԯ۠[bmFU{c%]lҵ~^P.Y7ch4%^@Mu9TU[um2ٿJmh74Z,@!Zk@L'@cL`=fUB/ўh#۟:Ј6 jt֡[w"μAq*2zj[:7$xƎԟb[O,ov} F`=Zm>V4]P.M՟e8ՠ!(C6X́+`]Wt5gÖnHxШť?T>}.lYj~XIl}}#T; ⸜v9QavǂFK\HaM]Aۢvϭ14N?X50rVqc lD;x:7 -ohk}:<<"hd14kPP) ڂBmSVe;6+jSZgZh\V4-dLqSdjpy!'w xe壤RFy-Ӱ葄j+qjVGόS+[!;O}°{d( sCw{ofD1)Ӡ w+)ϺH='Zv9s}kͶ*иg8dŐ:خdkirgsnXE_W)+(*4 wt4l]ݤ $…2ԊuF=gol={#]\Z.耘#w#tҮ˙ܳrTgش/=kMSW؄@%g@kwì4(/yT7,]^Pn{@9uiRӀo ήa75h価qhLoh4<!_LGʹ?*\1L= uh8xD *#kҢvy\N&yR%𢀺pxњ@Ӛb߬xCl[o"ڦG5д]^/14}(WݾiPbgOkhlǯt2oUP^m؊y c~}C3~?h"#rC" ljkapc6 4׾|15t|k5oMܝCyohm}\C]di?g5[=ӿ:z}ӊYΔ<tؗQRؖ.e "ZXfĶڦslR6lPhR<<.9EEXmFEkl[X_ӼMeZsMӦŎ6{kS* zyw,LZ)|?g,א6S@@9ch˓aPgm0ŢyRnuhh]NhR T']9uq<k!oNaN7%hFmV_Yf莥W5xd"^k%sϭ[Dz:yKch\14MȆﻦZh%=˙qMC./\C?c7PZjXkph,ȹIJ:]q'PR8d8gp.ӷqI6njy\y/IP89އ iQ;"{[rch2M!14z=M|pr m1[k6Z&'A77nmw&N5;!Ϸ 63m~bCv6{(ok3{[E {z,gjhEhLKEvpu3pd蠺 b‚}((W9|GO_ڀkeP@=Yf9>Y@Kα^ҁؘK?KvSN Ս =+ [`W|L+UFl={T,?ίƄ7(}_a-Ò.AUy P8f 4'jL"ܝsغԊuܱ0%jٵ{x"R۝cWL<*QfMDt\,K?ӫ G~ YX4.ԭ5t \sfMFDD$l[}DKR,|?}v-XW _Bx:7"M k<sW˅5PP/T̜8Q'?B/zGǟ+xl=>xaEdY<󓝆Iјp+LupK]9$r,*g?(И*cLXxv ׄK6Xo ⷝGkq[bC<[0h4b[<oO1=_{X<c`)(JPm]Df1C3OAiPʘ>ַUS]#]uh$?7 ÒRl45Jo(Dy 6k"5*%> J\X`|%.,4N۠E]S>!O| -BzBЛ& \f\TkL\2E 4]bn?#3T b=*Ǔ}AMYw.)֙ZxЈiL :'Wn}_D{ ZhKgyRyѡm1E':~=zjX/Ɖa%zDlQ;աg֏G7eK^64}RQMо~jq-hjJQveeg5Tŵ߿@#[o'6WW[jl~=VZQ栶R >ؿ%MإI}(Y]`J%Be;" lf!!1y% x{ySatX.gPy['`M/7UkY9:y ث;vN: ѷRJ3ߗNct.=x*A]]9@L/o|[{ BX!~+ 4DDDDD@@CDDDDD 4 4DDDDD@ӺIo?8/k *yi- '<({ vU<њ^`cZNQߚ Ӆ5=5fm8h/6jq5O܈F%كXOe\P6[n4Ol90hU(̄6šμA.n)EH,H_)A2#oԸ*yMw k~-@I8>kJ5=Y\]+"os\nCN[5E4T Uxq3 ٶ5=Fbl\yXzC"r>cs/+u˓߬&z!QrpC.yڶ} ny8ekȌs2eX*1Qw )֥Yx˨ƌ@E1 4R_Oh<1fMX-ֺ_w֣P(jKb[~HWy }Y.}.Y?kV<(/sdXk0!]Q9}"sb]H f3A_lNFX/ q]2:6V ht%8<˺k8.KðX%KȯSOa¾R4i %B#s(6ktGMmN~4I?L 4W~X[J~{Kb[  b#Ge@z@ .iÊXɇ6H_P&Zm(ѕ!ˡ+yvO@N lؘ TW-.ƣjhJ9S>'&gka(ي*641sk _Ոeʋz ]}V"],one"e_>JU^H Q[^ ţRT Z+YT0W~_ΠDUח038Ԩ(؂@k9E(@zۇ`xF߱X`[(xgU[v9hO"75,|?SPRK*M&[,ߟ{/*PYӊ}=Jy\vx(*hD=Zhj^Kk&`BVi+~mO%j5j)²T/.n[⹞O=xz-W{:z*m@5^˯zvf yH#3'w1G9B/L})jX\U5Os>]%,]^/@c:Tavhڟ#lN}]ǛWxt*z +o,H ]1A)GP޶@QqݸV@9GƄ}glG(ͣH١IÀU3} .E5*K"xlxAɞEX|6^bd'Y-޼ys'D,YcxS/N_ž+-~67d#Mn[q=8qTiճ8Pku3JPUMŏWi5$JtJÉRԈ\}y!N\yḏ6u/YK(8?85j3T[ےccԧZ>wVd|;prFwL>.(1t`φ>2 x;wh)Cx+FPฝ{Z A,O M&i~@ej՟iWH~@+_+g"zDZK'6?A1w kb%G$${_`+ЯCz[kU*\[?ewaXL[7ȔƶǏ [ǛH<ɇPTó=Qʀ}xlǬkq+CEi8R,ΞIp晀fKq7.5!ġ ďL%ZT.y=z!(8 h?,Јb@W;b 1cT^h(2x)򪫑W~<.@#^)GQex4Kqv^0SGaʼt+bo-oC%uG߄dQF=t7W!6dP Ŵ/$ ӓ0X+!!mDfWa^־;hQ[xKN(IInZQd,Q?u]} i- ObQL`۵xw(Z,|Ru)wS0fJc͸^-r@gUA^RFl;+Eg+咓HBiHy#Oq};g p,> #:Jw/I\hW 4IZ]9$e{u~[.`F#2:ZuvO^͍dgO ' ˙l-7=4p")=;nu\5l_gS=wITj7ߣY⽕ :.PophC9]mquWأxF$L7Pi:mVoChĥdDP mM냎=b*7w?A,s6`~L48*\IikxxA`X'=ɜcaN9|3*-#ĺp2"dc}кB{+mu[u-jQtYz{>:x 8 *nA2И`P7&\e1}E+GH' 4{JGb [RpӛhT0v93; fZSϠ-ބ 4јc7>>݆QJKMN7ҋSAa 4u85=nXȉjo"^{%B~}(~)x ɜXşyE~mmCLPuy z+ qrhqޭgc|(2[hM}ϡ,gM=KQxp.zk(qE>t0v&;8҉) 1Xhs\ ΡYZ 4.kӡ8c]A,x^v[{KZ4b=kq"\ȳ|O+7nxs S03|)?hJs:D[92#]E&݋/xE?wh|e /va}ݿ"_'q7m‰x.B*M16 ebj1K7W 3Z.HC]vO|]>s4v<7LO,xblf)tno}F`=Zm>V4]P.M՟e%8!(C6X́+`]Wt5gÖnHxШť?T>}.lY2ujEXIl}}#T; ⸜v9QavǂFK\HaM]A9MkG ӏ*!q ̳eaܘ1N+MC9?b ~uxy)4D+o4k'ch%޻֠^'R6cڦƗ9<0owlKS%mWԦϴ"и 8v׫i[Ș8"bɾ;1kCNeHGI b2[NS+a# VԬ& 46@oWCz /vac TcɤQZ巓4ẻbSAAjV3S,uבl;{:NֵrךmUqƩybXlmG549VROMxZ>(*4 wt4l]ݤ $…2ԊuF=gol={#](V;_5*VƣJcgDG:bz{Kv"<ގwu2`Xo)ߔTCL= Sx 6(^NC]j3柯53Zu({f'}}I,O0*74:e47h価qhLoh4<!_LGQ0߫p0yDB;20C֡i@97Tsԯq Mw oO^M+f9SFl< [b_FK.P~d[glKs6N"+uW4b KHM,>6 zǷ ][D_{&hlDei5b,aw]ږokŲyM-jblƲ 4N٧Mmki1mT:)XS~X&!m? 20L?qFrи 4kS14>Cqշ!$R&JukmQ>T 7_AS+7B8-)!hӴ+NݱL6]k-[܊O[dmhh9ڮ;C<ЄlxqM_b5|F^ҳy4b53vpa~gҰ{N,Kan{Mɸq\[)}C2t3U8 O˸Tzc7|u6_G١ɒnZݾQ"n)o#e('c'%#*m709\PMC-%7rVB)X#,g׶NVK lwh]5#3HDU51ѱs,rO6@eoc 4 ƅwN:n@ҬɈ-yx/Áhz^eovq2..e >W@Xb}= Yiz([k&5F1&90G#f6\{gNV14H8Un 3v_)g{x "_zHCQ.Gβb;$DHhL1Ν^FlW-hRP F 5ۺf@c^f*6j: eW1|o߫..FĻWH ~nA ?%gAhj^+0,;Q:=mtMEjTK+ }*\x]d%Иުxۧ >$I$WuZhUQIsߙcq2ǣW2տñiNzY1ɘg+o g&otLe3rK@E_@(|5(u˦ MmxjдrǬ;vI7wȊ5]ߐ%8иG^9x`?ޘ3OQ# lhnPs9 y%PԈFn#!v-GMO1r~=z:qmgsn7kף@t$:KxhqA1(o7=XyoԽsWTxVCFζW]w,!bxj\[HA|L&͂(֘֡eƱ2tWHC3nv"rKXLcmyéuGOy̓ 49omgxg&_| N,^ v1eȔ3((y+ 0hUx]tfo1ȣO* 3:1CFwTxqw/jh@MqĆ>}rKCo~x\_w1>ي^_>V{8p$*bc&md'G*l#~s踭o`9…]˾4E.4׺-tMi)5|JMzzC# }e|t3VΎˆO<=B >>jΠv5A4}ת4iAMZ4]jAy|)jjdtE͚5+eĉEOzyspmPә8 jKЄ~Y4Θ!hAԾ)+j h2hWJnn'zyspmPә8 jKЄ~YZ4Ψ!hAԞ)+fj]QCA)fjlФiӦQ3oO^jXbt9f7O[5jhQASQF jSTT p1A?A!h4@ h 4P.ګBܯwp6߷~-lPc>v\N) . 5#:g˙w7ks-ůQa.L[vM%ʻmuJV 1Yz-ذU:}OҒܱbJ8:&(#|}OYAa^+G):gŖo0qW,g/!A&eA=6:)c5je|=Fm[7K v(=KҨ=\>|o@:z-Sq_7[<<_ҽYA7/OVVA_ui.O4AFpnO}:( ܠqc[^,+h~SM^iQ5nY@+>)р|G64~He}uҌ4U!G: n[wޤ=s+=+w҇_ۓ ?Ƶp@bZ!{Lv ӸZj#-q{Pɜ}1Nu<'_0(Lw\V=͌{K)y|tt;Zt㴯Ƭ4b6, h7'{tb bNJ9|Jb8hwwd[~jQ? (?ck\ SVĪ{SGrIl)T ipʙ_#yw@^_}8n%ߺ\wԉ#>ީ7fT+>Z/裼E|kel\ߞsr6pƹ H34X[ b*4g)A4W)zg'jHe 1BgyZ1cdijgW%=]ޭ199s+Urq̜QIoq6߫SvvF߱L;:b:ƿuMWzz$'Q6Sٹ2h=U'Gz|qDefoБyfQvNx\+5:D;ZVzc {E#(ǴxcB}|0O7d+{D}uwA;Xˎf*vnkg+2`M5XY95{Aqg 4B_Q'n= m:; 'k, >SsLbh4f@oeMthY 诡 :eR7iVGxvBґaJW/m5Byޫdwɩ[,#a޷hASjT(AAnYShӈȯ*ȕIN#pW`_ǍǢAHO*B{uq2;>}0uML;:X׭Ʉ> *(+6+¾0|f4"iYd@_/_20[YAVƼ]|VYJ.W4@AS sջgOp54;iX/=:+AM!Z~¯=:ugaS}D4sץA;s_94hnKvr3+QnMsw*g!yý֍4B>]]>ZRAL|%A}{_8 4?54 z<Apۿ?3`P8PTZ׽XAn6jآ9r1[zn+4s(%}_erxoԪ1jx݂}0MٳD{y.=?eMnyǫ 58-E))N( h$jƇyܣwndzQ3bj|ԏէDϒw%(wiw?K4 =oՠ ?˝vxy;wQ;)gQ%,;`v=ҳI~; g5rAS840/qE)gV4-1_)g^AYYrXtDT}D>+b*4=f?<_>_>S#yNjڙ7_Ӽ䋀F}:t`%WИ3Q ʼw<#PrSK[d&Gsܩ~~9ifh+9߻p6Gh&nƶ뎶ɋh:*ב6i9jM6MSjkXA2۾mA(=8F4Ec%CzO뛭[ML?^:q`K,:"ԠB䠩&s֌{As2O#GOQ2h~uxNЛ\}>wC֦Z]$򁣻Zj6izM%;\C"\C]i7VV8sMbԪunZ~$i{Ǵ2afl%nq ʿ6Fnntn;D{wY7=nm53:hO윣+'u|_;[%pc5Ӳo4?AiQ ԷK=}ƾn54 69@2 hAC h@4%|j}'J|F9V-C̴Ndߠa?cdU|S S2gTQ03s'dB7{ڧvCcfAAӯA/)EUE̯Gdfݐ5j;ghNLK}xE>+pie}+59f Pm&#*;빺qeLm{_;=~E$hd QR猨̉>꘱vKtճNͨ?.s:Mf:OSɜC/ Mtc'jKq xЮMZxuf3NIj9f P w`ԥ\|{?~ 369@Lҏm(yam\X̚w>G_xKo=9Q:uV LU%sMrrFzxᅨ9ȓmmcu׈+ۯUR؟gkF1snuTg}>=GܮSӕ>n~qT|g+yʴO1As^߮97{DC4@5 3)19\ᮑ1mҦj*x>uT˰i#h2i wMrnN{u൩J3'u^<б)j9}:y^sjδu|_/ԴSј4@5yǴrQ6h.*4as. qBA}py),=#'տ}tS^v<;V!~*Փ2J7edDƌ~5 [m;+)gVr8,4jSI> s#ygMV')ӴT@yύ1"~I×j_ _O0S#ڡSm[wUFg~i |^_~U/[3F1#h4mr=jQERuY\Kfwէh%949- t{J<]s_ݢo ϫ5: v=~0ev4TSzNAЄAoڴO)WV+ls]yTAϗZ<{?/]cWr{,=+ѾOz?з+*#4tc32WSo-tvS,Mproy3G]3AӳoZ)*풒MImѺk{)מּS[jQe&jQZGa~c!AsQ [yFԌ^\4`BcUјf"V\4W 6\m)A*YAj(W[gq~&AvZʐ״W:#hTu8W8?TJ]~k厠 ]^` fKȂB>TVǹtsa:@U}sAEA󫐕]GC ws_Ac_Gu4630h6nf_?3EAsYY@U=;<̹ 2u':3{3610h6Y-bnfn~l:/䴳p4 H3Z?E1WȠ v&ev_k^,t\Mc7YmVjİͲB;v7|-dVث2uc׎Y{ųX<4.kXCCzC!ΐd1D2'Ymj[-jVkԵZ^̞cvl:,cyYq[tک֎rN[ء =:-VhnCS%Zm.f1[/Bfi.95W[?uٚFssбc@Vo5=#1+cŵVk\3S.44gW8JGԳV6tc&*&Vu9";vpi耦V4ZZoV[s̕qYLQ1KMԘq ڵq9fm츱go;B'TS5Nc{:fc\q_ֈ&fe/{?9NAƞ源gp @혁qugd쐱O1SŌ}/1[Y_"B8gk찹q*7X;錜9bǩ>+y qD}jUq̔3l:?y1[c{nj͕!qWk'ȱC#x.cx1cG̕)Y̞HiTXtCreation Timeпонедељак, 01. април 2024. 11:33:00 CEST&B!t~Ux(Gt~?"2#2%F)0 B!B{2WBLqY"(䥠|jEPB!R(*~WS!8 _58)OkLEPB!R(*~WzT!84bSԔIf LQS]!/JIBKM6!B!PTܮu~䦠ؔEj(LfYeFF'2%F)/5 J-Z %B!7(cy]|k(36lMQR"eF9L -ed)21JԓE`D!B4z]_($G)7M5EF7MQA+Jj3eVSEFF'2%:Jt%[Z%) B!w(czwEh:j^:e¤afJbxrh02>hro֯_?䥙,,,!B!DF8p CfwCѪ*5gyBSpLQ26MHjDHڵ_^z044ԩC!B!2+g BZ B1>+Fj Ω]vFWͬ8\;?>`jj B!Bʌp [fkh8U?ei 7+PPf$"211a&B!R̍p 1nhf!RY4͛RfD dO{x !B!zC8shC)5*DjtC3骙Gb/8!B!Dא#XbNYaCd"1SC@6k׎03B!Bț~&9Gs-UIYײ3g(͈ B!:JJK[YYɈbXvT9% ̧=`&_v柊n4ШjժWف !BȇaggW,"{\іrS`虮2K#OZ`DZj%#B!qxfJI{A>!v A.zV@F2wF'M:h;4!Bа,sCv{h$u²44e 7͝QfgHM!B>$ʓ(,3v9A.TWT< ;+t.;SWD?V7#C?W.zLEw!CpUdi v&O9LW@;5!| 4MHo֫\mS³xBZ"QJ3ὴv888y֕A.R_&gag6ܬ6#H%NM!!{c^h%"-5QqfBh )H-`XaԞDE,lZą}z! ! K"tqq(;S6!ĉ2ek2()A.P&vVpzϦ؄RF'H~'NHE+-ۆT<GB3|s$%%ɤ-{{, 5p1;.7xFS(NZ[v|HKKÌ3]VvѺQ Yfٱ !2 MK}G4Ir QKyX_V6 qdNw-|(R:~N&mw\ HNGĭ#)L J $i -<7d&3u1vB\Ž}`m8N]{Mߌcrt[ !C[hڎ QP`J#3ipvv'4(HXHcBHeCvñp'o[VGlcܿ \_zc~}bV*b"]`p_qH~莑pЉPZ8~jal1CBS+ŵBv( 6u Σ ?c)ˎM!Ih jxYHihhúFws8/'0YZnqrwb+D]L GTZ:REPrZ&d# O~{ ?ly& N"#wA8.ipi(\`~FTպJQL'4ՕBSXA3Vر !2 MbéSqCĦ˙Ơ 0ħe,dR.a!xoDLz"£AshtEaP3:uq-JK9D;,NBSGcR[qrqޛϫMM c?#pY%r6@"y4u( '4 jf~؄RI1Ox*f4DI}?qEzдg3 yx(Zg q4д{%W,~7%46(ISBSϞp/z!b2~y(@i]L&  MaΔl$cBH%#4҄МlRLJ`'w1K+4ͦtr_F5FCaff$| .&Cb} 6a5 L*>D 6ol@( V,Oh V8BHt$<Ç;^胁h"Fn?qj^#8t"$Јo (@3D&"~(X4/ [M֯yτ5!)61 HMzc72"x 0@Jg`fe3[AԄR1raϓeId$9./9~h+l`א 8y7 HKMDl\8-C6ϼm8}/ )R`G#2R+B-4zNpoE ^ xx1c3BH 4ЛHcekp(+V9Oh lU8B!33 lGۡ;EJ7BS3hRh!BKKrb_|(Dh,"ƔBC!B>t ʕGFCnG1-Ul/L!B>95/\#Oh.bE Mu !B!%# gM`] ^e)v[h&4)4B!wM1BS(# !B! BhjPh!B!B!BBcF!B!T1B!B>8B!BޡXEhUB!By]h@!B!o !B!BC!B!Ph!B!B#a偯 _ JTvb=460iAKw`Wx=!B)=pTc,+A{xnD]WTdg3ߎ$9Lknpl,?0Sbm5v)t !4 _Bl 2^|?o[h{&4gIYq^"ˎ3?#Ue b3YH}b[#`|p(&MI!8ѹ^>]W {A}PuYxgF!Bȇ-4\&4>}=1`x0ヌxlZ 9u7&l}촓X]mߋ6w7_ z۫Bc:!!ѽ37Es9` C£BC! M!B cCL6^lxo!n "!YٙH mS{N1qE꣸< ?/;^UQ[I 3p7"9# ٚ4 iUBPBDž7I͋ Uhg#.%j$==Cx9<>Fg`Tk|2d9] C|z&]Y}hV}r^UY.+h3 5iqxrk6+G655ǐ)P+hL:F0׾n=GJf63,`(3zEm7B~02`'Ǩ}bʻ?&HL?:8Oh&f,hn+*[0C4C<;+ 6oA#06p"BB1a'\slZϰ1(kWm}KBc)ij d?M!bc\мH! ;ٵB/w#\] P`zHrIY}omoУȊ9' O? nV34f KaU O.P_oxE#~3ۨ 4p! =~^C1khrqwW;>,ưa8l,<{yLkz `]d$6q52 6a_xGX742V~~$\\ZQ+QhtR zEaLj~"] dPXjw„Mۡ0IlFIZ0 ;9Q38[(24ѿ#`o KtLVnв) 8;T0iᅠM7AVΰYsw ѤQc⋱!ic97.xUop/И4xw. 1qE"6¦0yB!-499ΖAoF@6+b?s?lS4Sϊ–E9;0.$ iSʿHA}r3ExΡ8I]e Z|tkwsB"Iz&Fʈ;a‘ d99ٹ#G~3%:|}꤃l\䐳Z'W M{"Ihn,DGX3+4w0:ܤI_ 3q1!&n1pofV!gư6!mMzbdH)f0:Y+5:#0@; "{\܁:|-<- 0Ȣ(ySB!>(fvΝ]ѵO]Y=X8s6)HFZkC%լ1cuQsh^"9) PlԸs1g/4F؞ƅYٍ?L1;Im7/5PydI2uc:*j./k!+N"Zs:~b-OCs"d 99g*d5n]:m*P KR .o߈kIDA{M_W7#4f"}sZ hCIh~FԾ=+i7F̙ =YUeRCFs7s) >;vYoOL,4vCGQAh9!*oYhBvv26MۣHLQ-d!*JhVPhs}٘WFiatϳnO}}sةJ-4Bмs1Eewq{}44wA,Z oDtV$6)ʙ.L<4H^ IKL?'ƔAhLZ`95C;Y C˥{xr65\ghJ{-Uch7ײ Bc{lШbʼT}ܮ$@B֝18d[סbșci]N%ֵ٘Gh":c$4k<GB!PhApƀ1s1gf#QR`m_DvN]ѵW(vǪH'< >^6xyCZ"$Ј`[,+,B7<1nZ(%ͺsG?O_ ;D+~4āH3GS:ټ7{H>\s<>0 ^X7뵢G3x.$ f$ / `b!B0sn0nb!:~0:B&MЬU{8V2i[I#G897G'1x 4PLm5Ashao cKx pHoM[{T0G@|E f-<06d"F-IhөVᝥrf"ⲑ|g's >x&0$wad'}$Bm>X3hӠy#L~'׎`܁pWiz uZֱc$H&;W}ןCcl +8&C2x)\ G('ZX#HQ>X3[Ըp:KFuqUDZ;R'#llsh,c _]Wy(:m'FVz"\=?㐑uj/=d(r&S< 6o0j([ypfr?1qAcW2{s"zot ~W|]kC2a,zuA%4EPpBszw(`VIJ^>a %8$aF#!B(4oMh)#ν BPh*LI “ T7+ g= !B(4 BC!B!B!Ph(4B!?ԭ[B!6лB!BzB!BۀBC!BPh!B!B!BB!BBC!BАwN۶m1l0T?c+gQo= 6k;88M6رx-ubz=k֬/C! Mi l?gP|S*VY;(48 -F.Cӡ /N-_M-dfΜ9;w.<<<{iҤ 6n܈3gʕ+uܹS${Ů]ވI155<(@VˈbX'V&iР>E#' F/wԪ,5B%Br IؽO:g'48|V.u>h3e\݁ͼP;3nh-XνKʹݰn+OfZn+01|g23vX}IZl޽{{%;3vZYbJݻe*5G=pQŋFdd$"""BfbccD;vLG[/`̪Zjo mcb-c1T3OsO/uB!Bͅgq~Ofco_"C_TVhSnߓnH\GQ=S˿݁Kf+L&߀w*3:DP]^Pvdy:th 4HV_Y!q'OKh^FdYٳ󨯄[{J2nDeS6+Smi|{9+b_q )`qFF 毈6۶m+ЈJ׮]quY\Fdj޽+ 8Y3& ͂y3e}Y[xzUhzKRrj1Rդu' ! Mr}.7y>jO)j?x2MBF ;lɌȌ23f͒@ 1eʔ)=zx-ubG[;b 3S ͥKd1LGy!$HȐnYQ"S0+̈bΝ;K=HB#20BRΟ'4_kr̈PF 3;TըL"gB 9YCOq_ <?{s0y-WHBVQ%5zBc{%31FɌ]0In[η)4!)ЈL~ɓ"ɔ$2'NX,>,)ǏԈLr^G}z6錅8_ߩPÿZ3U[\_B 9300sYΆ8(=l ZHL `hhV/Wd3Kdda} ڂjcyldFdtttRs9W@'5G+PgBBRR^UhUVҢ˗/͛ENf9'N(ϝv\-!!k֬y#BL2d06A.\V OT3;U |/]zghb}wk^+gB]9]6p a>8_>2ASۭl6@(1LLQqw|9-ǧv#01~/dF / 膙l^L ,RhD;tt1+*4P֯__(GGG={VeFFmK feĶ˖-߿_QY F8/ȝ߽kef00O?T/C&?F;7dDb]-3ԨPXh7A5O!Ph31 Opy0/ F5\VDnauV5FpQ4z/dF )#$DT.R"Lj➗Vj>b;q ^SBSpٛЈk-+l¿؈͛7=u/#3!Yb2#CڷoƅF)3O\{M`_ϛ'gr4]3}&j ;F?5a*~-5 Bм*gu_|dBj? Q7jH&$i%bXWyٙt7mȌ@<(SH!%bҿNTJ+5b68F)6oBht"[.nÇ ض܅xЦ@_( n];*3ΐ2#)빊kߞR>aǶ* pة#-]B!BS ]7S\]O}p$Oeqbte.o[sȌMi5OhjAʌ@7FHdFj>B8fyFsd Bfd♓^FL744Wv02SfMe[kߚj p/pZϜq/hI+T ! Mxx8`G Id"90֕isyY[9 -l`jWqɓ'hѢ&3((RJ3Q2E)2Jed;KQLJJ RSSkSr% (,J,o޸dN2S^>!9ر/2"pM2s-2"q[>/|B!BSyYvML/3_[/H˺;]zYhg\m٫5#Z. C+ԖYİ%K`ܸqo\fm.lYQR#Yls-)yx(\ed$IuЬ̈cx{{z_IewK0x/.=w)Mש94>i۫7 "FLҙ:y{shթ/|B!BS94v5q\Ũe*;7l6Yh>|'ܪ; fޒu{VVVN ReF )Ρ|xXfqTJnF`bb"gz(E<!32NfҰ{R$a2['~zxHЈbyi1Kh-^?lVm:2SRx yas_^KB!BƩS~wȌN^/a6,%D)`jSœyϱ׬rAdD2#6˅ )Ѯ];YF5~Ԉ QQRVHx/m1KrV̈cGhD-*# $>ThVF'3ѣԁyi{TZU&O \ѩVFPDe?bg^u2b/wcgzef破}mC~B!5L16Bpdx%5;GyRXsnK;8sOB5{)o z_bYf削J&怈IBXf&3fzxxK$tYLhvFaٳ|8߿_d Lzz:a=fy;2&@h{&o/T0Ü_TB!°m%N84DZE1ڿr  gfՒBC!RɄM&cÉ{IV#[;8m z9Q cvB}~61p'e'q*:7qBcl֞ø 3:wΤ WgD'z.$gGH#]cI}T47!B(4% mq%7S0rX[vBB>Vnp=5G'iaBccD7A`&$UIۻb |lSx@g{>SP֢NPˏB!Zo#}c޲|8axtM62&hjXq5qidS} t!p^@Kع_&yl{.v]D: X?0 ]ma|$4/vQIR`Y%#w+#3).V- M^>6 ͊9oׂ)IhUh3(Raqׄ}5³em`sd"yL¡yUB:cѭd$%dQ.u~c/?B!PhJ#4g\z6홌Ml^ rBkc?~=2yٶOX @|w9b=<&0!1cWh 4g]Q}&rCg/0v ;=w~q0}?-L_ zBMa[ySh^qc ^!4&h5"41J%FM61zDo`AGLZNǹX$RG{ \cdF!B)VhءSF\BV5n[zfs|9+@_k٠iᘳ$DCJ<c*4BY}^}Wރ&'UQUL9MQ, O߱Xr$3^gkI9Me*wip7!B(4+XS,Y% mo|{O[ao}qBc!C}sڿ>lj[ߋI0  B!=Md&$آLLJA%nMEQ?Һ?MKѬ1W#A IEUi14B!Ph 4PkQ2eĮ-1 h LL-V$`l21x>"rsK+/g#;%_{XK{bg҄BC!BїЈ̌ d 5hI*egcNN^ۄx$q:" ؍g/;?<7WբH҄BSA Pvm>B;C;dhhT26 ]/d#=:MC Mj5?=@$ <YL;Hz&&D$4$tT4 `M><Fcc᠟F6.B!ݿI u  /&mF1ivQQ 'KcsL"f*% MXߛ2 uf$X#fDc<; |@Bcbl9]Lpi_$Bp}3fw2ו/b&&&BH@DxK#4$4*&_kqݨn 40F%)Lr,Ow-Ahu*S字8#98r03t9GhL%aY]}rv!vDܮLXj,oS4?%RY.U^z055C Ϳsol{oE>;P>T>*'+3އ']QզvGun}|.Qñ'j:B}Qۮ c ߳y%4bNݗP'd`hm<&̆:=g$y2jcf.Ҳ)h440Re{t0$ح>1q&Xj  ! dR RTUEԸ픤f$5GQe9 wgt:5B0Xe3Kcc!4b:` DHH&M'" >>>h۶[W ,Ti*MBPdTi> UZFQBT{7m 5ސ_` !DBdnn&ߧL=)\ Ϸ sp2kXa:C|YTU}x>3-~l'~fzlK޵LоpT1hz6ŘM M)F1؛vW?w=#fHX6a^7yyt" ɓKDl׻w&6c}S8{̹spy .\x.]|̕+WpUk׮Xju MKck?, L_Ĭ$F=;bx*ODϖvDO<;;Cc-nCh<ԙ?ֺ#BHM9Ϊb'H,E`Knz \1Tn˫kTOO2pE/AtEu5}#0m?W3ce[*Uy}VߘƲ[ xu(B#Ӽ9&/͇jl܎ĭ1>TFĺaih _>|8ڷo/fff6ppp+F)o'YFqoׯҥKd,^X)/[ | [|wXbV\~?#VZիWc͚5Xv-֭[ 6`֭8x ;xRhЅ.Fx'#jUoDD8B&_D|߸JB3@׭;nOh.u/4#[|&Mw{ 4|"` jVИgjYڵAڙ{)мANKq,v0[Y!x,<~Bn.q1A Yy̔XwGsa)Mۯ@9%>FOw 3+ۆ:W SXھSXBC(4b^ 7հ /vĥ o_-ݰ˸vWNK[{;i]>}McChD1d{y2#bη"Ӡ>ofY1S߇+ad"Q|3Yܔc9W$azK{g#.%Sj)Q7wA4QϲuGq7&l #peW' زdhKű,ܰq62ëL;~s-"ԷXLdcpod7-*Ia`0ħg"9*vFW+vϧoK#]^JƦ1|a!xaxtԇ ^*Jh,%qGr6fV_<${J':>#7&HL&':̓7%Fi_qF`і^04ЈEVE7_вer A۶qhժUu?j.Ofẗ̍7^L9LRf M/ ERcˈ5T\h͌mZߴfOv5D$1ODW-l+Nt86%fOX@ KhTA8ك\1¯?|Gį3-zj{5Hqg,0#fn-IRJhtbdl8x`)nWme>Bz%<n}aH=YAi[̹ۇAʦ:c]addEXR 7D71Z72V#>6c vp*1&7+.8a8=1t@xsWT'vuF{[? w e3gf^ h8+Co1^R3C}ܥ /#)1V,)`0>$/xu#_9qr[}&hagg֘t,Y/caR6"4TM*=|_ 7 wGK\B?5j4`|K%C{%4cjC|Rt6잋(#==/뭧&!#m#8zc(׉mĶb {[gM}=x}s9o]{׮-$DPQi#b *b]a 6+b (]!JJIH X]P5k(YkΕ9W~k~7#f/^,YϬ0+-狌xvHNNV@rLܹspB-1ǘts/nF,11 b6]W3Mah{+ U ;ty-௻:4hkug_Qs&׍GqS-ΎHTs9Yt-ʘRůHnTvߛ)%oWc#2:%XS`9 һ+016qM\s05K0+ 8|sL[sW8o29l$q9 K49ȗG_=lLZҦ\p-rfH~n ^5 %lǹ/~~nALbp5TPwח|g7^p9ڎG',/f0sy*A,8%dbA[_Phc>ZZ`N{FQtl.b$i8}/k9}N ZʽsT 4,gje2Y\No .gCgHQն[bo.8]c@3/ kKF܇FDspw‘K .B;TiMΥ8pIQ׹b_h abbLۖ 0nlӅc`F4c&u5Ӎah03q3 ШaԩSp@C?. ; b}l "o(4D[) jiIqD16 'Nv=?8g8=#,5QxkdT ,澴)},[A=ۄiL=FL`W) ={13YYlӮyҐ4R黡8ZވچtC@em5>6wCTm͎6v%YeP\%3>KQv)ǝ40Qk0A,pBվ0!I75Ha gPTMhC =O37YchBrؓ7Ձ,͐cl'rj ԇ4\Gh,k6h==ϑίw w9ż̟,BMQ.6x=kA =rJ7)3d[0chh8ў <(12-q8P,JW4I %q^WUetԟ>wXobϚ_ 4~~~Z0ì0ͬ0@3hY5 3jaVgtfф&&hf5t5Sӧ1~?~긋LA0"4Sڴx< 5O_ hGik8hX #«~@/3,Va> >02d|&54 SZ `Ol)ǜ@7B•bfjp4 (yt}}7qh9?5j3K?G$AibOq@ܙǖ"1$}"0 IDj|{Kt׆&A/f 4\s@Æ[h偙~kpI:1lHn.qXbi'. ͐gl[bHVÙUD[4 /Ss%9Wzisgk/jq /+4& =\?مv޳otst4Wz,d Mc#Fk^2>$0Xٚ v#^vŮx'"- nnBl97?^?MA⳴H?>?8wɈ벲1*I412f6HLBurc3 c,̨KS4r5c`̙3[Y]_xVb"8P>K x$_kpR]X ғxK1u6 =\F\ob\դx~8`.6F ?IHXeh4nlFrt!WmǩOw*"5yI Wf56ǕpJ@ [-ÁU=k4 Ik!n04į\8D#JJ ,VL\Ĵ#DVIWul2y*N9' Kg 2^te\BXS>$u ؓB>/r'@Yrhm41Aٳ+xLf8v nAX5+4ccC#h?1F!`5o8m3l;ˡZ!̱t3L]9a<GG 3GZfq3\hքgŋ[u9@Q2H;[X yk@( Օx (jh.gH@= ~$V@~h` YKdl,G.t<= ,P.d":xP\gVE^V\F qoVB|4_hhiB6> аeੴA >(؎An;#g\- \5 hiPRՌnҎz.Lwjyf R?ꍳ˜SՊ3 3(.~vkhB8Vs2܊2I+n$9@ߙcE>nWŸt`&Xjo8oΖG=2"ﺬi蛙t E!\҉OG>48jQ h 4,>+sQt7Ex\#VAUӓ6^5v}܈ ]70kv]{f1}/,~Ev/[ARQ#qYO <Ö* #=A sHRgRwg@/9}l2ms\yA YNj/b; 4F܇FШaW7X 㦏œsDkDs L(i(Ôeae uc͑ 艃KѬ 3.\PߪYWuDv IQPbBOA< ^M%'^ɥ񄈠 Y}Uj6%O(`Ezz߄[-Ra_&d5s}@>΍ُ1 |u) fO& i}.xV#g `ki[q-o_Z&`Mͧ ~۲ >zI)60E*3j&, h0+oQW3M0s%ſ  Dq`NE,hd"4u\͚ƞX][ b"> cbrR3,%q8'o^E 7IyUY5l(kWhUPuo) h1 ǟ6)j]Mh&׏٘^U3ćQ4Oߡ;_ 4f޻ZZ#㡧 ~W=< .""m;Gţwކ ߪ\~Hd|xrf%f=͔ܳ>$]хCRCPA 46NHMM7L7nFjfU˗/+Zxd*A!\Paz0 k3 `EY k{WdmoP+АFmZ)տ-ά(.|OD\|%a1PN NO$>u3~JDDDD4\<~K0eB;Xqة 4Kc`9 Va5t=q/Z`Ia?y6ƻσT׿?@!""ז|8P!v\(Au/ p L ":!^] _ jS3 _GvH]h,±dOpL7(뒣X i&x*%nFͣX7&{ Xz?5Z!p~]k+ǭrt]Sesm(wT ¹B^!6+O?<ĉ#y}˥(>&*Dk5 (s/:b`hw g#A^,6_{OCF92gz!jr}Kq5=\ +^̳]MM5.>GE$ Hqߢ_y9(m'@c
5xs- +#nي.E 3Q@}4t "@C&%"""""""ar6ck}UwC97gEɂhj6۴=AZ c4Wؓ\PB%m4ƴ#,zCx ]NXJkcfi#k5M߂2WcT+jy=mZfe[=n&*Ā F^ 2ܴty5p9aI4!j.EL48Rp4$e i٘ HUVx0F5{.U1 䵂RѭÂ6)yqK|G`c @3vM{:qC,Mh*F {>Ҽ9Z.h[|W аV.g[߮Tx BLZ^w?X27WNcu/` :D:(JnM`bヴh{&}#9>XN[:6W?yR<ϜY!@CDDDDDDD4⁆ ׸œbT]יm/SG~Xi25md!J=#YL ???|\`el:P6mSˈvl7;"Ң8jEYw 3a Z&Zbw ,Lן,fL7g鑂T0@밳I m*w#@CDDDDDDD4rN<õ%`ѹf^,#cA|6=@[s6̴1 n#ˁ,Io?иe;t,g6X|]H\$}*~X>}:А 3 2D"""ƆehH 1&}Aƃh @CDD b@ @C4ehH b A4x!"=͘X?d$"""@C h"2h,qY;R)/qXLĢy.NX.ےI 1،76As VN-?4h,y+p+ԷK!hEWa0ЌƑZ)^eͅW) 1d&"@工8g^|F|$Ɛ1ĀxSJp$rW}Dg4kb3 } Ĕmpu;m9EJP)%@qξ2 /oou}h*oTޡE,A'[;vrL0. nóﻌƼEo`-MVȎw "-=) hz ~OmHͨzp˼όǁ 4t1<:6mw5uQS]3h7a `iW5C,%$Nݬm(6 ?;p%vf`"4/Z!b5l&b5RIi,!m9)F>KP}R g6@c7}9>!KcK< msVYw#^^ۉiGq~I)t7V@8sg)~(iϧR0w3w0RXX%niӦtsswB-dOyͰ듑 wqQc8'G۪q6Ē{Xʁ/}6SjDuX9?=A m|KAp 4V8w"V!m(?n *˘{oC /+DJ;bz؞[CHK@hH8G==1gz3MPuumeUc],,} N] Su\cߡt$ki(G V?9> ո `Cj/YަlSM4K\d#ՌeZEGMa /Gc_2բ[.g C@cr|>8r2:|Ʀ[10NU5dhyrkO܆kt?߅ j@5Df\"Ćh;h(Ta٘=]1wStI?֞"r*D̲@#M~L3k r"b3KXstlND4FzwK;kfNơ Qia@(y6YigExڃbdE@ǞC9\o3% Ũ܅%EH'1W{M3 hz5Xu&|f+94jz=<4p T9Ͳ酓EgDm =>Q{gWG@ X#Ag;k Eޞ%YD_7!1́3lWy93s~7Y1S(kd;Ze`X`MAc0FfOFrA EЎ?ӮX 03M'C %ƵXk13_ȴ˃oAՎ1v0ѭciᛅmJ .nCNRD*v/36z^,xP Qs)2fK˅8,Gڛ4VVV*bz1<F7(< saI{cER/ÛĆ luo;}x-kq6@fXmp9==cpE7cqZ4D]1[aVݥGkk5ERFN""|#4+˚;ua|zNhE+y")n/h|}$ηPxݛ>9+ =n|-O!m9 _2LLL~\g A՞Cb}2<{ h49 7:(Mwl|U?.PHh%X?{CTZq)֑H-J[.XQ(V2xc*_鋭`c\b H n_M?{[bV4=ʀ !kbxY!D?sCRcXS•hkk_-'uW|X^_ T5gZ ؎@"Mt\,4w%.sa9J 4?CԢ#QshI#&k˓ _CO8ƵRP%1Q')Tg3Ѐf~TR8)w_ 4x!C8%"Q@|9w$o 4fŃWwR e1ğA*:p;U{6q‡ÁeGF)>zYz)/qF=3CUFn$vBB~N?[9ix$755[L*0@hTe'EܖxX'\T9Öh$LBqZ7@h8Re: s1;`={#H[B 4sGhet۲ Q@xCDC 6{`;jaS}֦Hh+n^ay#m_(9ne|S9/1iyxޅ{`= \zçb,3ػz`B!VAu"y<hO!_/XۮMTF1U7o3M|GiQ L5\Ȣ rfdy}mjtc\q[QڟEF"D%cBe@mm>_(I#OF0.@,z {+ e`YT(o¥ݠtvC;,.?IWJ@tD圝xUkK& `ѹf^,#1p[mE0Ӳ2D#z5G*!}3lY nqx'k+VDĠJa"f~~OqՎX=9C-MM0.ĒBxN e GD 6}If`q]c'==Dztf(VGF^8XMxrq39 6q8Z}=\(+xQM $29-5x9_ƙ$/PEG.E=^>Am8,̸n\Vx#t>C'z+1בvyK|1(pV:sJ'8?eX 56׏Wo}28\ᱧ쬴F^'c=Qmvϯ ŋGx%[ OO<0V`/ĝxP{qW)gܬlqVD"; <51l1hR#eMEfR(kRfsh2WD!d?#]Fy;LVc0uKp)5eyɛ].?xYF6Sh)ُ@3Ղ.ʴf>Xs=‚ ͸6Dkrї̈1$@\Έ\ΈFxpfa[ye҂E14D!1ᤨ[Hc6!4 ESb4V\öྠvw*zЊ[: ֮T\~X.m1f`дSxR9dVԖdDX (T܂;1i5 M,gUi8\TV\<ثʛa'1QlDL\{rfD_!@CDDDlhFxc_x ) 5Jw'4DDDhFf<|9Ձڇ'?'4DDh---XԩS/x 8hF0O""""b7DDD#}.#@CD4BF.}  ~ 6""4DDDh_6 t + |'8^19 "*t>gq3Ȍ=Brܹ[MS&""?5Q`tV)Oa-Y5 82"CDDD8@#çk )@p0I'߀MDDkxƒ?_E߄ϥ/O͒aSW>gMה‚ωs9r/p9"g#hMJբ,BXZvFE#%hx̠q}{ᛒ;)DcYS蘿 D|4wA,@SM9)Gl IMD$l"Jh[0HܐNULޣH] ?18XPN"4fӰxb!44Tp,ZH!MRغzcw4h򅷫QAwCc 鋭`]\b "@, k.[mWS=㖘M2iǶAf횘;#^uVxhn@B>TD[k]j8.6hkP ϴ@V3{ F/)Dz+ǫ~&F[}@3D-@3pvՆ'ijC{S%OƜ&h[¸4p`e^CZ%a@G$s/@8w4&.h2j7z'+s}^$$Ƅǥp m!`F 405l@.gxZ QlĽtos垄^Cs7dr ߟAbg)(Jߣ6-x_0lAG+ U'/_p%H )pzڅ5v!/x6ؾx/C 4VL'a})I~ ,uXV(rX2 9fYvz긩=o$SL\WiW% ;k&|BKAM yJxy)L |YuJ>j> '<MBlfG?5%NJi.v(!AJC&&4ԽCpEgށ"@CD4j\/hΨaFsuF 3jaa8vrZIZP;~0'(sƚ mJ?BSF҅W @pX<'t&"̓pabzk͠`WbCֻH4ll~ 釛؞G`pRѠ4N FՕ4ρNoX08 [l*ҟPh A 8 3l~;hXpuG-<[GИ: p6G7Gm]q+oR \ 2]K hh8dtаw5]5x`ܧrt\δh~:"Kt4ZO+7CP& 9ER(y>Au"y<fBzvulڦ2P1UWΛqfVD|Gjׅ,ʺ[.gFצJ:C٪&CA޻@yBf'HU`YM T.gg\Ό@0k0QcDg?663DaџpNn*Vh!"@c6fHq3jQX+4ܱ'HuxtvzcQ" vz.2]g{ oofM)&>%GeԕnP0ThL>* `u m3zm(ggu=hXى]ud`ѹf^,# z,T@ښa֫?R ݝaҟ`v[3?!ȁQAD.n/ȟzbsZ^_Z`\%%HuU'HKY1mc!}sznhױwG3"i [^eOU@/0ʻ.gST.g{mVr:+#U0a|ҷ'Y%oV"L&F%Ѱͨ&11(%Vp]=^]ލ98N5P Ha\hs!b  ]Ӗba 1e;]^TmNwE B: ]Hr Y0ԨcưǠIh5-K! b碬MK1ZZ7sh2WD!d?U~x?ejfahTRj8xː7g \~6m01+%au|ZPԥz Lh.A|/Da'x5!146S KܿP!Y6bÖK -c1O@E!KiL+/4qQ)ebTx56f#%BmbT gVrfl܌f.] Sw#<3LM{J4)@\Ih$0?Z'j=X6U2C 4w|#(G^FfZ3ϝ1-\ 1ᤨGONo c,{]&fbJƊkB\O9D]٩](놨1f`дSxa'&&&Pg\Fy}T9Ioimjg9SMj?OOq.uYf37)HZPt8$m@kZvN.A8G aHNݎ%f߁Uq[wd~?;W/P "iv.O@T837C io[鱚7_SD9Nh!"""@Jw,Od=b,qr<-'|k匿Y;v"L7ߙ(%9""$@CDD ~}b@9DDDhȏs@!DDD2!@CD s/ [׿Uqo""2!"""@CWfOes,YbPLxp\XZZ&""1eh ohՖ@}jkkS]޽{GGGDDdh0d2T?fZĿ}to .4.[ I[-!Is\pݒn4Gfи}OXMW JQW[1Bc9 qA]H؟'[ $h}ph)BPJQ7(i^@,4˙:`AEuB"@jS:bq;%ykh5"!OPOr rb/YЂ} ٩PWWBdb sݗΒW?ed{Jy ox_m9;K(ge#&&!5$cw{;N0';;; 2z{{C2+?BF%r3ggW3Yj7DD_?-?w:| ߹wy߄%KL)Wsme b`V1f]!=?ED4ԕTxZnǛHXbArfbjo,> 5SX[AI2ڄ\Y^,ƪ{Lf".oO`30Wh_=o(4t{b#㩉xLq#T1۫f8JŔCF n{-}/ICig#3ÄػP co1o֖}F:Ʌb|I?U&KQM25 l( &~>q'4w&AW&2󇽏 Z4>x}`ٿP͝KiK\ݾ6|4.o:HRNhxccpWJy钎7nMx%EV7CဆBEva޼>ƄDD#ИLJa&(( 5lEh wZS,4xc4ʻjcY1E, Gm@c<n!6;X AK,] oX.Կ_qa!ᕨ1[A5\*2Řhk3UR>83qfaVSЌ4Gl=}VR^[p#c:PMp( @LUU>k"66V%vT]h07' 4ƦVoUgH*{lw'0w]g$>bw܁Ր@Q]oo }c$ f?0z[bNѨ;Z3j[f#sw(MAږ O%H+ 9=gػ}n zY4eWn:ޮ>X{ =Hyjۘ?cMǐE?')1`'B7Fq -WBkMٌAZI/@Lkf*:>fχHW"Hc}rf;NTSh|nn͉JO*g| ߁~pwqo,TC")CbyșO7>棉$[rh!dذVbAذ>p2BII VVV3f +v riq}m<+ ~{{X3X6lUr 5G#""tf0FyңrԵ jE#YQ!7Ġ$U؏t|Q V#-mDWcnoA#L}S\Ui@cOu!LW%nJ^2|Tn4H-#$ PMICNy+Ĕe7ӽ/ M[> կ$\}R2Up=-?V Ie-Ƒ8GU!e.˖(iT܎0c5uU^98W/…$'g*gptZKa~ͨ(8dI Cq~Qv 2 e8 cIQm@pϚ5By˗ܟ(//̙3YSnC-QT0ש0p " ?+&`է5!kW,CԊ 4ɛQMTTx~hMx&AXpAF[@9&CI!lw,5͜l} g͡1ĔD@sE7B.a D셫m{yL0"/l314VC͂ ?~́ )..199z(a6mڰOENұRSwzq=( %-4CO тj(tE5x2DQ ""hؐ3}f09#;%Jۚ\G*_pk1w.!`IX/-g<81,#vjSDD( `|tNP?ҨX>rvr;V~/=:gV}9/!gwV|!"JF)6{+PYY`slXg3ׯ_(ѷ 45 OOOf0 1͍zdb y u܎i3ha!X< yipshoL(iнxse½\⅐XFsT4ܗ/vfh'UΌaPu9 g`Ȯkg"y Z6uVc'8pBV&7[d,> w,uv b= !"c p1 gV+!|\!""Vnsq^fX䂿jMǑ*t< cdVA,muxv?#3y#.<@K=WTYYx6{gӐq!ח3HQ$`Us/h|Z. r1ډ~]vx61(q=<jLDOAQ|B.He2HDMx<ۗyzlCpKԉ$4BN!4DD!"""\@O3VgF Ir21b a5?0yX" F&""@C ѷ9 \ix}ł οҠ1鄈Px {O%() ""4DDD(| 2Ehhz|1T,#""@C?!$,lK{nr^@CDDD SL،_ *+Y;5o)=]֌^I/^e!eľ dMnBT29?YwRCC3xv<St־]ޘ<4Y/@[(A"AKENÊޢ>~3F;!\!jDHPr#i&:7=^[ o$#S1L~䔷@,}Nv56g(̢sa`:koBi#2v>ϒ!=DDDD_+W"7}=B^2`C՘a'=(\?!.U@~C<͑ChIQ2,8Z֊NPCP-@‘H +I֍ՓuNȟG)pg(ݨf)*暇I*q=98Q̀p 75)x "r RY58v,hA2Þl'(OW\X4酝LX>0w2Rb $+녬()s`o ᝔j&}-hl')%-|_?G?ß+`[csnhJ^DDй}91?CH(dbjϘ^|=d]k ~[AIrB>e8REg7gmga3{>o2q9 x{+v2`@O/Ğ7OTm<5)1n/3]l=1B Asz(5y&0Q;NȑxŖ>%i(lDvt ٘Ir ڌgT/+i3c l$Wdhx@SB̲F~TP8f #k>b$b_~akg(l Ш/ &?vݻ9bϞ=Xf̀I#}kA$cnBk2= 42vBt}H=wj'{II⍇`m7-50߯?Ϲ]Aoz"`A]j-1&ƻ Ck(w(Ivhp3|0Fabt7^G>(n-@ ~ YX~Mt=](JshQηٷMk>0"P v8gdI::] B XhB0Yac^;:0q[u-qI[^QBH6p#`[`]"~y6q#?]wѳ%$b &!8V hn:~"""Mh֮]sR<h\hMoo/u5Ο@\+fk S򆇝~ɿ9㡴jϟZqsO 珝 7gL,]PܐHq/vov=pc4ʻjcY1E, Gm@c<n!6;X AK,] /^.Կ_qa!ᕨ1[AQkUe1cr!fgk1z",Qli&jwCݗ@0 U!dA#e r6D{vb+#@3h,'`F 4Ja39QŒhL&h c9d>|=£X-Np0Wz/+A]:O,]A}EمMr fܨ}?NPs3*% ;.?-_MP E} @B&԰Ru܇*=Q+p%~͋,Cc9z 478h(G'4_x@cS*^4ʙZnf+_h]J 0_t6\p&棳-,LJsww8|Ew аy&¬uC=1lj>̃qʣ/ɟ2JP-T}OB&tòQx掩x%ƫӫꃵ@Syf$cR(KB{m̟&cȢz˟]NS+!).X^fT0>yYǕ$?z"7lXjo0ZZv~ag;{kV93iR"|4xd 92\J>z zߞA|n +b'RKrP/ìNXke[0 At f"##q-ța&''+ + C{hqZŋ$ *Uzrb:Ě"»{e  pSKT!EXy7ę$Jo*+Z٧m"DDD*QVLT*338(ZȠ^wX=tOX׫(0g p2,sOGܝ6-H_|g\*v2ӣ<И~s#kk(<|w Z\xn3tKq{wn+ -ow>/^ Q._ Q8hbO:x>bk:poc0bg)~[Ix"my_KBEva޼>Ƅ^߉WgFn+q9c35N`,tb8{U=m=`ca [/FQ=4|p ~rZBƩL񂫫;NHSZMذ=yk; #xzD;X.4gcnA0Y ]M|l+ꅴ&"ᦰkIQ0뻸,OICNy+Ge7ӽ/ M[> կ$+CCFN@X"\ aKOźCD; +M V@3u=1@Si栕,hhHԌڦ.|.1ƴǠPo+ h(4[ 'V3'%a kk]mKy}d81+>h,4D'rh1y]sno!|$TN[p!o!~ Ni`GhudQ VXtƖavxl˪"B{CڥQ/C @{B3=Fh ,2 75>@#plIrh>hj<Qh40ÆYO #V T,0ҚC3$0/13{j "pq lm\'{_ 45#so*C%!F KswB[Aֳ28XUdh( 4,i98CݨѦ! .B\ $W4  R Ϳ0 x;Ol`mi6;hxmgFUb k[o;z=2y$o:ym|ɁHʦn.; ;8 <4zE;Gra7.U}^ :;hh@4DDD44QzfX䂿}!8ͽc ox6|Q$2Ӑqg' 졡(ӀhOB ;,u]evDjҚH q?9U (eɈj@gAX ꄇ6K#ph4”Wʦx!`ZcZ$J!T#;u%L?P.Pd*RQ_ Y8HbOwו-MJ%@r# FC]ďժZCx{H pr0D c G8Fw c"0NX0Q#KM, ƞՁ\!@́<4+ pqK p`VZo8-dâ8\i~6KA %AXx06 -v0Kzesx閁JNڷy>f">s[8sݖ`E`:^@3noY U+ lFX24DDhae``zvb hض  ߷bފP^K1X^F\a5:ْZdJL zUmbHExQ {XlGx n4@|'@/yI^qX ;!zPΟM bZq[%&;?`y|1pA8˜cK+Q8HbOK!EIe REא7Cc Vc7ě?-G !b)OS]?碼I^λ{Wpў;21ګ\8+1\c :̚Ej,x[EȎ tAYs2H{g k$x56f"V`< "tdGEc"R3|j T%eUC̴ rbhD @K\F*<˹MD_7@7oFss3QUb5bǎ:_ұFBlAr8+ [ €FQ#xcHw.Dz].O.C  (ׅMٶ:۱OvbEXg˺dlIį^l0G,؀5m[7ց !jÛ8/JB<Zm{2Hk$JQum=Db(x m=;CU 9ODDD=,1]w^ BOKK )$Gʌ VJqKn9Gh 4t[N {'<5QziQ>xs%u&3"4DDD="""4;MZhGZ! MhШVEdbX)se4MUAɳPL"VIaXRŠ[s*.g!FWD2GQH(; Of^k/J,/P|,ψ Jk&:LG{؇:簚/V~MhEZ( )o#;_lFሆ4t3X`!]@u;pV)ڨh\M< A`IIeh~caafӦMf*I$N<@A~"""4TXZF 6x%!ʷފ;h80ޒvZig[6c*W,ވM t?Ł 8 n]]Aۑvt+~ن(?On!6aampZp Rqh@C:/0B *Uk-.H>"_4l*nLMeYݿRqݽC +w#5F1\y1ۼYO9%ȤFn{oǹbTlGkwS(3S(xxFcLdf=TP3V.J1Z--?(V^yw6IjG8bcM\Bz /4t?\vy.ag<$- ohH i_4^HXW'ƘLTPs}[iғc /AN♖gU1hMTp-ћoZmssEU"{&$D@(/c7U@R > x"ϡQv31@{=Edp?ƙUa[H=4t;؆`_x O؅NJ: 8#1B GrHsRtk!f#2~7nUQ&&аsϰz!ZAIzUP20+捄VF3M?p Ưi7.jo4#-iOh-:a=OޮY0$R܍]/ʙ&"{84yltM_CaQ] h쐇I^e Gfy7h+9#7V{Jކz=x{6,@Vy<| yk4\O7vInl1x/@uRCM$3 Ig wkZhys#8UWp~p^RĬO4*7c*ټuPbшF\49b},<< FdD+As.J4*\(c/sUu={0}1&@uƨk>D%`]B BN;)A͟''F)My-8O +֫1b2N!to+*ƱX{X|I̋qZW;!" yE{c܄$ f?&2x>-|aj@c8!?רO *yb2p]Ypp6$3h5:WRf0pRt4yM|{#ܨQՊ| C҈ p@X?!; yNF.O}^o9pb ߈-h kyC@~0Fe1x~ ؄U}As:\]/"r=r_8{-RSWr >- ðF b.lzZJP76n|[۳ mWU8;'܂* 9~ e ?BĨ8/1MGx'^Cr*X{gk.V׈"s^}@B&԰Ru4D"JIOBa$ąf21>JQf.,~wRd`*;vj/Xm!.Aoh~7 @MZ[a$DžIā{*#n{+oo?N& D ~!y95Ba@07ZM 0 ocSL|yoUIUAr 6%Qӑxg~u_ZlܸIkc21P~E Tli=? Vs꒳^94ޜ{pA"끭r\-Pxz 䔵!F)uQ>pkPƨ]f19o%e=M( "h\SmDf<٢7Ѓ(mf; =m5(;iFmLޛ/#2i FLͻ@0i'}]2M]Ԗ\6 ~+M` #dsi0 ubܽ:CΘkV-SbtTꅰ2`kRnw9bcUZ Ou9&*q-֠SF94j,f be0^G(I'j]N4+FmFJY 0@y~"#z[+_RQǙX8@7xLx˟)]mL5p>q1~-`9$-:A~ F,DZwb=mW />CH %wRF +IKhq-~[s<bm94DDA Yv=:Kt۽Y ђA3fy^@#)Ƒ9|+T*_Fh* ߂cszzaP:+B`ɠW 4{LgCoF:qFQ[%pIµJ kgR!tuns,a`819m[ p(Vgx'ecpF#^d\e)74*aޜ93S$oC!j{ 4qghc̷)^VPgU<{0-܍CB9+HSXڎs3h&ui{8X`,(/G;`>s[W0$_znY@ۅهE8t9 ,{9N􀋋+|W" u'ݴѮ Jق@C3Fnm|pErJmY@#D 7o#'=PH~}@#JU%.צf (6NFX!$>$\u&B݌s}y;Q&Ul꼉1}F}*N\ !gZא֞ĻX#j;]ܧv堚Naw,tF(x1IKmNρYfK]4Jvi黯6x+l9t9'^$m@#G*oP#pSC1. BdXf-s *{_cba]f8̔}@C!ڄ5p?4D_^pybl#x.`Bz/@ a~DE>[pX0| oγكSI}(/@7 kKwA+p~"9a_Lr| Oh& 4\w/F`h E?WgV[n@3i-427f6u=%5?X"T~l 3v 9 4 4f8(E9:Α!%>3?辮6k @In"Ԓ E܁WTNr^ד?X  ÏA}dl9udQ pZVN"9>h&݃h 2-]hG3h 0nU.hhj2-x f!Ps|H1'q_C7CN}+5s!L({ƃ1B$aϷPJ%/\$F!NjG ]`lHX h~0ϵ>Cx( ;!'h~g&Z4^4Cl/ՙP3](;q5HK#;SI_-@cM^G^ H*e'qMD̝.P%۸0.KVS V\8(`2[|M cX%?>.r>3 YK#Vp3ºIz<^ g@l8 ]:\3-=qA& aۦZl I3xl!\ /_ 45H_r_U'Vfed< &Yi.$xb|w&g9PBIPv*K];3X{F ݋7W!.^IXv󶡨q\~ T2oW|Lê{̹o}c9^ΜcW!@cߠ*& p.Udzѷ!@CDD @Icc@Vb="ҮP c et>BD>ϓy۰7|%I^ؕmbHE?{e}\>>svW]Wrv9nqI&"4AHMXPHW@RQHS@iҤ D PNʤLM~THP^Z2{;.>[<8 }R̀4NV+:M% EߘyNvbNA3JMan:h~A_r=vB vɫ7Spzݩ. zO ԻSmo+ޫQ]:8wNY}33vל)TƅtLi4Eual[}M:eҖo6ťʛ;7CIi *yRr_m=;sH͓LZ?]M &(ϙ˱4 6]en8)xҀצsf t-:8ʹ#ElՔkŋ?hY9͇enYM1Q˞+b7J:LmKU+O)'6ijV_,S)VvRUO(snyOPk۵j4EϙKWhR:Շu:xX Γ+6)G.]gwUUzΒB"y_D\\ղ֪R,=5`K'iievY\U{-xۀ?e}^~/ LtXM0A-5%Nl5urS v7r/ ޾)%SI~/xZQZ8F{&)g=O)֙1ףƮ3&<tA}2 yQϭ^=yٕ%u|"ui2/=4`6]kF G̒3~b3Ͽ:5Gj]McẠ^V#,քȩXYJҥjB74ˋ8F埳,[Kwҩ9=Ljmi 'L]&ɹ{:u+5{[h*4}4<~D_0 ۭ.k޺lGuX^}:U's{`VcsԪXm=1M~54͵v9 /!L>8/_n\G>{f ާfg-UG]U#8 -1x~B0=TrBXSEoKe}mI3V[$Dۡ8oEDTn ^)O}Np_HU/L=CպM-߻N`[z0Zي#7ޣn=ZY"8(J>D}.5.xh#iM\VJqД}`dmx9Je g/iCN6 kԸyBhn>'PxAsӂ&%%\ћ3i5Wg'Wx[=osRǍHUZ6MhٍQĒlԮH_<=.G-H5?9 P=g/<<֕\6/1xySkxفz~Nr7F[OyO},AcS:c?j-fD-ӰrK _Xtof6iOIGg[Mo;OB%xhqD{4@5C*Zj sw\NA,Rnxyfظ8m4z9]Iˑ'@|J7=b#hnFeӣ8lv4oL]+h81 _˜ \/kf[8Z+,g  ]QfMl[Ԯ`o f->g^>oz,+p}h_a\^4HS~O|933,pk+4\&.44!u]:6WQT9]D ;kĪ8ꃎW#@3I <4' A褫mY{8 %߆_z >P= :ny]SS t˴7IJL+rKFfNN_rkOssu2ϫf~ڞU|ed{Υ:"}oy1ǙʴUy= OիW#<\5RÆ ?7h~~(Wh}IeИֵJ2;)qI_ L0xrV#uXԩS'yT(i;=f- <˚K5ꑐ[|x=}˙=fs˜̀:4+LДw[]ڔ>JcMĘ3As )&p䲻sdp8?KO͵>GL8^(?t|%>e$CY9:תuj<ע ͥ}>7]t˾?{uԮt&== ͦu)!!AW\9))I~m/_֥K׉'`w-AS M7s@x&]3նpHЊe݂燩(+}Ʒ*xfjV-R"l{?o9'hSNm\x~ϸL9Zu˱k3NZ`[1O PP6('v:rY d.T4! \喠8h^tF|>)4oEA[3)exW,ؚY']Hꔣ@&R ]%}J4T>ڔ.i֞$g9̀\':mf_/ļH_8%1_qg.(Uwe8q)@HUaM?M 4M8Rq;6YZY}[c9kqR[ߩx<4M4q*_Yf; v53)ڒӁ9j?)x ˊN*PjWwg*"{Yٔ2Asy%d5kۥ1ctأiJ3WZWw34>֫9۷wyZ%eulGmbKż|m3v*,Lz.x4oMsxpMwhY{^ߧ61v$++.Y_67W˿ ft5СR:tXfGv?̀iz\.QzrQf](#ϫt=YihyIV/JztV^UJG)1izlXt:T"'vf ȋ:]wYa;fwg4$'tKs33YwІ|Y#2B/V]\o%j:ˮ'g]?=_LZ>7?-\9:b\j坑R1j57Xs -L5p6Wl-b0200^>. Lc,p%.G;?C-@6A5~1AՄgqY7t)%z<ϘNw[I1n2xI7k6^:Ost|gMãw>SsޥSy'.n5_btgb}+4.d_}6lؠkCȷ&)񊒒j*9FsլY4}t͞=[5kּ'Gk=Y_٨ܠ$MhnCNz{4ıe\(wzFД4=žҦ5c}fkiR6 tmmg+W$<9 y[zML[9GflG=R|ў+t(Z:r7,"'svf(~|$Y,gj<<,_u,{Z8a+k旪}5{֙1C[%s;Kb:ͧ ~c4~1cw}4OI[Rånc?a˒N]0igk0w@)gUcxt( Af; `IXe3~ub1)]Ndof{[ZU SF}F@H/жiEn4garגߊrD9Auۣfpfa +n70ل7APjzuv;f׹cY  sW[QZz|{q4S*WlUL|kͼdnD4.M}MҕE[n4,vג)yeyx[s {_52]syM`ۄFBn`w>t/~ot~gm}29)1 Cx/0%3Ĭ{fX~}hBoVUfE1cmIIIRupg;)rQL6M3gμA-~r{ )|,V-J]Ȼx}==^5or=3Kmm罿9R=?T7u"_ |9tzK y'}- \N ?hO zZOz+Mˉc2ۆ&f Fg?n,)в۩9ړ3mx`w&k+ĝ%umiz#@wwxIV˽?j٪i5GJ7ԜbNWzzdRr9&?w -~Fryk_((p&%hү㳴*%̄ڄ.ۆghNFe9ґmL?|]ed9fĵ+Y sW'qvNK.K]83DRuGᲟfٚ.)bCzbl|]0sڰaցi@ݼ>wx\Ug]#+e _Y|)߾B=?nq;H?T6R/]xg!h{9_|[㶖:sò`BmfPk smٻ90,òn$6Ak03=ew~3;1j\jY[Actej[Zy h)z-#mn7hkkCkLVC38M165Aၿ[ǚ|- t3)ogm8W+G5rΝQ4՝V 3#*;dkyovRi3ͮ!' l^ ?:M͌]]3?(= M +qL5Aso}zMJ|>XeWfѴ4ErhYbwf_dt;1XSf N~zN:ִ:,5e¬4i 9?uT٠y衇/m[hҤI-23f[oM?#3]&бXgG{.ۥ)r8yu*MOv))-w}jZ,|$V3\J8U1mR|9lϼ\3(ɕblD!5/7:j^uޅ:%m)!\ [{Ռ8ΝWsG7XMz/9摒}J[[l 5iħ*Ǖ^φ }|;ubf]hةMjnNw3xZ)yR!퍷vʑx\4Ths&ܥ/QZg}̴?hJYJf({ǿLbYh˦#0dr>~}gh Jsq[\=6POW4Oz:TjN)7*@K&v;ږB롁- +~\jJaizlva풓 'wlm1Z)4JcIwX71iVrۓK\_1zdW͠rX`lcHQk.ᶱZLv>ˣק&_s::C4 : n2T]KJbe|{f_bf )zp._Wl{- :)61 MӀ3rܡWC&" 竜Oрp=k t΅y:]Z%ҟ ߧ}n1e֙9CaAvY+ZVL~m Qվc7 ^xXYxmVne3Z1EEu׋çOߓFLQ܂HE*zASU!?2J{\v4PkSsoL뽶YyyjBS[%&T빑IW_gj7iбbV3g~ޣonyB3Քiv8< 1Qo3'ͫ˺NV|kB)A[En=pz53Ӯlиwj\jѢ7k!==ҋ֩:D{KY޵KM.}ǀIZ)OBE./hB#]p%9.y4}P%MSO3%Wfg.o2tOmր lW3-64[8?Ձ|Pjigt ~eY1՘ϕ'L$1,#[LYUZϵLZ}U5.ۧd+3;f4I?&i5`%U))mHWJ[C>LWj)zO [x~,_.}Mt~KJ4)篆59Q:s2GNS4=G&hZ U|n_׺}gn=ήߙ4+dc>\|ed@NWwoL7ӧrm]Mgk~B. 9κϽ9u*7_[w:|]͖hy ?V`։y=n`m?4YdB\0 יN&NMpLl0=Q`cʬ3iN.a8)ѥ!KpvBWfy<ɥmZ7qWE.s[eU6h|Af}Ξ=GKŌ5fE;v+]j0[ rkcE~sns1] R̈́y,V0;Y[v~b (U9*xZN 95bJ KŚwUۺw 8h ǂhM{gj~e>rjȆŻOzyx|0|csqi,ٷ ,p;CE(^FOLVUeVEIc,ݮAS]lQfUYXuWMh#^:-BқۜrnBѠ>m?_AyH{2[kgh КxO7Y:x6%G[Z, @_v;#{2,o~g^Os,uJ6$ܒ{c.fVR/wBwNG:eoؘ1<`3S|@WQX^jť]e.y5}i~m~ǂ<|;xver$KN.?uƺ7wCt\PZ=r L יaWNe+tHeL5AcJvϧC~Wɠ.infy9JOKֹbsTR5n8.hV*MXy6nk+>)tyMV3E+r*KP#[IIp{ttR`wM-w^݋pCB~M.hi:ExVT]Ȼ΋u}L+`whj8viģ ]L};qn-պ]Y&$R6Gq2ɠL yk6뤯K ;]"m3oS\*xکz!hYr8=&$Pefg)%.}u)5qe+4z<^,M8Ά~AEӳW2hXoJrTtۭ:l"cԟ~^ne7$C]~y΄g3s?cNbZ-&җTۯq-LmnYچM,~V!oSЉ[\~7GݞnVk"e] w33T4Gykϫvy>I̬feO eCY)ѷi9$!iz3@Gv-Ϻ6ϿS!?ܢ:YV/N}L(Cum>M gn݀7StyKCj td`;u:˭^c> ?̌uLttpUA~ 4>x`kĈ4?`Є+ji{]?{ֱJkMN ]ξ>U+&=[KtI?( ΥxvO`7fcY[Mݺu:ffuk3f >\Æ P5KxK۴Vvڐ[UAWMH]+s\ȻV1B ZM=;jM*>n#&Y'xڿMNԣz{%|JZJosLT]Էk|E#bz5%)$5 \'fC9&}t]qz*27:.z=gӕ3THEIԤ#&X.j3ʺPltT}q)n04?%gȗU虜f}ee{V+Pd.=W<=:UmvBѳꆄ+tɛO[FG+P hn~ cyA+4kֲe[heZAc'c?tPkk Ќ?:gǪjX4V+.5W|ܹJ:V pXn4Uw 4|LOZ吝ƻua^^e+[W.GݦO&5*s2a/v$ ZDž}б"a-*֙-׸|o=a-}Il+Lt9gRnfgbvN˓ӑsvhzYB"a:j~oVo6֠nUbG>GyY)J8Y1O>{֣3jzsShײQj_xІeea6y_IPu*v/ǮWt3A4 =S8Yf֯_?֩۬3ZJ+Vښh{YҁH4ݥ h*ubPTV-EDDwA{BkWDzςv}YmY h>74VB)m,_ {ي4[!hj)S-5hBjk-6u5> 5Z1eWVZF65;QSu,>K~J;OA4?dVvUJ|{k Q!۔R=tQqj8⋢c{GY~e8z}?|Y18^(ݵ֥nP&4qp=9IG\ZޣO=4 6ݩ}큟AЄ8\ۑر"{s)ŏ_Ng`ֹn]0 @4-4w[m<yUt,RwSŠ y@793Z B \d9v{^f:7>E\QmS Y_}R9s{u*MOv))-w}jZ&сTrt|ٰ̠>T'}^[M]*) 6~a8܅9(7h|%M0mKwv 4f23vjD[.4CfKߛ%_z2Xm73,konQGm% ^ൊKre]=K^Se_>_l)|Ɠ]JU]- _f ^oߧSYrzʹ3NkAT`R'^ҜN(9-gX5VꅖZDMgt(9MM۬f}pכC﶑,Kbu9úKY *"e{-}~.gmH[m8e?M3z4(:6FS~c9 {̗[X}N/Kazm6%c]!Ye{fNSO=4 r?Q/Wa>U:ڒmC[A߽է򜞩`PgLpms?fH_-0_XϣSԻKgE'Tཨ/V(YNk<8v3+/{*fi9s'J Ch!>,jf[E ew!oz T*h<__Ƿh7<j4F2ӵ=qP)* jd_9cXp9?V}ګsx#z8ZUMZ+"ձszaJ9ux“ +:O/Vnz)\5=AzR[-!D/>]}d}qΩij0]:rI#R_£^w C%73rܽkMMOTGMV7^sۗi}2:wWlS/_~+@؝&վc&x7jlҵFv_6V/>6Vtyi𾊊4J_p?;'^1A @{v~UXYSnWNWz#堼]jL4:h:x85ܚ_N\)pטǂyPonwɽk[ވWySG8Tn(q;E+^U浄ti^]*4PolN33-ߗ%!z,ZASmrta~sx!>Qr׷8Bxۙfi_HE'wtPSnt C ~jz£OM'<]\֢ʉyLu?NG؅=P T}EZMWLX'f`Bγ7  nٓЉ 77ߕ'ǦZL }ik=ѩK l-W'Cz; hնpkKzLd5h;[n݅<`OXfUTuh%UAcpeb J|j>2prJOkW=MCe%;| ccj1FMKQ>>wֽXAT1Mu]-5 UM|Wj^+h'f8  4ASf+co=R3קSؖ І)灱%!T2Ӳd<zCAr@mttnAW `@B tX Z9'6yڣKj7j}C&VѻsXZ_sU4Zk>|ij641vX&}-WaT0_5_BNOz`]4!jfv #%\V14*46z\z^]Ξ8C_ 01T{3JV%h4I9-4}JvotYqa?u AAc'K?*;8~aDU٠D-VۡǨOdD.|=pUjj8ܗ}0.=_шjl ĉ k>YG.[-[OТ֫~ب=f}r^nhF Rԗԥ BCuI9S9Zno`ZNqwb?n1 &`I -}z+^1a }!RQkYg]@5Qi,hz=I_m}Bh.vt/ulZEkCj՟Ռf=ESD~$V_qO>IʜHHv5?/FkWZ4?zM·$ujeZؖ@\<=mMTǣizo=^xlčM5iLX#IgJ`=]ʞYV==t,^VL:3e# `U f,O>A2lm;NL.ؾ{V x5 VNdA(}mn;~UДng4hР uiڅ4 NO:VUuilc]vl e6}n|^LT2%k\Т3q bAsW5QePuuje]vdW/M?3@cnϵSێ]J\"~cl݇Ѐ^ж:8F(85W3'#hgk3Sݗsr `?ַNR_ΌuqKu(> t6-xjB?4q %سz'#'fQ{A .g@໌~λA!hv9@ACr`3A .g@ h]4@4 h |4 h!hv9@Ad3 4A!hv9@ACr hwA4  4NA @A!hA A4 h|4AAC 'A h@4A 4Ar@໌3:tРAn@4A=c A!hA.g@ r A4 s]|ϰr A4.g h4 @`3 h.g@ g AC v9A] h4 @ h!hA @A4!h4 @ h 4A L @ h!hA @A4@ h@AC e @ h!hA @A4@ h@AC e @ hX6 h4@|8  4A  4 @ h h]F gn@4AI h h4 @ h!hA @а4.#h3  4 4A  4 @ h>7 h3  4 4A  4 @ hA @{@4AA h@4A 4NA @A!hA _A h 4 @ hp4 h A4 h@A4@໌ 4 @ hp4 h A4 h@A4@໌ AC 'A h@4A 4A  - h4@|8  4A  4 @ he @{@4AA h@4A 4AA @{@4AA h@4A 4AC h|4 h4@f AC  h4@|8  4A  4|y c& h4@4AI h h4 @ h!hA @A2 h4@4AI h h4 @ h!hA @A2 h4, A4 h> AC  h4@ 4.#h3  4NA @A!hA A4 h{キʬoP_nKu˃|ϔEUf nqY&n{|\4V2h8_ASqTu94AJkFM s k`n: hnZX9׊ h=sm͛7WݺuK4h`a);@(y!h#;wPEˑ|\3hJ A4?ET5 @{yUNRX4(;@(y!h#;wPEˑ|\7hJF A473h* h=S) hnV\+fL=S]vYfU}sC 3 x@{UF ݬR @MUDTAS~TA{]FpDDD?,#PX~ ^>g1ԏ4*/ k:[J++Yak< p4A @&h$ TPP +GX\=Cח  |'uSL] r= xJ!PrzzoO'1,\Z^FWnriP'朷3.^b BY$2qb@Wa-{/ֵ~4-z?o>V"<A3=HL꿗=] ^85i-ч"/vZ~m˕䵃{dM,2r[reyE۹i@ܦI"_H8RM '_/n~X:v~C׿#MR/7H{{lO:r}=2pr){Y/wWdm =$?<-F|]F-%';bA ~jS"I/HK8%/]O,"s7/rɕ1ASTAS-s׽W畴ˏ{skGVƮ?q\Gd[iDW?+gߑD\qoH'ASm2ASiyY|6eдiЬ3hjw*+GeG2h3>)Vrl A{(@{P|=2ty֬=ON%ΘDn!h"5rf)1f M*m7ʎO_lsQ}MH߉ ҾI9A'k Ǹڠ),NɕyegvvɗlQh$h L,+h4Gyl=E_X3|a77#/Y{Qv~uZxy9y)i=AS8rlsSwgd 1O~벦'AqY*h晠5ASĮ i5A3fA%h&M~QSMM6IT%e8R"*g* "e&*.eFdA_Tߤxjll]v)6 &3 "'ǹlj8%N04hhܣHj#hkvE5Sl4s5Ig q]3 V:jfiAa&< x+gr՜-3lѴ`vs=<4RGC5`}g g|hhY+<\3 VZu3|sHФص3?i0+g-f:cɖI3ƯΒẼ `<̂fm_7$[&Y)MO\3 VΚn2-3&S:r;j::񧝅SikFS֦$_lv8[mvg|FT]&=}6vm !:)ڵ1Z9ArRLgfwjˤLif)?ly4=>ԩp^S,wGL:u s@ABCDEof?OgfLef1g&/tST:K}Yh c` }&` i+h;TjKh[jj:l&#X=Q? Jz.֔MW:>vL &\ii#Li[ik1cW2 4Ưe2Q'EfbSUUe"LJSC̄KJmrm?)Җ׶51eb&Ӭәn45ɛr<63q7&tB&T@DL%3~:l;f,U46~b ?*0餺 1~"CƯ-L= UU0ɖI{3Q况6fK7c{{gn1~,ۄ{fƊ0ɖILAdi?.3 f>r|0k&^r$GLܕ6zd fkLAsGԤc&3A6Z`Juo`Q0 4!3DŽLzpό?o 611IENDB`backintime-1.5.4/doc/manual/src/_images/dark/main_window_sections.png000066400000000000000000003007041477034762000257330ustar00rootroot00000000000000PNG  IHDR4+9܍+zTXtRaw profile type exifxڭWl1;h1ȵ {"&YžMV s3fw|&Rs+|j_l_!zOts۽߮St:_oo4"^7j^7ϴln|߯?f?b:.Xo%˟!4Cb.rBަA~e_ 5/^y雷{+%ᛑ߿|ݸ|ɱ~___F#f}ΪΙY1u~Mm'@ռ' Y&Zb̛ltצ8 8k&l Ǽ)6,FXUF8d7WqSUG-CMB㜣*5FZv,ٙ׾uYupfg^v&T[תl'gdk3'\FԱjL:J{,\Z{ tQA{ {fn[~&aJIHy)2??:6OW}}y |mKp(h[Qnmf;I. MVNN ')'˖ i&a3VĊ*m= حLt+a+%X,`é-Y.fuEX]59ofK pYM'beelH\CapzҶ沌d5$T̘]$0<03*i[e.@T{1}N3\N#v-7z?W#xDpQ:#mpZ6b}N%._{<) 9sLw{n4xuvA& Nfywe/vnJr_W% z=_HZn ;i QJ=>?~6 *PR 2q6G."HH֦n*j$3@ⱨJ9@Z,'@Lf"aaIddɖO.%8ӌ>V(!2T頥wha?Zj^K[vpRQonV(T agtZ# ӤpԮe*BY e]ؐ,&KVXB% e _ )3D8,ZރBkAݎdl{7VҪZR7S+k)d@&6 ѫi[UD/~~z=STΑ ݈0PpJ=րwӦqۖ]fC-(ȻAZhjk;&.FD9I9%iID.j[B{NWR/DTz|ܴ`$vRhIX՚īV3z]qRW66  .KH{3C:M-'GA1< oA8e;i(J\ZX:%Zed}t*@C@[H>ȝj#6 x"\؀4m>SԢ+øE-~:y`E?!|&M<`& pDI !KE]m@),[#αbW[ L$EhJv4Osc*}ӪJREx,z"fv~eG?10xP| "2rk 8T7ciYp,Mé\A 殢W_āTw)|@lzCi!n3z\#eK+hu('Su?";  $0fUZ)~B:ݩzAVl\-ԇ˧I(.BhgPzʊF ۘѵ};NĮHڑ[-!$InAh2jEz)D?0ZSr1Bg%.s",g_wD-rkFlczB@h xTS{-5cP/By u̓AI cbF\Y͟Q bz/[I5BQ-Yod2cn&mhAIЩ"pF ivVwS n {Q(hxz3.׊Nm<`յXSx-,s ) i\ #a pէ+zUR I7;$jlP ][M.k[DM=s)RN)nھnQiA8nikˏӢB`NR-!P)xT$6OЭG"@PZDGS 4u 00y"@mj fS:-oPd[ȼ6Bn5"^\v>䥭)ҭܔo*v{,kꀕuMOn"sΗL@a ",pd-ޝL,Ҡ -{<$I8),Ά$+i 2C] +:Oaܡdzb 2 o3N ֙J ="3#[tV/\c1@"jm]-R IS#Ԫk mW5EL<d*qZ!z];&vKL-hk~`F( ҿdO'o":EALȺS5E8LZֺV0 a weoOo'}6lDVjaP*'zR+7?͊lT3ls+mmU)=up74Hp sJSLVssDْ$yb7'&=Zq<(S}VnFGbST5t^c^qct`hA(KWZdkSMPUx+/QsB֒:US#Lyg*:Y*E;ۯ0 N^=P7I9 OUlm!ouZ0"TmY T֠H W"P^##My64L!HOR;4NT3RrH"XtJ(wa Cc&"AsWQ Tt2W}c@+ZZTO[@=ZPR^6mq}wm>\k.-xO0i'֓OȨ/ 308DMO.rOPǁ}U0OԵ"c@Ӡȝw;EIw靎:B ) :G;0/Z:^_m} Ez()ICau8`g Y%iaR 1K]frWbM,q?Z/t0_ˢ>%s¡x0‡0QKiB-"~kH#ɴ0qxw1q4**]dߖ!tz.C0N=76:*sV&->giOߛ>lk}!u`[ Qoe ̈́Ƞ3,#fI&MKfk͐:5a8mhBYY4;ptyIM^^'vFF-Lc0ğ'cZZբ5ZR`>s|3#Aˁ|z݁äy EF?FmUm#d54\B"݂Dv{}~t`川.Ye#&Vin}ܮv;yx\~,65=A"Rկ!bG!ROo2гL ynkl8<@inac꟔U!,%CR)$U&Kz߶ .zJvZ DMo]|M9jTC]}j^_Rs[I_ f{e4 q{PdçVwkjV9mvo Jei/C{4%FZ[)ʹ(:ɌWygg>]wЊS[m`^RIFOyJtL|DrC_1oz~ G55s6\$<{Q ec ?m]F~6O>lQw&Eߙ5g[|1ѾuvM_Nt p!; &RjR=RhvŭBmU{<ڪ//#:ƀjZS9yRK:.SjNCotf:X Rǭ*w [)z^ˠ`G,wmmwwo> Ot}{.ѷ=C>\G)FpI ]*wh/@Mh 5ceotdo_nK%Zɼe',},Ku)Z_4E$"ڜAqm~MJC"G+}}-R|*oi2i7EB:?" :d=N^,CGiCCPICC profilex}=HPOJU*v(␡:YU(BP+` MGbYWWAqvpRtK -bxsx>@hVj&Ut2!fsbЇ239IJ.Ƴ|dO$eao7->q<9A$~  f>Iot0 \\w4e"OlȎ%}SܹqdhV+Qǻ{oO{~?Yr8 iTXtXML:com.adobe.xmp a pHYs  tIME %,uabKGD|R2FIDATx\ڇ7/=QIK "EW4M&1%{!H 3,ú ,ݙ93ggfAA֢<@yE~ow+O_;L)yGȼ[(KX`   ^ 8)+ZSJhʒMDFYb>XP>FjhLAADC]<:JS_$8rب ɌȨ%"9AAAuv^7V਒eԔ*JfQqDFeKS%Aѕ'G_D   cya|/+ XrFqFQ'5ǨqR˄LCQ$F,1E"r RAAAuva\/ GO$9b"7 E!MֈSIM2#2EAdX8:qsџco9>EAA! ] vrFG$6hr *Qf&ODe2fdT-[̕H$LMMannNAAs!Kȣ;ThԨJ?Su2EgT3Viu LAAU@ e ㊼RPL'4PJ5pk֬YAAD]LbL)o ku͛7Oe"wqY( /4縉;#pvZ@74AAQװ]~T{s)wUQa. sRfqtƐc"  De""ԏCOO9EQQ3!Leiъc U7##ۣYXr)F Nϙ]*sYb?{0H QFU?qPL/AuA؜ܬ{ӠvM d@׊ jE &Uaooxi ri)w8UffDR jC mO㑜 xG`` /g"77f@R5Ři>rՒ<;ƅL}N*ATܰ$B2%GY35&,'Ni^[ǖuꤦ~0H+4Wv6@^ل#nl 4< e,>A|jr?^1>̺7$4#wDzz:OfVqNVb=c`o ~p@Dmaf?ʒi_~%1k֬2UA.bT@9L!4Bu3t33AtcA&Ipbyi1;cIN0ⷕk1\|V`t'}陣{J&56 #eig.@hZtF?qc&"##n0+s"pKNrK ˒-87)JOS0wb</=_ h?-5s NODZz2bnʱ] գ{ b؃!-4fffZGeFPMdF~0rڙPL!4g$tcAFчM< G-ǸbSxAȼl1<ԄXHIů\/6Yqi99ȸ!vEh}d#-1^"+VH'4$ efq$#E qc`syJ~˯#[ǝNXD(;46 xm Me比Տ !N1c"PV~0Dڙ<舄hGAIhs9ḻ%)vpr)ܠ=:qp09,2B #=4<";Y!)gER0N6dԶ뙇`lNpp`~շNfNck+npۏ {} %B$wڙ 4:bQUh%G0AIhxN:sW"13<=m؀\KAJ"by s]a 9Ȏ]_C5sh6/cȅ&Bn!_ڮa8 .'02dT'/7W&ftA)g$,X"<j (F U3 ΡՃxńfwЇIVesFa8S,48 ܂LhOK5BssaU# .ѳCМ֖ =' /^ Jv/(BC+S]T(@ELn\@!4* Xs   O؅Lha8LVplY:YKeXro?3~Do?,ʧl%-~o7Mٟb0 i ͚60Jg Qp& !uB'x1bӋ's0mOx$<8]ē ly\6Xp=+5/T Z /GD"JgJ7+FdP̖  VyAx?Bc+tt3/4Aӊ   taaaQ;kK\?TM+5ϢQ+4&$4AAD]GOOR mDDr?Ƥ"BB$4G(AAD]S}MUP?B*wKдP'4:$4AAQ>0{ {$3k2%UBӜ   7MB\4  AAAHhDBӘ      (4$4AAA1%!    AAAoPh"4 6AAADMu122AAADM@BCAA AAA$4AAA$4I2] zN'6`\c:u I[ Yۦy@J  1<gQ c6 >.7Ya-uLX|[k|`Bt ,0xpq~[D3^Rс fχ cv+p/XV] y(,*«\d$>0ͫ5$y1[0&FFcʔ)0"=YjzbDT|ڽ B wSK) AAu[h:ͽox!xd$﹇oWAd {Ϗ#=FaI,/ζo/ mRQu_IBc1QQCѻڴk7 Ȩ`NBCBCA ލf妃1I[`cMEAac.a>Ep=(̆,/nׄF~ vh+)ggaNƓDd0?w:3(}Mgfe g 932?;u3x9<>K,ήŘN&urq)Rr v񆃱vSd, ^~pU2 yMȔA'ESo q7'&wΩ̄L<2 3Oӗ+Da^:_݋e:\[BW!qBш RYka9y" WwAN0yX tBhG(Xo],RW Qa~=ƼDw(HLWu>1hSaXs&"7 nBOkcBSב  7&4v{cA  v ^ȉe<|+ ~2B0:r$zYǛxyKi0v8Ã0xEAy,ՂИkS? 9 (ww~8rg`!Eoo@~զ ?2qku K"O MkILXwX SK{8{0A!5Ƅ(NK>ĩ?EG[$mTÔ3cIbQı/FGE`Hh[=4%]C"KGp? 4Rx,Y:+lsuBS]ב  Cs{@珑rJÅ '} )#H|7H}ts~R723Pzae ._hL (l,;e0bȓC#wS&02LA'7KQ|= EԊOǹ9şa3,Q309?!UJh{ =p 4SD)a#I e ka6ш)=H<0 m,j1EHD G\JR', c.)UBIo8w`-C`÷"Bc8~UPꞔHv,Nu$ MϡNcZ;)GA  5d q7c- M>.؄kxq nUo l>幝Bc1n?'4!'4"fhtwsа93bxH%\[.GhbϦx #O7+]琟wa6( 0=[; ]!j0x:HB-/XsCј=c|\x!R'4](4N/fU,[LytW'ݜa+5Xhs  yBcewQ{[!`C<T y&aKuU,a3h~>[)4yoH\0 棫Դ!rڥ@Xk)g3\1 Ďs)E#?~3,* 47>ik5zF.+>f=9 7s~ꁡQQZG!*"E)g}06S)g݇r24³јgGt{5ۤ=Fkב  7Pya||<|"f>B>XKIda׌! ~ؓ(S(. 0u2&AInN?#0 'GʻpH*Dڵ-=&~~FNfJk!7<(3Ux};`T?°nkEd1⻩ȕg)UH. IQߩx0.ǰI8^;}۶h ŕ̬]m[;q,2(i ј4|:o gW7aQ6nmѮD"rT.U@Ih9s3Cv.ܽU᝚W9DPr!2nƅp<" |2=dzni^G  Hhj4%xr Wզ(FBȲSoԍ' )yHYc[ Zi1U MqjХ{5itnboFtc )+~f Y1urq}˳dE@OVТE ۣspwwa2mS[gӦM{QF! FS Z5ԦLl 6RƓ.}1h3x\F/C 80f^'ܹs1oc4lذFй1&73ύ1/{?[ީ%BØ߶kۮr۷Qh;ܣ1 A M y4gY­/R3KtX ɴ| Й|:g=[pZtQ[aoНq _LKoTfؠ{&C]vee2d~[mE~N ///*B ~1g{}'_Ouk-fN4s:>Ѹg$vCch@l;7y̆|2$ѻw ~~~ aaرc.\-caiia/Ob,LLʊ 0J Af |ٳg5jT"59߯Bf~m3/3,jdd2iYE׷17,_fـ]ӂ~ٿ)ywXJ!4o :(4L`04¾țKALYHM2m/ˣ2 '3\1]ѦM Lpp0/(|ԣGʄmɷam>tp7nh,4 6ͷ/߾}{EU<==qu^\EeEFAhXݻj\hؾ̙5U!4 } yҪT2䥁D e~ל|x}H4пܧa6?T+4ħ(o '>{Ui >b|>BA; '{}pO?Q+fֆm76@FPȉ^>w\6L1P*ڮaEG=Zwq_ QگꎺxxC Bx14.)4sU:lJaig:a!23g^0`sZMcl[Ƕa۲6mUﰶҥK԰H K?L?1ԉrTFAfOl׮]3Ҧа Qѣ\ Жа4C ʌİZ";~VsB[Src:kпagb,[?hT!Q&G_VȟB>Y偹6gUI\Sv9g9)R,<3[_ (L= 9|~F#4f0}XHr8.DcЉRjL|gU2``Ȍ 3L*0Fؖ&Fl 8OG*Fϫqt#6߲FGcZ-U [Rёj1ү) 'zHOӭDc>rK*٨Ry&OlLeL)g\h cs3d>aUnW~;+;EX^]֔ !ΧAjՈbC'1b|:.:X|}}=A_Hd$Bm_4= lEqG3鼢`Ѹo̰P@H3ܹs/0 5GQ l3&!b)0**4lbիyi˗qM"# ;ɓ3׮]+bڵ2^l?-(%3ش~_ҹYfUfvJ)|5R.]i{n9[ RҒg>#-pn䥢B#pE/+E7N .Ѫ$؆ELEXD8GS=r2Q^S_w J9h޼9B"lqOqReխf(Fo!1A6ѤG8t.G|H̬ aB!͌E[̰l~xxZaτBlU? 6*BgB#Ȱ,rtR> M9*ö]ln~^dXg&Dl5!4MO٣\ٵctQ~}MnZ:FW/'b}3SoRhr>7!7ܼKhjDkHh>}-5Rba(Oh_oωjFRK vZ&F,!fsYҮayXRz=Y+APʙ8¾ '8uϧ7VV-h`<[ڡٴtV&UZ~+d)$U.cRǰk*5 ێ탽gԆ(UgkNՄa[lAҎHmgLv2`)lnnn.4byk_Y=s 䫠 ϴ!4tJ ͋;q*bN7*s [jtRPKM Rl>FyB׽Is6lNe򓕪{%_P2#"lJUU-4bٳ'_ny2>?x`YU {&פvea]|3o^ kScտJ=a.89qi@Ssm Ԉ!<嬰Էa&FHKZ%#4iaQ5tzAP3 k/\O\q epb3㷭1F)=Bt:)3 a 68gŲ԰6B!BL)HԲ;wxxxBS<FRR\s P)2bIOOӫW/ {h&0aK wzV(Ec*l︒hcshS ~{2?_sB^2~m'rfRtBL+({"4 ,k.9!ErVBuB̈%,gA5uZI9Ӗа2B,lSjeL>-ZamKX 2mW bđVAvōoq  9â3`̔䪞$&2 /ZR3D-N9z:t(ϟ_c2S^ʙR͔3UrRB&'g܋Ge?74_\hlΈ9{>5Bs~*?4Rz2 W6C/^zAPʙ FF0n3|Dq.nܟ 3nOS6(46As+77m'OĢEjLf* PfQd+O?"$2bDVVn4)G^0ʬM˗ZM7 RBr/pu2sNq8UjF4zWm vk} ЪU4iq73l`/NS-p_}dxŎ{s*Kb"k~ٛ(Άn择75A> iР??-biYBðoC,ҲEދ+g=յ/^9ȵkN# Zr&DiM(4ƦhtFL0Bj\_CQK`\zma ceIH*VўFH80?jlҭ̙3G!*,a\1kLH3cYfm}}}+%l&W5:QهT#sļ6O *a*i\Uyy*5lP!3LXX)& {Daֽ.N6(Z5Dz?7pif ΝkO  0`7ʯ5B.},?gAc0k ʞ_ֱm;soKWXM\E[pYz]^GyG:-oU6:6>vHHk"Xă s`nn`E􅥐1a) am>u* KcbU~ȑ#q}3?QRS`"2) ( 3SUy`vaƍ|ի=wmRlm۶ Zk۷VYְ>į T6G|G;>Ֆ;pl tʰo_N~-l8oAA=81``۩Je`qaԖhx&2<5[iJ vN n#\OO֭a쁜l]Muttx`%Yb煥˱>6i҄޳$2AABCBCAA h   Hh   Hh   !!   o=tN  j$ ;- %:O!]   JhEh^vJAAQSAAQTY;!:ϫ(h,4=  Q-)g|  x몜 AA[+4ښ <@BCAABS=8@ @o -"CU7.N#P/-  Uظ|2Mr~l9cCD%x3_   yM!Ca~.igWGۓՖDŅIMh^hmzbҺx Yn2\^0I:yY.Lv߳FFFqD?6wg "$ \q=I}|7= GG bKBC0DGeSDH\},']` _ ?$wr{`ɝ|$o s~&]WIb^|<_֢/B  =(oڭ[j}F9%jXYY.d^&ck8`xB͈Ӻd`|2 v5Qq^,Re(,EʳKص0&8p!+,#̀rB OE:7Tu|a]$rKK;#|rBSdǦ}Uy.$ Er5,cИALA<)io-q[SN`W J2!E2G?FwdOj "$B#HhuBcީ^PډbX?{7HqE8Kq{ ٗsIb w)$f\q,Xx׿TWnyqgJ ͅ )Whރ%-mµ=b|g,a~jqW|{K8ۍXZLX+m +0Rq>Kn@s 3:[ajd^ "ףּ`n\~x\nz]URmǍE_gz}6-*zNٲ pzb]zю-Tq>`Fnު~/~sEQ`@Ba:F*7e 2H[ '<,o}wXªtβ>)O(l{x-v֗%4ps zZ5xX=5k]~4F8kd@D;XYa/Iȿ}lǥ> MB&a#Ͷ4"?7l>2=nDyif\+T݌ E.+NeKE sa֊?ScQ%Tn-ݸu>|[h5I9[ڼv=?Gc 3#rf۲*rNeܭ e~vfڰȘcN&j#g_\hl0/jӱx, a}CBaa0(π8q+ MaKqsFz!vO@G+n6}6o*F Yz/ b!Vw} H_Ɛ bߣ\Y_b2 r cc0xDO D[ǥ> AQ7&ѷX K9ʰTrXs3˪*4%12cQ&dS=?rc=(~Qu\@}(|Sw. Ӏh;t_fA>|?ayM(b[ǫWIwa?iXh Rn쥧H /1NoDGaW\<\l"Hɇ,#Ww/@pGQǡ:¼T<=9^$4ADK9cMIhRXt~íi W"梊"P,UiWs^}.s+yQs~!;.;oRkQ{=PYuz AAMhB[VHh.QsJDvsRNK9SrD&ɋT]EϩmJϕKS~9K\ 5Ɂ*А$4$4A$4Eh64!viƧJ=ФU2BV5$iŋx2?ۧTrַFBC%IhHh KS +ܑlQTEHbH#)0첺0mWszDI94CE5) jlė&!)Sh,,,CBCAB#^Vح1C[i+p}C=cY̋aNz~y:> 4ĝ%ј,iOVmSғ967h,$&~LeUʂ/c!SaYV%CX*q7b4匄 ?ѤIByBcee[[[A5De~[դT(K1bru9(/s[M_W~q۝Ss\ UeU䜞뫧>vVv{Gq߻Hh#X>!Qo\,Ayw,a"cffCCCjՊ a۵x-BI.#--4Z'0IÑ_\yƽ~7$6,Zb{&x0E}Hn s*Y3]*/Vv^=ܶA 8멃6jQv=?th8sZ[C+ҥ)bgϞmΧ}Ea> Aa_J AAԢ3LhXȔ   Hh  HhCh^fb3>Ji7!aO|./QMp#! x t?&$4 AA[&4qy8VxBɉ?[E[w03po*~϶59HCxqwk Ӏ !  тNEE8 &f|rS.Dq865bl'IeA" 4¿I49t[#6xOgԉ+>0qf=cF(f͓L"<8"i[BS/< +ҋp|9)Ҡ;+ d5+$D4åH=2IDd'|]¯>_$ AA ؿK$50 f2,^kupHаn %QP<-“B|C锳)E9$/ 8_z; V#3?KSQwƄxc2.DH=%6/ ?ADmT011K ͧh7`# D^ :^h5|jYyu/4 ^ܮq4v苦м7vA˿01qasbBツ,5S%)rS)AS) j+ ķm:;YYLsqD|Wih*gXA.KfDS#l Aq81rI>_k yܝ = acBBCAM1˜XR;֭pDEEaʔ)Yv4 ڎF_7W ƣvb^z=(4ABmq43/ vD i$l @ ⸟q+z!?4i* ,Z^=Ϙe^:x#z7Dv&l~ZY֦sd#cq74hz8#hb rI-Sg  $cyÎ!y(;͖Mߋ߆m[B>OϞ=y:uj_cb_6Q8y gϞ9wΟ?s/ҥK ;'.xvl1>O5Zyznv7"fCo~w6?[!3l P6CU̱61sꪐˌyRSSKC^fXf6oތ-[3 |79 Y]\[Tx1 ј}qC P[/^Ľq_7>ݽOPX"8 ("SA1ς(8 88΂Fq@DPe*fʬˬbr۽Žv?d\+sU+_}߷P ӝԇ]?|p&".Vš1l@aM%>vAZalRZ.]qm{ +B(iBX> GʊTd߫@C#J'X=7T7[܍Ɨ73Fnc[/!L>'('3ơ><ՂڃyCzhTOl %NHa }7qhͅk(EFeBӄ;:UO(|]\/bw(ZٚyF8H|lYΆ hFQ͋2ZH{n ֌=nBcq{-߈E\1MŧΌD܉wO,Joo3nsYoA"S_3f sYOP_q_r"Zַw'?7K1 kpcGC%fBק2\+,G,ɼnR=xx.=="Y2"P.wdBt;A^u؂x{C=eaqg褘{lDeJs;c*dZ֢WR\ڸCe83; j}̵GZ)S~0`-RmhG/!h\. m8ɼ1g:<{Z}?eK%52oI\HϞ}C_ 4쳞(YM27P WvҤI:uV 4if?(30zg {L5ԌUyh.&@3$Awcđ %h>!@ˁ\'#{'&ɏw >2S2ma#9=1ܿ ڴ?a!/enwu2@4>|Dž*誽pUw&0:g"^2.8JcFǽtxa`%_ⳤ/E/BJݎ cn{^),G TAUD lz*FKNH1QNH>]E 󨀆ƻpV1B_fMMV+q35xފ+%ukpơLJE(HR+B"^[GDL w]9"J *#YuϢI\TEi=S.Ypǽx/oXE' ZKae/1[[#Fo*@taf,Ex{5 G!TrẊG{/P͘~` |z2퇥%萼ChHe?|~>H>|qRn9@#3\l o0e뜕ysNV܀ݱf\h-ӭȋ&f x/F`'pG@#4JGϬQpXm]qxW@y n=Õp-N\MOڊ^13Ny01eX) A2lY6ʔU荶hXxYti?a=-< yvHJJA<777,^XM1a,ʛ 5KHH@xx XEFFʠM3Lf<ɎhJ"@cm %|~~\ h^Խ9?~\ԮuV3 Ewm$(<BLB/VSMetƆbEHfB_WYc#bW)p,xW JXƆYwpqnVJfY5Մ<{Ǭ.!/35"vKX>u͌1v[x0(F(+袵 s8H& z|dHfʵhVX< +> m hcy,0g"ķ;}]jh|ck  v0Pr q*_ .:T ? 4P֗Y?#=1Z%=+ƖhXh:g 8aOJ|')H>CR _0CZhץQC ht ȭ8t i'ebNr|9?䬲 [Nx1NՑ]02YKS fX 1?Y 4#UBhaF 4wF3oUa7P]TC͔0s9LEf#]G͌?>e:'Mf~ LWer 4k5T ,CraFuP5pSMނx'iGpppP,̘d05Y>Lc+1Z VaІ6y?ٓBsP/B'gyVpơL)C =qFۓHu V-ŝRQ^fD\8:{a[~MvQ!֨M]Wg8P}례&^+(Ɲ=Wr#pa:9qmc<1s-nP&%祘?kQDuJ@3sۆp l ("x8Qlz'T=̓<$1iF@,=X' >e֙Gp '+ضp1KZt얟.W:nK'݅9){cT}w_4,EJO2OGLcΉH9csH?Î <jeb=|ƖgʲXLӑ1gH@cii"ZfތP3m[4̅ pLv^ChдTw?"g-Xt onRxWN"鱅op:I8?E ?Qqf%`-Ӑ?`zdp EX`BI{]"T_\?Bv?B c`fybb@c@=| S ~W4)9(iED UX?`.Mg@,I`*~q48jt>H ҳı褙5O,1YA0 }(v ;]}/|%1>нmXYV{B{t'am5me@ē(| q_n~zÁ0SI^jNKFr;UhA1b [n_mU(jDSM!I 8$ʍ8x=L_DXSq6а.{nz^ ֿѾn #W)X[D\ ߷NQ\M{"d3oPY2 h0??O?2۟d#ca˲(4l Q 5̛afhTaaw4\Y(\m=$+c1.elk‚A670`e@SU԰ƥlq09,gD_ 3e\+S+Hn`@~]/U]Cw5]"]e'h5N=o0{Z*fbiC4p6fx? DTx0w _$' rVc-8< !̽%"[݋7W7^˵bbj@(=E9/$"""""Fn3y=8zb˖-nѬ 3f, p@%$` .A5܎Ո π щkv-`mB$( AtR*\.E9W":8Qج=O~wI|6L8^ʼ(x"65Aڅx{I d,0#$xmXiQHXՔЈ* B6'zF+ pN_pNEc_^7WLDDDDDߊ ߲toOLѤ4CI0&3-#xshL\a:m>̧dwYď?8?hq!JDDDDkKB`5 xp7p~O2ul4DDhF%"ƺ~ !3Dh-h3܈~_64DDDDDDDDh """"""""4h}@[+ey;`Q)Á`nW4W܋WyHWC9YWلnBWCL7ȱ w$3oWd.}D/36i0# .Z B|j9] ,JnEB{avzC_Gզ6|H8x :!zR]INh+Q#EI_ Q}v^)vhQ+^FωQߓM胖7cD,LDDDDDDDD*yXU-gC a ).‘: N( pupf TrLT*p#)oOwkhFӮ8 S~Cz*4;e=inˏy0F6J et'r 6 Z;U9 l-A\4qU9Pp $ezp )Oݜɺ$ xʡ1j;Y놌"U v2u0F~-^?nyhy'w4clWG1Q]Sf:P<,)xFzڵs?\Mkkl> /v\0/tׄ^0X#yzMfX ݍS1@칲Ձ)LM@wr~tg ya+14zJo%"|ũmp=2^Gx.tac q^4 5eisXŦ6,j_6MWhFi kFn7iθU ~<)"""""""q4؆ey<+!Ă6up49PHqᩅ/j˝5`[i=n4v -f)9xك=at1qd=P\ q=Y@fnsc⊔xq:'!Y>>Z]x}#>)L{g}7@Å]%F"|!K#|z藮%FW]s2Reϐ(J.Zڇ}RHÔyFmWfm)u <NEs`-aIĠ aBi<8-kQ֦V1u'mh '訅Y$Y 5П,V"1]`e/@H"e&7e_e?1""""""""aUT1\/{pct-z=pQBdqWυGh-Ħ G=sL}f#x5wYs)G#;h^@"XQ:X^ ]SYD{I,ѝȋђ3\M.ۏEf:sjLmTѬEJ"L5љǩZeJw0a""""""""mk]~6w9Ӆ݆'tti3,%Rczލa(MȟSN%"""bȠ |;Yodh aon]YlݻUgHk=L|2`ՅZH{ +$P~,N&~@[+ey;`Q{`nW4W܋WyHxW YWلnƐjCQi96a8d ߮\C6h1:_ wg l{Y0\ja/h q(Yze x{pGզuȃwh9L 3#:4DxraY~q_o-PtKL ШLf$"'Լx6+郰 :ĠDyt ],ʙύá 4߻:< &M{ uА=hs}Q}o[ažós(i5'̀ټ(8aO#0/"|1La5Ґ;9,zDDDk(mYˀFRŨ=) Rs.nX|ՍsV Io3^؍5)'pyuP4z+pclx` Gf dMu\ ,7k,qp+]Mᶷ^'ysM>e+]Wi` d#}ZF_':!<wC0RԐ/jidbHvL=}8uH!6=c˟13 +ⳘP@cER|V!rT_@Ť[Xh(c+ HBvF/`l6:M?#=ZP3hhdm|̟ٶfL p=ٿ D,]y0-Pœs>\$$D_i]sC}?"ٔ,DDh=B[;fڀ1 dOx):$5\lx~$,?}k*B ° tI? _nHčfnlCbH(3!+*hmz%n.\)"Eۃ7 h19:rg'煠ʶɄܮƅ5B87Ib<d:/Eb_YfZ6 <28а@U H."X W=H '|^\gRI@,DU;I x{2^3Fp@3v5ę=oh4( Z)QLp#X~L60VBm(;m:Z^K?'1IW)T a+v _zn]xTak rFחqM-_u?CLf)dq'yIߠ,sckCnb9QWN.7.;_e<3P%@n #u쇛@ۦ> ۓ2W$xsp!&gsM#N3U.Wz1e}hn nʹvX[HAT&u]Cok2@ ,aO,d$\lcbB RxyxZ33O}@\#p˝.9<,[$n{&z(PCGG2f !tEDoOe s٩3I. %eso)^$  P8qJq5ƒP$BXL6V>m@ѝ$XP8ɡ1ԫpdc2jX[ i,YcҨ?㆘^ip2q@3vu-sݵ80A+Hhkf%hk9c,Mh*:@6H*vbn=`|X5YG#Dnp}^vOJy ahFٗDe"@3,(Ӱ06!3q2_C'7ee⍘S,if؀dAT8#0t_ 4cx%Aۻ8 <%"W@#q"'IhxSv*!F{c#)eNC k%<3E{& qƇc>0eַO¬)Ԁ$}L=@ʏ8ƀZodd]\L_Kű' hI g+!Oşp/i# em'LoCV'IgH^<q4w5 ˡ@?<}JTCt>zua2t7"fk?oʄE`ϕ4Lajn 5 .< dNS#)E{YB&{G]ҝ%4y `PіMAT[zg*n05K?>ljcHf@4LOШA6h@5<|4P#i4s%ĹࡁV+(NqCsx@A*,Dʂ aKD4F&A8]+spL 4И!t#*uFr1*Hz#y;1G֛8#I7n:>o@c4Gj)9U]h:FC邽t3:FYTL.ہy$z vPSK(§4•η~Z"kt5:'#Y[P& )=£}']XŦLK:xXU iS!2V#@s݅WjY  ,Z`oK2QI)ND4ހ>o@=T n An/f=_|a:_^@ZB(D&bbqe@m~=tH>RiOа![J!~Bco#Ls,:.zOaOuvYbta\HFf54Tak rFH݌X꒐F҉oCkD.ԕrH /.c M\Hk?$!1*p$lD~u"F@ lX0D'H~5%h#Y’%K ٿ!!! If"##eb&::v."M0BzS)ؙ >frhLe AG!oH0 f_Kb^z)Zɀ#ѷciTvTQM@=1KgtG]Z8dGZ^[,Tt4)mT{Sj +G 4!lStKQҁΖjYthI[3U95%aA0@.ByDh2BSGFa3'*@Th?SEh!@ f@ 3JQLLL &rf9 ' b jB"yD~}p=:N2`B :_hdX+=@ici] h8#r);) xYP::͎Cf~9>t jS1&w T7Sxuw?F񮷆s "c`V3$|41enÈF +;_ݠg SSxu\}^ q M45[ıGj)Eoq*dr\L|E*^+iXBC CM@maT? ,/@_I*-hT`FVİAd5p#hO.M*N"/הgbV m`=)Zk8#cR 36lb9K8f}쒕 Ħ&1LhF=-hjx-!zοMhU?̨zg0QŒhVsΝ6퍀@@{y>ņCm&1x أ3Rj=@%Ph:;4.zpytPO5di~oSҵDjuNF mA34cSr>|.@d菅phՀY[@w]C$OC_>Vz<"H'p_E&l嵵< 9srzΘfeH Le=h+ӑCF3g !gjBF4]ځɾF~-ֻ'n~=&,!@CD4>Fof0#IC{h~s۟@.$xZj=d iTvw$94/ .. ͛3]]L(Fᖑ{Al4]Mх݆92*KnIoCg Wk+\qx?n ťx? b\ p~,O*gY{ "#{6{zS RA)Tb'.P-(׊(U>_pe:yس\ ؼ5qjm}Saʐ3}fT0 ?3-O@IFV1uyRHc 9#LC ]4OKƦQT5B.1@yu~3ji9$f#ZtDS"3ؼ'$mO2K!$h,I|dɵl" ֯قx\~\.\WC%OD2U=ČaGKPS#N=T@[/]dV=iO}jV9SzfXnژ1ZX]lNr5%mo{, ?MI$G[7| iT-(:kB2hEv ! (h\څٮ_p,VZKH^oO~A\(ԴMDD_F1ϻ@DDDp ElX0q+@^h 읎*- ^puEDI>*gXvz#;a{.)NtME ٛcbw[!o~q"/qŲ)xNr 31XWeGBK4nf""2@CDDD1/ 1sK3X 1QQQߝ]7CSݕ.BΛ&t!Q[0@ wrA Wl+I<6Drf>Z$$-(=Uj0K!މ`ree} 7 ١8ubr='* !""@CDDDFY\OV=f6 3a4,&݈0ﬦou{ 4DDDа200w}Xa!t"""4DDhr>@-DDDh!@.o1l0[w""b!"""@CffϞ%貉+V) QXX<==annN;14!cDDDD}!@z[X,qƑNDDf@߾e07h&o,?ə!""""@a`+Cs fDK,܃%ve&M?RqU:e2tԗ֡ 4~I"d@:F#`&UBBI^Wwyc@uaG(k%@}q6LX,INH%xs{?DC3P{컟v!8r):j5kymҜ'}=RΗ Qs=Ko̝;WbLgg'.'Ug)?z~To9K""?h[C0 Ө{+Mo0iWL®1z>HGy6 nF`+ 7+@Nz bi90YYq' %](Ɉ |?(')r؁H/?wrü18ZҌvP`Ú#!nB؛y'rVMꙠLنD&kU d!qǰwbi&,pN!}ڡkG#!B[~ NF-Ղ>9;%(yp`e&LBjKBoF<4:<4Z!/Ȱ4V˨GW믐Sh~mՌ!JC+4wGO. |㙋,*_žo+ `SaLO-"Ad87i 2ݎ7f99gSșڿ[;Ti`m:N&6KpFJ/jrg`S;1U0z9eTϰ߾F|yMMـGB,at,U4{; )1?=Z4[wȊe1-}is хfP%k>)-j&%8Z+P+ hN*&PtycAD"h/R rq"WqX1ň  4:le&|3}+اfE̋N޽{9%''sڛۓ#r1}F)&: l|*H;,u$Cb G4AȔp;j'r5;05[" ]3ϴR 3஠Ps=1?lsw4Cg:sC' 1f^>."@VRP,F7#dmnv\|-d= 4A7M$""߾)q'v))) {A\\D",_AAA\ёX/`y!Url~FFE݆Lz">1oJ?9;GBF V@/u(J6ǂeNݤa<UMM6y3>̬amcpݯ1W} ]1JiGnڢH!!_v_%opϦE)kqth6Sfü/~>5XܑAՠ+-t CGƆlY 2fh>^XdomV9j:s)kzۗOf QL oL4nhP>#\SZډ_6@ 萡2X+Ap@C,U9s0gl؎6&'4&f!<<󃿿?'u B [q֑ W4tA.rJ 1o^A>&QQh^ϊγ`],Xh! /vS}7#rv er/](KCx7}s Fł"M}fi%}rgBMX 4zݧ. h}:]np#c22QEu#(@Lee%>k"&&G숩0`fHhL0+)e ;kγA]ot~u!>ְ>mHѧWl$B Q:̨F3!!!0;OcR9ԵC*!i.ýc!i\ .Um;$4{k)*ruSu9j2i jK}v tK^g7,ШשìD u5b"& d&{ +-{DY-矢z~ &ИڅPV%E(1Wn`$3MR9F_j~ױbt4z ͰY?fe=Ք=~}/gn;”iѼɰз> Au\F`r.s0DGdcI!S=\R9ӳ>沰aul\-!gkCΆg@5Ш<䬣5Bu*HL>]UXO̾}oߢVCuuu=b֭[hCǛkHO7Sx"PBⴷ~m}z@c1fԽ3*QΨ`F4 4ʎaάY5y Cm.X+O[8c`De4 c"z 0z8 FiX%x Z||X-KEwa1mPM5jHT cX۳3 v3̀DzMhW)=3oׂjj[C@ÛϺ!a,uCР4ro/o"'ƽ&5?Ü݆4l~JAcs >|@cc^tڊZ­t8l1RX8Lo ޒMZ*1T;;h6AV `^`~%joZ#"hpayLi ,Qbdhj{m}jÄػH!VUs\Uy쳯yGBF2@ ]U͛*[yyyz<~ɓ'ܟO>,((ɓ/ P yw!XbHg")VJNm}r@wӱBͨ`F; !7wNfg)F&jm 139ۈ0\l8&ɅL4m-ab}3# HG̡f"{9F]4Ou̗d-cahn?±%&:B 1{KȪŸ U@#Cn\$ bnwSe5SS^J:2}|kH0G4gY)Զ1wkA/V!pWB6]KZ9B| qU #q)yhq?nҨcKR1H}.AXh?ާf3C=pB룃ph T3Fhv䞄[匏a;p*H%H^93q%h;(ގil6,Xa=68̡CPTTą`ڴiCʡ1CN+>FGキmA"yFaR>X?4&c7VF47+Y qS 1Q٭i h|M:L 4FHo~r'2-tV4$@Crh 9d?V̷zG$Wh .wʏ}f8lx̬sMuX 5e-ǯ}b=!iS|] %Ac5Mj;&Ley+C5[ˏECNw)&UEezerВ6fHSO!U.(zew!`kn?xUΔ^Ya8[6+xgߧf3 8oftl_# cҐagWU"\&F}IN9c) h<3fpϞ=x ^xY\\RL>}E09ZdbѲDDdP`cccGq ze 9o d=ygߦN:*gFS{ty X(`N\-CEj9 0Xͫb@W\'I "" 97oF31GMYQ$2$ޓ/<1i_9 a#l"Ha:1 d ˻E ]&4s54Rυ]dČQwF~_V9/}B*ݩb"@C3$/rR^^96ؿޙWRk@ ;oF30=c G6b navɺP 7'{̝v4pZhMF3 pAjEQMwmru(4 E%iQX(؛7T93Uw@fcG\܂#T}1S'oBV"ؘ(Yyy6?,uq h6$G{)z`dF ї4miiy^؄3gP]nkk˵|.""h[̜5 7BLTTw'gWuɀF$yPv#^ǻ\`)~HH!v Oz{@zdFl¹Geh꒡KA jew*Ihȹ a,` x sjHvVѩP"%iA}MGx f!ML.T܀gYؾcj7_V,U9Th<!@CD% aÆOx\o 3h0a|?b Ð[3ra9d8Û ""4DDD_<4p 2:L`3ׄG̟ x*E^'.O}DDh!""Js/@c4-AKS\勩b4DD_ 'ߌfvsZ8 GsKDD O hL0s N畡[i{ 3wk"_c=Y҈ni7^f"qل (.w_5S&CG} n L3ȟ$BF /o="fYU+$5qu7& 4Y v_xnPgP+$" ;!4<@yyĐʺT>n7МG1;o36GX Yg=%A8X&z$ +딁j6Inzژbh?K I6ia#@ h4mz .4*qw$Ljyw('e|;ς}n?h,p9)"mrtd<;Q(BIFz-Oi`tf ,]>>x&z^)Zb"fHRAjH5y0V;NިȖxՎ>E(nX[%?l/36[ͬ=>8E0/8)99}؞[aHDD$-[bGRӽ{ @ @Br沆BxBqm6P6}aj´g9'>Cӓp0cAfLbnH^uVרE#?2>Qd[• K}9XA9p1@ri5,Д7 oVߓ*M60_eT/Ή)%$@ͭڀnnZ6`_qeWÆnsPbQ_fw攔={ ..ߤxaaaܥ>쵠r0Ѩug!"]NO]]]޽ wn2hwé5#=>Hq[]ųƂh9x#cәKHXdu^Oc;8f1xtwe` XCFQl@7Ic$+D绫1y3>̬am߂z+ɮ4#zim |;$K Na(Ut-.Q{ac>if0BcSn+r0q06Mqɚ^eQA!~ij8doqpKLk{F![_ګi / O!`2y<[Bxr,7#@57 &c󃿿?4k׮9)#""4:/A[[.}w:_R Hx&CÉezGp|5g)?z^hlV㾬MjϟIb3.Y>x!&Nz|@dQ:J;jmY1y,k61 t[4B6Ůyʇ7^.п_3 [ॸ \`ihfWm2h۹XTO,DRPluF8aKN#ڟh^7(;xnbYE5zX]Ս吿 *ýUt|kL%>؟SYuDNU3;Dri1Z̶k՘M߇  5` 37on:., &6s?И/Kxt:.cz" R^cbL4vQNS2o>@K8yOD?=͛7oyjX]\^ )XJnFeARc(TC提`dulS S#EH 8)@xc>{,d+XQY~vn1myTvUBtZ>U'V/q:VX`i 4c(S2d Q1Ʃ;”iѼɰз> Au\F`r.s0D:2Bh?-uA󬝱q+ڞQ!< ~2$9ۦ?ηR^@|qj; ccK!#@h,& hT0zgXeeeq@O38䭇ze^lX୸R.Aw8j/c![Pvfxah U(z/:fd$F߈a/԰RM_ Naݕ}d"O>[~ZW 4FֳcpŞ|AIxUk+kt8l1RX`n~3e[r޼AT;;h6AV `^`~ AK#Z_WXܑzSąy0><{Y NէD^m@g>,M'g}F72sVHmZl {1{]P8jE 47aa֭[fׯB6l3=( ha{O8A gFƛq-ĺ癙&!.W%yc"[IVdO8'4*8ЁN{_ґ: x*kDL%;.X 2w7ɶoF;[%RӣSȫhDօw7?N3r7 Ґ[MA {0ka&t퇫5O09j.!Q2pŞ sJ>;u%A[Cq4oF>Ս{_N*e9QQ4 \5i^ IwJoB }8_ T\+Z\wQXܣ=(ec(/DM\'8;-[L`ʟBMKd PJ۪t'JPL`VX|5MSpq\W >H 5bzhx6݉G;>OEb9%ᥤ/Wkϼ+ s8nPjۘ; cǠE?+ yb!Q.Gӥ`iQLقUZ WĥQ.3?`^oq)n>C \,`MF%U3 ίs/U~\pN< 9< \L8:)ߜɽ5tn b' 2 rT/ŌX| nO+S1=07n ''_ 4\1fXCCB,\ثEP'g-&CR)_+T32^+l~RmDawN5{ QySY_}ڦ,"ADDUD22247И.Éwruq%~p8+y,_K<|1gxF))+}|6^C=Uzz8l{.[dOwyf&(g&):U;BeDێ?Ug8+<#!ʅkA  ZIPUػ{8M6Y%̵YL_m<ZqB顡P*93g6lGs) }=c죒$@5af .ΌӇnOs~X& O_S^s(>?:/CdJ>caZTx5NE{kNX4-]l̶KaȷrH^;6 !®o+چhLz/.KS|]̑{c5M;&Ley+C5[Pthn4W>`kYQxbvI҆,uy6 ׭QsI+B'Ai9=rkV9cnb$d=BDLsƘSMPq}M( !cGAr:\r/'I7Z_=XpQU [ 22fT@Æ@Œ;ö3C3xkJQ;Иx I3zyh3ر h3SݫhhLKDOv AUY]  h&CECx߯'5Dwh8N#z~L4x.LF)cܛEX]S|ʴ9BUZ>aUiDGMڙ~.p`Ş 9FV%{^jHr;kB$;#5u1x++2s.vx{^JC 4; !g+S^$m@#̻vI]{K 3|a2%M}2*_a"!.;z Ǘ3"Y 4Ô!g,̨3Fa?a&::Fc@@k P6V@b\ fKM<7V}=27X]z͔xMVr2ןbq#j:^|>S7<ņz[y_>偁8}C52 c}b\.()cX[j9/c sgP}L Z8hbOzaҺ<@6q'zys!oi F 4_ᛒ*ذyhPy?[c,k=h4TI܁z($(^&YEḺpkșS<@b\Eɡ!""@@WQͨW4Sua G(UΌ&b=G 7&\|#Ej͡hh)Txs9B7 6n=CDOu7N7zA:ҜqBCpsĜ9!l36z6l< fnh"YL?,'Sa`=YM_q㎈eĚlE3mJe4:'2 ދKp)i5!r~KSW%oB\0{ aGT,&ݰqi{ Q6z ^sfq,=1ϻ/TTP8-T:in12 3}+-OsZh,uW>Ѩgcّ7]Bjx+볌  4 w-duaGDDf0yݠ@Vb#"_AftQl[1Kpa)ɯB;[@\p6x)B$]+@e2q D3Q6k1F-݉opZ(k4K6A~U;T7^Y p|*Z 吴T~#ADc?9*Y @*)SB.$i}`=mE~ĭhISp4 b枢k$ɕ.NXsJ;ːw(%GqKZgYt3sh|Sq ԪYq5j#+rx&.um!N)A [Iv+(nLSy8h*Vі Bg-~( /;e (/FU@# 4 }^瑚WGaJ&4 4DDDD|زe 9O:4#\sss3v)n$i$P=_ۻ) GB -#ݎ˻ <:\&5"""4w (ׅMٶ:رMUvBXtFؑjqת[n74 Ղ/p^5^d3p%9swK$(C啍dǯ"[Էt g 4| 4L`˭jTgnC | ^L!i*D?6 n)@ںxzzzR4 UGM`O'<+p4!"""@ ?h - 8w?owT뵢86G-[ HX&]!b3~ذ.>BŞ s.ǶEth| Ċd}Ru< Oxx լn<9ўKP|v VKU^K2A~BB¶cY(mG' 4t[)r.e 5 ?Ju \,x ": X} R9sk yb%EQuzz/0AފP7Avm` )o}YGV#:~ud"2jBEp{1& !!8x9|ܿO|d |@O9Yp^~YsZ>}IuPsq-ޘ4DhzVEdbXreo[OE"""hO Si0ZF.}= `Iz ݜ{zDz) A4: 1sqy/7-BHX0ǜDLNwf6oތ:nqD#T޽{{K g0e D"EV>XMR_ }vux[Rh"90ޚVZe+3f`DF*yoµX:@ k@~'j/g OA]!Oso55?$?4:̲BX JyN*:P5΋y!,,Ta伐B(m`j.a-Z ҡO7 [02ά޽ wn"PCd`b/x ,!زu^O 'E_e80öLn!rh^B صBWtJ% +:(L@FAY8ckyT*Ge'vi4`%&h.gPw6F) t>ُ@.Wg ]{3THȻG444^Xs_Ux3PF)rR-řHIA7?ZZ'W*Q%Ǖ ~xc:n+Y6cMd0DB/}.) ׺K:%S_o!DKi#J\`Eል)3j@Cwv6[(Bؚ]x̩#;6 :Da?[ s "imDr Dލω>;qhعgXݿM@I{2M1IesF@+iT`\+q+qO։|N[waПH;,u$Ï{] dJe5wl3iu6v{kz8T9 W˺FG5lK66QDu]" L2lhjdvf co /mׅͭ77 ()x4de9 TNxxsmc]h"OpB5CR0t@CC^{"8)M|9^^gOWPʐK 8iF Eix!f֧7c*ټy8_bQBl-sB~ XxzrK&硅4EHR?\1?U*qeH1x" Ctd ׏W$=U<4!2F]]) r ֭Fp6j%?>?ӟQ/мy1i)C݌g7q,(B_CğSoh|s`Zf"{ Yr>+|bj@3||~Au2e8~vf O2pp6 Q p:Bf0pRp4EM |{cQ%1A@%ƞ&MKY8 4^ʐ5g{=';\.Ž>G7ɋ8넬ބ(8}<-!@[gf\L EzEěR@Nwgf HJZA005)=C`HP}c³k(CmmmϪ Vx^+[JK4۟h+H9Ы8Z#>.UvIPjEit+BN%H}zJQd+hXh 5T@W:"fywn#_(f&3f |t xZ40 y0OÑ^.CSV4Qfvmto~@ibi) 5i/FBl0x#8zܩ1"?}UH{P#=F Q+C/_j< }Ba:@7ZMj݁7Y9:^7 ,4 * e @dw ߜC6mDq@G1r:ry;UE,tj=A4J}а%љe>vv 4ҧ9MU@Y [[ABi EN]B‹/S 6Hd=ՔQJP V84D5Ш4C>yJKt:#M#:d7%Y{!1T[b&iX݈[#fr0 :BWK5sO"ta϶m AVφ@wh:GG:o99'W*(ocA+M.nBϲɈnݔC1B;>uTH634ZAR&2cu?O.Pvsf¬Yvl$y W@c06 Zi6p[|2ee0@ 2 {V1Iކ11p6vzf*/ x$kke8ks"~}in3R\フnl=@ܞ>s_ 7P$\xNy-[!ەهn?t9 R|W'ݵZY㭬e&~Ahvϑ:1;@;C=BHo1d‹ hdfxOޒJеG34٧%h;`0YHncr^4։K~} ͆rwVr) V@ Qfs!6!8@c+F31G{UBʟ3 D p-chM@lҿP(/(قBOpu[E}>OxFy=2Ν3B4U۲}"c!5;rY2s(Ga2ivnAd\hڛsж=S nv {s4x[%m܆JrZsm,qCWVl^Ͻ9P] o *{V ߆rգD6wYĺ]ۋ м+ ;XAhЃLlk _ꅦ>Z]8 j(4LE(k~x鋡KXK}7@Ρ&=@5S`'Cc)p#?#_.yuC ֞>ջ!I/Cj;QXFtmE`=>#pKj"FO78LEkNʴf_&3I5n*?$?6h%H<]cø)s-dʎQ_31a$l6 { ;#h8RXOzyIfvL=ŗQ|p:USШcͷ{DИ:=4xXccѨai6a+u녑Fh:Ƴ$V.4S, ,4/Ih{(5sJkJ7|l1[wp$cS t0ȱgłPlkcQՄ.ھ~qMz#d%!^A,/sif\` FOgt?gDZ MrQ*=^sWαXrWL˽Xr+2iT${ yyBA=4ZՄW{x΄]*I_;5$SW)4 D冽rm#hegg:j$d89BEց" 467ptWAy#q h-qL STwC*?Jo>*m@NcljWpdx7+yBkW~CBr4W`n !73)-\W>2Fu5:<-WQn9a}1ic !!CcI\8)d> gl[Ğg*ɒ&G0ﱘ{Æ^03\Iť<ޫ/z ז6htT~\\ݖV}35cgC/pB<=SGz`HLr=AapHfHC69o^|;XemtBc[BuS4(c+-$;^# 6 !!jؚ /M]1mI}!B֐VrǖyeCw_B6$e"rz+X}>$*hx"]'b'+d,Q 1EIΘ ڍö.\vՃ!1Dh:VQhdDwdH^Ct 0FVIyDLeKJheeϪ~>u)tʼg֓O\6JCJ" iwpx~cZ㪅4ŴN YZv3gygD,iMQߺF"9"=4x0)@5Y7FГxWQQLӕ ~JJJ̄ՕkAW吞7C2& w,ڧצrPL?l!ʹ<_ Mvyyyv9ّZn{%4h?b ťB\Z30I`r K{-'P]g> %10d`-j*4 uYd?w,w; pŰ@L0h\JRv(4}A.LC:D $4$4U 95}/W;s="z50^ = $x%t\@K^.ٞ&U n)V- wxU3Cy)jmZ֣Z18T,v pu%X'7U i?p=d9 8V6@ZK V5(bI<2 ,NiRI{7Z!g&4L`^ 3j6% >XyM b.R@Ӣ@Ë1uC >^5T$YQ:iϡqEBx%\f6$$еOڒcʗa4-2wzt߇R ಪyc5}2aINPkcv[+E"U&g7G20>u i pjRcoJ!æ&Y[&4a䚜܂8DhR3pjn_:Vm0 |ѵ#lHhޚrCR)Hv >c,7F+jq^pSa1u)muw*0 a]JLݒd㏿=` %4m~80f6\:IlnE. ۇug,B}f2jpͪ^^Xt# ͦ״4/ID\bOca\2Y8c)-*F+mW,HA@2PоJ4|]7to^sXSE{%*j R-fc6\k*=6m{;ߩ>QDžFęYe=vcqbגX0ayRu,qkb6lA{rB#pgeF{][/FQI8mߺT.ZW*Vh QT*b 1H "\t(4k)4VMb<F³UٰͯD P2 5ϰѽ ҵ_ҝ2PX%-cyf х87u<&Cx_:6Nql|,b<"fm>#<wΊ _,2 P*KrE{z}YBBYj.ʊ4+_Gs5V:XXw[J<+ĈL- W۹ Maggmۢcǎh׮mڴiݺ5OVo޼9s)"O,464^i]P2 wu8|ukܑE%wmd>d2$芡ך VymC4h赯k.0X hck/daלV&=>vh 8'!D>JMl\q.㐳^,ә;Vɇ nnUk¾\^nvxGL)A~T*4^ߺ(M`Qh8cc- t`OyGB &,aLh0tl]09aڝ˄& M2oLV0qWi}1;8$ޒ[ݶ;ZCLrroj}z5=ӕ}N":.A^1>V9'ސ a}=wU {KB#pq#++O, mDFFLjj*?~-[("O+4#X Ď.&7R­W~0rgqr ܄LrzY8\Jݙ ]I^ 6B;LwQ1qzX]4_NʴNFMN˂;|R^΅2a4zkt`BCZeBcՌ Ұ- MB31 e!O. 3%>u!leB9 xŰEM29VeD^ Zcv%v#yZ>#`vY/ip]G/Sy!+>I+We 1KpR|vryO_-_1-D*gۦ<J)8r ;^AD`|2 _&]:!Ke8*-Fy17^Q 2d.>gB -&"fua"X,4lz} =n'*?x|%d EkR8{!ńJ5La:_ֱk9;G)ZAĞH2-Ǣ) ߒBk6ؤT=2swYGΈ7c;Qb6-(B,{rMdfRv?Zl:*?mF=~,$lX91. Ꙗy|ۼ9(t/DLi CE:9-A&;&Gǭ'Zn._Qn+"s*~ j*4\Kbb".]ӧO#::GETT<}aϞ=عs'mۆ͛7x")"A', gsJGtۂm~`MBcYh"WbXt.hhXxR`QO*GXO㐧cqDE1jRKg`M \žt-oota]z|jo(o&]a{F^PK_DXxz`C9O7aP]|3ہ[R(~&3'峜 cJ / P~?: yk} Ҋ!/6JH!2f:_;CNH~n鐫oIEW!yhR$R<<pQ1{ Cf,b|ŕ,ƲVkhi,v~j(a|L"=g,897\/I14:1nW`Y 2Xu~X)mbtX+kT!d\ Wo1S+j_ܯ]WM(۾0[<+Q`O a{ "Xƞ8QLއd%mb9. s7Jї#qI˄Hk f{!y~ n`}ZZ $Ʈ3?=o  _ &.){g$yS>FjBU90qehp>E9Z'Kכe+!XXG}k"4sĉ8v/2F0b󛈌ĺuf_o7}.spvF; m.wBm,!Ťe 7kCOd85{^~$lhƲz〸ƙ azĦҪU^mK]z-Lhu=RݦbǍ4H(h;ZX-4}@<gk~olUCn'(U>Rlζ5y3kt қW,Fs1 u0](3ܶ}1U M=A5j 5|GXpwON1?lW!k+g.{\ܧ cwL\ `Y2vɂIKQ1DeIKVQy|3 Ѣm_,Wb攻%% A%= NELhZ̄& '8,ep3 f9*Re1VR^{ 1lk!Gp52#g@LV)`gLhqB)_"tث $M4 emjqEع+o'D+4mLh~ >Xd9jxf^`gz/'vo7{gen>grˎ\{ƶbm޽&Ǟl&z{oMLLLp2Bq+ xBaf̬\k׮}Bc4{n5@QQh n5Xn5Z,EZhW5:cM%tOM`npALh'r~ϹDbPɄxz"LZ\F} Hh@fuhju;\*Ҹ,YܯX,aLNX0/? ͓!JY=sJ<\J=V p& Xč"^4> azj1RIe~@ü%F~h aAu xtI\z&t+@B{fE8YehˎOWW{)E2rC˜-VvcC~%͑bk+Xt_"dH(*FL>U+[ؖc1;OVG2sI#y#gm˼.a t sI Lށy\{0 äBx3&/xaqj[!^_LF$0/%(Ls۲P?;cwp slNbdVl$A$2$2t5JUp ^_T!Ee;ُgbp|2H<ˤݘ,1}\IZz\XnCmkLv0d#+Q~IDI,1{(b&rE>/ e>ᇒH\oorI;<N0d^L~/Zk NHmn 7_F`r~?tLxx8/=%/^VZȮ!}(ֽpxzbtHRT$,/Y.AΞ1݇keBsAam(mE.]z z.Ei1^}),Mbg2dDkJLhLh ۞gb®s bt,Ũ|X:0S6eBsW. iÂS! N22&|Q~+r\.Bn3wHiy,HEzzXT Z p ]Xtٜc؛Q<) v7GAb,&)1p"~V&4,׫ /{xEkĘ%s0_9oNI1,{~9>ab)OY؜^q1?VIA.\:1(_^^! ;=6\<O9qb(% &'LN/ޛ{gerȄŏLj%|CZ zs!ZL]jΟqHT1b^L]:#.mOUn[Mдhтn{n<{Jy>f2l߶  )T/4`Ʉkna~_g\TWX7;nέYa35bCy}ކk?^ jA <.+XIzH*}'re \2Qј[ZB6 Mq1?Lͣ2ߝl[M8NI f; Msa^/21"` 3 5;a_F]܃FrmMD'c,nWC3A H<>JZ$';VvY _cЪ%fĪV$4ABB1cp9_@/3WN]7NҔhj8Q9WEXXZK8}Z+9'_em %.ڳ'ێ)`u`eExBȱr Wa?r=Qߌmh^_iX0C{N)BΞv?2_ yBk} S>Xz%|TtH11`u@&0k~xRbd%`h<9YXpCٲ𝱌.vM[ ~s*3ܶ^7ٽ'Lc.G]-c(J' X4oOq0 '*]bϸ^SՔ/k(4"p3.s rP\v>&:QyԥBٿ?̍(ԪBqa~_FF:^]&է0g[6B#p[W&4&k8͊\-0z=1"MU'I&^:C!xZȻG;$ɚ_"@U"cp4{L&JS|M*/Iq:dmC[9(d3BEΫ{û;;߰&fIhܱ)MkT*4-- "' +~S:>OY=M@rܱE ޑ ) e|1%_)ŒbܿNs[Dsj4ץ_B8"+߷|z+;ֈlNkXpʍ C2$A˕b8mcbH2|]BMyMf޽nL`` 3q),,@qQbs;Gpp0Kcmm&,B&yWk83\ {g FWw9ZFn; r&I{Xl||žk7B j&46p] "fVp{eqҿ$-bW{ 2e<\let|ZrfLYC3+KBb\E`k{`u}}Jꪅa^ގ6-r( 0/N e$ A|=4g^Y %XJLh[w\v?H^ODV,&U1o_Wm%Ƅ:-F: paE;ExP5Mbǎfsf0x&Oڈg&((߬X(ФQp ~8K=4u CXл# f[ky/SMhU0$^C{x۰]B.Dw=<:Vx !1vlt-*#Te恡N\`o Cú8!P]nsb= p7<<>9%FBӸqcٳ䄆'M5k#p.fѢEdǪpZ:wE$@W  8Tä$4oWhl1bڤp.mdyChSCdiC 4$rߊtPA,-N5CGqp\'/Fyaq GJ5n 0_c$ʿ&zaQ!tzT<x kY9bSHcY٢cYA/N@B ^BY.ғbɻO: )&󙬝bLȞFb1m8y?R.;̄h: Hhr"M민=z8y$\*gnСC8pڙٸq#&OO-807N]K A_^zfpۨ ԯ_5#?s=8~n!MnO?ğK'΂GXfKA ͫ '0Fmv&BC@P Hh.VCf.v+ۿY5sG@xv^6(qy!.m;FteYrw6`pn2v  Hhޤ4(1wBѹۺZόR~S[V v@H 3\XS(U#t? #z57L|ͶdMԋ[ƸP}z~;6c& ~}upxA A$4$4 MS_7j++Ki{ E|\XK1FY ƧrCFbC䛈8CBF^^"]W.aPs<, A[ MpALG h{0ܡ! A Ay_&$41ܱ 'Tu +GX uk9M y5C:<4k,nY&9zyxYkCweAؐRU/ub]wA HWkrjxyK s[EBC AIqG)C|M-ƪ9Qx%mJ{C<Y24*1RĴf:;y@Lj3D7ٔc6]E‹\ȹZaq컒 B" WkAx<(Jc۩\PoŸ a;tEW6 ֿoJdB79OEa1g\M.!W!Ϳ΂J 4ڊ"E7dЋ1Ѹ2%}*X[ rc Lb{?djn]q*nw^~n|=x k(; ܚ}A scAtdˠұSЫdu<6{ T4>Aއ6a8r7R:9bW >jvyL@f>8G` z;O))ߧ]?7BB87i8Eug! nA9\Pha&N@[jh5:NI fdra;a2Z#8Ͻ*45T2 cDP%8gumW4l4gTzmv7\\SлЈ˶6C1 ?4)Bt6ַDhvgrfc&/qb= ,54=.K`:NpC r!4{I}7}k~yWX ^Ᏽ*-f&i3m9ysʽ3|ݰ,A E/cg3p+uy82YBA5H֔.1C }zb HhHh&o1kI B3cQ;~_m']-LzKg8kÃk#_œW M|ek1qgAֹڇKp[T}1: 4 Wp«0+p<(&s^Ch:N3++B&B:XWvn~x>R󐙫@FUU/[tY)!g"G/c\$l(F: aZPsoذ)SC7LeZ<txI]k(4Xxד!+/"=a|YĪ9` g u;BSs,MC{?Z0~FUŔ&& '-A A$4$4Q'Ə|kK_vr '&:lQh8dɖ] B IUmj#_ ߓ Mrtㄦ8ggg3:r(`*ICao6g?=VAr96.4Vh56 *&nf=+ڮ*/Kٹcs-ootO7>F- TH\У,Th$'!U]GH2+I pj]9c*'kkt^τ&:T%4 I $4A$4ABSf|R6m{gJ&K÷iՁX;a5TCM汲֯$4VpZ-+"c`mi d_ YWf.4#&DۇDkS6006-bW{ 2e<\llJ+ɡVVvb2Q1PM%rx *inKƪb(&,ϡiXgx"Lme2wurdκ k>k#4%6DxSqaa!u9ԡr)Ḭ;Y B͓_d>_u-&/WC5ڐBxnGFGC0C\^U_Ah6ld5>cy`D '4 6=JǛ|ӘgtieW18e26: vbB,tot>>CGMjDžPƇw-Ag\Cyws%mg=ң0c(yVOUim =$q}~YM%q G gbx5AVτ"w#q#UzT썦I ÿpgy26>A^= Y ֦7RPhT?:c+\vƋH+`mfXT",'+Bý|/%*&xb l MCbEbЂxtl[b1FBC A90`LJBcX+-Y24}&UpSץ1IAx eZ8 $G$%@֥n-TAć(4ThիW+O],&X'F/;Km;CNNjf6'c8 n^*rY?>3a QCd% , &qHh Hhy}"ECޏ3N~Lm%)Uq:k;M؅BSː-z}%#]ZE(0$1Cp4 !gA$4A2xAABCBC4  !gAA 9#!  hA A$4$4AC ! !!rF A AА3  o AА3 Hh HhHhABCABC$44  !gA$4AА 9#  hA$4A$4ABCABC-#! Hhm !! Hh Hh   ! ! Hh ! !! Hh Hh  [FBC$4AP@BC AABCABC$4$4AA A A$4$4ABC A AABCABC$4^AAHh ?}0`L2ABCBC$4AA'3$4AА A4  HhHh!gA$4ABCAC !! hA AAC Hh hA AAA 9# Hh!gA$4ABCBC 9# ! rF AAC HhHh rFABC$4$4AА3  !rF AAC Hh A4  Hh Hh !! Hh HhHh   !!  Hh  !  Hh ! !  HhHh   ! Q0xM=2:yU}  o A$46A|C\O|J@BCABCABS}  Hh !(l vuDA?B| em*{~.'<5wߑʽԨ롱oE>tj@7RO Hh Hhq|=~Yw ׼ħ=ܜV?!Bsէko$!!  jaI۟nOw.lvE#6Xf{xsF4,'ot09M òՁn3}~zАABCABSGtf.Y*3Ȥ#wǥ۹\uh\ƅRͮe=P}yzАABCABSG&J[_dmzjjZJ޸,w󇖽4$!!  ͌eֶ3?<_*4NƧɯ۽}Bcz 4SO Hh HhИ+/4[\Д0Vo2YuB:$!!Ɣ@nNo -AAHh>1Mt;QPuIBCBC AB 7t_b0!l#h樂bQp~ߙмj=IhHh m$;ď$4 ;؞藜Ph^$4$4AА|C?A|B1qЍwAp_+LB*$!!p G_~<կZzZy{!VoLVO|= rK7fC}4\$h2M3] =W͡!!m ͅ?T9z`u8jG]@[cͳr v/fad, %91I*پ+}Hh;, 8 ,@H6Yd'BB [ HID`Zڪ#}[(O+bqZ+De(!@vz9LI?^H~ { h hMh?X M:75 GՇ 9U:Fn=-㮦' <󻆫'j{~2x4={v^Kq]y*.J/qwXЀ44;0h}3zWF┸mBЀ4fM6-xGdt']֤.xn{1P @QOƵL|> ;!hn>{}HK:Wv:Quzq]ޞpo2mMpfZԜ2ﮠA#hA h@@44 h AAp hA#h@@ A hA#h@@44 h h AAA#h@@Ѐ44 hA h @44 AA#h@@Ѐ42A4FЀ A#hA h@@44 h A.4 hAAAF@Ѐ44 hA h @4]&h@w h @44 AA#h@@Ѐ42Ap hA#h@@Ѐ44 h h @A4@4AA4 A hA#h@@44 h h AAA4 AA#h@@Ѐ44 h4 hAA@FЀ 4 hA h@@44 hAA@ @A4 A hA#h@@44 h LЀ4 h AA@FЀ 4 hA h@wA8A4 A hA#h@@44 h|^| 4AA4 A hA#h@@44 ht@Ѐ@44 h sfm7h ۮvW< @T]viY<8k`OVWWƌC# hMcccAӖLд4m @д:h*AfMA]A,AfM\4ivٌ3„ ,[r`"{4̓=R|>GA4 4f 4-EAAF44zj?~|+頢|]}<u?ߋi4{'~9 4bФQ#h@Ƞi)f @д)h4 hvTl.f @ԼSN ƍkxx`FlҞx{A,h8A fa m4mU'hjM[ Aj @G.)A񂿨<+\7|cnvdh1V!y(4AU|&`ʙM]A#hA hA#hƮZV-\so .~syo 90}>?n@6=r4/hƇw~}EXkk_ +y8{L ~{or'74_z{؂Mcx׆ .=w~XpiLXqea~{KT;gg.?$Lm88|oFufO O^0Gy&±M>]~~꺰ŧ~"̟<>| u7/>0qئn}'}%XK1#Y{^aDۜ>>bfOA#hvѠ_n_1æ\n݆ƒ7cqXr߆<&~ѯgE6<EK>Uᄇ$<0a nz07y'5>Ъ4|yݶ8EqC*#՜?;]߮.O;fh\MM^B7t#Tqjł>$|昁aMvCZ=/gzkswPyN{n o}O©y8_uW)F[F膗¿_ָ)hVڌ oz&la;_Z1ax=K‡'ڦOX(.jyrФ ?eP\~})#+?ip5w WOn_ЬϞtݓt۪ϥ\g釅c]vՠ lr6!f,̃fNA3wuk.A3Ćw0}*'LZv;mn=”tC3{6Eit=AsV͚j'k͏Ϩ(M[?s{f/y}Sa))@C8sL9;U;W4aa ]1w@n4RlX/煅_.߅ç^bCXyo?/,߬ k_f954Asc97<֮{6>.^=Ç(Z|BSV$uЬk!h>4yPe}K%NX;Д]sTZԷݟK7Ɏj@ $hz44%%?xbG=kNnWcúUφod8oʦɶ4Wm^ϟ\Voؘ=Ίݟ F ;06FG>h=Ul8Ь4h]Φ5W]WCWOW.OoffZMobh`7~$h꒠ut]%.5zA-[k&Nss#1qK\ AA34hA@kfKOYy ̛мa,g)hw%haՒ>fT&CJAӳ42edgeF `GxrЌMUۥ)h4kfAv”{4=}N heܹaٲe-M9Kw8+N'oEtKpAl/1f)M9{!@]餚=#ݺ9`v”3͕Zj4L9{3g])JT `{M3kqْJФ͊33R v68 g'HQ{U|&[/FYΤ bt:vVI(LY1,]?[[KΪFi/3&fs3]KK4/-מ0`Qˋ:-OR[b(MM`vfnf^fAfafQfIfi;2g.\yWw][tx}q__7F$ow 4oEyc,țcn jLQ(MY|gP>mX}ڨ̤Qc22f˼-w|愒|\|r\6&-16oykf-RlVtOFgbtگQtYiOt3&3.3!QGd_$pH:c|\_̔ [abEI-i(MԳ4jOY ]֌NFl lLgR)b=LNȼi bHJ1N5Vٷ(M1g5}w =<ؼ'SN;1 I`L ň%mQL$fz&Sʣ3霌Ҵ&j⢜!I KFm)Fo$S6pj KBfH2Ŭbt&L}?L=5F)hE#6EԗiHHéulߐSDL1"SL1ŬwMԊb~yĖn&j55hM6}hE _d9CItXH)MB&)̴3 [:o&j%5h$#6}Jq?ES{I&2 )"O2"sHM;263; }jDMK6&aӳ7I:ZiV CK3 RZ3L1:ewe0DoIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_autoremove.png000066400000000000000000002062611477034762000256220ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:16:29 CEST h IDATx\TY{>/̝f;=s9gml(r YPPD$f[mC[жڶ99bhQQFE U{kU;{^_߽R??o*?/?g2KAAt mt.k}jT{5ݱ]lO uɣ8j_4JAAt mt-mK]RٞPI%R[ [8j f?'zAA }ޤVjҔMMԔJJm4D&[IfWvGK!΀/=;AA@/i:ڳ4SS05RTv$]jٞDHMyDCz  Pϗ4JY%KTJCdRe lT f룦fU7hȤ vE~!6}PAA|XpcwA5Z-3^;dskwp>s#;I!ugAA|ܟ~ij:KFHuR-^i?"M! >Y؃V,cll7o?OT4uJ6fkf6t'ܧFA=f\̬]Xv!3r@.nudH7ȿjFC:TЃ# x| ȎR~?r>QjF$wV3[#?SV/,Q=@  Q%R ?@1ۧrJ'EOk$,aMAJKIZ=r@]јtӪ[[=S[=6j4[ {8<0wB[ hLJLrr>c%H{[gjFd\H`uq 5(5Y!aC]1CѫD,!z<#}kB^aԷO|TnO=z{33H/RRI̵zXSI}-tGʯu$<4Cc:I$ ⣃/Oϟ?Yf?dGKDr{ӽݼvn! hMoXx5LrlGRo(mgբ9vGC/Ug{ٿ,HG_R_̙3QWWy6<DV)j|n$A}_:HCRq3c`mV}~:,zc!`YʪkPUqBӸ~wTE~#1YR;HCq~݁sPQ]gxp LwG>}#.=*AeU rNbc3sRwbזjTIArmmz/~lڪ<|mf=k;=x*~_m'U *8O6`',YEe8p#,*^>K` '_`1hDr CDrmqGF[{$AmJjG!jC d%OL„ 荏PR;=CQy-;^;WC$u,)㭚OAvF/#}PE\o^ǽJV E1zT)埳tuֲ`o5j\[E3[سr9/oaٌ6L${ O*~K *OoO$ڏ[E _bT &I PgnER{!4&|N"ID[e\ha;bLB!($&ZFI8E͜ˊYU`'-uv.TK* amY);aJX@8Xk{ +jZ$QtOKJ~FT;ӽEZ]]//{l7^{ `jO O7:R6A?Drn>ӱ0ۃ4D=H 4ET)u9V:n9:mSr2 T+ds%;W y~ɓȯ\di fSmlxR"@msl ߾HK ᳱ󟣢NC魘7&HƧեIC["߄HQ^CR@"IAѽLP9ǐ1zDR*G)#$ Ye||r.yM.D  D  x"wI$  >n{$AAěɡ$AAH%$  ީHHAA|"iFDO>AAEr   >|H$  I  D   $  H$I$  I  D   $  H$  II  DҧO A-1o߾Ư+y*r%|[Q +<+F_ׯL T^?K"oQ‚ [cM|H$xڋ`la5DT^5pppѣ(DFF*fooO1K"Z$ Wbb"/^$|5EMIᰣ/vi>$SQW2fDGG#&&F/\(E Ӕoq)D";FaXaEAHjJ)Sptqqym\Gc|7HZx~s ۰4A$bHrxo啋aPPPɄ >z$8l:W9d3MO*q0Ҝ9͋D"[E7ӳTK*g{+PlB] I?((^n1uenf_C1c"9佈UT6D/C5Iqfa"鑁7}/n|iUlʈAXh}!v櫷qpB~I$ $_eKDebm6C˳H:/<1\/HLđ)_=,sa..H] -p`@sqXsWs031qiX=ML$:AyŪF 6y6/LDrkg+_GS/^[noܗ/ i\h& cy 9S3S= .#dV"T;<&^\#. ej ƏrHOƴdLpV噥R?\)H GV }QVe8ak/f`j?n}U"Y'Y_E"jeX`|8t+ɞbDs@&ۓw-]ȖXYDFFE/8e׶~LA?.-"9es5Ռ濋ʟ!L:=^˟U "O,&Aűt8"vJER?lT] 4GǐUCcs۫~O"emP$ F&!##ce0i|nq|l/(oeݧO%8Iy-0wCXZ& ailc KS21-Ru,\CR9v;06}"j^#3-nL$[O/d7}t 8| Y1$kg#BE: ?5QTڌ;9Rg+2p֣pg$;CzgJ, |Ԕ@iMd(d")W!Ca")"W&7KG$-Ɐ\a 쭶-("x/Md5ӈ?4Z- )IIIdKE5yzDQH~}]ވ'8Z*fff-} %!f p‹:&j^B }A"3Gb_v <5!e"9BpiVs*]:#^Lzibcx%֘veJ!f"Y!CIFzdXy\$w(H._\e"y$c&d"ɂVNS nւ6@=1d?C+׽4l۶MD4bf/: ]xIA8(D2Nb<&2تDYPj"7.qFZw4Bǿ?dYJ/R_a,m1 .lGE.|Lyf*FjS&2;28ԉUnZ(sfboH˨_2C1RoKR=Hj{sH*;b6+e"R2bk%P<_~|VB \촮 悮ߞ3FCA[Q$ÆkEro/:۵}w]{]o^{΀! w2l ng_&H3!F́'D3L?V'ƔõoW$빜 Ru ֣2x7xg:y;)M+!f7J_PF@ě-|'N8tP$X7&(~L$wQI3v?>)K෢뺗r@t,cX[1>0L-&0QGR[<<vHc+[_Dg!9 g^R#hIxv:omlIG0Nٵ)n>Ii=R᥼&w YӢc%xc0B%d멡 UAVu\5't$>\ÚIN08ȟP(H FPp$BN?ejjڂyvh}nSaVLg_8~fpYp Һ#*f!W*f!&8ƅH/̆)JZ*'2fc9s.BD2UlzL3 K% ugY^Jrz4F@{"UI ~ b}2GIV07x@JUL*849EcխZ4)ai&4|#Q&~u8\~]˗cҤI t-+Apwv&" )te;/<YL$G8df`ge8aBrÓfo,_;W!ogz"k_BgViL9r)=A-7DY^yKh,&#:<1pW.9#`04yوUz ãtkWZ%yk3 f-uWҲ2RYG ArV&YQ=}}l*W^ h"W*]3{M"W3 wLmX9fmbl (sgd UR[y!"!ʾ//Ga%\F!k%<)_މt$0&_/BUQ-5.@e(9,vfv!N¡Z| hz~y̲ ~µ 445QZ|7%Ln\R dZ9QHrDp N/FL8!톊$KN!gg+Dv0+x\ZY#K[3"[8,ǏGjjbLdRV$2Y8FhejHKNDD/IXD傲0-e2&{H*eO?D>!5:ҷFLBH,ҚR<9uLjxWK(E]yrl' ?`-m_rt$C+D#kJePc1)> f#y$t]$hQ:NZhfvΤqpЪ|LT~/#ݲ9@$?lxwssû5v3qtnAxlb~~E%+%_;7U/ݍ`^Y㏺:^RIqDDD / 9Uo^0eBi>VYa77#*XZZ*dqĉ}8}||(&Hv[9r$LLL5mg(E2M 7MU=!~u|H$)_K"D/D MU$+מZ~I$1aeOpAt xLⱩ O><^!_w }U<֋Ax,1Ǧ*~?|y*b%|[ś <&꠮D2zkO.$AAD   $  H$  I  DD   $B$zeGzuv!a I ިD_ D?33LG#|Q>Sx>||z[y[8;;C =ϐ= Ϟ"_EJOI@F6w- vRAtٓLP_Z`ddDt'_Łm!T)f{4$$oVoT 3C$S :I {He*Ȇm!T)f$$'III$$AD AHHHja-8-&=3[`XlZ阸`hW &]w{ax7γ)"$KDBH"I"IHHHa;! >=U$Gi' ^+x% A$&W&´Z$:y<7t:}#^Lzib.0>")pt<^xLrY NOw [1Ҥ;GQ\~|MH$I$߳H1*y^Z)TÅKfoL"}mVIGDR?V:#E`$8 +Խ*Ez I${H꛼=F *<?. Y'E{r/$֟;%cW5l!ت#j4nE'cͺq_{pA1hyG:r3FHHO4A\5 f,t߀(1HHHmAbDL&A^֯W}")YےB쌋Ɩ| MvqWV--;Bk-"YWGB*Ep[9/P#]_wvgl+$7JQ]xiM )q2;8< ձX{.BrI)XyKv )}_^r>QJdh*0ifDҐkL4|WYv.ϫP 8Ic;Do{J?x\e;./EVkX3&"x=C$AX} MOpHJ@RB|wVV 0~KK"I"E"z77caӰ}U~1bUyV'U,ȳ w c4u4r4TaK8+A*@Y =a*"i=eREE[S|VNfp#U (;y>&mDRWaϥX܅Fco3+C}Y\CLSpKXw)+ppI0l߭Hʮ·gcPs}+?ݺbzE'ݸ_zis7 &"iR> k&k"%6)K~Zi%sZ ɡp `^ڐȉaW c8^NYTl>VƾŘhg2X%o.\{Z \Wb\"t&UY9/OѪQc$y;_ß3K* dyomuP)t^!MA>fu=l`74 UAXyQ%;Q_ʗ98:ΦF?S7$}2(7l4'$_ѧESOuF씎,8?=I!WXp~+ b.I04@cM;#:,qkϾ &*uKXq"3ȊcI|&EcƷPXTBd+ /-sؽD yf͍$&#g|U#^]߂ٓ#8 B&WK̢wᙴIC`$~uErHwtkkp1U4w9n"/ b:؟;aP'-įd!."qi3=m"qu\F߉HMWuDWx@Yb% \7P ܅Y^;v T")bw.v;^G?7HJqjU$G'1^:2 *df ?!ƬYpngqfɫq<͎ KoHQwfq{K!Y_&c?GDXߨw ؏w H?U%C,Ϳ*E;%lMA ؝Sd溛hĄ2___'FmD~ p sXJ]LXc?W%oLL w3ZbkFn -.`Mr%b2^*䊉ϳb)ZY4^ W ^_svjJ*&T K]V)8VՄW{/?cIx,”H$-LwDؐo YQ'a4Lr5!$pco@ڸ/ e1L `oF#oăWO]w+歇pueვwe=]2xE vT 4[]Lބ?d0IERẀ}chl8tglrm Y;]ۭ5UFv|V&[x`Wk ?yc$:{O8[R},Z`8$~Ȱ.fܭ%n'@x`mV&*V?o{5Kͥ0E% )E8MkDҐ <͂U/Z?' 8 RV%bAKחw5r/=̴i(aUU(-.C}c("i$ԣH/υ F. Y ހHZ"W%M3re%ߊJ yZc$s6#6pƍS;AX~JOm40|&< ͬ1yf@}")k3l Uwrde9 "Y[$*D>4 8p_*Q7 ~~b3"鹔}kr <o:E2J%-pKu58=(\B~mv~3Fa'4{w"y"id$Fn,R5L$-0_ʸY8~|)CQ¼_YLm(ƭ ks&ƽ^l1c\[uM:~:1#Wyer<8AWΉ@42^j}fUS?8X҈C*o+䪩 9{#sr$P Q"p^>cM5KHǖ36~LvV;i(c$VZVa6 *Eდ?JU;'bۍz-LH*/sw]2,U`sc좓+ƙ,k{>q͒P+0U5MoAQKO-HtXg:S\?wĻI'*=&9{tŘa3SN2q@زB4F}3\Q,Eb IkqiJ)[}4h9Ƥ2.ن [/m=W,]&VE^ 3֯F<>ܒ:&Qxs+4#{(g;`#f S9Kp2ٷLndJ\~R M_=]+orAr4Hs^} \{R<~Z-gs޶p]T/qx432w;KvMMו!1$,3I*(f1ݘHH OI$ GG"I1DDD[H7ɮE$ajjJ@Hvd(?I$I$I$EZ(H$+ z$=Z$1l0@x~QQ><#0D= Ϟ @x~QQ><#0D= Ϟ$xAtz 777X,ȑ#)(oAt|||0b*666Ge #E  /$AA$AAA"I"IAA"I"IAA"I"IAAHAA$AA$$AA$$AӧzE?G|޷o_I :~)R⣁w[}/۝?:j(`e?\E"Ig_~cAJťűX`aaA<2>$A[f=h Qh]0kiz{{C,G/!$A $wW m| cG#1_Ц\ $'oTHGHjtAu=E`"~& eaY>II#IWWWHZa X }Xy!a:{[$# >>̬7%_F<툤o\ߘ0~L¼%($N$񁊤v'l߾]V|D"QbWQ X~j*υXԭ2O"iH<ӧ1l0Dw| TKQ_]wcYH ]ٺD $>2TKCNL_ƚ)nU;gxE`*ys'-C]@-ǭoGrDH ō70w\Z$NJ*@yHF\叱^l9KFQb;w[{2. Q_+;35\?x_TsQ_C$O G`B$eh(~/k CɃ&CCrPTQyc n`l_x\~:HPY=gH{`>C!w.?*9H}uxg.b4fcP⽊dDDRSSu·H b$>X=B)xK][+|`>ɛp*)jWpR e6Vr ?.)5W6\W:/.<gبcgFJH2Խz_C&ˆgPWw3FH>BKSJJ^vID둜nkd"E(~,iDxj4KF 0]"9@Zx_F`bhR/*T^hjܓV"tGHl:BV!GVb,Qm;yI 466ƩSpEٞH2n|A7 n 6ڊ!;P,/tm\H "h؀fs^| =K2z#]ř8W/Ņ閺ֿʤ6^q ^[uq@| ! `CGcc-"x԰cs%dWk $:{<w2J%MJDXt`> ףL8 ۦeeO9ȼE$oD~"/,%C/T*?G Y!v7c+q^ sFN|2ٞDHڎT@.ZHok!"%/o@VH"dhC* ot޴H^HqorZUu *Q!%mEr f^Trq_}ГmtQ,qoƘȡ;%;2x" =l`X5VN/Mhjduy_1""o,Ķ0q;"鏵2\Xp}h#fòUiVkD$T$H$2dݫHȎw6@Lum7C0]\$H}"iS ]7uϔl MƯЗQrgl%mW$ř m8$H"H!$>@\"-Լsq<FM4tIJ!y}x֜R$H4'[2gih|.W\|w:M<) N6tしAC#3ن/I]O1B'1Z 4;&-?{_ݤm&{Mۤ#JG&^\q ܫx(Pm~~I6m&a^ו><99{FP+塮6[HĒ8gvMa[ȳ V0g#"<؊UMOK$P}\ II]ۯϷfvm7om⦉d ɨ\<Oϡ$qX3N a7qC$Ez oDSz$?Vx M E((1ci#4k{$vOMk\[Em*\7ܶ@Dks"##=ݸqv]lK: ӣ9]HQ"}xՕPyd"iu *ܯ'F{aο:Z4Vl=O+snO4|c})"@ D/"%xҠ~=|}h6X.Ư?ʶ Cst/MwΊE9qXp~Ʃ Y%4>9e'!Hn뻏cjuR ԧH@8x2lW\yl3K$iI>JP+[bx"/)"̑Ho4W'u y+(;0/g ]+FġOHxd?`c{udc+bũEM&$s\tA"H.Z!CbAH'|~0RZWcaLXqlC-HN"9[&gK"[&p񛇐-_|%~FM~ⶀ+$AO$ N$=5Z4H2JVbتK~.0$$A"IW%`r۲~  WLK:"+NpeD Ibd &Ě/!  I LL#$H&''C&;6T*ERRWN+\>$A~qw]iĭYcp4?p=x='ۇۗ;툿$A^W91XpeޟrCXpe_$$  I  D   $$  $$  $$  H$  I ApkqkNBY_[D ɉW޹{/&EEEq•q{6A&ܯ$}~5MF{75;;qÕu$ÀL7' j9 HbyD  PDʛq\ _ł1_o( H$ `NF$cbbb@I:nh w8x4=!YMOҺxiI|ID233$AH,* n|H$w@" w8q~dfQX6\> Z $a1=0!p OlmA@sm&Bg]rh $qDrvMy뭷phmGttt)D_9&yI?DR `ӦMC$E}67!sD(xL݉jP^Zd:.vNZcۣ.-Cu]|ǙB%⋕[|d0Z>T9 $[U$'%r˖-<5]~] Qy;|R $l oߏ_lBC,.q+[/܉_O=/ DRRa޽xHI wO`98j HH]"{1A$.-, !.2m!**j& uXWWbĚw鿍Ȋ{L\6QUn7:8M+$D@ΎFڵUH 2~w+gIS.n{9@v<;bާx,{+Y+Lqx>! r&$L;㷡r1>D_vkLhtۆpP=") +v!$nljjBGm&q{7Xa}k*51%xvi7%VB9bA{عǓ1$1uh DDq7HZ0A4MEzt=:}r&AX+Fw=e5U-PF'ă.`euzWAĝ/%`^5PVހcn<.fAqb_@eQ!Jh/s`z#.~û&Cl-viBad*۠,E ~yAxN\ơMCP UK/tuIs±!| >c[Oܬ<-<ěKcXׯ6-j~@C,U@^uo29YVV }8e(bj %"iݿ yg(b|ֶ3ó=j4p>-@jm7kQZn> T87/J-VZw>MzyȅHnF6"/px]-$-/;msXDxAj Z~E,-xH'`78}:Ƌ~8?!7H `X~`]۾%;-~Ns/pYhk}<7k<3ﰴ}`#NЩ}>Ĉ!?#$H$9s^ OBH^_W _ξ+?⥦$DL'$^j#裏zF\#eXf2} ڂ!A_ܶ[c< OO2><] ! >kï/8y"9cq>5qx\dža+*ۭ $VtZ`ci <,]nlg2>Y԰QL";xԿFm٢@ٿvcvOtA"1!h2W!gA,ыKg:ۃH rWgxC!mH$D$m`}5E2 ZEsDRی?+ڋH0v/Q^@}R1L+*)IqeҗDHzIP!7]$ <&ϜZIO{"g%<ߞN<< DMx/pW2w "/2Zb /E2 hº I"-7El'>Bw9,=x,' (S$m.tvm*Eqs1Gדb#2ن[aR$=E#ovvr=gAc'bG^ dj ϰc#3ujɜ`4m vn0g |9K!vWvO2:҂=LT3y~O9_ R6Ãf5`wc[(>br~gÑ`חHr])м9 d"w&$n?to H$@Lo"*ܷ?9Yz"?=yD\K?ƨŎ Wc8Wٶ$H.Z!8FXHwHΖHfgg#""  \'$H$ DbF4$$$A"IH X$eee!<<  \'$DXp"h-K$}H.D 9H$&ɐd󎍿뮻 J4:W湲O"I_}~Wq+Gg7222?s=^mq;{A"IUw \Т<#\YW"I$  D   $  H$I$  H$I$  H$I$  I  D   $$-HN,4-6N?AHq?Om\EEE A$A"3 ½}lST H$ +b$Gaaa A D$'|w  D nOH$A"I$v{G x. n4 `ϣI̻ Ck4D nHfff: $ɀEWčDSH$Csn>3_ޏ"QX6\> Z$7b<{`74C̻haXE jv ã9 n/a"z5J3΋suH ɘpjz-^PP@"I$W'6mg}") XY)O;\W K+QWYDž֮Iql{եe+7=`A&lދ/VV l)bj|]&oyd>-CXWD"IHNJ-[xII jTTػw/x?"D/~a< Vs11ł; (zH$H q΍Y0q$= 0 mksp~gA䶰Rp<'G(qE2::.2m/??D H$I.9;k.Wi")m^%B| vV@۱o4F'찍ާ C\eoCC;{!nQx>!"yyy$A"9HO?Ν;hՈ(\pQHRVPy)G,<9`yqH0,??9I{#D9 \ڃc~$.|}?҄$<$AHަ]j|GF#oHrֿY,Lb_-m ;;JB$+bqP=6 [qhUrA޳8h{ML9+>Lk7mDW$?D2fd$;ð>AX)XƇ砫!driWӨ ~݁7V4#[Ŀfܤ,-^~ `t N+9[9 A1X")uMϑ\ܷ(.OL`bO|T/R6cؿ!G H"b8 I )BC 9V7xL9 HyƠbwV"_u^ FˇaZEFd;6œf9Y&(" &Ax|E}oOPwDZתi A"I$dnI]mYc-]B"bG^;3P˰q7}`7way"߱ϲ1ngd +_öQ|Hy\&;$ٵ] lY2BAxIYťO# ܺ@"I$-umo޼c4fbas 4&sEP &,'&)PЉ= T$j_ 6,G3~10jűTE>u>8}%QcŶ!Y>)ACz+(WqvU *1)?T!1Q"7Îсwpw %Zt+_̇5[()DQYo>&h"PzTQݹ{F-WܙAxƾWЫT uo^ }A"7d6#y<@$ OΥ)#`9EjPDD8&Wrc=m#$6H:"^Ÿﭝ8|v24_1\Vэ0lvXFpP,"Lsb3:p C?asj$\7RZ6~{mpAޠyɋj~ȸW}/6(G4o1X st/uh+S4:˟β^L ~"~I+vF{^@=V ønoJCe6; vq]+Q._$mA_\؞gh;1kqǕ(vMxn5!7!8?ޮG8 qD222r9}i X "h"w  bQ$C+?&pzpS^SDLQNPoEyh qErLΖHI $~" *sjw=_/L;㷡a;I\brycxQhys'GaOxo"vA|3Nsl=>:NY -CwЩ 0>r:`_(^Agz+Mhyy' vE=6qe˧XәPY.S> o W m…/CJ/-AAHf"O^o8IH[6VWC_c F؏QqQRk\[r%tkmkJꍎo\Jƶr$]I˗x(ɔ!)=6 уzEjMKX,ă.`euzWAɨ —&3>0l?+uP֢yF` BSqy(=E}]3̯m韭 KOoxOnFI$ D#)DJ~!X4y. luś(sV +{7a }0 I IbNY~\t%K$-8^ -|\EC,; ؈6|4bOai (zWXl@C{v&zQ D򎘵f Fq`}c\q o@d8jB{q!XLh^#eXf2Վ+]¦`"),,`J=O ݻ@"~zeЌkɖgЉ>uVz퇄GE% ;k[0d(}EAVJ&L;0j9-+Q~S$cE$ <&Df;<@~ riXBK$9$;"X',s aZl]bIAA"y#ɓņ+s X$PnփP0->Dr1µ1n s,/`z&gAxz;W!E|ކC/ȧẶγ{g~$, ?ctmԇ&  H$oYE+PjҘڎamuqLX-&Č-->ER?Y'pp %4v'9xdE~חkR(ؽ39njDrq0VAlyF^ލ?VHSt7>>7%+M4k  H$og m{1x",v;bx%!͗H@8x2lW\/o"'Bß3cpGЧ IR;Ÿﭝ8|v+.eJ$9ٓw&,M>ǫ,?㰏|D DE90c`AA,p$  H$I$  H$I$  H$I$  H$I$  I  DD  DD  DD  DD   $  H$I$  H$I$  H$I$  I  D   $$  $$  $$  H$  I  DD  DD  DD   9,Z1T@  \"ɉ1wTaD!U^, J9yby*"yTQ]=k n5T"Wb^JJ`֫71vL-ȝGZ"Za5 FYv"|?K<|B+~dF"ёo3?g׬gSN| D2Fːx3 QۡHHHHIS?T񈋋&6ay[7X"Qa(Apybch&tW%8{\]xkCʛ7Ic'EBJa4iQEH3i36!1"j='](fgZ^%gH.0Bx\%̽ˑN-&| Frm }}#$I /2&Z"Xeq EV dW!IMtʕ5:\d%IY6*ex6W7Tt`4hVi[ ztF-Pd̈ "QbM0ѭ.?W$e0BJo]qѢC]tWg~z)1v2&m=,{PWp|"1++!hg7ɠhdT48g';gft۸ԵtqOfuZ(! "7^󀏈$9m7poEM^3rgC{]!rQ過/C_;bg DK[7K[.Bx3E-d)#=DlA'+{4+"@^PtdԡGS 3֧ύzy^TJ4<(eȇ8Wݳ AEiJfK;?]f{0dYww '%R Ei))4 &CIG0M0`dDx_$(2A[=zϒ>,zM*8Hc$Y>\62$  T&AĻ.c$ٱ"*|^$u왱V^+eM]>%VAvqwz\ @;=qH&$Ë`G_M2ѠCm K+OBݮgwZ\"wV (, V#Q8\$H:ʷ< "m%EG#:&F83FD2eZ/?")*`_^}yɴ)!,U1KBlQ9PMdz4uR>@c\ݷnINEg^ʫV@,ANDsԘFDCD)(ǧH˟yȟh$Ws_r(>H.v4jP+Ff=7fIQ7!82 f%OOiB)ѱP<ӷ Z<7=w =L>b_<mreJ$s!V LZguQM U=M %a ;t$_XDHrErz ">N.Vޙ #=FH:}q]i!IQL&{Lwv 7iQ!&nb2+™vG^+s҂5Ώ p*-%gzuI cMn 񎥏5gv00ꛑE<֣(U$dWi7#Arzhҝ]f09g^Wѥ*BzB<⥉Szuy6`i<fQ7AD\=, jhu"=QH[ZNti"͂NA-2d&p9.D0-: ܳLAЏ(RIz.dA|J)Z=òX5kQ4 iqL,5DɓM-W3$BxZiS+Ey "٭tLq0{l94֣p9Em浃ȞzȮq΄i-\MRǼOt\7u{;>tuU \65YdH!f:Bi:u4#$* $}gm‘ō*GmQ uw?fnIz:[Ywk>3=^ח!=- ď@ri:pi֠:-l*=BqJ%cܒEz;a#Ai0:E3<rU]=hkng tu(O,R=aCJy""37+hFk94W{ĠdVZK]yjDrr6c)cZd^$RQЁ>nI5!AS+j@EW^w+ =\4[F LDOFbd*KRcص\"G$=-HČbÐA_'3[?ɔ 4{55sC2ֲ,h؆BLtNbs"N-YM&U%׵-׹ے>L5dΓ&jNsKHMbѢE1 *7VEz  $ ;CxH EGCA$kO[0r}]hɇ4AA"IAAHHAAHHAAHHAA$AA$AAA"I"IAA"I"IAA"I"IAAHAA$ `ѢE?GJp零OHHA\Du]?Iܦpm\."ddd8=CA"I"Iqpѩm{7HOO$A"I"IqmW$g C$9 n D  ER"$A"I"IA"I"U$e2IDD#(y:Ĺ*3^(5Ύﶺ¤(-JF8o=G^d Nm$-1113JqW!BĤQ}o^XZ^ @QBz_I$I$ ²6P<)Q(j7A[mu/|Ėv!G5$/D ir"d6v`؏6UOԌpuj_9yJH.DȆdDf5Iשgi*雑+G$2v4N@,$\^oI03DVv-E"E2$&) з#] Iq"uOo黕E"2.I[T$ϐHwMERn#>>9aI"I"HHKѦף8\")LhD}z OI" MyHOJBjn%tfGC) E[#2//#ܶ[I$SGML1:M({K"I"]$yHF+PHkžʌP6S(NCYZn2-x6W eHzrȨEuEĂI^ vLLtT!%y*۵׳|`hPW E(ok4BHN4zܘPVAW4؏Φ dF͔%KąY@""8 ,1BDy-\ąSxrں]gj>Huvj3rײgC4S#Pkk[Q#gN9Q Q u=; }]h*qkoi 3"qe="YHw+dTTT@pb鳁G X^L&=mMh59$էȋ乍CI$KUah@K]π~Vה\8/ŝ&tkII"IR hӝ-DC 3dM@FC3r]/)/, >#H >>z*eQ1, R)RsQզcs#"= XI$5_|I!jaAL8$%@s((TR5ܨBd)R$)+CzY+t.Jn6߽qF^܄>"ȎmDqz (nIׄlW9Ԉg%-|ﺞD҄WE/F8'sɨ1YIRR 2 )B-*q H -P6}}~\9^T'u; P"qa绮'u 50:}ץ56y2#V_V.CB}ܨϮ_S7*eAԵ}ˊ6t*)IX7APMh/r[W׶{>s[GjCVSk"*( *n8OZ_P^hyLe:DD҃Hv֣}:P:3ċ)Ay L4Mn] K3Lf,1<i*#L-+"-C߃^Lg7D]! \ T&Aěg)u֏S@ݡE^]o/ DErֽ]ymqMpf8EiI#AH93&KQ>:JY[$#4:$'3̳+&M!<_"ȮaiEKqaS$H ZN}TYQ-IX>+|c$筛yVèW!-xk8-YhbmH]yPt:_ei6d"S_%T'HHz#CbzgGM5ZefD" "CД@&'A<ﲕ,ZWe!Aqt< FR$TH4Ĺ Q|/"GR~jhXf5 bD@[$g^?"ϋHIO$oH%ڪg=QDg=,Gg!Dzm$7[$BkТ.CLy>E `P%&~͡^cY5=Y&(q0ĦOM?hee/=uQDDD׬ 5CgC}+2u1U繫w2ohDfX/Zz+s@qV''WSY${}w'A;)Die8i< zPV e>0M Y޷]ێSǾC/Z׶Ip4V078dr͊9iwFS↉dP\ PeDN"ɵ*#6E9`nwfu3kϒ}04BmcW $Sƣg gԳzX3Y&H$I$=#R NTȂؒ֨jP$i< )I3Po^SːXѫ.Cnj"d i(2lCa/L5I"bd!dvd"&x鹱t gU BHXZdA|J)Z`xv .ԲaidnNDr{sZ$Xy 2vn"dBhvTg"}rf b]f}gK2sOCmv9$/>?D XgM\,nlbe0 0 0;-#/J$\K9Ka,ȑĢ#VDYH9 Mj.-7`fܹXzY?}64XYn q uL7?q"^85͍. |qD= I~Zς% (KKKWb[)=;x ,k{8;wəm\S͖k.z#k b~,3ytHm8ՂP@HHPto" 2*!_밊;8"+ ]Q9S/b??&[|(fι G)hDz~}=YCq=t%EGÙ@.}9e>pPċ=K9fh""7<B>ЪqTn _: CmxO-wE7*c+'//N WH*lg.}n58{yG8U"yyiipDP_9Grq^m+e/[95rqCI?rT頎$9ɛ2yS"Չ`PۿfjPg7>K%h3 4fBpM,5hÕg>. =9e&mp.$$Qw#I[$oF&kI('Ac{N7D7L3{B0MDDdލ H$g+x"[2l4=BU iܹ!AgL;x;vPkuhΒHHlѻ$Eraa^D"g(<{ Բ.L5nd%~ZcZ>c $$hyH$_1|p\x7$$AOΛo_UGt:o㭷ޢ#H$I$ <2%Lm(#7I$A"I"IAA"I"IAA"I"IAAHAA$AA$$AA$$AA$$AAA"I AZy-}DD )D>1Eɤ*3rӯ$$ABoѾf&! Ѩ$A"I"I0FyWC$e666$AA"j$$$A$Dt\ $$$񑣇-K{ }%/6vV?grs$q3eDI27?Hja %1?Y'ޣ3YDDxaᖱVwstKx_ 4ҏ.DIsnMTI$_h.r$$OqDR;u|' ^`e {ER>#ruuNkϓH) s*&R[#I")#p["98׎Q2V%{~lN Bԑ;^:)BT[ hNi4  o0ϰwz]QBӾ`xٰ8.6Е$,(9av$utz.S; ӈh =H} v1X*تYc묂(Q8nDrtG< qVWz+b縐Qt9c+F&{^ذܱI chj%BtFDbdK3SCn/FN+kL#eB!0nֈMO7 dJu{oEoL(R6p? /Qm0`g_,SH)mgPmriNs7=QSDe s)&^b9ge׻F%.s[ûWfm*hp(m!|T7^yEIW}TLG#΂ͪ_N"I""w^[X:]܈U<VRn>T[D= G`k@YFQi' w :,KܝgTHEti`nPr=Or"qdrx5Zv4$& k̰ z̓T%/ڶ}p)Ӧ$m۬c֎LUqtAń32^ӍYg{ܔ)"uXG&WN,m9l̍ ۍbt+yl9+1؄on~ Iw{Dw |,]= V{菌HjMn=جvc(-xp5G/Yc䲾c5b1H6]̸=.luH4uc)X vy^ɻHq:HOOtn̓28~F0땱rbfus(Г|*K#x $oHjة65X=@IIKN6B;EVkض!'F?CL.,"A{iuEH=D#ɾFCmq{J);h<8H(.`JTXzriDJs)'"Rzց'Li}8$e=5iV+ ӽsdE 9%35^ٕ25ScaݱT]SZ.GO{ j(C!47>sשVWcM mԕFS7-`%/BdYNmʫ*£q52-đ8^tSD" 34ywpj}Gh~s܋3=|i2|Eh4ދx<>y7Yqa:4]:hC*Nfyԍ|ݜT߁'A#$-3:„}&ag6xuI4KNg0-B*oMaV6]Xu|M+ށ&k|6GEn|6H=sXX`ঈXXrdAt/L ]fb?YdxU7钇CPYίH|-mUFX$jcR̫a=HX$p"/ t4ptƩ AL+¯{R$եGv ~i-pTc)#kIkSֹJ"9oaO^#zEnBꚄ2 FP95-^\笭=]?Z] B $$$Fg.g1ըؠB HELX^^cɠ~Fy .{&I 5Y$kH:L Sn^Rvayn+kuiHGNCJ?"1a,s샞ɛew3Er&$"_F0Vn_,-cy6[^GI]oхpHX=\pш$$]:ݑ6"ÑI/<^N$yMl(}L26-S)C)W*5mUfvXsO^ׯepMIޔ@ e#'VޜS; +7wȱO̹yd)nI?ƴ,ã4H&~Y2ܽrԶtS#`ѹuH6wJڪI4R&yI* J>I^t:}'5"yԶmbL$y8[Rik~q8ns|䴺<nt$$w#cXŞK?ݺ`NNn?+Dn!N!Vn8.xCql9飕Aʎ{tz oˆX-to类49o6Ć Ic n ANcI5N$9].#praѪI.*{ÏidpF;aau_;*}RSI.iHܞs\ZZ"ݒHFk}^8֮G$b=j8auE.fk#rN7[e-.zg3#ά  f)RfmPYOHHtVf:LNGIu Ev V1;g4rDJ^ľ(}C9WG94K'XwM>J3zbCwN8u:[fkL.!}hA#J\H,FPf~lIG>r "TWY`;sS#u(1p\cDh~_젖]-GjJoEt|pTrQ M`s/:p3LK#Xj}&6K8?"DBQӒH"yS&oJ: jXc8BЪpx\E|2ctTx6kvf)uSf)j ("nK"I"I"!q纻W~05h|n ;6 3m[DQry~4) B&r{m։i/xZ;ޒHHHyɿ~bb̵J|7I9ic $$hyH$_1|p\x7$$AOΛo_UGt:o㭷ޢ#H$I$ <2%Lm(#7I$A"I"IAA"I"IAA"I"IAAHAA$AA$$AA$$AA$$AAA"I AZy-}DD )D>1Eɤ*3rӯ$$ABoѾf&! Ѩ$A"I"I0FyWC$e666$AA"j$$$A$Dt\ $$$񑣇-Ǔu`=}-Ƅ.bV)=R`'A,p$ijI27?g"Ip(Vsb~ 8jsI$I$nk% }H;u #ErG^7$pϥHf1&2)_ommI='mr+XQxb.-_$H(u(n:H"$7Ρ#ERoOi!|DR>#ruuNk/Hr +8CB. ԇH:")#p["98׎Q1V%{|h_k b'SFC!vD`^MȔPku!J}H*g;TH[F [i9xQ%= vw|hjnq\l+IY/ReTۑ,׻hO0\7Bh =H} v1X*تYc묂(Q8nDWg#jJoE}qfw_\5DŚ^za2V^4zR k Y>oIH;X&* (x~]oH7qCDЋ9nyNXEA|:aWy-~]Rv5l[a.XY<ƞ2r}[$9S9oA\dY5N3IBOLI$_4LBi YMHT$4vWmgNbff~I-Eteba%Ǟ{)}ܦp~)m\/DX{:ߚ)`7F!7쐃HESk٭p6kKhW{ՁK(v:qP.qwv~u"[@5"aG=Or"q:kl; 5xlfX{}*’G~\,#d~5:ÆC8xt $WڀW~aa Wxs>7%tzp֑hFF$Kps:5y V`sWbBy ?&..n\cȱ,>ӈ2U7PsʡνB6jw-A*8w[$lhgbX'wNYgLEDH,6CnVB̲ #6 k8y;nHYs5.aNs(||LꪬVi{r}׈ w:˫0fԃq~"1bI "$HC-s1մ\}0US'f"c)fuA kΣzO>~-fX]~m#kO} |nE/fWmq{J);h<8H(.`JT 5Ќ[+BzkNćUƮԡևABu:r̀`ZTIM +J8)q,.ۛQfu4u 5&QcedGke8ia]eH]&as#t,]_~j[E^=426L۶Q#Tj=벨yׅm= G*!XND?R gDeU?n:-'Y5XpcL{Aܑz6r/39, ׃oj[ct\6yΘ4w#m1yfJlpD>?3Q$W6Wd$?nUb 1Y<ƒAs\,@M@jHdt%)"9$Erjݲ+YEʄ]eXޣ6V ] Qf,[j<3ÚeVת4`a︭4ކ`j; GzoS/''wޖ eWpz\m&9]4LH^ׯEt"+#M].9#Hbv+޵+#>vsflVETw8n`J{):˅ʡM +v{W天meZujGZAI5"G2%-"M|C$:QNSIaƚ:'6QhT9ILw"_S/.&pC5ytH7cxjYI"B ֞7H:|MȼP5 BHH.'V. J d":pxF0:}tˇX p iG:>Z*f6Ғ7pFx;6LS6JEnL]ax-vx72,vA~ >;,f3,}|C$Jky]pWqRA¡}h]8iζO~U3эo4E(h-Qj7.4v`fqAn#B$Y/?2ylDp;-V6K#8?ijɥ+b-mU<7?t6h8jˣ=dg׉YǍ] 6LuA=Z#K alJ[9a/o 7 Rk: zGSĺ~D8\ٙ0Q8E@SM8BAox$EvmGrVA+*tE}('|0t,`9g8(6q7_*jfʍBW~Dp 6i92 GR6րGD1[R]m»?olg.w(1+$#"G2g+sTۗՐt ^gő#~`]&{#_3RD }:8?"~TUgAd?ZQ*w䵴,Zey D^Zn :8Nx&Q+8HHHM)ER8d2&W?kQ#f։s$λMiA7i q^m+9NH@J@73< R$II^B*A?r-Ѩ]d|$Wa̟>)WIHHH$qƋ)eA9ٴED2L8鷶I$I$INH$ D. "")O#[XwOI~&4M"I"ILyH$_1|p\x7$$AOΛo_UGt:o㭷ޢ#H$I$ <2%Lm(#7I$A"I"IAA"I"IAA"I"IAAHAA$AA$$AA$$AA$$AAA"I AZy-}DD )D>1Eɤ*3rӯ$$ABoѾf&! Ѩ$A"I"I0FyWC$e666$AA"j$$$A$Dt\ $$$񑣇-dzCcBps1+\Ǔ[bcg.Sz&7O1Ӈ^H$_X,c8N+} &ql'|Xfէyxy&#DF]IIÀ[ZIB{-9u.C'?702T@Y*= }Rd3ٱx=dDũnu'4ꢗ hv]yHAb!z)A" =TzoMgk`MVvfs#vTeG|i1rA"5V8ȵ%4]^uJ;Nqd]*4oXXGj]/tNsp(W.' gM&-غ9;vౙaaK^`mb$m۬Վ"UqtAń32^Ӎ|8nJw: #U+'`ь|i66mPW,>n1 6g{%&#mrz2n<Ŋ;){8^C4K^6z5:sĨr>6*SVMPDӈyб0~a=[}UTF,$pfvF,4uҭ@Eʤ,V-ZW@$8]'Re]ggHjMn=جvc(-+eū+c//pttRFIR%tK,7@k`IHT"9Bv'kC\$BmVj#T:?N籑 G EeH)Q؃C32ڴVa"0egm{tևABu:r̀`Z`I&nt\YְG8̌&ymFXXwLZPci&NGj'>7q̾R-`?Om+ޱTƆ]x6pdOTSEs1W{:ɯ{gE}bxClSWz|cjԥʼP3M~jWF.:{ߩA;!L 'Q4Xޫ;w=biMcͤU!hEh4ދx}>{s:~mu7huA.#״y>ZR k .3ؗ\„}&a3xuI곯,"I!k֗ìJmnLirbn\F!c"^cim#z  KnD,e+@ױc'k]8`Vݔ}Ayd92~4~} l[/'ɱⰸZfO._] e~n2`=*C)HڑWWIΔ@EjbL+uytEbǫDǢ'y)FnVw6Lq ;vHmZ>#`)pjtkX lZF"*c\.Coֱ,KRG4zÏϙu>k$ٳO{W"h.s~fZ]~ $$$/I~2k,f HELX^^cɠ~Fy .{&I 5Y$kH:LW"95^w-{EG]eXޣ6V f !k f,[<3ÚeV>zHztLHI#&iuOt }"9z:;]$9(Vf6r"ġHF8a 1,\j44'Z,Ng)6m,>@q[ Ef9œ$gDrc؆Y[ހ]K$OgXH޸W™2"yc=2:"N#$/Ϯml<~gȤ>Tڎ} ր~S/''5۲L1aشOmv?Hr󈝋ѩŕʤ"G2mH 5" ٻ#:w?]g`O||\0DrLJξJtd\"l4 ~ R}~" 4*;=;\rā{Dc9ϨɻI";_#9IɗI=e*\lEu:t]\$r aupp#dӎt}r;"{tz oX-to类49oHSNy]i,\o宄: K\( ~.5)e-l{,X2ܽ?Z\ZZ"ݒHF?H>Xfɠ)]yMeNvRHZ]BWL+GKS-u z -ap<%r|382A>&+㘝 Q.1"CI=E%Etu8(6q7#,jaVƤBG/Bpn΅D‘lzB k@#mM%H&S _3ʑ2R5FD˿Rˮy">8B9Ψg!-xH1IV$$~bΕDQ5<5j%Cj !8"HU;ʙ@.}auL Sx9%}XyYiPq`eCJfltw%ZycPX$ϷHޔɛDrV=CmxO-wEwY;I5"a00l3ho^d.$$eޣ{u Oi+%~"[DQrbֶJL"l3@c;$$$'$A"I"9V$`=. Y=6[$$$'$A"j½D"/H$|KsmE $$+&>. oDD y7SZ0N'~m[~$$AÐGI %^~&$H$I$  H$I$  H$I$  I  D   $$  $$  $$  H$  Ix:ana+dGcss$q3Q>AHS[ZIB{-9u.CCi:1.^AÇ| 9ߥHHhA։DH7vP ($lQa|ID{+_u4=4Rk^868/}H$ H$_648QvQt@OD򥆃9yG&$A$/HrHd+ܖHnεcjmZ4u\Zc;2SG vx]FZ QCP9AФ"O7rgN}r(i_{cx@o@W 8^XTۑ,׻hO0\=3PES PU`ի(bwfɏ Z,PG(Ǐ_!n8+s\ڨfw_ JQŞ6,c>CO*buNU%^08,OXzr{A5TANv4_$aT?<.u9qDuj!KB:bvݿ3F=LqdqقwoRޠ΢X40޳׮|Bk8 $X{:ߚ)`7F:ga̍E+5V~VFKQ7[̰ IA"I"y-}6k#T:?N籑HG %oL 둘")e+"Ќ NSÉ ef@0-@$`&LE%G8̌hfWB%iefXӖnqd+ ײ{&oWFR -`?Om+!+,ct.mum+n*[DD7~p!WĩcBY1`(O)wv{MmslV!]]0^AM={\,wc"DDrHVp\@]04։q&D3єF?;3ǯKRҝu"B7F*Yŏu|$u ;d2!"^cim#,0pSDn,,# Uv_ǎ(xU7‡CPYί`a4-y'[ayHP@XL8 ,?nAyz`*0)'3`ID^.ieg#0;r"^SڶQ @B~.1.2e{XBz DޜS +7wȱO]pvO COAKρ(? TUT8-]8E2 )LVϞQO57kd!Zf$wAHH*cXŞK?ݺ`bNn?+Dn!N!Vn8.xCql9飕Aj7G$Jky]pWqRA¡}h]8iIvq<!Vj#js ƽp:Goj~;\\Vy3^IkST1jly鈤fDrVLXՏ#ʆXF;uj53ꩼG'bk4sD[ l[9a'jNf:- H$I$7BD3։" )NJ!_7<"+㘝 ]Q9:S/b?3EI>tucD8(6q7ף-*jfʍBG/Bp 692 Gb/'Ѩ3l7Q̖{W*g.O%|el9̅r|mxH'1"r4/vPˮ}RWz+稶/3!lֺϹLK%/s'XYCq}8LUTGvO#OF^uA4`7V=!kF=<^J)c,jniml8 J @"I$Dv\ܹFJ4baA*n  $$|Jdh#zPAҪz2ΰ {Fe: DDDU+νDy Ŷwhz :Rb '& $  H$I$  H$I$  H$I$  H$I$  I  DD  DD  DD  DD   $  H$I$  H$I$  H$I$  H$I$  I  DD  DD  DD  xD7kv/信AA񊋤,?#?r/信A<9?ki^xp~gA"{w>wv-'k;|[TCLg'Oc|sdC|_wy]~c|'OIXyǙqJuv?7w ?A$y{ ?_;Ws;#>_.`]|_įǰ]7΄/}_;/>fK귾>x?~GmT?+ӿ|;Ÿ#"9RN7?sݴp& |ERşٟE՚:D")XVƧ>=OW| ob''i~4n= ,qg}|8;:II&wP>Qy_4=/~ ,z|/ GY#!ӬOۯo}1aw~}P2>o ?KMw]v_`ǟ@RwgP=??+c&Ãe0~ ۟iqt'/;9A㿊/.S+ÿG&NOk|?rO_~{N\D_{/M'ke\?;i<7񿶬4 pRGdۻ),M?I?ïqzr>{_ilՅ_a3 :GßW"gwrqa.AA"<~7`2&F>HnO"̞/ktl#.?ۻD>};ΝvӺ] IDQYTT\кVj.j;VkkՊUqZqW\P@='!@ت ߾^ 9Y?9'' {F8 1rĮ%MvHVvj.3Z\!u=B[ymGDk[k/A zXvm"MղZӰeXUP{F"-EtJ.DhMG |x|7\%ognn`e/!i2ϯ Po)!iMRO{mHL/eʹp̎/D܎S\^GgS]y 9cm_dj(f<4q-n+}5~)Svddy=Y;!c e6I)uw#Umd$PXØofq]p-b9:OKH]-ȳOB*mϡ F͇tz.:i9 hjAؘVSs:ioO`T?'OsuL+;BzzDȏFv]<.P"tldpp {:m x-EȉNb>#)Bk\6~vWֈۓÑ)p1gَSR4d$[W2%/w؜a=}j2~{yyhDDĐ!٢E ر2[G#Sp+]nHBMBR>2'_$)O'a ϷC2.pgm?SHzXB m2~ƾ1Z iyG1ݳisNA2ne0W  £( $z.gMa8]xrHfqyYw;CR X}boABe$aV`rBN=ߛ=Gdnbn }JBr06=pmEϒXW>ϛAW6ˍ0C\lTFVb h&)$.>իNmw_c6ƛ/LZHDtH"p~j;hY ?a{s;WYHʧ}>6i_:vt׈J6#v?BOs0t<7zV7!(_hJ>CYUM6#@RAI;cswLYv3Mj\KmH}XZXaH\_9vc o#eH;k8,asZ ..C6ѳn)I( Js~6iW%=t Ghh,裘W6aD| [+}^-0d2X"2%W`w$n?9 ơeﯼ4>+gȘۧa"j8g\TI~NGĔsF]Y-Lc$\yk8||zE8zGŦ/t:άfH6;oBb>[Ɨ=1z9ܕAq+nJDvԲ|"%=FxC^ng8$Hqi'ݲvosRz>bZd+}ifH1$_lԨ) B~  l~F!Y$bH1$D I""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$CDDDDĐ$""""$C!ɐ$"""bH2$!IDDDD I""""bH2$ I""""$CDDDDĐ#"""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$C!ɐ$""""$1$DDDD I$C!IDDDĐdHC I""""$C!ɐ$""""$1$!ɐ$"""bH2$ I""""bHC I""""$C!ɐ$""""$1$!Y$"""G wy^ &$bHCDDDDĐ$""""$C^lҤ 5jmj`y޴iS.ܗ1۹Y5q2?AVNWH6n;wFѣGjy-w}״Ak#z޸u[Hg~"4}Į?!)8;;S"syz^\ݬѵ/ 򴒧E/'v}1wϐ 1\.QX0.{c G]X<ywN\GcȰ#x8{SDzjYH_ 6!žgwaJwgWݛ |t3$DuAMՑke61c ӭF-_y,ܹp[gKoٹkhw2' [%#?0U"Z:  s3p>_GlG1_%t/}lp|p4~XP_-4w!''*i?`LوqC0,*f,ǷWrQftUcjZtVBrS U}.gP҃Sعlǎ)r>U{نt|R>yW[>tXtˣ#QjXX)L%$?mk:(!9L9]͟EH!=.u0~m'KH&ыm6}h䯽[6ݤe8|Ǐ 3pػ$Nm{jn1{`xt&QL}?&w]LʏU3h >;T޲3y+ϩ+c|ߎ#BrgBw! ~A5~]呧Y I띺G()yL×p/YqrL*qGpc2n0-!>kR5x<|nI*|u%m$]LEf")Awy z^J6QX~-ɻ*7ƒ\Ul]Z!mOդuW)~1z;9FG՟vl3W޺]B'F^M|`|c~2z+=YMKne۪a@0^#{S=ν: 4鶎qDIGC=(Ư"2$v FSE^*dј .9yOG$(tm5q"5֐ xn ɝsV/ȓ5<1 +q]ʼnm/sHn\r>KsHbIć@4?Ml)oٲ\pVMC|t '^:CF`¨HsvJ~!~HھXaژX"BRskL1$2A%ӣqaVRbXDHwjnQ^Κj,/cD/BHg -1Y^D~-s #gx[3!"|0".~oJcbll4GNƊCEpƇ=}Xve2ۚr 0>5iG#9ʿ䶎#/s}Txlɰ'cWf1.6}#$~RB)X& 5~=1MZgGaPXx +M1ːnFKi`>; \,;;%Q=|%$#ZJeB9N%;\lU uzM8>'4>u_w/$?(O؈kkJc©3;}v\2t6e*,!)M6[)_, ItС*<;LVS՛MUC57;.#6-3ܽtՕ̫g ֥) Q$rB2}{jaj̗3cLW#=Ȕh,?Y>FG"!I=$,/$|6$_-{v]SQYmA ϊ}:^|ghcLuEuuH>9N=<)![K8v?L}d8Q̃5.Xv-d"=EqI| Gd _=LӬ!eȽq3SIJ嫒bfg}0P8g K!0U">pAbܶCR7(=|\q'(B6֕;aސұ=^x?aԆe) #vn\7fbg3I8 CXE(wtRFhj>&!@'eǝxb(|t.#e-mЇ8#FrQz[ |wҲr>Ż` 8U3$X=ơE@*rB99(~#svD2$SJDNmNs[Ǥ|jdNBGjޓyz99.G.'$5HlIv $Sy53qָ0EOLfm>7)ڶ ] s`1.!JH.G/.݊Tc6H#OELOӬ^cCxa bC ؘR«!vd`ѽO'eX7tzk\Evq>mXH;B{׫QNQ\7ZGyg/іG+G b\R5jíBM9A+mzN2tfɉ%q ^ rDmg)$cHq釛CrI0<ɪ/s/3g>F Xdc1sũq;\SB<> C=4v,#6-B‡bPyh\(ϯR>",y4>N!X"6BhɶhUӻ1ٽq8r7ineyypm-!;Vco#zQB;qj_l3Ia9Įb<ޛ}8ߒ2<!!0j|n!pWO}_EcmM mSH7oiٶ6?lEC9izlɰQ10m&~OmogVg$7$=4"WHեƯ"4{!Bh>^"l+spkPuxvc3;jls{bա+&D%ik/$5|#RVw>$|\cadwHȀ2 $5B t-&eC[:\3`Xg;V`rpX\.6( g3qGDd_}*>zcG{9!)/n r }xsǐmWǖ 1(u&\$K}hݶcl;j1 ?kM.7S5n9XxDԆ+mf#z+n1g~WaDPӬ!Vi6$СC*4!駱ܦAԃx$Gq&`*wٿ '!""S>{\MĜG#"?oL~c|Kbvu ĉǍvV3x$޵M\Z0gyh1X r9+^pIkf ~x"cQ覱>3\-Fퟰ~$`Ęɘj>#^_@~M|(Q#0mId}4b8^blw.%!ix-:Q" '1_cщ=ĆױgD EA%=M|}e!YYa?h{!'k,aârL!1]4u EwoA<"1%q:9Z[g(VO)IF,9,>#L!?`?NB6 ڱlYs5Q(_lrFEtd"Bg9.i}~h> I-7py3?ks|$v&V >jL/#( ߌl^*S0>F!U1qT,bF$`uرt8\^NĈb#A^ YCҀ+BԡuqmO msH8FQm#[[hܛ8q)&NƸK-16#z%Yc@gZymiրCR^03)[1|C)H1ȘGe9؍LQl?`Ewr8 Z=.g(yL 2sD?| pn"DX"Ʃ[8_rd1j{p N='q==br3pӶ"E}K4U<\zĬp=3FOeW2 0$VXvGq_kb"{eq} Mov ەn{j=Cūs9wkiH|-167V}72k0Bč3px^.qX ͚<~|]4$Ѿ}{'zxyW\>&*[ƈ^l;$iܪin$YZBӎ%${(rCE6lm:e?6t|5Z wU!zy!dCazB @Xx,!Ύu!A IbH h3E,n?p)"_UH!SxѰ6+_+n^ӬCB/l 6cuBK.h׮ڻav? yrt+f@jS$ʖ1!$z;gnC{PY5CQiAKH6V_* Iwx <+ I.Tы-PP~":QӬ!PՐ|GyPkCUCނ/rmۖy^^|Zƈ7nfvu-:wo'ɐ$"""jX!i|BWBVWn$CaG%$-sɜDDDD &$Nk[>W#M!7ۖ I""" m|V޶\-qNT"""Ǖ\w_|>Rnȗ I"""ҐyycDDDD &$>ih˖ʡIG%t*<3OV9iVQ/uYz픪N|G>iZJCUG%:*iaM%)Rt5V ..xQ-tCDDDDUbSުRCi2WJik4] ,l4Jm?F sTR}VL:(_TF'$' K7XS͓ĺ, GgtJifk4\KlErC;:ŭɷ檣UG(' K,iL""""9*uJ{YQi3֪͕{[i"R}JVG#g I룒Sܯbol\CUG([)V%2UA_&k4dsQ*"WUFBTG%7+xNZ(%*-G+ۨZ;""""[Me֪k:LoNe4=i9)7KUmŤU-Ai9BiwrAy!ZQj*Gu8GHK@ZNeVDZNiҎrC|fR}toNy[$q*2IDDDDbUz[cMTh9* G!-,/"ܐ/ &::iUG(fo*Ol M""""=jƷTG-7U]m9 "vuH|feUPYZEkVai7TiM""""[mn[kV* ȗ>Hi 9IENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_exclude.png000066400000000000000000002405711477034762000250670ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:16:04 CEST2@IDATxXTٺYs={n1" (`DrVmjslVͶmSۜ[DTT(H 1+@QTQf}wj1;1M]T'5g5WSV?t  nUΥ0w-_ZZ~_O/x;v* >yG]Q_  .Sڮ+bO*;JC2iD nh0jNSoZ|fAA0Mn-mԖKmT )2N" >y4jˢj AACTOmK}RiL(57ٙDHmyLK  PbȗJY#KTJSdR;3iDjg!5}ԖGmiO1BM5fZ$  LBۡ4^uDS[.R;KJ)2٩Df!u3d -YԜt/Fo5}|iAAC)_ґM`jK&S+ nv34I"!l@rgD32{gWt   .љ[zcD1xjf[7;iL&MȿhIgZC6-w5 8| AAhqƹs k!ϴd/&dHΉԖBrӟ.~zz9AAhqƹs9tnW=2=gU$5H]̉ԕHn<>/ˍe>}AA|`pǹszdRwΤF&5Y!m+~EK"#dL.%ڿ<AA|J8S:2W-Wi["H$ϷZۗ  #s;nY=Z2|IHs'"?ӒH[n_~/  >.8cwA0F&?d$琭3/Gù Nh8   կghe%f#5CKJџ` AA177W7]wӟtPKk[_VU$Cܤ˸>]0  k xNIJ/V퀺CܚdH7l_uPO?AAgRnS'~UܔFC'+W$F~_Fet   Dj5Q$e YIvC61~,0=MAN&R_f҄K/+n kk̍~UzZ =l0<“1gXQy'4'U%R9qvZs%raFc\H뀨5q (^ֈzX9f z r G^Tf`@`P }=clPO}I$ qFIq/GzH=>kPϕ'ҧ(F@5GM9H'Cxy̜9wgwdث"_f o;R߰v_Wt! h-&&9x#{h^K$x7}:77{¾A=sv` "lX'$O~-1wN?Ӆۦv5l7?R߰@I :c7Q)MT ͜^.XrF;?f:,<)Ee]=j+uO^O'$<uuU(]UنrBp>ez7\zXJxg a|ٱMy[ʪP_S7Xc3E,lr<޽x=s;/Eu-w^1yѬDuq4h?m3<š'|> 0I=B>ʹ)%0Eghrh9N 'b[);zۤ ~NXpf=n.JA1$.y =/&7v-I mz|jUú ̔]NĶ*9_kf_ xk|k(ZF6z=C@և^Q[^hh, }:& $%n(_t"=o].ۼxBո]5doHbZUFt>F*=7+3I9D6A|$ ojdNV/h?=D ]D1O /ɷq{N 5(/k0Y`H݆R`m8w:'Kk$ m{e/݁sŨo@Cu:ž<]wP\]\\ / )`=_j?m3FȺ">*+{t>}ñ'(i`eߌ2A|͟H!:OnM;E<I >z` 4s!T5EwWuvEAcmÔ}E/ܴ/I$ 1N*3rxZ~"f9|9$A{ m5u?zDK="$A|\"n9y\ x[0g=TB"I0?Gne&MD^XI>$AA5gҔs˘2'ҀH%H$  >,p^ZI#g^"7}"9$AAħM'"9$AAZElHAA|"I$  /I$  >yH"IAAU $ dEⵈg}  絋d߾}AAA|HAA$AA$AAA"IAAHHAA$AA$AAA"IAAHAA$$AA[gϞѣ? ⽀Iz2\/ L++̨_1_ɷQFASXŤ/R)4W޽1`_],W̸~XI$2]wa`iiI^$.6q1PWeϨ_!_ɷ X,&xb /nWʕ+;~D$.Iuo+~qِ8|jL$_{:a`o`5- R}GƤI0s988PL0HH$"x05󦏃h"$$$/WS2c_N~;;zqgl d >ݤ34'ܲ(# iF4I$XyVZSy'"9e%Lmqp"i9zwH2҃z۰$y-n+'< 8q'/$zjh4~:9Z^6d"&X?WҜepErȑ oŸZU3G@-bvM4kЂ_`㒊jp{8XeD pMֈӬ߿'.6d:-] Uf^m"8K@zD"'OA$Xsߋm1ζ7RDUUă%r^sx!rƘߥ2\˄21B|מּrYFS%R;3DžL$#rO$x%2 pqJĺ FWuuٛ<c|EG[1wWD$'҆m1{Q"řGn)iUIr1ơ^J%$OG$;H___m[+<ӧO@d7Ϻ"DuQݸ:!.}]H7y.n]a @t+?DjkW<&%!-CU2ӐIp$|"CfsFX?Bx"S EU|7|ɜy<65dҐN{"9b-p2d`\v[ú<[n/HnHQk:YN$| M::$:J̈gI48B SP18!7RDUU20SrC;zAhӳMF̻x\] 4vv8IgZEr;܃[Ioo/?޹c?&ǧ"#9^v..|")< ZYf\€~"<[Q׬\RFaܐHr* mģ [kdZq,a'|`@$ЈpSTIQW_CO7kW3ER@VOkqc, 1|iTK L V97?T!GSS\568l6.ʤ8n[|;KRLFҒ$xWlB|#C?+^x`"ykH9WdzKסXIK`S&11udcIq14'^bxj:rNOG02RX.p4H:qqHx$ 6=~qp'WfDUzڀV1?` ''TVsOaTuy븁gps3\t[" j[F<?ܕ@Vr#2: @E 9Ne#Z^؊D"*q.6/LDrkW+m9x"},j O똘E0!wP5Sӓ1v$\97 VL,ƌw 9)L(Eb(w wqW@,R31Y]fVN@rDr#|2% iq_7"1ʺDHNh[FlF"dZy\FEdrY;w"ye6A؍=F[&B_HJQ#8g˰+Dkzp0~)d*Te!۩HìM::ٷ)7t261`X#q4W`M㨪7`Yc߱ZL$6gD0Zq! c؜KIO Yk<뫰A)&K1Bo 1jH '_HƉUˉH%# a|\e"["['`"ɂVNQNnm΁ \;1e9S;W=dl۶MDrm:HoX|/H[?Q)ĭnp"颊7vjt7U$}yER0tֶD  9`$wSti6Zaa0 ɛ.h[Fʼn]rJ}H5CˈC1!. i,j_zNw+6be=")l6>HOWM16A%|v}T"Sέ"{j*ۮB@$EۚqbsLvW?9FE/N؂by)~ ܶ$(l{ pWm;`UvL,}姸 a~.pKDJ:iKk-8{gZYnD0J9v'Ɣ# oV$#D΄W%zERW|k)<[ 'NqnH "ɷwdc|a7Q$m|N$y|~Wg^۱Ğ2oq0}'18+ppV,n'yyv7"iccmInT^ 吲AHa mpƶǪG[cr2R#FcT4T ##5^V?*; 3/@VrN„ISŐ^kd' °(K L 0L]~j!C! Ǯr@m 2ntT2a}yR 힉Ȁq;6/K 0 CyCs`"(DJ8I[7lEHHNi4Vgc3ۧp g7@Qy;$!m;*q6&A݇M:DGGJ8\l&OLߎ&2NprƎݠy"aJF g;OH2HV%Ϊxw DMw/^[W-WgÏ@fs/-mvaTI9wؾUt*DM']*,HDDH("m]g\sH#aomd%l9 Vzd(3#EAHHCd_#lWJ h筕"|vyDRU{yy)@"ފ+,,,kPd?V ^\l21},Wc"IJC$@$Q$}M:f_+Wc"IJC$obp~ܜ ⽀I\lٳ'ůn+Wv/P}/[zR^/7'xpI\lݻ7K_],W̸~XI$fffʻ(.%O>$SΛ[0WVt/P}/$AAZ $  H$  I  D   $$  H$OK=zWh+  H$Z"|[ \qeŕ I\Fʉ+/*7ʉ˲q >OtWF\YqeFuݧxP$ǽEZّq?C+4Y#*7 r6Eʊ+3[>kO2$hhooAFʉ+/.kDfH$'T(>PQ}jמ|"ɥ;̦ÕiD"=EʎS$HreȦÕiD"=EʎS$$IIIIG&BWg !zGb*$$(>P$$^Gfٖf3 ’G"`+mbx$nXHcJv@ ۱ Y.V&$HIOA2Hsׇ*⊴G^`Ig"DÑ)=>!z툣8U>޵HZy#4>Ա}2 ߈ӹI9+qz3,>6pL9XmA"I"E\QkpcT4HKP] YK`N"' 6dHHImH ɓ5#|N-(.o }MuD{q;G,ʚkQr~Yg^Esrd^ϝ5lGQvتh sb!j^\_f)}Xkٯ9l6ʭ}Hu%$|"inyhlG i$Y3.$䫉 |/ê?Qc |,ǯE9~MP-µj4ɚQWvS]!IQ0`?OQ W繨v*G舤oCI]39k"in)_Ec$;s:Kw\Fq/χ7E+;Ml! l#`H'`Z4< -! i !lj4x2'&{PhD*,+NŖP\uOqmL3#_}ղYyS .@(#ב϶,&C\.2(({ +wHZ#}//Berewqld8Xhz/YPh@EI :!DխCntwȺL-Er-2m-nyjuؚe"!B5Ak6R " X+AD sߋ1v4Jp6s&##6q>ŽIDR0b..ֲNVMD9p2yH \q NDBSJ9JD-dK =<?HlK FĢ}Qw>Rf9|)AՒ] N=f r%]W+m̍1IƬ{n j2H*plIl%Tl8F)kEW]Voc\ffUƅN氎އ2E,nwݸXBE3n/T G&a+:6!f[-׺l76q]ӄ&J]R^ܤz"쎰Q#{;;Go壬V;Gk.ۘb_$MiDŽX-gͭ!m16NP'^msיּڶ 6~uUE`CDDH>р؜RpuO/CBxO[+-1ȕM;%8L6ݞ DG߁5 gLGXxLNšPTG}!deDZ8&Cc0c5T*jp2U-nudǐ70-PK;[,ߖH04Z  οILMIE,7Iѱ ނGu!!a>N`G d(;,y̍FpP0lai?#d$5-h)X;ŒwP( U7werTgolVçfH>GҌ3( hy)(ڎIdųJx^Ζ$D"j"ɩepsԲޕ[_յ"iLU^ܾjp}}"|1>,S'8t+fJl&5목vW i.DX`hQ7Ɗ<fF!4$Snryhv/lM=-92Us$mʛ p[Im7Й(`Cp|2& $4`_gw@禷kܣ) F,jvgX5{ꎭ{qD~+毃`MgᅕweʇJ0CH^(KC%a0|qR:+gh[Y53k<\dޯyM Ռ0r"/[jp"uXkR8q#*'Rl|Q\vt!H9#e!L&kCނK;"i/jq:^-ciĕ.T.:auQ[Kj7tsY4X` +kkϜY[3חdRئyB(~"jrWbgQBVwZyx(D+MR4NSg>Sia<μR21~cͧ"mpBmAu2~]ΔX#Y!vYҼ;GR|lHqy+˩U$u(h+ 58 ~ȴ!f Fb7@Yx`mWn,Pi7vjB6~YZuHvmIS2w6l^V}%N:X)p,Kɂ`yRlmb}VچZTUIQ弧"9G%^Gs .Y Lz "i߹la`$/YU-hQڕ%(72GR`nD] /NOo=a,*PI$n.ATɦD&,fu|FYH"U)C:vCGY GU챪+&Աm#߁2 !㰡@DiN緫ۃx! DZ㶀˼kh;dF]e^:nq歉AbjfuI]DҔ3Ga,6!Zd: Ͽz+bX ~po74m(cU~ UkaO2n_5 "(F6τ;i8PY=8angI ?4E&mE< E%Tnm@(Oxzj1VC׽mp+ƹ9# `p^ ma"Y3T%O,UN_H >1U`@$UK&x7OmNfI6է4gb1^O:q_a117ȠHcDuMH)K⭁JL+C24^yfBc=NB; f`h sHx=DvĭE]Ieg,ViA3T>Z$%6 ڜ:46aQUn4zv/2ЦuN#avVvg~ۋ3Ҝ&w+!X[^/E"I͑dw:QRIn(!`/`tq6 5dz|~oE5]x./Şq1 mƂ`÷Ncu֩䬄wۑ0-B}$`˨>Yb{hbRmIYZsg"!"H{ }x 04ˊptD!rFdKߞ+P D!44S]ES8SՂ{bYjr.obF[koV?|}}🊝Od(ϊT>g 8+KpMh2Z_n X#ahxHZ{ud=<u8>Z F%{jO|Iqm_/ENDqAZ ·w,*~:b4 Vb$B#5/fšf(Mxqi!F_oG5vL$M ^zp.ƉjA{R<oOOp\(S@Z D[uAc8[+`5nI˱+LWx;Ae#jƝ:HrH~Cڰ C&=77wDQC&dMF{r4kV'<ۧWGk.ƮHeN8Wu ̔0#"v(|,%AkY ƶb)f D͊2!u8<=aʦ\%> 7_Vf,kakX50q,Dm Mp#HdFȾ\Xi]9O?- ǮRig=+=kZZ;?f2{R)w.YtW6 TYnXaEҊ-wVKQ ߂Sžsb=9*j"Z!S R$eEQHyw8^#dhnŤqR.x?'{ڷ)'Y]UI52\85! OxqBr/MVl`t u1ux'!nBH*pRJꤐJ*!jיHɜBT+K3,Y60/r헵1iC% .asxv>J%* -Bhk'wQ?hN)ԗ؏155pI7 d,_}g]a1͒J<^˄)Hj.X 2 -'LB J[mZL e Nvezl+w̢ȽhQFd-w,lܺ8{^W?`k,÷<Da\QYq@/;1l淈D\,7ɱ!y⡤Q9&v#:t2b1c..*M@9\dru#d}k ϮD|8z=i)vzD:>|};솁!{~ ?͈ED XY,RSQ}{8RWfHr`m~dڛx|jN<BY8W$Yɝc8HK5DuwPGٳ=:1 fulHԪTDG$`lTq,ť][L[x~< |C^דeaDz}'dG)ZZ*:WavJUkɖZ[ QN]cO +؎Pkug縘Pֆ%*JwStEkY3uR'kf<cHLw({Ө}o}Ǹ͇{N}T,TBB4+(**" [bb}}#tߝ+ @HJ2\ylCx{~>BVY?DG.OidžjD9}?y/.!Y섨t Za|ύlP3L-_IOb6jXoq i&& HRva 1W6 wbc/6\DCNm/ r*vf3Pl8N;.ZJolE7xCZe<* LxHfDa kX[wb3k?yc"i \Hp,aZ35uNQu̅vM8v7Ձ^mwN<#ΡH:*۠u)X:Pi|o$)Ե)꥞16U4KeFaXh%y%Nhu< `iİH~=a$_?DݺWY!ۄkvO܊6(޿l3 \u\K~n|'&|;jD2[HV De:3 9ƛW? Yx8aQ#. ${:͏u5.P1k64T_Bc$?u"s }HZ=:ίҽ"n);C9ZcV&C"tM` ƏT)jiZ?HvTd,oPM"LqvNcE$oDR=ӝEe!܃Wxa{34 6"ʗ?D"iD:VH~SsDR#(|n&wѰ ^7 zHj&\fg'L>HחꙞ&K.g`,Hkbޠ9c"ZH~9HO*io]oJ"bO犎mwiQˎh x:qO$-o3}@ikVp-S:̨g_">x0.-QXv8[.ECqUgtrvrnFfER <QlR&}|3{P>H\bU aeߺ|taL%Ssٵ ̅BrtZ\c=c!?H~6ҵm&Ƙ\Ytm/ٹԍ5_hUuߙȟ!A'c2E+2Cjk%3ki[ "9󈺒ۻ~;t'}6I{IaZDsED//},|ϙpበɨȢU3x?bRK{W2z('p^QV Ƶ"dp8H&syo.6a9'㺭C ;DU*1/ #):ށ@to,qNf )oX1 \- (W*fi1i[68{hbDK閟 $_s+僠ՇZ4{vCC/E݈ oX"{~^Z[鋰k,?+LI M@1׌ FD4+Pv_g°vzdOXڈ~ Y}%H}[VD?,W :p\ G7˗xb1& X&AuH"vA=uf( x,Q5:k rcȯmB%u3&9B4df>뙨NQ<T#PO:^"+djFOk7m9,qcOaOu.̒zP)\W n,KSEzu@E0ָ4Vݗz",$<s `lT(Xc,yѥ &$E{9t (ƭn%U՝E_.>>?B+Wo/7"&t  wg%tq tR@7eKg7[d7 $C;6m@"'C5PXSmMXVY ~cQ =pe(11p9l-ߡpFK42(1X\{m1zA~X/p]5AUğA3]<4!eo/H$ۂM] YUhh nۢ \߹{~-o#n\lD_lMMlwF~}HXB#-NS[e T6@ݤZ#?9ɑBhFyi,lM[HAA$$AA$>cB\KX1@qn˗cqh >s{%GXwwv{KӧhbDD@k,&X(0r<gODaFǂ'mC6W˕w3^1d 9Ą "ErxnMDʫ*HšN#hB; t t? r'{91/iYl,O$o |fR5c X7xN`BpAt^.Amq6Im-ZVžyFDv ڢz8G'^g 7D]@~#ycUjA^-WNGx^ԫh{-C"&]*k+-M粊rdEHIXɃ{>ʼncW\A~NV_>rB%N ^!E8g~-UhIbq3 R縼ٳs#q4M$.=DCx=)p~.*$rJ~f޴ ^p,Kk Ac,  ײ+Tse6v.e 31R'Mr(?ڙ&Ի(jpjv'ko\ZxMS֥ɕ!cFHBit)tA,'"njYZ7ɅM/x#Ҕ5p'.VV9dJ̴21}wm^}8my=SV\\&c\ţiͅ(C23”s V<!fJSKDHL0X4M' gqb;!gs&! | ;hFєS%C݅L\B3')=(u7 w53-0+\iÆ ;5 .5K AH~&و Y g (2O 7+eiCw"-HK,̓BpGnSQc&2-L9`C);0٢Z|3.aLeH]73./zxŏ18ӽfJ&'խ[=)̮;Fgttc̆t=({IwqO%L4Q޺)mk[<t:ZDD@ٽ^X/:D2q)CK=q֋Ca˵ SW}9 쵛_q%ԎgmbLʄ\,D#V!Y&ȶIh4Az=(IH$XyDKgwajM6%}waE"5.q{ ]D|HIMhҞ5|N2SŽ\Nnypя8gig6ͅ+|WtGk.vy!dU(\mD*x)F|_xwt!mum9q +P~>{ n<1+p^Iyl ovA7!pkoP!#޳o@Ndo}P5#7q>9 ʄsm ڥ_lXxơS$, :ʺL$lNU>&҄ݵ^-@88ˢOb0\QVz74׊dmO9_ z]TC eu,M$YƼTVP:78j'V&Xj&|6Pecʕwe:  Xk,,RŒˈ W.LHxR I![vNXmn0QJ%GcY.mPOHj/6 jQ_ص=X0EgRJP{aV}%"Pf,I+VJCq yJڙ-3&e L§)ݽV7Kܰ8GŕU'D$"ue9V*{2QsNۑͽ@w4leD(B-\dY⬷ADevRL-.Ճ{u)ʻ  a)-IN?[<=~e|\ OgBzCEwAj{kk+p?WZ{ b -mLX3}mj;]4k &R6A"WI'b^sMe RpDfGGUTl=%lÅ2GB;9?l`Mr-27O<¥}p&|0ahuzA 67ɿHpJE)8p'"㢓*a2>D|%;$3 $xYw#fI1| 3(1q;_k  DD   $  H$I$  H$I$  H$I$  H$"  xH$Y$AAo0vX=t=QFu@"Ijv& JHDtu0p@5$$AA$+DAWD sֹ@#[1o~}0![1"JkA$E288X !.Pq=~g{Nr71n:榼Ԉ1WV m'4 w@cy,bbl0?,Dk=L_ xN/8AM$x񢚅 H&ǡ6\$,P}-Si+7bHxZ+!`&c6n 2NIU.Fߚj1X8O<[#^1.B\m吺f~:$fIi Ъ`$p r^#rP$O`hqKY^4}0RyWZNCV_Kd=JVg[3f3L*!֡ 0xQVVT]aXp8/Kk!k_Á50]7sQ>˛Ps ]>/M7(Ƹ-%ς~Ę{qy)$pyl 1{xl\ Z}@wV#qVX9 sbVǣwK,b., {e£ް X4ofFsx%3)BM(> ɓ1y3 |"6>nBKY tr$B0}x}" GX7޼3|1. ñÍF$9<⪹NpRǰ^"nZZo/'|u;' D! bew Tc&Ee9g/桵96(xwEwj1#!E2/f ϱЊa8.{hP#=n6Q+OEoa|4svCż=j. `]9cpxqTq9lhAp%88HjO@}oЕx(g$aX,m=F0nX2It&n~D /3Kj0lj?3pߗAvwLxH ?Qy|z QvfwN;^B!Cu}x7Z:hErp܄4OAħD$"pmgx&ҕ~*GÆ0ӼoZwQ}IAi6H; U*qr@D{>u83WT752"iQOhS B U[+YI$ &ʺG8⣉%ޜDk0ھ#L0"ԠHziEr4!p "I{m 4uQwg9&Έ i=E" ÍfM7е]LL*yjJbSZn.Vw vI3Lޝ>V43"BkX9ҔVCfuiq„3X^\+/t4+P::>P|KAv-ȭ")Uqɮk6L)wɮk Ϣ0i'<_a6  gw1bU0K{i&L3Ÿ͸Z(,w/fXcKba@SZoo,<}  "H~6Unbci1kO+U<$a2K L2KՕ?v^1xX҄ZvR< >@A\Rczg1v>$=GyCk]rƂᝂawP,,#E}SiH_4r7닐rTXާ⟼$ҊYU*(T6Ta n co Q(#k'zx+V|V( -B> |4sDؙlT0)QX<! XEnL6{G4t؃1Hz^&aI"a)WRbSx H4<9jW")`91 T݋shw\h*8Y"SZo,<} $|ocDl9`}:݇AA"I"I"i._a   $$k9# ɏ/+AA_I|  "$)}n  ?$Q$d}b{?<7no4)AA"I"w?!3N;.G  ILzvlՏ#AA$u D>1Fxz>}7O_{H=!  |")4ؓH } [%Z!:02u9e  H$?H"9pZ$WCw pM&PsAAH~)"yjLqa6w_u-J^ȼ Um*`;gR#lbO_ؚU- F84~  O"LI@ 35p$$Y^Xv|?E"E.Ãe;=z.~j;zAQx+<1>!s؟2 AA$D$/0[[^\f751js6̮GحL~h ~_qQp`bIM+ddG0  O/;QYL0!  ${[&IB~w!spp"C?X{ᅄGSįhяI  T" bOv=sIjt9(Bm9VΨH2Y]-\įQ+hаHj'Rd3e  H$?H~w8Ug9Vv=v՟3k{JlKoϨHOKh+բzЫHvLe  H$?H X׷kLF=ODeg`dJMEtz/Ł:(uEQ2HeU85 L]`pc!=*' DS1ɣ_}ߣD -y=/Nvi=s#.dm+\>,|tD%8C",< 9*%duxR&! DdLo0?_K=[XGx&vwOؕ0i5AA$ll÷~Lir:Vm*'"Oxg ~DMAC$?Jdy˲pu?L  II  II  I>7? ?ʿÃӼfFs!AA$$z|5$q1ر} ?apvaYAB#C0G|AA"I"˜HC-=۷\"H!=02M2AAHHv0,ERx5t|\-?گDE?q+"oFEBя2!AAHHjbdldz[Hhc0/e?v_f\kS6cc?bדRԵ*$̾M3g5"l)G~[r$ٸy鎙oH/EU/c;2r4<|IQ%kAq5$ފh:AAHHsȤ Tj9'X\gDZz<p*.0m?fO A 5g3jD>p5bVـ!" &z i}&{e<43X)D lqXuŋ 8AA"I"fkˋˌ閭?Fmtz{Qc|@vGlz@*-+M2<\aْ8<0Qx׀0\8L`u:;s$AA$$?`W2*i_=oߛFsܐC 'r²]R&TA,Np鳆Hy.`&}P%ρQ@٦ěVGG3Y:_u'ߘLݲlGA$$z;j\R:>}δ01l  car)+Eɟ1|3G+auoĵep_=CőY2AAHH.}ս{oN*կ]{Lڞ+|uXwf#Oww{7&dLo0?_K=[XGx&$~qek q\AA"I"N"w}o_uߙ<&/p;Z.oEA$$-~*/ AA$$$AA$N$  / GI-X/51Nc  $c`]D]PJMY6-X䄯qh  $/ȁ_P6U䏠j>̈eA%ab)a˟"/y,WC_cs#^;>qBڒЇX~و~c) D!LEa/jJzm\cf@Y1oC)ð:fr߄qG}(ԠIلu165+UqMϰǛg9,*|r"d2>AAH~i"i /u7Jzc֮[ 2,5X8JI,oh{_gMivop_H$`eD2.Ö2>AAH~i"&f2KvM6EG PV{a%% YnXD"ٗ4Y$wV^v5uAA"C%T-2yԩS0i8&h=`L|&Rbo}ItSIY+m<Ѩh\&CBLGR :ce Ҝ\ GgcGA3 %KŜl\*GTوI:hfHO$kJ+bO9fl;Z"K9W![/la1s̽^W h/"E .g3x}=:#OWeM NJSu8AA"e$_dq5TZC%^/A)G˛%߆BY3\Wg"w4k;e*ྩ/"ML&o+xKKڎ~Mmfgn$lnzaJ*Uz^E2@!}Нĩ&C8 lo  DoIa- +j„r7Z+Waƃ^Z TBShmHvA]$mZ ͝3׵,9#W*(1ʔL)RDs56pcziuOױkmARZb1ە(M ݝNA!cQU!(k@YEH;3~~M=L&Gc9vd>t>B \YF,p vF$bO 彈"A$o9D_BăV2Y$5-qr\AHA$, (T\?paׇyˋu+"4UqE҆l6tk[O.H^9g`vT:"y(J0>29AAHQ$Wɣ=W97Q^S=_ט{6.HjyZ~+K&n',hSDs*"zϓpd+!s"RڀU)&IpM9L _fSL>H\^eW cp=O;L>>s3|A3"I,l,*"(AD@TP"K aM" kfXHDٻ;]]}UY8wNu+n[wUr'"""p{#CIcC$U υ^G/ TXRDjTg\BUVorD7)1J.&CR9eж 򴍧1"ҳK< 8Ŏ )U-oj:$ŦZlߪ3XL_CcgsW?DDD ''$^o<"ei PіsF̑r|#C!y7cdˌ+P|MY7 1$DDDD I$C!ɐ$"""bH>HOgq%gb$"""$Cm/ ~5;!n,Ul,Aʜ9k &9!qBn'0aG'% I-ZODFĄGN.{sp<l{oH?].؊W](Ć#q/G}_Gb j[@BƷ;C{=qy6Ӑ0; !025 Uq C2Hpn6wrU;MHz\!ڸܠdq[z[TBkņ=1~W^i 8Qx@ƴduo(@}NuN2؈!d^k al9k~,^*% ~,l:$.9km?>!wµ}1۷1$H9̰GM7΄+F[2q `A$""EM02xTå3 JaoܖjWCWA e)X䅤 PPz=r:$!:f%#XvF307kBD|4 48{k)C3{$¤ ٘+ǣ ӦMÍY 0VLCڂa&*Wtڒo"`@n^}[Hߕ2(SPPu7'ÿD@ IPV^.{- 1=Ԓ^DfF&x55 (;/ 6^?Q+e9xӫǹU6a(;{wnk됼ݜ6ܼp1lҌK-3$d|-JtBWשMކ<+))8W^E^_RCT9B5_*/ʃ[%""bH>^!y9xr|2m6dä!U}c89$zM.C:5 OgR1XD:od^t7N`t8}Û&:y0#8c%m>i+$#~bM >Z{*x`*7 ,>y'pCU1tk"L[A NIT,~0=R NR0C~u zHz!)70Y6n{=PoTX7!GDRUܗDDĐ|BX&Z~05I&/C!C[ƪ%T@,^|V$V˥eדB5w`8e1$~i;$ 5!/:q`i1C/P'i}OdA InjuE0!*Ռq4ЙZZ{Ɏ m[BR_q1~xb=եpLʓ0C gaFTR*ECj\w\ #!&gEߐ`ga$ozEcY\˞ۚjZ+N4Rm`ja=$*5osFcFx=jL s*7!BKzj:eN{`-$]ɱiL&D&Qw6 Ɂ3AހR^ES?ʷPq܈!DZ)^ f/ʹCY}쿡o,?/dOe%sQ<&یBryƢdFu Lƻ70=R[!Up; kQ(ǘ[l$K6X IeɈ_n`ۼ#m}!&k̨+*ÉOc0~O$@Ry@p:̲v Ϡ6Ekw6 m$VC>)8RoFCj,sh{ ̨ׯu BLj1o{kLH O9cd$DBk!-az3n5|܊ַ!(OnٙtE_j!2""bH>%'$̈k˦B_<iX|,nA]VuAH2;mKZ#oc|5 &._JX6k074sdbg2M3pq͏'S/Υax!kM7N#@-b=^+J@ۂ,|z( SĢT8فj#1 3 JzGecd|x4k~Mkmk[%$7F e~"7GڶG2䰯-,ƒ$+4HȈ!\"qȐc }s*,' * ֟#rD.Z%$nJ7jlj5n!OghD~A9싹?d"0[ d9NEE9J+Mم1$Tz]F8O-@CU rXF[Y2G^}>Qo-8#jo9 V!y ɉl~l}%/ߕ)7̐SU3a!YU#1mX$1$2$>1Xi.?mdEjrλdj C I$C!IDDDĐ|r3J_-tz?'I""""C?ϣp'$MJ0hQ"`8k!#y`r?T> &>.YLj9,m}"2"&t<}K`3eo.aN~x {eiȍ[`ҝِn Q*丌j$]8G{e[e}Au1ݐl|qIՉ!^k al9k~,^*% ~,l:$.9kmoCeǏE&W!"""SEM02xTå3 JaoܖjWCWA e)Xpr!"TZl>Yko)[\ÿdΝO뵸q= /KDDĐ|ZC 0ia6´iS1yD9,s`)C0i#St`岉olۮTUl * p"+޵1$(,EFAPZV Vݜ eUN=g:~T}mh036C" ¹pEĂV'<tiIƶ 4Fkc"ҳK, N[n%8VL uUu8TSxX"""qX~W,G*fC6Lh90ARG0C `ЄR_e"UHUs6Pi, 9z l lzWfHǼCI<4}8]oF]Y96HܣXq&߶G2#Fg𤦽d݌)TabͮȖ##ꑓYUj qDDD ?BHX\ r PHj $KF!3C|;!.C]] w8,4<9 C;zO 0ҸWΡȓti_@|GsqI#!-.Zw4$o>rj(OF?9k' [S]Y1$ |Fm$L!ծ[J_4ƵՀ?˿A;Bh_@}v_4nQÿ0ʻ3m$CqɁ5 '"VDhD<'˲b4KPamTs}{ë16FXkX1$\7+aT9RbH5Ks/7?e쉺d.Jg9٦3h,JaT`dpC+P 턤Ԁs7Pe2"rRI0QXb(? ɨ}ËJ"""?A]ab < Ui ?OfY^;gP";~{ Im7݀ʌ)ade$C2F6(TcYC["B&DbF;>)jc蝈MEfxH5eS/4o\>}zYy7נ.ĺ ][ 45fX֓Y%c\!Lfg|[]-'n⽽vyҭS:eBCdO#(_Kfm`n\zl h Ko2!39_MG2,띓m';wL""""wFƆH6@( P^PA\#JHZB:Z :XtzK(L >fr "TXV ړl-*DAi<މQnn'-GtM}#ʪb\8=QzʔljTz]F8O-@CU rXF[Y2G^}pDDDĐ|CoeFX(W#DDD IdBDDD I$C!ɐ$"""bH> HOgq%gbI"""bH2$ۙ?ϣp'$MJ0hQ"`o61$mG'f}L}]rXDdDLH1$+OCnT4̆t,ʌ4T!e, U ‘>WN27.1$km~2m"c-oXŋ?^%d֯[şM]84g;~-`u)C""""SEM02xTå3 JaoܖjWCWA e)Xf䲷E*xd@E-6, Nƶ\!䙽ARal̕QiӦbrX,\{S`G+! m0e+%ߕAQBAQNbA^OEH^ar4^ g 0<GHUX>NI'^AKisrtHT!UU}9MDDD ɧ+$er,ISIta2z?+`ZIĒhg >:n1DDDĐ|NH7! Mx ҼrHOgq%gb$"""$Cm/ ~5;!n,Ul,Aʜ9k &9!qBn'0aG'% I-ZODFĄvIgTl;\+zC!l? q SL0(3_R0T- Gzre~GQ%iǝӶ,K&z*Dk>> w_~XO`6~ñ7ş[-ϦCRx }:$dAރIDDĐ|Cr߻)>fCjsFR)͖Rj \ ,k-Dd !8PQG;Kӡp ֔j6~J@6cHZ 3{$¤ ٘+ǣ ӦMÍY 0VLCڂa&*W/n\/Pg4Chh@taZlEu ۔Fb-Cc4AS{baL-Rk [2QRZm!iFaQ-4 ҲJ¹upnIķk`h0 7 퍶6ۖkubͮHߕAQBAQNb۟~?/{WqX~W,G*fC6Lh90ARG0C `ЄR_:1&W3 K)rLBqM: KGP2>^Jp)r0HGR &]OR3EX|Tdz%Z'6?NcY``k`Q|kA]Τb|<xgkPc\v"R0"[srtHT!UU}9MDD8QO>pvv''' 4ɱ&L 'a҅PHj $KF!3C|'B2F6ėlm[BR֏y&0{z uX&THAy)`(/;^6}R\oF8eeC(V;|ɍ[3 T*/2:;ڮ.C]] w'a(?DDD ɧ1$CQ SzH` eqmq5Oo掄P8P *N mGcy \dHnN3"x"dJF4[HFcI]r덋j UXzۣe||ٴ~ٸ,f9dm Q1$Ґ\7+aT9RbH5Ks/7?e쉺d.JgtbYrZ;?ȼ+$ NHɥJH y CJ Բ p凒!=OPWH*Hnr"CYN>f}N'nZ5η!5&{U#Q061*ced=$֌a~Ae(58z4#f7 ;9K|><!G=!TdF$\X6!(HЧews z@ Bڕ힐i[Q|3Ú M ^R0;("ik|y\, NƢr(!&ۈu5|Iw1u2qq"Ldq'rTb4y<# 5 M#ةLecEmI>&mj|#M$""bH/wod1ilj PuO9CHTBXPܕt J$ %BR٣9X!刓cPkixcTBUϿ&5eb2h 0"ҳK< s<:mMĪuә`0_P5b,\BIj"Eߥq<C 򺌍~q(K[ GY rXF[Y2G^}>Vo H1$AH6{{?MȾ הu囂!IDDD ?$H I"""bH2$qHv{=M1$d/s8=q+ߞbz !ɐP^j$W7"1$-y_ڌfþS/DOxmMm1$ȐTL?rBreyC];3!ohMt81$IHk{ I{jĬxcie{xAU |ܗ0"""$C!:vd13ap z{zcxnA<j/v>[` jʑvq 8_P\QC]3><#{ 4j$2>juY*|1֞۶g~B_A(E¯'ppj$""bH2$ pjj Ieim~RW-h?h.F$.ٳ1 8T6ߍiޘUa挙4 g"[E CFD9Dj>x{ hEmh|9kGSY 8z$9g>1$ 3m\w_]qZ,!/o qReDb ּj(~:6GY A}}5FdoP|VO8RRK+^2 Ɏ.=lbL6mڳaaX'zgCzr}>đj2wV8q;2 8>cP!hNo0 hxp燌!ɐPHP=C-Kkˏkk^[(g>2l=$]y9$7sqTɌBrқCrO5V hvo1$=pI# UXw;Хq@9[3i-$q؈ٖ!i!0 6`V~!G8~'~QkmhC!yWBwk:zeݺ]cc! ΐPua/"tI~ϭ6w2)GVc̙Xa$ (8䁁hgLO/ŝL C!y!ٳgO c`mF'RrqJr,, &b!k!2h hSp~Gz!+^H)@"""bH2$3$c%}Kln?r|{ue}{̦0<c$6CDDD Ifvvv޽;uBmggױmrm"Jécml1$0$d_dA߻!C!$C!IDDDĐdHv,$K ~3ƥ|{֋x@"""bH2$6Ԯ} yr?!ɐl8!z&zo?8 ǜ5[fp=%"""I%L?eyC];3!oh)0Tw s;8=.˖=}qX1GqhqzO?Mi9_d魾xcC93?@DDD I ]z،Řnmֵg;ð2ByO jNvBr9 Spn*Ҵrt:Noi[&X㚢q^9񶽔  1$2$gj(㡖ǵ]FP3}Hi8-نS08t%,%l9O 7v׫f, !"""# ɞvv8n*,;8Qb ԜfYj7MKǂJb6`!'Lq=\."g>xzâfFfiy!ɐTL?eyC];3x mmv'"¿|58j^>czDDDĐdHwH*DZVH*ܻwpd8U# fHB8/?HDDD I}sChKH*Kkw<ۑǀϠNUm4dQߟGh+bg[p_ {ɳ6sf 8V+>A<j4[ʃx/f>;8"B)~=;Wc$C!y!ncRM\-!,W޶^4Z\Zjc$$ؾt>f{,ZpOS ? gL/v"ʈ 3X9:W#]+=+J#9 oᇉ!ɐ4dat7=)?aq70QyLX1ºX%[~^""""C ɞvv8n*,;8Qb Ԝg+[w;;3`Ԇ[[ ;"M_}lE ?m>/C!b -Wmvv9 zT,k;ŪꅘL,7&ی%/b9 Xk?t ?uv!pBgϞ(.=یHeOr?mm8/$86ܮ՞H+@$*%]–.֗s1 ej=$Յ 8Vc1PTKiz^""""C|I~q%l2[9ŏ*ߞ&]Y^D*@,? Gzy!fvvv޽;uBmggױmrm"JQ9~%"""$Cp,>HC!IDDDĐdH2$4$Y/s8=q+ߞb/^R ɻ mC2H^܏oD"""bH2$["|'NH>}^ ۏ<FlfDDDĐ|8! W[,?uvf B߀{vwk2?z K"""$CrL=m½{J_S5b֌|dX"1;qlC ݕx!IDDĐdH>}zH^wm Ieimg;} װj#z8aRi[1 ,>K{cd p1Q;07?LDDD I}YF9dPn xWCw[ U:OdC0!f! ?:rxwUP FH2.Q}s:{ \DpS 9D窡Le pjj Ieim~RWa E#g΀G6رt|^#w[~+Qco{NyG'b_w~AsdDDDĐdHHic>3ϴ?j.`l I=|:"TAsЧ9R_W+X"==pq-.!Cs^a"""bH2$7$wa3cn[מ k=1i˃ ^g@-ff7N9LY7궉=} `Ge\0l@X!ɐ|!9?vVC1pT,.?rxm5:|@C[!9he9$ڙ|E"ҷMl IebY X?,DDDĐ|!=4 bYey]zZg{0j] Xؿ1VC?c&vNraj"VbOCDDD ɇA/t\Wح{0?&QI#D%.dfNЉeb:f!PCgϞ(.=یHeOr?mm8/$86`ʰ!$jQާ8!+0α#!<7|=؞"""bH>lɗ_¶.=,S(˭iוEd˰taxg=$~dzAp ;t`f,)DDD IdBc#YB2alv~<ϫ-6h?]|2tUȺ*$%c@c,{2MׁY Ǟ0z՞GgH~l|&JjKFٸ ~:9áM{JBճjc~y]ؙP$Q4sp{cHSp-.A~\;KDDĐ|C2ƤZbJYZ[h˾ޘ_{fsK(Lqy;UA>O I*~<5n8\v}9ӧ⽙ 8>rRC&B|z`#HVK(?yo"""gژ/32 X:1:<21[&ړ"_îwmm"c?`LӄKH1XZӐlI3t,?\AFq770fHZ'.&EկwWHrŗ꡿5lĈM+W,QX~[>w&LĻ_Elcx0$OiHá.wo'tXVaY޹@.Z4sP.Uħ'q2| (;[}lqR=/3L ]J kuox X[3gc7yXZ I-1kzH88 6}93ga_c#msyū齄-H1q̝9 YɮMeyt>Bx{HyX5 ܽ6DDD ɧ9${쉁rLҳ͈TD*Sdq^H+ql3Nw" Eߜrb6H0q}L8z\vN~u%5۵iBoz%${{?CzFUl#z`/( ۬W(= +m1faDgFg ɏCl y%O{H6K/a[)~V4"R >)aGѡiBOؗx{!d3;;;tݺukܶ69NĶt zqv{671$.$2[9K,ƾ>R&B= ""dG#!;$C) ɾ!1$bHL೸W3]Ͳo@"""zK/!f 6B2'"2y T m8*sCDPlo/߈DDD0amj6~of tx8!7M0`R-'"#bv<3)yW:c=0B!6#=h<\M^?gޔ/"J!(c%Jz$&"zBr-ZR~ZZ0$ɵӐ0; !025 Uq C2HpZw;KƢdfCjsFR)͖Rj \ ,k: {d uXpyhHz ד ɇ?aUH(’ㅈ-)g' q?7!ID ɯ Oӓ!^H$!&m0\9U6m*&O(eU7e&Mpb CCn,4Bƌi*>0ԗbkp CxZ ADfN1G|yոQ-BcTM?[n`E\ DʪjiZL0LS#$ n6k IEUz9N [obsJLP׫qM q[lIC?_?{,"V^/ш*|VZBҌ[Ht՞;__=9_:<5F)rT :=bRJSHJ954QkKx FxY cH^V!^y]CEE5vk !C-f^~2r0O=:(~UXGb o=$w'UR QDZ^=L=ؗ#N zlL5i IBiY%|c>GZL*=ˁ8]U+#l!&} #!u 0hp)/ٞK+FƺR7JO UIpڞE'R1@f# MvFX{ޥbxI#i( ۟Go<5¨w81է1Vydz%Z'oSH%cJ Liwp*, A8&ʑJP)rJy[aƐ4jkXU*g}]{(LBScyS.X߸Qy?oyv>H{?'S&B9Y`kx{ lE9uq4 IgLךPAIs fPVH K4?=  r2_ ɎLŵ0`j8 .L^BRxUK >X2 yP;#@+Vcy,rdUH:nS,q1ssLPy#yC(#̮ݜL{v$fAԸm] ix^osL(ja` yI6>Ox?}k`}?LaW-ah6- ~ؚ_ZMI qOw:Ίf]KlG92 (OIЭ8Vo#ğGm3q(8v$"0ke'6}R\oFЉc$TNdh0j#a]vLrPl5;I^ ܑ @A߁8Cy+?{o޳}w_sֺ? '$FeATEAQ@qhF8GcGTED@fh{vU7@gawUϮ]C5K\-Kΰ\R!_EGqzqRD"q?Lx̍M (ӠBCC oBնL 8k2&pL 6Z&|5@1^mWk뜻ZJ[ߝHE7`V$H^Ct˃gOĖbEyz Cfy7&ф0 _E^‚Xvvus΢Ĉ7۴`2Xbu6F245bߤƢ͝@#=x&nTAd^,˶j<盠*.Dʟ帉堲E{c /_`b&ɝd p%$ 9o7^,ұx\=>?‰EACSϢF]IMshsؾح=銒֍Lϰn_~ ;nsMe(`-dr&V>gPRQ\^{xpvKuhm>&efcH ̉4C:"yyj#4{v]"W<e?DhwZZ>k98VoP H${ ɷew+5 ERt|1coy xn ə$Qc!zy&$E*M~?Ÿ]wrVm|[k0s>B>ƌW| :5{I`ܞ'8Y*P]mۭH6HӜ>>ļsO0mQx\Wu;M&[XtM,\z Y.n~?bjƦ#|eQw٫lDNlSy?r֯)p: .^Clg$,9w=D^B9{{jWݺ~|"8ߛmOiH`7a1 ]d/I@|`mvXY" i5z@_ *ty^w60vc6,V2ԕ<٭pV~Xt0U,*hZhj`o9 V4J<F+-ڏX]f`lqʐs6 uFi`WG`rV:Z&CkZ&䩅 U 9-գER}Emz(cpJ!cKKױ]}sP@S7] ܽJ6 ?sOg$P$pw/uBxT<@v^9)D$*FTԠQ$O3 A9J%D WܡKdFVB=ŏdz$B ePn/ o'&Qv*)܃@#fP+*uwf]^N]jVL|;J۴Y,*xƇ+__r&:C",Cĝ,Iτ[kwH (%Wc͢" $>Inh8n~b|*71ǝ$b9[ϠZΉݠWd|&-&r)_6 Ŵ3A9PWgapL ĪcOؐц%q-jŷ Q|B2ӀGiɈ GLQp4_Wntnue4PR&OAx0kyQ! Fʣx1bu(Gqω2 0ɉ+*YA?g3iہɊ3L>㇤(bվL뛥I^BbZ6)L uh)lW H߾1+~ |d[$-nχn 8[ވg#fZBwz%#`kaik\7&H${HvSu5iaeOrb"/Q3q5'J\RmBepH1r p Ygn% %R`Q"b7FZ2W'Xw2}%ֆ-x\ћmB>k-F1qN*у/cR$a ڈKS#neN꜀sl]OuG z},Ae8ohR8m2\Q3a᧩6(GFt/UH4ɨaxC-mGx $n&8So䓘$=P$.\mh[:I(C3n.D(yR-1i\GפNX/kI>Ԛ,=fUIH׈M8n|[f$7J->U؍65QR d2#lco<sq"Zi&%p^!v9쀿 ³P+H|iZ#<O`e`c$%qStT!(l[[!f*p IߞHOG-2&jpLWý(f*y'bE)JFRꌐizԔ'{XEҒ|x8dZpoNCY[qTաጻ#$^kr&yX7o~%lxmC%<^$CԫN#nثdN6ķCZ"i!OpךIVϞb̲<13Talp 1!H$D׶a."YDKnH_KDlӉݲ&|][Kj73[U܉-l(H9phD$[Ya݈'|uD&k/֮WF|,?rNcIE "ɂHF1Z̋Y6um"L!`WX6Z'%OEq,^k8es T=dL[scXx;Y[:I5Μmã.DR6I,`ڊ@r&5<̋Fzp7 ]hhkxg")ےKL^hM_*ZDrE"iAYpqC`6 ^1$u>!ـ{zI]~0o4HZˤ}1pt6A!BǫPG:"&ba"fH c9<ߩHv>kGqRKcYA"IH18CvxS><ѽHF Ѝ{4mG#0JR&vk b(e"lI6`cj8o=_K _k,~v͓`8/ DR 7ئ:\?A|o{z|LQkqcs FoP2{/x0a195QUZ 2tvIB7MreaI w h#=䛥"i2hq R杅7cLHNnX]Nu0+8Gr%LEloF^ M ωő:4^U$.ivɁ醺_xˣ|qjǮx4\X'MVAH6^K/\7諈Ki7sad|iceRs.~x'L]zd*4:v Gű:9\pzdZTVF Ni('ۨQgl}~3ߑH BgPf<&UUhIO2T0n2g0Rh H-m: P5x=;C 35e2Nh6Gzӛ[][pnҏ֜["֬V0s] yWcI͸IzP.rSbx-G6{<> }dwaa +2mTK6vq*F!veUe5({G|$, ˵jTŬw|O7J5v x|i͵Fo/PP퉄qiv&b %O~u+cGGR?,ؓRvz!F(Ⱦ!mj4*Gf7ʈ BX]ȎB\8Y8c>Ey,C%uX}apnrmYr>6:v2QUxZ_]CEvOB%H$omK{`&8O_fˉIYhUWT7qxُB6a8TeG oL+ z~ j= ɾ$Rِ ^x?dY1T.Sy)S-^VܯBC0Fa̴PasH"k3ʛ~诿" )~~g = 7-Nߋ H$H0Sz |*3q|S/U:W{y(YQA?7ovxS O[!=5چRdS衹0) eMq(AHm  D   $$  $$  $$  $$  H$?S 0@܎=1MR|)ŗy"'۸`3f b%L*_/A%(oI qwwыb&N!ŗKyF%(DωoIa]ooo(J"N!ŗKP| /sۯDRhqAr&`lg~ۈ2J9v뮢zXRL|_ ο~S639}oMygaJ,D}-É8C0=ķߵH* vb0m?v PcCc/ŊKq&/9WN忾ף<5c'rW)v™b2q]ӻ/䇐Hap7v8nVҷ߾߅F=aE?z78z.s}&$~ rx_?R"9s2.iA+Kڏ30ڪςnSl#$|K"9j(Y?ukx?Q~x\] E'D )?x~5#ĮmǷ/z<콚J& }co!aOķM XYoKb!7a%0gρv=δ ͎L[(@kDŵdSY#R9c#ƅan{pc%ezŗD=cs-#Jkf% rį%z "؆Dber4oQ3DNGPp9+`5HMG8G/d!f[IAC{n"i; Aa#"io~ OeϬ.WIa!2شRuMhjjW8ic= $LP봋i#+4G;H̤ TBS Iww V`.km7*>h~"ĮmƷO>9/tr?U۟w_̏5d(_s˷[gZf6CY~Bء~?(hlfRcE H-݊S롫JQ=$/_&ǰU4⧧l Arp`|_12 NePܫYx31u5.DGcS| u?ɾ+R\aÅD;XF)N~B쿔bL]yo_gv?BY"EхHZokىمVs+u,7m֜'/Uh<žpS9V̝ۘ]~mSSælIУי;!C4B*c0\n8NWs0ߺUo B:&wq1Y";d{iV݀{Zw֏’>[/e#ZurnŊ~Fήt~--=Z΋qQAʑbyu4IAT*` liMHggDj+Q^SbiIo3GmBW;C[QNĖj}lϜ3Qg2g:Q+pV̽X1'1൬R'e*߾+و%3*ʩF׳2rYsx~nbC1#a'nTjQk${x|rdq8R?c%K'2a3h~ ScepؘͣrLxdR9F'`Nx0"h]c(V#>+*ʅV{=`؏#=~^c*9-~i{9m^ Ԛ# "yc5&ן E->xD.܃5zo`D҃٨ӽ+>pr>m@55^Gw_)[orS;JETu*Fm碪Ժ&7{Pd#rJXxa 5O+ʴE8fۺKE|i!kYjf?dp>]xh[o>c7cNl.}6nL<_'3GiU83L,-طܓS#;yp53\jDEyvVW|ghkvGij4-"Ykk(q;/Q^[$UO{.DRneWP<M+_21Ya&ǫy<ޏłkY594N~mZ.{#|ᅫ&A"ikwYOMZr *0",ja\,XxvN*0G,L76T$}#V'X'&<{nAGIKWOoߍX\oiz /e< vOC,-ط zu|xkMC?6e[v>i5יH]1c]n<.Be]=jJKQöɧϊQv{lO !^Ow}1|D6"?xo]rx My$ ,8\uY\M"ٮ K$׾F 5IK򡃙M<7@&a,V]@q&+0'H%}[xZQF}l}2ҊbՊtbCov"d!8A>b}fQjs~B||L񀃬gǷ;cDj yXZoe$Q"u|k]ߠOd@݇%iZpDpG.gF#hƅJ&H1|e&hۺ&%0ˌ'sD\Y?/H"cIZOL8%sۃzu}m5i4Ky=2PǛOC\8g|{{$ κy "1$?CTWÚcC(G"$$ CT^߾7!SeZTދ%Q!]Shَac%>jIB: #E8/Y6zv 9u%ivwI`C6'%m&F+3QZt9c!bc:=(N 1+/b"3B4hoaG7$R`i^Lr4fFcaB0$=~^2[%mڦ`DMښD+GggyC HF)&b{D2r elb!P7HTkK"PL{tm{@>K#=!mLVHeGh  #^ٗ5Ķew4FNǡ9{0ǵdo"9L>\u &bOz.^ֱJ.Ź7߾7+x칔 5NU'!$ 3~JxE3EhԢ),9"9tP~9{)D :Ӓ4̊$C1 /#B ^N]p$aZaj2-Ӌ/ݮ*ícKZB:r..LKҲge`g2ֿX.߳ueCY B^{`e1uEҢkY[s>I>hI.V0=`د]'s!vUT*_[ߊ!C0ϰ?>gs nfz}~2ɮeBKt]ƗDC2*r l>͂`5s  XR\|+ 4}Y g{W?r(~$ľsbC"Erȑ*b]EE_K+tssBKb]EE_K?[[[8::믿&zB̄ 1R|)(ŗ97"駟⣏>3U4l#J;!_/ŗKP|~#ͅYja; ̒BL_K$  ;I$  I  DD  DD  DD  DD   $;S#O> I ^M"Pw;"ƌ#…P / I ,Bhj>scZwZYYY;\\\0`. $2L++G ~)“_W Iɾ*J $_ WABꊨN7~A:RHi\=Xش;:JE&q)HI}E"I !$DҌHjaD[s9 QM>חWo.?r%ӗCǡ2ڽEġ ʞ&6 lP~8 IBh-L""roooI H$ߎH:`a:P"> VP9 #`LdCS6\'a<8<6m#{e3b6I"f6m9$$D-^̝Vi +ER `d?䗮NHBR pԼ@ siQOGldi+t_)19s' aAeg@XEc 4|>HL 0C_>˽0}N]8̍ E~DR.شHS57j(I H$ߦH7VMjf4.3c"ߊRlMpL]Ϫiz m/gDSj+\*ÔUV!j5<+'PmEw]AJMsu)&ؚ(GBMZuy1Qn8oDt&RWn8hPs"Z]砬VSTĹH̋%]f.ǣ?v"S9ZdW 8Bl\2p6~X7PWT$y[OVH>*hZhj`oҌHYl#Fy^:R=[OQR( i&^bX.gPRӁ}Ubo8>lPw(C<IVq 2j'F8oys`,cCG7?%blz#; _o}xb|& fjJk?D'"6st4IX[H///H$ |W"ys5<2dFҖHzd!3y,I@s ]H߾1+~ |dz.Z*2`yt,΋/k[ERꖀx~v=b $~WjQr8$0&NPJI%09UǞ!ɣ9'?;S0q4^"DR_catfoF~ؘIې=x5"F AH<ւ UR/,\ me&-FhH(מG)_ArI>93C!tV&9I͈$gb1O?_x [$ygâpv|Bx-$ޡ B@`8v[EGD!44s9u:Lc"qf"YEr| "Z[%8$Us 0'1B^63#ǡ!O4cFGFLB|.ز90Ѹl'&  nA9dKe!XHA".H]rD]m9 uqG[lDy);|ea<է1dsۮm)o{g([[F: QJ"ٶ;Iy8jDʑ6oc=iUENoջ~#m;tDxҵ-qZ+.D(#q߭d1O;^@[rk{D&tfyo5i S!1r,LMGB"ơM4z#"1N_v*06*2qA.-%^E+K4/Cj?!h/?'$$D}LFf.;4kp6~DLNA>_v+H[GWa1vHcǡ$MU,sKd}޸N3"N ӋhsZ>FR_y3?FER+xDLER 5 Ѷu?mE|z"9L/9|go3B֦"TQSZv">X/& jn,%,@҂:n #79־A!=S1bIWLKHD101&ᣤv"1V1PTs0s _oa{s" ,i?k"HJWӓD 2Fy@*3<^iH$3"ߩHz ,Yw&"R4N)ܖ\bD#h/V|%ץH:-„,ޣH~֮1 b&c`AFI7_}2q4}/Ø \$c)ְwƔH$$AHycUF *\ mxť HqN:.90 Roˣ|$DR ]7i'"i6\̂~5l>VyP7VDR-6'{EQ=kx;.tm[EJ[3;"c=nERCeMݸNJdsrf%ÔZ'v|#H) 34q hľ@J$%+A"Iُ! 1a/ӻk%RqhNb5SA#NY١! \g |Ey,Cbbv]ƓJ5z-4rܿ-.~CCU!r2`km'=/:Z5 P[X$3y*WW+1E;*@|j6J1윫qLDzq&)Jk0x `ccҊTxRzN7pP Ң\ll?Fvl%*s*(,Iv8*^^U!V$ }yBkP$L$Ǭ0{ ܝğst8w2ʙ"9v9e1Z,Cd3f::e)_3PშLkv/Z[=ncV$i[[;;:aHW׶i;H, "9`Q _a*;Vgr> )R/ER)qA" <#_yAᾘ6+ Lb1֡ ɭ99s'"a9ԅ( d&ސ4#r/̝'CpOm?l>֦2^"I$ "I}H^4PΗ(XQ!:9&#qYk1VJ~"Z$ځ#G[&%$A$DE CzVF- %976]zpZgu|\5DD;H$ $DDR!C^ 777I H$ $$>|8]AHa| R@|ShaWWW⣏>§~JA$AL -FOHH H$  II  II  II  II  D   $$  $$  $$  }"IAA|xzHAA=^#oAA=^#AADD   $  H$  I  DD  )"9`63GT>^CCܻ`v!d3]"CѣGc̘1D?@O?T@|ćwsm i &aHtGB^9,>̔#SP aeeE# C1P=nmuw|&`hLȻ^#B7J%bO1Q u# sjL+ 䙐wJ$fj('BI*Ļ,cDzn0V}41"etm @$>8|(%Q0qYo Q$ BAC,m"U#"U9a$3YOj'\-[dž)ptVw€!K_Kʄr(Gzo<#$H$_ѳqfD{X߸Xy`ΎHv}V:!xy RMջؿCOݳH$ ID/:˗S&5oM$ύ la]aMQFA.8.03.y|o%#6j!YN+ľ;|&7TO>+tY8yĸ0̍}_. JGX<H;ؿy).$ڿ2F=A$ mA&>24Cʾ7BtDlZ)Ժ&455Aϫ"#{y7 \_ϝC͇=B%עQҰ>uvIF<9 !A>#J,?;~ y/I%n 2t܅wҰp1'JIIx"=D"vYJq:cmm;i;7ǥЪ%2>(FG;]֖^ vHs8Oʡxh+l_WFDBmĎn# ]W'xCȳ^'^^^dp,Aq![qq=tUX:Ji"Q$[0w%˵Ko-+3q (Ƿ(VH{=?!݉Ƭg"gbkxBBZ.Jy'`;(pe❣R[D23a/wjIR'dgܪڶF>.>o៰tݕjTl] K fRNn z'=oxm 2;).oĀ!l߿7k\˘Ia[Ӵbgv th/Y竅h#{O FuXb {Keмo|^!Y7u qgh(ُ_rP@S 7nc K#y 8]CEo Y$M[jaQ*m|aW#Dm!EEbFۇ QC74S1N"Y^Yl.*RCWtq]Ӿ;[5j?Nqm1bj]Z ʧQH"慢E$Mۥ݌|Y|g5 J\l07;~u\]έrel??3 7 kP2G=u+Ӣ7-i&n<Ӯ-#b5܇ X| TYQV):3'QpU IdX,ڰX6#6}]ky6ZWXS/+Ȼ 1^Jc↘xu-ԨȻbۈ_gvw%o?'|F/:HWl=I?$1?ZM~\|1Sh85FnxH -Wʡ)Iʩo|N]+ERq"A$o{-ErD+os ;qR_#a/,n\ 2ScIyA.Iep^Ducx8w>\pw9L،slk8SOl GHH$bCJ.PW3ǟ֌w8GŤxqsmâ8>_fw7wcUILVx \*QTEQQ1ш&1De%jBn욨q^ FDfz ߷hazU骮ʹ">RExk&&#c(_vsOp{vӗsVHgW!H#Y:q\#݌ I|_o}͜I␘%Z^1:Gud;Tom3@[帞>uL:^dg"9,K6^kVH'APGL W̓"vG2K`XKH'`Hx+#bK'.ke=iHNHDy4];bOC̨1p#~(754EREs82.1q[fAXe~Ծ0+=_0 ly)ƫ ;Rx/5D{bqPwĽ 9>z@2L"evm+H oOe7ˋ) %!6fb*f7A_|:> g!c&GކRjk5,۲ >!⁴џMRת0./ >ͶL+d6TtY\ͳ>q׋x@cnTFO](yEx,,dDZ3~q=Cyvp#&TKXQLܣQ]P=ݘh\ "g_Uc6¶~ӱ VɇW2>/!+<|bM;ή Sy ҙ 5Wo+Ӟ7&"Ў We唀uHxBRwDf­[78kI͋"陂%f's8<#:e8תZ\R^cuL܉HObožy'W񯉾52;$`ћ(<}&$o]$w97VVɖ5)"fn`=j3gm/op`A҆:/uwD$#4 Q${:mD|:FT*ʼnt{*Ӻ28fg`E |0ogD"9d 7n8sq%ϚHjQNH /^m/vHT]0{B266=kI_fiJٯ(L^pὑl"A]v<TH^D(w yNDj6Cؿ?}4GdtY\I^ϒ<=-A,hx 4BH} t35c]e{Ǥ2 W^qQ[?9[b߸|v,}=$ヒۍپuÌTF'"YbT܅AK$$[Iݡm.ж0̭Iyh^*"9ֺkLd> ?Dqu\ɗ%f&;I%^(`meۅdxd4EԧaEݵ(\ezMCj:\$OńMg_H`_<{܇ev^ā!>7)8D~j5Gð|x ,IJ̱>& 5HpPxZF/ kv梨g&#"EܯOHxH;f{gUeI"45<]\(bzN<u a /"iWC$gxVc _S;$PSt–PDrE>~v< sp} .d{맹G_GK,,ܤ/LVDe4p)NJLW; W?y(:1>FbD',A1cdF#:!vm\ߖgHaxPlLlS2N1p7}hL%"w׎]]>L^2vU3*pH՝/!bh@ cq^.p6\Dl,-)qV^,1Ⱥ IY&$[}' g9}mcm]Ȳ(xjnq]kLq{+N_Ul 8m+ Jc>vCۛf7웸~_}ÿ2(Tr IQwoqycA4 oRɅ4WưB`c;;aU%biHE;1+j%2?;m3鋤/ۋq19Gf.{; z񝆭]5`1s-fn:4R;Ng;߼Hq⽘lrY$7\\H{WV G̓"YW̻8k/Ɩ.Ĉ~l8%M\pzNZAEr̯|[)?4&5b{uf INDRW/ĉbίnH$'tomB+(/#o_!*"Y[v=5M!C+Q:iY$[WH?} $l%W$E&&U>[/Y^ÄF3cvL,?<oƤ@blt, Jʯb>rW>LxH@~V$!9H 3jՈM,`wZ;cq/dm˚^IW{2&a9+*~1i<'`wa8xZbrfƌ(Vn#$tW5"iÙz^jk=,(ѴRuWXu%e: -C֞ ((wYS۱O§\$C+Z['IMgX$@ }E_c=bwNsHe28WR{*lEdw|'pz)lH sG dR 8i bT 7"n8rg/_(43<c~ l\;^Jq1v8Sl|~j8zGS#+l_[;v?vL'Ezo$g3wX2V$.(<@~x ܍'qDB+t,ߑYTtK X?BJ,JIxhnZYUXq3x- Ĉ"),yt ppV{bHZ:ϖWTvW۬$x7o!DX H~o?r pVζ/۰rr[ꦩ}Bˣ[WNb8Ϛ8~FIى,ٺicΚm8~/ݻv6@#XǾ[^QfE]W{\iH~}Gw"Ur{eFaZV>w%6;8wl;2gǠwHϤQ"$js"ٯ! "lcE2$$ݻw'~xOǶ2 ^u$1DzX֩0>]z`Fe[L4k_HR|#{A$t=ʿ-pOPw8;cq/$sM_e 4ɑ?Q7Q_lӦ _ڵ+ь| V݆;S=?$ Aݛp9<"ك`G"0Њ$-_߸{}E򩧞O?D``rA#_k^nAm3eۘRZz%qAAF$FFޯIuWR'xy9{8AAqGf$FNz%!n=_Tمw~P&;?PA,)KAA O%w2whFlݸ=ǝNO"!mH![ܧ|P3-dvw;J X J&AAx,0sRL,BvN׎;^DCjz#SER+qdqA&Lg;:=v]KU0U$  AuNօ;ف;3|\Ȗ7R?|O[wRB/*joeA0t#  ꅞSY@[ssE"H![Ga[O& 8 CݪP=T>KDz#?-AABϩ: =8>+ȣ :0FO"!?rw?E&g&IU(U|()w  AhJtv=%ȣ: b/L3-~C-2;CF*[TRL7A4  Ct4zUy|\03[|w߉"{T_ʇlVTIA2&  [F[i䱥  yHQ"?#{yطVIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_expert_options.png000066400000000000000000002525111477034762000265150ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:16:47 CEST@X"TIDATx\?={]kߝ{D, C/ VAF5$j4kĎ >;30 3̀FA~>ߵ[OOyW?UIaY?3/TwƿU -_  Kh{s=Le] S{ ՞JdGK5Q[_W  ShkiXʎRL-?4QS77 >  6&MRljʥTjTj 12F"5 .y4jʢ:W?5_zw  G/i:ڳ4SS05RTJ͡n?H"u <~!SK Cj=|JAA%MR{ֿkߵR-4J"5{!)Zb^*L4MAACJYj\jJf/Z(5{'%RRR-GMyLC7݇WE??AAϗ>>ZLMTTj Rw#4J"5{!Cj WH`cfb\r\!  :EGnaTϰS9Z(Cڽd(D~1]Пs۷LfaaAAA8G\s6ݘía8i y!1R&[DR{NDV/$=:O>8SSS&&&իAAD7s38W㜍s7y)r馫Nw_uȤTFjKzNDr\0`~QAA08\9UU:dR{ΤZ&ս-CWDUK"ɚ.Q333y$ =qnOd2/RqFj΋\XHnZ/ߟOA7ڬ \=_`^'AA|Xp\j1Z&?`$-c^UKù Ii8  OTchJTi/+?5AAn9+++ϸﺲO~"/!n]-"9MLOQAAtְN,;ooMQ9WE$Fo_z#iTQAAgRnc'~駕ܔFCWCYaQAA?,--;-j}IsU^Iv"~4;0& xOt'RWϤ9S9^ɿh,i3^[˴Z `b YN&DD14gs>T[c5^R9+A0.@]}Jn~3'$yX12 bu`A|$[X# 8ǹսgx[ﰶ ÌD ] L:jI#$՗0ǽw? iCћe}qdi_qWQGI^OϞ=3gNLz5J$T.hv˻#u kg `\$-&4َL}'ݑO1>X_Ɔ=TK@8[:D >:wBu/Ѐsv61 U3~d-H$ hO_T^$!:9{}|t8p!ti~u)[Gb`S~ \%eUDݓؔ-jE3g+AUm-ʞS=}(-@qQk*Pw 듽aKkqvm(E]u )ޭfₘ{pc`הկܗ#gnǙ/PUq|1 Q3u oԱq \Hް[ QV]XpkNyGc$cƈmymGFsX{$Auqa%:aUdeOB„r郑 =GIe=_GC$ .+³Uhz5 3y %oz"{7nq5/a#WF ?,]g=;oCWڪJpzFb<+@9p=#(CE+%4Rn[Ei]ܽ{wNύI.^) \})/Dwhh 7 $ΓT m/hΓlIJs%%$AmW;bZ&858t'Z3 E7Q!& 0麀(gXs* BDR}m"hU~hCVczo>0e7ϱ v3YGP-݅H4Icrai!< r>Ivm DRH^S9 IB1?ҊD C~*rd [ARs[v: ̀\ㆽ!Δ"!¾>ʆaoXC$-}yŏW9-v।0rpcHr"&Z7`^CS+/Ͱo$FO`S6T =Bw+A4I+$]kMH]lvƭI$ hG|W}vJ`JsUh՜@]/ ^ .'qɫpn$pnԖ@C圴m/䷑T˰lY+Kg8ec5-,/"iXCppIU,Gy h>V`~E$_DB I ڋd.DDU?0ѲLoh]\>p}_]s<v"c"ib&spVϫ) fmöC3q)dzaJY;@hgI˵=ƺiiI^t0?:T1vb~jl1&Iw6}<,ۨ%|z3vGkhL(/DO]DHj6"6v$Az깈\{Mѝ~]z8A 7HƜK%v+E$UH~N"ID-{ L#3j(~Dbbb70|p Wqu o߾077qbŎʯb%|pOQ\ [I\Q/w꯮ŵ3j(K"! \Q/n꯮ŕ _?K"D.IDw 5zC0bĈ"D]0k8' s%&XC&F ::o3www̿$Gޞ [al}\㕜E!%%Cq5GmK/ᱣ<~ݖ3IίCʨQ8pBmKHvsx~RnF"{`ůG2ʉAHjJdjj*'>>>o|l!#1nl <H:}C~pt EֺmXH+'ǏP 50aG/$:D׍8f QPm`-ɀD?Ÿ\YSAK=QTҠ$' Jq뛱p`]+6ͩ]?A|puFK["97;=Ʀ 'm|^8qߋ]0.H\ Kdn+su}a.xuz.NJe0 m.V[~zH͞ɏ^a"i](^P$,{W` LT<0bjonBFD(Fč#;l{In!: Gn4Kqjq"韍=7a{B`OAZqeaR$C o ^~I$ Ɏ$2$$u{G`ȚY[$=0"2qc|Hʙp_qIyf:{u~2ݼ1LP<݊INHuZ"ոUܜld%#.b4H$߿H!Dw7"aL(BMDL"t rɜU2~kl±tcErذa EĹĸ ~0ksp ic5)~IcۉT"س z\dan_9\cՑDr߷ǁܤ _OM_}!`Hzt\{(p"9!|.({ϯ~Gt]B]+jƉ>E[ﶎ*\9WnVWE288}Kfw>> WW/H]8ӨUA07Gp M %帾l8̹l,W4BX";Ȯ'TSRhkK O6\Hg*v)*%M-_捆Tkp%Nz¬"i1kBVOkpm,0d TIT'B'p!俬T!GcS\9!ΪJqlIq"Dž[<~ |U HkJpsB{lסI%نc\[* CqGM0H7yr4hƫ ptLjn. _H<'bxIRې5‰$ 4*==]/E$;/ yN8[ 0ĥf ;'S\H2%} 'S1K#D1f`D>1ñ D!}9wW!^K^}coyxQ' .DBS$E _oIƊ\V{InEvWErĉ-9Hn':t,LEfvҦ`(FLAjz&ˣ͞4d|=-!m:]݆a\t2cdNEB(x;)cP ;V"B4cbضqJĄ$e*8HMzns,%C՘2qE"f=] YYΈDxdVyY96I)- ?0P$Ma7i;6T5qXVSyIDAMQ"ɝW h FΗSEHpQ}0KQ#4f TNAfr4"&NF}xplg~[_Q+//XH@ڂݸ[@D%帳= SX!J^=wj\}D|_ &*Ii/-f; x)%$ }>0ÇIx$+Qۈ` d`ɈKPDrlQ8_k[ejbbL$GZ\;_WhqMpin˽HwӸ&&lLF1cjN:bgD#屨'Ub⸡awC!! 8>C||6Yi୊?&"#q a!LFvhxWlwj..8 rZ6F{0|A\F.X9w1v_4n氰ud|yM"l`HJQc",4ER|x~[H*{!5ۡHbFTH=2O6Dn_a8!ҳ_c4zU M#/rs1X+1tNUHʮa; r{1? JO$[?,;xmLrŗ%h!h 45^n[HobeX$bvTv߆ڷ#؂gnO@d#|"ulm͑̉g#s 9F9_$#zdfHbzS[W˨iBqlm9rA4 HPu8X:F;c[jhI{]lMG=ʡ$ "))NhuF7ge?nn/@eۧɨa-mOX:rRƶZ`I9H T$dE#б5"ϱHfMbv^LAV,-L)!pcect2+a אDdDOd}z`mS$1dbyKAl:GvV]4p; znnkaOωpL$!rD0ز'\$wU*P 2C45V$Z;2튅-ʼnj\w/v"]iA8kV%xK$"dLV]i`;Lf9PJP s2Qd^]8#8ɛK1L 1*H4'9L+]q% a|\f"y(c'd"*/04J08 AJrbv6oz=ضmN.P69qp^8oSH Z>aƣ9Q7*+]=Ϫ")8=6>:!,VBp'q*b駘H^_mH7#o-ɯ܂)cs('e#;ypsuW},8P%<<"9UM1)JQVz$߹!,v\1D>HώCO_nܤqӺ&W' {I"㷠D?Ni:;J(ھCmw̹̮o[g! BL*Fl)dS&yX&~GFH=XNJS,v>3U NaF4X U<* ;).VC.)^4wƁ )<Hr9z(Ξ=_ iH  I䡢'v~\~S=%Wug^qîRlIƸc1 [9dO&JB^uq"tbۈsE۷'p Flf."rz?G:/qCۙ\ocqcC-?9Y#1|4dF(/͊EJ${ajȞ7S#0>"_,"\lcH$1l=V`d/ؚB<>Ӣ0>,Sg"Ѭӫm>;dx6BgT۽YSngW m8b}ȷ/O36cLW%O;[ع3r"/Nf'~ }R&ĶmV?٫۰8+ q4$+G91;P(= {pOL6X'EҾM0b ~q윢Qf=ױcA:رfciFHK:\danWu\ze˖a|eq=+1 ^^T[' 5'Q6}=#"ӑDr0Wٹ(E2[Y0!- 0gh|]Z\ UJnk1 äC>z[9Kꯨr'hw|DŽ=(:j,VwʛqAb#7mȥ8?{06'^*P`?ʌCdd R\BLU~J$+ ]k4LU!aAvP+^$#[y'^$'b@u\;wNDRW;-a4ko"2nP#?xN!ֶ)Q,OCXyox ?,Dn8r_@Ae#dxr~!38lZuzO78xՍr(Qw*A̪v8p@e駙Lw.:!dORXf( *--p}["$9<(@&NjMw5INYcJQ/}_ {Ɗ$q#pW" Kx\\W;"8߿E$9iӦs";w,eCs/Tq#lnZ62Ғ]"puAJ ~# Dv;7!q|x)W@ y! AxfuxwF9#L#yx^+B!ECe_ڂT'\7nȶ%\ N191 \DڔrHq1!1b$ I)c> ]%!=+GY.&"lc?2lll5n_,cZ x;puMH~n}Fk?ɷ.Zuy?鲸>Vu~5v'?III ޿Hfff25-apH4tS8!?Kʯ8::οއ ;H$Hں[c:C)nAPWC"IqS/{IA9 npu꯮ՐHR\)K"{\VVVANꦎ޽{SŸrv뇘I$1\bӇO/7'xpuW'quSG F߾}Sɸr1bG1HLLL(K ;I:on{0\i]ړ/$AAV $  H$  I  D   $$  H$ -ܫyzEHҺ/&H$ BD׏#Kk.͹2CE{(~)a.N\(n'AicNqb @@|piͥ9$=P$˽EɉOL'zp~rQ(fۍ7R`}\piΥ=IaI ,-- pq=9Q(N3ƎDDa" )pOT/ʼnbFPؑHH=P$ČōD1#( ~H$I$ Ij(ŌҐҐD $$8QJCIDDDRkglmb3 +X7,}X _!oP=;63DD E\Z$DB 9U7"TD"I"I"ul1iG)wFPOsqIڀɂ7:].ay #%[aK1-ɮJ5IMO&bu|\(Éް"iggg$B~;dhd&uXoϹ(2Fl)+R6TW˿`eJypۈ7A0{K{H$?Fcxڷ8pR(TŹ=K0݊DRG/%X>4~{JIxIHvm<7D8vz+<[ʣ$]WVc(c #mɇȓď~׮`s+>$]ɘo.=eh"WTMݏbNtLeh[l؅8r1Jk$)d*]!hs,\l;skT Ww6Xu֢I.GScluP f/i>$NLTy=lpU^&oz&:(?sª3y(,Υ%يPgվ@ UH @Twpdu"ڷ7h^\}XJp#g++c-TmcMBTMq$$q݅f4 lk-+xOq姙%VXOӷQPZL Q% /@pƒWYQ|ldr%7P BZ;|JDHZ?g7<(F_8Y.+&]㚬#,_507ȺHj4l#>V[/34XKW Ӕ"gHQ[;,ջI/+mF`]]gUP_җ=茟 +(mBm}km Öb):gR R\+@}G"i7%ER<ަpQdg=a6o?W668xvp=g`(9[cB#W/HqJZ '>G5qxI5`Tl8qe,jϋ/S,na\[┤ f{i~ N {QťZ=pE&Z7,FeJ֗!ny[B|?Vqi"#bgl]%BpN\yZ \f qqNE~3<,gD"5B=xH9dŻ.Đ#(ߌrD9IMDmZ.D%6B-oij+pB(z9~EbT$b0K:,PvϢ8{ʛQ4tfڛsٖĸ8LZ=wjXyyVq^mtކ֖<ܿH_ PcGĖ"JaYJbR0kUT^L\2<$sF4Ə CtZ6b$$h. " W&2LI+xw@U|&id/m 4Am;s 9nD줉LhwVZ{#lj2at|{ ."i y09*3 V8eVA^vg{C)HZ^]݌YS<NC&WKkbw♴d`Ҹ0$u%Jto𱵁 k/Í:\][hӀKF b\h$d|@=FΣF$0~c!n,?+TDUERzKBai?7327@QzY}e)cMk%qQQ889*YVw}LapZIC3Uqi:޽Kuۛ#),VHJƙ:\tvp܎jJw1zCJ~DCy Y>$99b/u=(@ka.:+Bx ;"}?o{ 4\ F<\GSe+R_H+CopbۏZu(4M"i6!XϞLoKF~)' Z?wH~FR瓱8eT [׎ DBmHJ"FXaV8B5[P,/ŞxCۆ%!kYa?1L7V:8U\1L#OH?x*{[LMZ|uuױg}4){'@ߍi?"iĎȣD$U Ndd,piO˂ ERkhj0fg͍%LR5k,]lptrvV*jQy}cd!T]VW%oBV{9F#y ~Ks^DS]e  l8/82ź=+`"Qm":n3;hɛ͑#&`5.h#u)P j%0Qan@$$m+P*ӹpϱ7Yv@ eJIc&tU+q_'v|e4~8QS_ 4*]N7IK&xXYw b-#Or=}mg]T6Y!koykȻ7#c`pF IJM,oTȴE6cC5hvHI#bfD}âOl/[(ay ~Ce *klֆ-x1bTYKuy}FW!؃XP(C0bi :M:YEǗ2~?]5|]AS-kXAv6撡LDAEDERL$/W'P]m?sO:7Anw1s$[E+rc4բ6Lt6 qU.Ó'0r,߈Q#0b&C&|Inh{fTJ2p9Qch[\Ήdn|ءHzՍ tE8trsGI$I$g\ZL]A)a @ h2l[u~SC^z+&"$xfSYɤ&#H7B$mivec)C[@4w HLl@me\(/(cDr6=P="iĎȣx̬&!zSl`gdNOGDr5")XFRHcDwuH[kKtҖ*_`6x D?ee|MҰeh{m/̽$@sh[޳Ǵ\ԢN`3x>j%1VE$|l#>ފH"idꁼDz)cCpst;;8@"z :G&k7p \\N\]qW_nDӍXt MW_hH3]BII}+;3 g k#mE| 9ֽz԰Hv6#CwF\Z"yo%H8j'^_`W}{D2E5G9du($XcĪם^z`U֨@]ݡHˋը81cW㎤gm̞xn`d"b{R$b-e۷I#bfDcfؓ9!!!P'_g8XByM g퍹Ycs}j m-+cdmy"i!9,ِx(őiNEXH;TsK0w+Rͫ}i/ ^*jpqAVeun.<7T\G'%rdq\ֲMQCۆcgHj X؛kXh " oDcGa L3'b>Y8R"7Er\;{W`FJ<2¡ #Y=<*Q{,J笧~3T=DR?AbtL8g"6 kEsc~>R %k>?^:䭟 766,NF\b.֜.Lrƈ;8Q ݽX2-&E#)wrƋɮʉ5PŠpf꘴x"*AgO?HZa:b9Ɉ4qig8 +Pt`&F{)PQvs9)ϠJ3 KKңQ'k]l㒸%r DNB$&E& s,DzXSߊɓXzk wvT.Na{dNGb$D&d"3b0U:;ϭ Z~m[c_g"mnH5׀s"w#=4 kq + 9;ؑkufDZ3bd \,Dތfv/خŮ"#ٍ+=IDz0Aq( }[EOmIID ʼnbFiH"E$$$X$G Eqkbֵ2IP3-?t:t(lmm.I$G D144$$H$?6ƠA#Eq8QJ÷;IIH /ʼnbFPؑHH=L$#  H>"b1|}}IQ"= A&((&DŅOw*C;-D  z_k,r=jY5$AA$މkccӂ5$AAA"IAAHHAAt:u*$AAaHr~TI  °HHLHAA:ERDj$$AAAm  II  I;FE"wn" "a+@%0sȔXj5N|\0~Rݺ?XY8"bJf[>cLDzSr(4G]cCk`#`~s r:f+'=K>hÌ{ۈM/|( UK _u\Rw(]}_Ռc>sO̽g"_r US]Y=]saZۥtg12r?-,bީfꔋ 㝜ፁ,-J 07"22\EFS-17׽Ҙl'U`Vcc[˶EA$LDmv6ce%{ )oKa&"9 PZB.bJ 03fh僧Pʞ^11Ng @Í/4cc:^,k@`jݯXIShhXإH="f3<19% `d pE@ G-1_+J P!!qCAa:ءm3/p7"lTkWq "i4/`|J!& 4z$)O޼5Zp`y5oc2 Q,X`PeE .bZW "(( LH|xxdΝ;3<}nr$dODr?ޘջneJWK(| KE2CY:EABlc.^Vg3 R>|zpEdFyqIp$mO`Z.U$Lk[LKHv9.A7K& P_TuARLD_9u]nܟwލ\wjf{DR>ilҌw~ ݉N57Z'{CSـa6P371rx F)ʰw >'E~<1TަƑvpżsZ4"i]Ҥ( IÜ#1{GN:(x^QVmi))E֠GS66VA([l2LQ~ƿgaeچ&- m 8`,6G()1+|.1̼>3 7#ه2g%ۣRSg(1]X 6Sc^Sc9!AfFfBUdY=?),r8I`.gfI,l2!kѶoI~]v?l/ζ#,U놋QͅͷV>|HJrgz6Hya*k!{/ KɏSD̩іz,(n_hƴHos`}I?`y'޳,meƊPHܞK?C9t(Ϝ`en*em("m% ys]uvQ#]mSgd/Wךd; gVR#*"$d5ȪL$_]$8 JfN+4Y݄E9RivZ My/T,5֚݀Q^rqQ%,ybb&_۹]}sDdH"Ck߽u&;=}zm*QLB5CPfN}6?ymz4i4вsXRuxZoλiy juh5ڻ ӱ& bSR՗COrMz]/0q!g3Go 2I#lT +2åN.Ov?⇸yĿCk)ʏ@elY|2,j,C4YUymѢA]C+6is=L z\_ +;s,Ĺ,76 6lRvD7="[Ҫ98z&Z]6V{K:ayOWttiPn0]v+N ſaׯ3ϧ.AG94ZЩ9")>b h95yƲ.Z$$X{: h‰@Խ)ɘ7B%iQ\,^0ćv %U{Vƫ:S,'^@%p#%cʕ]_FD )>hocenGb!n\ZP ;s1ʆE %⃰ VOqCN3 >Ds*ћӾ y*Aux4ysSeZ6db5. a|+NSl-Z+l.D hKwNԯ^ڸ om{bB41/ݣ*D枅pvo5 mhdjKa0l~8Njrozm9 E1:=Ƣ}DF[?hXhkQt$Va>O$M@a,Ç0:W>C;RNl*8Wl; @DHzIopX%"i{Qiw| D), 30CBd\(nAsˇ}dF#@{y#DPʾ! H-`܌|ǣ>rs_#tp]f-}d/@h;9ރ+CpGo \[W+:DNa"&TVlUzFܾRq\4 U-,Kҩ߹\ݙEjjP~os"T6`ˑ*L-qߔ M}>N`FCAHH%ns%HT<;1_K|l8akp&>YJ^!ޘVUS0"bMu Z)oau$a4Ӿ8r6UXj :eRߊ Ij^ bCu;PꝀzn,4G㘱Hu,43WqpH--`8v|K~FxP0"K{#C7૮ 1"A!X1^vvIW$ξ/[B*1kX_ނYӠ\{uS'6hH$ ^$ӥ`"(_Hr9 yCS6S}§Kqdj9%ŏ/9N5t{rL ` LOҺTv ]Z0¬VsnlSm9fh"ɕ`b0cGx~$1 5]Oo ptݨ-՟WA$$]D64DRLy"K*ϒ;,ʰ=GP( hzCs1wI_| 0(7!-O't4J< %){X0`®bpb\WPI5x62'b51cޞd/W,w tmG⇇ܵ">Xz]m8@0wq^<AA"I"ٵ&MH=gCy.8 H{_L4#-xP.\̩ӨcH^+o& bI8Y/=9 Q*(M>xq_ҡ1@[x żD,n/j  $6Fn7Ax@7ԍ=` FTǵo7")'xf w(B\дPF؅KOA7oqoG&`5R1*q8Haվ.H<0}eAż<`"iZgl4|u3y: XY7b;5oqdv& H$+ i } AA$$P`d%>AÛPyP51AA$$N$kQbǺ' DD  DD  DD  DD   $$  $$  $$  $$  H$  II  K$'?% DIa*{%AHL^ _K5+cMg."i}.\cX=Un5HsJ>?ޘԕR`ԢdlR E$Ri5?")Pkb8 LI<vݘfS$LN)W2v`d>W7ӖpErp V jV\~BWVr%ĉ‚5Tk@qܝ>4 &rIk"YPY]YuO}ܶH2Xӄ'!q@ˍt2LKd$-FXpoLǓ"K}o8`  E 7n@vv6<==F#{,h`E5=tlf**dRBX6#$ߍb y؉0139I`сۈL~Glx5mJmK1,!>~ztht([!R;m(\jbq7޻C8ᐿiwO#puǡH06m<3"p8>b")WAWU3GY%ѸlU|6 9gv  S͛F#I9G@RhռCJtb)cE,xpLWٹo}s]>w|yNjz*W NH")CGINQ&o#;G^Oe%2\6V<'yf,> pvx>P6TaO$cǵ]M3ڴg1'o]_Sc8qGt8#*Fǝjo@2S`y7s$UXAu% H$Cd8}I ؊Fv'̘$c$]$)ٗ'[t~[yOX=NzE %q. 5+ԁH#9hRD D+8qGN$Qb~wɏ|6Rr j=v:=>LXN'Xb}Hr0#>r9Hj/-Øli+Ds죄' c*")kLL/[")N};ER:y4gFĎH2d+2"")8(ίQEX5N$ pF@@M틢HvD]Bqg}m/( h-drA1a3mD/D(<&R:]UH ɓ058Ǟe6AgZs/  BxT,T#˺HE!C-@VV"8r2^,S")# Di*JO\sGǛ*xYDW8'X#,?-9]pQۋRuf2ījm7C/ =0/D(W7I%UP) IQX$rۣDȼ=wd/wQ x{nK6DXT"8v~'"ݎ''! 8_C2<R<"c6Pæf`B$T9VEBbT{OW!;uB'˄UC!W9 AH78?G ~ˏ~Y=XC Wp%e\0.Yhr4/t z4+@j[*|c_V ju<8m%nrM'"isvJay-"\-V7K#:8u$`1ªfpyPzV܎Cbv|E"3Ak tk({ ȺI"L~qinaiN2d|\ɸo(7dDXOw P b|/(v~"X3׬'(1.d߬Ͻ#(EBTkaڽ}ܕֈ 2!@≩GVJ }:BW{t' E~2aO0G}\d~C TхoG?xg)}N}BA"]$a#E?h<fEbOܳd1xO=mhQB/m I㺏w"PSm^|e$ðuO,I@alH?3A$$AA$$AA$$AA$$AA$$AAA"I"IAA"I"IAA"I"IAA"I"IAA"I"IAAHHAAHHAAHHAAHH~ z=4@  E({=4@ f|$؄~@{d wY`ddaүmplNMAү{}"5533q5/Ɯ_0$196+'yCC $")J{-.0),SP8\"Π!o#!dL gxo"r\ ׸E#SU^8x,+oX ,jh˅Wy \v1mKQJ K:Z)7TGP.yvYx ,wq^_ ҡXCypaF!!Y+0TJ H$I$I$9D߭xʩq$HI V N /ԡ%g-|IGE]/o?!`LLy-.wxKHbJR3b[QRRnJ$g:ՠa," (j+`Jq 7q1H*Be 9„ޖdFay ߌ9n )Oc>ҰĶ><> I$t3FTq{l h`y;)R[(AuT]^}cg#dv,RߘQ!cD?n=6E-.mA;UUpw/%6Zt8L IS\adv')B&':p7k"!-5"b}N@BD,ǡq;)=ͥ8L2q&ŘiMGPi/I ~;CC֎HJv77;`[$1b }fNipzTwL܈'[;OI04(meZxKd$-FXpoLǓFk=:   IH^ JN03b2??] #"$cd~;_8kFmy vȌ)fy_E`0KQo"5@)4T>1{+M۱v=SrH{ AʜKc-KmK#1딂v =PA m"Yo(,Y}op)'4f"ٳ6)%3e,6oq4qj1Jm& A+=l$g;:컦M(\?(Z") I/d_cNS7a[ xν!I샥&>?mȌ,`p?QOփWحs.|&I'P$%..tb)cE,xp"ɌůE ̲}Gb\nH_#c hЂ \$3ʍpuf4hxjLDw#Ecc;")}e\9.&Eq H@f!TlUR$͢gE vOPf@kСH$ɶHpNmdB u (\f9^ٟ"AHH R (D|@ʭұW IczB߈S c4lPaV*{'@}4[==IgƊZL)I6tWh@dF3qԾI^ƙy};Kj۔6삾ŦH|D-Jd3V(]Xd<1fS$11oSuV<2= vַ/ #JqDXT"0StؗV!!*'OX{B3N((N_p-bۧU?$f}#NDHT*æfR U*$FYىHF+Wk `DL5;A+0Tg1') |HZ$RG1"K6t \Z?As=^LUAQ3 .vN&n>S'ap$dp}< pbeAl5'ɘl˔GD1C֦YpblrUN]b8Y&tIжDl&DD_7A~Eu%p zI)KsTi0:h"˷|H1qGuT)UV E]͂m{z,+xnYh%z/EؖX>b&O"jux쿉fp~deGVw ~9q87GR?nB\k8G̠P$_-Gs[<'ZsR;4LtcQbV*@Uz.IR!dL g:% \"ubRx'>Ɵ{Cu %A|C}3d܎#f C.H~ŶIpADD3U_"/IvˈRvŔ,gxdнw1å_% D$={SY"g`RɸP ~ŒFR,߬m_K$ͯo: qKA$=I~V/x^.wk$:.#.Fay ߊ3o8d6@ıS)+psT V"O C|-<c@79PL q$`&åog0@XS a=wV˯@PЧK:Ed/@tCno{[!8Vͣ y.-N"m 0GnIC*J+`m*e>v#n_P!`p%)i?7 `VT(_(ڷDrV^ bjPv0Ut#7K7׉1%@?J M%AA"J{+ॾ% ռĆ 3eN}7yXZ$:z+w8$ĖHrwqx` wIHťM?#<(qQХ*rL^VWE#,d.̃FP#A3GEP#,j#.b̶H/ <Ž^r OJ^K~ՕElZI DI7*t)X;&L&DCͱPet@Wt"ڕ 4탽>]I-AC^YCYTӼO'̴ "(JA[6/#{2֧<4"L=xiѨ saɚ`5g˶H:ږcFێD${/{ύ/1]e~shl)ԦK: Yg,}<{3A$ߵHv׆WHVy[M>O${ɔ8\YxE+vEZM/p(q.zX.鋟/5A`x">@(܎1 | &MH=gCy.8 H_L4#-xP.\̩ֈӨcH^+o& bID9Y/=6WS<0l-S&+&Mƴg$2Ȍ6d=tF$ˌ"bK$실V<8dCƻ/ 8|}k~  H$92d7<5^snZk꿠REc:\R Hi.q r%)*Euzbb&uz13fRJxupV!u p[[]i}Uܣ3r٦o%<2+ws!BFſa"]Y?FG Dm{=NF3E\ᵠCD,T!H#7I7L]KTTi9:β=7ռZqb&tT⑭X2[ e<,[8}c0>xkzV͹h.fLzB2bW^.: 7/Dr6VEPV6=nK~'P)W,",Y6>P6AA"}WmLq NCYz]#^F˷| Etah3XVbUs!.h`(ߏyO#|rD¥'8Sշ~[\V3(ALh 8j_ax`xQ W]y,|e47A~E[8=cĶ"騿\3W[A?j*@}& H$Ì-(H  H$I$i(0o2Ǝ?Q,MAA"I"٩%^;֕8AA$$AA$$AA$$AA$$AA$$AA$$AA$$AA$$AAA"IAAHHAAH~_"O??O0(AA$?Ho0-{Pi+ Bbb*l]Y},l:sI3ds:wra&FݘW%c?$t=AH(")JeԨQoI F_Z1NG}o`bOO⁰`4"`rJ)4̐9/Cw -_.qk.߹ ¤L$G?r1,8/IP<"9yg!tU1nA$$ … y&\]](N"f$㗌BGB{yMERg\gQr*sfNCR_An$O95I$?+gſMnA$?HT*Qs6OX"hQ$6Zt8L IS\a6"fRũ>Аp,ZIn )g!8bEY *znTkw+%N`9ZHQ(=/No@7OY3átɫ&f]: }EKb#=f; 8((< OeۑQ GtԔg?B #L)ؖ\ltCLq>da5}o•<7c1P"!cD~Fa(sF,n#oG #B9X4j2ʪ{E&4??LYC_nܧ;ie6^"#i1‚ðxc:4v^{áxAw,nnnqi7ٳԶ`fFw/c-ݧ[e3P!T!}v'S⶷^Dz%n MNQiD́HJ#lFd:;b=1mVj[a 9`X7㖇CuC.W Im{DRi M#LXmG};KDmяl+ќ ñfgHuI"$(M9*g;ԶwH=3wAڎ0E 7ol7ٽH1e|5˻#i,H/AA"L&ӧMiV4;d$1ۊg6&b}zݼ7Bĥe>]}#Q$g7ErM 4"opXP$EE܉DrnꐮT'p~QX'I__NR؉0^hx˂ŋk2"#"iNɾ=ۊG; ~ǚq,7`-4;>vih vX_DA{"A$?Xĉ?hdw" ÿH~,7 aLjecP q<ө7e"ƪpB>)ł{$DR,؇aY AP{ml-fcO̸_Q$ d%d=Q[WqwII_cՀfڍxIwsUߙ_.ؔϣ93}%vDrQ$[iIxiEt~Jw,ƚq"\5*BnJm_E#*;C-.k{AqE$l_@Gm$3 s|  H$파 n#~x&JF6IlYBBTO8.{I :K$>Кm~YPe£b]E:( jrJg)'W=IQ&JSQz*8 <UYR$9ATƲ(g9l)邋 p^"'ĸ3;﷦)6) ÁlP@$ Y@ZŁZQZK[q։Uq@IN}~O G뾮uݖxq+l^Qq\fk5-Pz 2HHM2")OilDBIVXW^c17 5QopE5*S\X/D` ;kʛ0Y<)ڵm+vHZMY׷rnꁶ,>cXfű '..FX{eڮKY [Ǣl *UuC4HaJ~lՌݵ)U8Dr IeH:#d.@} j=s[*byh9s,Z-{pKVPl|@|l=y/j0'hy<+tImƱ //0|S[GVDOeV&gɔ2(T`Ԇ%{=O[и_<(oT@"oG$uN~W*fK D?tBh+bTb>҉VE-Þ$[ۏ{UkǕXfAX .j[؜3ފ)\=C`Z]cHb/{"M.a1{H -#GGlvc;' sؼu,Odnm@s['J !t7c2Q} %:U09qܑO{hUoQpYAǾ- 0`σ:NELVew+*; QuPkQv.9Y!6+(`=$bV'32^)o[{=t)֪1>D:9+׋*Y+<1_ߎss|ac.@wL2M 1&Cq&uϛC% \cXt.Ď7_ eO. A+D5- V܋A{ErB> >.C:{V9#;} Z޶+88!DzҨ1* m\g [s+d 򵫎+pDrjW&9rf@Wxhٮ8vR.݅kr-:b|.EU(!&6lgsy}}([D>ًcaF$X@p #2r2l9 mAI#bO?|xqQ, T%QShC9٨}y?Vg'C҃ #0dw4nEM4g?GzB\߿OR+QIkG_PKOA5t\HD_(O N+8)0ԡX3{*r1dM8$y-Gطs+}F;Tt͠ia5v^5y E+s_Eƈrx>[ۓ13:5Q$Nur<8ˊ[Êyf@)ƢH!rolkașKXgg:JN4Q)n(C e}#4 F> z7Q̳[$ÚH:en@[_FLܤa_L;PӋ_]' Θw&忣stJZ48fBR©#{!ӴcWiSB7ʝ]'Hs{}6+6< fq-Mmmx~=nǵ%sۂ;9廙Ik12:*HD_F; 5G$Ё+,ua;ÉlVC61A 3Wڑ5I[OQ' 1ǚR @.BqsxcL)|!vu0UW,M L!5 GE2yoHgț_?CR"8,.(&paw@/`LxHڼ6\ӝghH jMUvկy;"orhLHF-Sw6V֣ŒF~UA,YYqǁ{)=dw#I}9# AoBUtxpl%/EVSGɄ݆@I F9j؅āҟ6m*r%i8&8gMN$JROΘ[Zl'4*^:IR _>. NJdE蚇!od35 q NR=[IPM/cS֠zwᙆmsFqMmW@3hž! z4wQ !bExHڙq;?9ϾpYi=S$M1oUUAy2 Nq/Nm߬BqjVڮ#|I(!ߕ H$P8Kj7~F=3R5}%5-P1Op 2HHཞHcoUh/A0ْD!ڎؘpDE+cA48Ӑ.KX"ɦcj\d%EqX&nh-HZـ!JCld8Jq-HV+q{JXc~d(v+jh@( BnьHڸ\/D-`~V(DD-BS^4C=,z T w,gm6nI;Ra}OHGyKuNt) #GBTyxu,dHk Scz"k" %TT=kt/V{e`b6&9LםsapOok{#ogr@GA}hr,w~ bv=u䔄=ϔr_SA"I"|Gz1 Pm cLk ү|P;'a%B1pSz}x& AH~@"IMqy, ␾{4ph G$&Sάt5|mG<~xO/bb׿9<)؎ }b]M%xqn=cCM-3/| i 8W,<DˣF$I.;)"t,|CpHE?ӈUFTg#)+<;>XF k3W18#48FG $PgB$$$I*\T@miɊ$*tH} wK%S8(MoEPgB$"]}zqNŶ^4j hŹ(zRy2s<{ Odo_!_`U$mƒ _χ0r<ր?eQd^C;: H$I$? |5 )p|cR2 52-ү㸗Ƶm%&"%o =PB}+D'^y _b$!ʃMOv*vt=GC_]<+̨s'C&ž[ |^KqO HBR):ƼHR\EF :991Rm=Oz!!%uxoyK.hZquHILAg*lU⚮<ԡA"I"k~޷ F:3[a}Է@(oX U8?: z7Q̳ c?C7=m?DGŒs= 9s ӌ(9Ê'+RhgEm&yJg<%_Զ9)y|{ʒoB}כ 3f !y/dvJp8-Fs(wF謙7q)\Zx]6wCHة"O1$ٞ'sS-XKkp]㧶y8ƾ(*n&) IɿK$yQ{cO}/@:y1T6 vT«0 3FWn#[=P؀@WVGQ b6גHڑ"Ɂs`uv,mU2yGkV"yQI^>xʖ1,sFR^i1ͫZq(HA$&:I2'?'- ,E "9(̂$/kgF4D2yoQLdN$I;cHʟ=eo>-ڌ_Y{#p0îÈc A= \V6 X5>± lNBδpEbÂ[.fT$S]/z"i5u㧘eHG ŷw!*pow:<8d^$Eץ͉Xdž?$I<U28]6F$ $rPק]LKޖH'[<ݰIݔx."}lO%FCYL$EҞ_oCݼQzVN uP5HSz3sfNqSo 5ͼIwشvF.IVɛU)&}L_܆F~e&ueS$M1o=+*9̓9tΊ`eO5NmՊb-5h;ʌHrC3e DDlȪP([qx]KP]-1l"n-?bM~*dd+P"974,A(*O {ߦm(L"%O<陬H,K %!&2 {[ E nM -%HeӒ-A]~/A# oJa`^hbWy6H݁6`2m%d?# !ʖ"ϸfˆ䬕 bZ4F#|;GGtC_<'"$z"iKNж $$f@\]\<uuk k[4HB01({M!dO'}=k@Y Ȑ֠A*DGݬwu#8":h C, ?jƈ[qȇN@#Nw(@!ˏvC1?^`% +A$$18z'S=c_ IIx8 lyKH|<* H$I$  II  II  II  II  D   $$  $$  $$  $$  H$  I(KQ}-s(oo ,ǎs$~ 0*aŅwRW ?JlZ __N8#۟Vah8!$ {dj~{pŴ¹dFRVyc?^~fqz_Z ory{KuZ(Ѿ/$/_fdG[`˭^4ΛvNCJ:*Jgq(ⓏحܭF8uሼc*V `q6W@8MśKǛk :&C`,8 Ye ec]!݆޻5XvD2rs3?!8@"IW,Q^zZ'&dqz"hgв=xia屢؞{Cr(rDQEӿA$'_.|?n( <8cA}I^ V]řEp~K}gb{r"!Id2B9|ۿP$-ş"9-[# CXGG,dbP*jFp(p~7Dގ] "9e Nil'#h=VވyHw+R| dš:H+둋W|$n$H5uhҨquM+(`w4uB@Bg |oװU(0LxңF's TCӛ;iiBިMRyROxȕx3FWct>KS;U OD:.mcފcP} W~ LFEe%8Ũp |~SWQnx?M)gEcN$X@pe1]ԄDKwڸIPwCEzQZs^; n{W%HZ"FP>XϜl[I-FaXD&٤hq<3 OsDHeC\ 戅շ蹊"Ħlg`cK"ɖ,۱!zOZ< =x̗F/Dݍgr2l9 mAXwHbJkr!JLDJzW:jDzL"dZߑѺ;a! FtC:"/MX6KVMh"916 vħ^ںQ^ƖHJHE´b?n@yz,bJ5V[%o$K}6WM0lHIʀ+P3SJ]W|OjO\،YTE])"dl[m(i'DLcd3!-vMbdHZ O6n:4iډIoчJ(@SV"$2QV};0cNjzH*6H~x"3P?&7+c&t#>g V̴9Elv3SUərW* ]^$ϠfMq;ڡy+3)-SpC7L]{N!G~\dhMS̋]S,x4f֏.hgfLk ]B}K8@7Ku176 E;v\p_s+}F;Pt^0Z6C7~(޸ NZҶ$w/(S3:ʙJ(On-}|ɳίY)g\~A&tQ7~1qtm7浾 )o,֟ zY km\1#܍-ېQmC,ޔk~޷ O}|y_ 71C7=m?DqaNmsW~JU#>y;6C3&129b-Ǖ[Цf忣$nQ_EӏùnG`g!X];ծzb"ymu]$%ԣJ4Gr+L[C|G~. I{՞z-%*9@u<O"I"97E!,*;no-[?`.6z֚]"i~k2^:Tv5P5'P5a ѯpgߔ/0L}IKiH>ȨH~99Υ$LBrw1FtCIӼGE4}8& E``f{L݈d+G$57jdA"B#e\G6G}@l!)T.FxH(@zSί="7v'F-0 柑6f̚❿eVxs'N&Ă{=-cFQGuO72o׎z?ok5$fG7+?O7O݊Zj+#J@[4X$3,"*" y5"g0om SȰO4 1=m?պ|¤L,gI@97u٩!ݿdvey0nUh/A0ْD:{›O؇ٳSز\O>ezxo>*. m>B0yb0keV* _()*F}}q};vm=65 x$W l8~Oؘp &c*)g!ڎؘpDE+3)[w" Fg%HBD"dn:N|/l];Ϡ*' i!N? XQlSb]bD$ jLyHcV]Xkv~0^vgC$B-AE=G(qqvY tDV݀Bيr(\ҭ<m|[ yX? Ǹ'6cvx1T% MShS2h.ѰrLc.I1>ܼPǾu_ގ2ע[X4~QD*ߋ&,]$S4q0͉Dݵ{Ӕ;:\hRFчMm_ޅHr}Q:Uо$ a.o98ڶmLvO-8r)*-ԃ/pcN~ШԘ`Fa='ؕdy}Ǭ9;/а߮_Q2ER>*=ڣZك~Qi.Z^CM3Shy1 [P/dm8`9`; 0Ed돻+o,0z!:H،m}<cM2֎>ݱ5#| 5 KcPCUC߉;(َIw"qOEUjRD㫨9矃퐫٘?j!Z¶V]fۓj=s[~G}VrןX^o vƧZVۺm.uBh:پt Fkup/Ԣ*5,{ 8g9]\ϏM؝kX/'18[G;;=mQ[dr Ʉ=s7I~.50[O mkO:=yc# _5{dc^m~xȩ$D;=<|>6ĵ4@vC?3F;?-p}PHH+X,:zȍ0}/+pW}FAH"ЍMH$I$(dU~i/At?1טը4왏AH:#kT{?LHAA$$AA$$AA$$AA$$AA$AAA"I"IAA"I"IAA"I"IAA"I"IAAXISt5LPP:Dr|G3)tߡ% }w guHNeiD0 38#>i|ރFsǜiqFHlYm[,- ,'ߛw/|̘o7u9p?Xq|F6#y : P .HNR$\KE9R$52 HBd ߃F02$YE.LL,g<,$g1$Yw_$^R eȊxsI/|xbt7.!$7Q9b̅gt>$QnQ$#AALý_7MH=G A$$$N#,KEpQZd ·o'fN/EX񄇧7f~pg"@7͛ 7OĒo8)O,Biz0\9A"I"I"/ɿ㖣,+ n)oO$\Vw/J$Hy<, ID$9 GFR`ax#ᅈ,Q*BRVei0w~u}176E=JP'B4Hߢl,A"-  %NNCv~J$JJ|aaX$%HJc05p[X2eːhH^$(^kH/!L9(.H 8x hq!ME[ʟ델B M#bAȇ-l^Bټ8bq~ p4oW-!6YiXZ(3"%AQqѩ!{b6 GpmI_H4gqĚĈYQgIp[^IA"I"Z",#9|6fya~l&%Hd!AVL|1+ y- ="i=8Z Ia:b@Le{6uө>b2D7XI}1e5^$^P_ox{b^t:b8!$]xz{eBk9"-YXQE1Ǧ/ R X8bIlx @R9N&")AZ L@>g LxzFԒ"H忉HJ,-S}\ؿ9YI>bAR0][I%(-Ƣ^1^2,l3ii."?]"Ea1mfDVSGf$ $DDndsDlgiXgf\6"qlΌa;刟eǴ)w%qы="92 K;IBa楲6N6M)Ch~mմ++?Ӳ Ӥiϖ$_?bZﻏ53zXYg"ԕ32:=*$8X6 ( ʼn##:ҕKY\èX&Â7IMm f#dw̬EdevZS,/6׎:2xr!DDoIΌȓ!·;xtHR0W`^ 8aejצHھ!g;uTBH-@QI ąIZ"ia)0ܬbHk pDbfx9 K, iYVvJb/ lGB:T"J%i4V%cFH^kJ%c#]Ivq`/Z_> .hy1ʤe"iBysn1l駨3ow̭LB}NIkG԰,HM"I$ tmNR-[8wVD=dVDP?xNw`^_$9 y\gZ"g|pǴ^H/CٰHNR$ǔ="i*_I6mOFp6ɐId9МH,qpsu0YOȖ]a*"fꧢ=ij>*]{4bEp3^M=3 4 1c>LG$E+5t&\xoaDR?]8{",tD$-NDr _f E > 0b"Ngבs#DlxiLC8ƣw^Rzs{x ɀ$1S?3Onj8,3,%X^7WoxA\HNk-Ady9bc6c- ncլ@/,ށb)y)Ci|mXgѕs#E/cE6۰SݚHI"Ls׃򵧎p%wY&DD9+4K G"fδёɊBD-.A<a? Q: DD ށt,Giv$f< bW^ $$yx5o5*PADPA%R"bUVEײ⺮+6\ł XJDj(LL `B@]ݯ<03ν2qI.:O Q3AHHAAHHAA$$AA$$AA$$AA$$AA$AAA"I"IAA"I"IAA"I"IAA"I"IAAHAA$$AA$ߢH w AAHER_P<yڳ#DH0)i31w'b79p<LH܃'kDžcCN&l9GbcZȇ[.gw)NmGİϨ "Gd#'u+3{ IIX/"i3"13&btBXϵ(VC"Wc i5vX[1^6өJLb>_xekmdDp(Cv_Racc _Px'9e3d&;HbM-ǣaLDFQ `: H$I$I$=#qU@_,"8]98k"$uh"wchꊰmA0gFȌhA3*HB7$Y8@ A$$$$#q+qE2m_"X# H\)"rƢs*-: H$I$D#(~wmxC׌*49ph;w\DE];\;"'ԾK$M("=![ @I0yU,V%^W")6+_ :T\ڍk0YjIQ{(RpD/F5: h?D%]هf,4R$vCY%+vAfg^M@͗hnTI w$pr7^4BW3 IP5{|~movD*V6 եEu$IzC!DDkI)|7MgLDXHFVD"ˡtwr935||MZa9GFߙk"Nת3l\!;eCYD:?l+JA$vT1TYm2H)`{\MApMEȘȘNS} opej|̊+ZrDGJ 8)/Ev e8,OD8qHr[O/OW8|42e)ZQ`ӽv59!XdT$OьGGNy6yϢT: y1 < bf`(RrKЬDLg$W !S:ut,R PYIt\j]nG t^:VӚIf2/M#li؀=Mrn½@XB&^ y^ ˭ !a]5$I(S. Iɯ@$F-*vN̄)&p6ÇC &t@:?F "xlկv}7`"¶Kf#aNBqiF,ˋ /RٹE-oP4-c~j:)ŬWоه I_?DMmcmM!(Ulgqj[*;Q ^Y3yo~R8Գz!SES |kGH]" COHmԭxUL^DN8f]=8?(]\2 H$I$)dwWCnӧi. ɼ2Yxľ2IEr(Z,ۅVK~g:-p7“cg`}.t;[>ǪH0zU[^&X8FaH2SoAb;|{Kk$c|4?|"ɸ@(WNՂF,{z!2"E5nt?7"pJsRf¶i2FRj9؉)4 NIg(cDR?[<`AԸUpHGOҵ@$Ed^$8\ӟ͉ZjE$qZRH$DD+vE~ORj2x \6LeJ$rh[/#n~0e+^kkp8d^k<V&‰O?E/y=c \ُ8$rRt6Z!&tԾ^dFǢuGm?̼I)|ML2 UN OAc;G̊,x1k*Ӽ S>A*DIYYItLi ~6VdN$fE 'bOj(QSN6kQ+kO؀A$v ]]b!Œ]ŨtfIaZ7*!":e->Y$07u2E"|;^ # ¾j>ܒH !,>HZK4dć ofSpEKsryi ?wm[}1cS ˯4BW3b$Ch\.kM6Hv tu7?F!A5{F$ݖ_+# 8Y5z'6(P"ɧYB4p"iˆ"pjuQHI g]81_@P[Bea׶4+A6c‘j=Mr>Ñ0Ȃ"%{Y3Kdx1C9kׇ=Yՠ(' QfT^&Ngjk Iɯ?Zw %Up{r{'w H^/$v_ so$G:4Z|8?^{ci1\D6h5B GliR EqtN:{oF켐z5-By]Z _iﻶl=T)ұhE1OEE&G=C=t obKA~]SwB$wOQthf4)6Ldmkf,?x^ YZMh)\ҵ# DDr02Y CA.?]U29o3%5#A$$1xHxhz'W3?A$$1`J^BE:Q[P^A"I"IAAHHAAHHAAHHAAHHAA$AA$$AA$$AA$$AA$$AAA"IAAHHAAHHAAH~")dw}/sBAA"IA ~! Pͻr7Y9±!'sG"-+&0]lN%7 &$AD߅qƜ ZvK%N!_;/|"vD }e6@۴B 1cD[IX+'NSD$Qaq9!"J< e-l酐1xFLhL Č^T2D=a7`y'˒B!iNK<oh9 -3+ dkmd=i%ֿŹnMd:>lDU^vM14X6H>v3U1\>8ViVsΟ_OlbOA^AZn ˬIm53EMh(\bD?) ĉp>3zIG]v|: Q&DMPn5'seӈC$ύ*q Xq6>z\Av$ D,bxy{"Gu+jO,ͿY`? b]VUiˢ uN~*0A31P绋ߘH%?L]$"Q$ ܹUVaD )4>E@̒)$ '[?8 ~!iz \S7!?i$`@d/1"LŶr/vBj~!SCSH$"g,:"8HDo^$Ȟ7nȑ#,\)O؀-;܍S~6pƙҗhh@U}Fxb*-u5NE1AkZ< Bѐgǭwh?,pnl'iaŵ1Sj}QDH{)qE#4|[Uj?a |&5u]ݨ@g* \?!5T>^ɬpI:#g!->]iA~FH/Z#gcV$?'}g=e#Qȉ6.P~޶eU.-]WDv#~>F\=:@ш\hWhhEpE.UP|hCmEg0` ")Y &Ge*,3e9zT^ݏES,΋}{OyiAmEOn&IM3Z-ԍ#1߉#^lgq׺?] ^)EJo/|TCjQ)Q~: (ԭ(g_bWϪC :I6|ޤrJ\۟v$A},oƲH~t3^_lXXKg_׍j5h]kLmnVC7~KTGQj!O'Ck9,."!H$UDqΝHJJu4SDR42a^F!9 2ϡم"{`/`krB-FE4t21'( 1 |hpK GƱ [f197Z4 b+b?9;X oooxy¡53h4(9afhb Oǥ&FzTBc{a8mH)/XbVV5t }I&$W !S:/R_쏉 Bۨ*`5bApYn%L@< pDOьGG˳/WF+:E>O4]l>\qPm< u57FgEC8(růÉgjp/1wHؽtBCiҢׅ́<2,\[EC>,"a#N?Wl3m9!Ē5 I! Ed_T }c&) %d"_H[e.d20 ~kVFӯ♏>uËCj'8VKሏ!o.JɆIE^ɛo o>ꯇ<Q@ HJЬDLIL&t/N93!KƵ:-^Rmap&J|KIFoU$qyaG##b#\'otmj۸O}{&0]y5gĩmQӻEH*hh3|,,:Zko)DQMcZR*;AgǬ׀_5b/2ZAq-4#\=5;撎+jEKGu%h$&*m >MeT#٤J\ی)~33?qhɏ1.+>p a~sӤ[X™>\;.mZ?7q1 l; uRa [to "ϩmZm zZfo>[ۮ] Ga۷ ׋KF|] DSۑ 6XHv- 0N'K=8D}p3X`?D߁J:-ksgC2d([nO\(Wĝ?!e~BGŇyuIi9<6lE9׈AI!q8*6mqRKx1WEHD7 68L&tx'6_d܀Zu|ۆR;<k"a Y]KH2Yxľ2K|PEÐ>$_6SrPrx3O{'^]QyeK8O+YvPVai#~*F a?8iݝA^}/f %b|fߪzTV{)#E_J$Y(Gŵ*ԩZШToeznzXׯjV}z>Ն)ǚYh@$ID?C/F#(MT>w!8b‹ :T'S$Hۄ3>p7eAdt,x"S74\navIA9$[S$%M$+ 1'E,6ʴ:Zڋ;#:~Q<'aވƤr  GNmב1Vl1\|0|E|LIeḃ\dV$"9ӂH("nI$OYIigc3]6T٘=TԇJϺF$Yh#&g⮺ "lau54"C"9SDZgL-}k8 >(ci߆^택3^npbVwHV:F$ o}oHIg>eر'U1~3P*ۏ7ڷ8= txg5aڦ$y͈CbA!ݥ ĥ!h l~b")v򫼀Z ƤYU AX_¡ =DROm{g=ܽJe\aEER~kmMx8(pʃ!23#%vN|<5o >NͷFr"hT'0n 6.4Ԝi: y!)(TszlH"yR/%vZPI*ˬg6*䶺s% H$SfG#F) _6"xv* ɑrX2Q#LJ#tw?#!A2⾶k$#0w!:Dx,ˈ{brd]{&^EQ1LC>4(KC,1i"Vσl4##%'38A/P (H-Wܵ-|*y |( Q+LAQL,;W(ؔp !;p[%CAW͇SI2ŧ#r2h"pjuQHIK ]]b!Œ]Ũ;Ӊf$]춑Yՠ(' QAJmF n&ӫIxn#j|82סp "h˾d? ,8 )Fo *y`ERXʰf|ʂƂHRR[{:Wyz l̰$Pp(\օ=HĖ׼^jO6g8YP0sPv/ ~Hㅸ59g!zEjyٗx8R1zYd`P! #>YxȶΜ?HbCQ{H u*H>#" \HJdx C9kg龷kZ0"鶼m|2~𝑎=F${+!o]Ϸ!ec]B8>":e-V 9%RFҮmD?6'QK>E?Q[q M«,Mx]tw()OFU %s4N^3n>GVVē?`tOIĮ laM(qKNvhy+ =w6?YsߔŖ0z^ηƶSn@cZ vc^H06b ΔՠЪ|"1CRw\DE}%x~unE PoUa<3BRԴp|Y4|;#h1T5Cr{'5NWzkIf,?x^ Y5-/6C<レ|}k׳p 9ENJr< ]k4?A*&/SNAR[I`{&`Wk]?7@2gI$C6r8!5T6 uoXߵ]SwB$jwOQthf0.E[ШNWwplm~hx^Y!?~~َ^myuæ⃸G{XӊJi^-ƗIK+<tOQ; j7{K{ߵm-}B{Ek=ֵ5B G~\}7g!v_xVUq]jN7paM.A"m)PD7ڋ*D=cjwb Ď3%5 w H$E$oo5v A@.;WF:{6B/Ox?4=׿'$$A|+ ~+HvE_&*`~7gxDmF;$$AA$$AA$$AA$$AA$$AA$$AAA"IAAHHAAHHAAHHAAHHAA$AA$$AAA$LpU(  H$")/sxJ<yVq&+x\86dbhW@VZ dzc'9Kbffc{06nD8F8gB9 u ;6Xq/QM8c⑁X9$7/b_#"i i ēP/fdFz!dlg|0ޱѓt@z력J1qmʼn6f?w/$lLBf)CJT:U1zJ`姨kBi3>0>EulHmq3#6u86}C_vت\̒u{:>lDU^g>$I%'e,#_l&F`ZF lEI!DDҺH:bJ>Çqh~7!j݀Нvw$ .՜FDse!srQŖ#ۗ-g`%1xHa+ ofCȸݽHQbf`0fMrL3#YȭbxPIKr,DRx8Ht$$}I'\@011K@̒,(o<H~ C"1 >ad;"bPER R%Dw//:yDrOPSq{$!$d_EWu6 Ppg1{t6ΔDC8vFL0yU,V%^W.<@M /RpƣhSƋFh4LaE6=y7_IA]Wk7*ƙv3e \}vhu߫@p?I 鲝?6ꦗut-f;[yS7%Mcf GΤ\^̑ n?6:4MU}4ӝ7 Oe"٣ zW^B #z|/S{ \C7xI%uc5x$WAF6}|9]ye/CVa))Uף~,b׋XPPix}'&1Im7pjN7bz״19QQ=Uwj߇v N^΢zhb\4l6s] m|*ԔFY 5mr]ZĢ=?6ERg`EK`٩i{x-ڋ+Ԡm\{mdy-{Mp 4 Y W&a]o"iK",k uD $L%VY^zr ;%.oKl,J[ x\ѢdR$ljm:d?j5a!O??}RS{Pgw'2x)L=5)΅\p_CaHeKUr.DжĚ Ge{Tӆ''2.": )!.KuZ MhSQU"hA8B.GX:xW"9TǣX1Cr(D]i xUD#}O1tMTx@at%@ ӦC6?}Fn5aա|`Q__ϽmHgV|ΞlR ]QD:|Hr<p>B‡WDcR׌Wy.Gd&WAgV$oi2 ƗMF M %Kl*&y!ߎrm3N9YCsg<>;x%WӍr48`!\sibvno!HD%WԼ, h_nZL`885jQsAjqFRA8AocG#Yi=GR u&`&^ !?MmF t#upz8~.as N:|0lNTOݏ Զx,VkAI<_vO$ƸPkjc}(d!sC"BHHM${gR8RuXD}p3X`?D߁J:-ks1j׏)X~oJsRf¶<`y4"fB*%9v5W7o-n 'p<[ \E*|3"9D"??i4[uWCn;]3\@yb}_em!Vs8!FR U|#i(/cpRYP>g,EێG,.e-ZQ[SJH oPm9d{,ԥix#/LHZ>Qv. qA"_lsoӦb rOԱNo~oСp<=i|)m^$ ")A$EqF=M6mf.If^OX5[tBI?;+Hg|>A*D´K8$vm)qly@EҘ[kשmX736+߆'˯{ă[U 2ZKAzƟ%T~ X}MS/;:dV$y ZL>o4`KvDYHdI+8T%yd!Z% &o,.1&Sei5PF;S n;GDD6ۈ16okM(#"Zێg)L+!el X~;؟ Brq_5CS ~qGCdDzH%N{&^EQ1L>4(KC,1i!;X>6@PGRգcX@ 9\H`->G${WR[{:Wyz?a6fؙ騝SpS]I@C2C_Uf .!$znkDrCNxGI?<")ty6sYH4cЖ ]]b!Œ]ŨN'lH #}dUx( Q+LAA;6]݂hy cjW(4dć ofSpZ/b!e}1Jq*cWs Zv>sG@!"ɇϷ-5cl?Q.<[~l-bV$@K$x?⼆Gck^FV :ʮm>CB56b ΔՠЪ|"1^5*KC+Nӌ{=ø&3xl=oQ^ ql oтH - 6z!Kk$ d)CM _C{s- c *Gބ%8nz뭆oM=O?3>xːod`mCc7_A?/6.Gq^ᡩfk-M <ƍj4S- %v^i$}G]QniM gERA pU81XZUnf"L^X%qj5ʲ|p]RsHElCH~"I-8`6oFz`VD& iQBp㥣hSƷy>i$$Վ4_}ja-!o'74,~maCe- II zoG|mäI>!II #Bx$%=ˡ")*ty$$NFjT81p=dD H$s"9H3"H$Q$1{6.4&' Z>cc 7q$u *^ul"5%Qs<1Fܿk4uRC!q@pB*֏(2#|071Kұti:Җ$ca\fnTDy##F3zni*::u*$AHDR4|1.M3LuO[SuCX(ܱwF95";lq*\]/>ɆɈt\HS))Kp#T7C@U↋ lU7ÈeV`Fh#R.@tQxidΑkF/B3/ljEDRWWJQbs=^udB}BM)lu y ->},T5e8c0\Lʀx͇*-EZ4\"  W58>x 1VUASr#z9SC uI4|GtȦ&.BڢL8<F"8#h$GLQPQHH[P15z \ykf8Sӱ0hl{\vB(RR#|k$;QxGYH$Q$BS!h{ ȾZ]qw,\i6>ƔN4Sc#!#p;bޟ*cb:| 2)uOAFOs*7,LLb:GRB.W`Cҡ0e{Tӆ''2.": )!Mׄ{y? %ZL?Sʅ̡ctb#tL`Zj"ҡ+O3XH,ɹz]# ){`/`krB-FmH"@ NL7C 4Сrt9 &0FԳ ˭ !a]5Ib0[(+/G$9 b~,uk&0 U_G#*& sf"hzyA?|KS7}DWUezc% 1kwƿ;LT,ƒ)p>K0K j|tӡ%Xp>SGwJş??u1+5׈ $A"I"i:x#:^:9%{s$EԶc(,-b=F,Dӏر̙'*hCDh_nZL`?-*Ip2iiNTOݏ1'B|'2^c#6Vaũmy- b}zd_uV5,JA0EN8fms.Y-5\?F w!pA繳6oI8Ij\I/x>G ˯dpň1 xQHcXes.Rxi4cb>/h6}%4rBR"H0m"!alLi? ዗`d:L%Kb0{+\]>C ; I7j4}ð0-|r”/BwdnK"I.X|B8vtpSx/@O (LqwffhnxkpKeR a`#b!Ól_17i(~l|?\BZ44j+ !=2dS^H:-iE!b!eH3#@uS/[KfD>8HR!Oan")mptв,8hʼn6_T$%パT09kX,40YW`H́i1H[wzD^R5,dz2%!u]z㜞gҥzx8.${G"-9{"2JOۚ#pOdL Ӓ4_;=lذ~!H$d7rsnn+Qvt)$g_5ꊰ FczmybQ$.՜F^${>U$8\ӟtBԱZh7>t/D4_.@C/")EZw2\<3q??W4`3BS ?%Tjk[@c Į,nFb>xk7|G]e:DrFsJ"x)gOxz2 cD_vD#Gc$(R=#@~kXɴbqz #cnDru~#Gm/c#-!ĝk8D,biaf9rK5@ x>(P3I^b7"'|Qq)!5Sk"ulHO\*.,D FW݃8y2#F$YHa,LBdl:]YI/>Σ]i ːE|uwux|sE 1KWHi!ZUQ3;\WK&2Na-K˘$`ù>Y&Dҁp2jOImd6m u 9H+Es'f!ҭa١7}f +@m$Yk' ?һË$vĘD H$"YE6Iǃ2ǸyhDIsm{jtLol `gqtV"Wf=n1~pjB효]kL4p&O*1, S0X^3Lj/z`ED+d< K> ?aa'->t&dE0y \{MifAh^!JOQw A[`|һ8$IRCZq!|m !ӱM$:m%Jډ)'o>=ZsO#9$#3ŵGX~ɥѰ1{N{'d ܜ7 D, AJ c=!"D1c=9HOFd?:LN#8GR~"A$! ܝ]; 9Ie01f`b6ƱsNvJ%일[E =gF˕YAWxI|& .puY֑H~tܘ ls) ?b9߁ؤbwY%d>&3G$!u\6r&`BXGզg%cqFv1^HiH󁢷yhdAr~8\ 9G ylz' gg!cl"F }|oiRN&"\{ _L' gb!/Yk4de`" 7=y8|X/,ΰ|ldKX"i,I"I$F$ c,: H_s%#ƌҥS`2Ⴣ18_%{1SDavvF8\zWSrI"I$$2 /U@Ǖ"d4,H.;kBSWn/7Ss>{O$D H$I$ .1&&tjS$A"I"ID:v碥"'':AHH|v.]PZt ׏ѽ{wt֍ҏ H$I$ h|e^_&H" DD  DD  DD   L'  $$  $$  $$ $"T$$  H$  II  [oUĭ$AAH߿oVSZ$m1T "iccSu5J^$y1| (  H$I$ann,H$  $lcPٳgq*,2*z$˶`!ՃD  :z)%z$[)p2nf7+u$f DgoB,؉ЛI8D$AAHH֞lsq9F#pj'΀`ox{K񂣕Y~6ޱpaܮ`z~ Y[4D'py)a5 *cy3I2 JԿmgkbK%;aM"IA$$#٨H@ (b{I ]kRHӄcf21x'J9\D=:85F/9u)f*Y8Vp:9|ܗD  H$I$[+=zavntEvj2b""cz4-0zx F`P$?GڻXֳcI=Fm%T4ʪT뺼E oOD?1?O9?=_ߨDU|d2RF &6Yc"}sF"::8XPe& %ⷶ  K#AAсxiD  xy!$  H$  I  D   $$  :HvMp&Թ{T>^EC\mY< V+_.ڵ DPP _߀R ^T# sSytC1t( &O#>\,y#S_ 豳#:|yϗ*ċ*cv}6߻08!âH4>4I: JyO1Q ڻċڹPmhH̀O3>^*仩RtNoL$|Y#dS۹ k[noQݮ-CA$!^x7^EwDkw/H}EP(D'=VD{1(= c<&G_3pu3e8Pݮ鑌WmtKŸ6?FẄ́}Y>H$ b8}T?Λ/v~H[ ;ge &]{1N$ kU@?_N4nkL$ga.Hd#}}c"K)\.p(="y\,y~m)㧫PUw W<vDym(~Œ!JYa9,j>(IC{. 0|~ 7y¡hk !~448\AtlۭO%RdNw˗ieehHx h5&دM~iID;B{gϞS1Ṃ;>CzH[܀38>Lpx/6OQA߁ ^P3THQCT"dn?9\/H*Ep7M$;0)쀌]NυDD _$lCRIm:h??NA[e-6͌w(1po!_>R7 l0G"kn^R uynكb%}k=3X|taT@|t"9`67L9zQ)7m)v_+!LhARDrm+j9gP3ضd31n\,߶+G]ZDX0*UJy= 䧃M sxqeQ nL~f"ydطCH:=2FA$kfwQKToI٭Oc٧RűbjV2O;kQLV=ۼ _oU;y#K ^kU3+ % _\*CUE>l\Sae|TTҺ xuY/2 aΑGPV_W}i֩D/ B: \R5%wu:\1N:u3r<WQt'GA)'N!$ k]E=M<ǹ멨Y_(*,A]8w 㩚Ce ʽҨF$O EHJIsx ܌U r9z]7x]ҡ C1ᇋQi){}30H, ʖ=3wN.A%FYlcB %qj$ qlHnԍb}Obpפq)zS9n!:"]*q[*H$%[߰xo2yuR-}:ky*Z6XS+TE;B⍌/O;E(SkYBQa%~F%~wk [s{Ց>p-~^ J B7wU1"s06F鷹HD׹FE \q8=_-aK.A %1 36C~?}*r.}9}w쾩w}%"pRya54 9" )vB\^DGVL؄8$e.2,iDeC8w&N5#8ǞP%f|LʘG2$K.ןC9K_ qL wsAܔ`WMA$CY8ʑ.pRc1b4r߷2R_2Q.šSԜi;H)t4ƏCLHTj\DCP,7棠49Hrw`լ_X? N%—33p'j?ۑٍ, 4^#d}w EO"y~bVe-U(ۗ~/Hؘhf,>Vfoۚ_vsd$'"qD,; Y|$ۍݏ5ۼ 'V)5#ƃpX[me +qIcٱaNĎ*<=0>&qeU(a"ϮHnONC}wFh4>:H;CeaJL *{ ξF0ΕX{\.tPgUZpW|=@ Cq2 >`ars/ &Tqv8۴H*V\zVe8DE+M>̛\!$ժsNs?ɮER W|lH*"WᆶRj]wI$BTHl^sI3b>; wOmç"hj[WSFd ?2=~B$KoygX;\CWNzD eez>mDH/H$R?-6I~h]E2qp yiL0 PnD2$, }ZkGW{ӷ6SMCb8NH^Ẍ́D\#\A>pIބ|m)8;Z^`V_OciRM31UHaXue72>L,h/FH񃋭?y(RTxB_/{\-~xHp{g5yI>žC%uQ>| n8>zA͉Jv[E2)PmbN8ewaN zLVG/H \fMEC8:ggj2_8D(?nE1NI' Vkg䫪PziF:˚PFL-7BcFbH p1ָ\7h.Vpe DbȰX,9U 2m(]aPؘllNRed?aScqz9*Cc3Wvn/ |M @At4U~gv6ӻ n vTɮL8W_1XwÓ_bRBBC1v?=R}|uχ{_Cu c㶦u[/"*3٦}q(O^뙀갼q/Sq 9pg]6ޑLp׶#sO!4{"ٓEO#pC#lE?C_&/*r@RХWDʰƞNpegZ$eWF¾)רNJ"oeDMŖG,&o;*-,cO/H|\vڲ#cdLZ%܀H&㰚ÙyiRW$kpY2ʰkB1]꜃>r!`?~/+Ҽ6T$ױ"Y/><$gbxx})N$_^:b.ipkpG"It>`ٯckrDЩ.bY`8ũ% C"Pnظi  7Va36Bג|6."|hW:)vZ!}'|"kkfbd"-7 BX7ذm28ȞJ' 66>)e]pb -o42e"́mnd=ML~J%*//GrD9[9; fu48jRbb5i ;n^RS0:}"؊/2<5**o)rQ-loX86Ƭoax<8r,&M.$2)ފ$lЪnqSҢ`}\G>ɖù,3Z'66A.6|P+;`|"FG(ӋD=T3/q񩘔=m`R O`1,O1zp`7cFD ,|R?=B}l)oBlcUW',񬜎F(/ȇ,e mDV Ƃ*hN;-2o:77s>a7ː? cΫ(qzX!Lu3ґH W2}K# sz%ߓiXlFU5b&&MFLL['AP b#Y CKB$6u_II . uuqu LZ;^k\:8H_QU~ /7m1r.^}7 "W}k|%>EW\1|ub -zr0ls8te*<ο ^7VJSDzdw8 WTв~`؅L#y(RqДDž Cn2/-؉38u_-D봁CH&}誠)/­6si^2b7Sw\BA9~lRd^leYRI9|Q lRF*|8e/SY"Xc!S6- :MJ n8 e5n~;@ikr~1*4:v|)_ڋilߚ`%36b8FO\~Ɍ0}Dt")gw&K*m?a\1y^p{t=$Sfci &duqݶ"{WVc7z4'H5c2m&mD}HYHDa9Qሊ3k=mڥ!AH$5La8Og˾m$CHx)(KW ۬< fm(1%dWHZ2lZ">>>"::4?(A,7af30L>I*DkhDGnVy G9^yiB\PɮGc"i^'Dўe :HR;uAØ'fI{A}.]Q}%:|yϗ*ċ*cv}݌!P8MO+>kHZ .h!I [wͅ5W$uݻ 5|eAhk-K9?(`P}OCi吳 -~ nowQ$_7wz 6uUTwQ>ϛrAw# sSeI_{ZqjD "+8`o 5׍E303$?KAAD@I7"?"zDR(9$AADIbDoHfm3I$  :HJglkHU"3 7)Q  :H6hh1Gt$$AADIHD?zmSIHAAt.4~t_Dߓ=I)JT  N##)y?R/Mo$AAK$H鰶t =Iqx[͛IJT  N#'gk[6C?Fۦz%I$  :H6!y^I~\%*AADw#MF*&ƽ,B'1Sl\ pވ AADb_R7}NK|4gkYpWWo^IqnM}I3a:xos1 %Þpb83\ 7wF#<  faSrYp2є+8]O"P-FM;+]Ot۔LZ UZ ?m--C!D, S AA,}J,G8 NM&8p3%!mSC'^ɿ qKe.Kz'Hz(\Q0E$  ZR" DqL#4]ItHFEҸWR~]"dWa&{CނlD.E%  h=6ad=ý'8]WDK"K{#"GIdSd-a;IQ($T4Ɗ  hJ>%}4仒kDC_-6%7%CݢP=To$bp!"  )8J}<=@CoJ&֘HqHw#dR|gR;) [!oQ* ')$)AA"J\J|D!$)߉O"$#A _%PH*NRKQ0JD  h;DHzEy%3^ȿ6 R/2)3D(.׍ #-d6AA"LԽm$oD _5z'R*bo?/k"7JIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_general.png000066400000000000000000001537501477034762000250550ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:11:51 CESTTB&IDATx\پ{>/ϻw3{{3buMA HP2H%Gut131̘s*"*(dh耿WM7`B|VWתB??W?IWs[hAAB۫Υ0wW3 4B'ݱSL u#_E/<ſAA]Bۧ-bK*;J}2iDj v#_57oAAD;y߭4ŗM\RR[(v6$M\KJ~12٩DjBj@jRȗx>}SAAJƧ4~GK65ɗJMOPjz({';I$ $3\G2*9kq.AA]3jG[ɑav8Pj{' ɤQD~vd'?}0`lРA/  s3h՘1wnoLHlI9|W^H=:Oә> ;9SSS&&&ի  s3h՘1w>/c.9{'ULL7R["5s"%ǯ_ry/GDAtԽI9Jik^/,qwZZ#t2_9dkowp6s5%%4MAasOԯcz%uFj啶  [mff|ŏ3; p?Ov+*H6t'ܡ # +---acc)L,oow8v@!nMdH7^o_z#iTSAAgHC ;鉟~iҨvhJ+JmԿ2  anne5R$evJj[EOo$\´Z  ѝH]=Fzdv@]-i7Y[ Z `b,Z81&DDj04g9s?͕;%m4HHpI%Qz; p@{(/%#WH\.AS=, C1#} kB^aԷ-1}O=zM8q $BSFIyr~~f=$M )^g$٣'xzK JĮjN5q$$}x)L>6ۦO& H-.hv#u kq2 `ܫoj$7GaP/Ͷ^I݇r &1O1>AXQ؀Ƨz>5S7cHp*~I`8m4466bٝ~ KӀH^R;`=ۚwJkX{$AkKШ&HOaf^O,z#UNM ;fBPYWڊG~h%& 5UY?å;QZ^*k30UR ~FڌwJQ]WǸ{8OA?>gOn4sܹM(wn(C}M9.< KwxP[GAP_#oɻP]ˮ(~c5hFwǼ5ؓl_$ ^OoF,+ŨV1]HKN=<d <gx?OH/ $#F9t]R , TxUdR ѭ͎!+DiUw7O$)Ϫz55F/s"{W/vIRjkv'a2 3jOtlྷ v$Z+{;\/ܪqbG<.DYp=#T~_/$:۷qW4|=l2*gwxGKe z:lN4l( $CPwWIE m/IHRnjÜ2e$AWc:Npjqp 6ZbJH`ոЄuS Lzvæh'7u0Τ$Cα*NQC~f8 )8UxMQDkh0 G%t!+EQ `M:I͹%sDK6 }>녾}DclcClKs8BY#wl6 LOa4zz{/-./$U%Rg5Ýe -hvBy"_h:GZHql@[YbGhT^S>ٰ.$2)"ۣ(jlVRsINVIظ%$AlGEEѠ2h&Zǐe oSe/YĴq 2 [$%PIۓE2jrI5l_pL^V8Rˆޯk2DcbowZiR%U0߻e6DRnoMHj3BV$AtVɄ6DD߫p-D<h_l>pyNʻhl" "ib0 Y8_'QΫ%[#{퇶rGؓ펁jgi'FSմܯD|'&l~ʡ;:=Hϸm| F]O/`mWߦ{Y+s6A􉤕5 n>br+D e$A|z NZհR+.,ģr’3愒H177Dc"WI >,L$nEmj+ljJH$ {VϤ=C${wּCR@"IAѳLr1s".ՎS$F"IA~^ ^ZΤ}f?(%HAA|t"HAAU$6$AA-~oD  x"9D  A$AA[IKI  V$-_H~'   >|^HAAć$AAA"IAAHAA$AA$$AAA"IAAHAA$AA$AAA"I"IAAHUz^z?? zNӧ_~>3XX̨]!_ɷ=<<ÇASX]?\)4꯾}̌.ƕŌŎ*b%|˰(1ް#:MW zϨ]>_ɷ X,&QQ/6EWbGHdT8 iP/"DUK8&$s8ED啇Fh#..N3WWW,$G֖ Galϛ>xaHOO{Wcz$_wٹ 4 nNy9~=9 HLL J/ # #̀wxH<=HD/JLzzzrNF`LXHXuMߎ~tEΪXH{g啉axxxgرLH`dp/$rl‘L EՅX= n қeE""5.TUL?wu ј 4syЂR虃e5]}l}⢬&;'V7jd-md*{^-}[#/s,-Yt}p{)s3ěhjM >fZrWQ׬\R+Ìg ҦJ<86=l1p*<by! G4~3 "S/F@As]I[^yGxTۈ (°)P-yGe2?5`E,&ՒW|w& k,ݳPC"׫OP,CSe.^.$[]2XD.!HCHM;i g0N"/qV7ˌD$eƚS%9!zmqJye3gp5m}٫t?9q– a(We ^7 9>!qX}Ŕ1>Ar6'1fyz!0br31C3{_= BQµB $"aCyCV^2F8q?b&bbL|=o4nߞ+ge 7_)B ֏5GHJQ9 x˰57lm5[tCr_Hz!۩HpƌsMړudS[dބcYvmhcာHOMqهPU_: }OgbPWfbf4g}")1J /b}"v򳡓XvLU^׾p&=^EsEeEb{RnE.~+dXjz8z=a]-A$md%!0G2/ qBG'!71 1djh[HNB6㎧U%x^TI]}GmߥU}H lW:];՝ "?̻(Al Q.i;ؚ>CJEUD|Kޡ~G"dMP$'G#774e0Ylnqln/'}O-~mg$䥇Z`qYyH er*kh*r`ѐ0qM1b{0"99qbXdM wOJx eE[d/{tk3a)62dMnO's1t@7ErxRق R%]GzbyM2^&8;wPsc7??}^}zW=CE} dgf*+I")W d;DR pF_]KU2tOm_KK76Rèi<9"U\[{9N=":6]kdӯ2L>r2b1j)`>9k#? SC9%BL. ^ bLF2Y\*DĤnvƊM |{Km s qgwųFN~"*h E6%KD"dt,)'C\nU"q+Yg!Fئt<^#rr"ym!s"Y-C!'"^zQ+qdXuL$%*TH.ðp16BN$KvK+'Ma@ v OVV6nܨS"Ye8 UaF<IA)E2xd IOU}Ik"EI+^Z! 7 b%?{o:\Gy8Er(sgL9Ή#Nb"y  _[\R^ق; auSs6H_8;+W}(V9qZ$Ee18yM*pIr/hIeygC99\b<#1)7AeSuNt?s$ d _R3lgնe46Q):}k1|Cۮu;?*n(?d}lՅ4z}1w3bw:\ 1|MA'~هNfE![9U Nz MhW̿K+HJp`Xu PxƁ )SNa޽ݐH#DR\䥄Y`H:#)/}DHps.(?sO>d> cX"ty6/kk6l㱵\+C!T&1T󫋐6D1=d9 e:#0zt9' +'R&iI/c53@ʉduω쥍:'\KM,e'MUQ,GHvN='ʿ$qR#%7Jm HJqk_ 읉1wFk PT^湓ȥ9 BZFDauCEq%%L&-Z+,|Tk<"#/}1 1ωPV8D2CU163cǥ/gWC"q^ɍ1mò]N{Q%e'萾}T819[E5lX$Nވ[r) ֆyfas7ىGNmJH]//q8m>Xdg"KFzE!3?C?CYa.WJmk"au6DRW;gmrkEdlW<"ߝ; QÄmm?br>! #|q?Da$EtEUM5Uṟ15H?D?8%bRB@þOP$7 _-]Yݡco 7 PUhzprS BhniBڈbX'%]9d xvh=G"g S ptU|mۍI|}Uu81UuŗǃF\/D8ېDOI{VnZЙ>(rTDط +ްXL)NDds%&C _111ʹvR6ҬQXjH$_W 1~z%~xZ|HI$I$I$ x"I֐SCkN(ab)p7]T^y+e122Rz@6H${HzyyҲGcHdٯ_?}}} 8xQ% I0{*O?ЂŅŇ1Ō=$e=m$>ࠔKF M-ʼnbFyHdDIV]\\`nnNhzn)N3CbG{2F"щ${J@?,>l؂D1<$(v1yORH"Q$떧 @?,>b8Q( aLޓHH(P())v$䇌6~[e;U%N $mF]YvLvHZG`}wh3)HǾF)rSK113mP֟Zb* pMcSG5\FԍGW$){¬xz)WVā褷rT8Wj|וLG evZ4LI .Ō (pKD9Vr.kʯ颺.\]\[8㸤ggQC 8$DyxhEhh|Ũ=@+ m(Cu >l)[LE1~ d3!(+.>T.fqn.E~5'M\Nۅg~pChBcBBJ Ss[gccﴌ`޾K(ʭSbS|Mz]f {D),^KCm#?rT%w$*klI$I$ BdMپBZy-klUBF8阹5, v; ]"~BkƈzHZcǐ)?^DGrBd!/u3i5HZzZ^\Zb6N@&Hט%lciN¸1HJeU8Wɋ_ VVj,-[&h6<X Fa٭F<ەT`?(-+iH #iH*!aѡEH=yaxߚH b4^\I>dBERz BѱvyȈCܝ(qpl5;!)-˘Jtd4DG#>'\iAKy8b0u +J!JU-\3Lk0˧ɋq[c_qfz[9MݍjU|yh죍PlB.Puz˰#жaIBBN{t *&Tsr M925+رbiS-G;ΧH3._G, )'myHE-}*vű\q OM#l]PaHjX Ō34_]I*<ϻ動ʟ9s1 ]=F=f6dV!TsSZ ÿ Y1i*ܗ@le){>Voo*+tﹰӹX EQdu*Z8cO`vc1u+G'gJO^I8&a;w'quQ2N"UVm6X^bs]yb\\ڶk_{^e鋅׹\ 4&ok56\dUjIC$-U- 5^% qU\0򂟐82||"ݛ( d%^4q+ ~˳b_XE\$7 KxͿ YaLGﬧo<,IĎ(d\$mE"-ΑIa1zPQZ3QC XE A1\P#Ǻ/bdm톦-+ʸ*#mUk ⰭRGq10\F^H^}lF{ƈd*n8q>&)(H 04[qzpa !o/﹗|s<-ϑ0mu]$-ڣφ=yMvP/pDj4^ٻ_hz^Ceoل\Qssʮ\ᑼ|.:DBKx5Vy尹,6Em"뿈{~k=ƈ6>D#@9w=%_V9*7PQeD鹧: Dڇ71ZƮfE1EVvjԽ KX$ E?g]&9ZMxc~mWl8yeRKK/Y^)ICΰ$,?re 2 @ɽc;Rճ)Wh-l{H[67n<3b A'{cBvsXq1HZ|2b!W@}.,.;zYb(b\tp)c0.&_@[IydqxD>]vM1UcU%8r Rb!&9CaՑ݌ Gܺ7}ȷHMW6cƆuq{ع &'r E{ ٓ8:ju5Ts<)#AKqD:ҧODc6XZ;ۿ./&ކ2<wN4u]$\+0-WԄ(f ru9v$yC6U !QT1=3I94J<;#|iiAl|{ dv&J9q㐐9)Wm;a\XB1gcC[쑔]²8:c\YfXqJk9)isn҆^3a9(Am B0=튤#\[6c;P3Y •Wc4U?yH,8~BUx oĩiC+#_pw˹먼S|TIpvd24)%ٺEpHτd!^Hd֕=*K ,\QZ.zyKpJRJ.:=m i˧PPIT܇1n8r4>i.!<ΈѓKpy Zs~v0%!9Z^`[-F,_:g+Si*p <$J&cmct')"Eʒ_q9rH*n,MW o_v/ ۆa9w--7ɵII'D"TŌxPP캅ɇ$HD )QHHRH~"kkkHX*A5.N[D>!?/I$xHHHHxA1<$(v$$*/=D1<$(v1yORH"Q;LŇU '!A#{P$MLLMh$b^^^NAyDrС$]I'''eX$AAI6u AA[H$  I  DD  DD  DD   $  H$  II  ID޽ѫW/ &  (7C"~1|p   D=LAA$z   8;C@$YW3l  ;H$?I[[[  7H Cʒ03I; LAlAA"I"XdP'0}"HCG/!+XPAA$jnGBmo;$l-2& MüDR܁CI&m'씁 WFh*݌hKAAXvc&`1:qpaE#eT˰'A% %XDF`OPIa}w~PDfc:4A8ccD+18"6L?~ƜD.őG͐^}6H*"oB"'ND?c19Q\#%2ԟaBvJ#u|7AA=Lٳs}0 Tb}4(*qf+'M݋ʺw6GZ4ρ UvUqeZ,9L8H$5 2~׺"{s"ZWo;N?in$ V7 i*y)AN6fv+0#c5'ܐ Pu>NÜTչte6^kkk.zB ILDb+ t3 娺3&"~78 Maǎ(IP;q&cʤp T_9c1ztTHcDUpSdcunAAtE?le6Ͻ>:| ߑ-T9cW;qI-9zq8~jSK_d9;e*h+?~ 1ui/oL!CCE.,iVmɎZd}D>v9X/$2H⏽ ]K~i+q3I5@.Ks-fW=ÃK%R+qEk)  H$'{$zaeeEAaA"I"IAA",--  8;H$? d MAۀyg}GGG‚  |y޽{O>Lz9AAy ?H$?LLLO  7HI  ېHAA$AA$$AA$$AA$$AAA"IAAHAA$$AA$H~ᇉ~|$ M"JdJ  c*qi3 2G8# epNJ/`cjב/)Ŕ  |E{Mț#ۈ^&S|Jqv#!=7Nx8 ?=[?QL [$ݎ*S3noπi۾"7~؃z$I$I$ D癸 lW <:TKl Ax֚m*&H*Qtf&yK L-p4UyRi>_{j$>~l8"meF}N`R57]<> FY ڂ 4EYXDrTn aĪE o3D|.q747!|;IH7kWY.CCE|,p]ҪFH 4<3lVCܪSެ%aiP|*zC8@.5hIE-&t| .ƍØ!:)ۇ=m9 D/y,  |;DWx&kCƴu?/GcdF7Iw }*>b6=(+Lښؗo$g@pG2]^6S='`|buu9 ?AZ|Z m)k/@`}s4hq"f\ECS.kDE@$X , r:/dž4^8#i=(4ȌPщ$´h'Xo / NASiFrv=r֎4\__2 '}S!1q6wpO2ʹozgFy8BLs-m!ZTVb~@ŝgEu%pe+31\W(}`t\!vLԋu9E8]E.m3}mxm/(ܡDu]Zbbh~|EEa9m3ŋx0p3/`i[)޴o5Y[:#|-Θ^6wAA"ŊހC`FƒX5xt+y9Z{l5yjl -1O57kl;-޳א,2!"#]V¸oF>W.OԽ+1ơ]GaׅV@|Ҫz4+GLxRʅ&i1dmbçj }EIwȇt ],߷ aK۲sWa`2- Dw.`/Cf!Pٹ6mb]½pX. .ԗ`f& /?ZE&H3)OUxΣAu[DΨHciH8`E54Ov@> nn cjFY&!8Ƌd~܄gFEefkq\ X.CvPswxa8O*h-3sTxʆaJt;P$N&_ꟄCmBAZEEyAX]>M`^|9o7+ل h+I Dy4s A$_{$/lVEhc{PBwP_ Y^$xl͇! I.OZs"[p0P2.XtC,. 1+4|K2YA>nIAP7⩺,؈G%iN*xwRQkNӘH"t 4[YҙAHv=F3C 2k5xΈ;W . gS+ռ6Afܻ(}KbsЪꊖ5 nrs*ܖ0 xTHY هc^!A1hTP*JQp+>=N32||@W 4i`xksbrlƂ[YJFݛ;8[A#?`1Z>rHL0! !-%")H}&AA=#y vcƌA? BZBE"K")sR%LXn")I"I"IA$$$AAGg}jXWkwv&{!prr2Ys 6 Nm?}@fNAu%sm9_Cڋyi+;/$/b"bE2d?y1p|e HϨ'o&WƟy2g|7` ~42H~"i VbdD\e8g2󯠡OϘ=FM.LDr<6=eQW/<\}0}B?0[{oK6{^xcRJqAwúUG`eğC!~)[selA*<qkxM^hC Dr:3%O:??lO??w YvKswXcu4I$Jtj^ i@$Xx ʳl &]jD$eӰų.[e'bzp}3©f |YG1RHƭ@Vq54ͺ|q|qrS4l>Hő/b```L}~exC. W7#1ġ@kVІ>Aeo#W#SIǔLLm۶ؾ}mw; H"e$ӨU!0_HJ.Abz(<-Nlj4x["}}{'/\ hH}tlV&EL 5oqv/|"04v\FZP82V${) Haa__5986QaQL"ٹH$ DrE.ZS6a˖-:n݊T$''#::ZGLL f̘X#)) C<$_H2Nk ^$xeujj R!!))EZG81Ce{\ǓUP5hQ7i-ү壢[_ߒaq|I+|u*csN@]}nxľut9<\=2$\V6oش7\r5װhdE:z`uvߝBlRc%Yji+;5Lj0v͗D?B VU+dγ68ZcuK:JqOaI>l/EHIwYWP< IgWߡ!o'vx9/+jiu1H7(yp\"άcpIMH  z54Z8!%1jJ- <s۷=hHa";caz*dTĘ^$T0G;'3lyA6&gX!G<w݂B[szjmcB(иHT暬D$LD_D hi{Yy`([%#0|5l y +̾œs{$ 3K˒ؐKwNדgcpJ_|a ,TK1\jҶd ?nO_[P9LGzei2-haz"cgc9xUQz[Vգ" ᛐyeWR 6k32ոܵmHVDx/Z#Y/$K GL*PiK>ݱ㬷"!>B${'ZNO#񺞃dLQM`o.j5WO!; ܽ !qpe$9I4L_ו!ΰl{ պ S{$%JN#h^#Dv_IjM#dc,/Hķ.?Xﲤy_dDFΞ=ҁ$_Hn?6X PZy܌gfDR:q;^-Z#U`?y'^ijq/`og4FhYbx`3eig1l}Y0RjN\vWOEq\6-kq\ XamB$ fMERv0݌?rа8вX3Nc°@I#M$kI sѾV"i$HnD٣.dT9i=|mԷtxl>߮K]JE[_|;Pٞ" _c#/eR(¶NyY2 *qo'ܗD]oeL'Vi@2e̠Rԭ"i"_6gnci}M$gğWB 68mJ$mL[#m͓~4xmmmP "i"iIueaZ0׽HvWOFEVR *Ȼ/7UhP{>}+(Ք#}Cuq %qU"3$1\k&bl7e 4#l$ɞlɄ0ƑH~Q")PdD7[*`8[% @dr:s(:C͖$DYo&,[Sdj둣Rx5 ?0&g>KC{?HĎYmU6Δ#0,A003 ]/7hN/Zg$Ayh WBaIqT;1;`2<==}FDd7"mēn \ojt.!uqRAkm͓-xR׏<<~]Om⊂CH}I0x 4iqfy$员_E8ctlY9_VX66"|#3S˛*o Ǧ% V)G=ǡ"F{ \g EDAZL|SKW f)$oeVˠ_f\{]u3%Rי8pJN NYp@nNFkq1q0d&N,47ՠmڳC;, >A1h֨u nml˖'ֽ~G 寐7uJ\+J!FUʗqR Z'dWT{m&Aڥ uJ堜@Ѫ:k%_!q.Qʂl_#`؂eעnV6^[(Zav#*hnYQ# 0xxU'_Q,d CT\-ֽ2iQ,U6iD=emnʹ_(v{!xIys gkŋ0F^ꌐEJܹs!vv3yݞGt&[#p~A [m^ҿȲԟo/_n#k0j8ݬdw"yLLLD?h@"ňe!Rl % &H|e?S3H~ /^$uvvvF"k_R8OH iH~@x! I`РA:t(lll> BZBB$A$  >?K'vF~J44I$I$ f-5S*$$$ `H$I$  H$I$  H$I$  H$I$  H$I$  ɮ899HAA@$"$$  $$  "@"IAD2 ?`  $xd'iHAAc $LYY߼HAAI  D   $$  $$  $$  H$  I  DD  DIb6ƒiv_g~' DI8WZ X_{  bDFCZh w[F"IAA"ib :5Ux$AAdDl“:^ tf?R% yYwF1f*p!I'j6B03>`_ߤƒգ4WX9{f ( 3W⏗*p^/iP! ( q>p%gTx}f M߬NAZ t  H$?@$E$Erv3gI0*48ombig poeo7\Fbt0 q:Ӌf_6j'Hg0z}.:vMU\lqZY t  H${,̨5x*I)4j'nTgkcz!3~3  eMYgsnưO)mD)P*JQԂ:DEl G5K0X1O57kl;-޳אX v  H${$LZCZ70:Njyٚ1f4粨LM_guK赼6"/'OrؐڜHciR ܋DRTCdcf`80  D"iC,<*p/(JLSv"bb ^|X G2h= Tm,,nI[=I[=xKۺ5d!El>-?AA"i;csc:8RBf]Vq}x(bpZ&;&A*)c{(xQM=>ﴨ}tg/щ'6$*PBsm׳0AA$Jp16[Zˈ=V ]FW Z@1X1pv!*m3TL$uݗUi:f g6\zrZMo m ĭkQ  H$  H$I$  H$I$  H$I$  I  DD  D򳉤-ё  i#H !?  0K7 p$-"iUAAI'IaD  rDD  DCERDJ"IAaH D"I"IAA"I"IAA"I"IAA"I"IAA"I"IAA"I"I"ٙ}B~bvA"I"}"@_D5 IIO#b 6AqM=ADDlQ#"OMP\S vA"I"I A"IP\SO$$Ա4Rl$&IocÆ?o`g_XY;!D/Vgƺi2#"sI$ IOC'"xDcvxH,%*ƹ8ۿHܰ.EՑ XQA"يl2ՠX$2|^lŵ)$؝4h~Ÿ߇šk~nhD .e'åS%3~ j"t$SųM`>ca8!\} % -BMiχL ɘxVPUtB6{iWYl DXĮXyl,;z9{X*:DR2 OGiw{k0k{lBu3؈c>acF(GB&{O('+qy,s%"i=2 Qs2P $o6.('oơH>HJc9#C>3wadk$kI$CT>g =VyݘKXU{3DR8Q2NmH$]H~"i52;|F"=S[b%P?QLHjÃU8hǣOdY"?28݀1HJ_EFzTⱒ.")%*5 .AXtw%Kk+@i5]-/pyb,yԨ~y] iU'U%]7IHSYPz~ ;\!~'p- ;M!.-Eb ދˏ𮁃~q!yl[Be3:aq9/NFEK?*e\1N﫟=g!T%rRiM5d~[? Y*- N#xPXZ M[ੋYx;p /**^^?f2ENp5Aoe ɤxž6/ƄHgsPݤ!N-o5e;/ ")%Y(;1q_ȒHR "E2Z[ʪxiIQh^A_Sx fÙW*4n^s apضHr(Lq0nXV8l.Evřpwd$xݝ mAWޅQ"vA :H2+o,@kyZbt:wi >/~~rĦ\ᅠ9tf!HZID; ݦʣ:Dxkj(#=a/n{Yp\]E>H>V5M/1ϒ3 j#"p62|7mu1wДBIj3F鏈`t͹:XA3ߚHs Z|?r_E h=D|HAR#pzf䑌Hڋ鉶z ۋIH]-q<k/S:ID2")İD$/I$]H~"iOsH2!O/j+:>Ȭ o˄.vaDA(4Jjx8u,dP)DZPGKʱ^ ld^Y u?\m;${Krx&2=(J b}YmK̀$dYX8dH]8]E.탟u~SYuqHϷƒ魥mF/Zss׹E"i|i%gre=um߂HZ!RRk' vB8o>:RJ `ҧ,[hetI,dU*s")l3c$yUP]J{HR rER >ngc(jG 6| $^m(4xs3b=| lfQQ"H,\T \W:8{S{$Q_W 31WM3pLuU]Dī,áUpG}'>)wP-Uv:B=2޲4NҶePZ m%B DfFTE)5=S3thP?v;o㝘> GõmǾՄH/VkQ|tvj'nv%$H$"`\Jw6Xڞ%r (v2ʊVfOjt3v2* lkTjʐ>̩m;8MKz5^ T2/As)XHc7e_V#چDW;)?ؕA8D5j-Ү3]c*xwjeӫ'6ٞ" "و̘4lSP^7>._7>] u^:P|s{$I;RM9۵mjPq(.m?IXP,>M"IH~g"Bݽ?ѫRUVL:|¦O^S 4%?MK':HS^+{Ht!1?aەp"EJP>؋9A"JNh,VޭY @&"dTS y;\Lt{N#煘 yP8Wf(U")uGDNi*_V-'I${caF^u QN<(JZ榟1- XWƴH>$#G=h=t3ju׸z-ޜLAV!RŞO*5 vMb%}X|\l8l\ . t' 7>HaPi)0^8M"IH~SvݗmVY_';AJf 5o#cOے"3,.ӂ?{l>dyw> 67k|W29jdSqj HEoŻ&pZ5jKsKn=#iC8Y<\M[ ganD]R7'+™Hz"W\GE= DųegۡbWx y@F~gDqlK0rp]Ni%.0qyT+q)6>7De /X3I!6]E7аWâ=YU]^;+0V|Yh4{-jg(")vwnaoX?ddwO_~>Xoi94*D#"),3!'5QW#8볺ǤQ7g l[qr>$$=IM^DMS[/W{ :xoS$VF3} NMU-2g8Lxz]$;3i'^iܟoW~!9VkT1)-$OTO/XEYt8>HZ!HRB[5s9=s!:!$H~>kq䎍XHHT$d- n'`O")qE+(x EC; KqsV7j-ƽɘкL)ưȯPB@(̓$ꏰא[`Uס$4D :m Q꒾0ϲc]Tۈgs ;;+ty>(CBQA2`A1+pV Mc/@`P$BcU%l2`ܪPT?f:G*Xnzl!r^VBT)HZsKQTWuܿ'rGo9_益w(3GvwƲ|L@?KPyG: FEKJ2GXY!3]v:aRԢf2\Ƿ9!`.JkThը+^]EhJP[:Tx29]9w2υ UP!} N"ɸĉb^@qWyq&Ff;&#}Ti:>㑌S P^ۤ|/d=~rCE /mObQHkcށkxPU)A̟2apsqJͤkn۳(Y I(ƂhUrPd6VمTD 3hi 幧`|N<(ㆅwHbb(knauW7&!&/qsXwk}G!f0bn:n cGZ-784 3nFpl3k\#lNP<ĉSзSL؊Jz$+D 0`V|cmahhE\?xM8͟ D->J-ʏ6B03>`_ߤƒգ{KgAh;1tm7%DNؐFk[p$u2{`ܸq7v$[*cUD"0%;aҸEiޓ gv)D5´h7}%mePo" `n w1/6ӏJ5^+8p|G__م;5VΤ(#@Z#&k["ZvO!9ށp  j-L@ l<\]:y3FPa}s ƞBe=_RegJ$p[cscoӱ?Bx&ȑߎ sĂ|ت/FG[EagI}hP7;Epyqƌg!Č >oBdPFR^b[]5)^*5hT&+𚆰an۽F\tw!5a:'`kV9Hɴ { +=mg lEf5LU7n/k=>! ]xUGk2 B|clLcbdxb*h#v~{B݈E\H"8 ER󒝏A-4LdΞ @̕CKA*$}̔}gl;NciGbEkpb5@K4h29$C!+%~|;\{%f w}>:M"{$g",8b _+19UPzƖwăU.gaz}oӷ vLl9#|-B-H0v#Mא4A1\W(=[9/@X pqMץN)+efY0dTsy~i(g e\Jw5q6BA±6]m Ԫx'߃mS(r/>{+flĮegZ$ <*anmY)XY6|iߣYV+{4=OC@dѡ~Z۽,rշcnۿ1}2вo{nCF^lO5sS=[458m: U2/mwnҩP?إOo]0iPvЏUsj&rFfy[&dXmIŧ5~3i8;f/)ǎ&T3P~dF@ ǗXҶ14;D ّkrg"Z?&gPӾJ?ϻ̷K ɅJEYwInH>މՂp8{i[LcT0g%WrisIIxy gGaׅV@|Ҫz4+G{$%~8X"/ee}4Vam"eӵ3e0jmXE:[gQȡxHt|Bòz  NYbR ~AfRQ;ǵGpNaQ46c\$Ƿ|18n㝲5a9a2]Sh]YRv6Fupf,I,<8Rŵ@-Bm}Pi``+8s6dPJpzcbFCU#B$w 6/3"#Ba 4&K?^$=9@z0YtC=۝ D'EpyH6{lvK>۲Hl}ζ1xVfc A ⛞(;߾V74۞OY 11H$0mOTJ%TOۦ۲ti6/_}S3~,}qk ydH/6 $h*;ջ(rxq8_7iD"Kq +^Eš@Xu'Ss@|t5Su,wY[$ΘHn~f|MT3%nXKPlT{viiYQM̘q V o1-\E_*>;<["tw+=qԺU=/א,j-XN>oKTzIzD"I"ً"qqTk RLe AH^' $3@\ERk7rqAfNHj|w\! wX%/%=I1ҥR!b]ͪ :}^ԭ"x"C}Eu z߿{g˽}I CQ;i vƮQDc/$&v'*b`"Ls8 CP߼^]93g9SUuHf^nNd]v;o־5iPeDˣ6-MC8k Ӱnh/$z ֥qW6I8`oϫg X2-ouyHV*dǐxǾ5>'Y"޴},쇬5ҿ C|cMg_M4éXUWVNo2u_C-vA[Tº?NP|3İuN<<:Tsqpx:; ^P|Ye0m(|Áخ^وqf;)$m%5TU"j @3i!YwH^gU1dՃ!ɐlА}‡]ma?ڲBWUjc&S0k Wa Ƶ^q[c2Bo0/I-4'zzXRdlР N(nkAQ,u~ >nSieMx*Sߩ]a lNWWO:%K5lqgj8MIkS/@8j"@m=h_ĤUא4(YXqpVJDTh0Fc֦K²E%| '!B:z- !@쉙/vNcP&bũ_^[Z5vOAxPbġ_j[W{UxA\a:`x{"Dj*jYؓሚ3(s|~E??SH["v#C+lcG!h(L ":DzP.o}:{DWcBd0#1vT;ٖ^ &13Ao8E4$K*;j϶[46_~{0m埥|fEjf@کپ$;i.@/^]鸶!]%GN߽fCS#q2`:G}/D}ޒm Q̛m\o6Vqh9N O{qyۮ{\@V/\Y ɪ{iJDyxLqw_O]KkB;w_7@=\I 8sNvNNPe~HtTB\BU; '$/+黪ibןFZV1tzhs&g=7 KŚIM-UzTS8}ן@ I$C \*V- ~]+ƈ*],7cH2$oxedr ־ߦo-y;7q Sd w>qWkC!IDDD1$DDDD eh&^ASėjŶBf/nuqps"pl0,_hO;.0$;?,kߎS4& ׌UxٗpT˫g*]/.;A;N>0 """dS It;O"@Vܧq~d%v~ J80>]m&Wf_[L=݋ 0-!# NHȃV!Ǹ2gƓ RjյkŮ N!S_k;0+.X+v6fhbDGHCOC0e& AP|v<ڒḓpM׌ Wo5I}l U6! v7Do;EH),^hۡ?V,Ƴ}1kJemik3$Mbɶߊk:rUEJU݄ sٵMǧc\\ ]*C~J {G׮ū]evWx}Ⓨ8X/+beӶr Ϊ48?ͩ|-VcJ,.@`9ev[w g߯(~ ,1y=#;Yΐ$""bH6;8m|"UgۆdH1$IH~F}}5BU<=î. CVj_GTbsMЗDl7 r]]t]H{s$l 'tZ"!yk9| !Zvu>װk ,Ʃ)N~nxaUΐ$""bH6þobFhT>6 .[Qpuƅ!lTD7%=Gm%{<Ѿ‰IagDWmT ňH$ߍ_af2LCs'!rhQKOqZd{Rs$;t /.p_A7}]nOh0=ݦG>Daxp&&B3#/l kB UILv3ဟG~DDD ɦNcWWH|+F0mZc*NρJCQMl68F;ޫhj=u#:U>=Fl{]YL%{q(6No 6px*>}CaI-B eC}u<%CӚ6W[>Gn|) 1; x^^g1JpuWyv –GZd};?T:5C!,6m(]cq Guvh(sDDD Idg٘S],7w\ԤD_;7DDD Idf@n(~n-&k"""$C!ɐ$"""bH2$ I""""bH2$ I""""dI\ΐ$"""CHĐdH1$DDDD ɷ I""":O IAΝѾ}{|GCDDDD։$vCҢEjZx$H$I""""j I""""bHC!IDDDĐdH1$DDDDĐ$""""$1$DDDD |1v&خa> u}7'ݖ,1$|H'Fc ;%ZS}"hshn.Eo;NDDDĐ|K!i}'bTdhת6 I""""d1(J;Ię+}U,mDDDD * ڊgl o_u0vMq'u!^=L!G4pO 4ex7 S =Dz/ͳj[UHǨU8zrJ(xr  'h"""bH6HHv %zd6oc끩s{qE#dD8bɼFRS:!s ڻߴYܶ["TE6A + EÁ5Xz''rBFa֦KxY}dס<{.M7~>d'2u6c $m]1 9`o^iITP9JCDt3l}^ cH\}$,ǯgV+ƟPuNךsǼ+ŘN4\H ǞRӿQCCHsM&:|+W]Hz-/Ll.[TCwKx{KBzB8;WIަܛGƮxxY 8QC1BRDTp{:7=?î.ov[]YLfkuX킶hqvoUvՇ1lvǧk!hGm}߮ 1ةX}*Z#l Ѯ7%=vO`6'(Qa ybƹ\賯`۬X BH&+IQR0=:A0cB ]a2V{ {DWcBd0#1vT;r&"""dCd,F/ĊQ=Q;ޫhj=u#:*$ '5Be?`k~}0nIi|ꂗxpׂ@6h]}zm1!y_GGcȿښNg O^7b'j"""bH6֦m""""bHC!IDDDĐdH1$DDDDĐ$""""d]Csΰ\.7dDDDD$0H%̐#}裏 #{I&q%Cj"""N&q5-C!)C!IDDDĐ|Ӑw"eH>$~bH2$ I""""$C!ɐ$"""bH2$ 7֭[>0 9M6 ɷZ2Ϟ=~5KbˈM#v!!)V8½HDDDԬM#8 FIT*~ĶK1$j`NtDDD[! C-tpp """Mɖg cQzDC?z K ش~ 8rF#""bH2$}Bx^^Ê!7| ūo\m| Y[1,GoHND8)Iۆ!B@5^~ 9OSq GIHی1ݟ!IDDD 1Q1qJ*}RքBnqzrB©(M!9ީRbOw`c"""jĶaH^^9Uɧ=;C(Ц`Kpg()|{'b17(F*wO !Yljg\w GCQuH*WI;Cd>} )bH&/BVocq(yƢc1$Q@ 'Z8  ǔaۉ68D"4$5~< BR6Οѱc1w{ y6!9\,\;caBBgaM!T}`Gqrx?v1&F#a*_JFDDDMθqpJWumM1$}(E PXx+!m} k01SS* ɬobhNAwo=9TIǨԦb`Unc#l`xS4P%/@ဠ6m3$gLV 2W\] $`#&ű[œ*,W2,4Y~KA:2z61jqo08DDD)" $%!:sMۉp~V&4t9Fc?#7#U+i".x0 d4BH 7h(ˆ'G%WUny%!$S|xE{eBRQ Br;,^5i|mnǐl!)sGĖ4OkwCKf I?@]vJ$.>$"hSWc%8:^iv^Կ¡qYϿ$/S$QK|!)>v׮]%0xxL0G-gU(\퍷UBR2tĄ31:,ÐydagAk){f":x %Мd"!j$FL²wP =a/>/ 8VGơ逮Xv+ع`<#"3n6>8r밇먝xQяk0->##G_@'&""߂CACctBRORqza!iW3.EiyppI(fA\KK '9|_ơXHr(腿.ʲ9#p񏸗S33 qi6s\bhZz e۵UP+AH72hDDD IdB]t!"""Mۆ!ɐ$"""bH6ݻ7:wLDDD C-':"""ۆ!B߇ ѩS'"""fMlmaH6rHnmڴ1^z 9[FlmaH6rHZjevq8DDDD͙4uHd=C%cH2$ I""""$C!ɐ$"""bH2$!Y\.gH!$~bH2$ I""""[ I{{{$QBR'sh߾=>#È!""""^!iQ"q5H<de}${I\ W͇$5$1$!ɐ$"""bH2$ I""""bHC I""""$C!ɐ$""""$1$!ɐ$"""bH2$ I""""bHCoC!IDDDĐdH1$DDDDĐ$""""$C!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""$CDDDDĐdH1$DDDD I$1$!IDDDD I$C!IDDDĐdHCDDDDĐdH1$DDDD I$1$!IDDDD I$C!IDDDĐdHC I""""$C!ɐ$"""bH2$!IDDDD I$C!IDDDĐdH1$DDDDĐ$""""$C!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""bHC I""""$C!ɐ$""""$1$!ɐ$"""bH2$ I""""bHCoC!IDDDĐdH1$DDDDĐ$""""$C!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""ds I""""j:MH~GDDDDԄ4$"""!IDDDD I""""bHC I""""j*!ٺuk|&}?|@w讆5CRV@-PmHr\QcMcDMeduӱ`l_lH35շAzuLg~? i=a{BPvko&3$1$ߐ|[GQ 쁰9q86FaK2CvU-lûgNp$D"lV*0(_nfJhQg;Tc3)"Q2$D~ Jh;>}+=K?Y=.}B\0d^<΃F_G2JsHJdST:L3wU"|Kӡ,bN܎3]^[g_|=|bM1^ĺ>TXz1s%JFd=-l5n|hЩrnL\Ax%/VžqV@o0*Exz[)d_]@Z Uv:S҅qTbe!)M3q~ڗ;ʩw\5C ]ÿ\~ V4|7G/7(F*wO dIz ӳ q-Evb0 ̝?}*«X0ȡRH:#OUxu`HR ofWie_W K3hn =lQZ9l)~=EgE+;|em_BZ',JYlW!k}@&Ց;f!ފ tH[3 gR1>"I_!9[UCIIr !eA1x`7ɅaC:N믨^ ^anD?~1qщru/qlrop^m w2} W1A 3ZACHCiX_bs[?cFE"f:\*ʀjc|܅L&A[!,@Qx s1fl8ZE}?p7B41{׭` =~Qc+xLIn4T5mY.JgDBt ƘwIc"n|nzCְ0 ՟BIs8Fǎ)y~eaa\貒m8D =ӫ?&–T| ptP4FBxzk@c[X1&'/U/rHD[²P%/ /~qш=k<*>g fޮҲCGwqfȰ}x^~}K+n[XS?'碷Rdnz> 5ܷޯ&qCR^Qw>T4/@t"ð\~q2?w!o Iqc@Wh OcF/yo=]Or/$u T4ߧ<>\p W_W nI?BPeupSpyL{b|hEwyTcT &30ù:<1.e hj!YiIxp·c!yc5nڮ.$-qH>Ζq2m)&neU颚yi5ԧX_WYHH:=ia(G]&V45W{ YD2$䩪Br!ʷ;) IEŸ _aYgu>{y>Ck*ǃY&Ʊ 0Yxg1zH*m&vE*k7"]}q^wI% FpYMac5B>"tJ$yON#-g-ą|me߄8v>2s QY·`O)ÐwWi44 ~v ZՏH&"$KQXPҼS%dHRsIMiش-m\5dj.`x"*bVq !$(°w"|U7orYSyCë^ZEvtM:!=~.Z8[X^I؟SgaMۇC-fqɱ_P|;лޯ:8{!V]C!`!.l^aAW3>1S3FlI ߔde4h NbgBYI{Nh{8j.DwYކ[S~C 3qD7f6 s[^됌jBR}ΪO8\B7㾮G9b>mUzDZ.L& LҐ\#,̟Qa"Ƨ? 5C/um\*BR^]7 5xhCZ^HvƧ#ܷ\9%`m/ Y|VWhj۵<\4DH^b[9rA|}$ve@M1*ǣ?5ζ3w{Xo~v:Gq~"zd'SݐA׮]͸iRI/w28a"~Lw i@c8DDD#aLlw4a6" or&mj hFpqc^qTf#|k+*R!Q| 1M<0*q1wY{nYl]< q1;y QaknDǖGTD'4w5 CϮv:w,#"7qbdӫ 3m6N(QSs ,Jֆ&q=jű0yL,bcv(8+#3=rS6brpa 7Mk$e8k !`~\Y;5}WZs6dG탨u>!y7n!NXIS1aJl=EEu,zyo>ewpJ/سW6K8k!)N>sG;0;gq3i,@+AN `,eJ\|])J5x~G5M KW% ˾w30[ë-4p2Dx#{Y/D.;+raꍧ~i9+zpRUWxxGlNODs5#jqT"HX;c=H~(zM1r3◭qf#?J˟=R3Q /?`]p/MC.݆cH.VGob(ӫ0OBR!?mkʻX,{ fl sY2{Xן=o:aW#DQːfޮ!p {֛cwO-Z_"o 6X}<LX BFmq6\;B!]ܿzZ5Rġ{6K8{!wIH~\ߐF.]96 ?pfAQ4FB\0UJ A;:s6d?!lJ! ?`d;om6p߶~ KBU?-=%.Ĭ1DpD1ڞ A IbHi sXov8%H!2q޶ABHy6.>`dG'1O& Z ɿJB$$; $${Ν;SS6\(6_.o{_SHri#j !˹[gP!J)$^^^kA95rm1 Ձ8vu ɏLw Zא|b"GNsN1w˹ƙ^Fo?x C7q\Lwo]M-hgjC!&ӍmMwRאlݺ5ڴic zeA}{-{/N>]McDs3oˢÆ00İ30lԺ7 .5VMwjozDZ2|WQS!A=k\5μ-ʰvMTK5U]#)loj-B/!_/h#\&1 """#ژ}S+4$!IDDDԲBRz2rk!HfHmyU?CO4d-9*k+;JRg""""kMek'Yh# %35^m"Ҽ6Rlo?]ZLdS9(k(QEXXڙ^vDDDDT'֚NQKѼMXc-"͛ԎbCoĤyIIsPCMORI"S""""z#]%m%=ZMt-yȪ"L(6&&$Y;i>JPETgz4f+IhQÑh|_-Y%GfBWS;4$43IP$(bKs\C#"""7b?7x$ S'R浑FC9 zIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_general_local_encrypted.png000066400000000000000000002403521477034762000302770ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:13:11 CEST1@(IDATx\پ{>/ϻw3{{31HD%# (("I2Hqus1iLcsNcBEEE ] {:@t :=tUUk}kMjg i2  6&[i}K(BJnOP"m$R8mL _(Em _w  B!_:ֳ)LXJcB)ޞȎ$R@ #4O1 )  PaȗNͿ눥V* )2)4I"Z> Q(#h衡^AAIJUZXG4r)Ja/V(d HmϣP?Ȣ{WçGAA0KZUo P*=BH&MHa/v[+pE<<+y9ÅHAAtJÎkmOB4&&I_`ێПnӧjAAfј1gc;r[G2"s":{tʟ3|SvrG޽ѳgOAAD7s4j٘0n턽G&s&[DR+9W/~%+wKʵzSٟ"e"AL?'$,;OQ[Wk!p-wCi,5=R9aooA| ZX# mlcq@m68ݓ/I Y/7@^u_8jf- u (^F臀ee%xvK8J^q$$Cx)L66fH&H#4.سwG3e$Amaz<=z*y?Jl/GŬczcyAa[^`Nٌ_v/C_H{'^ǩS3g3]XFD־SH}ڃI$ hOY[zH6@^y SszauVsj2{c h x5.{V`°z ctK+QSSۿbmH4T//6bTԠ ^9퓽WO/؂KQU]7`U+0pex?BTԠ/Œ wxSW]Ǘ #mɻQYͮ(ϵjQ3FÕsWao@"izzA:{['sv9i;Atw ;(GS$g" o I%$AgV N^~*QOy!11r}?{(㏗xȔUOy%YfC|?f{cBS>ǽpJ%U{0@@\rժag|:y[;-UWpn%OX{n81#GMYp5#T}_/U /rrl J۷qW4~==Ku^ť݇2Atw؜Fc hP6HΓԈ:_ΓlIl@!<)# hzSS`϶!L#ip={g~"} VrSs S{^>VK`= W'i3X)ܜ^p{ u)J9/]g1s觪azIAX}<z|ETsD6 }>>}z$<ǺG/S8dBI=l6D pOcO"i\[|^+#Sڳ7nT DRH^8@ΓlIB3?ҌD Cfeiq^^7Z9*OOl\e޻ߟIEAE}˰+=THZwǩYIoE0zHWW$n yCa{Kd"&W1{XO27l9 }*w{Ht=V!81}%"ig,iɿ ~ͦ 66nN"ID;buam>74S_]fU} V=0hV*s74{NuU(}KGa44J`6s-v=w5ErTn}eo)܌QQ[XX̨]>_7HϞ=U ???1 "V'}*1Tqe1cvX~I$0)e' Nbu _w꯮ŵ3jD ú}}}! nbu uQյQ@},$oA$Yw1N n20$''# ཈1|qu6v.alǙC(*#GDDDbcco &_ɷ#)J ̝;zjJ.k1pW[6} ^2tye)FB\\ „KHvpI{צiB64h[A| ")ȴ4L&^9m{ g)־pZӧ@ല/E:mr#:>?|~1RZyebҡ@ 7n/$z44O\p$ CX5s~A 1$l׸PQ3CWp;iU#ͨ9vn ׿ 5k6.r8aΟ CXda#/hJ$#::ZՃjKqpK]oز2{ 􆫽1|ոJ]C{nmqeHDNï ggo`ۤxƒ@[+TL~;&VyQQ3;a psA8 n<+z3z+"iU8&tNڎfOq2M$selJs5xS='U(9񈌈DdXs:NS/$A|8"ّDo\L< <<늤3?M yIt5@oqmv IM7 IGGNK6;bre./7Y) o'kɷ/V<8&Ac;i.~Q }ɜY 44$cEr$p8G:nƊ|o lאzce*NMI<5"9ݾ^xG`u}ƪ#dcɼqvsUDBat9 L`".CjL$_%R7KKƳo 4>JS<.x]8dc|P4)PNAR6g8ګkR b\3a C ehT6{{'7bJB4?_g|&j kKOe8x9joвd ֊H|wS)ȃfܞpmdh8케u7Fdؒ&T&M2]Dڐ&Nb(m}C\dMLBBJ")qD\dy&yͼq"iYD:iڄᇇ_I{ʠARywny-w^CQP$%6>Eu#x!oQ$ي쮊dxx'q DR^.FiI)=a"rr>Gv0:v&ee4y9H MNG_ns2RڦE8ccR5j.6~|ZIt]?۩}b>>!|Z"2xM t9Ԝ_ c16"ޖ?`(NT+9QĒUtׁTx{{x?v(a KprqBFFׇQĕD2[]jHDdbhxmO7aFTI8 JADx$y(~xtEhj_}Q>3"鳷vmJv$͹QĭM٘D9V5bDc*ѱHNDMxǽ=󑑘Ivn/[$ӗۛ*ؠ xkݼH^"n>/yjPwgIDDtlɋtjZIOO޽{>7t 5믮)Cs"vmu=>6ޑŷvwoƧD҅CbH^&fb/NNd13&Wی-b8z-N9eU-|t#vXo<]zcc/p+6`-9g'rj 31ge5" >/q //oiHH5)y)ymqLye3gp5m}٫?9 ah'U da; qc|6^1HX}Ť^p}"1ʌxw7N@v^:ƹjbfIyLp$P#>7q#l[KD;De`bT ]mg!d],W$πI[E1օIIˆLv$oZ$. y9 ! !9^cCۆErB$=pjɰ.xVQTT]\A?۴dʠukbA2s.Qy0 C5N؎Re1Ƶ"{жJ$^\Ad mG$LKdqtÈT$c m9/WiD2zt XErS1_8H#hkȎ|ȝGrpI͌=6~oB3X!l"9γ.k8T3azC tu6 HʛAPlNΣ[a0<!x=4 ݭ;ϠH#hI]WQV U%i\$8AdX&"r%|H uvUpx*RAz1+*NHJߛ8p-4wA%AzeҘDIda5lm&ǰ:T#lTߔ1Ϊ]$mwyhfmҒ,B -0aD1:AȀH Ks%-lxU;~CvZ4F۩˜ !/V&#/9:}")c^ᡍxƦ"=U==7NEa*ٴ H@Nv4|X.qGؤp;;ޗ?~r^^s6H*oDT?{`jc>Dr!" OL;܅8K*VVV- XU>$^Y5XA<[f/1Xr ^$4E0VԽjkWa_8LUj;dE| KGƋd%^$%$WdzHnW]oj7bv_/Xy+/" PMnvv@v Off&6nܨW"Ye< u[bwU#ʋsU"v `<*qЈTjO.x -)Bx&;Ç=7CIp(vHx/;'V8T(>(ߊ/Ϭ~mӱǶwק`lp0[=xQlse 6")FP֞ qI;;.$;'rG\V#6Dr /d ,$')x!2bB3j3ӫ}YZZ"RWAL䙆c2éWeeWqi Ƙ11VN*ڨҧ98/2˶c=Kuv2 w >XT(ڥoe&FVNG\T436R33anEj7Y񈊊EkWz%Yo?6VmO42n#HA@p?ZkʕG%QޭJ$.Ҥk)L$qx؆/|vZD85T99.nmm}ɗ / Pq%LF oY'Od\YX]>_ɷ@Ϟ=UOQK ;$Sz7۟0)0 T^K"IAAH$  I  D   $  H$I$  "5=zWSg_JA^$Ⱦ}ަMʼnŋō /AAH6&GDXXX؋WP~DŽ,.,>Q(fŎ0%wP$p-i#I4/7y[[[\6"԰xh{n)N3CŎ0$$H!C:[Ō򞦌H~p"ɞ0 8Q( aJޓH~P"ɺ0 (N3CbG$$$5 3CCA"I">#܍89%$(PCA"I"I"i22n-wg F"ify`a+ckAPQ0e{cf,(fŎ $|}"iee9D/?BY&wpvĸ:E-j)B$yE=^)mxH`I`I1/N 95l| E`\ux}¹R s{{O^38g@I7'$|"WPG~ܼteLk$[H^SBD0;@no2D$b(ݕNoixMeD yh&Ru pxv$̉U'Ew!n*^`xcX"vUO\o:yO=`;-Au/pN, k^3Ŭ;A"I"E!i7.0OYM#+/0^ci'oыjȹ&(*Qxa &5= 0;p%5hT*XdEaoEshjQr0qDIuH CXPؽZD2_/swI$ꛪpg LAɘWH֭8JXg!t'dfHBj5ԜX{kpm8X2%N9Zۑ`b\.kË0WBϷ%ž.r2Q#k"LJْ(ĥ$#E +.2#gT)vE$᝻&jKnp2V.# ^B `y;hXFl3E> aO_b'.XzN(E"x&OP)W7:foV$ _EPU^G9P& Z[%7I-f  +РhDMI>vd\W$-CHKGΙbpH)16֟jQ27*pMbCOև5^F4GjT=apob vGq\Uk~F2&7 S^1}Fze88/vr)>k壔Ͽ'k.wϳ'k3<7쌡~yhĝ(iuz4a65_p41*,eMPԕ :dZTdfS!dpĄؙZWIWAB[8s_M$ I_Sv9W4fHo|@Y8p%rpM֙k6;,#ⱘ r((qBemgak4Mǁ7|/v%|_c ov99*~Ú)$$XU48:W++ނhF,r7H4P4! C+&"iqk+91>: S*'HALt<ҧ"P:K"i1:LiXyR+E|cO%8<cC1s8Wɋ_[XFcz<ߝGTXaԢP(¯̩Hh#iH*!aH ?yaXޘHZ!B_|<y~ BERqѱ\|y uNJxP5XB잙H$xS~HATDbs~f4 *S6@mS6˿S(Qymf !E,҈3Z˱4y*W1硙֣h"ɐ+@ӃUm7OB|t42bj^N ,L Tp8Ic32cUK1ֺ5C*3,|ՖM3$,Vٙc(#e!vNK@tTfRehrk,E#*1, Smb[Y3O;%vV7XC7|/늤{XaSƏȔLw7'$4$ctr*t{ ĉDoLf%8kEٌ߹EWAp{-.9̭gpijPVR!V"(X@ mcE8OS͇ ["e v$X6. \Q /^!=ôƪ|ef+'l@6?o|$'|חP[{;v磾x&8hIJ~>eE҄:r](xAQ 7$6r527H#&P@G @{Wbe]N ,3 AAۅ'\7!"L< p63ܫ#C65 r~e=}jn`U – n.02C([Kqmpw<Ԋ䱮!2dmweji"iJUlk %g9\0z$aa6CfKڅ*.(+rl+W| !W_A$濉"i޶2b矁݅ 3%ro4I1GRa9GP\ӳF@fP$%^UeY|)֛qZVXqCٶSf" @sxλƋ!L >c I".P$wV6h[:}}+þΑVp5 Q "iB41#6oBFf5eve zEjlDFvC?Z 1(ʘ>s 2xiRO24^#CcUm6+kq4t&y2ж fWph[W$8̋չI3VWiA Ӱhj(ؒ'0GUX"5*[8<\z/#DE/XlɆS?Hؤ'( o[4vo[Virb߭r(8٩KH~hC5]1== IH 4J{W4X6u>ۙ(]KJ̃Uh*9œ#$8㲶GRwI~puGox|mq"9T#9bvy8̶֡`%P֞TsC}oTn.]ݡHZxsU(?6KqK^s\J,>#k4[=?>P#RȲQqӅp殘yWK09/b9톶΋9烫>ll SPfDy%fkվ 7#oH6f3 cM2׳2eՒ|eeښTF˝{b}eMSߛYcܪhl*ĺPCZM;0x [:5E"!\ŨjPYـǸ} yuφwQRP7"ٕ4T'`ّ;(A^S{0{gS9>GõvObᇯ/ת|OC7s'Ժ&<; Tԓ5h*=UyB“mcIjwcޤDDD!y9rmvÃȨDd}5QoT$>>"zjgEu LUUr"-㘢[qhHD%f!+b5:o[S6 ɫqU!Xlc4flX';1/#?$En,tpO#ԪpU:iJ_;t4ב:m"fڄBE-l0snrx5Y"iBHjWajiaW XzN-xUؑ  -u͵" 6f翡m{_ro38/ӣLRJ%,š%8ԗI%ExHľX{/5Ÿg>"u'[`q>0ZEo3z \W QRQgm^ ܬt{)U7ca|>fN=&%_GcgɸE8re3s~~0ƽ~!9_b[#Fc.$̙@Z+M%~pJ${Z\F {JϵHh@B E]\ڃ)>*T{4,ϣR;"#I"ItHn]0=yDISH$E3C I@$`iiIWgER5Cy(Ka,$$$$^$AxP( A"I"I+>s,>b8Q( aJޓH~P">0(N3CbG$H$&""AAwJ$ F WŌLAAN)mS0AAG " F:HAAH{Op¢sss$AA$AAA"I"IA Drĉ*H$  E ={THAAE2==E"ueD  +$R($AA-ի*' 0 {&E$$WWWaĈAAaO?UuFH~"2DAAFay,z}}}!  LG$뢦  T?76N ;#)J  L3=LGm2IVcF{.9ym ?kI#{*#)FA;$4GmaC ̕kIH$n ~z.)dnt^H+g5=یh(FA;WQR e&I&m'CDrm,A㕯&7#\m?k㵱rU;b]p 88? a[{MUXc.#aI Er;fF흟0=&aYXK?Iq,>1M$YƊD"NDxJD:De`_YiHY#!l8lC| H8SCŽw$DG#:}!q=9 bv *\Qz[$ K53F""~:ܬ`5Bۿɧw~'zGH4iӼ]ĆYH0֞?qSΖ<$D#>5\mUr,ڄ2yHCC! )ǰpb"'b(88뒍WH>)AA&3~="1\&Ë52kJT,8 xӱwv DDrk&/]V3Ӝxi>לDFlHY$`wWhĒ 釪xyZ(Q>ņqC mو[X=eAPx#vz;'.8[>rH쁙g\[cWk|uVpX$mLOX&mɲ nߙ8,wQPċdIص6iʸG!TpUQ)vsVUj!h-psC"VS㍯/+pq6[!EmI ⏒Ɏ$DudkL>@qϷwh 4 N7}+E2Vg +\PV*RJ$ x# ^ds(ҞC'.UXJ0V%)m A*vȔH$_Y$Wb!Ќ,q{mUJ[毒Ov*pwg ހg'j]3n*î+H.cs|.龲ж7^V|/\@DY(tE2) ,~JW& sHH-n6>ǶUVSiAH="1[ +Xy(H;u=B7ED >HHF6d51eݴsPAgj oNBC^Kz@L=U+0=acC>P  ˵hzy}"BBYs̪mv̴tĔ (nFv|<[Cn8PD >!G h_Pkv&@'G/!':.',?>kB=c#~MM$;V@^TuW*VmM2 \SfIFB m HJ[a"A}Vf4b9 ;"`"i+WL=QTE& &y. 8{n4žIL:P3X6)1r15 "c!n3)2LcG_@DRb<  #y5E{yIEĂ(, "*1PQX b¨b("  %@{soHCgZߵF 7>q\m,^ܛnjޅź%g;vfZ.=ͻ{8%'`V760z=|,E7`l>vz_*4nڶD$3zzyj3G&ߟ#*Fcp7NDvQ y':uZ5Ch49U`36~v_:h'b i N(Wbl kzm'b1ף#|s,˔pxz#052 W_|BFGlFs]9gmƬ4QQQQQQW$Mޗ ݴ,mV\bvL2R6̂$ɯwK}&U M!k$-nt#!!FvVFUPgj1c};[HYAHVx& "p&2xR0 )]^G >[NFou%{-3GlpJO 5ګV߅.= M@_  醘ZO)w0;30*8?`ہu}ezԤ.@l|_8cѡBݓ2S?z.!|A%G3^1 /3=ũQhB%xUvArxx%|UkASn $-i;t>}/c'(E%Iv.X^E%6&!z_63iW!XcüFmkЮoBڱ<ׁC@BS[hz|gA_2VWr .ݚySG||a@@}s2ZGa'>zIg?J4J7 C]&S@Tn $ 7ӊK px N4d SΑj!Ձ۫C m9VviFэg&!<*RB϶,Ǹ p ~DR|^d%`(a=*ρѨø]PO %ڴzHx|g 3i ߏPjt;;= &C6R%Hیvc$;ɎlD9\z4;71 *hVVqjLs6FW_Ĥû/`mh(A4yFr/ ƒy(ln ewqlD~Z;F- 6,2:`wѬmjHw{cq;~UMа(?"9t T/I͢*4Pռ)3ڔ@e^JF5tH LXרi@TmLWcв@z_[m&c^|T(I@UW̕66luoz2dLO~dB%-Ƶ0s Q 6^fdծ.$ტjap$50JT>ދ2L~EHȢ:u>_DR=ێM|fy,B"Ԫ >( k/H.w Xo"sMV/Bɖ`tms\OPv̨PWr?KzHZ-|%GnM=e̚W-N?g@6i:Y],KPl874t=1 wza&b~5T itOcq Ct8j&B/k NnZ0Y.}g$#$Hy݆/qvcFw UA,I!] IwjS?ÎɢuȈ!((swY/A*#Q#Xft =*!!Xx5Vy7I0f}KVYs Y&Ǣ B㒥74Q  YǍ:ԞgVwA$ꖰ7 xC*aٖsxң.{I{_][;c˙6Oa޲Жc} ɾ_> ⽶o߁( Q/@\EZvU`TAL`ݮ~ˢ ȤRFGoV{.}֡7l}% 1@ ,A䋃͗ iƥ%.y`Dlnu|0sֈ ~FLh3Ѥlu:4Ʀ`V5PmNJ:!3u;+B / 8mJ"h{sgȠ,b%io? fB@ ,g [e *9E|&B&ljO 16HW3*YiD8ɠEɐ1}Էr Hv6BaDD\Haz2z';o'W ɾϨ(|gItՙJ4y7^¯7V\󉐎"uF] b2;d#ÂTTHgxťMR$4)/ڹw ΅`t,jm;(4ްh̐|übkB,8?Ѡ){\? r=ja`7 P?"| $N?%wY;0VlAqAj5t'eܤûcfks w1nDV꿠IćM0SncP ,ǤϠ<o ǼK6v5%chf_#? ´%`Zoc2`2)nwE(Y-dKclWV֚MeV\[f_}۱;GpmkM$΃W;ڔ#!;t *㬢qĞr6m@YR&Kwh~{q00Ih{W 0IǐsP誑Ҷ]kmy*H0Nq=pt<'28*82[d$(7U:0!]'ٔe~(uBߝ/X;6aC9Pdh́}-eIgkax] 9!k9p$`&wjSC=pHڵGvFQi($АㅆfbdR*=0J ĄF6;j`=:V Z&{ WGܬN`Uđq+WY0 #p]>LNB8~%*4_FJB&;aX]> >g0J97jT;X0c-?l΅In9\0a*|.m, -8ġTxקEP6bNmWs' o8#q67\AeȐqu"z=4Xwn~Gi_^$eLR+X|LV}یy^)=!'J\r$m)k1|֙%GgW;.s+صGR<qwhxq0bxQ $)߸'ШȠ; !:OEP4Cچ6t.!4'\ i- oWE~Q9"QRՀV4)-}AvyxeqV*{$!~nt-^> ){킾pӍW 5t'uA[q6!ߚgH]i?VB0$} _Hvy-cOKKMJ37!t/f >2Akѧ(:Vu9-4Ⱦ'HULm%!B+0ަ8́,GDd)a`n''O9+%JZ/~&{g#dz7~9pV8Gz RNېתlp@lHrp6mW 6ܰA[M|ŗ*ĩO<)15fAr$,i}۪ϣf3ۀ1Azcc`CvېעXy^ (:6bķ$a=rp7(TA8EsIxv7HW1xd䠟@п$틑Ö^R[@DG~|E"SCҊQZIBAGR4 {KzwWwdcN4{^=Q>zN7i 1$7Eai^C.MEv,=$w֓r k !sKjm~2 UZTN?$-xG)*~ HX[=_dR0IpÒLKۃ:qolLf+K{ D& -Sďiۖ]m-9X.$Y PڰThLNwHt2ó"lui'lk߲g%Lnf:A$)f+OA?z6-?v.mnSb Kˆ#XpSxb2߱#I1d_Ho? ~Mq1ck!ј|' )],r.0-3pf-1UVnKvH' jxupR+(=~K|'w85k$C`_yVZ'{fR&$[PMW0ga Ð3Q ?oIs47+06/]AR.]Zj4"$2(9!Hgy ʰ~2H!,:O 1ve԰cD۳f?"H:2/Jr",Fz簍Ƽٳ0Wso4Pmm ?zJ.`0H$!XϚ]z.MŊE4If]hX8#[hոR rȃ>8/GL/z JKtF_g#=rKJT,ʌ= iˮ$kӨGKqvD3dZ Ge yDPS}G6@XH6ب6ۮ8kH Obuѱ0A8& a1]@ 4s8D JQvnکوj* FFNo_6۔3av=oNGAFB 'Xkm ^0{^Ⳬk(.}2wj;l3V:/sx#I!<7AX$D|AϠ]/~VhQn:gFR3M!!~6dGzg$E>!ga$/9Z6Ɉ{ ҈-$YW:K iܶRjCeSCbz=VdwQ OJH [$dш] 1ٞ8?lR6"rQ$pBGAxȏ9.T"+Ȩ@٥1yVGY}.tkQ|@a,r7w~d~gp3܇ KFUS>ܾ *sg1z';'iNh˓aF:9|6`Z!%e`' 38%1O!\/F NDӂڒlZL§ yROu q{Ռxh'uIF(=MRIɻoPBO|N+;?k;axfDBI (AR02wQ\DӆwqacEv.gƇ͒:,׸u8Ocɮ$r6O xbef _Ai;m0/F(Jb_-Z?=?NF˒qo:%H[:{ĉw&pAݐ?="́$x6,U9*+O"PlonSb E 'izSR}69$'⍢͐ZJՀ_Iv$֖{8mM+6ARM/ i>\|A'VӘ6~< iOuIq$gMԾ93= fs+2ȍ{ ğfhXij2\M*,, Ǟ\~]fԜuHQ0 G9'cn^ goN`ʢ EJl[*^@̝Ѿr 1=~UJCnR^9,5CO= 91እP=FSM).CdTXw!>(5dć4l{#IJhg m kbo(3?@GU}r7w-E=HZ%k2c--5~:%^r:P{KƛFb^|T(I5PՕ"s% .Aq:D~b-.#cpWA&L`\lxw RF?)N~Ldj`-e_0tFj~dqxvP[kIa&iu HC϶Cqgsu dWߊj4kXhZbz 'F!i/W%Cw(N0 p[Zl#`*On;}'ߊx!=qcwBAA\0tGW`YY AT)Ǎ *oAHV&qdp%TJO`x-,(Xx5Vy,PrfB% !?7/ $?Hj$Y‚xe26O2SM`q$f1 Aؖ<:b%%؊ˈ́BD3l'r%}""02 Gі@i*# _C5`7Sl$m||k2#[ ǻẹtn~b"!0{_][;csQ"e>B]} Dflc-wf.K.1^I:O[<#1/x,bAEEzfp6^#sKf́$ GC|yw$xmw JFF/AEZqXaTAL7k!+;gl' A">H40Ilvu J?k$X4A )_;~` HڬK>g->l{g+S6E~25I@ & 8b+B_CS 1n?7) R^Kn-O%$1|q_nCyÌd#7}~ F;bvcr[ Kj:jh6-ͪBl$Eཞ N75_iQ:>ۑt)HJD^ n0R${|-`k010^+qoC[t43H^4jrA|02ie[7`'4io$;F !npwϸ9/OAҌa>kr73g qٔ=/47 9*/ !"}ϠD D彣m(@C: ~%ќ`l QܠCͯ &^j|3k(2>9M1q+4O«wp{|H8FC4v~i!98uSԣ~F?HڬK>g9> /m79PQW_0W2x IJsZ9_ 9J Ml/g{$+|~q$lorSk"I%{9wqʠHHC 6nQq߻-;4 t1 `ߚv*P Ơ*?l΅-$uREF0:>)4[s˝qV4~Йڀգ(Va$sKeIq(2,% "C(cq1\'cQg#qҶpJdUTƍ8LrkD]B Jhaui,'mlnjT,ѐ켈ehTY@3c;.bPojkŘq$6P֢^77x~!~XkJϻ 'IWl$_wԥ(x2#H2n$Đ}5HQ?Nd6rM 'rrfrn@h$g$yوf7j~k VRx-wP(Oyj{}!ӽmqp3vxÖ^R[/GN.?2@B+0û'<D12:=$X?_]}췀 V2^`,!jO&io_ǞmCUQ2  P$$H:G'VOlD( L4?:+jh*. Sd%ML,j$eA@s'S1vz9,=unmܲ/In@EdHAAdh2wkJ@P y8͍y=3xbJui,';ml~Adޭ)@߆\J\#3Fn@2H i(:Vu9-)/5(܄й13P 9tyԛ=ۅ{0F`$ȜC(hmIx`԰imIjz0K䠾C2Iocy$?(CG >enb[ i]p$*ٽ~~ꌥWTн5̈,>٬7hN d/귀$[%2ԶS~eе$AZn@jB.l^v$x*cIJ$_'a ,,A3TsF޳`x$.*t6sz%0:,s $#~:?Ham+h%=]olBx ;{ڞ!9l2 ́dU8p!ؒG{8JL`[`;s*Y g#(:U JπH4+vC%AW_:XI2;! G# <0sb6VBxn΃Z_#H~6ɠ M!!A}6dGL3F[R rȃ80er,/DNJN:= /6y? g8DYF$Dw2Z) dQM iW!&d):{߄h3{=e!)=1SE]F=oX*ϕĎH=b|P>Ba6 $"C#ԺN>[8igN}:2jdH_wp\+3_0GxEjhtZP[X7q12$,A] %ڀ97N =ׂZO< Y>wԆY1n{1*4oߛVYZ;|ʋ'6`PaH)f2kC#އOET.u,֘"rF%WnJ{ln8Esy?!!QVa5Zz~OT$vY,T54MUx̥c0%wN(w5"_$(lo:7桼ސ%hH-Kl2q9NWCj"YZъ/صm!~7KƒwQƭ(dB2p~QCG M $EwotTеף,VLv4,ze7$o9xTnc*'kuil'~bu#Gd P*1dkL^ʾt@Ghڷ#4\0 #hg [e;Si} ω]*kyM^,Tv'umGS]^ ðd#]6fg Zl4?S0rTWDNV|X\; RJ^?5~nf96}= rK͒>w~݌Ѣ ‘`C<,1IZ~.Ž8![n'xAf[ԵrNG r#i+SSB^l|x M|mn2~+tSBA&$] IA$I TTTTTTT$)HRQQQQQQQQ IEEEEEEEEAFN>Xy$6)tz3+H:fTgFs frW5| f%m4/i9 'W+.L`;q fF`M݊Gz^7l ?p=RQQQQQQQARM/ i>\@Ȓ:g q 嚓œ Җrk =qSe CeHEEEEEEA_-opׁO~u|U[$m#vFߍ$.$ტjVFGiX39e SPp`4CIeTܭ6 3;v2Aƀi7׹yBL2wEqjL sM}r7y0*_E"%b,I+Am:VV p$52w(Qx/AR!L@p#{t.-sg3:2W4Ewm=r! r7(?"9tR#$fQZj^r|FHEEEEEEEA^4@ + JW?hph} EF]O,k뽷'  4(=`mYZʭ{&IW"RĤUW3ܣp-ſar({ARY{1X?4CwKeRHBҝZϰxaFxG1ά߫+GF AAޟ -/"/ɏW^2!<亅EV.MV[Hzâ1Cly'PׅD3QXKl{7#48PQQQQQQ@R䓄7g8|H:a>7v 쫟-2{bdR*}-=C!р}/RyhHv^j4ЬP4~VւߊqB {$mP2%`r=Ariu J|ׯI Wډ 8bNtY0 # }FBRQQQQQQ@k'Qg A2\#̈%⥦:3fa @J̃$ v`P P13FnX{Hev)4d_= 9 6$pn ܺArV3X6đ塢 OIа%۾+H F,åjNr!MW-3^i )_rt-9Xnyi{:nh9xN؎gIl'@\>RQQQQQQH&@ ?@S#HP|j9B$AGza?"ĸ1xB:ܻg*E%؎[^C [5`4JT*JBwϙI(R_wx$ }) Q/AEZ㊥`+.#N6~ : "#\GdT( @]@ IgSPEH,f%3&Berhchi?㕶GW`YY:AN7,T*ò-JG] C*'WH,"~t#!k7u܃|c6Gk%5er, 4O'-""6 E}_ }ET^9B#s(u d40PAEEzfp5^#7 ^TTTTT$6.XvI8OP8s=oaɘNթ `Х̾F ?+{-38MLE;Y:csv-m ";1YI;Ay-gؔ@d+Dl&W 0Y[s `(ځYC1-[5x3;9+L\g;F- gC@e1VC4l ΅@38thKbOpYscWwi|E7$lvLB4y k2dS?G$!㌄o9 kТSazӣyXw9@RL%w~}E{el3.=^th}3 Sv*P KtR!I^},]BߚMC&\C zɻ0,]zO9wF#fgϲ@`L#0lD9QNs I;aGXmr%<~%*4&_FJB&􀝭ۀs!>0.bܬ쑴TTTTTT$?"Dm% oБ 9( ob<`9 3^1 /@ kh{}!ӽmqpY9@2 H Ƀxk$3c~ړguZCq#悓X+'N4'Jvqfy'b3 jӥ@ќеfow$wg)rx;jG]`7>\9lH#jaƟ9y"pA?{ESuUwuw]ݯ|W1$JPDŀu 9ˮuu1 Q̋b@ED0=! 8?UU`s=*^x<˰Y`K!ylyŋHa.PJ^|ڼX%t7>Iˆ: vjk^@Z摩܋Zh-Fo٩W^Fb[Ez|[DdZ41$@]{<:knibqp\c#s.mRFb 9e[i)$0h90ealW!<zn$ 8\A;) DԼ}҈ ׊C㇀ q]# Pb3ʮlB\  f#rDbF-jkx#s6t38 >s#-^ļHL̓OtlψdY"<$3di=o,$Np_ Ǟ{ZԦ69MZm.,1 ^q,QgĤPA1!=nyŋoQoE{C)\0H9YXOhbː4}dl;s(}zbMQgQsͿ<*m_\?F8U*QDuX^6Cq)P Omi.2 GS0 _7Q)l^ Mir.'_tkl*J 89ƪ >.EASi?adlW K`"y hש6>$kr.RN)z*^ġa€qb]>?ZF膀%q3:/~Ͷ)UJ>4Ag..yZ?zH+oh}:Zm>>>iӒ{F>'rD;:^ =Z/a׿i6_ sHBJ%}&hE 77JDC#y8&n!)O!ɐ$"""$C!IDDD_cHʧ;wlQN ov9qoz϶?t<IIS:S6DOzPuU1?@-ql4.;Oiw2JN<-UWDo>VÖ/|vYSDń8; x .?>B5r??a|m$c$T#!ŅdG=X %>N9~; ]gCu_j s`_Lr$ticlG`6 }l9нOD 2F%ѿO4O#/#,Kߧd[PϽ Y&7AdH~!2pe'l:!9j9>[mspxXIQH~&o[fNm ֽ«WujQ}G&"Dϗ]/` #- :|5e|ex9|>{]Fr{;WAȘVھ#0%_TC4)í3bBRn ln{؇>OD6${#rzcP214 a7mظ ?ی;С*N< %롆3IuVD7 ͗.q_IqYBrD;ϗw=po5I!f3| _@pDt:DEaCY ɏ@ sҤU1."-†=+dHlD_cH +VcڵF֭둘#66'NĔ)S! /*$U1C SH֡JtTf`tUm'@$IquA";Sul|U'Z^W)M<|5Kf케GZi.ţ]rH ֵmor9/kkQ-NV?j[ z4xp|m<&}64c]:u*eرc1n8#0a&MC>]P:0?aaJǻBjQy! Q9)wkJ9:9v.jnas^fo`4:~҆'o|ރñ#G"Ocv5,{82=q gnv0k쬆|yT2 Z%/g!;ǟ:3T͗N9#G!bdO^)72~ IV"텀]!pn|>̓>+3 u3ɳߦ;b?vfヵEw!A8D 8$3\F'vi S>v+y"y[[+Oq >>y;$S#ϦiiX;% !x /̧sҤ/ #1 !V\m4"Gfo/tuP#! յw+>C!(f2=ַ6s"N/GFF`X6~O%$"!$#!$"2..v3$T:2K;;r.Vy]}F`,6r9 -MۘSۖBogGu 9#nԲzVfIѝ W= ~ \X68/_L_.M?<)x+ȸ,Vc`]e1ڶrv*=mO-$Ò5FhdCDF6DdCHz 4SHQ^ ͉)7X:ȩW;GJ4KEm"o3x-rigo;bG8T"AnB;z@Dݫ3@(ڇs­*\,t!$c&VJ᥽-o$$Lֿ2U((B]!oms U(AHwU?e:\]x7HѧA~ޓb-/nnmH,P;+H4h H|Ի!l{|?Yã`t<Qz}º\ Gk!\8zz|3AXzâdܕBY\2]խ\#i>}5<\=8'e爉k!5^q8X .o>NfZlm/gg']EO3RbmDKH~g)E6Dhɓa՛!dEG'6,,:vLăBr 6C6PV>to ;?c|8>{7>]O1c}w7p{:EBH[;`eAh\]2HeZHڏJӆS#퉈2D;?Dm<$-̗zrdjkp7e o@1$B=5RtIP#=i]1OS!vVo)̩PYH6  ^i@ўir緭d9$wB%#߶]k:^^VB|H|"B2>>._DH`MJ5]ސ%d U2c061wD 78#2#֦yrĈMOHL |m[98W*فémLs/֐c"8d,O C)k`)"-!+IHlk=2Bd,Ј)X}[8ç-Ɣ7F$o8qIHL}<&DJHg^3g΄!er^@S׳Y9[\w Q%.igs>>.$DlcQ lSK[RgM-?Q]:'(=8Rb9;C# j pch0^guDөNake)mQuk6A=훝6?䏛աN3^GsyUA|9JA3?~GWWe=.f7Lo~KpZJ?S; MI i\+3~l,ˇBIG0(Xw8$ӫޘ{& 7(]-ַ3H,}JQ8'~ Awe;N-bzjx]KýJŊn{ar-htsi.2΂ON_?ޓe:؇C.Ð8[f,~q5Di> [ZVXΝ#SۚOo%#j1装"e[7Ȇ6mn^VM!o IݙBq > >W<r?e6SurJ>MÇ} !OhlH9g̘a!Ι!هMECؿBԒ>6yDJԉ!DBRA<[||wt:xH?{N=_Ξ'W&C3I /? 7]oN\v?נ+OE __GDFHakknr@?c2$?ߵMDDD 7 !7|ÝMZTzHdH~!)7]<""" ZD?ݺuCϞ=QӒ)O! $Q[v}5~H4iӔ͐dHgLG?H<7H$C1$DDDD I$C!IDDDĐdH1$ I"""" IWWW$}!)wC!IDDDĐdH1$?CƐ;!!)?Q[[[|JDDDG;dC]|їsdrȱ^bH[aHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ ω yT\DDDĐdH^Pu(\DDDĐ|ېtߊPkxW^ ֢>.\NP0$9#ɈDM oàE^*$1$CRH H*+wf\ A8g{]Bt.E(]p|NSc 諲E_]?M@$<yP ^lm3ڊ<\;#ݔDϘ8{;/0(:=sDSW\AYf:.20$!!BCI8Qm@6)T4 QA䛨b0san )RIt9ላ G;N8 xKzd+q$ֹ1$0l>q8awn'&݅XySNmCx&9Ca%$;8H[N3$!1BRsQ# 8R0"逡Sar?|0a3kd<*.ȑ~P_Fsk! :69FKXnPχJZzm;f DP̏H}: `t 5b!7Boz$1$?lH>>'f9dEO?JeĥBF5mi.2 Pc(PgТ \NVӤc0bOHM=ۆ#h6^!hK9BRpй赕(zxW$CC I""""$C!ɐ$"""bH2$ I""""bH{HOV^ F...DDDD_Α5/仄 lmm&їNcHcHƉrĐ|wDDD5A I$Cc|)CƐ;!ɐ$"""bH2$ I""""$C!ɐdHC!ɐ}o덈ގ|, ɯ+"eUUDDDʐdH~wOJʐdH~uŝyhcH2$DDDĐdH2$!ɐ$$C!Puq#Ke t;kX:@Ő$""bH2$?\H:#yCѰdCRYitk]B60!IDDĐdH~gmǸQ#1rd.$yj!ɐ!)f$Cie5 *q@"8+O !#ZA M]LR!Nfn 4:/pcϠV%F M:@58G砰AD͋H3\Cl "l:6 *+߽U<)#InwwDoMGizd^Pϛ݈_Y3 P2$ I<=*T 0?cqƀ}p4~ պ|^DD T},SzĆ 4;B呈 i맣ԿP=ni>o  C̼d\.֣&gؚpK|7^pTPW/BLh(bUrwYyL_A3I 轊E?C2!IDDĐdHyb`dr>E<4xk*&dOl]Et>5`}%nJKQx/VOm7YE7$\xS ]V{ 0 \ HN3$_57c? 7u+!@׹!Ԧ"F8F<K'Ƿ螘$:):KU!&^p= I0xnqO{AX6QC!ɐ|k$-yĩlB{$$;@eVULT}6TV)dx/dk![ Hp7C!ɐP!pqԶQGD|+0DjH8gNB+#]a}~{Q j \pZe$P2$ w:}7h&`ܔmdxZ]>άȠ@E!.d ی\ϋtYmi*p+'L Eq8bn2G&ᎨCv, fx:_~EDDI+j>diDCBwm1$@r$ruA҃WmY.-󃪍9x%2/UQEC!n^D}bm ўf^_ه1#b5gJQ]t'FM+Bwm1$;L~s3Zx$6C!ν}07~GN]bu I"""$C!A;3P{[|$1$_$C!IooNODDV$CwoODDTʐdH~5^~$7"""z;M"!ɐ$"""zk I$C!IDDDĐdH1$DDDD I$C!ɐ$"""bH2$ I""""$C!ɐ|_!ބ3X! g~^j+r ""$CㄤR|# OCNr9,a\_gBw>.Pr}CK I:/H# jQ^pf`#G2\/P xUgNS7OtS}!|W{CNqFČDx({WS0O1{^Οm C!i%$18€T$͌A䘱Š#x/ũE,u"WCAq[JDD IIu<7b)\3 Z :TD?)t|RƏ7T'9T]b޾xP%roÄ>vCR,®6fny0ԜDwQXw)JkD by`C)2|! A8iqI9tz/rqqT*_GH7u9ġDW hc<_WʡjP|46OjYu7sK}+}12DFX]iZHG{O+:T A[G;1ʨyH* YJ\""m3PV8x:u=l]ac#ծqN$ӲT,PPV`"$bl>T GNVL9|%"bH2$?TJDFc@GQw$DcoRRHxc=5n3q^[SS\PyaJTۏH Ϧ!u`НÌN)=0b8B %h "N/Cp#.jqT㶮W6bbp9l0zW!MR1OT2 wӐ@GĤJ!|q)l0xe&jOpbE‚uꋐ::@U_,!FPV-ggfZC#1 JZ Ib0HiNrWz"|Ģ X?c.MzHj%$`hNܯ.դpۍ<]!p]v REZX}_Zm\JŸ.hY"$m#JC9AA7onk (NېQ2ą"0to!=%"bH2$?k$݁KЗ?]?"ƻS_*žR4!)7H)PU}3 ܅B6ōz<cPՐbN}WJ 8NlB}dzAjw46L7WO~}q(nbJ6Y )xo.Aoy6P@O}rzHi8)'+ [oUCH (؆A>;Gۿөmȗ5eLǦu þz<l!YW^c SvGbeSj=WE.IAq'Q]sVRH W0{l029"@&W iRl^cqC!ɐdڶ H+z E/c#p\KMʋP.tvdK7T  &ipS(:WBрWs4?Wx{en OvGV^ **QRX );aWPK)X>n 1bsOBk?v vc-B8l0K b<3o#%b>jGbDUBR^7 jcû\#D/yjO`H5X-ě?BH7JFJ\6. B bӺ Z~*fո/}`}^gCRs/BME<Hyfϙ!IDĐdH~&B#(2Tx\gx< GGx'K1$;aEP8tHS](iNB~󂗗樰zͱ;xV,@_tI0x7Nُ'bCHB+ ~MC^up^ t4Z슔46TvZ[' 989 BrLI!+dZXY+$?Ǜq!IDĐdH~wm.7bѴq BhL͇֟Cr#MG#;&Hو &hZ6 m x Wkb Bǟ,M!)Plj9 g"f$߄=CR5#r|F z9Qj<#1/a,wx8S/1럃e"D MQߊ's,j7\sqdxWR cquP/DHl2n뭄1-IC PJ3/] fr(Cl ,Rs$|5G*߉@xţIHL.ʦߊ(z^EM׭ޘt;J=F"t*-00$ O-$c-2~XR:BOl95Ir=h1 ܑV6t9ӑSR `؝+B,~v!)OP$Bax%ȿURc(PgТ \o[H:=:aN~8\OᡡͧzÅ!IDĐdH[H~0|pcwC():hgǙ;_P 퉈!ɐ|$ؔn^%8  o۱gƏCȈŴ(#e3C!ɐmeŸ( оɤ dZJx"uDD I$C!ɐ$"""bH2$ I""""$C!ɐdH1$DDDD I$C!IDDDĐdH1$ I""""$C!ɐ$"""bH~e!oy#pc%"""Wr&l  O؄M@ŝ){ceUQO:&˞˂j/_G9qY/N_3}=&Pp0$mRlU>} TŲL%{B`Ýل 6{,~]iV ]ጰ}[ajH`rDE!ݶ+|"1 (%JaW/('QA^CNrc,ɔ=𪀪CѰBwuj GT' C!.!R̙3k_Hyb̲gAC_[`WVHzW:ts6ENӽcBa"kukj7}8]PtV$`btb&b;#X#/{~m2xL4 HiƎm!^:|$$CՐDס-NAC!G [F^|;wnGHbȆu>ꋓ{1@`g7!Y(:ax>dB+h)IPCR(jP}{5{0` J-eOpy, rRXI#`98wr"_2?ө`'b6CZZ!P\:;h0˭a>;bjW]:):T A[G;1ǹiâ+xPX ^myٚF$"j*"/sprjD!pspbkv}c_P\#@[kc[h xʤkA;b][,wU,V CAtrJU!Nfn 4:i׾erP,PPV`"$bS6AU$֙m Rk 4^y(糿qht2{a8?yUR<lpAw ߫B@xjgv" b5Nρ(cHV16cc=^6T="~+x{)͞mAT W0i* ]Ik+Ppgb(Z-:Ww4Pծ}nFܯ,ƙO(6k W[x8[]PssIOY((8m!Ig34|^܉-o[V6^ښy]uef@#@.ݴkxj wDn~ c]Z!Ċt$QY;&#,p"#'*{%|/lCBT0B&`Yi[ IK;ѽ cGe7lqB'-DZZfYsqpn$Gb8c7[>@:x]Nz44y @@h4Bv4bܼ=1p_(-~+%<ǯiiwav#OWq6c3'&w1nҲzGŭX0>A1󇛢=!<9²A`KlZOwBb?ltk皇!g! ~9%ַd[ٕ%CYSH=иp~}i+8fEHp8bgzMBT|H7ajIDX!lH 1g=6_ZjoU HLk!ٰ/AL9+RPCkӴ=uP|Q e_pE 6'F%Ttt+7O~]me*bڳO+;"u$aҒܪhؚ' { ɐdH8}4ju4Tv_+it]\|}4xѯignԶmҴR̖_T^}BtPk:Poeag=$wC{mƕR/k~l;6N RW4q!w4/aE|m߾Sۖ'I3ژf+SVqwk79)gἶgMgkƧէ1xKGѠtY{ֱIiVy7^;-/ zxD I맶####K.:jH-)$o.h|-2[T JPQU iAE@#ë:=Ah7p n !i0? tR@.hwU?.-?"~GeI8bm/ضAP$daeܤפa2c:tw"F^ھ j!@ΘzZr囇dGLxe~Fia=!wR '2Lо<(uE}}Z11KmCသ#&ct<Qzm#B僕|CAl Z~*iY>RHv]E䬓O*2$* ͗4oaqG:V><߹~oOm=l{BlZKRv>^jP^TrAĭe^'$cG_˰01ѡۇ|x5qNaS[Ͻ|<}2{vY1p`xcvXG)BÐRŹ1= b1vٴrt'&}w3$oj1 eF#[=mV߱cc׶aZ|[w!)b noH@rwpل^2*7;~0\l߆M'@cEήHr28U GyۇK/:X<+ {\"OIEPG IH ۄT/أ_;$Up"}vW[9g9X lY7Hr粝WP;vRHVf@X j$ͯ3Irq($;`r7cK95֮4F`?{Զ{ >%4D}/sD[rT`3c33YS>EխӪYB΢RLDR`K Vtr(ƉpL oQ~pVjPbpͰQC]-= Ĭ9>erڦt[_K~drJS){X$;K\rzJ"Ȯs/UAN4-' y|[ ^E~YX`3OThx ĦKFʓl\Q!OKO!d&c4GDD+C۩{#;G40'hb 4$1뒐)T2s$yql>K~ 7!O(DѭH$\ps`ݼ H$)_%:_%+cgB2^S 䟮f,EL$x@CƲޏ(Ps`Hb)Jݧ$>(̨W|;K!Fa{z_WOspAƧǫ+·߅Hj?'o*`>O"#dٹNۅ絍hk#.Y AXhbAmI Fv [&-XRx{zwNY;hk{lˡ.1!dS:*96Wmw#:Y1gA]Kk0/ 1QZF$ʵmG @2Asb e+2PxycR,.tdgi(>Zq '8 _ fsUNjm؂ص|6Bd}T2!:xb7^Ӽ=[oL0'֎p|: : ),Xc4Iyl<gJa3|! \3֫FgC,IH$I$sMWDRStY**l!,/~bXCJVjm%T + AoˇAlHͪ+?➰݈ "&c>xT|±mv*:_ -xWU#Ԭ9W=Y; ^56BUW}=B\1\'bxQnpvi%g(L#_*qL(ueh 6/j!=Lvjbg%gQR߻GSD,?߱(IV-d"Dztc QF|HvZur϶7J-s#AbctWJ|zqZvē!I>JF#V R}_k.Z]ʩ"؋P/II+#gM;R@6 Wxb[2ZHH_F  VGs'rqHb|'Xܖ~>sX`oowO#yI$I$ (FCvxY&{Qz9 CĔלz% uDgmHH ؼ;}X :[m4 + HII  III  II  II  II  III  H$I$I$  H$I$  H$I$  H$0tpp $ IH$I$  H$I$  H$H A"IA(HvC$/jaa?% Gnd ݻ &  &G=S}D  *H$  II  II  II  II  D   $$  $$  9Eê6}3(AA"gE* iJ:A?AA$ߍHZxbA"IAA"ib ]yU>+pu rE"IA$d?V q[0if l"9 NZ+bWcGb} EuDyPUPThl: ҳNVN wb8VTv@I- mds߬ܢq0 kPT~K1FdHAA""izUװ`f;o)l X,DY1CչX#rZ[:\vЈ gT86#anφs;]6kHYBX=K ?i$b|$s.)FDN ɼD+W脔X AA$_!!XzSYr 4=ws Ҿ"daidh׮>'#H(c5֥c@a_ (Ң4I%k|s^ f0vK,_-8IߍlY7AA"edlSE>&~'KebI'W0Cfr2&Ǽ+5__1#B!Q+WT{k  $3>bekJp0T;bu%4l *5wĘtTH  HawP/7шc^e݁1c%EiVU4^+c7Z8n|ʎDu32a\1z7P؃qpug(  D "i%,^ <ƒ2pvk(KXUpj'bb ]y"&SZι UCźk[ \mDGb.Tivj?[m: ~O  Dd'*ʴe`2JUE8:?1NOp4.>"&rK 4(X3 MR螀l=r/FdO^T}! " VFSX;G DaomX W!9u <& Xk?'  4Q$= WPoJ(O .7JV VR^ґ ?b#P+!~~J(ԍP+PY`4l3. nC*tP"WBj@ŧ, qtAA$AA$$AA$$AA}V$|q5#d$AA?9? I $ &ѿ $AA$$& F4AAP4y@ӂ&H haa?$ G3D"iAA(#xd7DR%$ gIH$I$  H$H OI$ ER II  II  II  II  III  H$I$I${ !@jҏ_~8&( ?Y $챊GyicIAxO1)$$=fTtcѷ$$U>5$DD*`cDA"I"IOkl$z.B8gybaN$c )y7H=bIDD{@dC8ޮ|,)f7(뿿bs6R I g‘sJgi1NP7a}ߢA/ \匃ȯzטArlVeH$ IC %qpnL؉\g̻8Xvw0ݮ|{.[!Ps TDF[a6n 8߿D|^h`kː C"}T>b{Aye.,rU(Ljw 4ɯq46yF|PYwSa8zo]NF ~=O!FS&c^p#+ kOL#1$$$+̀Y8uo.b @t5 f!fp9R<83C6g16;Փ-GDI$FT['^D4 lF~^<k]š\\Q(q}mv"ifx]Q$TH$l?z\zxt6Ӝg짬Y*(2^I$h!kH08Q 2q 1,qFVw)bm<-}EY^VIasqPg"l>+H3Å{ .?CQ%jWEXtO?VB)Q&v;L׫Ҫo,YHBTwP({s{"\`AOdq* M(3uL g# GqPsZ]Qڈ6X/va Hq HA1WSڞrf^,E]v,K"ٶN my`D- Ye+P5|Ɠ^N#wBVQwGӮ'S7Yy0[I 'JGT6(!/|sSᨋSw2X.,f6^^¶YQ8ϒHR ".Uj.Qh`$,Q20C:o3.W!gke@7:^>A us$c0~<Əw_!S`3ոߠFAb3E-ť^pwwq`+AFbJJHB0w,x۴daZ|4C] ZUB" ܄$4:V B@P4v+<"9p5!k3}=-3`+n8B yz\#ď1ʧ"QI/PK1[\JuX;ZNv fao "%`q8c&>y<f֮Wpg"lO'̗/yPZ[<粯d?yZ>0c`_G_J!o _b:` v čfDEoqj+ӡH`x2䩘 \?H#H֔uQ$5>Ožw$TH$H$ m'E7ޅ\U .ζC?H֪rggHZ`ܣȮPAU6`Sscl T%8both;my=Bílwǩp(~r΀ud3zNܱfُ\Z@l5KVް2ahJw9?HvvspF+[CPQjz:d$ƒ驡m ]}7/I"ixhBWN!7(Va9sK u|(824"lj|Pɐ7lmS*h^Im/dDR<qL%,JW@q#A"IeDo*g/|`ʔ.<=.\Pds?q| U=>K^pbzC$uX9cu8Txyr.\̍5fpY*l͑lDmM-a\I{,ّ (oao',By=vM;j=p8!Ȁ|RH2;#i1JX뇶)/PXl_(<8 f VY}-mt͑d0 4;ٟ('xic۠H1"^[ͳvxԕl"錸|Cwkq󼭦NwV57┙j\uk+F:Y6mHZ`+%*ohs]I;ȃV:+/.yt ֭M#"bL$/u_$TQpj6ڔ zEI$ II#"`|Kp5ivLDJmKa哄I+Vz.O_V \}9?NŎѺ+ ­J(*ԕX@\Fq2V JTecoM}${Um,5A["wkT%n[ 'bNDR6j>OH?M#&V#w,ʅC:x5/,NflHhP8퍘hցHv90zCv5$DDo'>B1)$$=/ *?/B q@qLPS ~2@"I"c"<G\4TS2ЏDD  w!$$  $$  $$  $$  $$$  $$  $$  $i:CQ.6s߁9 #Qw Sb`B70=Fڈ}4afbLtOMSz\^ou_Vr-{1SۖފoǑ؜?Q\'8nKbgJgI$I$ f-cC?,BSPfbP`xb`q/7V>9 =3Yywa}X H^GQ'4fe 42%:\NÑucmc}[[hP55Jǹmm")v@dh̷ފ/N9W|ij9BNKoU^ln?s#y1!]ՉHv9&{pD8c0nkX X#$Hr b4LTxؚPH"3} L>!qFl Odc&%Ὢ˕Qu9j47-Cc4QT89vo27 PWe#yB A5u|3mH-fH~:cqmYHHvU$qpo/+DI7W׀H VqUփU.qh4L)ƈȕɡTǽ$Ф;|cV֠0vDx5(+@e|֜F*(z Is\a_٩;v#ioSu,**> ȻsFwƚL>&!ogm/;{4E]if  >`aN uٿxikj"<ƖGsPTJDMn/}ZcޕcBӤ#_H H2sp@gbhvZ;y=8Dj{&# ߗe+TPsm]Ny(nx~~+0YoxP0{H'PUT]Q,u{n:kͫN˳SϬBYrr/b cBj*;(`K.+ӑ Ԭ%9Yׁ9`3eqBQU{m'֘yll/z1 $wb8mo- F-LUBfQ>ŶL\1g~Kx"dDe§8?m3ylN3: H$H>Xaf  1_zZ$Erplޞ!ŒS%"b 5#uƏn1,'Kp)XxnoEbW>F *j"1Ax785Aト D:[ 52e66az,mq|}!].cl|E6ݢyh̓Ծ:PL_#ټ&\h$=QPm6ܥPUI*9U{$ hBt ϽZ>;L;c")Pc+i|-o|0'1rf&WH;bt nf?lL)s|Ou3Z苢A{,;-Ƽ^~F15/jbiG/1SHئry>i; _ "WăROM`at"<#4:Hأr/ު; $.WL̰wK[v\a-Fʟ$'kBx'Qan5\gUYF>M 8u’6S$sNeg*&DA|}/$\i!Cu K.x ۊ(AL1}i@ C@FPw'V9$]q|Tp{g$|9 \?4Oܓ>Ѫmɞ#LCUO\eD 0li *> _3/iQFx(boׂ 㘮_O-׷*Ll9!:\pIÏE؆;bh.OԼkC"`l߭Ru)i?iJ1/W!)r~^c(a_ a|Mًlq ڥ못VbJ C"$^p$KxѭPb3.?2)ƷCA8]zXܗ jUfwN[懄GU܂6Ƈ;-&|ořRʡf?#~r70w:*wmPxHM t>ݶܛO;.9ض}68UBQ >#ë]X3We$RkUxӳe$ämS,ZvJ+ Oa&A>|xb1s~ >|Nc#эphېHBՀ(vvlpԶqL2J?/J񍘖B^wINH>OBDox{ {qmCJ>$VV `Us%۾0x]^amFnC<W!(B\  '$)aMx; '[ s}pHڅr$Kײ/\Eeh0.Α4h M l#qR5#E'Ҧ}e`̦ll]d&bO>SaӶ*upj4~[eIaIHZz'Y7onBϢD ^t83ugq/ZTdb9<ڒFc=P qiubnSE=^&/C$wMVIKىH]uDv|/4d)"鑈7\ZO9T=ڏ~|C}9J$2]9P8 'Ҧ}e7n䳺@@Vc{ޮpug X'o͢茖^$~{9F2T]ILߟ\:+>ŪӴ3uh6|_|/I|3 >qH+gDj;Gqqe$J仾(rJ9g5JҖռk"٪qj8kCȨQCv;-w19'>q@d<,QB]&{K-"9kIY ;>|Րg'brijVR&fOxwL>\HL ;$WoBY$?ǖgSD1$8jyw;u龇f͵Mpŋn#II>C΢RbD$_$1sG+Ć` 9-!s N?W۱H1RTVuf!Z7|%d7|u\NL?C<| r^J,(b KabpUU<{Q6$]y MoESwEO492a"iJtp2gaotXN?4ݢU9\(*#ͶfhC 8H6QKۏ66 eMgmwLƧ^,i["W{ 8bu RwzO"(\.CWYnj"J +EĘ8k_Ŗ،i< źo+U-D; ge*ro.9"U Nڴ|'T:* 6El:w]cH^u5||D:ij\\O34ȝR'XQ|6u \,Wuk[|HOn{p϶iZA"I"٣") G UgĊEWP>Db(؊fdR/OLW M \^/0>ؐF$97klbe.|!F+9a$X/R\ҝ`ÅSt~DH8'c"oD 6jEjZ SQwI>"S.Y~21ۯ`mנtj[jpsV}O4ܰq-q8.Rȥ$f [O7sیl}nx7r2{c=ktn)C +vnApL$FNN%GX"^VOAnKgm1tE|_/xL﫥*UͶDX8?֦{gk7!O(Dij[!Ρ+E#U41{%ά=vE!Lو;- _cB`g8da9q>Aoq&-XRx{zwN˅̈́ yVfv7ci5^p N r,xYup]#h^uΌfh7<"|M yI53Z.;TpzI $3 g Id=igu")ȅ$l` $X8k"EmeB: lN$ }$=COPՀw0P_ A▅J3lrI$lڎ!EZEEa.,i^'vCP6 S? ^56BUW}=Ć ~~%Fu,A[9Y*P)Q!NMm .Y5Pr (sM a475B,Gg:yVmU2EcetPk=Hhp8rN f!$J`iH[ 1NN"u=mL+n]9h'7MO!Y lIvidixS!Ǎy8rEvThi6$Z6$vCѭ;oceȽ7F5*>F);E5k 5{ë;1<Ɇ<ȿFqG 7G?@U}\Ib7L胸c7cU|:(}sg62E:̧jdH΁k(b޼eT3oJ uK0bC~roϣ).x(=E\_` :Kg $=*W}zx65 oU-dvKM)dc^R$\AI-52NC8%t.=+xَ1pϷXHLLn0{dZ؞J)'q.TZQ$??1aXɞ̶6]e ow0AqzV(nõ.$$$}T$)+jpi}ϝ۫0AX 3G1TA$$}P$-30>oV}eޤXe)-;<("dAsNj|D-Akb2 ztɯ!z* DD{Il'אY9^"bz_EqtyA~Y-X\}9b{HЪ_ Z:Yn.3Zl$[GRde#A ,DBF}5/q Lv^lӉH)>p3A$mRezbf&%!_v8pu{;ġGEy)ZalrP+*V<<Fdmtm@+  ; ;s݂I&"$ H$Mh\p QQQ$Da <\҅{ _aOvyAIC2)H$H=s/Zqhdsw`CyCA=1=vI"I "GDѐ)t ~^$ѐ5AAIA&h$AA$؆D  DD  DD  DD  ɟm  ψ  ;ψ$AAw!$  H$  I  D   $$  _5gҾM?B #zl:AO| io/ѣ ///'@k!υ] b n띲-Hi⋩@tFBZ [}G$ ! #zHDy.cwC\mwc/&N8OLH>#B!;:#zl C>~A1փB iקDR覦Bs"}g"IAf s^XoKp5/N"9Diߙ6_Kh3m5"9/T1`'IJ+b Ɏx0&^3_'F5lHp =q5#?VOϸBic{!H$ ɯd\l?2 Q{/F_ 2H9+b`o\X8v9$N"ܨ@YMl[HwcGu k kkHN0N"ra<Y0n)C=׈/\6~Du,5W+}g"-cs/8ʼny-Ҫ>Uˤp̏?r,8MǞ7O`'a ^Qpcqcoc=dG_,Mle߯{Y" İ1י֦IL:ӦG'Xp / ^xr.̟ Ys{k[65PP֔ y$jG/j]Xy!ROX''L\s tcI'xo{5@ DrCx}=#rG1މDD z_$=4CjRP;ql;={}/qyeUP5T?HJ1ln9R3dm@?O 3!f<|rOҐ<c^2, Tsg{±~ؒXf!H,TDZ0$ap︒Wu-0+>SG։AgxW)k$z>.߈4=qYr7~Bw&_$ AHH ~|t4:9P: ҉ b02hg^$sx<Ap}ǑM"Mb 4VϭwW5ſj?oĬ46D#z*l=xK{ԢwwcM*n؍ PX#;FhD2enp Jmxt{CHJ$6ṊCv'~7g9ybʪOxL{3ƝO`՗D?85~OVI18t >7O5xza+BFh3۫.joZYEd%%I$ h%T(mZZԵةhvrΜ3sf'sN6Jo^WΜgf>gN)kq\K o>qmZJq+cV dWB ׾'g聑}c9waLu>nGV?K7 aa-+@1#:a+~N ž.6ߌXE`.A nI>?ԉ?"F@a x /"-"ˣ*E CHd)T-96Z%rr `7=l;}ł[ܕJ;'>?G P&Q|#ra@ȼY KeHzO$Mӑv1_J086/o}U;݇(aH nu*{NC 4MkeUIij>^[qL^0X*aXYkc"duOVn#()~ar6VVp;'\MZ%>yBj»אK]u2veI/U.zZ[.ވ^wVs&>~zØua˱eb9{"7ɠ hz⅙H-@jN"cE(>`:vʮ1 -ߊ܍}]QaxTL V9L$CX<8pױ}NV &D#6avea:!]0"<5­X2) -+)0ė <|,|cx9 \Aҹ}t&^6 Xoa4i;,|*B* 1qV kh0 z)7u4J\O#G]#^Da!;wm=@m{%`a9n$vc&ŪW!XHswOV'`A^5[>.3F|ePq$^.A\ 1']Zq[vBVؗM} c1u|$‡ĸ[ɌP?Re> FCpu?Vϟqc&"im: p`$(5/ ϛhx rWՂ n(|v5D磯qP{ 9>TdґDȶL%*P+:./:!091buU1aUcҘhD{ rp6Iٮ=Q4l2w04z#G|37P۪`#Wum+ x [+P' v|)@Н}Er8|x8櫻0kHFOmHyERߐ(. fy$%!k`HlJb<")hTx/f* YLk3իJAk*v*pwNf !qO syRÍcߵ"k*{ !\H}2IpW8o¤1E$پX(UVNؐd'$|0 ,ݝTo:dv&m}E5;JN 5FĖ^^t5T^jq,g+s"1HuLU;؇qj^t0~!6qٮ=/"Ƥ{@E!I zI0ԍv{*ٲ28ae`E8:gT2"9dw8s R5%TM@ɥ=X'f +A*J>=@}7 o$ DW"鉷YBe [?m_$ Cro Վ }L$ ua>i^1ƥZ XƎ'/d\n`]"i&֥y?")C1t`M'hwz |1XM M C]cfl ݸdzpwrkHZx^Y> eu (.*F񶟮I"IEж,67̭Iqh^K"i]o:RAͻ(.#d\>9"sWʬ;1}}>!R$5M=j CEF̙` m&}L _BBxᩓҺWٓ iwI$wb߯GH(H~: z؋3u$X kNXBӵ9}r3%A L.3am"h%Drk:8+Nm;c6a UK'x)I$g# /hH. PSg|^#Y, #&H"ug&c P]yû_SΤ`1b'~ #EF`hMH긐.3!$ E( &yݵl](3XeH4>5&a;G^>t^2vV3l*wpH=sb4 c񰈤צ}'}CUZ.㰥wQy1#5[c V}&Xlס=V5,ےH7oF&c6mۙsmuq0meZ~ rg޾znqh{txϞ1mHN ߨ8pˊ_7#b=7IQ7,V\gk5zdZ3ꐦV,l}vg6}ҝȀPoT-7Wvs>"Jrdu9G dKMkQhEU[w@ImDd"#yE] Xc"6_>B?'"6?[T'5E Oe-I.uUtTq!uN 2/+XeUDHVl1`A&痣}75bnS\8ܑHMO${ѹ bV冘 (7F`77 M0smCRgtV{!_% O.^.V]}?}Wq/c{I< MϞe06ؿ1!e'}E200]t'I&~Ze3 ow-^vP˷X4-ш*m9L@0 ;?|w;&/y֠e~3lIʖNk56Q2_.q15Qt1"|M&,8z6FG 2v ^Z{稁Op+?!ut`ķn&|2ɇa+Tv;#*b,Sӑo?hY:/0[ĆkeZQ$-uAlτɒZnZI,c`5" ".Q\8^G& ۱IV'""=5u~ah(DRk'_K: SUga"0#akTc"ƪ5%Q ,]?L^q##l-;d,x#X.~3Ͻ!kL'#.jFL.Ma+wCK&MDtD$bDLVZou!{K wTuAT̨(;Ra1>ŦjWQ"rUgIn˾EI^I .$Byٮ=Q4lDr0#F:zMdUgKPQr{X oaHݗK_oۺ_"XאE+ ҖaP{rnj=fsf9 G7M]b"),90t rpd`Vٻz]f+*Pn)E8 w9"Bmq|ZE~f'VNfV49K!HZMXѮ5㕕+3 bnO-$DRX,ٺz 5;q _[w++?FWYǾ盳.p}EIٮ=Y4^$BWƥZLW"Eܫ6v);pmXJq.on=J EqQ0gvMgH>ˉ+ɀtܙ#>;KʰmOtiⵯM$)>P[ s:6k s`%~NTͤE{aҐ_\Zƾ׽W}oDN$u$$ljh{̊ȡ04r ΁EYCs_*D "}GeE;QD{.mHg"sO֣ސfd?Ri/I˺ވyvEDHD !"N:;0zQdTEC1o:70M&Dc-a][e~`y(Ͽyb5P$5 *"نɿ&#~~~5Qk_HR|3aI}e(@&G݉z Y#E]}Eey.VZME;M^AA"spIiAAMF$TpGJ"j ?JHAA4-Tz#am~zNRVfo&z2  Ɉsh<):dJHAA4-t9SAA4<=i71E$OTfo{%Y:cilt񇽏˜8AAq_Qf<(wGd;$;7R7!/+$+ܭE0y<  z)ų8qt ;VvNý.;=䇴FQU!n^&[;h+k\dR<@ 'zT$  h*|Tft|N%-TR6hAA޵Zs؊yT9l 'gEOvdRyf1N(ℲJ*[R8TӒ  h܊wUB%9|TDF>gIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_general_ssh.png000066400000000000000000002023711477034762000257240ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:13:36 CESTF7IDATx\پ{>/ϻw3{{3bi2( A%01ΘÌytL9cEEE ߫nQԿwjuZ[+T??o21wk2=gR#^!m+~'ՒH6Ys ۷/<AA|=۩eK-+O&j wso$^$aF"*^ݻ7  mVsO& pK*EۙO"8z>}~AA|Z0\z1F&hg$s1/lZKh8  /__]|J i/+m?_5AA] Tsss%gl[gOȹH7ĭWY$!m62/x@FA5V\[XXں]Xv#p7^Cܚ^foȿjFC:TRAA|gHC ;_~eҨvhJ+JmȯԿ 2  affa5R$eU;Wzz%5͋l7.aZMALOI#z=gv@]-i5Y]+Z  `b L\4Q&DDj04g9s?v͕;%mq2  Vŝ娭Dɻ nS u¿Ō >- zQ61S;W? o6їD ] H>*I$U1ӥ{_⻻4Rotx7V桖œW^p}8jH"I5>Dܹs6mZm3MLz5Z$]ФwGяe$A17QIN=o@nm`|M7Лb>= /3f Sоs*~I`8uTc֬Y~ KӀH^S;`o=ۚwJkX?$Am鉑PH*af^,z#UjM ;/BP^Sg}t5:2:k55( =ѯYR ~F܆QYSȿq&{f܎JQU]wcm;L^2~:[!J*jP[U'`xs3qD8s1^qUٵoؓmưi[q6*u9V#1Ɡnw MEe\*_?ǃnA ^0ޜG8## oI%@I CE/P'Cފ ۂ\EV9%[JWqKP{g1zdJRxW ~Wf UCĵ5/RJmUaaZ9,K;:{_`w7έ9iέgG}$)+rT^ 0l]5HjQ^Fy~ r\fJnAɓ>_#uQ*&~T 4Z@Æ@2t uwtZ$j ok~?OY$G:f)# hzS.pS#sH/w"!{U"1J-,&&&0fԜ[NVpXu4L&\K1FXpno'&Lpu}A'է'AhҎHjέ,#Z_uU7&I89=xN:Ӥ(-ى_i41,\Ow%兤2E&=sL$EMN=OY$ m]HsI zۻuhaX Jߴ JPy~ z-އ>L *ꛇA:D@%U/N5@"~Rͬ/ڈ=UC"+l^KZ #7'?\F$1Q6԰ノM`mZ<~U oV"iIJ{'<  VyY$5ظ$Amu^zbܩS L} ƛVIdZwCq;R wrp+ER[ +rʘؠ_$#+T®xq 8fl6A&zHy=&Hnn(%\Rq zQY&ZlO$-.[_4ȿ-aI"ID[Lh;oNLĘtR)(u"NRqVUrOdš-9; &0q5ʟѷ~xzha.*yYn^Y||nfX/\MCiIĶ3F]Oeȯ@۸v^IJ/ #'O$r[?ڿh_mE"I6&690QO2z{*ly : P"׎8q"i0 : |;qg/k$>69k/FEm*KQ,o`vCqe *_UpZw˜R!FىKī2e(,L -g}ӱCTF]O8r)J긘q"v ex?I+ڿpJ$FbۚD noc3\^N=Q|Mѽ%^z8AD4.HZVnkMHD nV8^+,(R’ -愒H133Dc"WI >-L,<)ƛ:T=ݓ0%Hw֩Ic{"߅HvWyD  k͙4ElcDI]_QHD  ソƇI#7+~R$K$$$ iG$$$  ީHmI  [$u6$AAE?$AAg/I$  *$AAHZ/@AA|sݻ7  OI  D   $  H$  II  D   $  H$  I  DD   |tݺuAt XԣGW^}WXQ@S.$# C%I_Rh_={)_+ T^?K"aOQ,c`kkK%`uXbTu.Q@c.$%XLѥ`u_lŕŎ*b%"ɺp`u}_7$99AAAD\ ;apH3؏YD啇+ H"&&F3,$GƆ Kal}JII󑚚 oo>Huq)\O[;sq)+{H>|8&l_G-ؐ$ X,ES<3ID)a2i;ѣ*4E .{H-\􂭏^}&ق/ mZToV^+|ƌ$ Jĺx#O٘kGͯ ^$ PJENN43vF.PK2<&PIn? >6sqUV] M?bD2=Ho F"'} gŎwG?$Dmjf J.ss5=a"xuz.NIe8~='},zH~^/|d"i%(~L<\س,me+_Gͭ Ȍ Aͣ}~T5X7k.7Iqzq"铍7ckޛ=}iˎȱ p5ƁiJ%$G$ۓ`ɓ'a8="銠$ďP= 9'R$},sdv0 ^5Al3"aԪDNDvd#+=#bK"E'!#G dtb'w*CLNSp'Z+ %V7j_okړH1JMwI49/DIwsp x&Clɷa'qu۷ZG6sUo ''{@dzI٥pOc 6Xz7Q 7)Yqy x|~3{2pZ ޿FI5CakTZzDr-P!iDM-2gD}TX8;};,6!deQ!ORJdx1b1u- 9*)vPWgL9ʿš qc@P@Z][!UOwswrduL\I؄/W%\!Em~d fᓴGB=] _[Hwឪd.w3wBDHHr؆l]8~|҈Uј b%q]AV_Pan ^I""avNޣ=~s0)}< wo@{`DxMh.r35,fg *ؽU/FǤ K3'k#^UVb+vtP?&#=Ku|BP DU*)l}z`mj.H+;g* +9Q :<@pxɪL>KpvYB@c(;2̯.5J$ bx 0a}4څDG61XX0l#V}cxd 2bهGYM8h:s"y"Amꯨ?/3"sw~%\TIDً^5.bN3M*bc>>"c≴/BFb"&.܇:Nw$Eȥ/ wwe<6 CB m q"ysV MCiY\!lHzH!9|luɷ}ig8+.GYUig'oS>ӘIǨx$+Ov-Gb= d/b'fb(kDr>"ٸP1;- 鳰\drN$Y\;R^+~rxܺuK'l_j wNqBn[a#sS:8\_r-(*j/b=R@z~ ue iD8IuZyOɖ㕟 e\,E+emrK4CEDXt W1ɲ] RI(aeM1Mx.{6$a@&ۓ-Ȗɜ9p @^C/Ġm"9awHfd7(ʗJjjk8.x_ZD2_:|ZޣdbU *da: P*/ƎAV F} Yd jGݪ$LİsTdg'c f#m>/_E2צQͱxalfC I1kh(pMQ>b{1,1bŐ 3wOH0xZ $dFKd+P6{S$uu ՜qON7bpNdq M Ri3rwp C9e;8x1F~F6q8׀b}%w~pcT֢j 0CYII!<2lI 98ɿ~"="i2<^; 6lFj/Ŷ")[LY3 4$BL)?L:'- y<ipr\2U3]BNmۍ*-QRi(ĆpqK&CU%:(#cC ٵyɇI6<6C?bRZ4F qP9eEn.'9-NFnr'uDRES7`NAz(~1:zBEуIcmh'f+ss[S8 DR~g AADۋ ^l!C0U"imm݂0ݓtg\}'5?!@d=BE%3Ia!W DrKuJ'+Cz@%}B 0xEȤǐ)n}>mWI'8B]ir9I/=шxD2Y^&;rlJ$Ba7‰tk!'\%c[Ak BO؆m'33[l)2Ả@ve#ʉs\" 7v `<͉#N`"y Y\;R^قΊСC۔8p o&g#;e4mZ >pvrRnA,sbH˨CP"r"ᩉ#SU")G%Z^,Ά'MC(< ZdA3GҠHFM(-ZDb[%[1C[9킙Wsm[Yac /6EF]H#7r7sYCޅgqgu $NuHaK9'*)B/|s7*x |I O!~'Jok q ] -5>ǎùs믿vB"I=㳑 '",}t"i]Ӣu|V|Mn]0SeD"Ɏm H/*D5B9G:.8,ؒujhW|~>21)n@V꜔@ r'!^'%M0|d/O Lw!YCm )|>nX> V}@3<>1a U羬ZŎRP+ kvmdSg oBZȓJi##% c]82S/NOz qRN$3VJs<'׶`ds3\,%wl4U:nCy"k Rٍ(I1`(ޕ*EҦUs")>3 ^:ݹ Ƿ(ms'"K;!}e7Ǎ &C s$&&ڵkJL.^ƍS6XƧY 8qVAZN6ҢC;}&"vTdaLz.G×K;N,Dm*d[,ba_=8lE4~EMvQ:jb\1b}n:⢢R\1֬ ġ ǷY񈊊E˨N}JH]/'~([>{hd#SFxF =77]Y}n.W6~Jii"!u.DRWk[ocmrϕkwaEdlWÔߝ=C-m3r>>|p;<7Hi$EzO* kK?aJ doudžkŨ.X~~_AEC@ZP;jM!Nůu2_UiNa +3V i=*K qgSޕHrw<$a||E!U8u2_Ěب+5^p583Eu9/qY=d .7Oq}}e#%D] Bo38-W".ΗDRE"I"I"Ićɬ,L?] Ip}`h WvvvJY Wއ; @.+X:MQd˟+AV7j?+ՐHR\~D${mN n20SչI+׏HgXf277':M5ݻwqevX~I$3,3z/7'Injٳ'k:W3;j~D`bb|b]A]V'iaXi]1_I  @"IAAHAA$AA$AAA"I"IAAtdA֭X:P  OR$DK6u,N,^,nTx E19rww@ ^ʄ/$`qaaeD1<$(v1yO|"ɆkYOIx+ŃEsKqQR|(v'$D~gggZ[Ō򞦌H~v"ɞ8Q( aLޓH~V"ɺ(N3CbG$$$5 3CCA"I")#М-8-"Ij(f!Ŏ $$41bw@`9"incI[c1$A~`1 +` XR!A"I"Dںc1{J50J*n`Q$IߒZsӑ1chM" x/ ($Gi)u! lUx(oB$uxs8O;;*$Cs1W`(BXb([wP$5n[:v\N0$b[uMEf! wB~ h}G`x!f=.܃I$$P$v㕢r6/kXvHGuC4V!) oD<4± ԠQ.GcclZB"BV}$HoDJD85!O]$Կ)Cm5 Dq[^QWcVf 'LƢmPܨs P"NS^Ų(~^"i.Ųh{?Evj2Rbɧoc`k$H D^B} =spϏ-DWx3v4pws&␔6Bx=Bm:"): q)uš{qለePCCWI "q⤐, ~2 ϡM=W)ԡ8fXI]UVaY4:j6v_=P^W P/K^ɫqsTJ) l ’[6~!qNpQ#Bĕ 4HQSnI0l*"Ű9TLW33N¦3P\v0\l^Eg!nI^`kl~,V=ˈTE're]^vz{,NKy((wM/Hw07\lbٙ;xRR))Cޑe>w Nj <Y^Ny(9n읏pgu961%8c2?l>qJ5 P.wㅢm"=Ry7bRaKr^f* (K;L9.eu;pYr0SKKFvx.ۉ>iu>8è+Fc<oZc\1 ZeD8^CWnU%l#@!ocl[?0!|}80eA>o5k6"NsL߰>ƆDDRQX[4 WBVѶ- ]z}HH'&@:D,+NCQ({E]D$0fsJbAR4E'aWQIj!s^)GTۘuJ$-<\omшI5g kkv๴Web0|{Ų rpo[oae KK5o7jqm#^=^KR*1|oԪ\$F 1s*-H!cƆ p{yvt1R#Fs0q{y#&77W!)?4^ChHJ/`aH 9ݔ=:c71W݃~06%XHHX{:;.=>q+2 9!ILւ .b@ CV"_ ۣm:C2v\eAYIgKMIij[j,'C4|M(`wmÒ`R U6V *3{^ו'1[x5mK( ,͵}b1{[] 8L &4n4onqb-[[RgA gDa'+ϱNK_XQ!!݋..fL8,L[sM!ClD٧XO[gMhRȸ Hڌw8Gz$#Մ?jŷ*hY4`9rʸI"iDl}RÏ=H/`{u|{\VS1PI8.`upJa+PV b@I#XF~ށ|74CPa\^bkߴ'3(l-Cǜh9LP ƎFZ5] 5"y"if&F։FnS5N$?N@X[W!7ܽS ޮGꌑ!n54m( <%[둫`g׎b` ":Im; +l0 16&),H 088**q~P@^3:2,KZ4P3JD2oH&T9?^ oq"ymIoqGZ]$AUʮmW$T*P3AHj*^i8SQZ)n&QQ(/ŎhcDr 6<="iDԲ)1C[vCFf-eϰaeN:Eɟ 46+ll0"@ 6+ʘ.wR2xiRO24N-Cm>+kq" f{ty_^s*xX#fhpHZ pYd'0?<58a^`C?AIy>ekE5. *pN؉gFm Q~*hC⺴{;m8vFob!#氏نGXålDXYd*O^FrjaBpGk>&]Z{[]Qvb0bH~/$y`ܟp~1h7_96^ݳl>Jj3=!4R$;2! XyJdhjARS'1wgS5nB͓ "ifkUmf f8ħ"ևj/LWke0l 67Qc,*e6qDڼ}X81QH^q 6IQɑeIبDd}3QU$y>n,ƎS;"+` d}4T"YUE8z2"*1 YaՑoCzrn];ܾ/p,sF'M)oa\,vŒx\c;9!{ amCG}yaOcH2}OQ0][7 I HʘuwVKcmCoq0;=!y\$g{Ie1 3w\rZ )_h0ƈyQPQӹjcx^|5FCs\VV³jMTX^[$GcM) *ޢ1cy;/nc{[931Y"NjMa:Xcy=Md\1C£b,箣ѯHXKP'Jg;/-XgD}&x#AZSa ,㾳`-FhC!U/AqF!ʹK"y$WZ-,WU;xILRkemt')"Aҽ\R9uex|m?)C{ޗmӰgq;&Kh$$ѕ"~*bF|yWZ(vBCOSH$G"IQ(I$H$)I$?a$,^IԠ-nD>!?/I$;xHHHHvyA1<$(v$$,8p V1P(fŎ0&I I$?+tssÀ=D1<$(v1yOR HD,ӳY  5H<$"訌$ x|T"ڦa  wCnݔ ×E6tj $  lne3JH$  I  DD   HAAF$+IKK#$  dzzzDj$$AAS$uI$_&I$  Zl9н{weO0Aa zA"$IHСC  |y_"Ee,+ 'lmm  ¼X$C,AA c%~kIEM7AAC9 n lڝɏGƆ  h:#z$?$ i:eI"IAG)4GCaR;I???D"  a@""?z*okn؊F` \GOOu Y^aǶ;`X8u%78(xT쯒њѰm C&=$ Z$@{Rų 5{l 7 B.* ͈gЛ&ŪHMIG5ع.6B8Dsr,܏l^L]Z$GAKW(|&g0U; `@"V"i ߥ }Opy&_vT?ÓWRP-۟ŮDHnG$(8ܹ̇ɠE"IA }'N N"d?R .!B VbRƀm(1fzn+=,1mާ_ZJb0]H bdmǝ 9UqnL96"O$i_/+ri%MD  L'$B$by)j㤰{b5PqPƛַ7LWᱬ" kA N1  ɷ>DR@],NDLT<Ҧ}-aω٨LވVaDŤ wPc'E`\$  H$ߩH ݄r2 aQD1䒫fYq"Qswf%F tLrw=f/b<~# JN,@LpCZCAAH~s$aMU.!NmD_QKb_{D.W ^ߦa}-lHHӖ(>Śa%Rn@Mm.5Hq~6ޝEu7jc;uoyynvdWA( (ڢ ( Q1QLBT#ƸF Q"҂l}N|fUAA>T}*>Noa_B:$skYƐEf 7"""bH~HGmC`l O¤]qbM/"5L򩏧51viE\ĐT:!ɐ$"""bH2$ I""""$C!ɐdHC!ɐ|z^z_C"e,|GqͱM=tl3$oI?E-5 kئ7 ɷF&V^ kئ7 ɷFy8Rk:qM=6C!%D I$? \k&$CJ.5q\c[4+q *; I#> CB [kbHضo)p!jd_n1aqdHtDI# P?fcU?$,"H~0$PruٳgZ=s!nC'Y#@V764y~ e{+Djð8|}wU p|XZWExKmq+HRw̺qpPÿ vN`H2$ Iyt3ZhLJ!zs>˼5OH:a{~!nYёl'Uԡ" /׸cF};,號ԕf"Eñ!m$C!}Bf4|w0T69Y9L0u;Ɛ#"g`hPpU1$  {$ mRC)<XjÞs&}Os1sd"՞HǕk!t\.(AYXѰ@qF!VD_bK>[m;/85Ko&pش71p"RF^3?AaH2$;KekfvAp*XlBYV|=q/js!Ц>7*DG6 #aߴFRDX4__xXB IzCҢOL./\r8ZӏBYI+ @~C_0 jHNhM8zGⳭgPX#/|"!I`iaro1nj+$!i~}d*툁'# I$_!:.OI籸i9  K򃷷s6m~k!iŷ(;CZݙt0TQmo; IdׄkoB,SghKEӦ!_TXh!_ă-o IH` M{Cñ am+.5og\k7fYZHk$vpoTx0"?qm tWUscrHb˷k9rJ16qԷv~c//5Ȝ^pYaiHWsߏ#O`ߌ; Id7:J/o!]? 0L(ETp "fi`8KfVgvZ(&DDb@M2$-4` N㫙 OS/ZԻ6/ ϢV*‘јĄ`imvIgQ{e=h$5&}܀,r sI~` [Ͱ\C򏟰:q*bzM%=.._q9 31"car4mʩGm[}k#nmƃndCھ>3pJIoM=ٌᡘq?VåJQkw| WdڶĐ9_n5V/A)Y/|>g1`H2$)9kD"ql3$P".p9c I~(qͱM I$CqMĐdH2$ѫW/΀*elp\56͐dH5}z͙ elp\56͐dHUT(!2–zئ1 I"""7dH1$DDDD I$C!IDDDĐdH2$ IJx{ ""qYΐdHv9-"""D$C(g@""#ƐdH2$!ɐdHC!4`sQ1$!ɐl%]}0qj0iu>T XfHC煤C Ϟ=$֢m۷qzUp[p(DDDĐB'0LGla9(2o C ɶCR uUI8c1sdDeUMEH|/"BRDQ~ " E7A L=x\eHCGExPI K #:T0$Tі!)7Ɛ#+f bB(^7$fgHC%`3<",F&ؾ|)pi@;i ch+[r61${DH>L[:w,ߋyExBNrAUt($ULZ3$!3A/w{9/Wc){8 iTh Id[ɐ$"""dOGBw bdy"-"OȂA8$wC 5΢F(%QI8\,4w-X0.v$&"""dOIb?$5ŞU(ndӼ;XӎQDDDĐ~1$ I$C!ɐdH2$!ɐdHC!Ջ3 Q7, .Gwޜ )e9, ɿ2o2kHDDD݇HD2$DDDDo!ɐ$"""bH2$ I""""$C!ɐdH1$DDDT84;}_jRNUK<.$Č߻>zwxV^ˇ S}(t|TRC*((K(C!tH]|n#RD~Ϋ-mpww})ǥ,Sկ_.ܗr6 ɿmA3#W|o,G 77.H,00"r6$CfFz>_ 7`Str ɾ}v)$Co]3#?|Đ$bH2$ Ntuuk$D=1$_rqqO_m|_m;uvN>O($qvM샾 IQDOXdH2$mk觰v.:V ϯjVm4Go`h5GhgBR9ر=Ŗ_?X`)Gk'CC I?ܐţ݈#3;%?]EQd 0ʭ틘=O yZS]>nHy IZvA&l|9L-f]C\tD|7$8a/193$?t@{(y.N F}Br f|Z={IA۸pxÇC!㎐!fc)Dl?YG!^nǮ I%8W?SaHL C!ى?>u ǰ LjtcT16wo1o;;|`?S!}7݇:cP9b|y9&^.ou_x6^*gtM0Ֆؑ VBNjWHi60މ9%_aŇ0He$ rq~6mpWM#&CqUݷ!$WmO0G]ܾuʨS{LǮK9ʵg9En3q;* :bM7>=ƢCeɐ$!_T`%X_Yjj*6l؀dƚM6 qqq1cf͚$ {!院nu'7By.dHv* ǯ[V qZ b"۽8XB}ɗe"ܖc!2b<~]#RU ?ux7}]cV-<0$ ?C+CC(ܾ 7!v#ڽ|➄31r>ٳgIB'0LGla9(2oM׌wrD?G8Ċk$zHHjfhLSӧ)1OFf;J9}]Dc6Opjc͋% !IHeQi!UF 1a\HJ(+*  (8>w^18veF)cjv4efJL&9+QZ#4}ݔbVby:T .DO0D߈K&<; ]>WDK1^+G,h\?e>LBXT,yzS!O>kIv ! Lhct#s7b;.N/ l[⫀͛UNx9ܑok}_7aׇp|c24m4jںKI g z."CeD6dcD&$$s; ~16oa naDhP\ú[Sakn?Ϫ7#CE?"րC@CRDX\,zcJTڃ( ĹvMѼTZ;cFa'0ۇ7gfӏ@/ꦵ6Uthb|ycMrmdcD\!i1?O_-p~8{g RT7_S35$՞![4χb[k!)xWXfo'TA5oڶX1_?e*W=ed"U<޹<3Af:</`Ce(yVw/XJ+6m[cA'|r'QCR9;@R,z:e&xD  Fuh;C ɏl_ڤ~rm̙3aϯS!}7kɉQ<)d*>6d[;!!9p).!WڎPc ?cC][#l U֡N!BL5y{!r8:6 sv|2ϙ8RlN@W堜tL|0@s`}H8nMqư%A/G֚x6|%N!>ΎN'mF!x7"]"jw}H2?F7$CC)s{ސ|}9l5 Iy y?V9!X%'E !r>D/Au>\Um^)W ʏbD uϪqhu!i*ǥ,Ԛ;]Zl;)?G*a gelx!VG= ɶ>>v~CM?O_bxvɶ ni&{K%ENlէ^B]rHX&hw| t4$"rk/㾿 Sy|6ܹՐg=~q. st(7q.0!$~ ސ4H@ ka"Wpع$ K_#3+ [ 5)&ψXsBrUK|<=UG"onM!'s FMqV$QwɎTHjM7_7IO;qv|=w=T;ڽyH\0H9LyymHl#_>#_OXh^Ӹ Q9 1*I cu|tY`ͼi~r :9,tm\DpGV!l\0Cxp8 J$T^ߍe S#.MLWpt2yrfGTt<Ο}^xnm#&!|YZ|5(4ݘdW]GaSt ÝT6xe,[܇u.ԮS xԶx/P{k#&8?Mk-6pGN8_;ː$zC ۻ_dcDΟ?0$]1`Egq?:y7~{~(0Né5 ᑱH\/&¾mذ0aQH8i~W Ie=x`şGbNT(BB0sIB֮;쏙p^:nBX:/J <Hc-+9 l=$e#0{Y}Z S] ߿߮#L\돠P]\= ]9/؂J\F\EHr*4]\q̀Z?t}ZܔRy폑#Xy9$Y N ńH=l Ԗ>Xq Kؚ.@Oy$G΄ߒ1L9@]`JAWp7D&$_^v5m冈vś?O_UY+?}x|BPN ϐ|/NHvDbQ+EG]~6}C&"`2%ItC?_ȵ"TL xIU:|,ە!>'d[u'$W΀_{*i8T*?{zA@!/ 5|~J<Λ7A|lNCR6Φ՘|)"mA X!$=7qmհ7:I:C݅䫖]666譲5oVTm?YCߎ^>|7<ː[ p_-fnwT/uTںݔTnә/w%Npaq T;.oJ$Cr*R_dG]ͭ$QtiO$uÐ;t8$ aggG=*>3^^DoH޷i}7* wD ׿̱1tΩGݙ~**3î}Gݻ7F޷iӸC3$o}aR^CYRʚGQWEߵ5=[x<==eەR#[ I"""nM뢭i£\vJL)k %>'$C[ӺpkZ{𼯏!ɐ$"""4$C!ɐ$"""bH2$ I""""$C!IDDDĐ|{!̐$""2$bH2$ I""""dI`HчJ1$;l~Az:{aHv2$k\U(G0$PGCC I""""$C!ɐ$"""bH2$!IDDDD I$C!IDDDĐdHv'*$"m?4|=!ɐl7,$@ zCMCS~ԡVzgϞAkQ6[P1$sDI#L7v|g=7!鳱[Ð$"""$C/$C{{$CrF\<,7$QYt{ᨪo ]؍*2, &:MP5(p# ڛ҃a4#S's6CF Mn8$_KyNV^3n= YDDDĐ|!i'ǫ%naxDj1ZT 6ڲ~R(<#!jV54,bs(*DG6 #a/O#ЋWܫ>U}?Y3WSO~2Jbcr_P6-XQ3VM Ÿ ,^.2WcR$/ $1$NH^\VX:/2 `m˷RZ`^g*n~r__ 8jaZ&**+PY (k3 5M5'0]4 3UpcSH wR1P9&^~ m"""bH|}9l5>5YT_r傈뫼8Smf!ZSؖy|RS pk<'/Pq061m[E80^I(6"娜uB%l*;t"J%?CR 'j}$!NA/wWTc){8,Gvz*4d,F" \zl,Y7;m=9P"{+0d Qp'LA;RNn5$'4C2[CC]d+Akhc^d|.$6%;EcA3i7qpMA:"mGUa~>ڃPln7?& |ބXYn-6m"OxGI 84`y:C]jx.:DB0#G%pqI; 3õi4-@E̚(6=q A灅gk! F8v죱AP7<uȔf̟ThsI 1Φ-@4?DDDĐ|!YO#: BM9tr'j$d\C|v{ #v> $_ž-\TV%(*xPyT~ӝT=[xl$' fNNNDDDD=Jc(c?C3!/&QOt?J1$;q"""BIe.C>ĐT:!ɐ$"""bHvuH*;2$C I I""""$C!ɐ$"""bH2$ I$1$ Izs{F^c;Sg}C!I] ,"")m I$c77ZMDDԣ(7$C1ezDC!I I"""$CDDD I$ډ[Ð$""bH2$S*M8 ]etzzWLA @Kh7B I"""*-oC ?RCbA֍0`2衻sr{H-q{4MW ` Ipʏ5Hi-8xq I"""$CC!rŁ yX;?Q azHE?lǥdSbQ\&G@[)qh}8vyH(eH1$o!H*ŞVY{& 44$SPDIPí0؎Ʋly\)_Cy>6Z:j*l,5$jܼvR咈T*glrLEW79!柺򽈴,* 0`!i9З_ʑi>;:>E0}|-"TQupIFiYV0$!ɐ|BR=(j%JOKkgATS)ApѴ&6Ml1xYv!rӂ g bDLO``s6B!4*n!)08o4෤Mjex1<84ѡZֆ!1=lI7,5&oˑHbF#$>矚pW8^V2? DDĐdHvhੜ^GıP"|G$E,Q~}$[D;CJJBR^$#k lGS p8%>&##fb6-yQId|cU.B]^;9$_(\/Nk(GCO(1`'? D`"""d7;- &\U۩a[ IPx`nDF/. gcTd͂y3Bw 8r,ҋ !i,HrW=#S`>$u 2va^S^MZl'Nj8IFD_$1$Q)ӷX6g*&M Exl6*h*Dx{ 6ɘ5ȼ[ b]T I O.ciB"fb/^ǚVXkJH*qMt3پ1x.:DB0#G%pߵC4"/c"B`,?by|BbS0gڶ ė9U0NC>Xq Kؚu^-_3 ȁt:m=&""$C I|* HĚ(1a#Ґ 8ttz#: "\J,߆t2$ /[Oj Uxt=C6M#!iڛ&H вQ^4Jj`PSݽ\I߇R1ˏvI-LZ<; GĦXyes#v9dӋ(H1];"$߄5Ná:H6Ake"$y61$G/nTڪa:Z!IDD I$Cd~-Q^*e"""$C!X[Iԣ.$H$""bH2$k!ɐnW^!"GY1$}Gݻ7?tPk!ɐ.p77eug#ɐdH1$C!ɐ$"""bH2$ I""""$C!IDDDĐdH1$DDDD I$C!IDDDĐdHlz܆xH*a\#p,1mF,ׂ ɮ IZ! ],pTv8:F8|Y7J繞P&""dO IHĖӷ Dc W=I0Wؒ<5`HZEz8"dxwװ͸USpT].bska""bH2$Is,H< cGj,8$G/S)~^6!ӰS(2d8o'$ M o陯+1$>$-CT=֭ߟ1sdDeUM4R^$4Gz0V8 %TFasPn!6mÎ V-~o酐j(zRsF$8V4F Ncbz&aym-|wrM"K pnU 4lkBپ(6u8gā) A %<+K OnMP"l]r 7J0Ֆs jNCP/@˸/*$%4Y1ؼXgn  JZ![&+:WL*]+DY@X('+9-kh%(},,xΖsqZ0x|k GòcEMFР_*Z &O ԗa\""$C Id\Pt(>}T\Gb6 94 m~XwKDM x|jϳxcJTڃ(-Lm0"Ъ!;1E~|j6a1&dR^Dׇ"_V!j?Hi~laqXoaq6F7+Lbwj|n{$|԰&r[*+\s 5{8E&MFҖ+(59_~XuMąkBxp_͉iHNF+CRDXg__xȯ IA 1qr"Rϡ,h^aTvܮ.å/nVqNu8uBFŔU?X3ߖSkW csVQs{OFhh8.ޅz w7M!d B>M~W=%"bH2$ߧ}$- `*S;V ϥMS*ҁr4i.Ē DLjˬQU} U فX7c=/Ҵ;lhҐ]*bx]  O6U&ڿy`ߊ}y/eBV~mQQ!or Vjv<p!8LrȴnZYYo1$ U'vjӶUp:p͘ܧ gUk!)dc:VN/VWUC9o|Mb1#C!ɐ|oڶCI0EYT_r傈뫼7Վ yr. *?1n*5R@|&$UTC\<3c r3Wa{}xWŏKacRcFg`5ƈp,1W`4޷ p6T=U A oX-+ZS5~[ I Z Su24Q ԡN+IzS (Cmޭ6|Tߢsj3kCʳ? zDu |L*7$_1B Ŵx=^ʁ@"l禳 M{RۇcCt;'>UЮ $ z >˖s ǶNObQq s"P` |[!+rDj$C!~}?}esbP&aé"B碳 ppI$#1rTX#ĂK<PkwC+TAzz [c"OR~:׆@q9w@hIETp "fi`8Kh8i BF#`L3 a*?> A 2X_R$X3Ltdss-26fG<^vB &?ҫ.LJ ,.7Lm->B1!r&B-OgY9\W3BޚGR匐?PcÕ#UpڃZyd-D"$4 3$!yZ}"ݣb.-komŤ_1<*qc"D Fu8PbH1$[HڏHWQP\e>X3>fp>V^4Jj`5ŞhjXc2R_;"TڝoZ=kCRNp=U"$yz(9Z"v> $_ž5/pϧ5ՙO(8OxniGǐܰ)\oJ/S֚a})Q;9aXfBRy=}1kIտ擮_?!D͠iؚ](7bcvG ] sa녤SrABu‘kE0s3\jϪqz~z[!Y!pa.P%Pzr`<'$C!ٹݻ9 ;B +u SX1O'd (qr+퉈!ɐPHu57rd=(Åφv?K"l(j1gY<!c# ""$C!Im-C(%!kmhہ:unپfm""$C!IDDDĐdH1$DDDD I$C!IDDDĐdH2$ I""""$C!ɐ$"""bH2$ I$C!IDDDĐdH1$?ݻ7z!m8X!u;B2@TN;ﯦ)u׽?IGTB (  ``Q]QaA D "- Hr ' H$Ź>Zkuv=س U/F<<6a1G" $ˑIxaζ}X5Åп/!iK' #FǦ`|D7$$=X,ѣ L$1TD(TY>ϰً13rޠVCólq!T4/wa?U$%E=#O$m?"0D Clf~Һ h"3޿S<,r $Y#kh:{A$B]'"(oH$I$F$q 888&)E 0WרkAPGg04,lm,3du(3t=˟l47yp]YQĂmQ-"aKo/q=[y2sJQA5Cq}<% "ɛG3Mj1%glrhdj ŃCruyM*B`7'è`_ ec(LF̭uAxQ+mjrp"wD-DEeq&n$CJv* ,s 9-vtjp6/@׬ AHR]mDyE ~M$ISrXZE1d }Ex7EB}<ކ2PRODB*rD3IF$a$h$$=^ك X*8QRq S pz\A%4 b–'h֖D""~)f饧M$DBT(dyؒUNkG;-G<.hF̘Y\*8!"7xĒ"e ybDL ŜY!nY]cd8 x 8_qP(KxZok$8\E7'oՁSƮԜ*p H͘ #&YSDjc~$F tv"ve y[I kq*Uţ.0 #یK4Pn%X fF$S~OLk44ty.Ć"PxWlcҙ#xҡV8(iF[t ўՅGVMٛSY4PȫJ OOb91H@-")ARb` CldkXNޣ1AǪĴ?v?\gt,9I㶉dOuR/E5E+b5$W`|[4u|=_>!]N`2PA6 u mĤ>q( yp0pŻ/P5鰓`S5رhBst05D=@\h7"bKk4pv[xLÁ2NM:~ሏ5O׹cQE#W d4f"Ŗ2P!;X"o)aa[ EN},vL $$=_\[&a;6!gc Dl׻;*me\߸1 l);ttԣ7>[w,PG0{ 4)ίm:My.Q8%Mi{Sn(I3nla|[}S%N?2^&Ӿ.a8%JQ!/P衩suk22hmjZNu |.fvNqW﫷Klɇib2h㖆C>BgG}!HW#)| \@< I4˜1#h w[ 6^AnjHSXKSێBVsoۿMZ1w+`,e ]F.-Ǹ-":7`K6-1\,aJ 7}sx^z]az Gm6B']1=\J<9 Njmr Z[55.s2؀Xd *d/l)cI*! |:nS灤,T#DDvDDarÆ G#D2(ˣMnl<^-@*GT4U"Εߍ\ NJmT$2ҏ܍W,ŧV,vā""3OZA 27!hczzXډ~Ŀ!D#s\J[БNlcP:MpU&^VA[y2#4WymKjp1RlrZp;wIW,[y0-]"YH)L/|VײD 僻Ć çxAp7J,[Ѫ:p+2B^]5WH9X%TgbͬWBй6ƑHskC+1޳HNM,ɵͥodnQjUMW(Prx8n>1ScZM\<'/I4ڇ\|J<ٹ`oyP-p7a cv_s1ps@*? ʔ8;Y0hpgR3iJjZY#i_B{%O"I"[H$? hթmY8ԡ| \->`;cQ~Om"|5N*pū'K8 tL7fK+oG{KgP"dJFi=O<p;*常.4ZIȪeR-aOh/Ӹ2*|VI.7YX}8-: R1UlpRa (N&V-elA$w L N {,Tш$$͛m|}}?Hm!?Q ;H=VcP;zmv6Y$SEsaۑ&HڞޮB53 Œ*p[01vz hwcgv׏g=͕8l\/)A_Sa&;q7ȍ)m/$?dj{| pYX`r_҉(UgE$$~H-=wQ3mȇފ$ hRȃ]p:ؕlWm:*4nR|݂i*qbQ"*[+/QHQ69q{5,Dשɾ[bV Bj~=B•ՖLiX${Þ!Ee ")y5m';8X(sm\ O#uQT,G\feil?QUElkd>B#}#DYII4;?A8YARW"." Y1HX-!pHuy{/$9"`+he2G#>phۮmk"NN5[ŅC& ETB2Mu"!g~M R#<] Z!7pG?dQcHaZNbz0knʛ1_<۳+x1V: !?y/3~~*7"iL#P><32Y̷h^bcbb:*:}5B>GT3`u)clȇފ'kXk홧#)`6%|iPaʮijEG`Dnz]٣HYO}侭oU yFGW^+E3V(އQ&/v6{&㡖KE~H<~%up:w+;6?X (XF!?t,IExxERAT,ꈎGGgwc!|е6#iJ ӟB_gZ:,K1Zա!c^yhwa虵:/[bKIH;n%wIXq<oji!N#dbDB-P/xmD${lzHờcx09Ï/#H$ ERA$_!_CAAG?$_)6G?G  GsG/{$AAEHAA$$AA$$AA$$AA$$AA$AAA"I"IAA"I"IAA"s sê.gP|' DIxdiY,{  LjS(W+ً$AA$6!ưPࣦW W$AAHHI'a LGjhm8{At*\/r(bԸпC#>E:"*hu<4=cۥNU4@k(s 9vJèhz&ln5'8he")$AAH~HDAuU,$w'2t0⃭٘O`o`ǢYA<Դm/9ԟsgD▦WDi|8Β!`4\oF^Ÿr( yp0pŻ/iUɣI#G< (#j4xi#bfL,.wkyT kCAA"")e7UP08IԨ˜ w='p40]o}LGaQ 9K\ kɊ7Q$gQ=G7#`BF] |[v27zug0S! g4E[73zlIfF<є m>"ocذ~318esƐE'催!r#TF  QTA@JR If| ^8"ӧ j0q{pkZ|jlHؔ~$AAXcERI{B3>q( BcbK!t9 qq^?d$j ^/GdxO{hf{l32c8 v$1ؗj4 AQR{H ;Zp+2$$UܐpC ^< M\÷^Ab4xC2n 8w")[:9ئ up'cbǹ|уxz2IZzr L:cEÍ,ODqt<Δ$m ĐHHH~[dh~}ۖ"rV4$]s!")oϠUX0{".}ǰz#HH~mɟ5PD.܈Sauq45Z\[j}HJy#zk&^5еD-`ϵnai(3ɘ>s5+*V@ѥDaER׏/JU(;"),gdyKcTCvCP 5Y[M$%ùr  PÂ{#%+ .=*FE: {ϯ52AiQ&vmTZ}RіWx}y$")Qu V7A˶ =5>} VT~f7Òh6C" =sJQA __{!Q݊.Xd/ÄYJ f73C1B5 RH$]dѠDht(NF4۲_RV^bT:[FGtLbdMcNh!wXI{xFrA)Zʟl4owiƍDOmI FAŋ6'JXI$߭H歁L4i^")x6; ԅ`eбnBԉ G|/?Hr(9 cxoxZ$?x=eKӏ1/l-.,󃏏8m$Vܪ_}VDC: ́KIf@0hǛbuBJaWQBǨ#}qdPK)HB+ N`p/)!~ C~(oFT?‚~pwdӣX-Gpx^-~1j|V$ũ&1.cZRF14yX;+M1#0 1Q8f\<0Pt6?"i&ƙA:SIGET7=_E5Wu( 36BubC(|+DBH8Nqf"dfRs5"i4c",r7 -a"0VER(*3)0{UsJ\? z,jHcVb|Nƞ$TH$[]$ZNu >^ E|#.ĺ1M<^ح#55( XA"IuDIp/"b-:#XpM?r L8?YDL-Jcp0ѻ5 DVE?!Twph8clI1F$۸8'sKjp1R") ie+ZuI` u:JID]#銅fE2M$|^C5 破Eh R1UmD3R _pպF\?R "9jc8K"II\ ?[{c1Erj"}\UW7+3p\ȿ?u#k]$=t_n-n}Bw}t)3iJ\N􁗗W'Ft@7긾5=ˎ©0:qx{;<ކX'閯M"IHĻC"SCΔ!8f=2jyɎk#b? Q[o/ǡub2μ&)s4k>Bٮmu+cb034sR " Ñ TP#[*4TXɸfe A!5o tݵ-POHA~[0#`id<D؜lxNk:VT4Arܽ Q!2Ŋx2ER%q-^o1ǀ<\lùDL`9݂qo?94k(;7u`?H1knʛ1_<۳+5/6=$m/7=@j(Dqo/`QD0d*_kDOwWeG5VU6@6 GЪӠcd$|fdF288᳏Sepݮ(i ebG趍+ ­:hu< q,za-# V7jp:-* 7ԥ9L?{!+F G3xoZ4Vc"` c~M" ҶOWD'ȭ"(X W8&TOІ 1$$}CPyї>( cSH$I$ }bG\G|))-:@uDD  B"I"IAA"I"IAA"I"IAA"I"IAA"I"I"IAA"I"IAA"I"IAA"I"01\lflX҉ajY /6j#R#oD,efbl ϸM$}[/V_t9b\;Pg]}?2Ӓ.6Yp7Z/%BW`U$$ȎV-܊#2a0L !oq8aYg`S~5$pꋼ0hI6UW`C2 ;^ԣ,= S+qmh+C볎.KR7Y-9p wոxmR?HQgx#$z:F0_Y:/o[%ARS|yދ08ʇ93f HsII[qC -ӡtHH${W 6 MdxݧHJgD[T_o$ Em5Tnf<1rRɮHE Y~>4*Q7:kZ*oŧO:p-u(ۢ1ۋc.N<l 1߹yLN;^kz%ChDR L X;eZ*gMmEbo9* qfϜkfڑHvHmV"wK|őbQqD{Z#I"[%ClKp O,=[y21i7Q\ϩ,{P'cC1q5.>z: ext& ڧ)pE :e ]ONAHҏh:C3j$l5 nw(4Ja[P:zѴMv!m2oS f:^&y$fp/|K ƤSՙ\C:ZE V7A+vGh]f0~}u<8qRpXCGyc$CJv*{R$9hrP׼MƯPu-o] &O:vi1(ZNQN׬Hv+C @%WaX@so𵷜wawR\֡n<=Ƿ#h!*5uZ4=ƙ$"h6]8h6qн?Ɔ:gȇ$sR(w TU/H2sqLwgchXƼD}8AZ=̋DE4Tױ؛ĤZBޗ9;f3(}G:pdu"epl#>?#M==۬<H.g")Ydᐼm, yp0y}Zw_bg%ﻊd[Qye4ə}R FhFdh68$[qjPgorN+wI{J߇ &5,;H?)/!~؆e),_yi_x]MV37#Ĝ&paO;.8WϣxϤa@,j>]hi <ġ6l)ȥ \ m\ %aTTJpG ȨP8}IeP>GL݋lqg:ukUwР)¾@W|/E.{ȮVF.SβH r5:2"{oqZ&X,K :t::I}cXl/:9xۿTX{yg-Fzm$S=c[ř2dc?~$J]r274 8b_Bso<{(gv|% *yT 0jꟅ1cΉ36Mmf ךx.Ǚ_Lڃ vG}GXjwc ǟ:ǘsYsB^x3V͉i!oȊwώX)1>0us:f)B=б\Qjy]^h๊GlI87^{\A\ ^{I . `7|XglgL-Jck/<Pp? ""w^D.Lțй ϶2ٶgcp=l)c0YyW,*u5:M/'Xi{%. ͚}SygvOm>]B/͆} B0>IȪeMDZD%\u9MK"xȡ*kNdYV#Q8Xz.'KsD| 31J ]m.P$ΜH^V6|gI$mg1ܼfa*HtWzikUQ^q)3;{]$GE+6"-ȳ-"~,}")SGkP qWāСT,mҶQv$dijΠ7}J S͘XrCpA:{H^3}Qg?]_dfw]/o6 <^ d6J |x<`U8R$E.6C쑄{Ƥ1E.vs(?4M_+B~g]";EҖ}/\7+iyϸ@ NߋQ^CB]]yP 2c\BzZ6} /TC[3\6"cMOm>]RSylKvtuI5"#ҡ4JlwYھiWiQrrP$mogۯRȃ]=ֻTvp9ߑ8QTv|Nt|'*x 9> 6DV7gzNi(U8`^f =Ӏ1Q y9 rmIpB0h6|'^(WkHZɶn<ӾQm$d- Bgא+fB}I>^ozQpuI2$ T/5@G|RB /A蔉 \uҽQ׀B%;QgPkJpafbɾ<ո+@.cA as11?-)K-Et~FcGk/{ ^6IW?/-& FЬH}km\ojͥ:5}7_IQtp8)r eH. %ޛQot3qŅ&>]Re"á k;rp.hQ`B٩õdB6{칀:hJ2ٶ6.)E [sf!tutYOW-% śA5ñ6=Iݯ2H]`#8ˮm19r0"ic8s SؑHy0Bct0Oh[4B+džtsȢH9s\ds&/\OG4+h&/\u/kSMk0\AT4GGgml xsyZ*`c|;3_V|?s͌yePq:A08UGDҮm!Ko:z؈02 +碸xtj\8޾@2>:6މlLNNSwNb[G$u Ex뚭Vʪ|vG*HzHh;\`K ARqJbϼ2CH\&:=B8g\|ZspQwcF%Pn%ep4#>ɶ"((Cx*NH4qRz1?τ?+ٷաCw{J"vDϨ#TY7ݑHHH gHEYAX-tܳ;ָkDd?Jߍ0Piz5]H$I$  0ɺJ$$AA$N${aɱ %4uMcKg;^!vxlM8%M<`& bN AA"I"E |GD`MA[73VFuad^<ƳPDU/>&Bq1$ͨ0! H$k>@ǎD H6rV~dʐ6RvNgNWO4CH{RNUKd\9塊yW/4R~QHu9m:IjYT[L=W!'{2JοU@@A-Y#eB[z<<<  lL4gkP~c+tn4_PsIa;fwkIso|yGۆVQM-g-~.ǡѺ:[#jA)PCѐHA$Ո޽{0ЫW/-$mx%N+j ~Ϟ7&n>%P)򷣘^u s1> vGST$i6yL/C]<}égpeȽ Gu|}G eaҵ|nF/TeI$r:nC4w#JQ^#_V2g0%E{*ONeWo,ZKs u7Kp V<YK캿Gtoݲìxz0asD  $ly4 J5<8L*}tĞ}a7vvӯ~qE!dHNo5fҡX٧fM;͙#4fcP7Go91AA1f)diʑ̊ Eph:-/ե%<yч()/ó+:q({ü^X+2+]bsn/2X@~ػX[S;fñ5C㓴yE?^-< 022~Ϸ55D  S)%j$sxi"< 1gu"Q)pZ Qu*픁U qǔ~(qIU d/ţ ޤHLd;sYoL`Gbd1"i4rQXB1Ɗ;*<>PI"IAH6i{ܸqU$D1SL9{ UmdaFmոZDƷ5ٜ M!tkHV3`=~S@t0ge"93$l2'!Y""yk9<";10KR5nVfi.NMq2|O7gK`5#I$ zeH6Ǩm$ߗ1bx0BcbͩLpGk>ѠF$ ň1Sn΄I6ӣ2tFPQ۝a=p98> f |uۗN؈P @]40IsO; C÷`Zz/Ot' =v{ 5..0Qy8IT>Gsx+EX=:nz J5aN$Gbb&pWY[&^dj<HA$4ئ5d~+xYF$aŨ>BӪBWt+i(κQI1)Q"u޳w$,1|CbZ.ރs Lr_8}LE$ͤ#c!2=I}^@\(·|zdhP'4Wcg(lc/=<:qДƒ3IC٥ЭB{GD0g*&"$ H$I$Dvw *C\z̭5U+Ϝ AAHHnd?ZҔ ZIMAlsmAA6#}AAъh3"IAA]H$  I  D   $  H$I$  ";v~8ԾyN(}-ry$v n+:Ǖ4fc:h߷o_ϏhWRi Z*'oi?(|a0 !j#>f$fSIO=VVVD;A4T5Ok|H0=|:g|ܵ䫨}||P(vki Z*'oM#C>kS"WSSh6A4g# u-zK1S{ No~"9DRO,̏w([\.'!u"+Dk)01YLy ?WwͰmcCyFr8k=1H$ b;+BU/VpԲFلM3ê90 k\1v$ [>Z@nmS&˚&IFc: Y l~[~8Md~ Z3! YzxM2?8q6 !ADR_U?ہp뺉d-H~}e$)wy!$$"Rd-_"}}i뇱+ǥ^H4On`8" ^BGd]HL#RgPAY+G~z8\E9ދLu[(, "اf >ڜHz{{C*'<:LXL?V ͫ3Oހ0WIFp&L܋+ؿz.aX(6vlDA}m"ٰ!r&\F#<`)eă kA$Sriّ1V&Hd"7p|YHڽ4FA$+w\0 [ om:vpZ'8r̚ItAY,QeO#6/CB`׳QtUM|~L>|᫛E(/Ĺ]ɘ3k6.HƷ?g7%U=Z?Gg{ eY$4v%uy/徐 swP ec훃@ڃPJr`(")?TOĖ3w]& 2qR$įr;%4\ ^_ދ"4j=Bd[?,HCjF6̫np8*c;~N)O8UDR5GHK$g^u|*b-~>k(jkERgeO1(-HVe_įsPT9bsO%.og4ܧTmR$ H#f"Rmk c2)8]ǿD$~\5=;W#m$ BH$L D /Hrlh<`'epYjIQM\㏔(ay(-XX􃕄e (ͻc: GY,/r pyZLǃWD1Nبxq yiv?,pnn~g;i~|w#)tXt5r|"V±V9m"=~=.qҿs& K¹3LwЖT\/ 'm;0=f"9@&4,in~41˱uDr(+:E: `(F' 1%>vmkK#ե-邿W'8a&⢢7e6k Ic#2coJpe-à0L$'i$_!WS| Q1|07%TlOJ@tvxӫ 'mߑz=+IAi ZHVW1R/I$)!,h.GD[}~ CX U,a5ڞUʚFm^ G̊Gy l0s\| Ml_CXSq 'q}dQ9r>lQˋP>9Yü}=(2+{G"}(wĐuw=݉ ;vd(_IF˪ Z+Ә*5ԅ8:ɱa}'Xa.8r*BbxJM&*W Ŵ&cvĦ0ɘ^$ٱ~S7a5NQؓ݊EJI}<I΢O״]HH+6S1{kM#&Җ vppUtQC^~F ) jD2{o(A|jOYnC^O&Ea|]Y`I$$ETu"|}e|v'E")Z+GY-1Vu.(9\Lr>C۵?E$hb|Ag=Fj)Jq#ɚʿ}Z\S{62oH0ԨU1ʋҰF^K]Y{Ia(~pkc=!nUx]qQ0/Aw& ހaQ$0ɥ-X&P~ئER5Q*Orn)&-D^mಱ7ڪRX,f8IY@2rYHʇmB:c*]wIVFpu b#t7"{Kp|!ok2]TVKOW#+E#sgE@d Ks1͡co5pe'h'F$QTXS&mDHm]$M6m m5s$ߴm(V$j,mN7E>r<ÈF$%Vv (MTI?Z_CZ-uMMp6 cDr-!f72Յ~2Ⱦ=}=YIKKzIM !2(mC8{adA}g3_'BX[OCay) K}"y DS*ZԉYu{vFVu`t.qr[HąnT2&w0RK>_/8ԉd6RNn?E!0yJ+V$c XQ:\ieEC8*>^|ѼHJxQ ^+.+pcSOrA$H ? (#%uH#&Җ #1r$8Tm."}\`АpN-I^ FtV3rKSu=QPkUBv Sj;TWQ^lƟ.rqpnr: HuKcZDTMЭmt^+G.(B1}Pa60}|uٳ]qYȼ!`(:D2ئÒHϹ H!,DxUjXߴ}x ٲCn]qp\jpo5g-!]=[B$u\Wف8R ._xH& Tl{f6$7%I%A X$TWnodG&}ER☈Er=ȚN$%}flͳ͋$PlwiE2z__Wc` ")qJWy⤪HV`E8`U4b:mU9m8FBz1Z'b\ ߆D򲉇_g}g Ik?"j^c_]5"ɧW[8؀E*<;ܑHO${X4?^lߊl94 y`H唢gBEUg)oyl\4H'Fa?r%,DaèP+bs_8G׿i]gH.; I,hF_Wuq)8IOOOݻ8&HI$qX"~,: fo~c1mv"? vAkp=ퟍX_a]'Gf2Y`+﫴")ׇ+ER9oڱH sR ~ ltl>gґUF]W7kN!+qA.J(WHƋp7j_0G'V=rP>ÍWD,;+^cjt~9d]%l#p2ҔCUO`~AC*?lO􇵾h*Y#?gR UdJ/%\Og,mhT(y;!Ub:^bց*QQB'qšwM9 8{iƻ-W3di\k88NuI#uI>g\̃SK+fFCU mҜcD2~~\c0^tA _g7a}۶⥩ct0 sw_DFn)8Gob(Q'3 cDhw")clw:K&tX | =^OÑQ+E8t +ojk"H֐k{W-{/`طX9Z<8kHZ ."Gm"itss^;$9Ar6/C>09C>)τ3zW$?cjgٳ'ю94@h4F- s͓^FΙ|\q]Dɿ 1>`|"lY٢"ٱcGtI \]]o^|AT#ʹے`3 i#jb6ld7Dpw^$5O 7uAVWQOh4F- s͓%_ikZvD "&8`7 ?5wE3>ftbILB  } ~zD3 ?\b[5")(9$AADIM"m#I$  ڗHGlj^$*I7)R  ڍH^6hc@7~$AAK$#mğъ_Fn'I"IAѾDTHERO~TT  v#FԊFnZII  %Hqx o٨y[?z7KAAF$/ oь6C?Fۦj%I$  ڗHT!yZI]"E*AADɋj#֋&k%Q:/ mh4~bD\7AAѬvEqE~wIp FGkYpȷVoZIjM}I3a8x7a~Bo CP06 ;=Áppf1…  >,-G'M!8DpuO/#FWS+)n6%‡*{zNJʐ 'j%K[B)Ɓ  >,[8Z N&M"8[/ NgJ"Mڦj#y|OF5j>],.OR$2􂩗L  (D(K/k j!; NxIIFҋq]LK$< ,&nOv-DrLdAAR$EKpk ; tD/D+j6ԊEuQ$&D)N"$#oA5_E+T~$^.A$AAD!vODQ/@hd5HwX$˄LL-ʿ]#|H,rH2  hJ^6]@]$oK6ՖzHPIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_general_ssh_encrypted.png000066400000000000000000002150751477034762000300060ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:14:13 CEST{IDATx\پ{>/ϻw3{{31H'r%l::4cӘs""96t`~oU(nAGQ~>߽UUjoPOO5O _όKe7 /o KAAt ];ô^y_ylO( ɤ+='|a^x|fAA0M|_6rɗJݞJ]4E&[I$(ۘ@ǿ/] AA Cw*gœ/|'Ƅ?ԭG=I>g08\9UMzdRwΤV&CW O"#d\h~  䜎s;L~#^ nϋ/J$g K}AA|$pnǍ6k'8%U"̋'v8z߾}AA|\p\f1V&?kg$ͽg^5Kù kA i8  _h^]|Ji/+   W3 p?]`'8 qlI~o$Htgݧ # +aii.Xv#3q@!nmdH7^o_uz#i?*)  3Hc ? nJ+W^$琭VjF~_Xr@  ǠA:,Z}MI9s=@vxy_ Fr?~%L  3iBiP__xnZ kkWjkFм2&twLf,HDDj16gs>4؃7W7kk'7/ e"ALGį8/Q[WKI2nS uܷ'Ō > - wcO^40mpX;7$A* V] r(S iC-B `rd 0 N㰷6$ǐ(={SNm!4j HӸ`voXc*e$A!snIN=o n2 JwRDYʼ:4ԿĎM3E@-I$ Ⓝ{'^)S3gl3]4U10}dHі^*l,&kt[\o`՝ۧP^Sgutޯ 2~:55(+֧y`@ICu|F؊3PYSʒxxvNBo6= /ǚdWfzٹt[+jP[Uklk˹uC]8} ^mKw}gSW~jQ3soԲ?a4z== ]} PV9_X0sN]y䋣)W_" oI%$AeW ^NZT6 t3sK]>=1|c=Gy(cKQ{{!<{dJZx\f]>~Os\#itCĵU+RImվxS×FjX%Kg;n  lss,~gs/Nj)jJ g _qGui-KT -ǥorۼo ޽{{x}iHn8TNz1^>#{QY&7n(H}C'ɯutß',#:(# hz0ƑpT;e&FrHc5xX׀ KѽG a>'*Ԝdm%NV0 G@xݭ'll 7g.n'݅8Q)eu3T ӋҎ `,#s_U/܄>zz,9=Ŏ81/aulEҔwY^H+!Cڽ';7*A"_$i uI6$ͿiF"IDۡ^O|w Rlk1^ZsZ)*M\冽"/'EB~y*jcdZƪYIwO0zHWW${nkiCaGDL5ܱo`ΐewVsb *}%C{Ht=}n2!ACj43Ou4yfS76nN"IDzbmAm^4S_=qf-U}0`vT]ڜD%/Yn!ERW;b;J9i{ްHoSm#bL QwDEWsCaDIP|7jT.y,-1$q/x nERE_|Ű $XÎrNh{/&B%R%(uE"L0'ZW0ӡ'_T>KnHQPXn43pFWs ڶ ma hD ,>i>'X=jU!d7b.~zW^c^mRw_̹ĥYsix ?DB7_y1x"y2 >ݾJ¡j\G-ġDZyZN◪l.f'hrːwW?~ 54Fwv=C6fK=KPu/9w" []RG`Zu56e4]kCdw;LXQ.о&]OOxXSGp}b&-x3&xB˞bguxr( hdv>@Qe *_qpw˜R!Fށy%īgy0w7HaG(E^=L>~pSTձ?GBН2A|˟H`ۺpJ$uFbےD n( \=QzMEz8ADrir,HZVnMHD n~Z#Wg%%1ͩ %$3hРNK$#_%$㢻6"Uס9܈oD 0?[NL6Dfc;$$AA]kΤ)/*1eN%H$  >,p^ZI#g^"7}"9$AAħM;"9$AAVElHAA|"I$  /I$  >yH"IAAS4'$ dEg}  筋d>}@AA|HAA$AA$AAA"IAAHHAA$AA$AAA"IAAHAA$$AA;G֭? KI={4Z[_|A+.f.Py/;{wuu F^"N/UBcիOWŌ T^?K"អ􄕕AD _\_k{g.Py/;D"!RpuWG.:W.v.Py/{I 'A] n20 IJJB@@GWc"(M9lm ،1AD啇 ::ZgT'X~I$SX,&RGx%''c޼yHIIWSz$Ʊ\N[{v9d ?=13'ܶT/Pd'}*H/$1X|FP<IDdӶsp|"i;zHW^MVo'痌7.E{++|ƌ$8'`>>D(rE)NM |Na? w]NjFM% nY8T\[KaŶ{y=t'n20hJ$GTT%89ic&f]opK0v?$DM*vӏm%gw|sս v:=0 mlwL~%ﭼrJ$gS>0@܎bHR.EE߽=-Me]GȈˆpa䍣9t{I}j*DZlw7SN5pji"靍]7aK<2falX9BuoaT?Hħ#Id``I&!kg]tB@d"F\0)}|n^ݤa"vj&8D޾U󎘈\uFfZ2"FъD%2N6BqG$ BpLoWBYs̙%pC#OvH:Bn.B&/~BVXV[A,CCyd% l'ԈDz 5m7kړHXD27i \U'`aF$]Ez19t!q5&oW`%p5o 4:jPX 2v98IWZkDr{)­ΊW<=l$%g!7#~^ ER~qxZL_1ō4*am7Iyd xrn,{2 3qJ޿FIW,+ɯ o=C57UȕxP'sѯ")ƨU /g6/"O:J <+نpH4N;׵)h|+'#VS)rNةDZOR R Yun0'>+Z4*׽ƣ31y}s%!_.?KB)Cm>dғ;qyZ]]VZ%wtv]4c !쇎ìhT1G%2l @޾Gbl [[Ŷ V-^Hq~vaW_p2¾n[a S4$pyPV y0)k ;7C2O7I5VREOɖU ,[T26MrR4DD[p W0V#;㛥X}S/V1Q,A}$\ $aD&ۓw-ȖɜxزAv?yzh۰HND.-"/+ 򥊚FuEuH&hgݚNP̽"EL8kbi%"lmivmH GܒV CI$9#DR( "RN2 nn~^&}1O#QCm[D7Z ،$qr*cPrks0CSr9 tF&{ n>09}d"J<;imW$i5 Ō $bON7`HNq MJ9d2Y3 Ptp Cٗ;8el7K6hزϣbY'e%xZVBim秫*I")7!Ai")#W&7Gd@$B'k!'=VaoU'ER߅7! fhkI^4&R$Wp9lisǏg8;kqjME:~`}*-Qbn(0IKܲ"f{ o8DؐA~u.xrE~dr2*e™Bn$&1'B8gRm܄C0:5i!\\%*rCMۀxdgEkEneOmuN9I9fjDoU1 ΆD %^l/wwq5U$---[r숅-pɪ*\{Ꙩv"΃,BDR<= AeW c"9Dp,1$)%W!3.@.; el[d`"ys ɐ0#h*f+ dxkRX.ܯesu0DcԨ ug# r"rH!K;H Ƥ"3a44ݼaojL$4BWrs۟E9<cu =!t5o]T8I:aJh /f_&ICld7BӇk2p8DF e%kgz%H}/'n-[>(d!CF=‘qqwU~pҔ+J$#[yH]I#9T 6r9\[l$Pձ'"]Ҷ *WxYq$'Ð+ oӋ?adE[,[/Pՠ Ew#W#Yݦ@UWhtYLu +hljRVޘoK$]?Ruxu0ĸ6~kJ_:dx5ߛ*G{y58=Q}9/Ii=JvS\[{K"8۷Y$=t՜Ȏn|RN:u8"SUFFZ2|`O$Vn#ý.(7YcI zč= u-sK ГU( rńDzY7 W===aaaѥ0gϴJہ5oREFFFݻWHsWc" /mP" ']^M/퉤zDDD /*rjva0ʡ`&/C9+kkk,^;H$HzxxܼKca?Y-.AX!_]1DJC-$A$Q$Mf:Wc"Iq_w k233#puW7`уNƕ T^?K"2gϞqsskrs WquW7` _~%_+3.v.Py/{{(K +I:hon{8\Li]!_I  @"IAAHAA$AA$AAA"I"IAAt^Э[7zŁ pqB  >J$wު{{{Fŋ^  >iz89ruu@ ʼn7ūP~\\peD1<$(v)yO|" r=m$ŋy\r?mDEsKqQR|(v'$D+4h.>\-ʼnbFyHPcyOSH$?9䞤0 n؂D1<$(v)yORH"I$-OapʼnbFyHPS򞤐DDFbFyHyH#H$I$?fDG`DAyH#H$I$I$MFŐ_HYcX:1wÂu!o̝b?v Ō $$oO$---;#2W൧(C>.YhA{M-Å߿K䐙$dce;X)d=hSSK?aN _MD7X^\aNh)5SaW\sI(M;#!5}f.\=!ΒD  rQ H$ cS2;'A@".W③ %{a0doHv"$O[}WNyc5^?ms#jA];6β.i~ 6$죈nSk4nDyM_Qx|q7 pndyHHGO܅WzZ[#bxYӈ縺sFiz,m<}] \ EC% .oä6a# `sHR9Z;%.H~"a 7k>v4E2ԗ*zH~H"i͏P03#I&a֋(jT7H~|֭W4_g!t'$fHIBF5q9NIBJ?M5| >{DIGdC띈i[G6Řn𨬵\ c \;2̅8'"H ߖĨH&'!EKd76= qUJ,݋dۮ"ى+ Q^I)Cm]Y<e8r7E^Y=Pw3ۈFcp=! 4< =gOr4ҕ˳[ϓk3\6tgU^<4Mn+kp[ws8߅FZG` QA Nm@VaK ^f* Cl',c"bgj]%v\yVBf pqѨE~34$M\'+y!~<9!k^@Elj)Jm:-#ј{*XUwjaC{!?<֌jlfuX!Dq`4 ˂Ľo\k6!{"N{].EEoX-&$4(k򔐟 'A{ 1r#ȋ!ʪaoC^IVZ DVKmAT`yiC# X7ZEDr0ƬyQ|qQ+pTn`C3[dp "ɐ+f]Ad FZhcyq9Ȳ:qhJ:/Q8H)uw*\]@NÄwTgԭb^aU[6쑸kk片QRw [j>vOGTd,RgnĕEhrkޖLĎ GdBT^y{ 0勅 669fA&=fOV#H{R{K3ǰA^s9|8fz({MٚO!bv@v;w<*.5Vz lh[W$H?DƼ 縩Xw"5MRmKYW#"ZP[X"6*K_4^F )^1Y mNanh{W,oh7|"i޶4^ d/ǁPȊp$dzC"^#IG_A,o{bZZ"6+[N=*Ps,JTKmMΥa)pDƑ*(`q Ƙ(h"hC(cm]Q$ #VV$5"#fӍr\2Zg0ж;\eʝxI o̺Xw8=Cuf8Z# mc)W[""i)xf˰}+4!faYc+s$[9?=dW&Ad@{]1bσosU44^l7ss$ m/cIs/}y dgWᑢGm4 ,lvc2T̫}y- ^+qqN5CHz=XSg W%cOևqTjS5\шIyR 6aĴ2bH$SzD:+nՠ6Dzb<gb'kUa63= }iʽm,8n*fE!$( U"$yg"01cE<)^K!CX%V c{y58kh,=乞3۶\ڌ 4WVj&lz{8rՍ (";V$Gkʤзe(F<[Q;A c番Wc4T>%իH`;n9?Fu%M 4֔Y-03 pANŋ[ؖ_Lv+bcީADQSM+#fY:$/u[rW:qle"1TǞ$I"I"I"I"ETŌ$$DH믿& Ň(N3CbG$$H૯" Ň(N3CbG$Hv$&"H,AAoJ$ BSŌ$ x|P"ڦa  CnT ×En4X 7ҩD  D{#͘ $  H$  II  . &LPA"IAA,@۷OEjj*$AAa\$Қ%RW&I$  "O"2I"IAAbO=z2~  S༡gϞ$Hr? +0l0  py×_~"EX0p?IdeeEAa8o!=(ò@ Ŗ p@""90j'*e8_o e#MDR x]+RހWqi 澷뽗nT@XO8pۤ`_WUt%5eg0clv-!$ H$I$Mھ/$g!P>[3h,}+EErС ͈PYb $!wjXQL2s2SY~i!ҰNֈd0$tB1q"yacɹyz\:Bň DD?.YS<å|Y GPQ d_=#hϸ z~p1v1v- +ƽ3W\Z$ cxT\i^$ׯ5Ec۳ؙqߎU6++K}C(8t4P@$Eᘻ2E7#+y){pq*dP(-cb8C0n='eRv:Ĝ@&eXp:x5*h8g$變Ki2 /`&Uvz9T>SZ$G?ٙp{ n!,(C=뒇'Y^{"s\Սr4ʵ|HI$ w>ȉ'D׿E;h(ڊswQ# T [o(P(dI!+<%QHĴ//1R5jiA [L.@&lnHr+"A;@cRP  tgX%coykCagm flZ$' 5{ 榌ED4lS YZZqHDZ0%q)**U89rUu+4; q9}"F tsroEbtR1UcmHs.HS%i$MH@\L_{29n A~g-F!(凷#D,5!1s?ACu,ib= 竕( R6BAAam>7$o$xP_3$`oi-Oud2(9\A]SYqBg <^KF_ ҎVA~1·X 28=0d3^bwmA)VߡIN2v'8}&qy qe˚P ~Y0+lD*f;"H$b#˟aCE$AX{.#uGamL$9I_-2ȶm\Z+ͅ~Lg˗0vz> ZzrE䕹䋵c&47^t9lSRۋc G"V C$A{$Dmd_+L:'C/L hxAf<Ah1.J<`k@^Z`7"'aγCpfHr\w%2dZJ4^}_Hj@hl=jE-̄{ɐ $YʘT=ÑAH3""caq&&(rțᮩӬG_ w> X 'm'0Y$B'd^X1)8d؝heP$š?@;둳i˭1L=$AeҘDH ƄQ-KLJy/.cs?U#L"ռ"ypw[I~ƶE(Qx (bP!,%IL$xj$DsU$cUCr,>pmjcR''AJCI82m^iZ$l|ge߰O -݃DkKǴ(x ؓ(96H*q|FŚmcIH^/~xN$bIHAۇkLَDE2ex6T}P %b`Y:dś:mU ީ=3Jj  5܎H^uhp5}@Nm{?̾?t&@֣́,w1& b<-ZCTw1wPwLY|dɳԕ@"IAH0 'wl]~p| |0GAю$$߹HL ${ghI  $BB'w,+l5Iw ' $$c@A E0b=nnnAAvA#H$c a„ 7'  7 xw, =  !xI"IAA| ($AAA"I"IAA"I"IAA"I"IAA"I"IAAHAA$$AA$$n~-.A#N^X {7ɔȼDQ?LKAʩHH~~FSUډdfDWN]0,"-Fa!JfNUc/15436f㮲VWoe 77lW np^x G:43?C$W@8~W yfw%3{l8XƳMNcmǷiTH]Z$wC ~<Ľ[LK)r7't;k,q_W=GEl8xIoZex~-hTk>{&d2 }# /t ϕv\p`P՝!\V3l[]3gDkϿV$1&$סicmF9igۉp7SzbSNPN(B&eIn٨-y4]Y2FĮo!{/DR!c!*jj\J6}Q1n`l̞,O(hгʺq߬0:3|'=.Rgu"F D Bz4+!ŲHd!si0We 5ޘ(R[Y{ǖb0E\M 5X;QC$%18W1\lG$ECu05PޭG1pJc#>pSBqX?pTֱp-rWV ]RBI5\/CZ U3KA"+w^suPgE+ 'ODDqzN e3tv&ܼ"-%*5ԕo0ҲHz׸m(Ǔ .?!K@UU,n<9Y@,S&מfxw"+*-縘Nyzta(Cm *0ٌW7sN5g*{wa٤q /%tе(Qzo;fJ-a섭cit}+f勈;((d(V7j,\]:Cb2~! -:VߔiV .2h]rjx/#N}:_y~c@CeZcـXqoXQע!Čw(ok5;94*$l3 p.L4x#\gbSCj48ܭ>3>Ǽhoظ,at݂<]kzD,ayP}K r j).f!\׻};˱PYfXG T5+Px1k_;E~=Xe᧕Зbٌki($ %-,T*dBlI$m-6QU5xI$Qk$f8EXuZ<@PvlR2Iy*4(6`u-Tpo5|ko&rvIdkUTo3Hk} YI ըAP56c.JxV<SeUjZ -16{va.`ڋ(jЎpf¼P oce"D: âјuDR4PԗM^H AA+W?¦q"닑'G``0bv@q$,#H8zeZnkdc.WBe:;Zl J/oC-NZ=*Ow-$DҎB4[\9AAr,Xw/T<2G帾7!]ptN؞EXHr/s@᭶߄hOI\ɱʑS\C El\ڞo9ZyPBc6; }3IhH4~ԣo`+ш 0H|AvbDb#mLpyfPc֧1]g=XCpr=kL::ɏQp;spjPs"CDCqGCa6c{%f#A+e\%~Þ%e-4PƊ7,mHH0iKpˈ>~ ]Q\:?tubalid+A-:=PYy6nQU8SbO(z a_lC8EftM:%N&S$֗؎WK2.8z% $kX6{cl- ú-8ֹ 5I{l6[n nb~[m$)خebG8Xn6>qqcrм$צx8k/Ձ2eQcٹt:Ө#Suu0tnYu|!KBcIZ4_[fes<-+3)tKIPqlթm2)%V44"ou(=^,L?[& =WTz2C'C~iֺ3X0% V(DwS&VLB aSN+2lZ}[Ʋ=YI,3zK=QbDS T , }㐣5{Ck$ob4')3":0d/( YQJYjݭ,cL L[,P5 㲱t5V'UPhcDR4+n꠽{F6)¹(ga8d:3 h$ģL K\N]n?E[yPc! EÛ)]^E\=NKIjђ$#ʜ XzՇ1Gg= x)!jh߅MY%I?,Mt3 g/֣R^ޖ!-Jvw\$)[u :O u<-9m͸١zġ5IX{ :OElӒ`%%"72>4*֩6Ia[-^YC]'k(QCʚ&"4'"i, ˍ>`9Lً"m L8T~ e5hhjDMm*cQǃF~x<F )Y C2~qmn0>?q8T4 ڒKر2"CIVqE DR'|E>_$l\wF?1 4-(\5f G! } ,7a8UǣA~L!0.e:7͆H Ϥ_!Ց矅RΆelڢ=8yzM$/)>$J9k"i?Kð (|OP?LD֧Дt q-S4fǘ'")-yc1@dyj[*;y&,.lp۟vtX/vDZ;oaNpG1ZsD2 "\lԣ`@繙$%FlEhx q 74ma/TºFŏsq;4")uUFzFs;fcv`B/æ÷P塸cxwo2 u-(8#BfNeE;DRG*B5 "8uM*ƈPc쏚}"*A'QWݥd,,(K#h9 ޳/:+_"}f!sW!!&ӦbFPN@QqCCUp A& AT\"5V6kq0 :I2!bG_C-Ǎ!("#v IE<a ?왖Ct%Hu(Pq(;.75lxuD$|ٵ<g`S=C#l' qJc 46u(7m ѕ5gqԀ۫MeW#,y4DИxDX8A<<Y =c0VGf8S^X\( /Dv%g,N uXNc'ܱ(K l ?Q9ζI:2\ Bn*D ,t%NI$7HeJt⑬W&,lNΊu"BQu6נx]ۯ ƍC^;y=ŕKXt G$6?qY(k1C96.|Way+xm3JPIFg:Z58^|,`+6V{J"i:'r.嗣A8NDӀʂ,[=plR!x zk^kE3KV֓FQA,lv U*-xH8rw޹!ơ*0ȶch$=M]@-AHHeJY5=@M}wJA8뗸7cv?Z:&gLhQĢaR;aF _Ni3n4_L"R,~h'ft4*OMCYԳ/C ^W8LNU;GF"%dMU*KkE$[2e1Yq{h?v;TXWQv侫ڐUXpC=̎(g{U8ux+3GbMn3ڸHZW0#(Y?HFS5G G-5ۄ$냥nxY,p;p&ٮ]5EfhS l=p9UXH$1Tbxc ČǑJxF(Xz_8H+zăFsSgEc%mD L$ ΡFqQg6Z\#I_ N+E͕ȃ I?6 IA a]8~;}C; SC7#7L:@"IS1y/d񿣸)](^IIumu 7<ęf7}M܋sJA=7HµAGˡ嵨/_&N II  II  D_5=.0~<[RW#>E4O3 R!;ɇ dߟD`˙Hoͳk%x8u_w -ۯ“w)N|s>a=*qmHǦ8ڥ%_}qx":{im? ư]~@3C*űPׯ{#xl8zL.ӱ噑fGI"ixo|Z?{G(}u$J_sH01543m4ø9<49GpX6@8\6;F$$߸H=bpl_$]5\Htl?EKu9g"@&W%~ӊ]xauSN/1$<סU8Vt^5q+DX_YT8XWHsY=~\YNfHt9>C˫Y;Pdn{%o?'JlS J^F|F- g(S&U)=nr_ [@5퇟!=a)|sjU"D3;vF*s|#gSƈ[TGɡY?0yKhcX'c\F6_IɿV,H$+G"F_ĵM2̆,l!A9k`>6E$$VPTi6+*dEINh7.ZPEyRrjTXRU^]crǔ@VAXq=\쐷xq Ylv'0c}9/P5Cq}Mu"d.߈rk8ht{q2SCY !n$]1+5وu,v]?'ğH<`^cdע)N'u"")'񰬞TԘKT#5xr>{;"nZe [f"7zq?,. wOD<?^EożLramI=>EFKGu")<ϥ׽ꋭUѥ~`Ηf vƃAzX <,nm dxcF(w,-NAɖHaMθl@lyD^E×!IxZy^d["ߧ-%}Lwsxc @>z(.0ƍ?BCWzxIqjZ4= z~nl0zJ4PԗM^VD' 12:|S(b#Z9Ŕck/FG@Nc2AZL>`IA4XېzUvLs(ig5#,v|3O+X&D҉XdYlz ~:riL[+1&`/^4+qsxctAPG'H;lpN솇E3Ʋ/Idoc 4\CjHq*h?t䠿t=<a>nv7yFו̥۞AWz.(dtxhe: x$kP-9hX#aspE2JtooALѠhѣ9&rVf~c2HY/OX_ƧS{lT,-Wu"8E$ǹƾK\}ԶÒ\h-:=YJDB:⽬Lon#-Xfv<$ȮT*K$tVlNTg+SvZz }b@54O6cL&6=Fs ioG]$M 2b{?*!89MC% #"EnZs>1mc3(k)Fv޿_0Th'EzޙEC4ܫ].gBz=܎XvٱcSw{%=s2ks*AjO$h#l%4%G2@C$fC×t+-}w:+_L~^yaVFQB\E$$&ϱIрl.EKGJF:n!xgXCdX{1^b'R{"pGzJJjY?9H$ީm$Lӳ{7ô8?E[uyh_nQ<){Q5\PA|_ϷAo@k")rC|-ՠ5UJV!|Ia16[&bpu?\F'0^h|.x·P[^&~aHz!}8U$":1\G*'T4TJW!R+k$YZTW"#MAU ]q\ ,}xf(Ii(2ޤLR1J|p " _{:u{NmG-ƙ/q9u-Bƺ9ԣ7TІ6'd%aP6^^?9lG^}# VAq(ټ0i1ͧq&+Yi8|/TN{qP5gc0[볥 YQ@Yjo/I?~a0owN%GICE[&Pg1leERwI~kgZ2b7hbғ(D$ݰQV^l # C z[&UibsG Gn*?Is.ŹqKt ?VX!`AGjWDf'qX M)D{Hl*d/WoPG;Ph7?e}l0v8#inkz^'B H܍׽.di#% \ZiwsRfk7m2{`?^^?9l~}cXvP~7*m*@jPTZooeTR\d H@va,D2ؒHD|! u2&E#4[%")Y,7k[ XŨ SRoEcZؽijqX*ߏ7g2y,vTks0c&,ocRDCNoH$Xi"fa,D}~dE$Y/B:wf$Kg Q-r(WGѸcM.|9.mܠH6Xu JʦJ}?Um9n8!("#zv9J"-6PF*(5z5 g~N |#I\&}bVo~Z:s'āk uKW?ku*fm6-_iLfbI YwcX=Ӓ_R["H6?|Z}5.ǚ{*ZbL0H|Q:D̩,}5W!}8OwKCdGDkCEWVW !AKݤ]ТH i ߍ]CS~ i"j^8Vkx{l$ %\ ţHFxx4V$KXr~yʮ!>xv9C"9/Y^ͤϑp7xc L$#]-V bw?Kp+T^+SC$#⮚2C =_eTd!f2p9sLPkP: w|oSdY$«Vy~ %cܧ!=i߰Ư޹7yqJL+7mt&ZmaMTddzdd[qYx%M] DZaN!Gk$H.d}t9fpؗ?tnܲ!N,đPq,Ux"3l򣍼Զi`Tn\)BEWF`gxI =Eb")+x-G }s5rb8gtۖGPH2۔7Jn 4d+-m9{|@.C=F2.wYG$Mf<7az"(=Oz(J p2RaݸSڀƵ!|yr؉]m>g|X)鑞+~ +gEN:|yaTdW eb!fyma2V#F"I|  H$I$  H$I$I$  $$  $$  ${a |ɔ\6o  D*Nӱ噑3z)Sp2 SSfeKZ?E饨Y`y8F`ϓLXj\[1@_Et$ oU$%^Xgs W[G!s"嚞2.%Gp8bC7x#AAHKE~M+u2~u|߫H~͕q #AAH~#n$q!9' Ps<%JòIVdi~;iiN*2o E\@%j#0w[!NM:>UumcΣH!7"rRLly/q[(nЩP" DԱTkn( ~]np_JscH0(Wq߈#>ZPSttlI{ΐb *Z3[_.#O@.)ͦ+eSkxs 7LG  H$Ip? lƅwpz\cgD@QF%!=;2 5:輷' 12̜ykO11 o{n×cONE{H06h1"03 qiyhԗ uCq Ærɣ`?S$%p dtuIS|rwc<A z%Gdw8"YS {<Y5]}12 F(V4<;Ccr1H{qi72󓮡Sat9AAH~"u:s^"[K4{-66MaM-t1Fw,&;>#l݂^Dp{K ^pRã!f9q{tװlܨnB?-d &ҹ2gmjۢHOK|CmNQU9L#p_#XFr  ?I$%>x2/I&7wٯ];UO?&bR*rކɾր{ORyP6ƽrԪPP^~i|,p=F䛠baT?Jĸ.k d'UPcql dBp6xnSNsQ#<Nׁo`&ZH  Ds6X'x3kɐ5ЙdF21 4-(\5Ia,"xƈX#0 ȮՙD˯IO<'}$+tD$g!\׻}L$/a«vu͸(xg,33<AAHSE524 9#\WI8[Gő@.)L!wZHJ0%l,b}j{xz,cZ{ވG:?ׯ+ 4HA$IdZPpG̜)S5W" " Dpt1FEׇ#`L5#-Gv-#L&Gq&tJ{:HHU!, !4&%_.Ž򈓨ЫR2GA%4E(StO  $DO78%uͨ*Ca9as Μ(5)a,۹SY_nS h.BhD̛uL\礡LŇX("~@_q(nQ?S$>$AAWI'Q|8lx'B[yg$w ˸7 4Z:.] 7ns',M #:4z\ jn`83 )W QkPUc8;#U@CRr<&Ј'AAH~")j_c{PBNt XI=R.b즇VDҁJA#^DBDWh ڢI;EOA!a'rDR2IT1_yK|z#l'1hCU!͝WEisP\OBTL Cl  ǯt碣xC_9[;stQ<򔻨h*;c1cH?kk$y˜ W',L⎸Zp]]${cÑ(kOK  .DRX;:= -v]p*#ʜHv{s &pv2k@ y'p;0II f. 1E6DTU8 AAH~%iA}9eH 싱+O¡X=ArD@[5s$]v-O>‘he2UHi;krqic$E".v6}[ɄxA*1'|=ToI7mZ~7 Q;nF__8Q# HW :RY5.}0>z.z-τ3AAHH֐x‹2|RikPW S`3 AAHHAA$$AA$$AA$^V0`AAĿvh#"kL  ;#6NAoAH$@$]I  G

sU5?>Ho}ηgJ.5q\slC!əqqM]pl .d>|1Җc!Ά}``WhvpEž/7m۫Um<%$X:.ý9. 7H9lt: ^/?EۼLzJD\_!I]z? ?£G K ,;#"~W-v>o/7oR|/T60Ք"7crAv(V>Jܾ GyB8xƵ.J0ԗ0I!i9{/p>~_xq\0$ I$Rg|5 a:FE"nv , ]'$"'-Ĕ$~\V.<196n=MEܔϱF=V MX`Hvϐ|r6C!ɐ>!i7`"?t Eq~{:<-\/μ;0f zO@9$eH[K,P=$u|3L1Œ`˗!M80B4V1+عe7N^Ýe %?#|LSFA=j W#Ƶ]l[} rnLo h6wہJYܟ!nH>c>^_腈p>Lu_ŊhZMX#WN,)::7o;lƽxGđn}%?F4| ? +`85BoL{u!Ğ!ɐ|<>vk0d%n[CR㙀efTǧqceDCr5Iq,E`袑ǖ56%`8dfHRII8X'xB9JHX2cƥ XHи6vjE17#1n5ҥ DXf`~}iꃔ\= /s]@u{ J=HVvq 53 ÕvXw -Z"S|.~9j,?m'mǶATE"2n;x@_rh\C1NYx%ýe\2$ՈPܲFR\·wM6%9T D' ,*}*_LuS/@2DCcHy_CQX[sD`Hvi E#fL|>d Ð\_WIu{({`;$C-# M!9eg|땅 0$ls%ㆄ"8p|<ی[-|: }GHڢ=]9vag8z͈|OC ig$̈́SRyWִQdƁ@>}˦:fB屹`W IgZ[cukXsaH2$NH XvRM.zٴ:-.e'JB w֍T2$#نM˰uS 1pӶ އ3u+q^ܙGF6^x\ |]{1]r rzyvmd0kmXA}!ݪ*~Ō'}2$ԐGĦYA KǧFFm­a/SZraH2$Q^7Z UpbB:_E֍eIT+l{y0$߳0(g|2 )bUd,m\wJ܉wptlď I ԸQ۶_фkk|Ѝb`OBRc2ʸ;CzAk 2 yk1-*&xh#/ni:dd+703̐dH&a A4A%l\pj\y62FTݾ麖(BXIbF8x6uǐTǻsR7BQrN9kI~ edv#%ڶO9J΄Ɏt[-l5p Mņ a _?B4}|\=%;p 4ee9Ǎcc3Bڶƀ%y2'CR!(4Lw ^cWⷢJd3c//&ψo95|@mC>Y  Im$J?H I$gJ.5q\slC!əqqMĐdH2$3%k&$C!>@j:68c޽͐dH6}>C~1P5q\slӻ7 J75$RBw_r\ӻ:9um$C0$DDDD I$C!IDDDĐdH1$ I""""$C """!e"RDDD4/ ɷn"!ɐ|) Q"ƐdH2$!ɐdHC!lbDiDDDĐdH3! o5Y2$!G=,5:NXD?'h{{ J0&Ԕ\P8kڄ$ZVmGMSH5(),AQas>Zoԣp5DDDĐ|'BҪG(^Ia.)Yy1!sukHDZ($zQodD@lF\2(GKHAJ$1$qH>6l]9E0%0Fc[s BBm0"6wc57mC~0ĺ~W#x"|v*(C-zT./B!A'!6 !IDDD w`+7$bZx:x {@]r-!!Qt2$!# 2|H*15saO SÐ$"""$Cu{~ t!AbKH dBAlDG"aD8t"$y61$T ᇣ(_Cb}- Zr3/ڏ`67An/t"$y61$ $C!ɐdH1$ I$1$ I"""bH2$E|?DDDݜ~!?DDDݔW IB75$""C]~HD2$DDDD/!ɐ$"""bH2$ I""""$C!ɐdH1$DDD8iv׿m!ɐ|g>? ^/ 88!!!ocݠ.3t1$o ^oD:ϖ:󃧧[>q 7{ۃ< ^-{7e~PP<<<*1G]u 7ug0z?_ `Sq 7;=u 1$ I$CH;k$DbH>k+'?vv ::􁫫2+zE8wzWv3$ IwO t3r~`O"C!IĐl_6~ {`;$.e 6Ss?u:|s> У%BFHz~ mm'f[ã+C! v2 [>8ow|%&ȲN/PWߞvY>C1epx /C!I䳖]?cOK1:K`e|<2^gp,vCp|igw=O1<_|!%C QnF&Fv68*p0ɾd_L} #Mpa#˝{d``eV0͘IH )QąƢ{> j$tm:zHVbM!q?} ҷ~q,_NXD?gFk;#U"@C3Ǧm`*ك)> Iw<$ f/Voʕ+'"11'OԩS>!o4$ӵ}q*n2OdI!\5mbLG| ڎݟK,dzH>enȎnn6LUqǭ)$|3Zt돩PVmYa(=K" $Œ͏w!"γ|c B|ӦMz˅3R`0t"7slRp }3TH*9]C$zGBeW+^b||<,?~<&L`6"'MddRR\?_̟7]{tܽ[>ί€!7-|wkGtod H]#DlqGIlKm|=2**#DcNn4?'>.Ý߱+}4MœQV cU!F#`YTTs_7uG%ssy2)[{KloC1-&V\e'[ȗP)2 .n? "2jn #=q'5gcaƐP8KHf`e=1e_?qͩߘsrrۨogBR:/m/:8fQ A+*AU|_<~F8OD8Y)Sv@oIVjENmAmCRnU@BM$n(56<@ok0iCRcIR>y<";O{l(C[.hrF1z /b},"CmD6dsD&'';荅d8ۗ I;d IHl'ð? .DH o5e e5eAf\NU3 p%B^c7ؤDZo>l/w }o#PkeAwUo $M+0 a+]] ]~RnLO"3*p"PWgE䫄U$QF|f%#GaTT<z@vה/ &9/"_($G6œ"lmx~j !+oBhxSAmԴ~Urn2i&|D3m-/dI kay}jܦ BOADBVQ963$MOmFN26\Hh 19nܫka5(jZ]Zy]=[Cr5Cۆd8dޒOqdj'BJ C2)NG Ļn +hlxQ[GJ}A ɶٹ9$cyO*uv2z;da!2-Qo?Gb0HU†C+\1.71wme(!Y11$ZɖlgQܙu6$y$P|ʪ!ߠ@($txX٠_r/ eYQ{o($IIsπ(x{&ض*EQ_"̭mv>is O-y]l >D]($;}dBE6GZ ɗ>o<[0gHbBF՞xŐ $}i.%$Q5m~jHE;[FpSϵnH*mnnMsMbSH:cnTobHg~~и= lHdbܐPk:V |/^vܒk¾ɍ wc=fC?x:my!4>}3;5GN2 uWa\O ݧSϸoÒOx:5 I/_dsH@BClj!}qDԖR cyˇ U\x熤/>;ktK7qwvPs,k %61?&?Qvn\|õ]jDČGҜ/^JX!r.K?-ID0E,"WEs$/V,L+UBGĸ5 `& T"7wib0gXws{<>/ꗥy'Q_sӏ ߊ׵F,{k[$UB w֍uǰ|;'tCOm/ ;E4\[Ѯߧo JG7eHugӦf͂ IggxvC\.=ҭ^qCo?3?Ps;Q1 HY/mĒX9'ёiܗq>fp܀?-GbTD4]i?$_ҧC7cy'$ss~܈p}"Tz @_+BV2ZTƴ'pABlF9kPz8Ϙȹ|!6{aKSJƖ2aÐ;: &MW IwnIWiDQğm Wy&"#(H%'ZCR*ǰlbF(3ȾZcZa}Z0?MP{瑴0 z3*azNSy0V܅AQ/b|zCDGGwz戜>}:/=?}t\յq1vf: .qBrk(R2#V%> bQm?$ Tafjnö-G~??$N ]*A X6MqHvR??[mz %X=6w@8]T|Iy|~PYVD2"gK`P>_.f[j\`(,$K_Eg@_Bшot>5B[ky4v8(VyE8sLхc;7*0[ Pװ€!v ޮ'{HRǟAJ.-R'IgH|ֲj-%գiKtRx㟎}//g+Xe/Lu;He3$5$7ͧw2$_=/@).x356D($U45 ۼJʙJPsޟj+U.~otC!ZCR=ZR_|v,d@ɹ-HH$!wlŐ!M'z}1H|>KR??]mktbH2$u_8ug >‡~( zAFtiU!ɐ| ;uһE}_/uYx$uf OW.$CiU!ɐ$""qkZgtbH2$^C!IDDDĐdH1$DDDD I$C!ɐ$"""bHtuueH{j1$DDDD I$C[B0$} IlyAujÐ|ŐlqzWDDDD.i=juDDDDRDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$C;8!$%! """$CӴ}]ADDD ɗ I'I=zYj@euܱ~N0$sFaWnT$}mW b$"""$C㐔NK{g*efCи"~c>J0&Ԕ\P8keB_'lF[S\ؙw A("rWCgB]Qi2P yv&Cp^緧#C4ZMX#W@Y9QWk!ܹte$1$DHZH:ktJ "s2Y7nYhF APHN܇-[E#9."48azbzc)0 I ,32o=>//##N5t!9j,?#³ 5D$Eٸ\͐$""" 3F+0&F?}hlqnA_h5= #DDDĐ|#\ĸ!O6Wk[ثDn?ui} 6d=y6Ε ?8-wg돡^ K롱'L[e1coc< M!9 ]"s9~dHC# d ɖM.qخ7?vL3]& `xN8k7vk4~'*nÊ-%hP7[I@jr1գͦ (?B9{k(Zkݼΐ$"""I-@Xc BT-o^#逡bJ5) " #q Ć"8t:rit^shBO1;zK mth{MBbָpD$,FΟFf`UHZY!teKe89qG!|,TdfHC͆ds~80?!WA+ےAreLˌE8e;ZAQeP6EHM|%G\-[6oU{1Et&a A4A%l>eG!иb8q2oD"""bH|HC!IDDDĐdH1$DDDD I$C!IDDDD WIɪ/ ;sT1!*!-/&ѻNcHbHvƉjĐ|TW2$} I I""""IuS$!vC!IDDDĐdH1$DDDD I$C!ɐ$"""$C!I/?|`3DDDݙ<裏 Iz[""wE!ɐ7Lj)!ɐ7L'ѻE!ɐ$$C!I I"""$CA'S79DDD IdAWOpǘ aJh b72Đ$""V!ٖ[Zٌ!DuGCo!KFT^ʼn3o^n !T0 8 QM WI"cWH_1K8u'L}} i?mDDDSHB*;TD 64 u_F]AJ@H2KkY(6p*MŸHr֤ l Ƿ7JDDDgHQhcc{{N`Haw lmw?eWa6´ˆ(|}`4kvx :B|aXs7ja*[@xF[NjRpF(2,PSrBihyX16?YG#pDH:bȲ<`I}4 ż'qC<߆(m & S.G 21Th \7yǐ) `YTTC ɮ~i8 dO {hZc:y8>nBG!iFA84CR:GE3.gMF1!WÜc0cG""66! 0y8e2xjϖu߉J}"s2YxBZd/7ϑ0r“2p[̐Y`]{4 Xp׶!-Vcf`%LUy>+·906K1PPC*DDĐdHv}$ᓸWa##!Эu2N$)l:C{<3C҄Im$&`Ww֍MQ I+34Y2#j=.ƶ MW\Xv+#Ʈ\Sv~Nny m7LZCz%̡ B2Mjx`MECXMDDĐdHvţz!4!Y Pm6ǎdv @̼Lrb}rRafdq4>[:I++'$!_~N}h8dW<`ވ7E'mǩ<0ԢJG(R_%: vȄGEY#8R=4톤`AP](llI sd<|T=laq}50k|~ qxm$1$?58ںbJwDm*l5 -Mn?ui} {!i`{D׷-o8 J~E;0#3­SBrEHi|} Do(uMyXYGQ_h{lCDDĐfxhenZ.6[ސ;f跌lHks*QwlܩlA&=6GS[@V)$ xb:(cHҾQ>SXxm%cüeo ݸƗ!IDD Id=j;$;~^'`D%bHbdrDY[gH1QK 97 BCRƽ3YX)X `gl'$ո؄R F=sl'P/aB44{ŖɄوDqO U0EIW.OI?j>_x=aNjcZa}ZÕy6'} \c]e{MDD Id I)X{"k!2(:aҀs2%MyŐ,>ݫ$|ѳ~^$$@,j\BU~=UǶd}(5h?o܀1q)Xs\Vq;nH ABQV! wM!j~![kjo-d0C (9)~vDDD I$om1$ |;G]1$}Gg:DDPk!ɐ@P1CDDԝ˳H$C1$DDDD I$C!IDDDĐdH1$ I""""$Cx"""!ISD]мlcH2$ H$""D$C^:N8!"w͋DC!I I"""$CDDD I$1$ w1Oh{ z&< I"""$Cͅ3R#m ' ?$[uFS g@lD8"b<7 I+ Dtw& i6cո9E!jb.lTpǦdBAlDG"aD8<98GGhiSWܼ7H(UBGm1$>!cECgBR_+a40VP I+7木#2 UːwJqJ|qEq~<(؍v}bV@~j% u?pXyZvBGm1$]²n6$1$!ɐ|CRԟQX}C잳_&1$!ɐdHZ"bC L UEOdH1$Đ$""bH2$+8!"w|cH2$ 裏, t].C!IoPc;Sg/ I$KcH2$ I""""$C!ɐ$"""bH2$DDDD I$C!IDDDĐdH1$DDDD I ?"pC=I5 6]/&._#ZC!vBRվd同\c=y2O_Md=2ZDDĐ|BRSu "dɈҫ8u&rt.Ņ*0W/X6 0$G D^qrt{Z\:8kzM–sg6ֽ01$5˨+Y 7V`SFzirH_ 0:]£'bGPbpqp0$_OH*+~_nDDĐdH߀rE۶xWoGifل؞jYyR~Mqk m,Q'Nj ż'qCo [I:IIMm#!"YHdFEY4,o0 \/μ;0f zO@L{lƙ[U0%/ɥiFX7u98iMӠ Np FI-Ҹ#ry.a007ůB,1({. B-?+$eH[߲Xc0fl8?+F v`_ې#j 5DD'>.Ý߱+}%60 I( M8Z a߅((0U4 qִ"bT0 Wt GGp ɮ~i8 dO {hڹIa.)Yy1!sX~MBծ - x,f/S]|L jmCZK 2jِq(f)ӧˆ6 '˷#ֱ1֖HÃFr\eڄA_ gKDXH0E&bp5l0zS1icH8VØq)8<H <#$?^Ws˞ܜ(6qdKT@;ǷZt\3ޡ}"$mcw(&(LW 2ʶFܯS3g)dž#lj|"&V(gZ3~ܺvqGGt[9߉J1K>*ARTW+ǴMe".}>2PLۖ5[ r !)|K$l`bH1$]m^MHG֡T %,QEq Q%JԷqSoPߏQJ(h\tC'G2̢$:`~HݒGxdPn 娮AyYmY+;agQaSbro[Q6Gh` Q(%DP@ N݆[RsH6o >[ 2 2ּ^ѩ> r 7*۸m/Sw).W"# w]0!jL)!YBsBR @_-$}: }I>6^ʇ5JHT)dk"}x5>K7X8}l} i?-!U dH1$<T͸, 2$SkH;ݘ~Vuh)W\:ulC7+cZbEU}lt(4{“`J䚎#Cc0cD *!+@2#k#@Xc BT-oFR$4(?_֧% *<\HlJ%TA.;/I[P$6ą3(wn5XKb GsPR$הƨ֭-9IR>$\wDDg@ ^\;g%|Ǖ鯸1fT8"pAH*>cX61c %/;ݣfJ£H)X+t<Wgzӟ[617}0=62?=#?-V_WH*_Lz%W6E0DM]#2C!ɐj!88k^DQyt,R ᇣ(_Cea^_|lk5FJ #.C0g AOsvOܐT+ 䣬V_CM9J"OP%o(lDؑV%N 懖?c|.d$6m BMcZ3Zy%50I xp(&jLQHc;(}{}Ξ{Ϲw "dP HDdPň9sq& 0 Tzoha]u<]&twuկ>]sT| , f5"n Vf &|&Ϯc#[wL(cz=LU^9YyVu1Lj$f^zܻO.xI2 ʞ\EK9%$ $lHȋaK෡`%ڎ l~Bq!ؘ:4u,1mOAHHH$ > SquF6ڎ~%afjB`Ư[  $$$>QHGQ) )é!XpI܁[Eu og`8otim III  II  II  II  II  III  II  II  II  II  III  II  II  v&|&~W-߆  v.m 6%@Ll1dZ3,ƴg[QM)?Ԙ؍I𰤼 HqP/XbK17&7$$͋A M$aA ŻBљ*K%Xassxlb9r]>-&6SɃUy߯@hؚA0sqK+)PȌC f콊'%5j^ιGp<0-\\:V|=⮬;FtnDنŕҫL[ jȮŔDDR(e<"o)H$I$[/aaauf̘a܈d,^ %.lԄ$N5pd AL^ӳ8  6R/wI;I1Y"řq>=&[9dEYسhD#~\:9~ȝo Y3Ug2?"Yfb΅)ö$A"I"iP$;원݋+IIEvI ~NM#l6Nf>q>2X7ԘcH\/D&>&T)ExRY-aMLFWV^)؜q$?ǵ1DHrn~E)$4^Kxĵ9ԔT;םR1e. =g:;p "ELtԤ~,+36]2 d2<܎4?<YDz by H/P) )}+-&vp^?)~IT~֥o֞y2H*_Ɓ0e]~W|R "N+b 1CϔBzU' ]Uoqn;Lc,4*|'suR7ǣWj?>!f{.^WH1_Up a`,ӢJ9~1Rwlʹkͥ/+Xp4E2p5E^*􈤉]B |WH*VF>xbmҐ8 "RQNNB?3 .k o,/CamJ6{H #XO}/:#fiXCپQFA[_CQW}<[_pL1B9KX: #GbBpHk&@9rExpDEŸ5&B%Y1)z$Bc'aU3!!s?p) (ފl?aI qE &|FXu-ݵ44yfy|mC0n01"Tix}iipW@0tU#W[ly;nx!-< NW_:+;dGWo䨼3@8#i, pAg3")+ű4_U9yF(`3wX/ˍM5b3 S?Q)JƉdsuɼb"نXh>fU"D2=l?r^ɱĴxYʯwHC@Blf+!gc"BB>z>{ ?vp::`1daH K@,IM_^0nDâcP(O :xd> 8&t 5#F9*4qL;pfoW'gBRu Ɣԩ+7糾 -HBxH8ŝ"<^Ȑ|-$$lN$pYdffNh!4u,N0cp} =^[r9oM'⢄dq3ϲNKCGwm ~j 3s X;E`:d4u?N{ɶjUD=hlJu-f>P(a(u80Yy=XaP(\1 ַŹDg0IUȓWx.]X%Bu^-|h7[eސfK8'BV_6"=iW%(?0c HŅ/ʅ494PcERh%|牾mKVoX㯖8~[ZMQ^8cr 5r?ƍɖ ĬqSc6>>,"L3{*TW}*{Xe|kqj"t>Ҹm]bE&޹Ki1 S'x &L&DTlu1TVU,+tCqj3& 3cXw}2I"}&S{.H&Pt $l:7oH"wZL$?wvt* uq5D:W35xcWhg:`l/GY HNLր\wKh[$©wx'eqlF85N=1l!d":\~Lݒp(_dNV ErӌpE,^j$/7!}MыI~AU{F˞ަ: ;+wqGr\#iakHvM>D96k<M`S/C&>xDz?ZY&&;kņz2Cٍ5;|gY:(w.F3Wuկ$7M`;#Q-|εI͎: x":~b5F$+}NsW P*FEQ*d,PMOfK@ۂ͍t.~9cթ"OϺsc;wCdL^Wbᘁp4\]H<;uAB<߶; SlW&[,.1u'bgHgH'd %}'$lHJ5ipjK$)Pq4^b376b|?}:QJH\F+C@+K8E<ɦ&ȋ}I+x@fE;G  IVgEnySHDSg Y udnCeM}H*%zL0f GVaDuĂ11kH!a\2 =q&JS2"i` By\:4%։,p3H'/Hz/jİn&e+-ً@lz^a[=aaJr3՘2#kX?Sݡ͈$?"yUa$$4zoH4ئ+vB|?[tIUDP:zZLlUSyn,Tn51ŸGGjwNGcŬ~8'T^"H`EF%ޭAȬy!%;oky! 5 ^˕rcahJ2&ȏLm{/Ro%"LRMy#bemigҲL#"ionh?!˜g:;rF^"\+$["Աɝ v&`_g~2Ɓ"yEb.gBhOmNX0&f;#lO uOji$?-y\=dsy|::ov~(F"ib1'* WcO`Y^2Y#DZ:0ò]_7Sc%=&ǫ0ҨK$csV=$$-y?}1=) %ʩH GXdގ)G 9L$;uVH FI.OgBua!*X';VaGu)sBg1IA6S(mWm!YSLɄXQ31"$fTm!4x"F"OgND,GG"p/|M="\6>^cdP0B7bY9(A%.N˩c'33/$bm0E( .LU32ˇM5Jeq8G}4_zS._z\!2MD amȒ@% $d[~٦%"|vH]wXE!B,]gSգe\Qk-X^L7`YrtkxXT؀>+f@O\ 7+oI; \NRgWwc}'rB:~~,=!JĬByv23jK;OOYxR\|L٧>]w9-IvOInV"`p]eV+?/Dz G/ljTJP6=I1LƆsQT-SEу}rHOc,{ԏ1R$~V|># 9jr=A,ॢbt>I^!yLse+ qu?1/ ե/q$F Wm.N^H;jv~fk fD-SvfI)vsn2#ro =ždmZ#ͶkͤCHxTuN w24Zj_ÕeuKDC4O&vXw%*$ Ա phv vtB lTO1֤>T8hNd>)QSrIdձmӳ .9$g$$3ÖoCJV0[< l ͜iI(z;@ϗɚI^II `bo ]s^ތ8R'Ôʗ lͯ,FM$8omHH &X&>]?Nô4dO3AH6 =AA|{$y{$[U2NIe8&cP|' |2"iP I  I0L*Q"/c+I  H$I$;u'[: qBzw<yk \M_ lN Rfse<k&R HBIY>lOAKciFUB) !vl.}=V -+03+lθWUHʟ`mbTI$  lHZGۊdsȓ`kP,#9,a Hߜb*~CW6&i ;YyG`td0Ũ' {^?ߵ29spU7/Qyg7f$!$,Ɂp4Sd,>I+qT׻˜~ AA!ⷶ  OF${  I  D   $  H$  I  DD  TDcǎgs|G1P;am8Ͼ +HvA}$|YeCـR|+cC܇ۼDN=!A:r+i`I'zv_|1@A|# snk0,~ywHCԾptt$!|)&CA|l0u @D ϻJ$ajICA| "il;7~k3*?X$~t bi_+6]$~"_U888cG$)cHL3l+z t0"9"==\=}1+~w~WkJkyoD l%N~cl $y9rqB82?κ^;FM4u(>bBv!$H$zRqoN$p}^;sieCU`lcq8>fW$u8L@p|>qD_%SIC]H ۞6m^íO8dXr_>ډHĸ#o!VûwPljڑU>: y ~q+W4컄o + *D#X3<=:Ia50g\](7L$]ph.D:'zL_wGp7ۑDD >HvQNY %& m}1B㷨!WսK7;=~"mޯr㌯mOן@$ )ESX7%sO<y)k+ AVx3B||nIٵ^vQyN Ǩ??ph>أZ$'8۵q_yl\({{ VBZX2Ğ8qQ"G!~˾9l]|8`R&MDddBXדj\1XW>8Er>^L|p7N:_3e"y 5"A| "mG)/߬R7L4ޟḪB.^Lś䲰Rn248(}Dzl7 -q:mT$p_nc!uw fOǤykJjj-+qR$Umy!-١m>/}y֮DRSwwrAkoDRH+^fCJv/<dUTvHŖ P"fWU}t1":K̀ȼ_Z o/́N]~VVsX7ڋOW b(^xO ­JH91J_G}՗rmĜrI^dŔ98D'lJ#A#6 ?/D ^Ŷa) {r|G "e^8ԋ0d~}csڃB.:'A5'O M}~}6n('zzx2w hHoz~rU8Km 鉩H^Obr={m9gJ$xyG ET\/@\N_V&`TpB& 5/lgI*"01.vxwvcvr,V )`3Gm+W|Rbqd*<+rkz<1SHjoa}stZ 7y+Ew>8a\/qvD$&c֮ۨ+sOG&!w9K%ӍڏS/L)n\}`?HBX++ĥS1&& q!ýҨŇ:L$\7h۳TpJқ1c\Ll {A|o{=Q.wbbbw&m?H%bsܭ@x1\ 'bbp(\-q.8$M1&b˜(F`#x,25|u2&ܫK4gFǏŬ7Q•پaYyulX䢉WΦ`GcC]ANc >uF&I$O۶~_Nq8PR3iW}3Ȕ8ڪjvaPEJ|,bGOš L8h3P돛5mۼ  >mF#%-F_Ԗ,e?Oum9 GPun8CىI^T)IZ }Oϧ9yE1SHfR&}D97޹#_a\O&Erj,(CV>W}Sտ4b#E85gCgt=;9EdjI8ZR&BvRE9=Z;}@%P%6MIK4"ɎuB;GG}%H6CR]W r?6$Z/-K Y7#:b .={e(. ԥ)fLݘɒq덴3?ъy=pE8<ڭiGsc:V ĵuI"I|"O$k,_49H{/-N.[Vwq"Iwݷ7WPvLz{ Hm)nA-WJĜwԯ:|5nYcr`^$H*d(/A]M,%b q%8Ԩzλ~S{I5xaO"0be8?i䲰<<!!N-6[#+VB\Wa`l4-{E53.F+$/OQTQB`tkH^pyLvk68Y:TQWvHIsISjTNm eڮo|"[) =OĶxե(,%8cqY@CuۈdݿM|m#9jA/΃B6oE-wV2aq>j\A}-~ "K%76#߳|}"iccBT") Ça؈qؙ'6DL&}L7#vpxN/==NЇioHF"e'x1Z%[FA3 ߱%A^33>M~PHqul=L: ޷Cmi*{w/;Ѫˮ~|Qd#~ ekq--uڛV9j\qH;dHE;Ƕ_\ w|C>9ErU]}zWP (w="\mDD#M%rPo2ܕwhB1dX$V^@$-] |gltWu&c(o,\;jC.z4?Urst?8GVĀq1FH,Zff. r#u<9cPSb1HrS±5GkP6?nkX"9lz{QVMtXd'"[M# GPuv::ր8Omw-nɱ> r>>q IsIa0W+xs$I!c'^ O;#?2U~ve6+%F:&ixqzTiF?af,Ǔo;%b1jT4\CR$mu-.䡨Z\;;^%YqY:D(kU4ri<*Cζ+{r|U]zR1 _> 3CԒSza[7ul5elY0΃l.@\qlaz#Ɗ$d.GRQe!s~]ZT=m pQ\Ϩ5 %GFQM$me)"=uɾ Mmf218GUӽiz?22fؒHN$hľkg{_=0uid ɕkk p,kgr7V!H4P돛=mI 8fz_;M2QnsxV\m>.KHz c z gHM hHzzzښq5\n؞/Dh A| "\;gǘ4L٬o:ö+mHdRċ{7Q]Sgwᆵ |?"HMHDa>.!AJ+k| $H$L&j &<3dzϨnk&n}+^frE}?||{?ޯ gQ$K$"dشF$]:=VV,WaWXr|7'D[h.SVyG>-1Y+EF ɿ4'fmI)|7'ć1Dڹ_y4QoyF4kH~ި [KE믿F=aeeE#2˞cA|l0ui ǀ8Fg|޵B$]L:E?/˦ꍭ[*;vķ~ ~)0>|YeΗ=NJ1P;amtxB)F*GC UU'a5"ivAS~vſ?5"H~B-D:tP^UCD/sc:xCA|l0u6nrt%ϫJZ$oBi"ߌe|a"ě(AA"yD~vICI$  ڗH FK$C#6•$AAK$+@$WnkܠL% h7"yCkMY$\pOD  }HB"Gۺ$$ h_"H?jDRs No_L% h7"y]kZ[s T5$AAK$5imB!{$5ۚۼfQAAR;f ~Fs$wm]$AAK$ FQ$?/~2  ݈5F#ԬW\U0K=g~]  ⃢_B7-]P{4RZjJ`TRaM&ۖapd833\ 7FOF/5Z!  ZO |\N]hjgU;Վ/jVjkF#C0;MϨp[LTiQnD1 uehSAA"}JY=v2٪:ND uFP&V;. F'F(^}H&AAvv/8ڨL3E0 ivԎD 5Lq!dJ2PZ JmF2  c#nv2KiF M:$`J[{4R)"4F&TF0:J(F*5Ԧ+AA"t9Ʒ<`D R;1wSܺdRonPjF(5R-ԌXODAADTfG8C H@j&XXK"5SvG!3)嗂)oTvT'R( $SH'  Uh{йXGW;R/dOI͊PT~NF.5A AACZkȣFG0_ٚQ?Q? EuȤ??BTUK,5r@2  hJ^%Ւ/=BԌF1:aIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_include.png000066400000000000000000001066701477034762000250620ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:15:10 CEST6w{IDATx\TYsι==sOn1햂 dYIlshͶmjs9`STQڊ=3Mkz >;?h?j'ό?i4oAA&t\Zzٿ|yO<4E&=&I$R+G/\9x{'G&s&DR+9ɍǯ|oyݥK   8cNwU;ԝ3ImdÐ?I_t$޽;<AA|=qn/ud/<@!HHDr|&2kԵkW >AAGvhf?y2_;_R%¼yw5  s4ؑ7W7kk7 e"ALW'D8KPU]K;(2 ]HXՉbFֈbh;nqq@m68mN"I>?rY d0թcw F֢H2BW ^*.L"_<} 3 {ʘ8jH"Ik| ٳg1iҤfqqIc҈dw 0H}]0RF3uU55Lrx%=;haɸdx#])f-+sQ#-A3U@=I$ Ⓝ{'^lj'B*bڴi-~ ql2?R߰vOI Abv^'7̽F<;6f>?4n?y*T?ŭ#קz}{2TV"?$%7 j$ %6u GYe%ʊS1~h(ԟqa+J1IpE[rQXZ"<\KwGx(ӫ әNIq Upu?w}GoT˱/a4z=a8{碘ŭ3ܻAN-y䋣)ߚ"= oI6%w$A4+W ]>G˽UM&;dJ&Eys<{Q)׫Y?94:ˆuCU/Ud啫|o4eQ/`fǕ>(KUo`[Y3<՞'8Smd,ó] ǎwjdU()z:Y .짖ۆ}+Q8 YYY{j&|mH18J7pC<C;SY&7n(H}Cݭ'ttß' #:=(# hzW2qXiv[!X drܯ4=4bff]Kd~pMYL1k.Im0D)@)rC篌af;g˹4asITGs<4xILsZ5L/I:b&AlւHjϭ÷^tU5GT#ܹ$pXۣt~ qGP(enGhϯ 4ISBey!+=Tz>Y'vnT DRH^8`ΓlIB3?ҜD CXp5bl `ƧpnV%Cٹ wUq{Ս"1GNa[Eur#Lf%pOz4oU͔ǰ!]]/e5M,W'D1I:NWrǾY} `-:*ƒH$M>XzB{+-{[g#OOAжZ$̓7 "wޯtč H$ hFg?+UNqZ#0B2oHv7@ w?d"*arí/h,. dϪmde7c|̟ȼ !13M$;X$X7~ ߻AN~W4zxnW$\VzsܻPY&ZlcH$qïx nDRE_|˰ $XNhx!3k;Y"&Zq+ֻ\T8 !0ϓB$͌a8*eyء{WKж$\Pmhu@Ⓠs{վ]Ts5meE$Mghjh%˝-L$;Ħz/+Rۤ,{uVwuK g6A  nbr+D:e$A|:|a}T{Ǐaj9_kTfWxӓBΕ8vr+[#i4 3v>Eކ6PE|,CFtiY$kdqs P&d_ zU*5m^|2\;@=doH9` ubE.v3z:y.R={ix >y ɯD{ +U6ۖ$AbfxS T_`\̭~U Tfl982HQ<Whi"i4 #h:9~¯P3}0lGiU5 |ȪR37ɿ/I$  >mZ/I$  *~gD  I}M"IAA}I"IAɋdOI  ❊D  I[?AA[ɮ]  !$  H$  I  D   $$  H$  I  D   $  H$I$  wJǎѡC'AD:udҥj0.V\̨]1_w]]]AAWk:w=zPʸr1bG׏Hc(.caccC.$n(C;AWR T^?K"佼`mmMѮ&2TqC]T-\]1_ \w1N \da~Wq5&o=N `{nֽ%T^y8;;FBDDU}DuD=HZYYA+Lσk0g$&&b|\M|Dz+p [;6esG8d|$SIW!eȐ!DTTA8䶥zz$@#$ k,K($_"njI777Nۡ/xI/K8\ upZ6{vzF8>?,ްl[ypĈ- $#G~2I"o\bÙ)Qǒ5'<.߱m/ 3{}D"]Kqj@Xj0eu^"euJԔ=ŕmgLy'2T[7E :+qsl9(XqWVYEK<8 96TVS(`i*ߋ>\z]w^J>qGVcV$}䎒x# [y^'`uuJ&lG@<8JNN6}{KdcC=Ci[+QcRNHCV$%L^fX+ D6۶$&iǵ^Őg-ĒCwJ/D^_$%p 7VǸr1dQ$m`Om'8 aqcqIq=ĵ C#0&9Ld !t(||4VnSڤŪ@ O@ K3#m,bF zGbכWvmWFF#)Mt |"2t?o)Pyi9₇cHD.<] EY,O EPh*yE9LvI9УEaf<-ęc0bPD}ykTN$W$qE"kDn{ 2 5/v AH}$-c0L-*&F1*x4gC& }'vsL$۫I܏Jc:%1HYUu( &Fw7Ca ԗ_ o /ͧ?3aO DX.Ń{pIh8YX|G0$`<Z$l{~06ͯ >eo߾fpڇ5믶5R+~ ͉׿5 N#əi ~nptH!V$&qz#lur13&oW b8teSQZQ򢆿<9A; lc)Lpcyf۸0,+ VOL@TL*foz&SB̶xN:D!:i֞̓BDWښʽ/ϟ͛7}ߖ{5;'&lL:b`?c39n}b_8X ӴL,7pk8bҘPDaށqz $9#1Ƚ Ct k>HG Ԍ:{)>p8 QHbuoKSлg%ј1jc^I9'oߞ~se!-BsGUE#&_AX5=]Y!d jNBܭuC+ ;A~v"j\5UnbM;Ҫ a}>b} kQ{2DRq s<7 B7AYaֆDqg}qrKJfU1 7`Dn fqjDxGtoE&b Xoհ xxAV$aD&[w-mƆɌh g18:Q>^ am"@7[χ]$E2h__eYʪJFEmH&|4=VO=W4 }Eip&z>4C*BGPFKc>Tm'dI0hT"1Y[ӑm؏ˤ/KiD2lUC[ĀXxNNpGƸpx6Aa͎ߘ Ed7&{ n/.Dɿu|zыFHvkPF9?^?ȞnBmɞKI= (^Cyz+ f\RXXg!Xry[a>REAgJeU*}z(OQUER3/C!;DR$rDI&7Sb@$mbTGk`KjjT[= 6mI ߄u=  ԡ5ג 2iL"ߥHrįmؐg G>.pqQfo0gU.=ǸL$o@4L$a")' 8V_/'ۣT۸oZ$;~3q$PDU^+X4rjt#>g/jv AS3a~IMMŦMJ$pOC fDN{q?U#DR*>xH,'nQ#SEK,b ^ZV k,b%'P_sO׈dsG?D 7nc͉],,~kqmMy̴U$ Ԭe0pOGzpZ5-cv"Urg99JԶ̑4*]s+_m%_ACwbjh S/smHS7JSHGme7s=&31-E/dgvM$cT"imJ&j+bw̼\Pg5^lq+ERCkڎW؟kx{$Gٳؿ$'*~p($H 8Z(>*όMӱBoH40SCGdd3^(w .n"beYL/n7"ioofm}QQzzjHـ^$E mq鈝Z7TŠyIu$ s\$Do~T"ٵG_L:WE),; #FPT\Ĵ~6D.n+X6/,u$)ext`!R1"0cd"ж{Wms?eiiوU)p?ĚDczg7z;!f^\zc~+-/a s"ЉA[ L0]Ԑ^)!g"bm|,3 ߏGpWfҡVT*dD@$܉{ULfR̶ ¢;rHZ5CI9n|]jS0ܕS2 nV:JFK;:i 5č MfW+իWUp29|=Z`geE߾|%$#1&#c1ܵ&#d:E2U]߈bdR&bc Km7; Z\UJnj"@nĮ&i8ُR9'zfD1QnbQWz?JBdhR6RS@ȵan8UbAZBC#W-\o5ƶ3 In##)3UUxFS1&]! "g5Ѽ'b z%jʑg25ښU* DV/uf$'o/[zɥ(+ p|["$9/AƋ;$µ$VؽBT+ |oHkqVD'M{$r PԱ_=QpD{Iq޽ "yD.-uC3!Vq6=\t&% :Da6231.9#ݭ?T˰oᴱH/tFJ(.`m%a?dn8/!OŊ0}TQW'9/m'\>|6'\ 1#WUE?cƕ4$ōCER%}ObG9 {?3quG#x$Pcc8!@$?nB ve8DXM?W \da~+44T57rϞ=Fk?ɷ..%.ڞHI$I$I$ x"I!wl,P v`"^T^yڪd1((HzUQ@"nE jLnJہ5BjL$)T^?K"D{mN \damq5&W*j%|pF .sss vW'quSK Fǎjc\Q@c,$.3:u77/7'xpuW'quSK FΝ_Sʸr1bG׏HTOQ\b^ 5_~%a.N\7N\]]!pDueICS{I.󸷨٩'zpq÷\IapqպU3CS{T$޽{W^8q"4]$|lq3CS{ $׭=Pa6.^$$֕-'))vO5I ?P亗 /IEWݓ;ݧ$$$$5;DDh")`h7JG20-F| $5!Ŏ $$4q`S >P?WRJytlbv" K}? z>6o_]h5!Ŏ $nZKl)']ڟHƲl97 o+,DR胰 Pː~yxŒ" iPXz|$$Y$ͭ1(i]}j92eιq2'$lH!FxH$[o%(Q;'\~I"^IZWի ;gUJZ;y}qG;̽Z>o-5#z_Z9j^]X[99ҍ]ןDD}gCZ_#k1s\Ǧcyd5"GҸH=a>C)k0u Tfy07C+۷ŏN`H/]E~hKxZI)pv_*)jJG5IkxYcwL&GemѻIez$!(HK FxڿY=bTIb$uw`rxruxuv&|Do._4"):#ama,Q8,'#1}֝xJ\>6L"MvIqsPXg6ZԖ=ŕ_&a*KO &3uP֔"x8fFR(n>GT:y '¨ ϡ(`:v^{\HXFߑH <96G\9mj҃O,,GmF<KU\ƇߣSѪ0 F,QUpF y1e2J~E=Wgꇕ߰@8hI^P bd^ɳ6dV* Ȋqxn y hX="p}V_c)g0'8%Ņ).~yh](ĥ}tzpۉu5K=m5 KXr*YWyu!OǸ [V2.?X~<β<<"1!v9;p~JT, pjG%܆+O!W*L...o&=./Qsg$| %cX9(`u?m0 "q FYX3Ҧ-f4"=b, ˢ=5voH,rJؽ47 "$4ЧF}/iHq IYK%Jl5W*4nOBDh("Z(rVcekP"ks"CN"plQW1L$s @F싥Y TJ'7!OYqFkr(;4gm̺RC)p@`Ԝg;+3fi AC*U:X~W{[%B Y<\pĤNDEIDR2r}u=&Dž!['C➦ak[X'GXo~ERh# 8&51^D7Ɵfvu6HZbwkBш5WH*OЖ*clHw#Q#L WDÚϧlHZo'5=iw"'{kd5K-!mNC7 EֳbTTW5uϱ>в5,ʱLIŸ(C"k hA$-CT |]Α0lOZzaZV6q$qрŰXQ49FE'p#iaQQU 5%$xCFbg9 UZE9vG[#rg)u_H TaEs?6\p򒝈 Z`myY^` !if|% /1n3C( kqsp<Ԋ䉶d^H;^٪)#D{Hũp\8N:7DfkƽYE, 1д9cwT"4 W 1%bֶu"y Di(Fm~[ @QrG~Vm&)DkPA:<spC-FXyo-yˋ+l M+³X ?OH2ɋڎ" u0 2JVy"*p{+CYuS m{`5֨] _]mpӥRTVXzC#<*-ux߀HY-27{5rзl)֍j^%aX$$' pNZi˘Nah{vImz )GHܘ*4;"r}jnѓx*e9NadhAMU%X3ʨHn+V\϶E^͇w↶?H&737R>nS4vof/ꋑ˱n |poH$?9I'pv" >Rz\wwɶ+(P-佥i")b*bI @l$x3Oőj nL&ruŗvR"#,m:Tߋi ĘUQh\l㒸J] L@it(91^qWVӓ*-s..UJ<\=Tж2|yZ$0=WKkD$,L+0 ݐZCyv _#CbvFřg4{ظ6qHuq/`2NikPfg]EMp#lhf]e{g-zxOI|fCQqó~@Y#)vH:X鹹*̫}y-/*pqNeunv*j{0uIeF$acve1QUɉ< 5e0A#*hzu ^5{ms[(mX!-qIB&{079F"~E&߼6Fݐ 61s]G?@+G Q` pte,l"nVv>{`ݙ) ǭ;b0fc*{yU8p=W2cp u{YdIDUŝX;_'>SB.$@Or쌋h"\|\_=*v_HWnߥY-܍؆9L*M+ĭQ$J!+.4\is-.ڍK9/Q%WB^]GWbigW화4vo|dQ_άCHH$O$I i~i|O"I"I"i$$!$?''Dr$ ŧ")6!?/I$[xHHHR$G"TGbGtIWWW|wp"4]$|l=IyH}yORd߾}&ŋDtպE$!Ŏb=I(\CO33302FAmIhӧIc "ࠊ 0R$I~  Ǵ0I  D   $$  $$  $$  $$  H$  II  &_|AAH$Y觋  ZF$ۙ  uHHAAHHZXXAADwIiu9ZA:p VKh!?-D:6AAHH6`| &r&BGo(q{Q"Su-Nf8&lrchxIbkʑ<3vl  $EOˡ2nD$07c|T0y8}?>Խ0%$AAHHTd;8v"&^3$AAHH  j<o $gŨUN!EXQ>H<`{(C.-ˋ1R>O< '\~Yz[0Z36((vˠd"Ʋ/' KQ}+]!䝓 8+R!z_x *jQ[ WO{kN؆+!W* }K%'×)QS[cޤ[q  Ԕ<+ U0di5* kOGTڊgܘF8vce5s^CNajJԖ?†p ,D`ٱlv. (k+PpoX4 hHIK/,@H GxL:*Rvs<a2^(Qqg;f'E"StʖD5[žB%nmTNTbyZ YrH)6+(%ѣC{$+"w?G @ӣ-  D\=2OiD҂m(%"68_$e .',ॣFbM8x^VESb̉zު+/ƭIW'( ?TOU1oSm{ٶbjB8FFa|("i.]fAM* 돃 6+cs0.2nTʑħ.ag!ċǰ"U_t9 ,>RѰ57=bx<|\䐖<ǽǢU=T;W2o>Byi艃)n)VzǢRwA:Ԕ<_&φ*& DI  DD  DD  D]d^  V@"In{  tH$5"Yb>AA H$ds|6>يϼy݈߅P! DDRH?w_ހYf6:O~of#ۈ  3,  H$?Yt_ޏ?>B.᳈[qro)l|˄2j?!R;PE?RbvrNI/} Q f& v"}og>[ِl>|6(>cR)I;ȹt؍;Lo9:33@;$ $@p# G!7r ("(*x"r`8$U;$華{$USIAXǍ*8kЛ~W(@Ҵc:5]3ަ ~~d<BݧVkI|pzbzLGi"ݽX'-umOJmx~91'4ho2Oc^Ғ.-0[PO??[n'._N+Xc @YT~N:M2sRc(4ڷ.}W"WqN;+;R5dHr)l|ĭTg2e1P]k^s*U3[LS#fLj}܌Ib~_}B}TN>yd~97K[ZYWҴX5{x3(ּo2{x)>\ruZmCUSuX;䙼.+ίM+yߴ2l4njMF}ީ O9l}iDғRݿ?nPӺmC5W rm8]=_PĴu&-;ǩGD.JUԊ}VT6,ѩC9D"'Jw,[ͽO׺@H6{K߹]"x!7VW7l3bpS2˲"e!?VCZSc~Df3RKK]PK*1QXc.-[Ymݿg#EJ7vxe;M<^h*T`}G 4ӚǭN2E,O?k?zM4L6Le1Le }L8Kau{uIؾ7li弖E*Lֿ.kJU|(*+EIBohߛV.J04=Yo>ЏdOt]V $ ɿ3, $ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$ $! @H$! @H $ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$ $! @H$! @H$!IH$!IH$!IH$$IB$$IB$$@H$! @H$! @H $ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$!IH$!IH$!IH$$IB$$IB$$@H$! @H$! @H $ IB $ IB $ I$!IH$!IH$IB$$IB$$IB$! @H$! @H$!` $ IB $ IB $ IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$@H$! @H$! @H $ IB $ IB $ I!IH$!IH$IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$@H$! @H$! @H $ IB $ IB $ IB$$IB$$IB$! @H$! @H$! B $ IB $ IB!IH$!IH$!IH$$IB$$IB$$@H II;$I$!IH$%$z5ns= Pcޜ/!yuyӮ];uE]v.zX7Ǽyigg~LHUmn7`~gs~LHSHHp̱o4Or(SqZ U*$D د@y=!y]ͮMo{q̓?̏;#pBrMjZظ[{@n@Q3.{0?8~ ssj6{sYQBbȸzڪJ]Ў𞚴yOlU2J|LcCwXƴ as q_߹p"rj'&& Ν;pAj󫷩+T~ke;{!}t 2ɯ)͵G{yX zJwPVD*<[.czjNz|τ9k;P^,bELY>PuXw]Bmf~p}m#<3X AH^",{V?k9zx,pjӴ6҃g#`3eq_߹P㺙Y>ӯYJ3>vʽO!?k.WE7iVg2?ɋTX;BRuaP.MиurYiѻu<%W)tY0OWi͙6}{\/miÃQCf|ĺph;Cjy1#رl6[@SpmzYJJI#&h ;ZlPm+qG9$Hi;Ӝ1I>v|L.qP樲N{ri#ճgOCu4vD!/sPsv;kGO-Ѹ;5tڞW eد@y1̏yۣne|I)Tf?j]]Qɯ>]>EwG7*ŕiǭo_GC4zs0?.RGX0m^e+.k~4P4 㰌/Jn[S:?^9VI JR;3U]I#5):U e8bvg.]yw .=r󃐼XCrbumrNfxddʾFXu?+.AnגI+㽉jmSk}s@ VxO[.:bMlPpr ߯9$~~|IC|qG6ֽVɋ:$/qPʕQӣ-(?svt4Sq&(m5ss >C!uCr] !Pt|;½Z'/T/S#{z3åoai#Nt*o47\kRCIvaURaYGuzf@{v2jn3ɺ,RV5J6yvzC2R6:UR-X%35.qHM5ƵkhY-4IOt 2лFF\拻Do s5!Ybޠ%ɱZP:C G\:`i8q*PS_’B}CZvAAAs[, VU$?xك`q@ݠ-,dlAk/Lp۫[;I[g]ws $/V EYINY\$gNެ% -ʮ7Z߭l;}T{Ԙds횾vRwiawDc'uWzy|{ɀ7O3;E_P m-3j_w:~BQYnfxB2PvÒ=&7.koּ!ijl!dz=d΃OBHĨYf{"ڃi3~- M0~mʋm~0?<3Y3@dhnX;ݪb I[(.A:LӚ鹿y>ȴT{of0?,$;t蠦M(`~0?3۷gP c%p#`BQFjѢtm7`~gs~LH^jҤgDGG{ ؙc7 `~gs~LHvfU9`~3?&$pn?s! B $ IB $ I $k I. 뮻 &$p"$@H! B75\61oҤ ?~nܶ%?_B> +$5jvکK.ڵ+X_ف2>s1~m3"#}k51"g/ۈ/40DLLBCC@|15ƀs3ͳkq*w:0mwy:..N!!!@c_ӟbb|\1~mڞU8s I45"0}m!cuumnMn՚S|o{ϘC9ɐh]L|.q&I=?Cׅo@u=#ɶ¹crFqnxЈ-ݠO723)}""o~7*+Jμf鬭fn3Bd=vGW>ѱjw uH KbȖ$IoD>U=/̘9k!٩":t_Z1/k^lvAdΝp8;!ziu q QLh)幊UR ߒ=LYqmzǾ)GxkJs!NfңJnmCX'*Aa~E߸&Y`mgSD$c 8BosDkr녿i6cݩ'5[DZbqR$$4nIDŮ|#xiuw8+zr9kR;bڛw kֵzxXd,ukt@ KBB?]} t\`!Z.U8em/jZp}'WPB}H5 a#$];$)A 7& ǺaސoLsv~6BrP9X/$[$c 8BM*/)K)o?gm|KE Y*?O^|X3'؉`:s2i6c{;.A'65]3V}ztVIeEݭ'w86Tg=O*8WWU˶OH6.C5o)Xsk*$+ԃoD_]. ~/4yR Uv>uZWL9g+3Y4̦J7~:](]pYt9<\y:>u1ogp%-zGOS3OmвMx-ؕ/C_T+_mҳE#QK6Yw]#i=acRv`K]ɾvyk*pc{j8C_j=`^yTY.mTe!iLΏgUwL{\ʰ}I]Wpz_(3nq\alUkH \9OO5Ef's,r ㈶|qUڡ Gp 8IX#o;`Bk>Q?>JX"<\;燵vg>1="?M֊q¯]\d|oJD޲(\O79Mʾ٤k-ꪤ~]/RVVɖ4D~4w@\SM.Ȑرl6t3$Svbn[SkGO-Ѹ;5tڞWa<;3rG_9|& l'ͮ!ڪwTϞn1ji7=^op+5wL'?G g#DWF=:6I U6c"/ߧ/j xyPy_Ucp:X:z>w+}%'ќU>&u\z\D흸P.SRf0{מqjPOHPZyڼ|F Y_mnh;he蓬"xNsqzj1FHvsX=w+'ԫtLU~;ae Ix4${ 珹|TҔ1}sHucϸ0+1mZ>CkY-=QC5yZ}_>^ZٙQ߯c}5rݚeӹqeۣuiΖ S빹c5<ɸq7^pr ߉zvq |1jc̏H_LV-+t^M-V/{~3>Y T؇W0mOh$%GK77s=0k;W4pn1ԭl Q~6rkwxI/)^┚O~LOu-[V=Z^ sz"ܧ 9J1Fm*<^3ujgbH:B#p D'KVeը0^eģuސ4hV +gG˾)pgQ'rݨ @[-Fk]K_?ܥJ jCXcNS7dɵz9*˖=meM`c4v[G^e;$zdWHC,7~;xO[[kJڮ)$+b;Ӑ r_vUx:F-GZFE)+2<챪0.jK6)wՄd-c&ϔ@1_:Bcz}ddwn%;3cQ$$qGՅ*U/ e3W;KF#B}{lm-tichs9 >FikHeލs˃=]7~T~UeˉDcd"`-n#$:}:W9;4ߌޗl@ JoP Z`e"5mS%n\rn][5=tߦrԗo-׌! 1$#5Xkh #Vrȳu+}Qݮ i9##$;2R 6fvQCsN襡!u~O;]%VuH>ӢAտ K#,O | eulkzlj\1Rul9.W0w-򳕝G/{;DFrNW[YjkgHۻ_cnFֶ:?K5,VNv3?zG$! =$>HSۖ+Ǥv~|d-Oʍudrrt<Ռ4 '\gku8_-th'7W=xڧ"Ͼ=4-7$Zrl~v7$[ZGrPV+4ߟژ ɠ3Toֈ>ջ8@V*8^ƈ>#{W({bi.BՊ ]G1HxBM7,$c$3 .=؛ggq{{V-kV>:<#E:llwJRvuAQ.c_oI,^7K)^a9q Hu + Ge?0!y{۫<~/*>!͐F~KxB~uWnj)ݾzOu4Xٻkpc ik` , Rwq}%x{F䵱} Wb4~!Hmҳ/i-nW^7.pC16ƀ%$߹nmf7|Y#6XSDu%dVq)ss6WV!AzG?84pս1:,c8˷5~3Aߔl}reo=m˿g3~s`R}C5Yst } V6:FS>2ֿLg/$mmf|-5~Cx;gfu9$I^CHZMDž.}`DzmR5$˵s:cm,Ҹ 1ui [Cr3?bBYHV{?1"{a}!I$&$BQu! N6t4[qwKpUh9VPq9$ku8WלO7HP(ãϒJA#-a/pV Zq=oWy^ζ*{Ikt|{5uWtW\߯۬!y ڐUPdSFHgS:m 7FR=[tm4~ -$6_S{c4R;F πd g-x\{ځf)ٸY'~kfpm] Jgy@{y;8;͐[os8 3E[44y?JmcZzR+)<\w}XFOmkY { )1.XCT}0lr<0-f^:dLc1g 60vD?ܭA]v=:|k n~J0P]#<;'oNLҐ!trxLuףګ{˱wgh;ԧ ~lR)Z5Q1Rت,Lw>_mШDcCD{v %w;pk[fy_lugN9V1&ۖjt >Q Wn =]鼫mx=E+ܭJ0]lƫMR+]gt<'c 8BJօy&rڎҫ U[>WFigf0$Ŕ"exZ󶏒=#i̹do3$ڿk۵{8KC#[ rZtUq"M|Z(8W{Vޭ֥Hze׏SvgUfnIs jl! 7_iN8U_r"m;|w:C-Q33,@6~m͈+ IZ]rf諷*/j8ۢ5t:}q䴱΢ҏ~asTw??NKڡCr˙Pώ\z;mm4dl9]ܢ&+̷8[!i~/4^ߢ}Ǎu9ttN+}#yLZndcȩGwJ.5snu0CG<7lIzý:ilbcr?[qPJ3;*sŅЗ?Wqzgqق9A1cg]y}ם:d sq}OC}ծB[cQ?xuZ[.ײ,$c,׏VQꐫP{MVp*3O ɘ5k An6MTz\|k I1!Y~nUbl5)s]( 5C,1𚡷x?P32ezj]NH^o ɿT'$Mkp?t}xTNɎBd؛ol#_&}dl#2c1+d#$#۞Ub#t͐[=ȾtUMj^ؖg}}?5sŐ%$YBVCP}BCjڴ)wZhS "՚/BL-$hp>忋mn1ԥ{_D=/?4Y=C2ۂld ?75$$۷o/@}m!c6c([o# ۬!yәu+bh~!yWEqm!؛ck?7sfn\mbԾs[Ff涫GH6M6~qok{fg7V&M<"::.~cm>co~1ϝmKzRSQ\^3mI/϶ lÖ'$y[Fo^m+'_H^^)$^fBv$jԨ 5cύܹ۶OzήOբv:ӈomk+C 5\mhbgwS ސymx&$JNHVHZ?_H6wnwlW6Bmn>gLH~^6*}eކ#oN>FGxB޹u$@`GZ߱{_H^'IZF^im#HOH^Z 7֧}g% I IH7ژ y*Nf~Fۀwkm|4$@`dMg#mH\ZYIymlT mF;y/$ԤەJ]g̷{ͳ;vY|YW8*|>gmg#}!/oY?ZJwiM%of10 ᆖC!ʫM%mpF*TkKoEy,dF 6py.oީ;GH!/jJZ7y?VnQvCZ²*grO:%CMm4ٚz_ަ֧4tV\7ZNb9Ci KX:w@ÅX1^p -7zZo]])"Oid峒/䕖l}'urfof/2pA`ln鯦&h37z:o5D䕖v峑d]bow\c9; ,g)}Q;[y%0+k 3⯩|ue9x% <}fC^?/}A;C+M;RٿpF5M3p3=kE)ِYCL^3i=; ʿYEecuȴrWYZK5ģ)Yz"?h6%5,g'}_++EUK_`6&kk]cƫ-g}x Zޙ; "v5$'&}啢Ja˿Y"P/^WT-'K@^Z5ֈL dIENDB`backintime-1.5.4/doc/manual/src/_images/dark/settings_options.png000066400000000000000000001536701477034762000251340ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:00:37 CESTtIDATx\پ{>/ϻw3{{3b 4 MT "I$IΊdscqFu8ccNFE :0M7݀ٿwjUժUk}B??o*AA@/}JW4dS-|TG*5RԌNv$I$? V $gVDznie tU  StVvZh B֌NI$/<ׅП z]mbb"0` DAA|pn9jqn-ÞO&bLHDF Nӟt᫯zΝ1z###s  s38W㜍s7y)r馨܎W-23"hDDjJ$/˵ѧOAAAq.ǜ._E&5LeRlV//(?3]To$|'oyvk'/i̸J7 -o(B7Gʞ(+cG0X&FcEyF &B¨;nqr@uT?uto6baH)Q-n2f #͝:Q=)cO&/>Njs< 8D >;e|ts0}vqqI}KDDFto[?#n$Am17P$϶c@w= H921wGYGhlx]1CսUAI$ ⳃ[RWqڴihhhٳ;L.M="r~:kJ[{$A鍠MhPd#U0U=f⢑jM _5Oq:$7V?BQRVJM"zPAT֢_?SRK6nA$A?T+^\> QXEV*L.GOn^e%G(gQw{)<_1FӲW=лw/Yg7αw슷aNP-݅_4IC2eB\yFعQY&I"yM倦*''"6e|9$Az=z4˱#xqoَĨ:?C\ZƜ Ia5Ή1 [#{vK$ ~XyFmz ?.@ڣAP׶R$͵w 7-"wޯR[HюAei9XG1V6{Z\tOYgitmQtm}}ۉd]o+S6zz Yo`e.:\? %U.p󕖅u6uA10kݺ \-'u/Ս \d_F΍kxGWʼnPT۹4)tLa&4%P[Ct,bE/P VL)\?_u = `]jUm^z*\[7T$1R2XS͡]OQ+qn!=L\} ԽM8ɷ uHt0s[?hßmI"I&F60QO O"|[1Aed6e b & Ii(a7aɳ8s|/~-S$F՞,{ hv-(Ae]=J1,gv%-DIU-^x 髻uLAswң2U:u4,)3tl>w̳Age,^Į2L'y"i1s[nڈ/ڨgl H$ x6v0SEㄼe./BAg m0X*fnkMHK"IGIKdQD=2Ē ܳcBI$ xuY"} =E$D O #Gl9OJ5pL3{JH$ ƧѥȤ7!=Uא"$ LP9!c"uo-ɾ*G*#$ ք-礑o3}KtS$M$$$ @$$$  ިHmI  [$6$AAEr$AAg/H$  w*$AAHZ/@AA|qׯ  OI  D   $  H$  II  D   $  H$  I  DD   |=zA|puR^_}QlW_g.Py/;Hѣ +\]I}Uw055w.Py/;{nlmm >::JWE'Zv=v\~I$1\H" ⃂:JWuuQյ|*b%|"ɅpMwUqѐ3W}"u5C-8 fok*<燈"&&FgC:K""666AFxypWjj*.\4xzz~jHDMEip ?l˶p$SYW%eرC||N8䶥z"].ÁM1ԄD}!ce=A|&"ɗȉ'*dͭi;ø`o8>MЍ C՛Ndߊűκ'lY4OV^91 P ?II-o>k 4DfǓG0nۦ?B~x ɝp7}"9j(X[[UD~pg-K8ax^A3*I[6V֊`زml<㪴G2?'On0k4%#::ZA^6p NCnxٰm\/sߋ1 6o%_dwEK5CP7XWg3ױ}^`轕W.hD#{`*XȥbTH ʜ3f\j@MȌXpcy8uf^D>m?+p %$G$;H'6SLiG//Ϛ"1QIrS: %7aR$h>>xUŗ~8Ŵ1L͐?H2ɩM󊘌I_ܾ>\cՑDr߷V!y)XD]5DZ9 @2'#lJ䫍n'ep5o!-i`˨~M85 )"s[;Hk^+7q"۾Ǖ;7wxĄle>J^GDc{ 5`1 Y1y c`;L$O8(M;Z23=HurIcsQ_۲%s1ǚSXG Cbቤ/AFb"&/އLw$`o=ܑl @c;^Tc"yc(5Sd~kQ,HDD tojs&==h}I_ܾ:\#-kL$}EV7z;HLbmxpw&(D҅jo$fbb闡C`gf3}"ٝ|0m}8_tqBAeMʫZ>Q#h>e@}Nc x(-Əvۈg~Z*3`573!z\0gb<gcbHeL$XvrK… yVrKi/sbDŽ0%p"Da;qA61Hge,z}gd1i'qHbBq=1>KxWUy!rr2c鏨9I 0 |-eD9ga2r0)^62yHgρ31d) 4rx&slo~ l{8=J#m=8?!m"BۡH8aƥFTH@gl_x*Bum0y\ ɹipïqeHV u u1ij!9?ÅnPL=ӄ_sK$װK"j[1d?"ZK$[W|6|2ir;\mN>Kn*s۪D|wB+E6vJX`Ӳ(b Ibs AɎ$]d%!o7F27c~BIEN/bXk[HNFo]$ZE2 ^TU uK*!VL6=V:_W{UAXpUYKۄ(`G\k`V 7<(G=ʮ$ Z`7 #Ґ@guA&7fe?nl/Xoeۧ6-m[d䵕"3sɩCRo|T%bu_b.cT`bDxr1=S΁us䟄xXb"r>M0*&p{ ƣH3g| 7HhK!HZ(VB7̽,EIƋΎcn#DjK!b"Y%#&ּ')"r"+^q(ErHs1WHNgL$Y%(MV %sbv6=LlݺUDr 4 bn/쭴|/hӘHZ|ngHۇMDMY8DUPj]IlC˿?WB^O!ǁw9* SN3mD HŊ17)܄ѣە`C1t'BRr:6m0/ qrRnA(sJ$[ʨØDfE]oVJS?J(BTw=;+[&JqR6D㜜acյ+0 d Jd/Sm-"DmaٮYW9۳V֡H[a*[܌iL@ZqL첎ĉ0PI8x!c«@")+h-x^CcS>x ;)b,R^C._`P^@ě-2>Ǐǹsp.H"ie&@t,LDRiI_>~+׾~mӱǮR)oIŸ`03CwDI^ʱ".n#BY9t~0"eY9".+U EAHZa׵E[:)GZkB&0:2YѣxR{7V~?)g!}q+&E $b"ҚK=?FHb{!U\`il 똝(2dĄ"$4f!Τӳl&;ʤx.BgV~Lar;]0&kP( FPP8$ XB0A;T&}kXaՒ a"!l{>oŢij w;Xh#MeNQ$CHc Dڼ=WDygbh,#QM|Hf")E^PLz~p&ƹcZ7!'#>K2[ MvW'ILLD~~N&.] &(,QGVB>N֮1170ruDMF\=$pTdrj F v~Z"ɉ`4]ēFH+1Ws}"&ؔ_G_O Ս2QrTڙY* QKqkoe)g\!ZTf% *--Ip|S"$y/C*;G"ֵ$5<ĽRKhxUSePd8nI<řiCѐ27@*gi6I@@Hrcǐٹ ɧFKl]09Xd"!l$-rAyyȞF$4C'ߠ {һ+0JK S.GŁ48(y[zHԕsXв; Z r *Lt{"ɕq,\DK6>YțE{ &$#+9YHOǮB0.VO:"bq!HaL F(tJ\s1) v-"iz E#5K7.=ബNt\Vnuy5t:I$$$A_$25v H3&a1ah +3*<XއowT'H~" NS")ϕ 7W7k?CW}"IJc-$A$epMfDZ~I$1~ܜ ⃀gϞTu1_vX~I$1իƸ]ܜ =E\M5{F߾}dry T^?K"022REq!y N2$n pyeH#L׏HAAoI  D   $  H$  II  D ӄ[^GtpyE $$%O>_" +.ϸ2DHr r_~I'.(((]qb +++;*oG|"Q!UEH;g\Q<ɏT$FC .ޚ)((mD{"I|nhXG*\X{#l8\~QQ>Q!dD[~"Ʌ _oOg{H"=}$$Og$$$$$A=A"I"IHHHj`85 #,>6Pnc1"K6~aY Cš3{ SHںc\Rܭ|n=f!T /XH$$$]K!)>H˒JV:]x-eޟHB J~%vIvEtj-a{"):#`K msع8Υ%we+j{v]e>E|_ϔ9J+c${IsFU'QU\{#r9([J!݊DR7;-A@ H$;-ȚQs:9L?*$IHby5 oI1~MrnRk4oA,|HXIWxxi/'{1q^dHHO4wDB44ѱI9x=[XE$I$'H CXPr9dϥ&|kO ɏF$04RضN״Q,oo@}UgM29p ph2*DRƳ*Sl tJp2۾3(KT7-–L݋ŨgϦ\_ W0}UC"2X+ߌIUa IsQVިAs~>rR3NZ\=L"m.7@7IM+RE,m"m<)X*E#gia|B/EVHYcJ,Amo8(V$WE۽ _QY݆RE'd.\)D ؓ M Ŗb k3iC \*+䙞2Dk1nc[l/ٖ6\eD#:?#Am;+p IXY}qGVõhs%UbE-^hq9 Č[k HP8ʥIxe5<"lN{v yrm&\9Lq=HZ EީK~D.l_@d#B*,$#9{ eR}sd F@@GNN$\'` U9iH^O .XE[CZzKi)jsQЏKRk31a\03.ib:u^J3N2jïp{>ȍG(C*D1.혍ql cYlVYz ;NUg]*FeocC"I"<^ҝӰdXy#[qX2 W;L9(ޜب(ĥ/ơ'M>Z@Τ!C,E#*1CbI Xs(PD7=c1,JƄ$L**X|"[%Dq +<]Kt<ҧƬK"i>jx3:C*SK9vf"r\(R>i%g9w:-:n1x |F}U Vm} . b61H̜#<_FߍH }n,+yW!8`\_2]-x_`bL E!kT^KaDDG"!5˘^TDED 6{\nFse|7=Q 6!\Y͇N~NnnLvb3Xh#yi…&e?$7Nu0}Ą8iaBt QEaq(:ncW݃4Zl# وGZ*6 Z-~XY EɰgD]C5"aë3.NH[sGPV {' :*go2Yhv-js VUތCI15x;Vr>֝-u{8Y?˚"VcshH#2P $`*SD=~CR V\$UJ0Hp<5)J=j=Uֵ418x#~<HJ`u׫e󡉊0a[P,+Ş[]%a0=**+b=rU1.cVH =^})4T$/nS;(;ˤx)DR`cbH̅X;S i+:'xhtϿ1msf{8SVK}!hUP$4Q7"ú-#_*E-kۺ KnI}XiD۱pHl gץmՀg[[Şe2ZP6!"7<ط{f؛*d"4Xa"k-i:= +Q(ym]NC?CrנجX.I3+L:",8[} H#CdD9rp1O=hK䷬ȺW#yg#"`Q-f+8e-H˱#F^4 (o?< "1VW`E7ER=R@HgѷgY|5r6m)6XFU$9af5++{#T=!f:ER_& C[QK} *8oLp21; 渽{إ6iQ&E~iwÓ SL*qB]ʮmE.tWDs\x]PVCaeH Z]u1#*Z MbW$wK V~xwm~umVkC:p]{x]ۚDzAq."P!Ng[`@[Yw+ h)&$TaeCUsF.ڊ$-=ܭ_$`?y ES!VIG+Ka*LSsÙ&)ol+ bk{r ~;^s;x5+qf2qNtmb%ɗ""i-DVk}4 (o;CI1d߿Iw)+&/#feD(+f_jDuyGcUu=F]׶2yBHkN"ߵq~ H?\1{kԜV}k ecU{`-fe"ybl&9*/-F_QrRgJ Ū UR_QȋAR,-#e2Tت_7k7 N}H GbެI Ƹ$,8Ø$@D1QF!H{7#\Z2*X}"]T;;dwnF}on $/bPc Xgq\A϶"ӵ]ީ@ ;rT^[{cjj: [ [NU4`/g#22)y "2P$=k0!/=iadjP"*Au^XR݊`,Vl3+1X/pjLG@Q!L;[ y%lKDTdE7fX:QW' "" )/N:1iJdb<9QJDּrx")+"ዡ\vET4E%gh:1-uS,dE f_@r;}c|f>ljo϶N7$6zL}yϷ L5Gc< )#+qI=Ϯ#m$ؘ.j$u{ٽH uR<sV4u^$U 7cZ{L !XzNQ?ᅬWؓ u-{ɇ [Q 2I-J\ĞiF!#X\HtM؀EULBdh(+OC%i7&[=kvLi vp]IQJ\bY3xYpyDR1uFd(Fqe_EMx)TR圁#QHv$$$Q8HV(ϺL{􄥥% <{" $$$E((IIDD}+ D_oOg{H"=}$H`pEFDyF躇$I*oGR$Ao###xxxvHwwwjBG%[ AfI;)|2D||"Ia  $AAA"IAAHHAAHHAAHHAA$AA$AAA"I"IAA"I"IAA"I"IAAHAA$AA[=z/>T0  >sİo߾crVauLulcl{bQ`*AAHM411WWW߫Ha- ʶc.tzOCF#r*< +cgf^ V5BG3*vDb(E#u aC0k`Dl-BՃH9AAH455q) 4HH y _0shL9pg\)WyL? Xud Ie ~ 8?1~ōc3eJ9AAH1k,"J A R7*8bƕ&T유z$ D $ԌF^|666i1CMqm 1s>/E\Ɗ'C:")E˸5~z;i*&V~<`6_ᙍHq:C[x\Z TYc\=xۙ1kUڦ&Ԗ&?_$弨7+kV~7 $ȟ䒀e ]\w3T4H!CX"RR$T&#ۧz2Ç꘵O$)^QO4ٱ$@2w$1E7e;;7Hqyqhv,Ƈ"sbDƚm &"is0)">j%g7U' ɏm:+Z5Ds"ُȬmfțQ nnK4ר5(0VǠ0cxPQS+`xXV\'F5" GDWzGW7 9 ~QMM)nd#i( "_8AN"?Issj'ldpxק{6A[$]P9 B̊8^XVԠhw\e_8@$$$AG$)pw|L upaXF-תQ)iQB/ `5ոu,SEG{ܪj˳h~uYf`̺HʆĺS7Q)5OhjAuYQh(qAL$7;'{ [:A| %Zu1wr sRHɮVMe6Cx+",LNqcJ:Ix`p(w  ]89E!)ZyJm KyG`~L$BȂ-6? eDGL7v?%בv>v"aef*vh͉R7❺gD ye{{=<%IȚ;L#qꭀ68llC#wÅ7׺pTMuf,#8=cO,Օ؏ ĺXZڶO-.ƻZ\e\)(vbmg!#|$A$v<Vv,ӕڃ{UxBywZܵ)6GRDО"iQq>#i~~9&^By_(zHZw\#Wˢ0y d+(mU1\S{ cATP-~(Ň!J1 6we?~Yc}yȘ) -a}~:MMKPnVo[A{.9^<8t2Ky[z_A?R$.9kC9\ǫvڒt$dv_1PgTp,zte6 baܴ&̹A}#r3I;/Kah{A$ۑc6:DZ| |>;ׂ/݉L_-S P CϹ~Z@ T+PSC7O/w9$N6ֻ< c_F1&ïєXT|?S@ٰ\Ԋxq8T$cY%nfC~騐YnaїIF;3rXؚʨ$JUq ]L]Z/Ø6_IJ T!x ??#.TЈy]'nMBP/`6w]EP؁IC$'V b|}PC$yhoEtXB5)Z:;$.Us0~+Ć8Be*YnEBJ\803, '†d?7ww21A%svM7f'g.݄%  $.Jw{ٖEc&a]a3Wo e66zvZ⟐@d\2TS,ȃ[q%ɴ8.^X)vMe ʨV!:\KQqX':0dyLr$;sb\Öc`VDRx+# y?J  ڵ 3Cy+#)]/19M#mQB-ARxȭ>_yUBMam H3jI;6$ и![7I3(d{&VEN I*|F7UOQjv Qm>Ep4*ؔJI_ 5' QU^E",skE OìΟ~4mk]\78GN:LX#E5$x0f=w!3[cCCA""9h {c|,ϑ$\C:ѮZ D $A"Iy"g"7#7L_! $$$CË`*7 A$$AA$$AA$$AAA"IAAHAA$$AA$$AA$$AA$AAA"IAAHHAAHHAAHHAA_H4|̀0:AAW.1o=@3ua? Q,.<?`ڃ  O\.UtXt,wn$W_30~*#ǐ9cy>/U?+bM;\^>rA@ErN?Buh-G᯻0$2Ğ;Sx_/ldpx̗\[)='a/'A#HC(DLpf+Y5W|DD?+AA"DwqI[Q,x> 5QX]Ae=oG}E>~;kuD(z$`;=8O8}zYvl+;`O`Ҳ,yZM$"m]). (ym?{Ѧo<{-Kb2AA*!2"MWMc;8QϤ`sㄤQB/ `5ոu,S>WvKUN V$'$tDRl{g/Yk?13 ?2f2'Wj夸ף 1f")G񖉽 54@ %]& cV]CǗ)7 :"Q@Ь٘WTXobVS{ xQS!6]ǚL?7Ux en}3S9+} oԻF`~L$BȂ-Z;I-$<`^agወ;f/ZYT,ƾ@b-#ٻ\=E*JR"$$q ? ,R"L 5xrY݆9OǭoN*1> H$&(OV&[="ɡd;E-7XG YߛTaznHkd|7y. ϡ/Ccahg!/ yhkGȞ!ve؏ ĺZebg)V,k.ֽ+CoBM:2\$=e(1\֏wvpf Gbg9vK`bd#bp^@su~KuĎfu!fmYNAiׇQ=~m"iiOx4H2_+ ~cgާjBk_aakeE$K1 &4b<==1ʪwGw-݋K5Z\XalK":8}.b%bnCY9^C6 }"K8O5PWbfH: M~²x{CuȐHb~v=U΁f&K `,>? Drzqm8С#+,]?e1ͳG W> H$9v)(lP{f>dY/ˈ`EiPy 27$\j_=3HbhYWoe,*zXZy;|KͲF~ȍw KE VkTt˛?o*K"'û-3i%ɲu=9֬z?$Uq8B-*xw7EZ>_$W@hdw9}AHHLFx_UABС";U&xERбc")bš"4nئoSZl@9Irïj`n_jCZa@XGjEhBbqPM1gAk"A1C?J2RiXi:o "w*\kxM]>v#q'QYIk|4LHŸإbs|D'bY }AH~#Z q6 w ~V!Q70IEp7lFqM  Wq8ajgfl牤JN[;WIe?1}n4CxikQ|v+>V0_ЭٸBa׷a],ڋxnw(8IVH!>˥Tb uxSWwɻv|+>mk?13y2WeЦ.ű=aXFdנE/BX|Ϫ;ih3f")%ŃtE/3Fk!u>`'emZطψIar  N$ryL<DA^LA$y¡63v#1OWvct=Q}Nph=eƘ(Ձ+݅B`L`Ò  08<؏H@uz?B[%Wb]$*X ,*ϬżY (9I+ǃ{0e0!:8}.bÒ  Răa2HCxUP B^5Al͞ H$OR=}ƄDD  @F޹s#GY$%3sд9-J/` 23q؁s5hs`jG%IH+:I; \+)p4_O6 9rb`9 JPN V$'$ HDCqu=z=7i unR-K׀k?!ncg&.=Oki ,4/"{[c$㓊IjGEAD3pHǭրXhʑn2cIoӷA]Qf/gx.ף}*o`E$Th?abp YP[IxDb+4>ĹOy &*tx45lOɆN7\Âc5x^x +\b@fxͤT<Ӝ,QYؔSʺ)Էp8W"2 P‚m|;!:;l^7Hm!f ٛ8yڥ~ Τ"M9u`|a<~6Zक़]Y-$ H$A"iŃ"11lDRf$R&R&u-DaTnC?8CLߎۑet"Kd.2 !lr\<\p̍OũGcD Sf ُ؈( ㉍wZ4RTA _%Z+`ߕ=yDx-P YȈĜYY_KOhc·XIPG@^GL/2W(*mE41ebB- QAlr!%c7<0\rѷHyj\>Y`e\Z2Z cV]CǗ)7 o!)@F o`\MB:ͅHl)á߁,t{hG.c0 Db%}(AHDW\Aaa!n5iH~(BE(| QaBN3  5Gsk 4`8dL0g:-<=ꯉCǂ 䶈AY8pE|؆ Jτd)-x&hg1_&ț Mx|\<֔!7c-"&:[V ClruRۂrd{ ;Er()} t+3'I&4"ՓU>Er(cE>a8"c+}X҇2A?Q$oҀl_#9X6\zd|WϮ9dsfi?d~m$.|dBZfUv 8IH$I OOs;uMG%AVt¡WKb)C$MCR1jKt :hV _tH:xT&"NB-م,/ұ( rK V_ $9c&#!F6ǚ͔wlX.j%{h-O!c-6s"Y/ж)~fÊ|-ޯW"t=7RN[EozHvpc6鋄ޔtI"lpLr-yHt3KGEnaܲHK Dah;''b6ҦJa`Q(1?!.VMlFډ`diX15 $i,6;dh,[4d=nN] itO!tN"e(B8^!Idbc QKJ x#noeMol-[!6ő( (cV!5ӯt ÷W"'m%*#0$PIbqPhƢHP̐%IC6.臧 ?}9Ta 䃝Q=W?BtQqXǧE0Gvf"/ Kv U!U$=O Ez$ 0BuR _H2Ua*,YrBJ\803, 'I_>{e'a]a3Wo e66z2Vp"inOŸ_9> ER,дºP`Rr^Ah:2^UjcCZa;,f r`1ө%AA"/eEhhL45(/޸iґd(vu'`KEUsaqH F67zxȿK P$֮8 \+)pQ wʼn 4T*lذ Q~ނEш]mw$OB>~=#{/xs'H$"9X憥^^ 7M B4d {f#ܹ#G qCAfuNHmlF!P!J_C vW }Y`e\Z2XcjdUA1G 0VQel_9!QL 1,A2JoW|t8LP,L@xEX-- d}Zx:V~7IR̩DXsF[bC$m-g h~ 6,R"L cI6JzN@ce`+݃Ǯo/`CsB 5%:TۊaنZm7;`b-JKqXz3C1TfI$13\D`PRadtg9UvM(:`?̊Ţ@u5l2ً""xF=3PV/iVBv݈:I$a>v6r8\K_ʶC}SLَgJ=@ zDW\Aaa!n5ٗHn@/WYߛTļfO<,2y1}YNQ0T,њc̾/ |>Ws ǮLm5<ǞC[!͘t~⦻`[Xg(QX8ԟꗍJ Cj #,suL,$ %VDi1TFC=.E¨~' >騮:v5ou5h'f 6R&_dt71d_qa0ug)X:J+ =mW)xXf}~T-#b:_Dk>5laЌa?cS|goujmh)9ʿ)>su2AHU*1uV>ErFܕDx뤮XϛExd}aPHr|`{ X5LY"9Ku!I74Ba, tn2C߄3- 8yp(|VAt2I[b`Y$Gv5+dr3"b%3 8=9jh[8Z6:ec{X2d"=.CxYh=3'=p\ELBv {:ץWaH3YJ^"ion`N+׏ {Wj<8=; Kq @k(}Uiq8ζzmNΑEx}+ ;ͼm:bZ~A H$"igg~(,e#v3Mc06HL%).݄OY$LP7&"銥W"b'<= Wƒuڋ}ldpxǢH(T,<{a1*H쎠{{W G-h+GZī"ICV㏭ CnbE0LUQ QĬZ灋ᆲ@ ]!$a4fm%OmtT, t0&9-ʲR0_uPҴi")s4j_H2Ua*,Y򁋤 1,2BJ\803, '. bUr|j|To:p5ؿ&Q*6ދ͸0@E0xD4?:MqJ JĬo1qQ ;sق璬c6^XCFW\Lc-=5\*32*c@hT֤ ?FQx( 7D^Fω%CfԟQ 2c5w_hD,jT^߆[PY~lAgX?f-g|Spqď}e nsŘ!8 }A$M$rlr\A!rpȾWl;{c>&3K8ԟ=}A$c{`9K!'n62k8<7d*2NX/cHA$$$$$AW#2 ܈ŵrZ5*r1%3a^{۠.(wB$⃤̫|.E+v*!"4/*jP}N3KxDb+4>Ĺ!ER?BFފI'KPf);X|JKv7׌6 E;+VPfAW iH3A .l 05ǣxDȍqQ ,׎wO #γW̺pҟqF*M/Vy#s3fgVMg0s߮cS]-c+GV;FߵB/E}E>~`).s^v"E]PuN`6Ji&7p57+Y~-\k^GwG6l&֝JU~Bdǎc8;l^7мN ɯT$%9\C}e;T~B|__눙5>@ %Rad9JR6~ZQ]?OIO EDFdW#$8'J5 _F-%7>% Nc Q!XpV*g7`TQd$xB@Gm-d$/DD\8ZX9VDGLAj0BNU;N/f"fCY紿c,=|(m |UxT +1ϓHh(3.6Mkrw^$w,*cߍzgr1J pz\)pI<֊;w{$ UHpnjyʈg=^a9:dIg (9TuLS"+ xs"1 WVœIG d|ofwZ I[YPkS1U\4r[f.=72VvjZH*1fDBG%`frT)i*3cQ [QHJWZG]9\IQa 93վW;Gm* 8qG#p@ 'eIEE~G$aTXFY˚& _?`i|B#crxwKo\ 2S]#9%[aFdjxpt)&(ɑ]]<>RpS ct Gxtl>LoC2'N밨$$ fjsXifħqCⴰ=$?5 {~~,B!a~.iKK8D "n:R3b2pBGC\nlct&9%Z*>*/s5PG^W;%t w#A>uzhU9"SfnIŽrz ^ÚmID/kY(R렗'}?fx)~h(~=:4WY=4ub>ǃg邊ƇZ{c,=\YbDD I$BꋸeZsI݊A<IDĐdHC I""""$C!ɐ$"""bH2$!IDDDD I$C!IDDDĐdH1$DDDDĐ$""""$C!d-6.DDDD<$0Dz̫ d;])a =mD .Cwi6 bt;s]#" B]nk/b=7jp$C#c>!B&{nmwV_ϫ)mc`DPPp]vm*e"$CRbijOYd;pBkVscq]`H ^źLĐdH60" Ô/KŒm;$C!ɐdH1$u WnBPA|i1ߤi:YW39vvvp98:7HW!lRM)rnŲQPX{}]1f]*J^(ËX=qrN <=7l\#}ݣuncKoiah0+!`ˈv5q\*U2@_)b:`kSrA:DoYصW#L^BvA|i^ og!T Niؽ( *#|'of@t52X p =JuX: m|~֜ 4P`= vGU2ssb|ӡs.B:DcKt"< ck|],`:^׼ ǖm4]?yVvpig *m_!BRDDcPp8&ob]& jc t q t2<=+05G!y]K/b^P׸QkTSq'yMVxabQ!j@\D(bĐkxĝ{7p7|k+ ___x{:|h2DiG)n# SuB~12D7;Q: VCG'"yVja1, ð#mԞ}Cqp8 CԌopMG0e~( `xaOp#21$_YHZh7 ;Hݰ!2䢑8և|!87˽j! _]Ы Ÿj/W\gZԏ;׶!UfZ<> qF]S] EE(.=IG`NM1쪍Cp5>nrQ(Ga/ZNӶϧס-?fF<cKC:=Ugˡ<G6]t4U,moːoHKz\Plڢ>bXZy]b|rC@8to5vmn!Cl#m}z(_utSNCblr]t}h}i:0ΆSU=S@ mm/pOyWtRP|| `.UwmbH?&m9_Dn/_8&ɦkX&bHT"dNĎ; P9 o^6$oKztm9(v$C򵅤v *C7}y!)d SQl"//jz);7Cr6diq{1$_=E^n*wm#FnAζ8 ߈'4a_w:xE?Qk+0'P)t9t0ax(+pG눞3;PqwsS70deАsc%(=> ^q(XuG+4wW @Q[c">1.wꚳ!d1K)%~Ϗ/BdOimҗ[QUNIGR5WQtrm0dc]u7i{̳ڞWS ۶+;%Zh![맶b,\&X.ڶeo_Wd@Wtv I{dתe˴CRAk@W Xnts]NoS]6\u{l}CΖhaSfM(>]X q{t(Q苭21$_IY(fbH xa@JBû^ N1#B:*3|ƨq54$?lKK8D "n:R'FrwѰ<4]~g9>;o b@Yr/tO6o0v!'iP#0a+2CR_vNClD8bz9:*zFa tŖ6SdD%z6<G;Nvf*Y887aј4gE 㱿@ d-mZ+ޖ%6^ö-$S7 2OǨpMG@Gٰ>X ;8G]9\IQa 93ֵir]t%$mZq1 G( "mglzG/Dր#|;ĐϽ#bXt|u1z6uO8qG#p@ 'eX>"NcxF$a٩b\/_yT,NW6zL_|xkvk#tE\' "+d۞[{eU-+DtHr~q@|F%kkЅ :a}q58$ G 0sK*(7~MUᲯwPӀHp=Faͥ(TQWN 6|M-[NGvʋ_ Q${W}P.=DFu~&RiZagGl4e8A.97q(_mv^3>GuI%: |3q|I=@ٲ#6Ğ-ja]vn9tbteŔ^ BhqZz&}?fx)j=RܐR[Hڴ~YNºS5,9?o7|}Nu[fX7|u*)^Xj#P,˙+Ӣm\!N݈jgtDx@/nuiߩt-?"@ AZNU5UH>?ꕈu \'g!B\RH!!IBE0l1\0ޟ#j۵k05$$5/> 6jwW2|fӈĐ$"m}7!WNFAO8"qCyDDDD I$C!IDDDĐdHC I""""$C!ɐ$"""bH2$VZθ4}yZu I]˖- ߧO 0DDDH |`8Đ$H>DDDLI- 5 IyCTQ3'5qȐ$4gs!""" #...DDDdsecl?(~TH7m>HZ{{ GWDDD I[BɆhiڿ8;;7 e8&Au!u6djp{u$&˅ 0$tAN8VI;8֡F|=5?G`{}:|5_!H:hL]CC=+05G!y]K/b^)~[vi8.ű NSxabQFڶNqj !0GCmɺ"!isHv.΁wmð9G5hy:[ :IEjd^Vk&@2#C|ĐuDbO=S.C/QK)Ŷkt76'z Ee̐$""zbdH6 $'Z PSHC2; d,k "//jz);>k|{::'ᨪ9C1$_=E^n2.zX˂$k>.!yh8`Cr(TNAAA6ݏ!imߥ Щp(visLaEZ=s@87%Z5:hNMcm!i|48'tn=GN RUAm逐MYЫ/!Q ܒ/J!fp8/q ]bg7j!O \ G+ k,vꑿ?ݺaW™YݣVݛ%WH"""$D{=0ߍFȟV7:wLDDD͜ &~@"NE x.<͐$"""d͸":M1:}TH:u"""fNj$5hJ_#ĕ&`H{=t ݻwGǎZ@j dVZuֆo߾5,~Z@j d-[}Hӗ'lH$4$1$!ɐ$"""bH2$ I""""bHC I""""$C!ɐ$""""$1$!ɐ$"""bH2$ I""""bHC3!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$CDDDDĐ$""""$C!ɐ$"""bH2$!IDDDD I""""bH2$ I""""$CDDDDĐ$""""$C!ɐ$"""bH2$!IDDDD I$C!IDDDĐdH1$DDDDĐ$""""$C!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""$CDDDDĐdH1$DDDD I$1$!IDDDD I$C!IDDDĐdHCDDDDĐdH1$DDDD I$1$!əGDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$C!ɐ$""""$1$DDDD I$C!IDDDD I""""bHC!IDDDĐdH1$DDDDĐ$""""$1$DDDD I$C!IDDDD I""""bHC!IDDDĐdH1$DDDDĐ$""""$C!ɐ$"""bH2$ I""""bHC!IDDDĐdH1$DDDD I$1$!ɐ$"""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bH2$ I""""$CDDDDĐ$""""$C!ɐ$"""bH2$!IDDDD I""""bH2$ I""""$CDDDDĐ#"""bH2$ I""""$CDDDDĐdH1$DDDD I$C!IDDDD I""""bHV$9ޚ?IDDDDo&$Ő$""""$1$!IDDDD I$)!٪U+hтHu\>/cDsfv]S}#Ҵr ɖ-[O>0`4?euvլRDz: 1dh HHV1nһ i+5#<潴 p׵nνu[:?h84i&M&$CP* I?^2Fq;jmTmp(O M3iڽU!)Jn\HDwMb;+wwŠ ~~M6_4Đ|Ia٦/|狫E^9w=W1~1Xy"6&3$!iȯ޶րΘ4YH5G?_m)"!G 3q"1@F>w8uʄ "\g.dҼ/$-~7[X1X)yOX6sρc0>v0<~˂r#Ht@,) oW<^]z9A=~eMɺsZ9"o{nK148d$<5ZNE,&[tnqڤiLB;&}r/_P! {Wb|PS\w1\]}xY~V NMq621}T;>pH 12#GA?As/߀U<ۊȮdvm/f~vÄC.-!ɐ$z!pZ?U#-o#=0`qshuЕͳؑ.><ᔵ-Ǐ߫5; F\4yȼrkfF~=D.{&z|r>8̿ѯiu!''?h؂I#1::ụ./1L9g1䔮N:(gru_0mxLkvWc7xbCV: >i/| `eDddaJ\t0M\׷Lr.C+7VC2] ɝq 2F&dm۹yhgM;}SZ><XqOpۥH< phY+Yi-Р(;Z|?f+?3)=V>,OX^,ݾs`,U"}koBrD} hr~@J_Wmi֬Br9n\[:.>MM :8爅s5 L]QUHaZT|2iun /ݘFmCUC\o{K.|31[B<22 .κ= GssR0zp?\O<]jTzƣ CWHǧ}YO?_[#,ͤoG/kyLZaKpNJ\1lE:5q鈏I¼?PG3<Ωg2RL/>) _!TikL>v3Br7]Mʄl]; D!v\,psyPϱvҼ/$_n0=w1$?,n@q?Ȼ 1v\|u e2:^!fq۽vh c\+oSF~k `q8QDp##dXLOw}[Fj[,Ҽ>s0nc1e\"G!a^-y< PZ9ĐS76_F?WNyᛔ ;g"W-NL&;o;1%17!$kI_c3昬-"%V5;s+Pr|ũw("⸸*0{9U%Ą$3bp^ŧ}Xv}ۚFR >右F=%ֻ_#,__PTay ~V1`>NT n =3|hGr__O} Ӭ9E#e}h4zC6Du g b\W .ƣ|hV+~Pr:UT8:{Z s=SqqOU|tKľB7$N@¦ecpCXUL8G'!Y!w̕ÞpEmc&38:<2*7N1. 4O [+;/<)=e1nv]!iű!6GJ7;k.#V-gWw&n.rQǺ4Sӭok ܝe/2_8.{ZgHz#qEDŽT;^xq8n!B'T{>TX]qܧC16:a>r3ֵ 0M|?`Vw!wlR.둩xjI" CXYp2"V^AOv㋩!b2Rsr? U뀴fu:Z?q5\d#W|,N/]|E\N#A}k JPQt y9tD2$mIMi8-;mҩ'jɀ:MǦx%%yΕ"j IGeu6_AH C^iị֋ ҿ۬}nR:m)$ ʸz4* q;STt2 ˱G 'AUQ;[\H{B&+ I'hcH~=.Ɲttƹ>R$q`]kF_^Xtp (e;sH:lcHNuSrܔb'8e~c08Ug !| $r1$laz5|R}>*cANVI\~N)p1㪦)$W;U>A X**}-Fy8ڰXY^Q$#i Rraz~ᆺ!>,FbEZ1z9q qce\hܙ|lz~rU|Cv 3(Z|֭3.7UrN~ K,-cDoJHZ[~SZ{mj_5,-@ѡm}QF`#EW1!q3pewOrkݶalimɡӫQZFuqMO;"#s/R8[9,i[Psڸ )~/t(kk4^GHu|!)ߩ-"M41l=~N6 Sq%Њ-3~;%j*$f]9l-M.Ft> Kxy]c=ۃmh>pX{_T؎0D85t!k6~(!cIq>΀,s9$cwAy=f+}+I͐-kוWV`rau1qkc Cr162$leg䍏ω}{%;?ewxƮxZBRZ^ȵ^Ý ;$5W|lհ!lo`uH7o-@+T6d] cmMSPj[lPwI _Oٰc̶,4w!6xz"z]ٶ7Őܕksh Z};Ui5"$; Itҥ<&Őr4YQ .ߏ6GY8-P=LGdd g~F藀'!2lǂL.: mqvoċ0g";][HDO.^QC}{ \pqgBIgH]?c"?CGk#fiM#1>cnBo5*1lMg97]F.ǦyQCwqǬv]+(G~VI{ ew4Ę6b]ğ< 3q`xDV@@ø:y__Ha|x:zdgSb0zt4W_@!$LGxͻr]D̜6,gU^Wy΢P8 ¤ų02ÆD=Q6,#-["|hmƸhq9Miy*֖#.CЦ&Z0;0i_˟3Q]X;R}Nc\S>Rb@yɳh:x&lW !YvnQI[HG2-{v>РBuG֦`8ĎYKƮcঌķ(S#CvbJ7 Һ5yRHjqgu0Խn׷?im 16Z BQk _Y҇8e9fMIscәG((ŭMѷ1M!SK _ X$͒4͚qHJ 榪{݌I8-rd]IR/Dž(UBBXgN#Ýr;p Mg!\V |cgQÕG8Ư~9εNM[ <O^d?=UA+H3L BWƣBR56"#[Y?]EfB72$a3h:eCEYAn_؄֧ $MGNR?t}cm<M8|qbJj42WAQOIz8زp RլBh pqYw;Pzm sƦxQbMgHxQՋWY1I[q˥g(r4*Ndž1n5Wq=#}eF9sdHR IgцicsDǬ p}/Њqt퉸>|J;ukn{ѵ{FsM?D;c+y( ODZϽ2$e>v"SxhfIfFHM46$ѹsgzOR5|./xi\>1[ƈބo;$߲]rh N\! FM@)aSn'GoS4!,$V[H!8 i!'bTpEMYJWqx%.Đ$dv1WŝUsu"$!ٻIu@ Wdap[&߯MfMdKYHv9LH:u7]n%.D/߁Pt~aJ󾾐AQ2F&omݖbhPz~#4d4,.6dH54֖_h#5~o9ImR^D%"""j6!yԀ櫵Gm̟w I"""u! :JJ/p5 l0o:4izty/Ιl"a&?\p^)׮:.I-F!ɎJ쨤 k?/igOHQ,RD"IOQ/ A,{dnFSpMMxE05Jmw^QI)nk10}QebzRN"ue7 1'5eO;,]MMbj4GSu25\[SYH)mkG#ݿY)nyLgh/;:^vRzt6s`#O) FS{f#eG!MM޳H)?Y7sHZ4~G-ɖ+yi!{vhβ492dE_LMh#Z"e씶HCH쨤-1w<-dG'Ai';JiJԉZS{ʎ>}٩wMgKDFJ mǿNq[I869*?KKXjKDDDD b#p@#4ki>vw#&͟4eQ$qOYd}HDDDD/ŲZ| ﲀ4&7S;J 1_?ɎN#m9.́RDDDDtBɎ@iTXtCreation Timeпетак, 05. април 2024. 17:45:12 CESTձ\IDATx TTٿ&%77y/e%Y7+U3* 8*( ""8#6*88+"8-8ڠ"( P@}TEThY s޿/WoZ?? /  0wmaOzczo  -7&K!1+]dFtſ#  E;.=oMo5F^}"otUwAAA0t;=zq ݄?  awz'6\F2)1GLo2vC AAAA%X`⁺?AjtP3C2N/cL=1AAAkkkRcF33 :̰v{giiIOAAĀ:; L=iͩL`FwF{Yg6NbǷYXXtPAA1C:縭N>)5ϴijAA1Xqj>L_/hh Mf$&  b077l3nR̥Q ޙΡf슞s   ?&U3}4:B}ߪ p  lo̥!4f^9!%  ba݃qju&0:܌5pQv3   =XQ2p3d? ݌ oo Aķ]?H#4ƆΨ` ~0ܣ2} -\dx9'b)='A?j{v#4GflbG7 ;NGNg⥋>sf :[r\܋ȑ ".bO'36g1å!w-SX5=/)A6LaTXRSS؟_aD"[5L)4ϰ]<OBC!Ee͒{rt?BʅoXhm@f.{!f9 t|9ƛd %Q<A+. 5~ ߫<B= /3:xQ+x3wGhR*eę\3GҐ8{4:18t2/S8u,4a72/,طKݵ!Ӥ$?>rΝF򻄆ȹ̣fDZk( 9> gÒ='Sr}XrHbz&U\Ef dFn{Ϳ옵 !}\bL숝ý#L| OgzqrO`bc:sǎǙ\,Z19sAy{_0~1Z>={.=!4.eidš{ۃo‡gEΙχ-fub9ƛvInDL0w [jX A<B $4A}a 8cqnŬv]|YJ99GӃagp_/D3>^OXY ?sF0goC*`盚C40ViRsTa33ݪӬv NxDZv-#G%BH8tI{}̔3.A%9vÅCUta7"GzfoU isfMs[}F%!j)\a,&D1t:H-45$BN;{:Q5tИaE̍AUWcd 9 Kc.bs\ E[{/^Et[hKAI~;=Ih 3|O*`7QS+cEhp]'r!5ll:X>L9yv*WFXc{$t w,ܣ GAAhNzcq95{-SܳX?ZkkYc'﹨o~ ,1i| [L*{e.";2a$nuZ-n fpS8|eVY)ٌ\^R-An6YhS6w pnAǤV/bn\X 9ȄJTN>?{Ӱm>F9O' NENj2}rXAإ8fP;zer},la >s`'.;uNEq|Go=ǜlj:Ƅ=nf5˥̵7r<Lߨ>Wa4/ܧ'[P' I_}L;l38s.[gumʡfy8>goCN̓2 TjoE:ﺭEӫtl&!fS.Nd"_9_ڤ7UMd#4Z$`kv8[!D%Sa;1b0Y=֫}4B^۸L_"n|Y407AXx ޟ_oܘ q58{="u`/^Zps4~Lyx#/T3a:2ϱ{gF۫F(o$hjov́K#42CcL!05$4r펝80)X{^!͝Xi/!;Q\^ iDux}ë/~ w_p5>7 WH)F;aBIT6|~>=1wE;T3$S( m_s`CqF#tK6} 1sTzK5q"NbΏF#0=) O>6A*ED;AuߘИ'H!hc΢}'wI3a*1ӂbn-n* GP]Q"ŻYaeA0G*ei~0'Js|9^e&"*tB6 yQP-cX56BobJv߼Khde ǝ̏܄ݟw+dawPYpl46ym;8ɜku|qAо4<ۍ1ckFhbj6M9u\{x$eG4𳏢BVN]WZdPLC}:oLycs3|8q8j0ǘedq:Ҋ#4wI@~[3n{$ʎK\\z'y|>zqi=VLTg'-†hyyI6{?ctvW= D ZNBӳnw' zyey1Ǣ9qpBJjocg\bILꌙ%I>XE?/V)I(l"!bq fy:{=^"s| X`: ?N!->zN%.Z=K"1r.&a<&!r^B/ǁuP]T!"" qE>ߙCwÂpD.="(ݥn7XeF$lI o!ؙُi&<9  {ETC#Gq 5 N&#F|YE^Dizɟҷ3tLws琊"ѕ((䵰_zL{ ZcȄ7%d{P&oh[CΌ/ bsP!EU)̷27@pםGsa/Vw|,x OqR8`H7p\GQ]tg1X_+;/4oq G-Fn1ӝ+܆B_ne4>kp&LK\ppLc/L=jBmzcQ4r4EF_1OT p}O$r%XGXKBsșiITKvL;RuNLݮdO𓺎TZWFj2 {OI%4R\ӮL X9ց&4#V܄DQN\n+  + Gy 90'U\iԼ9Yu]BuQq Mr!^;_P}RǃTi5yH&[y=2CFR o3 N|B{|ݐ@V#e4'kdx` #g>#|s7MjF=bO,a8ZGxc)L[`fͭB|e*dό2ψg"YGP.o@BLdMi4@1< @&gbN7Au|f>F^FbaO(t[ϩ6Ңgb/ĝY/B31e Ȝcil°/hS@,3lxF6XWhff1|ܾ6zpĄīU*?8icr(SZ?wFLnde`'ϾFk=tٿ=;dJށv\4V cܹs̙}\;&p>ˉ еZvW6{u>Ө_/7]~JpQvTÿ/s)cG>S ;P ϘݮǴջO]'GՉPۻ!ҝ?=_vB`g&+-qdx:lG1ut_ 7axQMr뾎'<١ʵ8@lfd:yƴ}cdڅ?\u+&_[o!lݹcG7AuۿuhxNNNAoBŮ2h4JzG\[2ȅiAhI{Ys>✴Ŷ 3E:Jc^q}e/(0:y8Uߢn'o} a#Ӑ9yW%g?@VqKv;x1XZm ^4އto<^2<܌ i.N µUya'3lߏik?7"anv8&bJh* +4msHBC8 иBӆ(Иm#D0f!QÅH[QY Xyf8"4 I!{S -NmD^>8[9d"ݮB0](rkH} fYUr: ;1vď&4I#1gv0Bx](xkÈĉ_tR]QF^ D 247+Ps1 N{xDo\oV^3i\!FGb^N tLP ԈՅ)*qe| p9n?666]؎ź6bNUn4$m(ވ%bsLjX\*S1s>&FxJ5l#hm6*cU,ueM4vml:>a1X3 OjvRy~ !Ns൰w*8*e]u?f`'9Rk3n,爫{cm,"°`: R[* 8m/CXR$|:yMV A|@ 0h\nQŕ8V0B0gQ"½OZcIQ bگشW5ԀИ!YfVߑBõ63̛v{'2N~s@#4=g'[ ~N]aX{ uKYOغ1B#efbt:$',3< $=/;C .B#Bik;DX0KlH$(*űX5# s5w+n6(! 凌8jkzsM1uu;HDfUA.*K6iS1du_[hxKuqd:lK{|aX |򦫈A-A 8S2Tyع`4 a&|P]+Au ZTGҸR{9 (<qdh+ЮSl Y,Pk)B-rJZ`1+?S+?'cGY|MQrG˻Ĩs "j]#xɧ e߄fyr"ԊsnC589˴v<$dwBPcLM@0s6) $/wǝu(l<<)H:HjQV86SebWBhok9p"@"߮DUwT,c}f(~4`T/!sL"> M\\FfK 1uj$FG#aq-)(LU%*`$f(!k!y&32::BHCO {S'|>-0Etu9WIa@h2uWx0X-GTX.0xҟǝϐ # PǾYs/[!y/^azHf?ں6~ Zj$; aC0^~X*Y@xbiԬa!.n:|lBs (4dF[jHhAGpHhSa_7PN&7XRߵ( 0kba|{'“M!}*t>C)4&D*DW:%4q)Һ2I:7oȋ L]1BgVs2Q"oK-+F}. uqُsL Yi8Y.'!J @B# e_KPNaYOAF4=I4拯Kp .WY,E[M .©A9vS!I%2k"ͻ D~ޅoAU!00NාhHR .X/q7 FlV꠾C=e[0.iEp| :v,]B|LF-GA#A,HDi {OwwO]j8 S=ܙŶ_3,sUrk]yk 8B|,/CXL?bnzbAB ( y_v#g +n5@'0wRRI ̶,azFa4)_ հZÜ]hdxW[1c}<-su 7?wϡ1z>CTK:/ߩgvHzlN9Fc9,ĺ"6]@5 e=^Gl?tt,"E:(sQsVlO~uޏ꼝(LBCq7$4"4 4t)~YwoX"*Wa^, O㽱"e1Dg"w1O܇L{dVcq֍2!;F~ʁrH5ÇȚFcWRȄtԐ35'1K0L˵kNY;/Egbn&02HR.Bc>$>˫q.V좑ЂEhTωwlǟBCfZI·˽P=_ ToLܘE(X44𲗲&FuX\WPaMQʫpt5ffT0}$G- n>m%4fL5sX<{u;V/F0,xO?`>l~uޏr$B`ʿ\F ;ύ?یoAp_ D/*m`Ccᅘ}?u$H+p Rhx 2E5NXtVm2<c45Bއ.S@XN=*8@H`&e=HaiWv((DCRmy2jt8l#`Χ]X#6_ Y:Ԓ T>4 )f3H@۵kZc庆Bh 2u'X`zrrTiX:'?IǼ i +^/{ Fh {zDRkߓFǃ6si%J |-,&ar[}KLYƚke6.fmn'ZСW5*rz"$>*u0hrfH~! S%P\m76Ǐ0n8 tBChrƳCxV5uq a6}WJi,iEkq |2\ྴ 9# R-d ˟#el_&o`?5 P+bC/'72 i<0SUnQZi1\&%B*hmW&0_l1p! .ɺߗBV^shz9_pj}NTCѮL,.0鍹 08`n }azb80Bc| Հ9Ze-МޯetO"[f GW6 mWiiș526};w7B5%5 / Z]hqy)Z$Ef2p485 'H1w jΐ2Zh9\qu аLHωOZ08F[-rA@J ɟAh shF%ᡸ79!,U/Mm{1{WDaDtO|/`;/B\ ޲c1gNq1+`<4䌆 m&&#;b/&C~8>FmVވP|j#͙K6 lĸ$K'< AAO<_x pOj uXS3'L]raڻ M-7(;qFhA e6鈛3מUf9(.}z2ʱ2@3޻庌 f8g,g9TfBps;iSG#vD{|q f} vmLJ"J0mbemHzI954n176{*˙mfW[{љLr8Og;OZq'wʄX*^3j8&B >>FY?!4ke\> &.s x>7B,+\Oa}C`3OU %y).sh#eq< /?v.δ )P”O;r$Fg] ~X{5rXCFm^=[.Ehr]!7 ]߱cnǭ&VMiTچR9 9TE7t˓爄- 7#BwCN֡1~/֡ID3v V<Qh{3ُCe%?h9AABCBC$4lGbM%N[ 4zo}sAAА ހm&$3f9!hM ZPYA$4$4AAAАAAABCBCAA$4$4AAAАAAABCBCAA l   !!        !!        HhHh        HhHh        HhHh   !!  ZhL1'`(j/ݷb_!'9NmJyrhf}#}T4KȞn =C+Knbz|R qZMFa# OAof՟L>d%L5odȔ^Bam9#f5x0N=rk(sJ];: Qz>&!]r՗&9x6S,m39&Y_Dx&ʟY 4,$ƕ7tQC]\R>ABm 6{VMAB p{|.* jd/p 0V0/[$ܒ ߂"̌lg၀aA{VhxpFaOzɐ R T 2 Wk(jE|Ja҈/8Y䗕Z=P~F}g{1Z}?^hLڟ[he<}Y Hhz[^k|?&sj /4V(_#_uh7c~Ŗ1|# 7mclޅfŒIZPUt#Ltx:d?DX Q9"j_pU [Q}7щV(B}^vɈG䗢E Oϭ$DrgCaս|~bQ:2!g?)G\lQq)jk $| ^|nץOhaiL)bpվyӱT~XV ּ­0ּe?z)!yaƅf PƄ:?%xЭQR R4|^)AP ik ^sG薟Rz\_JrviTJ=)9ϣeڤ7+i;UV~jބV"y9m}!< @ϐ3ܗ|Ņ%8r=4/@j(Nn~ՐzE3rt'knW I {u,᳕3sdF|zU3^,<zĎVF}άòP#zMBóԤx+R1_ĞQZm # jĐq66p6,cFL܋[eL(BC5$e/%(?>EPqC`]g&s4&zTq;tIKyO?=l[`Tr۱z.nC(uyO?%~Wpu|'$Ke6HD_,3:%|N~yhgVN1,bϐH!/+.֖!3zp NJ43ma[M .‰$4C 4JN%9Bc6il]ϏmzSqDŽL4pg6ܦ (uXWj4ɨ(hK Lx0;QM=Ry+>EvC+ǩCSh)Ar<̍Ib^#L73N&,r) kdn=뙴B4^6Ù}{"Ri~V]lg=߈Qq*u=֠ Iz^ueQQAa|58{E#lv0pR'7s}?(\oŽt?BAK9d7D[2dxW[1c}<-:?)mVFDr9XwRŚ!t%9eȱMFWZ^쀟TƊDT(h#be2u#mAHΡQ Tnpt/A'4L`w"K h.o<8; ?G^ZPװa GtsGN*ÅXOs6 zw n aSp3 /[4z*$4$4# 6O2 3sNEjV*G\9iw69.>L`7MRmzۦ/B^pMeWc@3bz ƧB&d~fS M+./P J"ͧ׹m\'Fsݟޅgxs`*,4H׆s~cxLppVJ}V&jlB䵈JIs]B&S.{,eȡwm2?n|!Du>N Sh/!Һk{4S5B1$E>0Bp3&4jdOAaڒb&Ë^ И hU^t˾B&:$0G_V:1 /B#-D3Os_\އ*|k!+Z3C>4zY=2*p+sX/C)7Vk"\mkE^㙌bq5O+A(W!;5аAԽ/! j`F=fˠQ M^:@?8 J+>Rmy29sQd ^esd+J.5r*XOZ_g,dgKB#FJ!OG1S݃uR=4 B7! K$2BѮcpw)gDÜ9ϑy`,6}!.,0rW.k7ztnqpg Z t{Ṽ.[k&6g1 >Ygyu9E\3u CڥGxWӄ6Fr3ջ#2CD<U 馞YŌ fqZe>0V\XC 46Kp],EasױM`KHK2̰2SX 3u2O~PpnB#{z>Y0m=6u5BNI 4PrT$4Sm _H5'; 0(A bOLゕ pm6O i<06 ǪB)$D e: 5U MC^"½ÕBsM!u(L(BEw;h5昑Qk[v['1ʏ+z Cx!R\!gLЪ` Un1Aln orݤBH%WYhF#/>֎2sTYJ30stLO=l=_=~_d oLRJì5=LXCX̳m" &q{Q" T&]uUh͋bCճ"R\>\ՙ Y34+qwuWu u6RrP A{TbOsK`k2"4"{=&z!h\na%y@);^nKߝ"{ܗZ9Y}1fY$r[{93^>k(纖} X̩I7FgDJPYfQ1"Cg判IksM]  ygL@9R) 'HhUhxvo%Wh& k!g4e=4 F=EX:b\*핮%D|~DjٟuhXhHgFTQ=e )OlhB=iB4>iq5cW|8f{?{} _ϑ>˻['8 왤u ʯz/4lIC^ܒt5 p;C3Ҿ sQvΕ\kmnyޔqf6;\QN,r@6lÃ*_Q=`3<\{>qCӛа 2H^dsuL̵2ؤB4 aO/)A{PXkÙ}8P3n-Fk=;v@2p.}Bc9MYto-Fb} fz7yڂs~L';[%10&&K}o ̡1,4;^BN﹥Rŷ*4ܯҟ̌]|SPCKv7vձhQP%י:t{xΝd`^ ;2_v] kF,Ҥt62l1[tM@M-`j愩Q.lCbϙ~xP6&s36Br&RCr1%;Y"\X:!NFh ˙cE#.yF`;s D!4vfSe9߻@4ċ˵z %AZY |3\m8~1Δ4C-4?G6-EDH fEn@NmLC̳_76#d"ۃ +^Wi.#Ɓgp~+4h-0B5o{1Z68FDl=]ǎ&ƫcp3*Xa22)Rx :[~~xHsSR\{2-K(ʰ{Gmp];fYD"(0)_E7d9kDѕe g93$4pYx#n@X4gB,ڴ3(()1_9neQY@=cjaMnBC .\Fً1 X+! nx_tYQhTǮ+P$L܈e oį;X9vc]+%e4u_+d^*AMZkXLR?vDԀܘuF9O[!Ek{<6̽ >J!V$/so 3%A[.D@1`Bԫ k1one1.g~Fr-lY}"מ/۱x6_w %"&oFsXGxo-t p۵~  My|Q!gw-|W#fG+e#) ^j4G43B ~oWwX7H#-PXthGŸ$pd݂p}dEXיݐg)OM-ZLVϮúzxpoR&{8C=evܹ_==<)ؐ[Zؒ"F~eʐp9r߹i7v8Qw&TqШa.;E2 *p6:4FͬL[(ǗqpyX9155'͕3C%4=PMODɜ1}o!}ٱ<-GK#K05vH)6 \1q߈bሃXݏץVwhA@BӮ %oi ˃gI+:Hh0G=ɾ}"|&D|M Hh~LrM wG~f.VJH18aj <؀6\9nF,,ډWhCq'4et cq!c_F(\*ħg)ȉzgWh   !!     %TgX~ ϫ! ]r6rUءI YL++IH =6k1vK1gjՏ7*ggFL>d%LsK x6< Bأ^QY]PHyUx=5μ]r߄ bųei6"£5]z[X[(e>z * iLJHIQkR>K/`Ki}#B#} ] uX~ l[ b\VGgaM }tHFx d]iY Qb>G?J_)W){ybH M/R ui/{ 'H31yvT5ާJh(;X~].ډh (y <*(qB#{1_Ss_SMLFCDO0UwҐ]0~B#؁sq*W̻e#=qEڹ'̻;;nwuaBm) ABuhxE u n[\B5-<0w:<,h~o (,r5I!Rs]jjV8P&C[j@BcEmȞo$[X"'+R½P~[Xh9xL2  jor9UBT#Mt?K+Ã!!Hh~hE(c2ƠBc;)u05]w zxl [HKj&iAU!hHu~Z&7sx<;E]k_ra+ :" E/ދ .1RԴ0 Oϭ$DrgCu)e$ӳ&lԧfUC8 ,Rf x6(B5赅h>/>'44&ؔK jjO~ћPPيB$O2 /3g7rs]GGXH 49]OhTAZ9f:5K@>ix!]`dl/^L7 AsQ{nXeFFV{=&Cv5xobO(υ[5MbH_Q8ftO1`#Gŭz^Ü$(?>EPqC`]g&s4&zq;dIKyO?=l[`WDYNQ<# Pp=gSD(@Ym!~)W %|N~yhgVN9, Qi)'|5e]hxSMO0͆G9AB3Bß ڮDT!4f( Ig;PwLH~.L%wnmz]ǎ 0}U6+L0ZF9A,HDi VgQM=Ry+>EvC+ǩ1Sh)Ar<̍Ib^#L73^/IɄE8].Ecr 3؍pGv=Ohf8;q -NTb۵?8FS屋AaS <+4 F'TH^kp. 6/F`ťzOon~ݶQTߊ{ku^!{&ڒ!C};ߊ)iH)fÈH\.g4u8NX3?Ρ9'L9#)yH_Qs1{ _ ыtՁX  `{BڂPn䲍|,G2hxwR wt?xF>a_"͇]hxNXqy.6E#pv~:KUZ m(3@4EÞ7BcߔhՠJ, Gb|b$36sٴՈ]YQH: M{H0˫?5#Nbꙉv+by7bl%|Nvsi.$ yphYBqm Bc MlA\k]so!m+;oWC.,ZdZބc Ï]5,nC6D#t,Z;`ņvA$3 i8`,@93XfMqSٴPH03lmmnïߐ6^3KmM{m4=h]W^YψuV O-4B)K< |&I+Bٮ L`χW~n":JSlݭ9"Wo!SDui҇;2q: F6j|.B#JE/{伪(=C GUF6 MG 6N *`'@gB-cյ[GQBx8yVr}BcXKEi:P~fLv;+cޅm%=d˔6ܒFޚ2 :j ؎1۵_j Vv1i Ζ5 .4(ŋ4^qrƟe1 V n.7ԮXs uz%3qJUõ}ջ.+|w5e6r!Zz%`RṮBX{k>=0R2Ty'Dq>^?ʇ9[GRe~zg^O|I#BsAb ]XvuzfƴE:(+V\y|~{{cE~5Zˎc  ͐P V%jyIGp+dȜoIhn@Celh"4B$:4u}Ha2Flu:8N#sK{ZH%Ex86`(Rt/նVEY>;(W32>rq# \ ۠Nb&`cf E- L#H!+і(>3E`;)Q:Y:Gɿxj˩`=M0j}dX;ey*[>Lvy4J?J.7! K$2BѮcpw<+0gs$s)M_F t⥤'ڍ/,g%Aen=q?ƞagpb97Fعoha}SuWWQĥi=S0]zw5Mh30#v9JSiѪwG=dHQy$|A8Q-M=21 D=#㴮.R}Bc Ӹ @s㵬gk=`RH N1 :#Ou> Lw1^+Qdj 2Lá .G;;8Bc:YxX5Zs0+$$oq:.X@6l< _}cRp*dn"݅2YΆV|ol/J&BU Ð:r&xj!C;gsȨ5-;-ǂCB ;B&.CΘUA#b*LA8吻IɅJ"e?4F^D}}efDa ;=ϟz^K z{f%3 왤Y'kzQJ60Fg{ Dx{iL7sDtdM32КԇgE l1*}v3ϙcghV4@lA*ĞP=1_Zpy wCS`E<J Vϝ _o/x iNs~̉,Aq> G3!4E"3ce 6lʇ9N?Ps,*MɀYD2<3rD$TLQ ٻ}:_ M{dfI+ZSkJA8AB34BóCl~$5/ GBL77qdm(X9/CpMh=44\^_/JbmW!nt5>HATYfF0ɏhxoDո#p0z]xJ ͆sb/[F_/1qgΫ u9 t{֌&fPh5(=4J rZ/odߪڍ/=shnEA3 Z}>W=y:Z+4s/&D&(>Gi_^AV>/HݭnapR~F LҺP{?^hގ %CKlU>\YY֏F ЄriC#{S`꓂6r PmvX=m倦m6؆U"˿, V{gx 4|27aeއ)5kexIh>^R*4<سϡ(ֆ3Iq0 [Z%}.&ܯKXNSm[sŚ|͚n=9a?- CsMN$/!a'qK1oUh_?˙wW%; TKm|( zL]rKG/˹>C'm3U>: x3f!shzaXaE5j0>_sYΘz3ڊcJ8AB3BJN—ba xZ{Bc9/D$4߇аYV(MGܜ٘2Yv^ Ũ.<5Q!BtC:-0Ȩ` 'nDQ/,Dȷ0ԙ6' K#`o}Vcga$C(rƥ z5?!z{bQ|vf>@IšV>ίX(`ӓLN`a*yPL6~6cuf9kDѕezf9{`E'5U>Q3eϗ~8>4 Q6XW,DڊOpqKC&7!.BŘ,ŕJd7/Gb,(4uhcוglC&nIyWoWa8fc]+%e4u_+d^*AMZkXLR4vDԀܘuF9O[!Ek{<6̽ >J!V$/sCCh3%A[.D@1`Bԫ2Kߍy#uEb\>.Z,X *EX=_clJjELpߌ'6"$/4)^ߢ[uJo2 4 6EQߵ]W~x}>Xt8jRgvuGu4ie'`+ >g#+º=>7h2mX<~ fviVnaJ_h|,xV@hr~9l`Cn)jE~zcK6r}(CubT6!}E>r`ˇ9kCyB|zv 3#\ݟ'yƺ=f e'q]H&ASE&\rb@i5'IZP'jR[XJ3zF pf  c5T=?t] -c7%hi`t~E=fZy3&X5;(L QiWf4~q3 ڤR$4A|c#`l d__Lyp4cGvW9cu$'7 k *I5Ι HhSrMVwG~f.V2!|05l@Lx7#^tď+42Zkz:tAB# AAA$4$4AAAАAAABӷҁlc1 ӯyU3b!+BNrVf>RCJ;4I#}T4KieeO7Ä衤go >n) B D5:3g"9x'#-ar4u]PH -tČ\8a0eړBB*Dͫdq /9/tr՗&9^),Kی0wǰ GmЬš2Lz\Fb'*"=|&1km9޵(l5%ח6fpFx=lz=f-ٶ .=xš|b} >*&1ˉb>G?J_)W){ybH M.^X32 EOgޏc 9uk0ROQv:x- h]%7PxUP~F c`!uk;D h\"a! ;ACP 2dU(<鉋d-=a9aߏ.b^H-%!Hh~rѠFGoig![6$-alaM ̝ ڦ|BÃc54 ܅7xCHTh\ZhUVZ#ИxGQ[-tIִJ$Գp/1T_d{1Z}?^hLڟ[hehcP4`H0$B<$4C.4E~L_h"3p'3QF*ݡ>:+(rf OD+li-\TM%44{.ԠM҂CYўMb)Dop"xv(*ܿpVTMAtEP_A]2b=iaa[I6db1φ4Ig1M٨O ͪ=qX<][\lQq)jk $| ^|nץOhaiL)bpվyӱT~XV ּ­0ּe?z)!yaƅf P~#=[/q*hz.!HRjygͽ*HDRNRXLY~/&_Iܑ|:PrpS+`m&Tɓ9n Mz\+.$-{(}RuMNn~ՐzE3rt'kn}B0_2Q#>*ęx/Mo=bG+r#/-`clm#UhxtbԿ=ᣴ"><Gn4!EllmRǀzQkHW= :UB eKӬ(3 9R=C8珤%Ƽ c-H+"z,(Pnu| RU^}+2ܖʘU['$7(qfDͰXx/.FR|գx,⏗7Dń ㅆ?Uص]֩$Ch&õ Q-@vʡ> \J݆!!E>?K ba<@mV6r|)܃y!X>V| M5{ /V|oV\S5b<dWRyĨGęnf*$/÷۵m1J^ p\ƂZ=fwz&0 pv'.5@ZgŶk3qBa\c PW^^aOX68FZsyY4f#,. +x"X~s;-p¥V[;^}Rp7і +UVDLX ,OKdGJ1TFDr9XwRŚ!t%9eȱMFWZ^쀟TƊDT(h#be2u#mTc8F#{sh37e]6 d0Ek7z x]Hi>|Bs’&s)*#qu _pH7wxį:\T>nਯGyﶠ!/a}3^)^3AO]vM`{>|wbs ]EqTbnWBx{\=/ GH>$!gP&aL0zwWcu T* ~f#U>@rfh?2r_m9mhb<<6VVqFخL Ư?u}WIL=`F8jlC N:*Ʃ̳\*JťHWׁb3cYG.l+![\@%4rl֔i TKvI߮R VÈIKp g`8owG)^:ć3(cq8LcBó[Mr90d$kC^ Lpp@_J}4zY=2*_-8_ `Ro.E֊( gǓiT>ᶳ\\#>Ct%ydS<c\qa@cdw9_Lu$̍;8=4.X^سb= N,&4;WMm2Bc| 5*s#4 տgK mb&(ed\.Gi8@XȴL)*t '%xɣG-Bc|?g!uu%@Oh `7r|tlgBL IAB)4!8S'ciCՇFtK8#dWtwkqa AB `U(v9sשM6ȅq$Ԛ| Y'Q&yqʿwe'a{4GcU!t.p6T%4 {c{VW M5j,zRBR-PtHqgVle|Xrװ?Thw^; dx#ep*`0HvwIJ[L[i1r7)RUDs쇑ȋoLUҌ(̜>}a'0p힠뫺kZ;`͞IJiuGkshyvM6aAx3>.x/JAJVޤ;# yQL}zVD6}чk7z:=A9k>V|fE3 ĹΡFJN$h`ژB 6ИH/- ^χޅ|e;!ש[XIoa"ho%v NGt[ ~w s_keNdDg GQh\ΙpcU1d6({MLh̢'f#@&GeШ_YԽLtFح cg!I 9k^\MonPqrFs_8)Cӛ({h$h_ۮ9,ƕB^jxMϯ4S- ` 1ވq1ʹG` $I`5 h_;^ލM_cΜWrM ,DCcXD /g5bF M3yV4C B~fgN 8 dWcW|8fJ} _ϑ>˻['8 왤u ʯzа {;lpKҽ24 ZI|}3Cl{hB9pFHh?&mCiM,,4my6<]e*<ÅHhc94 .>L67^ǘO!\+یM*D W}pfc )N3F=!yk1Zy</ńuiʴ͢{k1=.kK5k^׻sft#܇Nޏwҷ/0K6Bc`MP94M:CcXh|wp-Ő*U~,gf⛊V]0P1n.cѢ0$4K3uj؎9w y`Y#“Mc m*mhafHF zc||B"mE'%PXZX QbLcJ%2#1]kp:43T6!7s}Gۼ7V0Sų:4z&?wi7 ~IyxM f釵JP*G{֚.T:(527p]jQVHZO/EogSRa5JR0w]>$=9s܏[BzF9'#WeB/xFꊺŸ} &صXfT^{Ho%ԊOamD*I^hB:uJo2 4 6EQߵ]W~x}>Xt8jRgvuGu4ie'`+ >g#+º=>7h2mX<~ fviVnaJ_h|,xV@hr~9l`Cn)jE~zcK6r}(CubT6!}E>r`ˇ9kCyB|zv 3#\fKp1FI3se'q]H&ASE&CYhsD_Q#R xP At`j2z~@L1y[Hdoy[FlKkajP$Slgx,as&ƨд+3H[oȓM*\ABC79`Ly^G8fpk'?qu ;VG"p|"zT ;,duqw4WAڻibEcB 0xm2r݌XxYе?؇Oh kw9 ͏(4AAAАAAABCBCAA MߒtKX,LU9AZiJy*q$Q,U= ZjH陶[[!>P~5:QΌ55|HKI9ץI܁rۺoB!|m˰pRߓߊ,ɷq/6ߗᓬkB04$4JgG ^+s0*q9}r7<V Q}݅}] kFF#~h RqA8g.գp F9N'`~x8"!cv"ZBJ^ϡ {/ȞpL8,\nmהA-P$ѷ>L0b]4a}g} `J!i}e#\Aס.* jd/p 0VzuhloAr ִ@mw+4<8^C]x'=dHFuF[@ m5G z"{Mw} kZd_VY*z/} k=->/4]&CZ-4C2$[^k|?&sj /4V(_#_u謠gș&<-F moӻBuXR6I !\gE{FCJ4տË)_pU [Q}7щV(B}^vɈG䗢E Oϭ$DrgCa=@Y{ALt6pB*ᕜ ,R x6(B5赅h>/>'44&ؔK jjO~ћPPيB$O2 /3g7rs]GGXH ڍ/}B:ThFNdO^HtF4>[y>3K&jħW8數sܡAh,Ԉch15,KŨ}{GiE|x.܏ܢ7iC*4é۰Ώ1=r/n3 א8~/v :UB eKvPјi?=$],6=Ǘn@mAОeWט:W8,@WWxˈK uAB7OUvmW9V&Ipedb|~m$гr;&$?`|p;w6=DdeFрϮcX~*P MF-GA_ ~^$eEǃU+߳BӨ@M& )Ģ[qT /)Ur 9fƤ1j/q& vm|[Rd".`VOF#I'4Lo3ه'.5@ZgŶk3qBa\c PW^^aOX68FZsyY4f#,. +x"X~s;-趍¥V[;J'+4|Cx#M%CwxS171#RiHaD$z .3PI: z'EKYIPœXOhݔl;?jڕl,H(J$ ْ$7WYZ\[\*BmD-IDڦeZf93Sߙ:3s{>ޏٗyרּ]kwLY;ob>$5#6tE:r#鵑7= D  s-`AQ#bZAR Ys쁆E= K( 7 =1~/Ձ q3L7H*탤 &q@`FbBLd4r^K^cAoVzYHX^~ e'q zU)04J}ut.|^ffߚ iIo"b*ǹQMnT uNT!gS4>JՄhlR )ݡzq 'ЌhqV6//Ѝə#$ f9e* e% xpSm% L F< I㾱Hf]7h]uG 9YPH߹t@ӏ B @HuFғT*GybG౷t:mas_B#Q&' {'X5rB7w!qəSq5VFK]LʗzY4dOhn|ətmdyXkf84΄3\f!SHTpZ Ze ʬ`idaѨlՕں[FxBU h,$ٙ&5[ ݘG ' TALݦla@ 4JTo/J Ov#)T 8S6zm7=Bq37YsmmckrƟtCǺmoDaugB ϩiDk f 56PTVN&la6 G>__/NqhF4 4F[֤^@qmd r׺-@vy7 %B$_j"&84 .L:^sҞU-GY Bl*P 3 íp3yd(tTtVpPO4: u'Q+]!j@r%|i^h bu IPR $J #(3tԇ"p!"eoq{nMڮD08}P&cOv#U`Sh 7XbaK Ґ+E Ib@Ռa9|.@~7t9唿L>oF4R܎q05˺V˙H4o/ Qe8s -:ta4.!EfM1G\X1^6WY;{(dy$ %3gv(M&)/W[IT *f]񷞎}d.:iʜmT/m(Rj]{ClŗKx'y#hr 4#bkPAVgjqJ2oY J;\ta4| G8-.|["4C7_' @Z!yci"Utzh$‘*9${k&M9K!Й! HA wL4ڜ4[ [^3S hh<7AHZx o^MhUE+ZS?&<̊G؂t(XHҡq/Ct;>z9ΉŲ%K0~ O<}ݍ_MD),Vd_S25`m s^؝u29ICL<̢>;![ +u|4 ^cEQ|3 #r٫bH ^&MohSV #$IV6@c75 IPу`68n(18ڢ>GCq= W:0'W(PSna9m9V/L1Bc>+!Mz79܆:y@>ҖKWͼ"Iu|}8ŕN89ܑP?.N7IŅⷐ({ )Ʌ{2N [@!!)܁@/n&n.)5g7 EWg#KЌ2f#W/P'oş)fVe)Zjoh +eA: O ,ܒXxC> Mr'@- 4Gk@P%( 4n9oQ[ׇNj3P",Txs1csHܗ< lӹ%9 jetPGB ϝ:?IoVwxr֞p47A:d^lFDbN53arR) cCfqA^:QS:pnVkۀȯl% J*%<^Wz  b2V|&)hA5GF\$VƦQu) 9 H_]ȥX2*R ^,ϸe\BL8-}ػc˜>fmċMm3LAjw:>C(NqMV h#pҶb0,_yrh=AAdg41BOY||C\ĆcPkιH%=-XMI8|%u돻+=r^uP1qƫUE~Zo\&'boAYX:yU*Ml!;a>T/N8/͆8 NE G秗Pxd4-bZalT|? 1KX6Z =D7ZjːY.cjg̚kqh? 08cAjj$4+dܩ_A.…8Q-Ggqt Ur n7p杶BGTBB,$^{~ UX0Rf⩬׹Y<5ѼX{*L3um^т~M,[ؓ| D9{]N+h|y)2}/:LA`8ffVm5:[a`2J@{E[HM<g`"T~Vx)i wtX =DA ǡñ$>]X`-` 4?rn+յOxU|{ ky{@Ws(sea~5$_(#PIJ Ya>X/N8/2^@ 'OH{)8w懫7{,={-#'mG/35⓰;xA#rm ')9 ]K( J 4pw&s#00 GG~ g;'?zJ [ yUUp 4?(ޫ5> \,N8;?JciN\9 4x\ӌnBE5وpm 'N8N8N8h8N8N8h8N8N8N8S3w&gbC}nAHyFnx q8OE24Rxpߛ1P%ktXS[1Qw3m z6bPEB^وoƢ`GI]Ff]#BEI!~[Qˁ5RLԝzIc!۳"ʗeѸ&~.k~b1Xʰ6z}}]4Ju@F!y_u.!(z]3i[R[k&oubpp._[ Co3պg߫pk*Qt~'t2o4V3A:=$:%Sz~5ȼS.9i+j\GZ/pf[^`?C68avovlذNʓ&5eԸ "߳V 4q\>xE dlɫFّc*=8Ub4eXs}Dz_"c1e#N'E{0Mh knS Ζ@jGAXHRʇhp>>1#3 7c@n^LSwOR C 4У(x6z}}]E- 23%6j!S#'4JDHUyD>XFi͍Dl\6e =SBc.GPI!N rMO)'IvC@CT݌=Y7QѮxz__d>|/j\*6߀ԣvcר}Oú ;ˍJ<OqhOV܊4Q0N /[#}wZ`MBW/拿aτ薖`dm@+0K4vřZz%[>qk)0U XS}3z@#$> 5~lwalo0.nX e ȮUx+ 뀆HZ0GGn4V1=*Mzڀ#n?-(ۮ Ҿ%3g!~![5w8}yٴ!;BWr+yrPu=7I>SP!7$4 hqnb'Z90514`rf痆qJ0GH]V!#T~& ŭFux|~#6u. nCKrtV2:-[E M W Gz%&R{Y, mjqJ>g"㕒^\\S "cF=ggW/&QʦHv{kM\WJN<ţ1qefL=ȺL4ܱ 9VGώDBT@=h|?iO^̻UhRxױaʋ&rU!eU4fV^t[:D5M(x}7 @9>?Cis?"%. %EHrd:-Dћt(LxS͸# KaDbPy&幹ڠf i標+4BBލ"\K ЯyeeGz.Q7!@ %Ш]R.wq2z^ć/Et--23: 8%OQm֔>fh K;z$I- R\ 3`*V0RB/qi~ߖlsgenC恶]w \iS #5 4JX0A\< P 3k@3PVgb6F8D#O@ՑY?UZ$a:'~Fݍ3Y$h~-o◍ %`NcyOiť$|KuD`eF%A˫bu;y 7ʶ(VMtkV"&5} ||nХ!:"Px>h/gqZ[ ՍxIW)t0pT+ˀV\4|TeBtcu!=e8_GJ$z@Q?X/F'U=\kF؃gqp{VD jK |=B7ٕv:f[,tIthsUC 0-ؑ5?2P !#C(,,R@:]7PEP0h([*+ęva T}IkPA%Gm>tFk#ot&1nF9sr0RheAQ#bZYR Ys쁆V6GZlVö/ +ܠX =1~/Ձ q3L7H*탤 &q@`FbBLd4r^K^cAoVzYHX^~ e'q zU)04J}ut.|^ffߚ i hlÛ<1=qn{"cq2؆lLe^,t#x1hP(ʱw_Cmx$xx]>̀7ho nnF$Ж h?Gd m>ô)(a_,񟒂(3GK>zher h9bJH2oQ!@^V'7' )&g~z}c뛑@nER. B:#UPO Ĝj(y:Gf:7i'Tcotb FOyH;1ŪɔBNF`tMΜBϠQ2Zڍd`R,Q%xGv@\DkL,S>=k݆+jy~p&\5 QǟB"φz-dJ,cPjKsФlŵH'ؠ7Fe%6݊7z[]zL@c9/&D5Q9|Hƌ=x'sH^6ECYAB'8{#3p@5qo1Z&k [֍иlyҢ q徱 o$@c0% Vk|$P5yǡQ@pv@gr։Uj9RebSχBV؟Q niFܓ ?QtVpPO4: u'Q+]!j@r%|cf^sCp%T7BB+>$I :̬Q+p!eoq{nMڮD08}P&cOv#U`Sh 7XbaKN KC-4$ U3. di"b wHs]N f$@#!qz!_nLi;DcY%}P6; ݢCv n!vF 4W V Շ(Du+E!s|@F iW +ڹ06"/W[IT *fhcN2g}J(&Ȱֆl$+ev UРORxqv @co4]ppe8 m@{,EUxs#pm@@}f 4VFTY>#q̛x(R"]X k.twyeԒquKnB![}c/w w J[D4~q*t h$‘*9${k&M9K!Й! H*zq|cцH/ 6]ܪM _ИzM@C/ցGF9iV ˢM(\vwGۄY[0[cr.m6l ,q`yC ڨ^>lmK Bϣ :GZh~{QߚHoMܶi~kb аkF.+qݲS(Se)Síh 17e>TXZ//7/5z4аq<1aC;Өmv OPv,vGg\h -Qo^'jA `q.V;[ J*B9͵73R^˛KfL9xwH-CNgrH)n תzA}NBV[#VY-~#~<87(3ܐ&=TR<@Ab1CUD>Q+) /nqW{~#b4|GΫN1!&Nxx*OmpؤD6:ːKW"R64mKjqbͭXk"\zx #1n VY*lV1xCX3.vk& 9+/ ru`Q[ӉEphg %,Ff-} -eˎ,GÉ\1vMbq0<~`:rƂHhi9VHSqF1] qZD12*V[u_?Ц@^o+An!5,jßPA^(i wtX }.1h?ޒta:%TEW kG?Ea".zÃ,# 5ZDZ?1Ki**ώ)6oC Z! b`MoջE2E#kBƨ^z̓TEA6|[(ثpRQY׈PQRߖ '1pTr`ͱ2ug>8!|y.ek4n>߳ @9&2 ǿ^_Ap8kkb x3I ,B(ұUkJy>gYEC/BD.%49P/~A!`a;T7e;6l؊}'_I| 2j\FVш=+88A^`p@e37_乏dlɫFّc*=8Ub4eXs}Dz_"c1e#N'E{0Mh knS Ζ@jGAXH阵RʇNiRhDl|ߌ1-i{QNZP>H}lGFz75^@Ԇ_wШ(d\2.s38D1514`rf痆qJ.GH]V!#T~&>d/nU4 ?]ݾzi?ZK3'K*p3@ß 0!z W'3RD>>z1,V6i&.+%s'Izٍ82IaYtdI &X VBAU{|d#gG"p!} 4>'D*J)Pbذ[qEH9ڪ*Io+/W&HdfFk塴Ow~"9FoM^ &gj͸# KaXbVԦC^E;jǟ7iE;jK!F[%~B%&HaBR.wq2z^ć/Et--23: 8%OQm'.!t8ZCN^&) BRp2^3ͣlQn#*yGm6wP6dkh+/~Oa'}@ ۯġ}xJF7LyoL8QdwLɱ_#b@ex Әb^SZq)7 _vBШ$hyU[cnyma[4 3ñ#+ k2*eBF< "qPXO+xUYX0/¥8B_uYkSo.`+yѰQp {"vUV݉3e퐿9x ;נJۀ}ȍF6h#Fw3G74Pϙ8RE,VI-Ő+k5hhhsQ|F l:l fBOL_1KuvfL'Ӎ2=J )zhQ>3WXUzV2b"<2_G~vÀF hpܻ:^gcUa$ d_$c*ݿ2ʙFCBZ&"&OLrtܭLeh,!Evy٬ר|' "M x~$>! ^C@c=r HoWGșP s4ѸC+[PFSBy2qo􊷺!XU)r^LŸjYs5Ѝ{D NxKmvN@DՑYJҊOv# U)pvqԠ͸^ۃ1M`4P\L G'PKq>|F(Qw&B=Od踱aN[no#%Q;wU82U "Di&8m@AϳH7e7D'{ ی1/mvfyr nyJ3Y =IɳHV:,[_]Ak:ju 8Iw4H@0@cP`MvAA w+qE$WF4& SR@Jn`FwABE^wT g t&g]e9iϪ,e ]!6|(jVm=Y? bc?D+U%m%MB hJWȩr 01ߘYEXfsCp%T7BB+>$IR0(+@:f?Px*xXx9,Qvf֤J;LW/l2d'\;R F >߰L`|)漴4jB8AhP5b@oN/V.@~7t9唿L>oF4R܎q05˺V˙H4o/ Qe8s -:taغ ia7a@cqbP{\}BTga}u9>{ #H4>QL B +$*҆{4ӱE' V %dXkC6^Fh2k4+9^)]ppe7+@hTxc;"D`:F 4aW/~WJqw@R6ݪF,p@C`15 +|J5F@8% 7Q.D\&˨%݄C7_' @Z!yci"U65Hڵ͟#UrsHܗ< lӹ%9 jetŖ?\s1W's'OǙX ֜sJ{[ћpbJw7o/FW(zD?b4w/70'9HmPu!;a9NE^U'Jc306mhږP<[yר;{a @ ~ls,5 >fX3YxٮQ\`Mh~HltZ ~t~z?1W`Mv@ b,FHIz1|? 1KX6Z =D7ZjːYS.cjg4::šax<3dJ s N r ~%bDʼn&ʏc1T%x݇VLXK4w* QQx x%)PVTd`"ÀJYc瓊^fbԀF&c%2˫BֆX3Tކ-b=Hc{[y\ыƗ7."r4 l߬ت|F6Ub+ LF[ zh}u gQc\ l<_b@@I[߽3wP4Ax$y8ħ K̔pE9y7y`QO{X'*ˆ< RA ~KLaceFqC鲼-jI7PG(imhŦ^#F8o-=[z9cT UG.V[<؇$!{TĀB(IBp@ k/sE'CF{=ԇXhQTOB÷|1_ fjj&y~  q _BFQP9N3qD螓Xf? >[8K\9kU&GX\Gbȫ2zN89yE iO~N8q@H,LԘ>$ @՝@5&PQSh'p 'p 'p 'ߏ"57yyV$BCN8ဆN8N8N8ဆN8N8N8;t `LlȾM )>#/=m3:9_^JVVQq~v܀O{>fz _k {-@g."-/:Y…7FһmĠ/ ? ߲E'^|ZͺFB9/k;%d(# ugD/<\qM1]lV1am8~JtTk8t?0ro!iEw!x"ޘh P/~A!`a;T7e;6l؊}'_I| 2j\Fv͊FY +8.oI¨ƼؒW# TzaqV%(@c#.h88$;7=PD/c sGN`.M-(Q{uFGcݦ-mBՎ8/α25kT㥔/2xшـx?cZvd$v}lGFz75^@Ԇ_ @!:>?~~=U\9 ܌=Y7QѮ¹p@ġ=6U+nx(|'gV-Ⱦ;Xg-O}@Ãg}tKKc2o6g hx;L2Q %CֺNak #pQ] {9/_LA7hǯo48QKPԆ`}mhmWa#:@EsȨ8kg4y:r Ys0N8mqC>Oc!ˁy}f 6p$0ə_^!+och!u^Y%CS9DD8d/nU4 ?]ݾzi?ZK3'K`09S+Zednnƅ'MX0(Vu_QզC^E;j"ʟ7iE;jK!F[%~MAh1L\nB,Ky $:}A|'E|o8:{PD^BR/3ÀXvHIן5$/h $(H]'5s[ (+Q٥6 FUh%.mݏےm7m@ Dۯġ}xJF7LyoL@hh;8Er,!h/H &~ٸ^4>V\M}]+4* Z^qϻThW@ImH\1Sӥm{5t .JCtEVyߒ~on Wԗ zic ,d7Cz.p@ÕH큨TFg#u ݪV5#8=Q+"% ō>l;3E-w:$e4ȪQB|!CΆx[tpJBJOH! ^U p)}Wu{֮D(J^4fBޭ]kwLY;ob>$5#6tE:r#鵑7= D  s-`AQ#bZR Ys쁆V6GZlVö/ +`6,4_ÿTn'kơtx2(s 8xlS!: 1Hy.y59Yu!g%#!&#czzOg7 hǽuf>VFB(ANR0,z ZYi|N^}k>$%o"b*ǹQMnTb1QdzV mv&M#XJsiot$0j'n]P?`Gz}zFZ'>B|JV eN8>zher h9bJH2oQ!@^V'?1VRzkMB %CVwNoF4ASR ?RE_H4@ɪBJΝ~njG3R9jϣ7 >ymS ʃ0 4?My"^&SN9"$NS59s =Z3Fhi7K1IT/ @#XFɦzM-ra19|>=kLpuv,D ?N뵐A+rA9,A" c#"mR[w|t+ouC豪R2弘?;D5uk 3s*ȟ۔7hF# .ΰ۟FVwIS⎩Aqc͛h8lMO|X 4<(QL95 {qcwL&Fʯv (pd D$}Mpڀ>2,>gonO Էc^ې]PᇅSJ3Z˭Jub:JJI;N8@0@cP`MvAA w+q1z?}cHdaJJH (.H("(kC*>b5'YrL Ħ"9>@?@< 7Ӽ'GAthtz Y8Z 9UC.F?344@SynNFHhŇ$)PJeuAY>Y(?< M Y(Pu}3Swkv%+B6{# zEoX&0 s^ZEeRXrEhA IP4P q1L7'@חO+?a[ Gr_g`&7#)n8D Y e]weLY$? d(郲oܹ~Sl]uC 4̰0bb m>D!0Gw>QȺ=$HU抬v(M& ViýYG梓Fr߆ 2!e#kJu?؎pk$Ae4]pp7Z 6Hzw7jkЭjD+ '|@#Xs * ,R8N ABMz9ΉŲ%K0~ O<}ݍ_MD),Vd_S25`m s^؝u29ICL<̢>;!K +u| SA,jNJ\Xf@c FPw5%W-Ųk|zU(M6(l@F^9%$=I)l[IO qC!ZLT#T 8+H^Y Y)0߇޾6Hȥ3F4qg3itX&gې~=F hy`K=6qp݃RBervq'|@sGBQ8z&BP!.D'{38;4lohl憆p߿hd&ϛ w{1!l8}IQl?B3vҰ j,8Y Y y_<ۍHұ%CG^͚U, c1vFJ A6+ЌV =vB| .xH]5&2+^peT-n?RŖ߂tKo?mЬ652[[h Bϣ :GZh~{QߚHoMܶi~kb аkFG hBm@Q`{)ᆏN8n'<,6wl'tU͎i.?8x>fyCc hԛ׉Z~BG:~:XBΖ*B9͵&"$Xv p%;x:Vy[!6Mc_/&qZq,|ySD5ɛD> +eA: O ,ܒXxC> M%@- 4Gk@P%( 4n9oQ[ׇNj3P",Txs1cˊp!m+֭ W+|pc^?LvnHC*)DDijQ}ǁxq!Ԛs.8R>z}x "V zS_,BqFh p_W'c4BLFU s$߱ImPu!;a9NE^U'Jc306mhږP<[yhW֌]?zw{_|f?WY`$geD]Vp59;͆8 NE G秗Pxd4-bZalys!%hЬC@At yqhM>ƮvVL#cZC?L&XZ 4 2 )w Wb`(p!NTYh8C\}hńEt@yjz88 ^%mEUAV-9 he:v>x*un(F h4o2V"󞺼 (dm):5L.m^т~M,[ؓ| D9{]N+Fh|y)2}/R+MLp+͊/ @CkhSu /Fd俕Wx5E F/ ;:,n^y>Q} E4GŸcoI|ZL gQcwC%_u|«ػl]^˳+6VFh4<.˛"ϯFD \|}FІ,M^l5Z>a􏣾=rR UG.V[؇$!{TĀB(IB'pw4eNRqWo(X{PNcZFm> ߎkż?B1M87b{/#s1lC~hh4/Kl>O EA䀆N8{Nb|b(Ho,=8ruWUi8aAs!ʴϋN8Bޫ5> _N8dl!2RcX!WwNGd64P@/FMq6}?x^p 4p 'p 'p 4p 'p 'p 'p@ 'p 'p 'p@3 N܁|# !Eۇr䥇m# 5ZDZ?1Ki**ώ)6oC Z! b`MoջE2E#kBƨ^z̓TEA6|[(ثpRQY׈PQRߖ '1pTr`ͱ2ug>8!|y.ek4n>߳ @9&2 ǿ^_H%N (" mp@3@C~m ۡA/۱aV;*ONo Q4hV4"J,FP>X!'hq~LMFkMƖjY8<*AYq)F^Ɓ5!qI遪%28~AcPf;bt_tijFګ۰6:6li vyqEf־kK)_:QhDl|ߌ1-i{QN2b;L]>I6#@#=/aj7/6zp ~H{nmCÃ{l>$V܊4Q0N A/[#}wZ`MBW/拿aτ薖`dm@+0K4vřZdd=@|KۇrY;nu52Fr ?r2^2ko_Z_hqsFϏ 4.m WVz 'p@- ?6/9xVNMM}L" 3\_7RWşUb>4CID{CVE#z :<>C :zte^ڏ %R9:+O!#~p> 7jVH$z=!X, '>*p3@ßWJƨzz W'3RD>>z1,V6i&.+%s'Izٍ82IaYtdI &X VBAU{|d#gG"p!} 4>'D*J)Pbذ[qEH9ڪ*Io+/W&HdfFk塴Ow~"9Fo`pLxS͸# KarŪV hC^E;j"ʟ7iE;jK!F[%~<2 Dfub 0^X !c@织8=h/iAC"Җz8 𨶓^GL@!Qi'v_@!EA8J@D7[X6 FUh%.mݏےm7mt@Ej*)ĵmF0weK4od9llIϧHy^nO:h#Ex'!JOmƑR=~p@U@(vq&XC^ܯ@1@Mq iL}|1/)ћ/|x!VhT*ѭ1XtFk#ozN׻# @LZH)j  FXw4re  m.QXm?_BAV =N׌C_dQ@Ri$q0Y3*ЧCtfb"]j rC\JFBL$G"+H n([? {W|J9!QÝ`LwY3844|HHK@c#DUsۣݐ,6dc./~WʮJ\q_كv;1Z=q9$j׍C&:X!rjv43/K4%9hT,lѤ"-&3Khw34qh WggzBBAߟ5dJ,cPjKsD+" c#"mR[w|t+ouC豪R2弘?;Vp5[ ݘG ' TALݦla@ 4JTo/JҊOv# U)pvqԠ͸^ۃ1M`4P\LM\oؚ@-PnhxQأDݙɽ4y"CǍ5F{2D@sg@Q#snX B&lavF@}] o+(ɝknѡ ;Q7ĐH #++C: stg;AAa\5Dul#00x!оpJ"m.@c=\t`9ۨ^PB1A6dl$yX+3s@Aͫ,J\P6{i.97m(׽[:@QgO8ThhqAYaS1)!Hȼg2(p!҅pӲ<2j%B0z ol|NxN~DR7v(f fyCc hԛ׉Z~BG:~:XBΖ*B9͵&"$XvdeSDAǪ o+Ħv4N5nOR`ySD5ɛD> +eA: O ,ܒXxC> M%@- 4Gk@P%( 4n9oQ[ׇNj3P",Txs1cBW@rSL\-V`muc/g6F}-ZE'v%""c/yئsKٌ jfRD./\̀,u(Q8E[ z\[S_MJ N,3@t`_D;x!d_2 0Y.3txnX2Z0@r&pqXzDQ30+ }u #b˨K-x9coh>Yp1-(A>@cjH:/g!2+/6u_@3er(\Q+) /nqW{~#b4|GΫN1!&Nxx*O5kؤD6:ːKW"R64mKjqbͭXk}&(ZwT \wFIf^κQ.Ds^ξhxp]n:n^իhBqzCF;tq^8ftF!&/)H^Ca XI'c*lFsVX*!% $υxC@CBcэ2ea6KY1kqh? 0@8cAjj$4+dܩ_A.…8Q-Ggqt Ur n杶BGTBB,$^{~ UX0Rf⩬׹Y<5ѼX{*L3UzE 5XnaO54g^V^2V[u_?Ц@^oяWx5E F/ ;:,n^y>Q} E4GŸcoI|ZL gQcwC%_ /bﲡw=׉py{{y'Ҁ_? PI ǡjF?$Dd=@]R&{ 2E:EZt 'ЌhXx '+ ?!5ڛ^P>B﵌}yb0SS4+p o^Fc؆yq%0N'9 @3 %Y6c0T r@ '|g='?> p~|$psにת4M^ ]̿ŐWeZW~/;d>_/[d_;}86ޫ5> _N8dl!2RcX!WwNGd64P@/FMq6}?x^oЦb;ͯsw; 4쀆N8N8N8ဆN8N8N8h8N8N8hF7™ؐ}zAR}(G^zf>2^Cu;>NSs ƭĭ"'!6oC Z! b`M+!\tdm[h twz?F^p@= ;C%}_cÆw2U4 w @,haѬhDX/O;4 }&s383514`rf痆qJ.GH]V!#T~&i(ً[!(;F:zte^ڏ %R9:+O!#~p> 7jVH$z=!X, '>*p3@ßWJzz W'3RD>>z1,V6i&.+%s'Izٍ82IaYtdI &X VBAU{fsv$"JA -1JdޭB/ƛ <W^4*)4zՑ? iDFmYX=oQJ!t)qi(iL,Bz#oi9 V7e.N݌ O> a&PnFk:ԩE^Iyn6(YxCX^n4Zb~wC @4o&.Q7!@ %<z)dt _^qBË[H[jRw0?G(>fh K;z$I- REF`*V0RB/qi~ߖlsgenC恶]wʣNBDg!h;' a2%2%+u|D#X>ѬO;]^z_B\~hI/}l[EZykڈ!;2,j^ r95^G'VaSL M9K{ℹEgkIV'#+%=^/e mx`p@= ?Dƙ,c4A{qF70|1żRDo: 8XQIG`ݎxޥB(m7}JhD⚕IEu.Eh#߫[qQ. Eʳظ0xv3yí&%j3pxe9h hYnyqBw O_( h՛N[PeBtcu!=e8_GJ$xj{ (՟4tDBkH{p#,nCԊDmBq#ϿG72NLqŝ~Vzw!&2I9/%Ʊ 7N=d$Dbyd,R/B RwuǪH%Ⱦ:I Te>Ji|N^}k>$%o"b*ǹQMnTb1QdzZ/ &'M&@vz-:ёX&jx:C?A'Qaޓ߱Ǩ|A']?+Va<̀FՄ s9g xALw7]Yehh=r,fbL<^]NcF.{ۇ՘nC_L0Jf^*Е9(Җ1 ȍ^S *7̵Yo@Rx^LA7LMƸhQ{>k*=ĻnIR^H &Y$>vF@}]  ?w|G@0@cP`MvAA w+q$,Pg\o~ P"$MeJJH (.H("(kC*>b5'YrL Ħ"9>@?@< 7Ӽ'GAthtz Y8Z 9UC.F?344@SۨxnNFHhŇ$)PJeuAY>Y(?< M Y>(Pu}֤JiʡMƞqG_C o@7|CÜV\Q-Zh'H f\ >ӛ}.4gHF1&QCBoYjz9v-7~C3;Jl'wAEŇb남b_a݄}Cehs! Q9B֝  A0P:s¨; ca BB}DEp]ցz:*sQܷb kmkH-Rf-x@P%ڤ4/CL3GRi Nak>z;iF S˙^#ƗsB{(J\P6{21-6ƒp hqAYaS1)!Hȼg2(p!҅",<,OZ=n;<< |SQj" Vсj*jk? GxلԊ\k3CT)i2%Tha:biNMjf#'xhM3((!-j1zY49VkNVb0+a fkLE{c 4#I )@:'˖,A@ ,>n=1acuAfbNiae0%S0EYP)4Ą,#NRRwiN bP;VŚ7#1[!/g/j)-_˯ЫEiA!d?e2Q/!10H1M"^bk75 IPу`68n(18ڢ>GCq= W:0'W(3Q7w-/<' rDet\yvX&gې~=F h7%}7yy&RBkdMxZGу.ۅB ҜF(>j"АoАf1*>cKXi;gbz:5)dИav@lmp@M玄qq 0!`M*.DDOC\HO.<&gۗqv `h ILLu37qvI)!l8}IQl?B3vzYp )@;&_<ۍHұ%CG^ `zR^ZG TuD)$٨S|@3[/74Y U5DMx޻!RgIL׼8}U%ۏTc ?]O74+zZ4ySz'`9fhԷ&[mxDߚjCv74-Qf(&hn;N{Anh\6ᾌ5 JZt7474ۑd-Cd F& 4n'<,6wl'tU͎i.?8, q@# ټ4D-wbx?!jgL[p jhxPCy\,{ 2݂)WSGcUbd;b')G)SFMkmVqqFB9#ۇ *b7%"׭?jo^PyՉ~B9@#i>^o`T2i NrtxUgcTUuB46cӆm U-NzZ7Y8B'D]|nsPGHPy6ZȘHɺ0N?"iB)ڕ-i%$}|%>?{94<8yiGyn:/o^24?=+~~0w5~^5B(l?Wh~ lI_E 8^Ca Xp2h4iRRB\7,a 484kq+4Ph-C^vf9nʃK84 ~L 5Zid2iRTAܯQLB8Dq :*Њ zFN[E#* O!!pqDs?Jڊ [ļZ*3t|RTց,PhdD=uyPPStk*]pX,'r>s+AUV{Re99@_tU$͊/ @CkhSu /FdUǭG[HM<g`"T~Jڂ7HFA #ñ$>]X`-`3(ʱw蔛EW kG?5 /bﲡw=nr\OZ0< 40@Z h8\Q i/pb4~xp\> ߎkż?B1M87b{/#s1lC~Uv 4@3 %Y6c0T r@ '|g='?> p~|$psにת4M^ ]̿ŐWeZ,pՅ'w_O/jH{}pw$Iן%)Ҝsh<"݄~1j# N8N8N8N8ဆN8N8N8ဆN8N8N8Qp `LlȾM )>#/=m3:9_^JVVa6n7cJo1UG݁\D[._t:-swƇ94 ^A`8aýfoQg=V\m IaMXag)5,F~ :nY9!!2T4rHPJk PwVw9~S*Qb02."Imԝ/5y@>f'⮷B&ڂ o 'cYL bWF(5⽸"Ffʶg K)^z@,_ م ߬!ZdD1$EXW4}(4Ls8|?.ɪJr G[ϸBHM|wqe(j5|uh<캎Xk5~[2~B̀щ.-ӟV@Pg5 yJE}gm(72w+,SaMa$ԩA>PTXSch |@#$ 3~o@38?a% G owA]sX]4+BFYyM7u14rJ.6}/܊kb.ԗCIE{nŕWu ((Z?Um^ Mr F8Pq]$Hi=^]LEGf9Qp5( kb꾪]XddU 1)W%u2"d;lbtw \x㶠l58 _J>V׋ \Z՝(q2ϥ%EiEjKhG{%~t0lDf} b dL2?, o$B㙦":E=ht >BA"d2sq} ؁+~u+-Fd~#Qsz#6z) BRFi\^oLP Yq AJ|%Nێ"mI'yٺ6_cg=L.g*XYHu9HwT\X cyE⃄{-Dyylhu97ի8@v ͷ1w Á j`ܽocu XG_F=#_^+hW7)?` .^9SG_n̶cxz O&(w*(_쀯1Pg/ލS09(rR0K##ӐU.d%@$~n ^efp}Uy[-²􋨤D(hUt[!nq$.ۈfZ)ه T1)(Z{cWȫ.\e#6GO$1F 4g.v!H+eMf z1ZA]{ ;w)DF\$"Qap_ǿT &kDfR3 x4l^K)MXhSTaS_Ň|N*GaATTC~huI0-gf`qn$Ȯ~F+5xi9uFay[e8>QqY8lנfMw6<,5ю3 ¤"nGTL3:0eN-9Gc6@4BG\,}G7G[A\efpwuDx 3@c>R#zUEF)ԩE: Ѯ|ۧxkx Zh,DٴTi| ${їA>܈<,쩄fNٴa@hT;o#BI+8ǻ)\kp5Û7=7 osmƶu=8ja{6y>Bw&`9Z..5|' mtg[YӘ,: BGqfp#A'p Jy4nk 6ykc @C2׷.JAJ.bVwCb1eV89Y+.,vԾT)P6v< qo; 'H4WwP=ΎePw"0DUF ]8F]@+ 噌 dXC6Yk 14} @ +o2:kw T#Ъq}4R[?g &DH6Q2) d)qfx`}UC~#+qH̾gurp"ʍ{"<"4-Ht}ůD*8#V`-hXpFOk 14}{w.t=æc èz/Xw^~=dEq<Vf@c@raeH=SNu'914q UP PԘ~ =a| uIpcH ۀy =P Hqis>9%iq+eV@v,ؗ#Fi rDy$;8Y 1N+P(rf}Yv5Xm$ qE wo\J)Wezbhxc5 =PRnkdM>ˌI˾Gy"X6,Izĝ(Ux'Ң2I[Fk!!A/ZF6)lg$@QPԡd@#RH*^࣢ e!)tIR5xYx̬{KK妖5IFX45Bc/]yDgW4vnubh}sһ7CRG@8ӈpWcƁ kO`ӦfY|^#w3B1Ov_8lăcε(ӟh4V#Is9dga`;f!hP4$eиm9 ΙOFiɸڅw/"h+m󨄛bBAMOV(6Gg]4c*[FsyOr^㏝@/`6Eh>Ǯ@)AmFjn3jYi- A!k7z{mfœ4L-$.-5Mv2f;8>Sgl014& !~Cc{Rpo+→W4y^YΜ472<ެ_C({< :]jKF*-K`9Hb$ܖXXC,bhFƭvI/%exWFעh|,y\94C둲1f^XѸAPwr--WF14>L Kn kM%Hg`:$}jKq߀F&6j;\ވU q*^Q@4׏lBɛ4ѼHmf9? ,6W,g67W 4aK"DF!i[. D<_5t|("r Ds{k3f9k.H6xt6wAڍd* 2lBƛg061 Pj3rtV'`砥xA!ŗqaؕXªv̖co_>+A`[(8:y!t[1jrt3Y3AΤ-!})C)EYFe8͏8Q % gš GCKl֊1VX % $Df K@C nVhGcu) r1`Ml>ĦV\#ΣZޟn&WL/; 40 2i+!cTE8 hd8GB{}=m48m5YqASt%d(i*dk1~ʘY~'O-ab6&coiƫRbSK85_5Br[Rϡ(6x[}:*r߉<|a*Um̊-m@C{e|W`oA(|/AMWtßUNjQYNPF_ݠ>5&6Ǹ :'Q{bLQz%GY y#1;,D!߮ZT9{zxZRI N&%X2FyȽeiy*4+H^ԚE8Ŏ9dhņA[w.']hP&_ıg uhk!!{N*7pt}.mx*y#4Xz:r:G@Ú pđ2^* TgY~fY|x\S. sbpSӸ4)^a\[r݁;Ρy_ܺshtk3H)&'h7| 9EA Gq3¶H ¬Q@99 K]@@1V3@}qGkG_VNHǑ>}:ԏqGCCNͼ$+UZrs4#r] %21E7#8 GqGqGqpGqGqG GqGqGqAH `Ԥp2VN? 3(m3Y%X~_;)mZYIEmՈɻA4CbaM]ތݭhy ~1I7՗=j(E4Ʋ ŘGQSCI遚BIAO k%i:n5(1Cm>sv"ڗe1];j*+CBpugJ`D໸2:4IAv]GšB?- ?!fm~[@h`X]@+aKh(3j%>36ɛqe0g mISaMe53`Vr,Ͱ_4.XtDE~՝!p74Hubuh\W,IM]}L* 3lN TX2\ a[qR 9مc1hOЭEG<< @TS=MҫP#qSTÈ0'X*z`w `rMLT2^=9 r֪w9chUb,Tݧ\_YDǤ4:ϰ=ώ/&@qKM)foݷyb IS{? 30Șy5 ?B`u@3%1ovF!j T@{g%]웕hRdbgpE=HW mߨ#^2D!S :fL@/7:b2Y| 1W:ӻ .gq[PJjx/%iŊwht\1N&㹴Ġs4-P^z)hx/¹>Sh\1ތܢ/AxI17K@{83.}E+ȘesWVZ.* |+KIjτL.A7&(,VѸn Z%smGݶ$ٓùM3\^m14<~ю9nNG ołQqkL.3#r|㑣3y3ep1ic7 LǨ9F_bԨϟgzG  "Jb7lkE@JS58X'.σ!,?^4Pb'o"$8ow( 4>=f‹a!u>V\K}! QKXq-GxަF>0qJU.:<=| j3x o)zŪe@"Ýː+*tU 3a)$dV- @V+x{`^5K6Y29~a8PA [c0/A~0|m>$l~[ (ݟ3hvuйbQ\腑^;u?l;fG$mhy: %Z~݈="!'42? YrP_AV DwF }iV`fg ]e",KJzL XYEWuGb᲍+m>dlIAW5ԒGG^uB-ٴэG8z-&!/14Z93uwkF AZw(k0[`'V׋ ;P!'𼰦k HiD܆1~a/Ղ}3,HyIQq`ZH %]q=% D9vM6|.^{]!$%@c;QX^ VFT\&nVCh,!Ev}k]ĨŦbQ˯IՁS)Y ǟCqy]eG3@# ǭC?>*%(KƒKCn_Hq`t3DiDM-=yT6%`Qb$d^yxqѴ.U}&=1~~6Kt$fӆ^۝?JXǴhy|alb ;);sL _iv|n+8=Q cն|< 2Bsb%`uT8"c`ȋ0r-¿ 5E; /إ4hcp^3 ,(trqȾDx r2Ʊ+\r HU,3w9ᡥA{/9#~"qmltJ{%y٥!$6X TA) njt TN+|O04Wi>؈qMBR v$\3nGTLbR,eN-9Gc6@4BG\,}G7G[A\efpwuDxJ+ ^2h6|ԫp.Ű7ON/Wv>[c(W*&@c/F?٨"3~8"r;ȇ1G=P<)6 {͗c_h"ix^z@C e+\<1>x WwrxF40FmNMGQMq<̉uy>_p5gjU@zg`x+|Yt9V5D_Vbq/'3j]3E[g h W\Ci@*?Eج y ,Vxi-~m kAÂ3~JX[a޻Sv\X6ShާFF%ի|\]!/*'^Qhk6m4V[],g/x/X3TwqAgCYezEOFuG]X5a6q^yDO7T&Eһva9 yHHߜEPM @82Sgy}9b9"IgNXs<-ϐn.g}mG_h) qE uSJgZ9>)d1]X姻ʺGW)< AwAI'߈.Z(`-6@_ ]É(crž sR+ƖPZhHHnl@q&caQqMYQ0I-PT"e uh"hµ~Vlhx ]hَ8:'"`% @c!& M%@ȟ,X, ]Կ*aϻbr)fh@ [aՉR[4zW5whYrkoL/@ bC3r5nuNE@i]]\͆q-6ШH`5b[Xם:14DPˑe' Vd,MۉKza,gԧ|,[m3RT)o}>V\e'c@#8±`vT+ ~Z@:Z~݉E34u,)!@(oؑx#$zrtwk1ST1J叧&b++Z!#TCh5GK z~lct;шR&.%(lTefMjg m(Q~rbFc2 YάaC49o˳訷$\G}HYዑtXfU#E'{eТwfQ/#|3AHRFM4IK!.&j)v[mctl| R0wN(fiTO%1};z;T_ q~KhR ~c ݟgDԂEX/d9.@ß kC""rvPkSkǂt,ՇKSƘ? foa hn7akK\0\5cAJ*AH>щC;^9 uPh.EAn<8m҇4znkuh{\ \13$\+dL]XBwQM,RNvޏJk,m ^8 Ky νD%mBeQl-X38㩼Wc=,>P d,B-xPʿ]A,`t &Fbb-PGaqxz ZDˋHsr v.m̊-m@rs-(X[aP* kjvTqIGxef:40t9*BzGM| ޢN"RE@ ΚԳbzov[ğGE_!eaf\l8$(]Z1Vkc@krG)D&v}bu J7~H̻&Zg%Q3e8]}EenlQrtMc}C>Gskh~а4qd( /,Y~8~"9b֟@}>Yy\S. sbpSӸ4)^aVgo pF1Iى;IcNg5 6\GPr`C/M6orX=[r}=pG9#l!lOĬ ZE_Ԟ`㝣z-DP d?CQm5G/a˲p_bAH>Cmw\m !];i@ 8ҧc]#8h0 wrJ8?BwfdT.k@;R&ƻ;}qVJڒ?7 ֠"i" X.)npGqGq8@GqGqGq4qGqGqh~VRt&m26^w Fiz .q$Ii*MRq4?mF|LU\ k>fn(GcDN,TW_IHk( 6cGM!B 76'jJ ' j?Y.9d^{U֠r" ])lىh_}wbL P ם)55nRta.+K"I7WZvƂl3d7 8@ h{g(f~pj[Y+aۡB)?dRX>>AYJ B[aNHr-9o$(smU(;;Ow?)eبK1|\mPΗȚHz1X+hZ?C?f`5/Œ ;1O?@Eg@Td!࿰w9@ hsWVZ.* |m}HԜވ_^JT(}^f&kh\B~9mx붣n[heC୻Дg#:,^X4&AiDpn 3Wm m6_eQ(9j{`;d@k0GQIR 0̟/D9.WMъ#H:] -a6o ^=]x#tQ?`b9VBb| k1+1vzFQS5<#lޗ,u wA *2*ډ0#K*h~Vߌ7Ch; _žU3%`hu̧RL_q`eZƊ;طn9b765/E)7]CHZ/Kӑܮ81[QZ$2Y y^RBWu2bIBnhin~>o/Ȍ7&%ii*]Cd% } {P9ձmtF`#' M+BF؂Gs}<F"zmW|]q*Ó&#" ;` 2hw#vL4dA}Y 4߅5W"c)tUǖe,"*1J&@c/f]Au[6"0S`/W1&_PKaoJyՅ QldF7 0hŮ>=6iߡl[]/&@C_k@z@>{@C+k;@"#. c(ʉ0 Gc/_Wg"F3Y3 x4l^K)(oG %%4UaS_Ň|N*GaATTC~huI0-gf`qn$Ȯ~NZQ5xi9uFay[e8>QqY8l\eA[wQQ-:M1Xj)'X_AR(?Dˎ6fF[!}#e|%cIx}!/$80N[ 4"v4o8=Q cն|<؍Y Txz qeR+|6oz|l#!^?)sLҬƏd_xlϳ&n*A %xq"<\m?FX9XȘ5~b= u_ԁG CX4~8^)C}>h\'(G]Μ1.4ٗPGo.B 9'^2s3Zor/s4fD) ~wtsXf h wWW{MAK^u Vk1AG=}9r1SS}ߋt]OJU X񢝚* 9zH#/|yYS 3͜i.)ШPwJ|9F&Vlpw4T Rƹ|uj/7o{@#Éot=azğqtm@\*| 5p;L'r\\PDt++wUD)}s6e%Fa1xwx6CDx`f4wS}YC;]!+1BhpEYxBT68lch7m 67AV}KƘz*V+…8@B{hyw)d^y|-1aR&:`s,KytdƮ?rn<,?ٕJ سWny%~W݀T#NGܗt =Q7|?1e:с46p'p Jy4E 6ykc @C{a2."h|7$Pm5*Z#Л[[qa=JҴqX]ahg{a"W\8ӀI?-&VӨ!q%h4JWw ZacY"94Eq 灐(V|HRG^8';;a=G>St8d9XPSH J?XmN40ßl8c eStbLx.H_BIE}di~R~p9u&ٴHqu xG,oYnuLD]ZYЌņ.ƥЅbb(^d`cYes# QisF, A`\ݭBUT#Mwv.aD&2gh1Zi`=Ո/dPL !4Ƭ4Te6 +o:k"kQ:wk1N,Ppv!q|UIQy10օoYMΎb4PwbK,Ƭ;XqmN\]Ī`qU34,csAA2ư/re(hUIņas]}Fm80'9Վю hsp_8 Eb%~юEH3 :je khY)[ToaNݐz*ZyHuF gj3ŭƅ@ͩH׈ hh!oU=Yg! _]hUM+ߧzI@̩ZL(Y{C*+ED5e9ʏs6+~a vI{/H+P4,8#dj;e |a1}jaTRʗ|;/8ZBXic zf9{02@S 8*(CDw}ԋp(:W6<ƪ  z2-oaDB,R"hJﯔ?;e{ỏ49H,k;,@c}LIWy?Yw9šHī~&ӟBI#хe^~{{{2ʳd~'\te} o 6!P߂ 0]yQ?M̚>D[+z .-7ϊZ>6 hxcSwd1ϼqi(HNԤ 0fdh:UYAB|ߣ$CV MxDRZbٰ$oXwCT=Hn<.g\0'hZhlfǿhi2{Vf6a[E@ 2LEs)$/Qфkqc]VlhxMϺa;h)XnjYދp(,4%ZGѥŸ_bƒN!ʭ7y3D,u4)1_/;n<G{[>fx:1[?mZhw5rL1-4yiJ/xpҾ3?h&sG2V[sBî4Ϻ&F Gf;10 r9ʳ,Zn~ZZ%QFA=Zh$,4Q,-45f<-!Bcx,3f2˩{{@FGJcs_hRmBepViG%mv jf=xZ@ G9.<+%8@>y`5bz|B|K\L]XXuF5BrfS 3-r8!hw9d8!WBVu`qM۬x ÖRm&o }^XquO3D`J6B MDK??Y h ]Կ*aϻbr)fh@ [aՉR[4zW5whYs'1oL/@$-/3XЌ\[m:!%exWFעh|,y\94*p=R6!جF ugh Fwh y91D֊lIw;aRo9f 14h"޳yCc'ag4zJH 3x^pGC)XЏŸuԋ⾴t*C@"˰݇ahtibSJõXUY.sei.ل! 7h~@ܨr&~bYymYXfw6hÖECҶ\."Yx<(-Mށ.N,nj@i>>[7YsA"vc n&Pas4M)A80W_}/w3sZފ$"3(D2.sQXNr ^+A`[(8:y!t[1jrt3Y3Oe-ŋ 6׋ЌpAz>S@|iq1#8±`vT+ ~Z@:Z~݉E34u,)!@(4 Q+ĎxQ\& u3^ȅYݧQr@/<5?_n+_ @#Ĩ >^l`+deWX|7qWCZ$̡\B],bנ; @ӗ '7!fa4+Z:4N3󆀼< W()""|1ЬjĹ(Wd,RH%N&)Ǚm+`Vl>)fY,y .^5e9;m>3<ӘۡR~^A4l>TN M,|@{s3V~.Y 6!*"1)o1,K{M{^x(VAϚ h1+x^ M1]݂庿 MWtßUNjQYNPF_ݠ>5&6Ǹ :'Q{b.,솼z͐Qs [ w?w@[LJı~{e6Q7{UhV55;p@qsа _l.e K5$:|~uhla*rU,(ED5g#Ă3 ]e*.4 &_^* G­V)B}1ĘTAqV\yU#_^!&A[8 )I@kaDx_,WAET[+|dh:WRP{(z/98ZOFVrrsGD~ g'D>>;-V6Uu捚gK[+d$}Nq*Lvcl cfՀx!O$PPWt%7P)ItiV?voVIJ*;"^Y4zDNl9X2o$vdDZ|JdE vfF-'\@O0mA)نkp$: ;|+ޭ)rN8"[ҴBz5TdSL:{6qx3r2&7LSY"L4_ye! @m 2晧zU\v`ø_JE$52}HԜވ_^JT(}QwZf&kh\B~9mx붣n[heC୻Дg#:,^X4&AiDpμ<6怆6/2s i(|AX0ʂ۝w2uvxd/<|!Qt mVIDJHhYW}.c;ϹXYHK9<؅{.gbyԨϟgtY$y3ti h(kƅxo!bu@v{5ܙfSASu2Oa:+q7/,-Z5@*v&Br(SV~'@Kسj& >V\K}! QKXq-GxަF>ea]tIKayTu)Q{:RW^hg &R~+?UvD;ku!+WU.@fR,I­Z78W-D}$-M_k(l0d8s|p woX{]<~:=8׳Qi ~mtF`#' M+BF؂Gs}<F"zmW|]q*Ó&#" ;` 2hw#vL4dA}Y 4߅5W"c)tUǖe,"*1J&@c/f]Au[6"0S`/W1&_PKaoJyՅ QldF1@˻I c @hL]cCVʚ<ɻb4w 4 ۏ\MC_dQ@.H17N@ㄠWR!ۄQ1HI+zUf{8QX3>AC?@j8n]L˙XF#`<󳟡V.wM6|.^{]!$%@c;QX^ VFT\&nVCh,!Ev}k]hĨŦbQ˯IՁS)Y ǟCqy]eG3@# ǭC?>*%(KƒKCn_Hq`t3DiDׁl4N<=2tp> [POP[` zEL0)yWwx;eQ 14.I8Mǟ`f}}0~Sa}F]WkM@HNd."6=PN[v1S5r#hsHifXKwB9raoqqZ0|O04Wi>؈qMBR v$\3nGԾWV|Y4S-ljј".w3ț T h wWW{MAE^u Vk1AG \ {#T"nqhWS5<{Ub4bsM_Uș@Bg}ÍͣžJ(iMvItFʽS1/4b}[]/=J2n;Ps~9y#AN|6'Ц[ [#8y>Bw&`9Z..5|' l;;JdaqJߜpY.dX g޸l1<hc_琅uξl%u+ڲ; ;)_gXe ',M)m6FӦ`cqdէdAo`%"\3 . s-@,Yh˃äLu8&X\Ȓw<_ 7C'aI `Zo0FnzX8Q J07xw*σ>f2H;|ږiсS%و 7&YzTm<-Do5~6!UTƙ+YI#- 9 ʆ/0`]F;laK.Ƅg4'H ( 8.s'L˧/SP܌3= 80Ϧ=F˝L;Gf˚weLX$ —κf,6tA6.E`fv/xI#4g!VΗa5(DU'9ן㳸rIqu US/QL"NWHU:Ǩ hUT#R݄JW3> c]k-&hl4;Xqm᷹W9]?ϯ|<a}F -N.}\GvK-i G972 j.Bˮ'jNDFXDhlFW!4B} PI?D DxD"hZx'6Rpy 66 ,k;,@c}LIWy?Yw9šHī~&ӟBI#хe^~{{{2ʳd~'\te} o 6!܊Ÿ=oeKhtaނKͳbΪϊw;]: kE|-FBK'\NѲU7@}46 ŲaI 4'DB{8?xf.eX9`l-4BCBrc_4= ZmRZf6/c!l8OAҹhQM,’̂ҘY~'O-ab6&coiƫRbSK85_5Br[Rϡ(6x[}:*r߉ҡf;>1+x^&ie|W`oA(|!CS';'abonW7OyɃE=1GŸIԞ-`3(˰7!o$fc3dnG-*q=Ⱥ7kȀÄ(#?1o~.IVU lʪ."k ?_? @ßJ"?o[_/aCÃg\!$&\Y>D໸2:4IAv]GIB?- ?!fm~[@h`X]@+aKh(3j%>36ɛqe0g my/1SaMe53`Vr,Ͱ_4.XtDE~ h9Y|Sh\1ތܢ/AxI%DhyWAaG;PDy^f*;0waܯnHL¾w$jNoP/%AHQ>.23ޘ\X}Gk.iK^EtےdOF (u՗mo<g>NJ器!0 Jk$uo}sfnchxn/s0`-BIQދ,y'^g[5/q uuc^7r=PL,܉6Sp鄸"/o,w$-{k!KFcS@2c=)Gw)ͻ ͻw{KՁ^jt %=n1>]Cz{RO5@*v&Br(SV~'@Kسj& >V\K}! QKXq-GxަF>ea]tIKayTu)Q{:RW^sPg &R~+?UvD;ku!+WU.@fR,I­Z78W-D}$-M_k(l0d8s|p woX{9ձo D3{F >WЮn_:7R~\,<0ksp"ݘmbVM4Q ?9TP_cDx_`rP6`FF!\?JH.ܨ/]<L<,[eQIP2+}`7 rCH,\yP݇ T1)(Z{cWȫ.\e#6GO$1F 4g.v!H+eMf z1^{ ;w)DF\$"Qap_ǿT &kDf(g q$Ei4Nz.V6ayT R_MQN}m9H\QqH?S94Z|%i hT >zJ;?:rl\BHHKwx@L2[Lܬn\mXC6/נNVQ-:M1Xj)'X_AR(?Dˎ6fF[!}#=~!|TJPF+K#;, !ǁtJu!dy3q]['+1 9 &iGS=Ηҟ@ǝ=d|R9mhxۧ)!"#!>[ ^ò'LΉhQሌYn /ð7lݩ,$X41AO,9c\h"/]!~DqxKh|]BxxxhidKANȾ߹x\4-'4/ԗr/s4fD) ~wtsXf h wWW{MAK^u Vk1AG \ {#T"nqhWS5<{Ub4bs* 9zH#/|yYS 3͜i.)ШPwJ|9F&Vlpw4T Rƹ|uj/7o{@#Éot`zğqtm@\*| LM'r\\j]?W8YO@]sv;ª"㔾9E]#Ȱ<;q!"$IR#/Bcf #)|:oMzPy~[jl$CLV6d'\R% 8'(Nb؂u/E7&<Dh/$Aр[݀S>w4|B?x8@S: lh@#kpd_y^YtEp-|][hbCIT phRyZLNuCE1/20a݀1,2UhLO4r?gq n)D4vD(ԝ3̯ 5x?u@c;QJF|y&bM =} 6fMUfc*`&-v/¹%sg IJM/?:|^ g !W3> c]{(~IYMj\ɞz<, O(}u _kq J5z@иIVaֶ@МS *uO*_vVm Zh}~ia_߰uѓ8@cW57-R qKxV'J'XW #"Aӂ3&?ﵑGD#[fIxN}2u)'7(fBtrTISR'ZQD:VRZE+p(#y_m՘ Ԝ{y\᭪;,[ˢi Bvw[{9 9Ur)EB8%Mkkѽy$Έx(X S2B s_ޝ r>]B>50*^KV>_YQ-u{EUٴXvnuzDy`RTS݉ǩEm BdFBcE8?}*a| uIpcH ۀy =PB A0}"!}sKB4%WL!ҟ2 7QDn$Q9N@c;|V>CqL YC} >fJSJgZ9>)d1]X姻ʺGW)< AwAI'߈.Z(`-$@_ .fH2lx34F<})@h9"艀x Vhw6w*h'm󨄛bBAMOV(6Gg%kh~@T6146*}yOr^㏝@/`"KcW khnO5<ӂ+vC֪"x%o`X|19ڴ͊'i-$.-5Mv2f;8>Sgl014& !~Ccůz;{pUJ[_/,gNjo֯%uYX.%@w^s%w$ qnKqAˌ?,!14#WVG;$y[|u2|uY@kQ@p\\<])lVu_l k4CC;OL[Y~IkE6ҤhOKP~L>1b]Eﵼѹo`_WN7EX\mS07$'(rs752$qS~9rDԅVP/v;4htibSjZFJXW,פ~d"|,Ly=&Fm3\]k}5rp@-BdT@t#!Fn%iuxwb9f"POL3>߇y<0zja h#q'2!vQ8؎j@ _Gˏ;hƂ⏱<4!Hų4oؑx#$Νsrtwk1ST1J叧&b++Z!#TCh5GK z~lct;шR&.%(lTefMjg mٸ9fkGMY,d9ֆL! /B=:J/Cʪ_"4q.>ك7D=-KV55!G<$-Y̛d(ћٍ͘7Viv` }>#ϠIY51YР*_M)'*6J 0E]؏x!J5:|9zmATvB?7A,}pY‡8Ew*h h/)X}Rk}k^&;@@b̡:HI%g<:`_A_7+PA@Il&Ibxкաa~frp"JSs.3vb =F5]pJ;I&9x?*[1Khqj /xu0M K4(P&Teab1O:[p5ŠmL"dҌW ; Jpj2οjL[ CQm"#duT6+hu//"-64yf;>1+x^ M1]݂庿 MWtßUNjQYNPF_ݠ>5&6Ǹ :'Q{b.,`HN= f(MMZT9ZRI N&%X2FѨyȽeiy*4+H^ԚE8Ŏ9dhņA[w6FDRM!%e82_[m k:@q= &>mn ED5 #Ă3 춒b7$?Bm' 3Jrb<ߞ1 ~A&:4;j,=E]qq`7CCɚP~1Ǟ֡O\X7W8l|&me]`h.ƾ2T7k{]g;f "aMh8\Q/_Xp|DrĬ??|1๦]|;;/দqiRA&xA#ŭ 1Iى;Icx5);hz}x3\|g\4qѯEr"1+(nG'#Xfpx^3/uƒPTf[8@h "?28vD:X~#8rBh]&\Һ>>OD㝣.N(N.b|y_ G#8#8#8@8#8#84#8#8#8@3IҁNx] 2dFm# 5TıÓ?ˏk'M+4IpPͿ1yW9sr[,K ڛQ-/&9ɳa _}i{У&!m\$Ls`,Py58/ܨK۬Ğ))K4dPz3VAZ3t٦x>g'}YKxïš2*@9$o_wCNkY$7KQBGMUKMY_D>}9Xhz!~mM EXr*ěC&5c԰A)4(Pe愄 8P=#hy>N~#v@Fh+.-BYixzaNN9(F]˸x$m;PwDLhy h &迩4*Te11]]SE?[?\Jye' fJl.Y7f re$S'&r͏%)ʾJ7CYE$x ahӲQITzf @4?~_rf s< !Q7& ŕաH:b!l\ 6nF'FOrX _z@Ca0U+! hLތ+ L58Sh"z1X+hZ?C?f`5/Œ ;1O?@Eg@Td!ۻF;9Y|s!BU"*`A*""*X]* ł%X("JJ(!$;i0I&\(羞]Q>&2{k!顅OOg"Y!WLd*0K`< g@*@3?yjƪQ G\?%B!6hheSM_nްx?CNT ,w'{ď{.b EzML1Tj+!neHz@]hzo%揌E(Pr ^k@yU8=kJO4VQ[Xq͐*(-xv dn^+JAE a,Ѿ g3ި $;p>{ND GbwDh\ nsfIiY`nZR);Ji-} Ѽb@|.73O⡶:EMMkvt?.UCE":9r2*7[0{>ܪk҆kȘ7͐h8O>E!CY4x 1A1fzu+jQAӖ'8j3g+}-c=Q[5xn 4|ħǓfz+?JZT6Hu'Mrr5y@Nt=),op=J=FA|mpO.0V"ma,OGƣ1ZBө< Gכ-ڎR9<8׬FO])rSbAJ6t9 b'_`gU>kÔeBg3K|G`\`vWS_Fh_kʋ`fa1k.x<>t? (;36һ7غ:bכ|8c{$\l~X 发CPR -bN2Thʷc񌉘5+@ y)4Iކ !USiyzjNbâX,>MvΡp*$͏EkQT ;1M`w6!5HbOѲ3dZލG±w14:3M7mn GVG0CdԕסTDA=aEyKIAH( Ln07Stp\X g({ ^e$qChS$Cb\2CY]anw' 2$dTKvف.iqA-gb~vȞz\hz~?J1M0#|~s.h%HI[{xÐX*VG\R.uBAhl!Evm9נͻШ;$ X6$n'XϡM $&`͡Gj]^9bvȞ!m*)ұ 2>òPXz .nwԀh:(!C3'Օ$a7FǃNlo!_uFӌڧ86x+rG<}Ī8,t/{d=މ)sڑdSnZ#t+=7>$QGDΤתFDhl>)D- & 20Wğyg-[ cvIF5HZŹ۝/*1^'p2! ?PxQ0mpc͵GhxpK1p_ϧ~6i.h& Zoq;̷L!KQC0 ,"Zataf|۲=,3N()ϻC^#ULl8F"CDlcFh~<k ;#,=RqK<A_Ȯ"YAT1 }e? @<5sg#H9դK2ʒ {7#3!% xc7 cL[_^|}i%_t7YRzB ø^يS|X7@ w{3@?@\ Wr%YLr!&wzU}Eьsm;%B V-f6e$~wxQT6AJ+>$IRkЧ(C=KVXE3g5'WX&0$pMUP)rLv%(S(HG[΢b0?GD4'HM(z5-8)w'{;<< d9Nγwէ\/@Z~nԩ>dH?Ο5JkJ4ρԧQ#e54}fv`cN{)n.l-\z;BU6˦jh Jvw[ی)6Ir+E^E2k{hҸ0,gI;{6""ЗaZLa7X:X ~HT# %JXۈan^AP$FLDb2*_zR_owNq3eI<ԯNf.pv˘ E,F2MJy+BDo}47nb2:w{l(ńcB2^-dVy!Dh{ސ=?3:1{ʪԁaTؗfi"r8w{ܓilк-%@3cv"4))ʔ o#$)i~kkPH`?}P59hVk^Ay[w+a/δA!!䏘9s0GZxvSx9eEh3~i/9r&oɗ9=%JTm4>m y錅#4>m+b.BAM4+ѫ@] ϶Gh~B$614Sn^/[O;E)E=¶/,iP:T#vf#- Ź6\9] y6G]5P~#]xҥmVX/(l$qfioF}ov=-V 46bhtY(\F mB%Hmy61(͏Jh|1g9sh su%psIVGc\W\euGFd#k!NIx5"fr\4 !.),^OwKhq-J֛ǂSXǵ8CV#cm¬j԰nmaͯw-wTC#Ǿ7&Yv]6-v!? ׅfCcи`CZO-dlb a2(IJ3 JOPY̾_=cm]j:^xw5aX5X.&YCh*% C 8]BOyG@bYj;U5x,, daAhY겜IbyXuRy3F{D!)1qIHTRi}Vb3ؘ?a z2)De^XsR.ĥNzϊ#\h ̯‡37A@/of } FL 5%!6)e ,g(nPAV} vu ,grM_9!ă(qm}3M1T;/fBU+P6x)JJĜQ>>y9Nt0'41_Y986K6N 4PoǍa'd!͸2R֬|-)HN6CR 7vCq緯D|<$,#m?o^I8^AKP\9FactْtȟϞ4K{liDaj4,FiM;djs706ch9a˭Xk` 0/Vrf:4nPBW~ET݉e 9iDnʼn8O7<'iY"iZ!mA,rjefLF^]zB -X6?q+UpW9@x"GCsuRXh3~Χ!'LFfϚi㼭FB+=7ӭ!뼴΢yјl=d iZD8"4q"/GM $=Opa[$ *Ɏp` y:VXM*ҷ{8Ŕ˝%סYWE@Etɘn&v`z_g{uhz\ <1- /\+d4d]DFoYztUz 5J)n֚Y@htq wxzyRCDx9Jֆ<,X|fq g_cb.&#W߫J/`KK8)'9l<& EFƋn4=9xD>(;[0YƬ8AhY3J+ ĥWښrUCv4x,;T[ iB@Zuׄ":hRԇ>z$)D VJ8U6ohyC1#8D 5BQ}65]Y"p2FeiK$!oy#+rT'Ɛa~ ڼ!4\4Rz_ԡq SaMݨ%g!rK9(@T}g#DtI37b;h&AtEEBfCcDG,8:v\)Ѳ\&aO 14}k)+O RC ZqɴTp-:Ɗe[u^73Jp^^OhX{_D ɩzׯr߀z]owE9z_/}MMҤ|Z q[0sGch7R_Hn\OaKŠ}EU7?;3 2,K[eM ?~[ep: CĢ<ܒgͿKqݾh ]#h~o7̽gP:{ũr}%4C qe : Tr ^^/DB'o#4-nj+v`P޿d 9BÒp8p#48pGh8BÁ8p8*3 XZx ϚA2||[(|=Z8$FJtiT9| L5 N ~faM}JPcFSs (Hn t՟}O x\V^_-y\k(ܨOlľ>h($*P:]X[r,әho@Dv٦x3`+DZl;g>*hK`MG5d8*@M0` ~ޙ6yM~K6 mr T,l#4FBC= ၦm&57?A#{VcUشZ{DPl DA 6bVx8‚ q _oJZT>݆{ fA%4R F k.IFڦ({MMs Af/.C.ڀ1w ucQB/{Pi%qEM7P}/||Rk/ᵼʿrU$S'&`{葖ai0Mh;QU{)~ߋ0'磆h‘(!'p!8kE}3B:4<&]Tӆs- 'CQW'ȞXl0 f#P=)owg?] C 2Þ(SA!'$q ܄*'[me*)AIu܍?TXSk h~F0{H;av܄滃q o 4=:^>^끦a?P_Nh<Ω<$,]},* 3.g%{|vb"4Z4ZT"׿7l66퐓>­0݉of3d^ '4C|^AASSVOa_F$хyVbX_A%_Tw^㏛C*YDiEg!z ݂gW ` L*V)!kT4ɡܐp }9`p9ڀJWw$Ht@~eulV};_LFȵkQf=gQ~H^]櫕/-D8/Jǰ+[+ $o.XP>j77aYGTUI3]xívZ.*!m tDѵX)e$iʲ\fW 5{[ȾP z84XէV"Ւ4AƇ8n˫g kwIfy Q1k;=̆۝:nvw|Q9%Uh{=n홏QV[/5O[ eSN%Ș<\7>\΋ߗ@a0 dűP0ǐ?1֢CTu'0҅3w .gqb:4h.c㬷}oh}HMK:|FsA*>l+",Gh3uJ-l#BKl \}aJZq)qG;{w 4)ZcD,^s:4t&_vj|EX$fBm GcﵛSIyRE7,[r\_? y~qYR,Ă<\m$r xOP}0P/I)gΊ5f 7쮦Ї?qAXy>hX#}LC~ b$b$4ğC Ǣn 8}NFį,&7ov' 帟5Bc$4TCx ƹ ߿ūXwpc @hL l#ÑU"8wDh|u(/QgOhx~XQrb9o1=(۰p8C`.M} :0Ù,ȸiY2Z6 yOѣ@Tq (~B+M}7q qKBvI5d2Ш&rf*gmGjШAbF8F;7!PmӝsA.AJ"4R ppu dO"v7|qF+}#4 8EtI4K.g53gФЀb #e:qeSIgT+F Xt Ѵ4Y<J!%q GhMhO0fVZÊ&P3v9Ch(2=/*AJOcNBj9UF8jāYn jE˕p(qs|,2\UQd0FӮPw D3-DhJ}/AJ(l1/氎Д%:GQQ)$JA InN|3h K;ch!@n!1 ?\0vSTʿ

x!Nט㐨es% Q[Ɇs GGx+邂 Ad\ӫFm$3HwT.DX9'4w 4ʟd/tTPL$!q"4YOh|L.L^ՍU֭XB]T B%\)X>c쏺 O5CiX!C"Cxt#'c߶›~]X9 ie\gj;׊Ш"{4eg }v9H2MKOW>ђ }ηb udEy+v49V{!hS7/rc&4C]G kq&%lt nKwNwCB#5P\N}KH?M eq8΋ 2* Q4SKPG+ctD{3_ ;"UrriEDQ#,;"v(q?_S)>7>V)3pg03!9պh8s ݉>Ȯ o_6]hUC+QWߢf,HAI:\(*YgC%.DX9g9-Nٳ1=Oݞ) q@h J$* ӑ%SGm0E݉ V(b#`"I1PC/=Y/Է;$Z׊RXy Bc@8wer`n"dT[Ӎ{&m cE70}*etHqyP DŽ}e}P[ ͇CA!!{~ f"tb0''Bd;U61eYDm%!$dZ>[+nKpI>8hkofJ 2%[- eJZhZ9:Td9R=X>cOoTMwqF8gioE-TxQ!$@ӱhˠY]%^@UMfo"՚WiЫ~~G5=:Q+zE[ˋqc'+Lˀ3ߝ3tf6ᓒ&)}$>!RyFꏡ ˅g:ܥH/r!"\]fW調Yqŋ匋}IGYg!!/:LhYr\Q] 3%uh&! ǨWB҈~H >)@6o8& /__uB{\ߥDK˚ݤ07 *ItYhڛ~A߀C7;z6dAhlD Pۄ&tKڀ{3mbPаbr-CJ*N-G1 N;EF k!NIx5"fr\4 !.),^OwKhq-J֛ǂSXǵ8CV#cm¬j԰nmaͯw-wTC#Ǿ7&Yv]6-d[c<T 1:q Ƈ Zx`#f14ߝLB~-f%4aHZYWĝjxa8/!4̔5/z*lbhX}; RV#gy<*d01~9XX!*@h}<겜IbyXuRy3矄D!)1qIHTRi}VbS'lAU15$!Lo{2}*ME.h uvAڎgdW &bfrad=D B,`h͝qsbdrf-?D}-bLNG#.q N#65X[ATMK%lU3c8x?g9_C.SD4 =ljR\@+&,e 48m y;<ޖv Z(Yj`c9gY% q~ A#4X_~ *G,߃c,.t| 9l<& EFƋn4=9xD>z cp5Q]ah&.֛c١rJMJ֊Wwԯ&AA>#OW$fR™x!9҈Gq1ܨJ#-A 4G̟l|/KKg6_'% ycY{z81, k g ~D*̘6g kF-u= @A oE=!KAjT[CE&Ǘq`uR[ԢmuDE(Yj렌B>uJ\q9;˪PIKW8 ANN\Gުx"W~Ŝa\ k|/BÁ r(!9Po~LwQ_3֥I[:.1a к-nݸ6ŽA_cRÿzBcr䓩 / #( #48p {9%CC1}f#G \9|o~vf.AdXB# ʚ|  Gh8BcWyҟbp/lסE9p 3so)*^q*\9{ иByقNB\   Gh8B8p88p8p#48p8p?*3 XZx ϚA2||[(|=Z8$FJtieU9| L N ~faM}JPcFSs (Hn t՟}O x\V^_-y\k(ܨOlľ>h($*P:]X[r,әho@Dv٦x3`+DZl;g>*hK`MG5d8*@M0` ~ޙ6yM~K6 mrNo 7 C J[KWaKx.kQX=B.Fy-&\Y /Vȁ#4:H}CtW֢r6t41@ .qPb0e^XsI26Eً.h o7|tr1SOhԨ3xykJ[p-ُK,bFh&nڿ6 {)@hT8ĥX P͈˘"?1C K+܄FU ~~}; r>j&rrC#4vt RM%P0 E_[ {.bš@D,@!?^CkFw%4 2|{FN(@%ppn0%Mwq7 SaMe& =T#`s1Wx x <skrzi؏6ԗ%Ÿs*Iܦ[XTf\.9x/dg\ -dۈ 5(4WDEE{܈sOEPPΡe2Qm)*_EL{yHθ72%c"#nOOg"Y!WLd<JC%0pQ_ɴ' ZX_y#'D=`>~1[lI6WvIzJ^ցe7yQ~/C!Hۃ)FßBmE8mIH MȿR6J.v < 7TcM)&j;j;BRϮ` TíRkCxY9hC!!7̝3w!\srdgI~WȡPnw^kt4{,0) - ,W+=_*e'Z^p"-_%a!WWH3\$4})oboXq.с!g[2` f/ه[u\TBp C%kS4H:eO3N 1A1fzu+jQAӖ'8j3g+}-c=Q[5xn 4|ħǓfz+?JZT6Hu'Mryu5y@Nt=),op=J=FA|mpO.0Vyšz?pD]]e1{~1z~ϡSӆcQz7R~t[W'#~^ Wzb 7;~쓄rk1~ ^z\I Uv,1B ӵ2?yb!/&"p>k 08/98BOIlXE٧QCb"4vڢs(ܸ Ic0oZU~NLd9M@{ 4һرx)?Sqld>wpc @hL l#ÑU"8wDh|u(/QgOhhdEyKIAH( Ln07Stp\X g({ ^ej!7=EJQ:$% bW[3ɂL&!:. %GvBnkk8n\F˙FBSM%ƶ fOw)i8xoK%ڪKŕN(461dkamF!A-N!p+}D?xm.d !6k=Tωg0CQfn{WIQUQcHpat3DQD bi=$ |1zn>t`x #f4>ű[8JWA&賧|'V%aɦ3x#ctFݍTX O!~C dm[cUK݆??#L 4/Xn{-X%0uNU2AoX@>Gh$چB7.g53gD/RB:.<Y ahox?g= s fzW|?-U!u1*3_D ugyJO=%vO{>BwsL_uMSlM Gn(&{_@ic\ L3"g^hWh vjc2UOD{c6c)zFa3x{xCD+v7. ֌Oc[ǐuɶ%y7xs+z5w<)tgHdUM',)mB gͯ'bmyuG`w@*.c)"B2kU:@#=ʷ"}r[?f"OmOs)xGBCH\BL6pC㢌WڲIȯQ&Fy㗎[=&B3H_J.较oAoX@\R'4nߛИm`,>uP8ȇUS?7gxJ A˨JXSZN@U"Cq``nmǩZ%*F r%>@?@\ Wr%YLhJ;w"4Zk澗 %RZa dMBsXGhʒGQQ)$JA InN|3h/Ef`[ oC,gFujNt 1XM>aHႱRKUE !?0W`n:NBܖS:҇AhBѫiHA;[|Zш< d9N[I &^5j')2w@D(40 H<U>׸ShU$~b"ƐM 3m zBCcta -nng ZR$|uzҊCwN'\^IwDQ~n3\Sx7>V)3pg0s;Lqua+m!p$F5%4 ݉>Ȯ o_6]hUC+QWߢf,HAI:\(*YgC%.DX9g9-Nٳ1= Rg ÍF㌁DHT# %JCv'nXě9Ht'C eTdPf˒hy_+Jb']DΗ1ΟыYRnM7e14QWZ)>iao܈ =etHqyP DŽ}e}P[-I!Dh{ސ=?3:1{ʪԁaTؗfh"r8w{ܓil-%@3cv"4))ʔ o#$)iwkkPH`?}P59 [+2^7ʶ3=,$>AZ6\H1/I~'fC ǚ+ g3qGK--kv Ihkd} 'gv^'nwbhu22H= ]-5eIhW$.hZ"YŖ_loS_SY>DV 1@c7㚂h봁k>8C!dD̙9:D Bc8ӖofЌG2Yh_j͏yX]`ufǠmv 4@] ϶Gh~B$6>73}xwLw_㗭OAHNa"ta[2wvj|GZ@smr!tvmajxGK۬:_QPIB䍠k vىNߏ@ذ C50B 76bhlН/AjAi~TBþ9˙FnC(|L:=[*:-K+a$H6:D'9XC,bh.ծN\Oir}Fעhiy,8u\14+;o52&!̪F ygAhA ~?2}G5 11p{CΊli7eRoH @<@v5g>A,ɁK6>TB&9"4Ne_RRWoch_d] ͛Y2S ͠7^F&66%.ŲwO - k~-XX!*@he+(. {, ,63? [ bCR,b⒐H7źA{2:f1Txy8SCBbBc&4AL;1i;=.^Y:M@582 !ڛ7w Lю4"]|._eR˼X]KcG_s6fn*GL^W1=<,9 Z pM >˙kKClR.5;MY<"Qܠ(VA9˙#@WN@11;oAh\}1:@eNzS6@fŦ狙hJ%ԯ )u G;1gO^5 ,UX%QZVhhqc+bj-(A3YH3@&ao_yHXGQ |:qBrB {鲁QO?#Pmpؼ7I?B^hYҚvn`lr,Þ)[mנ; Bӟ?!a^m\W6d@QM"y#|E|R}7F|<"[0YƬ8Ahhx'Gg&WK5;h>xi=Xvtӄ՝+ E5tФ}HSóp?*l4rbFq?ANik4lk/7RE>HKke.Q/'͗jIIBGVlN! Bæ-6ygCh.Ci_?" '3 CšQKh]BUgTMRTjҷqܢ% obCS5 1X%W>jfo_ƁJаo7@L w uh W"_D83yExF Y <QaK8BÆа"48X+ S 7#\Abo@ݏ?7໢=R|ubpSӺ4)bVgwe<&Zͻiݍi#x5)m`t/#4FL])%: r@AQPk8BÁ ذSb0=4nF;DG\`gD 4b oKɷo뿌6.oA:2ǹpk#4zAK&qݾh ]#h~o7̽gP:׀{ũr}%4C qe : Tr ^^/DB'o#4UB26G*_C"#dh_8 Gh8p8pp8p#48pGh,)U:Pg5w d Qfi{>qI CxMʪ,3rGA@VƌjrQ>* ?ms4$d)0[|j PQ0}}P2H^U8-tPa淄|Y UCހ9Mg`uVďcنw|Tі. kpT`~~}3mD}yM7# ]+l/;}#4 7 C J[KWaKx.kQX=B.Fy-&\Y 3C΁#44$^|Q!*+KkQcw:^U eW9K12/$iE4O7OyHhީ'4jE X< B-Z%1#47@_e 4jJI@BRɿ^(fDeFTLGZnB#؉H^i ~?95DD 99%4:4<&]Tӆs- 'CQW'ȞXl0 f#P=)owg?] C 2Þ(SA!'$q ܄*'[me*)AIu܍?Mh|1Ziڀ<LŞ:F??7``}bC0vՄ> 4>HM~Lgx.)ƝSyH f64gQiaҾr!'4=o#.H {\u iR(j`x@FMU.g,ՌU+7@?~1>K.ClѺʦaݼaxhnXfjټA(jY! _WPOE"{a_F$хyVbX_A%_Tw^㏛C*YDiEg!z ݂gW ` L*V)!kT4ɡܐp }9`p9ڀJWw$Ht@~P (V};_LFȵkQf=gQ~H^]櫕/-D8/Jǰ+[+ $o.XP>j77aYGTUI3:e2` f/ه[u\TBp C%kS4H:eOLkh]‘}>my6~"ݗFYo@א>m%V6 Ou8ox#cpQ܄nlVHjp9/~.]~9&"↤2%[1۫LJ휲pxα]Vޠ6 7CDRe[18ҁ8Bcg;ŕd !-[F\{)@3m4 laJZq)qG;{w 4)ZcD,^s:4t&_vj|EX$fBm GcBSIyRE7,[r\_? y~qYR,Ă<\m$r xOP}0P/I)gΊ5f 7쮦Ї?qAXy 4Ց>yšz-.=c =?Щiñ()?xN_:?/+ pc1`Iv9gP ?/P=ނq.$Co|;Ϙ QXSZ<Bm@5f|K$6,ŢӨP1;md7 7B[E|&ywk2P^.v,^O{T-5Hp&22@Z!N7=EJQ:$% :}7q qKBvI5d2Ш&rf*gmGjШAbF8F;7!PmӝsA.AJ"4R ppuscM{;>8T#GV}BF=B㚀s]DPf" (-HEׁp4C=E.g!|||t& lh<<G8Chz?\wR0o/7Y &B%39./t;{JB+|zE&G0(j}ԫ^Q.M3s9Ƹ8`p]<"PG|2z21I/F0M͛M>^"_rf=1!JZ@ ͣ oV^O2hsb4p"ô6"It 3鵪Q3m1QKԢ`2  ÚqENwb8 @P;la@OhԨ1\_\293g[\3w6>B ^d{6bNٺm;39VhZQcgL(Ʊ./H@Ghܾ71T>X}:"[qj+B['BUf{ PB)@f~$4u,p|qMҊIR)ʐ7~V 0YΌ%Ԝ\aB`|<ph`*ay&;\hb#@ -XgI1[h,#"spJTV0#HM(z5-8)w'{KOGZ w;ߩ| |68Chd8fA ^ ?]};_YEJto5=P޵ kSaz!92iBsq, VAɸWIfJ~]& M#L+±6OsfOh5ib?ɬ_騠H1dCL[Eh}^j1o0]zW7V[cq uS-\ pHpc?&iao܈ =etHqyP DŽ}e}P[ ͇CA!!{~ f"tb0''Uީߍ/2'Dh+ qx' 'Zu[K.gǐyD[Eh3 %- eJZhZ9:Td9R=X>cOoTMwqF8gioE-TxQ!V$@ӱhˠY]%^@UMf+o"՚WiЫ~~G5=:q8>lcqظH:j9Fw鏡 ˅g:ܥH/eq"\]fW調Yqŋ匋}IGBAw;ABzy B_t>|@!ulAZg(k 1K 2LB#ՏQlÅve#)@ЯlhXs||yV g3qGKClYBc-}IęNiWƉ۝/zݭ膦⼌!~BWyMY)8 ֣ruVcW cӡfq|0zlS*u7T=5Nw{HhFk5Z[M|q8Cvvm q,_ٷıШ` 7AP@j D242-03lȷ,dA"+˳"4ֲ$D[ \j#&#b!!N~ MY&YZ-Bcp^q%ױjF 8%QI/6qmZ'\x=}5?,ǵ(!Zo_ NAbp [Iĺ-5zY( FhJy~8FgE6Ҵi7oDOP.4[%*zjߣwߴao>0>xX,jXsv2S?[!9>N]BOyGbYj;U5x,, daAhkuY$ r<,:r< OVmؐ$m*D4ҍsP^Nl̟U=^NԐ09hDycr4AL;1i;=.^Y:M@582 !7w Lю4"]|._eR˼X]KcG_s6fn*GL^W1=<,9 Z pM >˙kKClR.5;MY<"Qܠ(VA%2Yl8r"Bى=P~ B,s,gԛb2+/6}w8_̄FeW*~mHS=ډ9|0|raNh\csVaql$lFi Zi@oǍa'tq2e ٌO͇Kؒd3$EaP9m=w~JC l?RFՑ o@h6&@K zl#=H:JFc΂lִC6wc3c ML:nEm3uB:$̋U6{4<'!pqgw"cBDEG>>[q"< ωfZ <(BڂX$^A#%G̘v ֽ4[l~4W *l1QaǔMՄ3y7Ѣ5 6 R6m8!4}zn"YRwD _+L =Xlt 8"4q"/GM $P¶HUX۲ 4[Y"nT)Y}E}M]TD'Z*QZ&kb֍v_^g^&OL.K)41 1 Yk gVE8{jhfBRhA̢_BPmy9>i'EN, 63z{\@ؼ4BɈEUG#^1JpR:N>m\W6d@QM"y#|E|R}7F|<"gS-lcV| 443J+ ĥWښrUCv4x,;T[ iB@Zu":hRԇ>z$)D VJ8U6oyC1#8D u)Q}65]Y"p2F=eiK$!oy#+rT'Ɛa~ ڼU~=JJm!U81m@G0tߍZBzW-C+/$U@& }{-] v;)ƍ1+X.IoQQ"4:4ѿQ#}6$x2W2 }Ir g XsN\Gުx"W~F2n_qaEh8pV~A%$-?\Abo@ݏ?7໢=R|ubpSӺ4)bVgwe<&Zͻ#pT1kS{Yc}(ti%Gh8pcbsJ b({G(s\ȰF,Am 5v3@mpƮ ?c¸n_4C4R?r÷fR(TjT sq */"!@p#48p8pW 8pqh-4!f[u\'OǤI1q~p8p? 釷w?ÿXxF8K Ys7BoPegP~H* ?ms4$d)0[|j PQ0}}P2H^U8-tPa淄|Y3UCހ9Mg`uVďcنw|Tі. kpT`~~}3D}yM7# ]+lҝ?ڬ//#4FBC= ၦm&57?A#{VcUشZ{DPl DA 6bVx8‚rs/(s]蕥1} M@*Khԥ~\M{Q 'ț`~3I!m;F?ӱ(!gVE"ffkR>` FUC) HH\5Z yߌhو*\0z=H˰Mh;QU{)~ߋ0'磆h‘(\q "aCÃo%H5m88B{x2~uh|n칈2G`63_OKhxz vCߕ0@h(=:~OMR|¹Eަ[Xš4i@]/1p kj-4mbOw#Ο|w0?z [@T!_v9B3؄fʕt#RSSzi؏6ԗ%Ÿs*Iܦ[XTf\.9x/dg\ -dۈ 5(4WDEE{܈sOEPPΡe2Qm)*_EL{yHθ72%c"#nOOg"Y!WLd<JC%0pQ_} Bßj5cU~獨#|KDhni&EX7oll<^!'}*y[a= 2fFQ Oh"ne*  2j$= .4=G"J d(/5{*܌R5Z'H-z8 fHh^1 ^g Q>FxsÒbfIǥzHPD?>9~VnYˀ-dnյrQ i5dLΗ$O,#AHP= 23FoLP Yޣu G|T ڌ2يt_F (utԖ~ ޼8ʏ>A!$ Rݼw6> ,&4<܉'mN6G;@0nw݅jG͓bTI7g>FYo@א>m%V6 Ou8ox#cpQ܄nlVHjp9/~_@(-þy\xIlݢEk/Q e\(>J/6$xSu&%KH6 7CDRe[afI0-oZh3uJ-l#BKl \}aJZq)qG;{w 4)ZcD,^s:4t&_vj|EX$fBm GcﵛSIyRE7,[r\_? y~qYR,Ă<\m$r xOP}0P/I)gΊ5f 7쮦۟~Ǹ H@ 4Ց>yšz?pD]]e1{~1z~ϡSӆcQz7R~t[W'#~^ Wzb 7;~쓄rk1~ ^z\I Uv,1B ӵ2?yb!/&"p>k 08/98BOIlXE٧QCb"4vڢn^9n\1h-*?Ab' L2P&d]X8Z6yƠ( C˻H81FG { *UCfb"4a:('4|jn Lezd끴,CDŽ yOѣ@Tq (~e-v?3M,Djb㒐]R.}d 4FaYۑl$4j=H+Ubl`F{wbUBl:=2t׷7BEH_24J&BiڑS)Y& ͣM VoV^O2hsb4p"ô6"It 3鵪Q3m1OG-Q| $ kg;AYRmC'r!F*y6^Oy#!"@Vm6]в4S .,1#4Nmł lpJZYȠidWc`*ߊdqoJ:}e? @<5sg#H9ٖT","x+T"B` O$,ɰOY gT+F Xt Ѵ$dL(Ʊ.vchFv &4f ' z]Td+N-aEht[(]o!4QY @{!jENU5,ڎS]u7JTfAJ|8VaH >B*(K BL+T|Eьsm;%B V-f6e$aAxQT6AJ+>$IRkЧ(C=Za=Rx/|Zd93z;Psr[jx CT/,7d'\2Mt8|Z\,:)f s[oDdNJBI EG"doiE#H+WN;0g ,Ku˺v2˙~H4]Zq.p-4#ػv!}m&taz!92iBsqLcD!j 0{(o%]P$Hkzը͟dtert84(k#4g`V1{\N&V囎 dC61$δ5X7 UI|Ӆ+ ޺U+jZ+EgQ7ɣf4m8+dHp2ԜArdVxo+$M0=L-׹Z CdfLNՀ5] !B]BAp1j˸ov[8/m#wgȔ=HA8}wE(mנZ ~u G%ȨRwv\n#g] `@q9-7"4f"5 6)8/VȨ(DшN-A;**|yR3Ȯ o_6]hUC+QWߢf,HAI:\(*YgC%.DX9g9-Nٳ1= Rg Íq@y J$* ӑ%SGm0E݉ V(b#`"I1PC/=Y/Է;$Z׊RXy Bc@8wer`n"dT[Ӎ{&ŀm cE7bBFu=R\^6b1q_zD_/EtBv=EoHȞG悙I=eUwlwc~̉49JB;IBc=ɴ|V2ݖ|˙1dq^;`̔ IeJ[ʔb5µrtrz|؟>frqB'BߊZ:tB- I9c zA_$tK < q-) HEH4j5ҠW y!RyFꏡ ˅g:ܥH/r!Pj$07/ UU!4l-46BCBzy B_t>|!ulºAZg(k 1K 2LB#ՏQlÅh W}RLm64pM@^<+3ƙKϥ5I$45V[D Ǔ3;T QQ };_ 14[[ M yC$4+~SqI4Gbݯ@6l7fC ͼH=CaD+B#OTn}z 3k< j"im5q4,4,BYٷıШ` 7AP@j D242-03lȷ,dA"+˳"ֲhYXk  5ۇ1gWI-{k@PMu %(qs}%t-կ163Dٞ p.аJ<,.:mcP6GJ!wƒg'Gh~B$61473}xwLw_㗭OAHNa"ta[4ѮCe9Rlg<RkÕ ŐkxUX>҅},]f,}L(l$qfioF}";{\[ ~ذ C50B 76bhlН/Aj|Ai~TBþ9˙F;oC(|LVJz4AqYq%ױjF 8%QI/6qmZ'\x=}5?,ǵ(!Zo_ NAbp [IQú-5zYoCOLQ B<{g ?Px"diڍntٴoD .4>Kh=˲}M[141%-' ua2(IJ3 ?JOPٻ0g'X=/E=;Wĝjxa8/!4̔5/z*lpcBOyGbYj;U5x,, daAh>kuY$ r<,:r<OVmؐ$m*D4ҍ>sP^N)xÉJo&7uxY>"Hig4[ m3+1 3CG[ 02GRf!D{ 0}Z)QfPðLQ k.^UمTIY1v MA5 >W`S0ar4ep,󟡠!ߔ賜)A8&墬QӔ# *ȪbuĮ.X"v[+'[ Ęx 42rF) rbwLhAv׆:eA ٣3'/ljn5+q8gF"zf)Z@&Z~؊ةZ JFzLҌ;I/#ef|h>\–d$'!) zwi;ϸW">fg`rT6_m7$`P%(nPB#İ1^l`Sg=6 GдW05sd21Khg q[,5h΂g0uHld9 Ci(xN@!CV>"*DƲ}"|RDyʹ,t!mA,rjefL$C^]zB -X6?q+UpW aՖYuZ"~Րe ֋z { #! E:t)Tf6\SNRIB\T2. 1,KgM_]#QC׊ FBcɓ'cҤI#~:Bq8p5T}~:Bc@}q_B(r8|5T֒/) _#g~ 8BÁ8pY}#44V\8BÁ8p 2s%p8pFhz=R"4 ۴Xbn?Ae=8Gh8pIhuom#YBcNf8BÁGh8p?.Ej8B8BÁ8p@ht̫j?@}^;Lǁ 8pa0 mյz-}?MhI Gh8p 8p#4 GhH Gh8p 8p"4L8}^9{8W`#8 D>pń?s8|58BÂ8 r8 6qBÁ8pi 8p8| 8BÁ8pp8p8pp8p#48pGh8p8p#48p8p#"ޠG6m?egFG ~ځwK8 C_n`]1 øtHX;X#eE@`wqx&8pÏKh7_0~}QAxLJP% '`_r_ s1e`֖ EJR-? |(&B{!0{QCHg?y> WNPq8؄Bs^ C:?gx~G"4>HE2~z.$G"4U$Y~B f3g9b')A Մ-FYQ.?ҢtCPyoD{vZZI0DuH5J)>yc((] `4蹨:M!N;EFuRؙrF1.UAvQsqUTT oТo>u@/qjnX6km$rƵ{joȗc΍@Ac MP(xݹ92-?|a4i(X5}2^Hو{ble_%S_دw9ƹo>BJ_LūpYyd!&#^5w zASaL2THW$ht%042-Z!j)ԨKcV&'¸Q-C,1쳽aݓk1)]U&݂b3R=!T$Šr8(kmݩl$DcXAx/a* #0BpG # ܖnN~[l qdC9j8f t펣.ݎi)藘Av4GO+Dn.-$c(hܯC6p_{8팈4Of6ASPùg hQ5rJt}ȹ9嬵٬0wix_E88Y"h׍'VxbO/ARXBB/P"""bи~иa!5Ǧ˔?^jujObnt&M=]*$vpkZ8GA1 {j83W2S΢  4L9$*PJG5Lkxe|7x;4=&Ds'aAףRkU[;%9zp/tt{G[?IG2,-}eIxA扡[Pa5Ã5\S_ derﳜHۂZ}!D*dx N ,V[' #?TӐ5})rg%>X|nx'n!P[OTHN)0H8:P }l el}5E€ʂ0=cQgM(1hbM@wt*ܛŚ;٠π󰽠U:oƎ)ο+7Dkx& 7{jqh mnM9W9 PZCr\=LQv7Tշqi4a-lMdtFm8QRM%nw.'hߛ阷)ʫlknN,K}?28!هׅ1pZh6F=gQZA_+'f눈נ~иL쨺m=^'p^ƞ,Z""""m8*Fon- >~[ʠy\0~9N )h.,O7:kڨg}S dMh$us;/!"""1s`6B';׹q 7@7waAX {?p\ˉ:}}khQC[Y0)ggACDDDDDĠ!"""""bACDDDDD """""" 1h4DDDDDL3VdǪC """""W ;;ɈK"{1*`NOACDDDD4gb3.]º Xc&)PIΡQqıc=堉mb` 60[Mٿs2h\ Mx/$RnVjي:g8f """"" Yc2V_;cnAo>ElhDx1h\$hz+# 8BʎYߠ;o UHh/q4DDDDD4*;ԻSq*4VPX&>_ e;pp\6~6aQYpY$cƠ!""""rOP7>8;s6&_xpgpx{QX_:u)l\i'c̔0]صlEb)htO8f """""W nmzCgcA\1(WjeEؓ!z𡋱Lthox<ě#Dhwp7CkĠ!""""r0e]#c[1#\Ѱ1|U?F [a B2r#Jc1ƍ;QTÕMc&n't$֗Q~sct 'Psqf窡Cd~)1h\ h ]jY8h,l vހK`$Ac%fSCS qA#6I̊&T1hU:-yw(]䈆ҿU5McƠ!""""zAӳo:u u3SIYF8̼pJGBz 52H{8|wGiB5/`\WbE>ո~bOIGDx0^tutЙ QUw&DzR1h\!hSfuh۰z~`n (Öz\\W1hM"4i<|s jPuv-R#LA;C$8Ce~)q4DDDDD49ġޝlsO.muGƷe0b6/W9SvEOk_] E_֜Ї5}.髱c|$7 }|/tZE,EF)2E{X1ClE]U1v c ha.]6B$\&+FgrGl]5 GV(dz\<]`܂5,A<7;|R 0w222F!٘7iev)q4DDDDD.4}^,X6cF_muLujuVSع|4": ?=$DŽ!z*)*G^ػr =頑~g3YT"""""zAst3cʴ3˳4 """""zAcyvrAc9LzAC%~""""""AҦ0w=ggM7{(hN={taN3Ӛo K7o a&cDDDDDoNx3ěhfjW-Y;;(h~g%j j^3-fqcsFLsIȼnj {1'+1;[AҨyl4lqc7%CDDDDDi4D4dge^B/ gV5IܘEGK"5+!W'c4yAؘ8IBO6xU1BE1cJFNX iܘG?e/[D3Q sH9DDDDDDhDq3Ơ6q# =5‹V"Z8X6ҸK/sVX vB^NIENDB`backintime-1.5.4/doc/manual/src/_images/dark/snapshotsdialog.png000066400000000000000000000643301477034762000247150ustar00rootroot00000000000000PNG  IHDR*k-<sBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:25:52 CESTdEhIDATx\Ug?3rΜ3b{P*D "UEMƘb&QcKbAQ@z~؛&}r>3Z^<]o~[?qoW9aαs9.RDĈsyK8ՎO3vNwcUvNQ$'W8cۡwg? |>_&`hhHK; 8Gpث!Y~FRCRc*Gosz99z cƌo} ^2ع\_\9cڣ!֒U4CzxŽwy~ \9ztY_szJ3 Y=7-I^gbC:nxG#' UQӑzE}i%vr

Vc?FpNy%swծ^њ t}M#; ;|빶5f ]]`=uї8+$}{3FU p'QKVse)ע %8U>"\ƾpz _si 42)Dtlڴg=>Y7uA-*5c:N r9.9B덼&mܿ[#OTqQL`s6n܈V$$$^O6ec 4st}"+8-LL7?or),ƨ{?o=@Eu=PQ|DO Ͷv 7ũA 4֊r~c9iNMNmua*Ê)vۇ` >܇1Vk?2Z31MݒpIY%K.8'ʑyZasqQLTu h|ߨJܧcL~P%.#e;ڇw *eV)H;>#5~E9oiRE[T='zH70%Q`bv|Y TD)և0큈j /{xb5Y9Ucw9-oaY[A,²2۪ b37*k$gX XU_x7>ig!RgxWt WԎ1Jc+~|-Q]r&ynkiFsKzB J @c}iNakeMc@AIS߹Wn [_-16{ݧMdzMU63D]qjGi9V?ӱ\y_qU-Q=gk_3#Q[/@'?zi%[ZTs<=äKp_βiZ[P]~K-QաmT7I1/㻪vzm[Ogi4KI UFi식1ZmuۇfpҼw.3>+#-Qsz7QgN"nJ!*s+=gw?t]A2/f=zWDEa-7vGT.9T$*xysV:RZКK)ST&Qԅ| Dg]zDEߊ>D Q+*}[J~$* FD$* xaEeB"o *a՟'A '.cǂ b8!QA" QA"QA" QA"QA"DE"DE1Ee AslQO3 |k ^T`xjfvAs5bCA$ %Bdք3pF'*Q .-?!MKBW$]b5udww3< rOFr3Qx1@)&'P'&Mǹ:0[x׳ HT_w -'Z-9zY12݅!ɕ$Lvr\/C" B8ms!R28#S܈l,,F1or쒁b*G9ni.g M{ <$w𞟅ZO@\rԈ1p; Qb9ۆcѝIi]g >ύ6 Ci ww;E9(PC2}e(!RcAv#9fTсv9J5%N2nBZ {L0_Zq9FZvvt/bwBGW&)rEㆴ p2\dKTٸ݇D3 pO;gw*jHonT&Y;@ހ<0e-&X=Dm) P4#/ܒFU>Q ` *hiT,A]T,ʻ'*.$t^sMLy8 $* mVy%y+}=MA)(L SIG2TMBq%e:ܹ< ; Q H&A0eRzF{@ڌGXllXu&'*>svށDZS$p>.͋) 0kG)eנk q],STdgCTwA}Xn !Gꡨ>e gvXv -nr5󵮾#0J89 HIESh6|f -8ΆDPDr֡M wOb/+Z!\Asvp8ZdTH9r9/Kh) kռ̧߫5g&$ 8v< AUT,)] i,%c]{2 QNQIFҒx2 QRQqWZ~FIřF]$)UA-!t]5cs)XteH d,W|Q\;~2=o'%AOJ& QA"QA" QA"QA" QA" QA"QA" QA"Qxq3TW6)k-M[D# YfJؿgΜ-3\Γt$@WWW,\aaa}–a˲to!:E˸}oLadd4|9kW,or^w +V>w#n^ynj|D &OZ ֭Æ vZDGG#00P9I*88X)ԩS(--LLLr.P/-ÂCN׹M Q #,P)66_r,QEEEu@%/c1NeOAΝcBb M1԰Q @cs\ؕ<&bHjb6k4ƿߛmズІDEs瘔֬Yәg#62255Xj@(ddÒ TVl25Yi/} D^ JoNNJ4f⠖!Q$MLR }S6 1M7%x[kA-C$ P2/l*2 ړ9 AF vvvprr{o0bc-,El9l}"&HT#uT4{leM`G9,tcZ֥䀹v~yx: HP$jsNؿ{|A^p QA QA Q QA Q QA"QA" QA"Q2W_%%eTjԩAd:QA"D5ܢ255%%Dka=1!ߊ4 QL7T>v03CaK+A28X|tPhxr>߄/u ?m$s:X ը |]ӎֻGQI,+jN"QT&&&J,SE-.| {J&S@.ËcM2V(^VfTGV3L}tu܈M.Fݣj{('BM;#12xM,f؛b*QpcJbɪt|S*N̵P/g6 QX4!Pp!Ž}n= :m#trlq (tB؛rXbc~2_ X|`پwGTB,Jn:J9B: $h+\.Qn@謙zO>ڥ QQ1Vy=8QLC*Zmݹm4n!Tk;]}L}Azͺ*]L`lo[]rM] YIs2\bNܕ7h=ˎpߥDjmv EdJD]OE ?3ݢ0S6Wd\|ŏ*k!VcQq2݉Z|؂{mWP'oEϑ{v9)VLҖB|R%Cytv D5EՉ&9*E#[S]Mi> aDzA^uA=c&DQ.=Y-Pgq^H,F!YovXST!jQ!*AMFQSI(flPXt/Q-Hr>F[:r2Ōې5@vS;q01j +Ά.j7BʺH.8<]> _&}9gcO񠇨p4g#""2S5*PudLmy#:%KgNe3y@T+muWb`,\oK.<+]7_@1%/CeX&K5AA{qQ{;dxx[/K}9^XQ"C{ m{$**Qn24p#5IokMj v_-G[_q8M>k5>8}5m2H*p6;i֬}THQv6>K5A;GEDEDE$_]TFFFAd:Q/!%cԉ7Ad Q QA٢zy7;R u=܊*DuR-~h QE*AFdO$8Ёs5C~Q՘ZHd(.iA@Soޯz͖mIA̼έ{EA!*ɭzфKv9PKTQiqJh [*:PuSKv(|j/u7Utjb#1ĨH~ۓ^mV J jXSo91Y+T[um}n҄r$g< HTCom^=(T&?>lۂr kT6 |#AF5n HTCC .4`^QfU ;p*uzBNq )s5':pD[&g*3RO@n^.2S6"f6Ek=yYH_)Vpb ƦGNFɈ-5Iۑ[{IKWԄ8'!slxڢCfj=dh.1cE[/SEZ >aBpr25yl\ltmorJVld4,OQ14"HT)ǝ|cYXaB`ɽ<foPBN~I ˧ tYt :#OaۉM[2 U\ -AćcH2+Hvֈ #i9$Q)*$,(PdQ` eST0Mayz_mĭ?2rvx0;8cq*kG҂0L:_کddz3~#9/%,Ub,&x,t5S89,`*Lw<6}mj(&7~6.G%aӺ۲]VJ}e"-i ӑV*; 6L2S|a~6#3# "=ߢղ)o8 Q2^i4%um؞S͕%嘤9p|@ \xyor buxtKlo&BjC2D?- A8'h9 Gm)Y(8#p)-W$2W Bz+d·LZ'!B6@Y6 L*dazu\MYj l K%h 7,q UǰAuB \S.7/x}a &UIcuzᖆ|a.t%\^ Z.گ;ֶؤ~oõ71D5EŇݢx;7,ơf9M:hys1s RuZ't.D7rjL pBzY{ތ_ :k ̺in ft'pC51*8l\gB(?yZ# Dl&X$zgfy B=.ldvy1GWXe nΆєwH+>F)$'*nsŸu ˜KT|츎H6 nԀlοD%F}EgV7xF6ȔԊۅs0L] b%wS+gw̜}WQ+ylba!g[f 34yv8VS}>&͸ \E8P%Eq4MFp^>.vuSGE}o\} C(w@!B*U!S]Yig }1g%^0h=d;9o̔sUos4*-ó3H/)*-3#}W̵u l֟C?PC!G/0UO8mU(qz1Y%jב2JܐFf墸׸l% o͉n8Djѹmƺ H0ݮ Nnnpd*>,>Osdz[ aguŐ]'& .$+9D+k±(.^h5Z 1Ϣw9x<9?KQ{d-9YU,21X {0D'}! HTzTT .g"d:I g▸b"q5NS;faV݋1Sk](&Ю`r2Rcy~ :R^E)Ȉ]~ ZݗLфq.PGI $y`h.1]^6{^G \=S]Swiހ|cLu0J{ Dg1a$&*|Zk":C pn-21GVPW2X]RMt ^Tk83\)ųV96>G 0ń77ygxMR.t7|~Fm nVB*Gtb>/ݯx2ݩ_a[l272\OD)BCDE  hA"QA"QApߵpr(|p4? `'h +Õ/0φ?.vXiN'7 Qiz3 ľ2FLh0"3N≬'VkR!oמ b?ύ `rY*ЦPCB"QQ<*pvNq+H,~=%BЁK|Wn@@HTT8 /!/Ɇb嚓Hc0{#)oƭ{{B3T6DEyT8y RHnhT%  D=/}aoH"QQ<*w<-Q#*8Lp?%]Wͭ$*ΣySd,sm2R7_3L_HTT8 S8g \F&nCʫ^zrzVZ=w_HTT8 [8g2_ޅUAOe8㨚 u[jq #t6|} Gh~C QἁSr'Gc24Hhy %J<*_GYr -JqPB :DE[h Q QA"QA"QDEDEΣyp3#Yi+J g }đKw \a$**GR8o,~P(U_ϳ Bgv"ntpJ<>NRiQ;`g($|:ITT8 G<_%rt-4}+wd(~jTSKc%NrΣyC/7Vt}?N[.CZC;3n1vcɵO#,ΣyC-7`Q,UyGulbNA,8>$**GpDo #׺` d%vЉNyT89 dD57:f-LﱒT$**G]8_QW)h)ڇUs0sQNWP$'QQ<*7yUϫ~?d=Ԋe4<ąјbD'8n!DE"DEDE   *GFhA3Ⱥskľ] t8ngS<ΣyC)7}dLܑu[`xiɱBW TnvT8DEpP ۦ[h߭0?Ҍ;DEpyֹҰg($̻jw$**GR8o |YZgMRnhwKpsP"K7'C RP2DEp ^y>{>z7NJ㭐I4"QQ<*7yCi'F('*._q HTT8 p^m'L CCrH$%( gm@nJ, ET[p9эB?ΣyC,Oݯ'(=EPz Rԣ)lsÍrԋPHPYr|`MO!Q-4AHTA Q QA"QA"QAp0{aqi$VԔ^0Y`kx$7"Iw{ATH!k~,vɻ5KŨ{x zSITT8(LJsY<2b $t2{{ Ntg!.=@ox͍k\sy]}$A8XES11uXnJ%Ay/R<Bɳ\9n鼅"v4ܐ5HY{9(y[hzotw(6;q8nnTA׽~G ׏DE^yڢ:\n駈`ʞC??0~WL-?FNH?SK[0YW7b ޲&,DE^yU g'O(N2RϐGx;#t]("Nr{I };o糧68Uކv74@!ŹX{I9ݽ1oz8I'nX}( ˛Pm^ $'QQ἗pW̵ SĎg g8ٛ.4+hKUL`b '1[r4.DE^y|8ZB̳ 마&Ktv#Z4 _q/[GhϠNV=~&tpދ_8 |#YտpS=_ĎSG.t T"QUJ7`sT(*'#[=Kd>؄oK(}"HTT8*LJsttB_H;|ZqS5J}}I;wDӸҦJ=D?ξ;'⊸ uoܗyX3ۖ*{ HT$* HTAHTA Qb ,\؄$C2 Q黄8YYؾl#LI9(,Pt HTCY f.Xd19 fLsj;3uEȦLj|`9_Q(OF(Az[h1cJR1X0}|W^#SʉUg'ߥXܼ\dlD ԳES#ظ %ss.e,<8&[3 $F"`*Nm s3ӴseˌS:lIDnf0Xb¼ݒٹEVz,F<: hf>QSA \DRrݕVLV,PaBprh+/)[SW@X[W9yoVym7m0ӱ-K%‚mX9UarվdG{J䕍p\t$'%#=KFHUqa\{ؖΉ@_  QxQ "N2STcS w!ƚZ: 8i3t]n;a(c(-BUbeV R)+t*wm9ܗ*+H^n8-J1ŀ[. lUIS525" ["U>8ccJk:A BrDEB8I"'>"@O>+o-f3Q%0ִ5~JLy1aCTڣ a &cv&p3MJeRmg נH./و[Tʲ m ]$HT#?Gŷ*4K]@DkrT2m>Uo P= c2Oª i8"^P7w\;.D2\x}(E _e&!\qSgcfa*Ao0yWv<ΝXVЏDΥj4]@tj+~?O! !_ pRJ|3OP&ǂ&$Q3}C*ilO@,;vݮ5,I)IJ3=3yy8WP-nQ.?3rTtDy|ٕLg HߖN">p9{}NT0ΉB*!r'l@L&$ bJOGF*L,w: ը+s),źtd ?/ [7"ۺs3uƼeHE^^6'Uqf #iKr󐝞:9h0 T @{\p[#'򐓑-U^Q&"i;'L$o {: =:rTSqkg1rTA"Q Xm۳UafnlDE$_ST&Xf!+y=BYA4$* QA"QA"DE"Dܢ18_*Em B*<(y6IoCF}ׄL-|̝jHh,-$C H!n,(|p4? `5g-qҖJ

6m0/*[ w n-̽z i+jJ/`zO-@=&^J/kYng-F$ *c[pA鼳P$nEgq GR[ yJfBL >IYE!aX<R}󬃰#l@+nĄ#2$pbxA=q!zkn4v_kN!f閩Ky4Ip45_  nwo~% ]A(?Á;nQT /c= BW T| $'QO(-1{C(a~:S}Y n2QQ 'P5[\吞^UhOYOVEخRu$Nwޞ~pCր#f]#@jyJ"_hE&d&{*#*K#58)FJ~ uG+~<zqiF`&QR[pg'p6v>dr: z22=aȝHC?h8=:jP~D5lv?C$.yY9ɅXq;P*{md]c]S.7xpm2Q4Vwgjy~a=6~Bm[K埄u9D<:IT#VT|-:mqbv6˹pjI*WG@ hanaZ"z|h`:^BUwQ `hjss5܉4 ̺in NK!=vZ'(3Kɝf7ӂ{-0$יF "^Ar,Fof䁤 hlSWf,&);hwKe<ݮd3K.#Y6GZH/ ƾR4gm`w9Ow%eM8eLͱ|8ZB̳  F('*.^q HT#qYT .g"KsY'sIb8#-u  !=[!u:0 ×2^Zpkd.a waUPӾcY=N8<:c_(VǥԤh<׉a_n4Aro͞WD㑬W=mG$8iNXTwk!8*p Pб ]rr4^(CDPx]`|ZqS5J}}Id6K7Z!ף{X:Q46_9 d:BlU?c$ŵhpJ/Djz4ŃMp.~Qz i*Kbt HT$* HTAHTA Q Q QA"QA"QA"DE"DEDEDE   A$A/'FTA$* HT$* HTA$* HTA/|M_B Wo+B#JTcƌQ+0}tXzw"~%^wĉٕ)S`kkK WXQ/;Dņ!3wԯċxHQ xY~%F;bGT 舊/DE$VVV `}֟_znQهpnr| C߯Έ;#E۝b3Ⱦ)C(ӉDzPȽֈ8qVG#zM<>o`/U~u¦Rh>DUĉpKח;~G}Ȥo3.giKq)7⒢M_w[Vn"n=ADvY *oF,pU-2Z*Qt8s։sk"U@!m“3z:5ZMD[x \!ESuNskxtO۔7WƚV 'Qƽnկ+*T%Aj_TV" xP'L\`=pM&xc\G$+u{D+dWRnM'rJ_QM6 ]ϟ8Y_qG(t ʴPɧL`Y@w26]C]_C?lDdXD[>Z\%9vJ| ʶ`-Ə~A {me[#h",4N~ri\E #qbfa}֟zlD%;(nDoh}O&*[k/l9WYq–mĮ5^D, uNm,)kq(N՞B|T|u_/$8rH/C=~GLxr c}N iV'ϗNFkQܭۙ|!䦽4l9٭<̶%Zr]A4em$$F**vA1ħ75'E]M%*ېWe]_/*<[ =^Zヂf45oâ8=_瞓s>}BZZo7_әS4Du#9 HGy~ _;W6d~ks裝]3ϬʚǕS_dß̃p8p8.*EU͢*[n/ݾ4n?/mpXp+uKT^ <@xѸu})<5[*)Y?( DGsX> -uGTEmj{{{NqqqcKa +1S_Jϡh4'L{gۈ"muEQѳUП1mA,IKSDQY[u*v K7ꈓpqG,&eyl2#*\6ޜomEhiD+ԟӊ'\nAcZ_zܼ>]ƍK.xwIO.3϶]*1[~X7ee!iqUT~qE $IYeikڮkIQj"/iJ|Le%gVִhchvqs/~eY#*sq^ܶՒYD2?PQwGbK;۠!#g=#$k+*[͛5%Eټ3im5~b=@~z~{"E~& k*v? Aކ03nʿBұJq1/uh m:gHuz赹{]0 nvku@qHg̳)}Mк7+F.2/9?GPHrjCcVD'fK-lРY**:gE':jpCMݱ3'MKX^qy#I*.A wITS@g*sBTyݶe5GױeL\{.ñswq˕3y&L[Og.TT[}wݣ9^ 'ǶsVnJ> q*q̝O§; ?8L"2~q<-~VOMFDX*iNTTRM6Ű!E44*a76ս7=Q\ [3BmN&NO@xuyQ1óoK0;IK줲F$!?*}OLyisO'h3N/<2h'sbXUb{+6ުM%C[2ŘcΠ ]Y9(I0Oc}lēP(f>y %x&vr P{)uU׬bq Oq +]hj{ڕE, WsuAԚp^BdƮyna_{O}6LQ'EELo90 C~~W"Q߲ 4g]1$;ɄU5"apeڕO%]( kԼ8%F_~sX ר2\u ziTnJ{1=fN*kˉjHh():%X )CbjdCѰ'k-i# IDV(GL֔o\] Ut"*5SF=xnPQhP/"؍0gl_B/Ǒ2^"*SZ×Lo۵-$嚉p%م9fB!vG"8WQd`dܾ+fAm+"!(*~0_'1,CVVUP84KQ+LYsym+`o%-mk{f90چǂ/c`"ȯhe/SƋbX+W%WVU3ٟ!ݫCTtH'qNo7dRQa ͸V` wdA_x;_tA4gagCEH\ Q  ^fQM't\^VP2m 6!8*6痈jy⑜GF_DM.;( [Ɩh߲О)h^AT%r#jH4j۷GJ5iD̦䲖PydX,q[~D!G3IYM,9RWbF\$&ZYXRF9h- :HL;R]] y+I9\FF.Hpgo\dؙ;ju>*FQs0y bYwSTV|4~ֈ1 FY5LBb"~EԸ|W&_/FnLPDnN2*kbCVa|q2}#2b'B?ѧ}SA>K1ccI[JOr"Aw+LcRlKD5t>ݭ7|յB;Ng 1KGLپLEQQ߅Ew~b>.)Ɋ~,3YI :;?EEoA禪?bW'L#C]cd|u#SNM\>l"A7~8?.nhœ1teiP x~ _;Q q _v`:5RՒBʪznKY[ tyxCk"Tu|{.Y/Bld[V u(=-޾!<;[ǔȑ΁:3SnxM5?:[ľW_4/B4XT[~QͅVo@Oe-()k|i3rma?]bH.%3!f:L//`ڵkrՅ] y)jl552ga!ɒ,ɺ@٣gSMĖv@쩈@CӚdItH&nu -kmuUFT*U˚Rz-LMJ<>vG<"& }O$MU%Q "r[%zn[4N\f\4f(DՄUFT8IgωI補Y?KиYsVgYUU%%*Eṙs%G!#tdFŸpjI)g:J\.+*{'é)Q7{[;EpjJT?ɢjȈʟ<~ԀM1ٳ(?- 섺MrAu63j )QT`*kdBodW:2Y,-9̘b+ϻ0SGFP홡^+!HJΦ]zOfhJV{3f(( Kΰdiu0quވ1]8NTdL:0r3(YPP3qnJR 3JV fH(Kg$/S1ln!^ FPl%IU&7$7QGfdՐɮ+0Vs#ivR,68N݄˭)0,LseO΢?$7MJmFXH\Z03él~HLMԘیI?\YѕgpIENDB`backintime-1.5.4/doc/manual/src/_images/document-new.svg000066400000000000000000000104651477034762000232120ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/document-new_btn.svg000066400000000000000000000163071477034762000240560ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/document-revert.svg000066400000000000000000000137741477034762000237360ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/document-revert_btn.svg000066400000000000000000000177231477034762000245770ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/document-save.svg000066400000000000000000000173741477034762000233650ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/document-save_btn.svg000066400000000000000000000302001477034762000242070ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/edit-delete.svg000066400000000000000000000115121477034762000227640ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/edit-delete_btn.svg000066400000000000000000000151741477034762000236370ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/edit-undo.svg000066400000000000000000000071221477034762000224710ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/edit-undo_btn.svg000066400000000000000000000160621477034762000233370ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/file-manager.svg000066400000000000000000000322221477034762000231270ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/file-manager_btn.svg000066400000000000000000000325131477034762000237750ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/folder.svg000066400000000000000000000266301477034762000220610ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/folder_btn.svg000066400000000000000000000226001477034762000227150ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/go-up.svg000066400000000000000000000034411477034762000216300ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/go-up_btn.svg000066400000000000000000000103401477034762000224670ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/gtk-edit.svg000066400000000000000000000204551477034762000223150ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/gtk-edit_btn.svg000066400000000000000000000314271477034762000231610ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/gtk-preferences.svg000066400000000000000000000252761477034762000236770ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/gtk-preferences_btn.svg000066400000000000000000000311521477034762000245300ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/help-contents.svg000066400000000000000000000053001477034762000233600ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/help-contents_btn.svg000066400000000000000000000122451477034762000242310ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/light/000077500000000000000000000000001477034762000211655ustar00rootroot00000000000000backintime-1.5.4/doc/manual/src/_images/light/last_log_view.png000066400000000000000000002532651477034762000245460ustar00rootroot00000000000000PNG  IHDR4+9܍sBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:27:45 CESTCViUIDATxXWۆCBG]kb(vc1j4Ė[D{XP]D,w,ذ`eebKv̙3gg{{|gYaCCC& a#`N^'"rB!Bd1ű~ ;O؈KXrrc8rc(6HM*e$2$&H^ҢoOD7AB!BG]}EG,8&#=Lz2cLdW$/ B" !B!T.~4sF/b % G/:bя~p&=1Kfģ22hL@% 2t:!B!|ra+, %bOE3Hj̒Wj*sl޽מ?211Q%@VB!B#h\A wᆭq% RLI93bq3 YD*J˗*O"66B!BhA gи!߿q -CFDѹU_27Խ0k 4^+t;vGĤMY, ͓]:}7A=?4} wE#xQthu~оc{kqqD'sNO?oQ1^vvT'?7h zm?N;3xSm>ԣڲ-FO_o݌ۄ2c?Lc#<(391b1Gf4h4Ch*H;ϣI5&MtB&SڢaVhۮ 7|;X\w]4iݻEֿ"hƻ툎;1AЩM=N;7޾MЮkwtlM)"hDomi7 G'=_I/9gtFhд:y5+hڢ9Fl\[GFn C¶V>[Lā(GBd4_/2evNh*9xMΟѬ(P^9HBRbjs:$Zl\ᬜHh@Bȇ!IK$;OJmwC)B}{hyͻ~X7(9/uEhO|=<:nQ_f#m l>F2h-L(S?751\ &ǵ-N Ьq}OtW[oǿp<:7@}b !$y4EBS.δ5 g(4!&x7ݏʱݾ kGаy{t;v܈ 0Vh#VM~Q Bpnt.53_#5 e#x(l~mˏxtQv/]sܘ#'IO: Zj1n_Ҳ VV |k]b"Iy"RWAt47.sc hh6BHrqTTESBS`35 gE+}I!=bp/ D]Š~ fLy !{e[f4e-|)Z鬴JgBfDhPh!1|5F6mТ~^Xr$O;wdYf45w;FqBysa8:j~k:o}!H#39!4%to?:B!b8ƜnjcΜBS],2:W1*4B!BHf,yAyѠo-͜M0&4E(4B!M:BSBC!B MxQh!B!xB!B!BG 4)4B!|N!B!|@qy-!B!}@!B!Ph(4B! !B!Ph!B! !B!BC!B!B!BB!B(4B!BB!B(4Wɓعs'!B!$hbk׮Qhޗ̄??O\t)RC{?B!BH)4͐;!B!9&֦Ph!BPh(4B!PhrCڵ=&I|/+/C B!iIgwoÉH{p }#A!B2'&4O\S Pxa$*`~h8^M+4+,?30/pz+ELYjaJaRBC!BkB#6:Ç[ϡ6L9FR'l6ؗcxQw5^ A{.@sO d}k"ߺ VF@Gh!BOhugkRMC)FCK$=9l~'عë`K*W}c[Fi8ɭ!ˋނ*B#;RW sAb-snpwZ㖦 >]a#gx q2czG+ 6 l\'AM?7FYwa;R;a_q[nEdW;XMtRΤ+2 ( #FpcjC{aeN(y;Ly,}ʳ3Ѯv9m5.EQ|6e;ocq|no[ae(Vn{\ۧ'0Wt}xK·+)B)IB!$l܌Xz4Gwx%n'/X }5 ڋW$pB1+3 o @=g)M0C*B^_ }2_]3r97`H!BȧF\vsh䭰敹B6,!UK%2AYI93{_>y7iтmB.K=Dʎ9U': Z@Zq,.*Y*׾D؄ʐŚG.:IL}ֶuq 9*sFV md?a4B QZQg&), IMԴf|[?k}9 )BiFH Bb:B!iӦT2=k>ayNqbUYnQ R +Hd2Hai;r fZhF}޷B*oOM [ER橌?ž* V,,`a O3JДL ăW@J/ieCU{1< 䁭u1t4D;9dv1^h#%qw{DmJh aۼd6Q/Xvx!BygRc|B94F洚SWp劈 }ɂД~cB4]w @y0ڭ {B&UYJKpN{nǤQ#Mj# .@v$c <$l"N񢆐"P#4'zHlZh2Wu`!, g+;x} Qjt!BrMX"4GǠ$QELG 8}}:/l5xBtp)uT?߭] - +2}}%͜!+.+r6 Ɣ@Z?Ǩ&4 (/ծ]+rF $4 HS2H7(5O:B!!Zy2QE80AbC15k ƪ}!ؽ~!]Vtr{ {ĞEc.6!4qXdYA<aReRh83sٖB7 N, w'f\hԈ:DZ3gq"xT|ee??< ;Z®DS [vM0ct/ zuFB~. spj}/4oϰOQHM9wD4Yh2[1gf;K熍;ؓ׷>< ,[>#:}1w3Zm@,}f"T#n.P}.Gf4&|ӾA¹ lc2^^W= ͚W)pinT'췥%$(d0_3R笠‹ˁ2Y[A%k 7Pڶ^?p k<`\*((vB m'tB>NW+X=1*Fbj_.H}bN`^q({T%l诨_vKXɜQjk캗YB!aĄӵFvkV'P=!B(4 NjW7]8x$__[ܵ?P}!B(4 G) WܰJ sD1Gg!B(4 !B!/'NJ"B!0XBv.\4iB!B>%5{ B!B&άPh!B!4B!BBC!BB!BB!BB!B(4i9r!B!Z%!B!$@!B!Ph(4B! !B!BC!B!Ph(4B! ";4(B^ٗmk `#or<%nnN:S:"puw^RK |fTw0 X;[FVӺk SGbYs}ǝOSg7`L($>Tn*e%B]ah +|&I}q); X}"?H[ȝh\`#> X/)Nꅜ`c F|淙Q9X;jz僓LS~Tn1dn;;$<.w.`{DϨpgAC8[Z­n$CklA|NWF>ۇB!߄ X;Z955sB>&x@^wvUC%][`e÷ՋK}WS8ubTiaUx2m|w"n΁(-{B+ZEjMM/bmBh4m|ﮍOwwQ)+vK7bڅ}h[T8 ׶\Y QA]PÃ@ha 4W‚ ߠZ}Lk!;FMУ=eGX\fgF9а z 9Ѫ-$EzaS:f)8Cnc0cj,#I -5^yVt/\Vٖ:sZN W1 )-gBg旝rONAIͻrwo^?'FT@oҒVJ;ߝ]N-:geN;!Ph+4-Š5P62{siQ8 ]Rk<=W'JEOFEF|U~J(2nF \5f3-0_u}``OfmϋA.c h6t=ľX5P-aƨPf&F\NMM92ع{kRMb4=PRe".+pW*trA /Ҽf޾ ݙCߠ#mMqS|>l?^_bbOcҾfe4lyy +5Bټٸdj\6?DZ6զzcaٺcxצTԩ36I?pXn2a]Er=RVPe Q/:OIH%4o.`zw8}> !EAVcrl-*::L޵~KQxm1}H{YFbgx%vG 啹i(- Ďرj)B#{2r6kCdBH25^xKѣ-r՟:T%%C88|%]B UOw03(s<~3̳#?2#oY/3u|)wI1tDQX!?;S9-q{_ d.hfn++{ި㒏1!w"4 Dt.z|OߣBP'g8u k-2**DumaSs*&QUҸJ˪:_AoxYŠCw/yɟq\az|DQ*Dîcベf2/m{|'İR%G@5V'Oʐ:ƚTwJs*L-_0B#{ #w`3_;KhM',E?zH Ա戯VDg)2GhI:߱l [e, `ač{`nTaO9p D*]ХJQ y0И[Xê zt=`9WZXo=Ki}!)^ЏŅ>7b/u3GA3SN5­0/XY&$#&V *tJy:<.E m:[ g32,li| мQ>}(8 ɁWnDk|Y"/dX _wB#)Zu CjU}\_C[{)jq+hLϦ>=][]F Ĝ4'8@aqrFzqN/&VdI`aA Tr4#QG+c<' ie LIJA(,-߁$`Px\R8g#4hX}f}CGhw$o}AmPp@hFdM?}D<>sGZE]qP(O_]`+C&Ҫ&QGV{( Fh<g3HOH> (i W8P`ŝ,ՅYYɸ8z } ;:ws!`1_}ETwÒbnֶR /p=zøo)gL9NmHqe\rNPkFEy8ԘȹYJ"HL/02SAI_vXYo)ҙyиvǎ60_гa~]!qIHZc记"4Vk_\}1 +L_@yq9#7OSBx~cKgfއ$"_XYZC*K5ek&Л#4o_W47X0*JZۢᢇm*/v=B u1y'F x6И]rѥ_ڀH SrfY&QGB\RTed6|Qsxza'>Fm@7E˗OC1nB̫,mé(#qGm/%馶v~ø)g)gJHS\2ԙ!Yy[Af(4R/ ?K 5&_Lb-?VRq51 YR$ʎh.6$ D44CՈU?0RCc .=!AFhb6g0ALR}f\Eм3٨+G(=%- =gGK.&m Rd>EҔIc"TCZ (. $skѝO􇗝/ 7^(p!M]32CJ}xĮYQKo[i7L9#L9Pǚr&hB&b;{XBj(4ɫj)t"0{Lu>gH!"T #;S#,k CtEQ˚Q&3{I"BTȖ$;džW&.f{B9і#@}i/ snIgs&(.+gMlW/¢"2 U( \R)qqlEK E :dVifX Q$$,>Ɠ n;Yxv^٠$Ԩ΃5J ;n_7LLͅi/FMd9#㰞 ѥ5r5G(1綕r3 b^32ږ+gۇ)gL9#-۬p8$^nb/M;B#~MY5RBR̓}wjML,98;_5lĞ}A|"Cѧ\s҄*3N?AB|h4 8j bϚ4/[xh,֮ڽ[ҮV\~>Ђҕ+\~Rab=c~/4oW9f µoCCbpq ƃ؉ˈ%X v%[%[?x'L|0h[|i^l? 4݈a+:po/=Բ\6p)j&_<]*9ʥNиЁ(*+..yk ag䡠QE >lihֵ{xID}-4 \[%vð_g`%1*8[B^~$IFa˰y t/yPp&k4UN(FM%˱h`4+iK:#LaD}u|WDyo0}/Y\ 3zK ZT$SKʛ9ۇB!shw`hpIaQFmiCL<@c\AWJp𬀦C#8Ǧk"pKa .sqyus:WE~ ,-3e^Ioξ#4/B!5`il6C'YiH--sKS Q1#d2{)Zz&G݌gF{IU3ou47w{mt(Bp@色}1DLJЦ~S3;\(Zl:Ǝ:@vsh2mQq4l9Jx䂍DKϱ6^Y ; I8kʠs}!B>1,#$P"|j Wf?ԑȩƱ=!Ph(4Phr4؎ل)4H/O.>39BPh #v[oJ(;k/a[B!B!BBC!BPh!B!B!BBC!BPh!B!4B!BB!BB!B(4B!BB!BB!B(4B!BBC!BB!B(4B!BBC!BB!B(4B!BBC!BPh!B!jIn3֨p ¹`k2fA{2s`i5ᦊ}lͱZG%^zc,|^uQ_S~`;I0]ۦbx~GuNQ {u:EQZ^N'jWG-DYR~fa+WhW\~(pfm7R||guP??am3|;CnBk#D\V~z>ao/an6|n :qGe5l!!r3\Zm _D^)$\(R#&ghSr;c<2SR"lBe]|(BKcR5U{+ HӴEuX Gm35WFQ7;H$p+3"ZO<y^f5}q^\QP39ë.ͰDUQ*kqv&91t YnjS"i8Ēvo~] VbƨN(RO</`H}8v\B CXLJ.t.Xյ2&L{BcC.9y4/H*MX1c:VruZ|6. xuVbcgw8ԟ2F}amؼv6(:FeQ(qyWz.WPxFZ mö-dB'uݗqQn꡺;>|@Wp/$3ޕ{`%4WD6*QƔEaPŦ(|[ y˱zt nPRyymym}߅м'r\h^a_B6WڍIPh!]FB"\.Lwy=bm+IDeF vdJtPGcq#IɰPAvM'X*L=!)6Rnmp a(%-1todX WXNűš"ŸTޔ3Bk8ºp4мPP.!XvBr o6#äFj?~AQg9lݼxM3?_W{# R||&, ܽhzE4av_( pr{y"#77cT(ܩ0j3MȊ2Skآ@=xix.1wyah +kVFR5L&1:\#dPi=OSN@7ӯ*/cBIKR ??L*[fmϋA.|OU@q-.u6#ߓJC5 Ew X,k*u_p^ap{'Gۺh6e>LhWd9Cu/u]Y QnϪ]1g~߯+ÿba`h7*D@;k 9D; M8>?3=ⱽ ,Hʙ\sˬ^IȑdLIu3k=^Ƅ&)u*nOUowKQI^?PKkWAxI\Q?zHH?p@MFً"]myC|1Sh18>|K憭ec;R ]l!͍⵻Ï F7‘M#Ѭ6Uǭt,&"VTŘ߫& ;aVf=Ι˚BRc$5ˬr4[0j XA647=0me_9wܓK_)7/z/:'Jgڣl\sxƵۊ;x'!}=-Sb 7z Ջ pWFeF]tXt z0~;yKz8DehV?N?VR/)EyVZ<m{S'gH ""'A2Ch*G{z`ߛ:Z@)Og^toay -;gׂ[6ֈb 5ΫF?Ig8?'m`|FP5%LRNz#>o׀ԡ=_%jChDž˦ШncW殎gn1:MsXx6n G<|cóKK[~#>CP ugxgXAj-0vl^2ur[_p՝%h*(ع[fʎRzqFbۚ$}Xuq@UICuft+,cn'v%l~CP\^ c/H)\+Wt_>epmD4}(ɲ&4 CX9d5-]_|RދCe}ੰʛsÍgeTh㳣\ _HR\4Ӗb`X5-ڢX`ۼ:g\Ei:;ޜ;FFy *J nĒ!{2r6kCdB܊0LnY֘n8ׇ1 Uza}:ut%0zJ1vlb9кd7,޾[CLܼk:"w{s9Iϛ+itV d9WP#OcNKOHKt1U-`'q 1VrMN3(7coa7Ѹq wގƮ#:"&Dž)5(ae6,T *#L|{vl^-{q`F\aMU(U]gp93 _ rG/t^x {hWRU:䦄&rOk~Xycػq*ڕs 1نݽ6g[Ww5lmǒuf큎I|Ʋ{GGC)aob%w5:r"tؠxX}6Qo((QBo@R2 74~;cRdNqfny9v9M?,P r&VMyc)%=W^H(\K|Bh %޼| p8K9H:aS}:An *}S2I9)E~DEtFh6 ލuSFYPTHx /ǹ;tRRضߐ'KAf]F7j[ R8~iRHo\Qo|lڷ;zW r֡=JۋgjKGІW?"4 8`"Y?$:Z0IwzN]%s[{g{lh sXEmϓİR!ЉU G!uj5aQI7 %bU(QX 'S.TieRoBMML33'״ Ƌ@PQ`%VUebQM9{utCB0 ~#?;ѣ)8I93UNRݞ {j:Ӯ˗xu;_r>I2 2$yW)}C8ixϾ} JBHJZbLhLoTxeԝmu}&; PňV'jԜ(@HPebJu~( {K'4&X%^Ž3ѫ Jڂ MQTLJ.eCnn/(/lcQþШcף^ÎMw.ֳG;S&X:mPC*c)aFXDĦ6{j:8ڠaṙ-MamhL&Ѣ>H,{zʍ<9PsoAH?f. \'f׵MͩH^W R)-f7馜9/}!zwMuOe,XyǺkh%ל[xSxH/kej3­UC1`b؍m+'k%gXVŸ LiЁ("-W Al 8eu 8!{\ 47>( +As#Q8jeqh_tt58i纾af9XxY%[ؠX.tn wb%h]?"4ShԽ'vg@}LB#b2./״Ҧb- ˃9~.mkZB33<m*-u)g[8!)0<N >D=J&ˤA)N/&QeI}Ggf)r5T6Lʙ~,InT oӌx 6 wfxCjk+ٽلNRAµwiPx;\eGho+<(O_!Ҫ&&yZF: "N]v¹ҜdFheKH ơ4T\ԫ%Q*VMK&K8BR1F-މS7cM.b^`;z]?q#MXh"T^)mbSy|r;A|.C.ȸ'DJNP)x Q[iFIܥU0!Ltc̘d׆fZmФS}WrcΥJLEǪ|.Ջ[VV4K8=ו&94 Fqa|4}iysriUQ&Rٹ vCwer@тT M&%>o=^ycW&&弍C )^__ep|eXYUDę#8KF7EQh8;LwR#fc'[G٧n.1 o),EsVZvj-<% [PZ\D3QXs|׿Y`4,`ҽcRS[;DTR&|}\B#7| G7fU E?*w Ir̯/\gKބ$qH2&VCy;@.)wXda%G ,dh?GlPz@6va,*I,bO:e2LZuw4u]Lb u=M;3>d4[h2S Q9IU1s?'/Vl |_+Fr蔼I5V?MkshoK/v=¾DU>JI=<0:l·I}NXLM}OxW91ЁC5ʅR9s(ǔ(& Ǩ=i5'U[nh>ȍ&nC{ZXBܢtKXkQ%}1oq\|W6OqA=)pʉ/(G72)4(uOt,7Cڔ0c2tvdL*m캐[WcUOnἹ\_& :RsSV# L֦f"hQ!Ⱦ'4R5BYK#60]wTTѥ7 bQnQ#"jDPQVP IߛSxo?Zь{{O\T˨vu xy!V9S"ڐ3maVd7dF-MHj3.oq: u {ɔ m}aqcNPfQ[=zҲ *M1cxC$,kGot =wd )ݺ:U1d|Ok]gJB &<Z=~@~ayh!%CÁWz"xQqPOct7LcdIr&4Ili -wKR!)@ʟdCDHg. v+ȗ{7!4ڴ#JņXT!'WFS_D hD+›F|F_4ohs)XNcY(x3%9>Jh߯r[ `e*.ر%a^|nHVtD9䟖zh ^F5T|E7פ5daWy2,ߛ/ =47K|?}F,g'8/\UhN8T6d!c<7z- (@IJ/W`I6v2#ÒyclJ4ʠ.d}~\ I}:ςT${9"SDVlsPmr]I;'X՜e߸0HNh$Hmd{31B5Eό$G!dks*7ܶXBpE&JO 74eo[:){e3Gd'7xܤ%VšJP)%""JN@ y) $xr|[{)b>/:B}Y>HTqPe ƎnF+AhJ_z/Yy ohΖ|Cc p77 oh4 : W /*a>>YޕY2D=̖}#&B#{R'v#$ 8F|!ohCo3s {;QpF.)I X,kg&FɑSR*'۱uA${aš_oh1xCN 3^W4o#7Za{P{;*DG70Ǎ{:9)4z_bmqCD/i5Jm̾ Qai΂XQ#Ѧ8lyHTO[8+)B~~aw6g'P >'#!z;Z|&7?^lhZW!}%ohf^Vpe#~wUS/H\XF: (F2wI \ ÷cAhwWf9>`Y4Ÿup:>7φ-jy8 4' vNP`h&øOyk $6i3cשX -r欜LB#=A\8xOǦC1>u0{BbsWg A+#Lĭ{pO.I)Ia+i&,g6"Ei窇 -E#OٍKqs5/tIqOr@ͅh$o|rАk\X0=2’f{knC~\YZ&ӄi3vpx5H}PB#r3GF@u@,;0i<OGhjoBm _ QAQq Q3]&?%YYH_q,QQdF!^L^~ ؎vyg)øoaLCSp M~fU;q$&bH]>,A cJ5JX[ɸ /Ċ`lpMCNh jǚՂ{'Y8%^0lܠ`$_t `EIǐS̔Ø \vOx4MK lWȲ Δ&P [ax?=`Vck-/*}/rf(lJ/]M+<@h> 7%]q:r7A>kL@񚃱$o>)<[ݰز$Boذ1t]?qb|ʼ pt߄@e)֬c1Dò^% kW 3bP|:gtHr6C0Ν Vؼ_R8 hGzILB%#46E^ .BփPxh(Թ:E tGoKFE)>Ƣ3"x;B,Vv aRiIL8}ZPGw;$=s "cqj:L88r5v{4̆- <&0z+ ?7 t럘"4R}}h֭\c+:4I;<(hq逸 .pFy'\!4R/e 4emtYE@ƨf3cv{s*Ɲso7աy\$t!YXRIVl)tt =o|Kt.q3H0fsnM`n24!I)]4 'RLД2f6|x]nF&#{{R%@lo>NihZ! MS%c3Z\=)#)L@-3nq5x,|l`HJj{qIX] 䰽^[)B#}O;dǫX6| Z`57ookȀ0ɼme7wCTfέ0zM:4ՌyN @k$4A7&uhĐ.ءv ~C&#|)K fܕPj vGuK6cJ}ď OK5*Ǟh]g&p黓%V݇Wѫ $e@JdI_u%` laJT5{ǡ9?֢jބv!۽8|xDb36umAl|npcx6{sJ׳0xl+ae7Yhl;3:O&h:t.?I:g:2dB-gndtki5x[oql`a4G0r 4ߕhIoj·2Ϗn^鹸ڳq-[}adA{/0#ao uRנW)P3'a61COSS {U鿵tRq?Ghi2k֦6@NGht|[bmxݽk'֢oM\&eQ7w|ͩUX| pa,l~ťfd:\]SȐ #D':BS FW4+VFˬNt}H@lic){pn:%4S'vhs|}UىhӃ 6v҉|F':щNtD':щNtD':щNtD':щNtD':B]Rt*y~Fqa[UJ,ăeQII9MIiZYJ<ֽcT)[!a k,)k O+o5 X VUYzB~#<) ߲UĘ?#_RSsokH6SsISH_k߿h.Y_XU8M3bJeGq 5]*-KY(+DJaXikofEμ.Žn&0ۭm8M&a}Pa{qy_yOG۠T\,;ѫxA`Gʛe:7 kCl)yÒgJ6#at'O԰䚣F<=TWXDD</G#zc'12.@oTfkXwo+*?GhE6qx6`cqN?5RX0%R`e;RMA$8S ._oDGh{kp.%KvKyQ\^TBSF]ra[72me7sHѕ88 ޛTަаQ8z Œ l/. L^6!@y1ñYu o w+(zm#~8P oBSpiZy@Ehְ^淀xS@A-mEtVQ35Y0b"|a8hАvXO H+Т/ \=|@i˂$4'Z`G3t5s08XР-3~^[_/)ٟTЮ}W$)wBN5^Eg@[;p@4_'Es@P;DuNT.F >aQrQvl8M>'g*wׄljgբ1~/ ЈDSN5L9 v4IXfMD)aW#&#Ri? 9{U[ < 7tJmNhaCz lhU[O1)CU GJTbvz!:,GĖp3k|PG0Fpو`$fh +6at4 %AvEN1@ hB-Pc6\3pfJ-p"xB< I}Pl^tF1l~%k[֏튟jXCS6c?j1f&Мj67nh tJUw>nOR47gmZ,$HC; (Qy>NmQF>lA_P+ ՗N-Ua! 5uB> qiF!dc>X !A`b.Hf+3MhǩAvcj0r`Z 'Wb4RB L1xxTQEpX#_N}0&Lqwl0Lh+WW̨G!ǕѦfHt(J!RFn7UsXu_ˀ5pxյ"~ƖZ bA\'nP՘E=pSZ<3wtYCŨIul:5ĝkїmP5dXV_eϫ]G;W jO0wi1R gUyر;̹㬣Gakm!^-j09ߎ$)Tuy%$ɼjYOPkm]^?/A; {vvsՑCٌ-J6(F * ھh7渁1tK%4 Y ^lW6h)L\7U/m":յt'1  5'˝=J)NK ʼn BnY8n #s".:iZ*\ @HԴ6v<ÖF* Ý`Dg_>S yſ95;F/ ƞӈ?}5I{l|,*Ah.9O&[8{68Fn:S{nq yaC^H\h"4e#~!`YQ8}0}C@h4gF7L*s^b Nڊc12%,X6跿(UW<ĎqhU?rZsL/z3 gy< G#ߨ7l( ]IԞr$sOM 2W8nZ Ʉ3- ¼& WMZjq擪zgX <0%!e'fY0>HXE1/5AiKݣ&0$8!&ʧtBhm"7; _'"Xs\016S3{]~Z╏+Z˜Gq8&'c_Q/DU|Poq˿7Ild}x[SĄυ:ehcjf p_GhNÏPQB$4Lv&Ag{y Ⱥq 4z,xWg9W KiQG1^6nSzMqBw%9LʅWJJvvXDan-k9q5$xA;&ŅěaOk;e_e%}8*.F(=ͧnDJA?1cA8OǥI(;-fxP8㪈naoJ 9NqIaܜXsR6-F6nB`_җWߒG]30i6DD±0Xx3_˾pCdT#arLaβh.aDxZ)6gi3+]@?s5 ={J%J掖%%HM8506Kt?M6vW;<U&J?Lj$N %BC6ZJ2k4+4 4ˋvX|z;)%\0r< #OQ RE| zA)ƴ(=Æ6$xw⃊ݏC=I)Ne }ZܪzDJ"4#zeNpy|-(>yi$4S!ţ,(c!A 'CyZq;K]ۜ%P%YQ,v4)KxMlф ϺV O9ݧ`LP(2>8WsCCߗLONXuHq"NPPNV{  a#}"K)5N>+ FBcAyJb!pjaBEx_Yda@T ’!p{h^"N1w \1D;[ƣkل&?n,숢Rp=ǰEaрmgEYlx,NRՕB9d!Q}EzR«_:)Q"<8Iiw+IG2J[CY˴꫼M)cΏku6(`yJ{U/w*s/xd{3#4Y"J_~8qhoxCSpi  Ix- xCވKWcf ?z?>HHߒ'Ո~i}RōsT\d35F\]_8sbCS/,Ek_' ΎD)io_dJ74}QF y p o#{R4$͓{~JU=HCٷ—k&тДJ {U9~?u"x|cC`0}C#|CZՂ}=zcnt4Lt44e郭[$`A5^L7L~Wp7>'/Τ𔟝Lp:[)s"ED&:rHKBSz;~&`3;%CJ_òEʋД:C˧*a7ŞljZőCaF4)BFFRrCne@-MYI({7l*{:ˆzD =6$&ė2JWzcCE6U0"|y%uhʙ$!1,.aK)Jx#X 2!0ۍtwCBM;Tlh+HB[zRm |Exh4%K@ڎFx(9nķJh{E:ۺ4љE7[2J;ꐪFʛ ,lj8--ĭLZ[C;d#̋OV-)@ފn4R/-t+H&^Q<4*/BSƘ{E~>&s~pf4hLg w͉FXL3v- V7]iJ.%m!Ub&r0,PFLoفTFvOѿ*5 M/CޜMS23> =2ZHօ>,VO,.ygcL? jIBD%ToIm6*)*o<#4G ДEh$k~]pkW6~Nfiΰp7MZbŽ2RIhx/~؛0 B9pgiSZI 1!R|^t&4m3}6)~݌WД2f-ɿ6) ^ 4М-Lponh&4w4u*^ UB|}+Pe{- o ]F,MFtvtIOT>R!>F|!ohCo3s {;QpF.)$GYo޵yq'GN]Kk֟nmVq_L k~Ӿy ' :xK\MohҰ#O^hoIXA7RV0;U `9(JojGt"sdzdz,؏S9lyH,\&뜏 9i 5S?D ˪^'PFpy?!dpIFn/,d*^2I?,wI \ ÷cAhwWf9>`Y4Ÿup:>7φ-jy8 4' vNP`h&E-2S޿ZB#rM̮u*GFK9+g9+Hn~b#ӱP !l< ТYFok4‡kʈS#q=ܓKRbUJ(˙Hf%y!HKшcSv#e\Dl-ybReܓ/ͽV An"aSRּ k9桿9X^Xr\Xw:_2@&TL#Ã!RsY3>H矱<4b+\,g ՕI~u) pGMڇ1 MU&4qSWđ^!uP.8)(c%bn%+Bv?iAXZY<$ 缹 Ftbq|,.r~?Rs rS[ˮB I3!IͰYי2¤ d U;'7ba`LPu-Uoe`^EYt_8rv~^3){|w$ _ƳDӱkT1uR53ÕOXTR쾊. [l<åCqlBLp"0~a|;G +аa#Lؼ_E'LxtQ;$=s "cqj:L8"; e:WG~ShM`bڨ(Ge~hB#57&P`ʥ9H C3{Á6nZ:opZ9bJmtwυ:YB#b\Kj0YFǩ ,Qijf\j.7B#}Ž= h7'OI;0# XbST:"eƯgS՛@Бh)BSxu&j^oVʚ{PqllY)9wѿ%ph<fx/ֶ)EHG{AALV@zH o#>.S/ЧUthE7<>n60$%=\и$?WG 䰽^[)B#O;[kǫX6| Z`57ookȀ0ɼmeqhWj̹FoI[f{@WQۼ:ωhM&[ i}?1 ,x&v3P}|FAn҂5w% _XMTwT``Y=ƪAKpxA{owq]d k: 6p0%*}Q~ l%^хpq7: cT >I8ztI*Z P[ƣC^0qpGwa9 CܠmZ ]asa^ G8O{]:N-w%nltR"a?vI7\\ dٸQݾ0wv^= x89fXPVO]\p \C}xS\P':B#s\wU\._b[rĿ{ޟB/2RǼ k@غnis,E.}t`CMxZTYJhب=v GaFG6FT`&^RY~ X,:7YJt=Zs?щ6we?(d}K c,BC? 40<śpaPwK[&-':&ݷ=mYUvW%Wg}]3 Ydo+[K?c+ Uف`A3`b{7!ypNĮ`OXgsh ss5Qt-j'Yq ق!X19,YFh|۽?ܤ B^+ohNy |.aV]b_ѓuh-У[Xš9q_U,hЉEWXSo U ]/ M-̯A闔Mh*]h?z+T;FX'/<wPŨS9ߗH$։'+L~S^oٰp=1g1:jS_\WC԰Br)lv)8:$oV`X]0Ra= uwb}c#97J~B{6l\ctW&"fɔưvܑKP Qɽ[ŪQ݄?tÆc*)R|e=63. :Mۏ""*]F-C8tX-f‡ #y`8WEH@V)lʃhdJƅ2n0 .cKQ%a3FiݿJ3Sj<QL`Bf#4`+Yw~lWT G0W13i\U tKDKh>cGWqP~8<3ToK,|}ih^%*߉-ˆÇm! s`r=é%Ӡ*,$Nhg!N>-Tҁ|6 aAе!>Leٍf+&~ 8U0hnLm_\Lkv*FK/:B# 20Őy*~RDZ`Q*V_~|s87yT&tBbdF V?R? =l65G`U;G r`6v$ [ Ū]sЭ3̤=6> 4l'- Z= #7 zϩ= (b/Dov.egXp42C{,Za(>>u!`i 4אI"ʜW"mXqLk / gO63iZ\>')\&Ӌ洞̄ovu7*ဲ(o>DW#S&΅a3Cq2 e 0ohë4DcVI.8N)/ SIW1ĝBx@XK~_Eh!]9$mzw2Hڌ Az5MgY^xփB:dVZ0&~fʼn=+0V +Jo9?زb̑)YVT41saY86 D}UA~ BC `?>^+_Bwv"~G..,T{%4Lv&Ag{y Ⱥq 4z,xWg9W KQ}LMhoƆ۬+T|bS{GP] wr}!$yXeDaK}>F\t -I24>gЎfxhIqa f蓴F2hWYIz/ŇNJO{[4CPAXGqaRNllY *콅*[RCx8`R7'㜸M1ɨFT<`{7qCДWLp`&a;z>8+;[Z٢F_#/Dg{6L:nSY8o C9+g'U=/~)wu${ ^mE'Lvc1AJC%&\kIz }_2=:a5Fzׅ#EyHP8aRBAq8Ymir&9'8RS⡐o!4D f_+T0{LA*,W%Bs0a~Nm M~XEjJ~Z hvfp9PdV C(L "$OX߂٪'%nK'4= V'')qt%HFik CV})e1cMTelCp1 ^6F1PD֑2y`Ed^RBtYHKsqG2+qc00%~RDԏAh .c3 , ,Jp{^@ШHG9/ٛ:<#1tX[%|xJ_;,C3`ST6 Ht yd0sqWg)Sw$qq֤8iPJ`sKcZYE7EXw@lUt_IҐ@oވ`Lhi"ʰ,˙ǯpQœ4^(U.'ъqv&JICx SJ5+TۀUxܓ!YddmS°AJʾX3TKݯ,g8X, @PsKelE϶(OOl"!01M6"fq`Xq? ~q&Հހg"MJ)"2ёGZɍ3)ea7,rV-U^1B_>W>V |-/d+U /Do 3Mh/% z0`}? t@-MYI(P{7l*{:ˆzD =6$&ė222I86lԜqҗn~/wOz5a_Z77 kgneBymmQ[I_#zv XeXUbƪ˩yXxޑ0TQ(І~7ۼ?eϿd15`Pϰo0,? 4ctŎtMhzh"4[,Cp<ij +~}_/4a=E5p%KД3)HB`KcX4n7|]@:/ IR$F$eB:sa[)Gܻ ѦQ*6zp -=)"<4%Z mG#Z <ޜ7[%4Z̽yCCm]Lr̢G-ω|uHUB~hnDV@}p\-`ࡉ ['xIoI7MTCih:Hh$^KuɇPt{MZCff})c"^?Hl~C? 8YysAkor&|3…;XUčCUn#,M0ҚD%[݋ɰclJ4ePؒ V} >La.-؁.HY*Za9ͶeAz*=􂱱?":L'O{KScFj: H4[VIa6 #}X]uXTgnA0Pz*vU݉u+*&"**nJjf|;0ufW?<ƙ]kֻWmdxS>_IÖ[SJȒpZ`MB@G?8HF .@#^k> sK<G4gjMN7֔x+S1i+ y8\ ^ ~)?/*@}A2Lp*zlMkl`#5@ezy*J+d%h4МVRR pè 9 `ܵ:Y)`zn\tI~W C)L;:wIgP9G/H3`3=аh|؍VJu8.! zy£  hq-<>:Nq-:P 1Rv_t k~/)chш`g\WS M:V5eʇA2{r^«ɖYwrd'KXi>cok0=göD@O ;Ԡ{}["ٖ+{BXlzpY>q@:!MLaN/+WBABS ^D(e#ږMR*DK"F|XRL,jaYr&xн8"`)\4f;O|R *f9O >&9xϑg9N8w,B g R8hH~%A%veٞ܂u`T{ȿ;gr 7lѶ2pFPEaX8OA l:E%a7uۼ!W~\$΢ {2bt]!wk k=\Xam+x[[0wc0QqHڔjJTԯh$1WiKVT uhkr'x'"EGO?4DY25XȦ< X1. OEX,p(yF; GE+X\kEYHɕ[m`s&Zˠ:4EdLkz4Q }aٔ c#._.c#s.fsIP U0h:vP~ MAFp5enyGWLh3vт>>k|.1@#ɈxY`ˡvlyt}Iފ ]`*k CENS*Ƌ_U#{KTj4a QdTePե[Ƭ蚻n~i4$er 6:e)+ՑP[q<3!>՜`I ~:GnPzh2m11b=›E5UP©γ;.OGŵ=~XuuqɓY\ظĘ]WJH2?SGV#kcޱAfc i:}љW]};||mX5Ѝ)Є)=vz\4ax!C5[.  'TkIWc4i76&e&ۄbꠒ,&vZbR}$o u3fDt)NqjvՄ6t*|I~n|X;@1/HEW6DŢ|ti1M5؈k9Ee犭G*[ >lZ}QRM%h~*bc2',kă#Rˏa^鹸<jSq9Gw̖߹yQ/ 7k& V1GPљ NHl?^G%:G?j_*=h%Yxmm9Ց~jH#e @2ЏE8vVF%۸|d%Wʘ438n9 sGҵ;u~?u| ?#aX3ߠ#@@SFWpO}ӂH/n#e/ @9(C:^e[YLc;qa h>6]aeeڝgPzOWٞf0L8k-nf 42 d @2 h d @2 d @2 d @2U&>z,嘣\rZ!mSF%]fU'*V0끽ŕn@Sp~z B۲4TkX~)k.)MP@$HoN%>z_BksF9gN"jn;ghٽo'|Fΰ`ѬG}ʅxwbz 30ݧRJ[1aI8} \{B)y1-bފ ܱK7 M-tfƾ`roo0ͪՈض0|}:+ԡcLOrˣ;%CEQԪ|¬κnWX[Ö(S@C1/a+Rb_P4; +,Ua͜hU ' k-bx`ڕN< ~n@SDn)#*q@_~(VXqal~ڋT5zۂF/=27#]X~U/‡KCTس4c{g3#YhFXXlh\OE_/h>aW30<249=5ޮl[z ʮ>J3u8, ,pm=a2\V\u'PDRhO⋫пa%Xq{̈́=H-@գmlۧ+<,LQbDo O LǩOr0fzٌa^ õ `E.=,UAR?&U&BѫKLb"? 3Fp3)Mʕ(z6Nj)0XY4{EhniIc+iۢb=L :BI{p?W1i\s*lQ=qPE: P  Z,*d߭.ʛ6uB?*݆+\~['*cb>]} ؂]|68m.>-TyܡZ¼J7E/C;#Z.o[.gkKؠ߲*9,Jܵ H]M,px+;PP.(|uR/_,5\kcX2P_XQ{(VW̸p5M@#kyUp\W((.쫵r 34<6QEM R>mPOIl0dw긠82Xo#s A9V ̺QQW823qPi҂T\~ȿ(1󬾀ؘ#bpchaP.;cζX2MlpWl lA{k&@xĮ/3JVkЮѨ6$9mLyT@ L쇐#8]pEIXu0 (('dts`úKF>>OGڣs6@C^.6R>pl,o/ &xr68><ދA̤֔-p>Q-(a6ސsO{QlT{sOKr0Wxm75guuxH|i@S8Tb5lฌFRijG?9pPŪ4YzYYx5RA*U RSpv,*ưA Jr3^:}=aͪC*ޅs8 &ܗ&q/% dw Wg7Tl;y ^s^R)a{G:_(O~s/aYgv`hM+x +WWf;:ޘdΩu݀Fqr_Smɇà#Ssu:18[JA^Iώ1.$SYX@jC}ދfPi#z\.Z?lJ@y iXgKWR%6sA4])!u~Ќd^ W7B;5#=i#~c̴?\jlxNJYΊg1mPwU@C'M݊G/s RIP=r3fS[hSc_ @K` ɪI 4n%'+ |1G<1 L\(-kr3J=#MB[ڙ36G5&tf"nx~ hÉU^5?pa^&d>Aq1SEɑˤas-8h챚U_;N!gyc~?nE{6ж4WI-cΏ0j̺6(}`y [ .%ֽ4YQb/?q8~vot79-CtR2^f 4?4EtUQ 1e]DMWqO`}wǫapCQO:=*]"=an3 j4xJW$߰٬ Ј~_I8-3ۣ$kNd%xվ|0(f@MY0"+| KIѐh9@CB H,4l] dzKJ~7٘cOL\:4% h ÓWc^ hҐ qR?gCÖGuC@O;4nCX%@=)4,4&Z` CdFkE y.7ugxQe0~X@#kv&Bs {plk*^hE2/H yq5ФcUs>\|[$c)%:*l5Z~'Gv&?1F708+gzW 1]Xd(>͡>q߳8{A6=O䝼%DSLqd_OtzL0x!L'Ba )`f!}yO7X'-QBX.G-4Mź6v07cOT8OMgQ3˙16#BDb<Tr܈r6{%b "c_H7TaT`OIFl$˙SY~$ d9sSrЈ_IbDž~v_<CdL"ܳ&VFoj+ԌcqܑQrbSya+I,g}w!UM>䪺 -D= @ x]Z #~MP;{}.)A5!peE׼ k؋mg5 t78z=bh<,0paI.ZF[,>tw=G,; Y? '">|$|-ȋ^@C+i *+dip1Q &#ɲ=Ci֣ȴ\]'X1Z,ųDQ}wcX]KpM~`m8+ѯ|RTg1"ytZ){//Drm`nR@cR'VDE+ʋ9_4),܎8{@`195r cÔ,@K2Ib,L3rN;wק+gA_o{3謡ZQoYnuEc^%,g O!|bSITYZL+z)-*А}}NO|c8as]1XLe fվ|Rã7"O69ذN%Ct?82]0D\q*`db9fS7E`$Eۈ_V|Fw_85*,W'}^*pTk}1˙N#imJ|ֺ6Z#m%y7 bkv &*y9|Bd;lA0 &us5٨$hI0ç6"_Hb vO RY$᭨d'cN*OE*~~K%hfezkT$7M5y?:X)@#b\  XUCQ%4AwVp鋾+&ژ_R$/P?1 DvdD]+ku gS&j|^>k|.1@#ɈxY`ˡvlyt}Iފ ]`*k CENS*Ƌ_U#{KTj4a QdTePXȭtcVt]742 @9JskzֲI8CjN$uV7Xy=46HIM"Pe*J8yf5êW\\Z70ek{TAΣo硓'y߳qo10Qmd~4s8MK%GSc8ܕ4t3T>U6Xܚbuhƒ݊h;=Zt*Sj$~M aRUMZWI6!X".G?:dɅ]T_'#+BduI,&`Xf` M܇?#!f`b [?݀Ou!asrs2J3 #gkRf09A(O{iyWx8œ`m^1e]u]m1'y$@T"M/6*s"1?;y]m*.c$َْ;W;/sEvt0y p$a 4(#=;:sm#HtDߔG@G$ͻ6O i,@(ʨ\}D\TsfG 7ǖaκHv՝5WWpy$lz4Xrt$hЈI2\CڻoZmEк@?bH'ԫl >)q}l5v'~1@͇3Ѧ+,LPLJ/*۳ F3 uzl2@2 d @2 d @2 d 1@2 d @@_RtJޙ]P%s}CN+mޢz`J(g 7K$,R<2ı)mHK[~g}5֔V55PmVUF&=и,D%g~c,[i+ŅqUVCEҳ$]svyDIsa$e~)372fof6%ʸyKFX&+tUXG&](Kְ|+Id#e3+|İyX{uɭvUr:tg'wdC~W__·H  lXGx!˜^2Rm^\ĕ߈25I8W Oon&a z`gJoAhcdSѡ#l*5ĀUeeiG]uj>9 \2&Uc@n7<loG :w8݆= š/v K}eh$U =•+vMqBr`LeuަWqYb~><#c\lFG]baш ulEs)EY1aOemJ 5܊0Lj#zD1UJ)ZR/aDŽC8[DuSc~_ۥJtTHg[̮+A?7)8?M!mY5,y}?Kٍ5pޔ [ y>90t)QF"zTn ñmK.їiZQfD|4ZVTR hNX[^/pi^s9И<"E`GJLh Q/檬#oko,-˽8 \xY}'b6pf٢sn v"1aI8} \{BQ~uC#ǘcGwJ ;UաY/3(<@Cuݮ.h-/E'W7Qb^2@V8VXq:^ ̗ VPK T$dUx+X0Xﲏac{cHklf8+lImG? "|>DE=[]vu1c*.z+@sSjI*pm%Ti?q9YòPɂfS04*>a &RE{_\ +m&Aj)mc >]aa#zCoxZ``:N}G0# f h8heh+TpQ~qd J9Z\*&3p9h>]\2pj8nqx< EsWHo^TF얶>?ֿ-z/V o*Ô ϩS-ts3v(ɥ) yN]aԶN~~GJ (u՗yߥu%yʁu醂;ֹi!wwrO /g,5(zxT%)NZBC8ڲ)Nʠ c*Ƞ$a\khekp{-iRt˵cBwPEM R>mPOIl0)yyj4{u'X"^[˘΄ðbT1y"|XR1Dx%D+l|#׎c&8&U"}l(ɺۑ3m65HEMERc-Z,5@#LCx'48~E^k' 7CZK6OCW%fsQsD 3-V=,5 И~g[& f DG!2cʨi{1f)`9:lLž KY~:Qе AQ@TΌQsnOxrO\/IF7O6oQdt=:o4El#-{ف32`'nÏ9𷲂ߚTL9/J@C'?)KZ 9 Kãw2qs%.* ;Ƭ!izٛe3A hw06+&T,ػUC8p)o–qY|I&cq>n`Qq^ wRE|90qp xcⰨH{\ %͘^9^ Ucƀmk,8Saqnt<_=%ﻇ8WU `wtNXr&^^EX@9'Rs/*@C*;Ǭw-vף'K@g;-wO|0~g;T>LKw9T62mh|PCѸt\s^%wGy|Foġ2 l豧ȝU+.'cط9<4Xp3dMiL`:,rKf 9qFGP͝l}d14,S02böR)]~)Zď,Q$*Dnv>Nyp `Le3rT}W^3C4`Wmrmi6ZZg;⇡]BqalY<@$-ѩi{dh\K化c_F+8LԠЕ,;= xe+*,T+}!r&];$G&Ul(()`W2`YDŊ~d]βMA neG*ajR)_;|/sz?8.T=.gڑOjc?TqM,4MGFV2ޤ .lM8kdJ8C 1D|oB=s_OXꐊwa/NIh4g܋yȕ| 6ND\t@ h^R^ByTlV~ 6BVG<CkZch,^402uYqQ٨I1^ hD Ȋ )/§XےAG4N  gǘU ,R ix;fEw3G 4X.- Gc6%Ѽ4^KWR%6sA4])!u~ nFt1ڶX[s+"X߉@miGi/zX+w+K@#\,8[ "SY%X@džעba;G% ~&vrjJ)C`8PrfKKy^< /s(>lp;n' tM=F9Qny 9u}:9  @Cz|qzmpe.GWEؚž`41fE.aj56<_Q[C,gEٳ6;tRYM OH!ēЦ`nLv_9FАE X-4}II1د\H %I@alIdզ_%~F-8w}o4 6ၩ .t殕_YΤn@*܎4 v Kligk[|W}ԘЅbAN5^jU7O'Vz\Wa^&d>Aq1^^Y.j@J׷4*OjV}F{;LJ <T CZW_%h9?X1높۠)f0n)*sgXJDdErƿpCCSp~ܘ Ix-VF. Pr=~v`BY֗b G!>$,ꊪ|txQC6 Av :*SW.F ~J>sgqv 0A}`T>=kMg<:2 c`zcY#L(P,} v H`ªk ?(ZaJ ؊`i 1 )B (a=q H Y%H&COKς,:XI}enHF&LRyd+&Fl^A`87wK>sct hKa6 ZTZE/EX;Jltk!~`]M /ž)x r5nΐw˷cF_cM /Zl@} 3I@CHg5%S5PE %kbD 9.R`s߳c+HLl$5o4Zsʯ,g0YIۀfaB71JwäisIXw"nVQl$j5|^;\'G4)&44; =Ӱ}c ҰhKh]n(+(g“=殕_14 a8Y~WXYV4+onFcR#+0\Ftm!n"xK) hXhNG9v=LLQ[ޣ7M*Čk s?!PM jbj5Dҳ뫤1xM]5M Mnt_z]mܽz7zd9d>ƩUQŅ:{4'a*paat)C" })b@ 2hԕ\10b&M)E1!2 ~ʌ ;UNfqjy`IRG'ɏiHss!:f;佻1JQ|oW[/ v~] 8)$X5m0'6睢1*\MNJl܂RFk1YH3qS| ҈hkv էrvP`iCph'Wڢ š~C^ vej<&v#^Ǔku+/Eh/H6ZINE/֗#)z`hYv/OE5R v@$14VJ WLCܞS\*Tpbܵ:Y)`zn\tI~W C);:wIgP9G/H:2`3=аh|؍VJu8.! zy£  hq-<>:Nq-:P 1Rv_t k~/)chшB*`g\WS M:V5eʇA2{r^«ɖYwrd'KXiѥ$1,ɸ'S!6Hg_yG0v}bSs|L, 6GzE$:[3<"A&kga L\c^,e*>6ISV{v#zM*bh#~b];XF'*˧Aæ(LߙLہa{q"1OE *yr6{%b "c_H7TaTвOIFl$˙SY~$ d9sSrЈ_~cDž~v_<CdL"ܳ&VFoj+ԌcqܑQr]J(˙c]Hdy.H Q0C;p.~brVr1:_}?sE=="e<Ƚ<8n蚗ba{mLü\"ǡ=BG~\ bL'>)Ӆ_KHv'pȳe'a; G!Yć,} ɯ1Į>SQ sE3] &#ɲ=Ci֣ȴ\]'X[^`d{WU̽StI Ɗb`ڮ*b+* "غ&]3;ܙ(s<9}}x뙃Lhb1&,݆'C@b:WΏ.KpV"'%UXaBL^kU HՄ{Qg([fys~#P:߂툉=û7`X?t?hE\vl*`$F6F'ToezI9w,֘+玮A/[XUo{]~ڼF9pT &5F9M4޿<)}dIoBC9xl=b9É;z-WK&)0^?6IxV@4c;3PK>"Fe}KEh$z@"y]Pq_w]8=*؄ :ފ'b}l>%G0F#L^Ub)ΧO+L*(L|?Dw3<:Ds]tu[uBj F%artf3ncHGϝ % °uBhҴ1SfPNyw_- c!i %$4Lŝѧ~"B#U=^fP`֭ .ǿ2C]SӉv>vG-Eh8-fa_fת::<b\w%ql % ,AjJ\Wư̑ Gc6 rd_lO>l%tKAFToDض*Oλi79.$u:^8ʏgFK#J]V w[R#4RE!Gnq*N؂aa,2k G%nsTikeǧ9*7h)}BSpe R(^@h(I;4 -m֝um.+ɨ#0i=T^MF0PGRpA9ppZ@ gV?ʺ1)ᆆ]bB1.yO`waRR FѐE9P?_O90vi;߄n2K0  ]DT1lM<4aAnAojh?=υZRP? !^`#5s@v]Giޔҙw<4y: |ꢲm0B%NFUdua8>=<}A =Oᕰu<( i E]Ch\@ G;xn|.AP|vk'W݃s?Zp5ؤ=;cҎd>Ww5;rX0"MSW'ϻ%jєg ðO/r$cM9.P8,Y2#kFm ysR M76z)w>&|8="?WY}}m?XS;g/}LP8cCc(hU2G,1Tǟ4sjLo]|U.#4R|ԟwWgn:&52E/ߙXw]qgFp]/?q}{l)ۏp~w^]L]K}<shHzыД#C$Ir$!]W HއԢ2_e$l]OhCrq9 T`KMێ߉/p|&q%a:]gPj^W&03kK/zBE/zы^E/zB'4zы^E/zы^FOhE/zы^ MɂU&¾zs9Y QNA=5\IiXY<7i8g|5&N05 4rU)f)(l 80}f!"!+}ʢ_'IDȩ9Ta[ !-kwwK_4',KQ/pllbRySvѦiW6o bR֑vhqQN]5gѕL}ޙJ7[?F\<=_[:ێ6JKiK&/k 0b_Pقn"쾰 1bC#g2P\C$ 0I4iL{9„`kfWV}АMµ'mE;ہeV ޽۰rF{PIY )w5Y.&?~,\X{]ÍE '4R9qU8;.W>_-ϩ6KQRN?+gO] ̛`͜:K⏈ Z<)#4l} :C13#;|pWvgH./P^l䄆hp(z/6!,2d%z -8tmab{Mh/As! }˂ o…Aޭ0!^{&̱.yZ/>ti!JD7=8Vi°mŗˮ_QcAq5\ K O6w6B}#wbz+ݧ`rw*CAԪ|I Gy,:`+q)-)WBC/9!pELI@໮@Fd%Z0`B9%̊ŨJFOقpkJ^`Uß {B krPuE%cr17{YrR'489p_XXJ{]ʼn`Ár~Cp}Z> ZvĦrÈGKͩi1Pdh/78r&1|W=]茾;6nؕOjp \)$DN/s ,¡<_JL,8Y{cx)YM'> }9@1ApH%=E/ƕa%@{\%٣Ѻ_OT33SEf|6ӟd$ G8x:H@Viqd+J1RΤ ݌ψ>l'"p%NuУP_XĊf#4E _?U#:~[s}P&I94jxulŴGlHUs6n)Y'pb?9ó@V ^N"W=8 P{P9aDӊ0a_oBʜ_X9ADql ֩k  @>t.0uȥXG_aV@ əZXЦ*,W*Put窴gQޛקLKm_ _d^{? h+3ƫIz`8b#!5вx$5:cJS{!-x yVpm:KfTxOGRj=5»S1~XcT4k] WT/N1bTFV{O]`̶M}qGP1dj.*y{[G55\Xn)*2o\ ,שTbk^*v!U9^_ECړ4}tPtP$f>Auhc>k0{-mǿJs^,1 2oa|woۛK `[ FRsV8DU AHS3 u(Ujn1dk!FL=n-^j&4L)Y]2:쉚u a}7cDf*IDT:<$2XT9$ˌЈRlF"OÞ.pm 'CZQ wR{-)14(<gV=*3aW' vcftdwDiBmL,X vE]F1F2e(~{+aRkB"hBt?Sxrb5RP O$r{~F²f\||Ԑ:Bi2R=<\~"_>+K?<8OT?>ki3mh 5?1arӲ0K"s*1keofm]hTeO=̭t9RD$ku[WilW%  @vˆ8󚋛u0O!%(@\ Msp3_qĦߕ#_1^Lkl F&ړu=Ui}hJ]l*޽P?{S]| n >2'4L`پXğ:Ayg&!,5O.LÔԧxE;cC[X ŝEaB8w?>~7A7r963]'w" kF6Yy,*FhNn@R- ] n nIFX@1̷R=-MFG9usL i K8LLե_6b'nġyb3XgO9lx-GN`>phQeVKڗIµl;|WF3YtQ&R}Oy1$?G+15ZLي)]Gck=a~=p+l:iX&])cBq'c!"/j*96NB-DvF>5&/,;l9hWBzբ \t RK/푞)5OIg P"S̜0*DuI$ڂV%Z΍CʧtK0>rn˃G8p06jhaQq]3cvßT[qAc즇cS3D'4 dٸU x(W: O@ww"0iw^Z ,6\&qO'%g Of3@6Xfo)S&0 #4lxO,3ġCQu䄆쀍/3oZ6,_ PDݹtf\gjzTpk6jQuLu=`ceֶͯ#ob\E.|ֿVWcHVP4f_2 '#~<ڬU\H^3 IZBy Δ.]AyůN\ç"%BmТ? 'G8p PzbM+CTس]ah59ݦvIbܬS¥t} {M;bɘԥ{>KOntHα6x#HBVzp`c_u"l<*dKڣ|?\_8U0BV?G]&gLaV%`E3886>;ͭd/\Tk8nؕ)]x9Mny lXn=B$))ˌ]ݤX[?ņ7yy!8*Ս*?)%0Y'59c&`'C_Rgvw =$x=\o~;u }:5ո1r"4%zyzpy|)DiRC4 RBg\ً?1Y & '}%h3r$"W0: ׊JYl+y_؏q ݱ[9]~1J]e* %IBC_z C}j™"<$E( \06>ȜԮ9cϨv⁐7%!4D ]-qߵΗj3#EXN +l`K{t ئ#fMQŎQ8^1\p=!A lp9PdeVC(L#"$*O3AOk'4;l /'(-Hґ mc jY*-By'1n .p\ J^J//n$>rJot_W),Ed|^e 5_4m s ?l+ ,U2L;~q3d`(tx| 0;47o)l:"Ku&4Tv9Q Ԣ<ڂQkr> : PmAO 6!`;J$&& ,]Bs+Jp{nt_ͱ?Q3Ay 8' ߸އ""7ݝ "*`؉<0hNr)"| MGRI02 n{%sJ-Hb6jcc^_SBC);sPm48kF3 1,N"3Ajrw#dCX[KREqk>́,ʙp:.^'5*o(xjD+G:qCJF9Rb.J$.pTbYddcs+JG|7% 4Z D u 5cp6 ֍js#s]rL}h/Oaрp>qxZ&V|~54 M^ V9[$$FU&(\q7>'DwWR xNx.Dh8p9""c9h򨄄F{99LJsMδn)I]Eh9wz)䱊5@p3Si,SHaARFlC`( +5,@&0 P?b#L_4:Nω6,U6kK;]%l=k)qzY)RLqsCX 8/EH]Tj a{&4 _E̦gݧrb>3̂@rn&ra&~g7r ^h!oGL3/4k͸{_E*BF/+Sf&3Us&.g~MR&4 if MwBߨ7~i $(Ias{.GFIMI`u+*V!ڃT dHa8 n΄]|PrSs\xzSzHs$Oi|fJhWގ&`9[ m/4Flqjg}$=~+h[q3n(!hHh$&6&GD2{aVWimWoФFKn[?R!Q΄OpzUo± P)(byC*&et4bҞЈ_oB{Kr.__H~>lȕ˛0W!?OaEY94PgFhcyf$f7VXS!Yc&nw{Jo#4'A>4SO\N.i o89I>4ktIh YZC"JL\`ʑ; al+zc+~KҰ62MKḿ#)~-Lhiis ɻ: )| dAh4М)CcqO >4 9u/P"4^ k/(gm0SbCmgn0ai"4r+ut}$~R#:dC k͇ia5N䟖%y#D_/Wxn ̯/<:~-:P֟ MQq]Lk~?)a 3T  H^EKH6K2ֵY ބ=aX67E Q΄O Xr/Nĝ7hZD &FiL<(WVS~$i˓՜ʣ=ͷIM(gmgaS8:LU9ʙNB#B?g.|&a=+gbl-u9?\%`FE |Mx3!=$$)z*/H{-R̮.$K#<LJuh1A;{.}.ƫ myal%ܓ~(z͹9  A Bm ]RNy`/OKLalm[:b}+PLCS1mfX RE_ʔȢA8\p(ewf 9 oG3jǡ2Y'"-? b砕 2 4yBHɢ&@fdŤ:狞Hܚ|kڥfspgK؍U&4ynÁۿj!g1+QG%8y+*C0!x5\Fh`yDjb3x-39L(ovĞ`:ϟQCHGz~oh c. M6?KF9F##Y72¤;gmksGנ-Lf`LPu,Ǫٷ ꮋAJm Y{?8|*aKrjT_>o$Ʊ]c;c %s+bT\ַY0hκDϰfM*bZ*/"5+v Xؽxb͂{HCD;!@G1l3Gg$+E4ĝٲ0n>`es-WD߽7Ƨ":z7O= UfRWֻ'${zQ%@Qly `XcgKs uQ+Etگڪ@x)poM @0qJ\,W>+{4J =G~ugjۀK :|2(G{&)B@9~9CSn FPm&PthU7n|=`LJr{aױXuЯ qŃ: `\.L*VJH i\tG VxŽρKSݱ&\tەY1d@hŤ_6UwFuU  &mpe5B-XU(^҄}74s5՛cruUMF;{SJgFTߕP2 6ll:YU $eY]O1Ǖ]MtMCO{m;IJ/삠c/ՈJ^>%`腞JX~1k! hG aI.ڬ}e2wCvYWB>qEƓ}fNͧR M76z)w>&|8="{?WY}}m?XS;g/}LP8cCcvu\`#@;Nי8U{' g#-Lҋ|F/zы^E/zы ^E/zы^=E/zы^E/zBSj@Uz3{AEs𸦰C(m'QNA=5\IiXY<7i8g|5&N0h4 4rU)f)(l 80}f!"!+}ʢ_'IDȩ9Taa. `D±v~TEsbͲR gn`Ȇ--ř7emJva &ai1؞ftѕX{] (Da睙4ls49=CYkąoJoů,(n * *VWD/İv^b+ɵDrJp8,mj;@`d@7ʒ/4UOE}#0 nTy.+Q3ISp![a> ia; D,{H?.Fju! 0IQOKp7(ZM M@R}ՄmGhȦE6B~͝2amX9#g$,H{Ԕ;XҚ,B#]$De=K׮FۢdzŸ*ԝ{Yb+l}zKsJht(~)'3ЧXMfW(6?"*>kL^аQ-8x '> J\"@y!&F¡Ɔw(*o >[&4砹D[^n ˿_>eAhq~vSxޅey VIE /ne=UX$xX]Xyرo F߂+PDZ&Z,Z1|NaWGXFWUM{ڳPap"'EuۤzX6cepXH tk(kEE'ݧڞȝl&= }95b;\k7Hs<4b| ߩ afMRC98&8aWMUF7p@h9\)l b;| >*3V?tT T6gNg!4*[L!) W&Ar(mez1.B䆾0öt #`F7O8p1CF"LF7NÎ#C]Q4OʇB%Lv3?#3Fr+ՐM\i8=#pB< YKH*`/:B#1K[l/ֿ-~FtD*0Pԡ6:Mރ9%h3rhɕJ/-[:`՜j ~ Xz&,P"%%|uɔi쀺݃eϹ #V zwT t%zcNEX Hp]Р\}VtQu1[/F.EJ8"Fod7wZphL/ע5 V6UajPQŒut窴gQޛקLKm_ _t{? hL03ƫIz`8b#!5вx$5:cJ`B<<+6U3?) XSM[\úZlx@.}&M9ZB7˲}&iL#1ݺ}^@S&mzSvя!S@]uWͻ \: ݭ9ҭ%sKɜU>WMgbk_Se A x*s//ǿ"F! IS:sJ:( ~UƺBU41q5ނ_9gJ#m70ÃTqd713đMO;Nf+vSb1ub4UǞƫm]4ygdyu751V ᓨj.ux?)&?.UscA+R,3B#JAX[aĊH?u {VGE7(2SiE?l|ߩJyАZ#c^ F+KSZ쏿+Bcd]1g[4lfV, )ۢђ {?rk~ 1Bcɂ25uI#Mƞ ]˔ ȆI8 Ӎ ;"Nʩ9wHA'Q>^ _ I]ϴ%4 % OnibHd, D̩Xly2:VYw9jJ>MS=AKh0DH) Qo\IăyF\ XHҵ;Fw\S ONk~7A7r963]'w" kF6Yy,*FhNn@R- ] n nIFX@1̷R=-MFG9usL i K8LLե_6b'nġyb3XgO9lx-GN`>phQeVKڗIµl;|WF3YtQ&R}Oy1$?G+15ZLي)]Gck?a~=p+l:iXdxKs]Θ7a( P[LhDx l/FPѴ&qJ* ;xXۣ6[qλ5^v]5j000ϡ!ee@[UAo%8ŽK26_<RXC>knAhcGitKhrό R9lj^v1퇃əlz"ⓂE_l* a ^Z ,6\&qO'%g Of3@6᝘ dL|,(а5_aםwf48}(*YߵΗАe2?VՆE sB;ΌLM nF-׺nB#lxL= kPaߊW l0?UFDm7ٗ̽mEǭIFy_/6k ;ChC3%KWPow+l|b:'𩿭DHp[# \'b>àXӊn$(콹uqWX07ZMx8e7Fp)z_^c-uJ:ΌҶvE7wb3LɍJD%WZC_ՂU-'#n\wdJk*g-e )ѓ`k;A34O#q+ J?qL"DUj]Rx>\_8U0MB[F(=ۡ8@}OlIJ2cW7)֏?!}፸h^^z]x ZRP /Ml1 GЗԁ2Eϱ% ^mrAO1zG:: Cso2OƠ"^NFD/O.5G5/fWMo`mB){ mA-A#iIxLVl UFb[ްHR~D,#OW6ʑ#ДQ2&.p6_k,IdԛeSq8 )Bah䂱Edե ~HP|FOL) 1E\%1u80jœIߵΗj3#EXN +l`K{t` ئ#fMQŎQ8^1\p=!A lp9Pde.<${P6,FDHTpA1g0ډK{Nhw7^NP[Б#ƐAԲUZFKNbx5gR1] \;Js< MFb7\y9%7:|h/N+^C"2>2/vbdQゾ{_[|I E_ĎB 8W6'`iDN>nj>' =Nqt[ rszwOҼ`iƽ (oAh/a+ HA,+Bs+=`ύ 9V>'4j&(׵rbdQBPD䳚^-ȓk; 1ߋ6$7 —͐ x$ #6WR98Ѳ$&l\66Vj?%43u0M3~i49@+N>D؊䝐M FVt⨿Cf/4*-B]#} !wb~R*>ߔ ʙ0 N 7uhVHT6D7b)0K,2 J)7高sH" [tTg[c͍DOrP=K.nDI=&hT-u6/oJ|a%l-9۫, &l^Rb͢Rۜ{Pv3#4Y1ؼq3byPn+)z@`ꐬ17 ʻ=ͷ ]FfƟ?\4gX|\CfBswNp$ #H0r{y*v|3%f5s kɩ0lj^4;s>4و/q5ФbUK)1& ؓ۩W:*5Zq&w1R$4 >?artzB#Wϟùs%%.%HXy'B۝ ExN8ahF)jǡ2Y'"-? b砕 2 4yBHɢ&@fdŤ:狞Hܚ|kC G,Ǟcq8sC ߤc Ǧwx? f+^79ذNCtر1D^ 1*.].E-`=*{0*b\I#1Pwυ%f|hv[x.ȁ$:$fc86*`eFU܇rtf3nc84Gϝ/¬ljڼH~(]NhhCh 1  ۺ5AW\yh2kJx:QuQ@# ,l+̩hUf NVʇH_1.QŻ8x6EF z5D% .%kFYHQ&Z?/4.Io 塡q~.C: \ul(d@+KMփ1J9]b']UsnQ :R _rB#u7"al[c4՛Doc^}Nha9h%~>k.5B#8^T{ {6G-\,vpT6Jei*^v| ܛr!=f'4W*ΜA*gEWuϗBCIڡAgU@hoC@mp)]p VOFaD?xWw9EH3g9Xޠ"zh |ݭ52Hmmyk5NXUx3/+FƤ$vUg z7nxP={ ߅IJ)iGC6H3|s`cw, ve` &u1Wͻ,ݰh]*µ9mI&,#-(mY hǜVx)C74s5՛cruUMF;{SJgFTߕ͗(t~Ee66`J~,čn ~+aPWyQHgB7:.N7,7ov1nQyZ߰|:*{J\JPʲfS F)h1#h 0 4MMQ#h 0 0 aapʙE 0 0 &B$Fa!h>X0 0 CЀ4aa_~,^5A#h 0 S'|W&hM' h h h h @C/F(Nkbo_gU-n+N~[4˾6ߎ?L|4>K4^Ua_wk=*n}d,>_VzYq-s{pfϷ/ϋW;̋]v?RxfQѼzμ{bxeܸ.Q5Nܕ+!ZEA^~4zTܾGcĹZ__cOmly!.\xq+ƇjTO~Q4Y8f შLߦr_Ѻji8zt4):<.Y{SkWʞel_-xrt+*1yԘ u TMK=umEQԶo6$5g`lٮ8 Uc*Wc/-ZFn;<o-ϝa!6ϋ-b׋ڇ/#hʞ*3_tk, Mz51}akNM3Wy΋Y0ؽg(*hVci-lL}ͳk:߈~/*rUXKh,y-߉K&-檠4g +͕c_:FK5G^˵0 ~*=⸖)9~[qmq5rDN-mq?Ǽ[=[? Zv>s#1?MŴ?{o>ׂǠ1~}K~sPlٺ(=O!]T( hjg,ʲ+4{^o._ssh?XL"J~߿ؤxpVz>tj-lsE3n\{b'5-<'?9&cgRlЗ4ocq1'- ccq"hRNgώ9IJ1뢝YQ8; cSȻVHop6-ػC~t;il, 4u&//u MjDơw~vdd nտ`WECGļ++W {3]ӃYkKcʩ#k?5ˑhT|/}Ϛq!m"57|y=Y8`*:0nX>ӞX^砩6W,4~ҵ `v-QRMмqe KΗ[J޷ŷO:hzYmy?V^/GG>+p毢o~8~lb4߾]nk7M 8 4kh4q5Am#n? sϳ&o/hV,.^ = Q2A0or`c1kԭETm> S*k-Kln$uo|MٴW_{%ukۏսk??4 o*Ag9sc܄ߊ~Mq>Mh+k_jhZg͊F4+#G_\퇶T_dze_`Д=j*{IP;/q'lŜN96A~mNyC73wЬXt??R}~>\u?4vy~;X+hby#q~a>8/1aҤ0y;+)g<~dO<'T3hQpϢwAt51&8cxB n?>gGawU4ݧ!#.}0z!S~;E8>mu=(.wJ̜5+fئ w ^i(߹rL<2qL|׾u {g4kp)Z #ν6=qӈ_OXB6W'SΉZlŽxpԭqչ'9ίsh^~=hVT.'uqQ1˿} yS|}h51·bңcͿ[. 4`M"5xb}?X3cI}fv8lphJE._e3>r#.ܰ&3 &~U(LG~i:ƾSVD{Gh$ŭ;FmkdWZ:'rN+W.>wn暷.AoW:̸c^YI4)lG]8.ޯKЬzo02=otd5[D]3y55:}=7n?- DϡE橵>X2Ak/{?Z#M4 ;>:)UpU1hs{g֢itsZ4C/Y敧?mQذf٤SwE5\CSxP\*kRpA]͗cֱ s6h>1y~|hyF5<^Uqȇc1m]q!=q{M&/jX9|1$?{f |&5/ i|n ܒ6iT;Aԗ״(@~&ϧT{`}*Ƹ_kRQвSf@AAAA_?=Y6!bۨ̾~gB̌x*Ϩ>Q#h vꄈЩ̾4_9jſ?c=wg,}xKanj-wX)24\YT,/ϼ(b@<վ_wo} A "huT,uLU/zT9V8-4&sWIy힭l̬<,qYը|fqve![4?AS8vT=gV,In3ãm| vv͢^Džw<dnW/MD~AAbM' h AS^%e{WދvkkvMw|k$Ocڥ9Ē<=<dfLIk`=5;?*⒩s s^?OFl5AS>8_VVs/xEq "xH;m:4fft:hW4>^(ݦ<^G4-3xs)gDqȥSqȏbiY^oMJ>&Ӡ/]^7yQ?Xճ/|Θ8wQlr@vq˨bqgı_łҊ?ѫelw51r#1cPTt?x4Kgm#n{'M'M/80'?RK?"_920)}C\zshy_Nf h AYiipqua>˫} fuCzThR*:#sx$GŏvV}ΈIfS/3k4OYAq9cb-x0N=5͚EQ#K੸}#1q~i_Ά .#hVْ%%ʙN3mr%ۖ>O"h+h4ɜB$*_]vpjǕ2~ߛ^X,bffDL!VӿJXVr{ǧ4CM ٢ hjФK>f@}f$h`E|g<"$2,#hv6ɀlT4-GwQ'@=sn7Z1$#, .4M읶>,?"lC*jWlʶv6]%h:T Ni_K랶uZi;`C&mf k `CMC5 i]ǹk̭t&h 4r5.sA&4UW:- lyʂ=|flˬOrh &wLrA+uΪF:h~&Y\䮣锸&yv**実锸~feд0@,6tfg%ȴ&-\G;,Yfک ɭn;,yLe6iQ崳fi ٖٙYV5dWa0hf$nvU.hgjrUɬ&0=3=]u`Vֳie=09Fj$! &zDg̶lTɭn224KҴMV<2;͓_vҶO1m]vK=mN'mߴg헶Nf[`lmݲs%϶Ŷ]7#"r3m3٤x4SϪCNٍ%mhvC%g ɅN>@S>wg"`e`hvζٖmb&yYu3٤iY6UN=KFMd>Ov]l͠ČMf$g ȅN.vnpm\ 6BnFfPbV-zg[{Ij֦L\Tɝz!5]Q36ٵ'fl˖19qC g[!7#?dۢg"f&bCT3+(1KS\Uމ闘Mnfp"tht;JlLDNbU53ٙLlRCqԳ&P@)hO ȾNu30ɀ铈܌L.drudLTldZf5kj58-7mh'{'W"bruKLrV&w̺bia2-I*Mb&ZČM*qUv#s 6.cx鞘ELČLM֬diSCe& j&wMMDشKM*qӹJ"["v h;O6תL*!2!Ӫ53ɘΤ?/CIENDB`backintime-1.5.4/doc/manual/src/_images/light/main_window.png000066400000000000000000002346211477034762000242160ustar00rootroot00000000000000PNG  IHDR4+9܍sBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 11:32:37 CESTH8IDATxX-ػ{Mb{n{{JG`ADT@@i,wxQ; 9?odɒ%5hPhPJ4Ji!SC.hȫ!PB!ŒK#rw(u|D'Z_ux"](+0 t(L!Bb OBI(7FGl'"3IEeL:PXh(CD0&B!d:SPGpt#8y5&)I$:+(h(CD(I!Bt$k $MbR*I(2IJJ) u(e !B!}{md}rPlR#5ݨnDF+2 %FW^J'rkCEB!Bn_^ۿ&]I(7ZэFk$*3C̴Q2mDN$FWbꈋTVwOʄB!LCbvm^ϯ@zHh#7t"6ڡhhĤ&I1ӍщhEFT7%:It&]zI֡!B!COKw8AW#8oЊFkA'53ӕ:t #ko611qyeTFGG#&&B!Bd#Wp%4ݡhEu5 F8I8g&1) ?R ëW UAAAx9!B!G Ap//`-4Q< I8&Nhm6df[իW[DEE!$$B!jKX|&ZSNII66Jwތ6@BxDDD0C!BIwFFjJ둚:Χ`L>2#B@uV^m"BDB!B8ʕ+ͅshCWj гL¡flf93Uj֬93<<7B!ר^t:sj =&G"Cʹ)y!N33#B!|g?פv.qj ' :}׌*kמB!k􄻻,uG!VZ5/ԝO}GM(MLAv4ـ !B׊YamĶGq1M*r iFiFg&jVA'O^!B!/l=!b#m qݡgEDidɭgntDǀ6fB!λ/zGKA"4ڹ4e 7Νэ|'=((4!BadGHzq(N33ʹљKfv3BJ|7c8A̤%=sYzq:Q}7f6+/&t6jBJM௺檛%%w!LxO)XxAKl]J!D"jDLwؙ,4ՄvUFM!!zS{Shܠԭ-:Xw>Chnc}zzi:@:_`!<߄~4Ę#d |$Dጒ-Z3BX۷N,!D"kܤl"nVIl؄ :ߴڶm$xiɧY '6E dխ#c\neMG;_NއPhz$%-Izq[.6oޜC8E*'HpYh%n6lBLB#kGm)IM4|m}`zzo%)hF-Ʊ;>:O\?ziԲ+og .v=~Ap'B@ѪY#ԯ Ǽ7u3,|-"2 :#' A I}w}S>H h,KJhyZjQݥ{#cz|0QIfbBFi!"45.RM'ۙVhuF_B:g~ĆM!kM.0h N|=΢C+F$-utŧ^lL4Vs`>uZ`I#)OG灮=TE8owyO^ u;/3Be!g4.GS1qB0!V]l؄I<<t? m^ha`ae:k^^O# K/bUF nߗ/4N1HsގKR7@1B 6"%!C>V!M /Y$pM@!L8AС=Z7m;^Z|~ xgV о_&8Fm?;=i4'7@G,$oiA[|8 0ڥشZ5o$|!e _kjF axB0enZC٨ !$范{mԑd~g$fm8 mJ@O\= @zuP^4mF.Ym2{n2vn)mS GYqه2rg@9#Z`K-4WXl!Zt6G>ڋY!qfHcpf:ӗ9Nhlf8BC!BF8;'s@!B(4)'&p; LP<% %N꯲XuNWvj̪B6.!B&^RPfϊٕȑ*w˘O-4Akڿ@{`_Jq34F^sIhP?<ΌW83 gY"+V&[۠Qvd*ڣ /-aœ 鈫Uq !~*  !Bnq[F 0]…c[1K^vyɄM8\¶`1jc[_Ã1_DVDr W.EP 箍e{ۣ.fY\UK?ST G BC! \p,\gy9~cM!~ 5P`( &^DpbbR,Ty`\=S 4'гlTp>tbƨQ0PqV|q225e^8T^P$! T_>Y zҵ(UQHr'ONNGZP(!=oijy/RUm]8 %U̇mDA(TY=i8NnZzQk~?= jT(<00̏2:cI7evx&~kwc_ǺA QD^,ᐫvk8z PDbߢ›Yh:;Jx=*6M. Ta@(S(|Á1=ThB`L˟P& UD[`_h>s$B M4"^<]PNii"۫f9wW|N~#lj^oc03?[vHML&Zsx :pXTK|f℩,֥VϑB!O-4Y"{YU: e[Dbc@Z.IrDh9D:q#8;]*1=ی&F*4ژT+uB2w4YhEܱ\ׂ2$}B<~vAڿc{j'c߁͚5{󐞋"d^ MW<5mYL"C`hM8 1#O)DܓMM@Yc.'410rQF=[pT9QqF^hKő(,f/>h#Ie^ (.{qk**!yaٴBݙ?@UXiBUΆ%&49B!B&Gss\ı5#{!,`T+`(RBc<^^[:Fxlț?/l=I N^hDZcDI~(;Miߟz5 UͰ_{$!**$pOv.n^:-2?.wMx=m_W3:94 _^k9CJHm}şP xV'YyE#^x$SٲF3r%2*?z'qè tgV\J]|yN]ksyTмnY)AȎ&2ɰH! C]jujxmm|)\wÕ5h_T'4! MG ILh̯Dv[1eUa$ާ0@~['4tF1: ܠprv.t:7F̙*gAx]eUtRŤqE75btPu4l=/3@hT߹}Kϱ6ڇm#7U},;܇+0DŽfLjWDa+4MRh>v{H~ 얞I0sJxOh"WG$C6h 'vcf(ghIhxo\ocY\;7*NhDM 8̬-qq{0⃤r0ua7;꣘A4(i'pZ?Pem KkAѿ0rQZ[w!6٣3X߆ݵXӭ㘈:D\281…Cq^}[q 9[YRt>r8C$>d9؁6E#_Xvprr캦Ɍu $Ya;BQ#!B(4Ś;B\Pf*7[ kH;8!NhrA-;T xş1`ߓO0* ! C>|M EH MЬGfs( I@ݰ9y3þCQ.X@X~l39!8&#iƷťcx84Nyfl<0DNy\b!d"g.UT. C/R9óZa 9Dooƹ&R3SWES UPyK#1xf:Ϳק@?c ?9|[TARG?_k i;}ڴ{1UukI {iD -gI0wa9B!BɄTws$BB72Igk/3Y{H=B!BCPh(4B!B!BBC!B?oooB!Bȧ Å,,,,,,,,,,,,PhXXXXXXXXXXX(4 BCaaaaaaaaaaaZݻw B!O|/n߾-K9===ww$y jGShh(ݻӧOc޽X~,9;;d[uu;BФv;z l~ınFGaÕl^ipFE)MfΞ=+wEK!3BP^~(DGG'Ǐ˗EjX[[c۶m~,Zb8@|ĺ۷ŋ 4ŋ5kڴiQ#Ge d*/:7L<{q23S^H璙͛7dDFFʑq={`Æ 2sub"R>|(_oFK8֭[akk+APP{3@ܯ^7d~v,ɤIлw/X̹GЮ];X#+fqZ=(^^aN!Ph2\-cv>$)nE~SRs],g{0vƓo?by9Ψ g;5ʌSN!&&&Mp-lܸWNM6ۦ\ y,Ii1Lӧq !6Bv?.G8Fj))JFǏ]۶r?~,bBjGex"ܟ(\/R%iV[шeb(b[WDw3!B#y1Kkoii 3KLdFe"S,377|jr8yO,/ʌX.MFO 3YVQZ/";'B(4kYMad0<{JssL5jpXp~L>x'_t{Rr%37oEf2#dA}ч!ZnkggIFbqFg֬Y#QbdիW1p@XXXۉ)d 4H7/ VjDFw^^#>x/ķ XlF˞B|PnC`XHE!%ޯ) mOz3^?BL c3 z&K0j0/Jf$|m03Ԉ]b{RR#"Di~&ڌUh1MDݻwvheF$46mF-K {D1S Ͳed9y@<чمrJg!_魟fp8]xi~[~ Ba.n'B(4Wh_'-mKCe˴,k)7689t#\op3Lo:s-Ql *L_Dg[@;LD[̈"w$&4gDiS]wCdVGzĉrJnDF`/"-BFeĶ"@>}!fBdĽB$S8Y3&+36ЫWO̞=[~fzhxRܢ"Lu\)RYЈb}d@ ['B(4wș3`X>OIꃋ^`6h>wH7,8,*ehNye!3N!!BlDc"2R#q̌>fF$5Q}Eg~߾}‘#Gt/ND-[%&c h#Zr\1á;g̞5m۶S#s|굏'$~Gv\\Ց}shz۩w\t>!BIvڌgo6\L 9?vnHqơo߾ĺ}ys{ПBfڹ/BZD&HԈ}ۈ73ZhtcͺutI͓qwwܹsf3ewUд⎏yRKjd&åέ( _h 1Rh$e⅗H(G9H &y2":I7zEFWfĻyqRr?v"ZCȌ+2BnN(0`\!A}6xBV ?HhlJאIB!dDhõ~N 3);I/Lf`ּq)ZI\ K]JIФDjB#'#4Q}4ړsk^&,1g|<ѨH)-^)`!4'ND6mf̈[7+3Ӧ+Nߵ@yYkD_͵o>!BIh; ?+W`p\p٧YZo#C#(536rx빘dFԐJ!g!4LD'2Z$!2ZD3,! {֬YD~ݴЕ .dH;I~WoRx8y~p|xHIrO!Ph>3Ȁ5tTWxvqU-h)&o9nf˵qQWt*:bK I@3#S9},5B^tEFWfW,bI 22*'rjoona T̈fT;IVhO'${"n4B?,Z/4L>!BCϟ}מ mSfnz RS{Bթ>s_t+tE|QtEk333l۶ˌ@_f}2N}i32B9kC$3!-FeheFC{+ "Ũ#XbܻkOh6o\293uA%*5BfBn܁q`/|B!B9 D 硣㥰;~0ltW#nvì+팱' ohEJd}xYfR/ԕk~N]\$'#dFFheFy+++x! "Ҳk&9Z#ĥOpv'4"5XQ?qolw',G}B) Pn!P^c?.~Zv3 ! Mr tۋu2 WgGoz$[YJsؓx>1oFL@>odF ^ )"%+Vh2E 2"ӈZĤFw[!5ڹ8bVZoLbCRX+""*}4If^_ʌ'NadѼ8YdO| qB#3#XRh7OmVp8۲+6A_8٩ 8ۢVGfls&'B(4kș,Rwa=V1qyYfEIMmj|_şx -y/3u^=i=&}СCy$ZQC1_ȕ@|˴̄<=zTW#=TLOͻQ{Bfu7OFȌ>x٦ȚQ0c tIKu7/ xix٧ZhĽ0_׍ŋd Te!x~KW=!BCo"/>`l8 %QF:̓g}A{-=`bl$I'z7t鎑ǽwn|_VR3IjD%%"3'B(4} 5x2U/kOÆs]ٚvs]Bhͽ h 1joƚc!DDŤCC Ȉβ~)E&h#5DB Dݴ)gL@p Q8qDG!KKKyr6ʌ1<ŋ%Ra=ZW-dI&MJӋ33~އK-KiM0s%O!Ph2D'Cn>[E3gLۈm}MD,B+|3@q(:EG sL>h>h;͟+ugvvvqBl#ͨ"]Ȑ&D3>""!$$#OLHMKQ'mJsdzꉅ ȉF3\6{lybfhGB|rH\M[w˿GvfF!Ph2}R/}qx]pECtTL\䲟 1/ܰa,uNVXDH̃EƲۈm>b_q%:]2b~~|"YD޽I;֭F B2c;r*ˉxcOXlfBBC!BzF;7B!B>6B!BBC!BB!BB!BI؀B!B>LL!BafЈB>!aB!/`ș踱/B! B!||y!D !B !B}`(vg le20&:},Dg/*B! >@ !: KqE0vI&Kl(XRh!B2мū;1Euȧ2 Mo=DTZp MvT AbRM. T_V?&d͒ELV"OI(41Qx9䮉Y7_ 46QVQ{~ TJR#! 堬8QB1Ǽȟ?':wgU/?B!PhR"41kQ?u 7DHuZZUVf/\>z6fu3ΆQ:%c)3X¶iPPG[!Me-D֋qm] $ T{3Z*#C c$6T9[F4X:8<_"&OPhchR0<V.:BkC:p~pa(yNjDB|M1on#ex$ðXEB!$ "?UbR X=vׁq:?a)W2EB2wޟi~Mr6& =nyqm&8s~5Հ2_z> Uĭȏ._HVDf=e PKݢ(E`p~B!BAhR9LN("1ƃ0)Q}m}0UTVEc)(8Q4gE$n)爎 bP֘į[Sh1M6mo AiTƆAqie`FU 뮂&bh94T,f7#B&5Bq?3 +vy3s\8SZRQ_'/qkAlG/۸qp0U\UuV`ckf~yϢcF:Њ8}nļ0Vȋ)[q 9[ZRt.r8 cɆFiPWI{ | !B&5UP*JvnњE fwyȞ]QX'4?PPߢp DaŸP(;e7BrNc\*(S UX=za}툭}ku40*oeBC!B2DGG"qY3."A!BPhB!||Q՟0،B3՟𼄤 !B$4(4B!_М;wCbBǏބB!$CG,BtHLh>|~aaa'B!I LGQhB# q!BH}(їFL_D!:DJ(4|fS~)B!чDB>.,g$M ^ %B!B""">Ј(?L B! h(Xz7 d~Wp?[CVi]`.ϵ;Q{|(JN`GPh!B(4 4Q(5nEP WQ0 cã0|>C jc-m=߿ϱ;؛ ;;҄BC!B( G#Ur]ׂ4| "o*S#,(Nb|B:W ޑxeF8Tmm_Qh!Ph(4Ҹ$],m#K}Eg%1YH;C/z v@/kK;1P@{qЈs 0mkQx&I[= ÐU4Ǧ{w| 5̶.Ǽ]@f7#_Є n=:.FFb^~ٱp[ N3:#EBW)4ax()&,, ±cpa߿Gɓ'accG}J(4],u#KR64, K|5ڈluًp(6J :CN4$>MPw%]z6Bipj /Ε%&`'2϶uwkG/ٲ"kP*R0wMEg. fH]PlY k65F`j+xEPhLEQG9έU0 ǖ(f]jRɮB"Kˡ3M[Rvtli-L{4} B"$V$aY3=68q vđk]qjW16ҺV6bۇ3?X]'c k.^^) =}T!b???*4:UVaXfM<ٸqc<ٶm,42gϞ8uB#QGE3 q#k&#nH-#Kavmoy|wĵpO x>km'\Z=BF(!yFAM4Q]BE˝Cˋְ8;EIrc,zPU hD\hBjaq0e (7L2RH1*a(r6/c+4QbUoU¨p8v9 N(p%4N A\oT1 Q~Bqityj}>WkT)_\+`T2ƘF^?[Wq. ǟ}gQ^f (`(+B9Vx)'_l߿5ڋt9ᏹ7!ݿkTP"?wu<VĭT JtFGIߎ|!Pw-0WܔzbGT7PEJR!oi9|tgcZqn( U4銸5Ue1bve1C: NyxUEy[R1ndlT 40 vȤN*۬N;yxb:*B9 3t܊ t|eD8 k`<a`KnY /J ^J/JhCpvBe0/;:=e &B.րZp?Ocu_Ibke tC;\m].v,,1׻$0?4 Nʓ-FbFl09*瀲Kh|/ }ȅ 8~$p%7SV<̉rh3kNިl$:r[DM9 Q[/Xӻ2r䮃u:QCsR;aW>(Jt~ myңOmPب:^{5hToz{T07ȁf5N9+Wau| :S"oV'Uh=-q%Yr.|? kaK}/4VͱOk؃swix,@8>:V4BΟgcʆ9]wbtMTͶW=7L`u _llp v0j{PT`eesZP!X}<ԆEaPD'NhbیD,$N"nhpfR{^ŕ0&<=[*ą& j^~ >ƔUx8ynڜޓv$Nj۬97 }mPZYxkI)yk)XX[1xD'Dp^8wp)}g{)vHyٰrpJ !z}-NHl3ubmt ͓'OμiI ) 1&z={X&%9]$j6eXcƌ;v,f̘P3]KLd?,& B 8XSIWInB) {vŶ]MQ{wE4i"@@AaJ/M$ ¾?J2wff9 7]G4hk͑~`^o7ݮq17Whx9 :pLr, P] ůی'~aOWcdr~'sa16$} efQx, `ΕRߥ;BpȐ[M998s]hta<0 * 3拣JtK_pGPAU\ξXu| nF|*8|d}SK0H :?SWCiGǷ% b=[\Gh}9(^J9dA';Q;?hN5kJ[)uHHºnt^Dsu4e O.bh)4Lbv-GE= Lٺ{W 40U+VUu95+H0zABh h9U1TTʁԼ5]a^:$PcP?&=9 ~FI3:C+sgu UhU ưZ/_{4ΙqcF3a03f);O+4tmX~)X, ,0͍MNC̛u?{?:#LFaЛp8Qf8Wlic s)sS0x Ё2~J hڈ䴁K̭JTنG2qgZjAS$ jJ1ݙk rʍYZ#NU<1QKcv=TwUp@W蠶 Wt^x놩Hƍahe\¯Y4,yZŭnS6"-q2pbHXקr- 1.mʝ@ͿcH& `@y ɒ2ư# pǟ,8Kbwr1JmQ.L֔l[Pq2SW4 Vh~Pچ]0k{TVr`B!l,y*MUNj6MrVv׵H4 }(K*\jYg K7~Ɉ~@Cͩ .g'Y#(~2|cFH?#=}KcGKtckk[l1ߓPGcvҤƘbbqK|WLw]W 42I;wP8WUFWi[|vᗺ ,wQ|.Ư^MQfl{8w@%q."%f |"pVqfÆ<4ϜXH;Fz"2CX5]k6d|g1*¼uH%Mǁ3x88FN gxcᣰ<^|v2šqn}r2oa P@ wf5w{Kw!Ȃ ť [A{ҀzH3Ԟ ABM@#t,\Y֍X& ^O.n<Geq?.B 'X,7`Z70볘R_=␸'k{]av6 ԃZ8.mXr1nДs^&B7F`1?/z_-UC#RhH\8N+:0 m 4 AU!A3j% j48cv,)h3?oRCsk~ gQQūleF.f*z غW5]kVr;@c1*!bZ]>Jwxđ4 8DHp{!%ecR:d @Uaa{x=R0' ?BW)L 4 4صNVu#X05^AD^x,Âg XN$4tygWb ;i"6Dj~ B{x']-/w\cLyA+|aAC3V._ r~XPh.VƊ$0C; }җtESw|>\QT@_BЊ.v', >{棫.VMhDlD-m.pþ]>x—AE2Cz࢓d3Џ5gmt\?\jP8;\>l}-~*vwR㐅jX(_‘?1t¡(ms~8lMY0a %+4WBW a@#L?* 婘ہsZ y%!6[RC)se飻^]D 7iV Mޡ´~Cܭl©@#ʿt,V =tY%@#I |PA%Q=W/9Zp9⋐m CJ48OFݘ^; &lSYLP9te l({^>s`DIkp7!8Bq C@uH  ̪9e=? ZݾS{{z` .3m?c2ܸwERSQ09Ef ?]լt܌2W3e)aOw3lW[]Θ U aA6|'`@p|%|lu J.gjI'ғ $1r yז JAy;-VҳB '% ,KN!E񇱈s#ǝ>w EX54Xbh O;@CE޾#>8DdhЃS+5l*wmv. IH6z-f[Fl’VKo=yf >bdOKNB| ]-w_ l =J}]>N[N kMyrNT6:`׮jiFb^+nxc;fi }xAkaMywO+ neu`qaذz-GFqXMWt';@#Yzxۡ&}.gx |/7C㶃ѻG\1F}=-Ϥo sN,' s=fK6¤MPG hu*>FC<8&%ɓ'q.~~y S99Sƚ5AMլt܌0Ì4.g:GX[(Yˆޅ`3BJl?Uo\`INJxpZWc m zx1_y̹MNG/&F>44@>.>&h.ԟܚqˏ`Ͱ<K5;4[%{c璆90}E.Aÿ[yͩqQmOK2k\DUƨeVT&-- HJJB\\nݺH/[аP{gL,s sl0u2u/  B#jV:nf \@#z֒ ވKjԭ]l2fՄEp# G4qᙰBRrΖLGqte\= 8~U;}nn#p`hP{d@{iBm[!zD 40."fd]W@P;&G_m:oF<l>uEou)M:l Zu[Ǚq5$1}i"r͒蛓0yyy,>ˀS 0bϼ|Ɣ)X&q<<<(s5+7SjV3̸101e\7dl6 G\f+ wm۱mdC 42(Rp_+3<8 KWm,".R71K{"8.:H٘%!锫 n1l鿭 8}?Z[IfEvws%[,g"&݈bn@dj\鿵Y-pw@=nskU_) 7 6ƬdddHW2FϘ2L٪@̿hܼ~ǎ;$ngUM,3Lf3pt\둑5hĚXG;w-m`iA=\cxdEx} 6,_ [+ "Ӑ/se$w8ZҊ|Q|Q"z7KM IVQ{" l$sģ;ki&^$}gw}=lhHu{&T |m$g%4|z2~ C!'3nu*o&7P""""j#oꬼa"4#gI:aMIs0b\2Z`=c/v7k!Z,jX ]4[E~&JDDDDO޽{HII!߄<>O7KPHJP<c 1!3Dh!@CDD 4DDDDDDDDh!@CDD2!-&\}St3wC+†iWV`\zj¤9CBX0{l0 94Q@(|y sZqn ͊gq'slfu }揗Y GkcMP48gSPDn 0BۑKWyVR^6$ΈQH\ C V'ÜUK &V!Sgn%MfuAiyߙQ!V&(%@C&%""""""" 4a3ka;pJ.A:ji"i»n誡sv; [v?$~jhCK]@O1 aC}PMe~-^{'l?㏰P?Y>&,m xc20,܄~ r"|ltߐ0yL>~;sFȰ6ܓܱW~!E I}]ވ"""""""CI18V#y2Ͽ%-i:L [PtʞF~ (,~?qkzn H( ѭbH@/J (S 6߇_zŧ啵M})Ft`ʅ%H&h2 #%@SMHhiޗeE8~6Do2+lh1Јw>Zix. 6'qn ByݛЮ?'87t3|@#DAv&222$.HvTZzDlUHLY :jMqEhnr+'҇,J+hB3x;~q͸JM% (h-*Y8&I |pJJ73`V,bB{N!VpA>: R@#K[Vq :y?Wv?BNzZ, 9_ygTN ĮbD ] ˆ|?Hi)@yZ>Ш\63Y1ZݝI\0 Be}\艉Mtv^*[] t^fu Q>Z1DQ,sj`uwE/Q::Bd$v$*L=\nZP8pXQ6 |qш(:> [*@nt&|w-3) Oǡ\pk 2o Trbyem*tvNUY.ppj)OvZƆfuH*'?n 29>3a GB Qۮ*yŸ3 6[E@Pp lXȂH>^^YÐ S\$x۶ ^"C<)@ 2U4f9BTx/ h* g҅i%9U-2i_Dhw[/15/,ן#FSă矔҈?²Z[QyQ` QuxԆfO@BBj>d8.4;/AD_SыB1Āx Hx|}(%ZeR3u!34DDh*K_.cF=5hw ?3Vfe3(h$" $BG@3 y}s&""$B޵[xi<)[H)!@aߘ++0}=hr5a!oK*#z 360(7//aN+ؕCSq{8d Nqo:{aմhm Gl uMSѵ6Fh;r)VMUjyO`΅N㞘6#{`tR0l~37#|ƍua>'2 (5;4fcnO^ 4j0n?CE)Le;uZQ,\4ݣjS`Qh8Q{2Eϖ3|[{,048kν e#zp&_"”kJFiWmqz(֚wA{(Yb:iawU >}-h~m7h͢MaXdϻczm:РX`k8㺙Bit-7NaјhBρ-10|6P fJjs}+!Ww76?U>y@#/ Jw&#`1حqGXP홰SC:-ƢU C1JL\5ۢ+4a3ka;pJ.A:ji"i»n誡sv; [v?$~jhCK]16U Txw3 ÑCaư/!*NXp",4Ҍ.p ,3uZ` sƍ8|%gǠ1eqGW"<`^xE/}5MT=U˯xu?BB-.Fbkl1$e-&FypjB/Ĭvw20}_ۈIԡ} 2eT| 6^ bx2oFCP*|ꀐ0Gyc/BVuFvKIfY^OECVb;Sp&G/6 D i-Rzx ĥjy%mD~}=1y&> .M /ext<l#>pOZ_Kv .2@#yz` "h|Dz;W|LLP4& %Lzq<]\\wwڳ1B h8#|YG$ʾlsEaiOހ Є%@Yb|𔺜](;Vr1x ["go+$@s z`{`u,=' aSOh+ 1טw<@+;aۘ߬@\Ѽ )t]!=%u<{ /ԩSUT&99oRO83[2W>RKZE4r,SE~[JJlBZ;ߑY 4^ͽVlLʦ% րQGFk@c1|(CItZD!c@’n& (}: h#S 3qkzn H(H~M~@i nˀJA }IЯozQZt.G\Zш>b+k&2) {}## 7Rg^ڇMu͏02-R,֝}r< :K0= ֠1%+l'sA ܅"y8M 2oՀF낶 BʺF~30-F]6n/2D&KDTFpҌP7[)@#Lǵ-1CSӁAÆ0P1EaQv>ѦCP2A lq4} z~U S"jq{q303ݏz,ʖW d}p܎U|;7mާ h¢.fBaި6j(qb:<A@#;hْOR(( 6'ɹ pǹ5&V啪/ qR)sC7ؚ̗4Bdg"##CTnN-Aծj렇KD1E )3#3"&cSouԮj6ыД #VDOYUWЦb}G4= ́!=V&6:ZU6~ڌrƵcHF90\|,}L< Oܙ2TXg h҄rKn/csh\ϗ+ËheJqF+v}X9?MɩyA%I澀[T 4 ~?x\q;TDDD:VJ .mYAt,\ 7Cpc:i(|!hjQTç~ 9~?R|Q|m48 x Zi@͸S4UC44M?sJFk:'Ee \сIg@TbӅ ӘF屴R>uJB"T 4bda8NTwDb&؋\ 36td@SP3C&ܿ4|Ļ[{K hz~2ЁNH)PM4plAs. @|sC' _ >΁\P=!} >Z1Db}%JG]G蘌Ď\Eэ] jTŪZY7xAQQQEǧ!WvK-C>\ d##euFxʌ}q: '{Z$Bv>[X^YK]D%.g{(_.r@3[QǐJ@û~[ǼK|tP氿( 4bߜï 0#zq3~mή-yTЈ3pWLF`ͅP]9#WӠ:Bc]7N]{MO(/qxXBCqehR%@#.z" *.y^ݜ>'n 6.-A?=} 1tNDTF,FS;PjФ -N+Lu7#AL1;+4All9> nf(js/΁)[m&_("BprA% Z#&+:k5Ą#Jqy!f+p Á1Bd|$o}|/a)wIm N+x%DPyR- 43Njs:R˯өf4X3@F؜WWŸC۞%Ȁ cP튂ˊƘ}IbN8E}D55PZuѪp~"q1Ph%vIg3@;F z }\_([77: 1F&xs]P yB\x%Ee:붟#0B6]qk &-8ka;ShCd+rhD"7$}QǃuݵsCr̔LQ=FաS3wčNi^_\dXjlTlU- A=-6Ԙ{a$唗1Dv a6  C1Da2G;Ⓤ6֬|m*f9=< -Pˁv&>R`halFA^ + TrB_!@CDDDlhjxyB,$F0hn/B2h@CDDШ%"""RMc%%%Q]tGK[Lh` >߿9hj0}7Cwyd<*4DD5hY "">!"!@C3ʀ QM!"""@#Iz 1~/ځIN~iK"""40#"MazCbU!m oF *%C~F)9F=`ήm]zo~!>uLXSҚk+03""4hzU|T*ps Ϸt)5> 闠63?,bOT4p~+fU:?D !}O?:g"J$H8yWrd\\]׳I!-&\}St3wC+¾1iWV`\zj¤9Cޖa"LG ogm: :`9<*P—0J]q=w2GfP7펉nxYfjZ6Ax6 |@䦩P\ #^O+ڇ*Y~ \ ְY' }"?U hLr5j3~?=&S/,:$D<cׁ?|iغ LDTP ǡMLr07{HoMnZ`KիGH6wUC wNku~#I =Ѥ,<7A}5/c ?ca{#4lݯkg#ˇ„a_k p/af4dt@7]@~Xu3n)YJY!XЂB>8|%gǠ1eqGK(!OCG}6Xj,Vh*Xֻ n.ꍻHI/ +487- Kz=!"" Wm{~8bݺu-#9\%Ch]<|Z,)dΆL#\Óɏ}s6ZVE%uãF?4D[+_H*햒 +(Գ "z)uL8#{t "hy2i-RzxK 啴YBI}=6\x9~D֧/4TU!mvwph)4B<<F}@q ER!RX2`']V!;Gƛܾ qEP!ė86X#%ST h,` q'p=@v]x+vprۆP &@CDT#]ΦZbٲeł $a…ŋ%b f;~&vŸ|= QQEF,L M& tZD!c’n& (}: h#S5=Q$V T]q$@; ߥ_'^I Ic0\¹8`}JU+k&2) {'ퟏ3~b; bV#r@Sq W6=y]}mswg1%@#ξ]4pXUnyʠXnEoaʳH|;ž.ìY8@Lt\G]tye8'@CDTfiQ"")%K` W}Ơ)hk6J¤?1Nhb 6 fdu qa#%? 4=x]W&p5Gmp|f] h±qZOr@i7@ќ4I'hL4WaK Ľ"#BVO@6&֬T @݁FwJ% X:ltqO3l+J!˺BD|YjSn5/9^Ѡ ;ef@r|pj v-P[=\"Yf )3#3"NMQoG/BSvc,[=>gWPT-_A#8 =wr(/` 2T@D/~-0oJ`̟x)"@S&Xn)BO/>2+)JBi8qȠW92c- -?*5:>~IklA; "Z%BwIuy)Y#@CDTI0#:S33E0 n@w.xKBYgƬ}Wq=oHkaBip&0 W}NXot%"@3hIf?88TXq,::CP9&8M?B^ĞEaV4ק1D-'ym\;!u0 F{M=)Z !Y՝j4]3SN)YY)t,*E2}@sOԩ; .hAgxjK)Zb}!Yn,tBeQC<#.bW1`i"_®}amyҋi)@yZ>Ш\64?f㕬,?<ƞ"4e\d@sNhquD "Tyۆ%8"({ig=bh oIt!>ĞK,cx,R^HDT e\JҥK1jڂ="”j2 p\FhBV Uɥm(&kyY%d1m#$6Pi) BvS؆r&LvVP أ8_P4X@?4|<;5͵cډTO5Qtbܢ\Dؑ[ztcׂE(VmԪ=dE\t/dt|rUmT@Ll12R ȿ)[Iǡ\pd˗.dsʸ5\P˙啵ԭq9KTr@Sir3WD]@=hJeDbu t4ʁ&2ǔq<hcY?΅VMxm,#@CDT#O?W)nf$@33^kzC G^Ǣ*^Sh2_6CTch;# &2=Ϸa'iODF[LĹbhpb<6Dl5*Mۮ*l\a -p``1} c<%'<5+88ePwYw-G@5D_ŐݩQct-1e7=.fNUQM,g_! U3 p<86G].7),g?*9]xu M-eٺДV<]K6[XBU_xNmW^DP{GR~ʒX8hc͊Wަb3Y\Óuv&>) U)gh5(p`qM6W89/J'Y[@c [gy,ڥvb|JŁ`oc lGa$h&ǐ5t-s1+İIs1b ?O>~&"""@CDD ?4bHOO۷o+ջwdeeI%LDDD "" h!"MAA.]$eUb>gyyyI#MDD4DDDh@sEL4IX\1Y%&""Fddd!" Nuܹxrrr+Q^^D* * H-]M7ADbî(#*" HQD`E+`asfvvaO4ޜΝ{Wnz:rJrT 4Lb3e~܀0b#&[o?ٜbPd#- w:|= e/)AڹeԵhcC_54Ø.Ai7;_X؁nT߯m"OC6zPi#:_cCuPvP(N?W3 yN?n+g|ʇf~|ZlLT).NKnwYk 4 ,)S F0!fm0 8dz[^Β_ch6m= mu^a,q$̰͘,;O,tك#~琝M-""ohއҰFlsa*iE7K>-܁3!NP IIVo0830MTx~z}V]Ѭ~?.k{x? p ޓ^6Ae%z|KpP/`64d=鄆H1vB]pɚg y; m}.?J@uWE!FIx^6 ͛AuzJ'$BQ4sԩSBLEaN/\43 xJ!LUݏlY ^?6Cg@.>Kqo07D&+\gM4#䛘͜9sX@# 2AT_ZUX48ܐXvnD=0|)'4C7h>a.O,K6Fx"4MU)0*))aU8 0ep) XrJ*ү%|hY.٬ 4*2!lLһIDDMغcj޽ի=F666Xx1آ#nnnoV͈ (FMLb )g='>J-LEXB \i(CAY䢧{LX ;a hD;6b1 '/] &-B/ojl fHw%IDD"ЌK.e"ZZZʊ,ڲb8yoh=q48e J<Д  5[brJfb/w>IeUwwAf'B jQ}}V4Zcq, u^g,#SІR$EzaY˗//3b*ɓ'Thx {3jOH(^cԡ:xRJsR=BUmv12mH4C~fffr0#YfjV{d\$&ZqPkapdWX;m:7_f ,;4ӤBi'⁨liHYzZ-` x'42tg$"%sKN@jtaG"yќmM5/|`o\T,~ 〫]"o hxrl6o_PHBɇ~1aQr_5|X5eiC'ũ84+n]ŕ+WX][!Aޠ4gd)q*敘{xY#e\'U kf^MșY1 cB(9%rV>+^Qc.T>ǦwFTT?ŠlbZIFhhrU$?1w/N ݬl\1x&`(Nl2vOݰx3G1d]K/5P-qCh6*@{?&8sExl#V9iǤg;_,|7)  0pS Ѱa`$T/@i6&*T,UXtN'#TqQ 4kd<([6?O(64'3@FiaܜڶWԧr^5ly,- s%gE} U]y4h귞aӧ˗Xv-n޼ ?:_bb"ݻw(@_'\ծz# U+)tU+ˀF6 д!@CDE9RYż)zg0gӿ!, {q?kI/ew4FbkR\$mJ 4q*3)bhUݍ'y$o̡Mw +hmy'yhiQ2Mf4ĢUcP-pu3psePzqu9,` !gЈ2ԇ@mi^Fw4_l@ƻz,ڃ>j`=I3O6gq+AfwR-PTcQ%-qb".?[YrZ9Bp +b!geE"lN&!g ?ĬYpBlPa*1 xl8̡C6,-555+h=.Z-Ds_ cHrlAjidp~iBHVΫGDD?LUތf,D≥6iBAs4R5j;R7~O X;ea?&C=*W.=\p= _ȡiqD47kRM:/q`p;""auzgFU94;r2UA]v|@ÎSP1iBҞ:GÆPШ],Oj/N:!R{¸-9B18Ut].]BqTE^a/8|.kgg;V7ieukSʙ$/QX|4Ŝ-א#RO*ga:vhu.úK%!ا T9дh츆l!) h^~3~`ܹzaݻ>|'OݽEH;r[`aSC7VH_v"0"KB;Ӌ Xix,Vc8T9#"6y3RaEghr@Uut }.CUh1T9z'ǴGΡa R0LZr\=ZCSBfI}6 2W d`ё#GX9vamܸU> kl^ i0WshR4ĴAxZ,? PS~ ڭ05DDDDy3RquuŘ&;v(0/mdڸ {e5M6Bڂ7Urvӆg/W\VO/H>#:R sb̄/NcAs.,<# 9 U{x>-B3n# ,&BRG;pAG΍uA!`>Td<\5t='gœgtm8oNȶC F;_rs ~lƹ89(XͶ M8*w_<~6cц#8s'W(]@Z=`) 5s4DD a*&lŊl7mڄǏY9'""@h槐_50s+1c@;SPoCz6GȔ)|Sz _{LָI4\Z5]K 켝CvV9-[C;=>( [.?+dcׯߡVK*彈XtmJ rOOƵ}0M5y^}!@CD_""" hO:~&ODiMAi0pln{ǏE#GCFX61!""@CDDMM^^#:bMb0yL+?e= Ʈ ^8~68i~\UK6XFDD 4Cz!,a'~ڄibv像?JDD"""4_#- w:|= KI; 6:_{L{ K_N3<4vxxX^x8M&4kU}0<ҫi,u:6TD`rd!jL|5}tӏ8hz6W~ɾ>Nׇ#7(< @+->xs+ uX8 h@7@&6EHwCTѠp|E@{&ͧM0sEI)~ؕ>.јj lϴ~q؁َ;`/DwDDhʀ""]pXh8~.;_W M2FM7Rn wLilT5cC0$@VaqganYEaU͚逪hjSm첶 Qh=UNXX0_)mh {eʎ&h∘aB<9zJmSi *]͠:r=b*^I `v7q;(l}.EGEY7܏Kxj wU$.x 0%ihMCϿk 4-GߎBuTG"PgQ(dpIA{h, '}YAk`1&/D""bT 4̠S 11͛ DHH%(ӱKڃ9g pf>NN1 mhf&lB o5r+:M0q <gM4#Dq&EJ-&,GW@^{A@MT+860lKcCfUH*w6x6 Mg؀uyD/ԙzufΜ`Lw=}ڿ?}}p^B$""F@@$3>|AatuzAbA!x=Vc b=mׅ nsW[H(@Qqke? Zqhjٯ( w|Es+  atLÑb +}T}8Nn_qќ>AEe{Y u*Oh4.K6Fx¾Jёj-:9Z IhHbf((R< ǚ1NvkҒ-M6Mغcj޽ի+M777,uf_ׂa'^+\DZ`bB%"͕+W;V>bt5 j/qm~u,/IAK'a ߴDvIjFFcYXwUm^OA2Vc{t 4B \i(Cc(kr]F/AcGp ⃑襽d:{mnw؜,`חR)K6zSP cTSO}"+1K>iӛ`PTQnU 3e}.Fkn XE<TlH?*BQ-?A&U\>Zh33W"C qo[#Nٍ<#V=1^+gS!UPN]p[Lǟe}zB>DysB4B~6ҥKaaaNkii +++h֬YSxS!""@S%ЄKEaFqqqˁ/P:_wl=R$ToF܈ITn041_j_p;F6l?+ľ4; aWof?|]/hJ-1Ag f3`J,0 ak07 B<;ےД܀SgNY<~|k}T?QOTO 2*F;惠o?^pq@S:}#R)MFihCc\ڨ^=ԫU]]a䞗Uov09x'S9)Lơ?zC  qŁJ KD T\>lү033F DFFZv-Rq s,6)|䇥?@<h! J<"|߽ jXnŠyѹQ}P< 'SeG+k|h9"GD>DD\x#UEyYO h%s #xխ\pѶD{ݬP CEXة>:-0PYS e=Fp[PF$L~sٟ=,x8F~@#cѶ~[z$EO55:|5-C8lMx/Oנ76)x<(N=ԭ1^xv*fgtv+opkzҜ"dWbeb71|$dYwߚWrVC{Q~ V փDZ)wyϟ| ]nW&(vPzTPɻx$YonZӏ#OD!fh0xgEEE@#ZxQ~d}2t?6@+ EߵAWffTv!ї`AUG9PLiŅ/<_!hoˏ#UY?(}L;}#"MHHkTFR(f]< Յz[ވ~gqlqZ_ }Y+pQc%pŞ|A]]fz E\9 5\R ( _(y=N1C/HN* g,: ґ_(@V&6(*x)_MFBʓ 0G;U8614z/ET7( P\%Э Pߠ}GRJ(+4llAWMO(A#Q@wdo}Ai;ǢeYp? N<@S}᠚=)~ *t Ma 1pN}Sr(^|QVQ1 aHtiUuGeF{^V <.MuB;G.a zQuЪL,?ZfVQ.ZBK=5p9|;oPx|km9 Z6n ^oDUw/)ڡvLg@& &oEmXk?hA[η4 !+v[J!/wEU X}!{-mSjsdq'm5P>X/F *ou80"/@9ˑ臝6Ј;R$\x{e6A0=W Q5/jTK?'s~"X^l>HD2{4j`䲐; ¡u&ޜοTZyi*g|\޶|!<2gcل~,<S4+t> Ae0䄈Vʛa a00h=4Kx-ݦTWve8َtY-YS `eTy:< ,V͑I;~ދ/wzG$Ro*#J]p{Rb@#(U@@P4Q jAtuDوm)hMQF~a=wk~ NsGTД"51~-mp.P4EA;}8hntQI7n1~I/NDpGiG ,:@QmwVUD>K8UE0G/.CaCRjhm .'җpB'dMMm)B18U5R.]B}RE^a/^~Y3ѳ Mz8~MY]{!l Jh;GrUD q>m]Gd5dŸT0r\ʙ0 Ǣg+]9𴚢E\ /'5u4h#.Á_Ki Sٙf@Ä1@;ô8h.Kb)E3C;1ؗ) 8&LKD LZYVU 50}Q\xTJVkxFT\uhS {~O 4xk6L Cڸ/8:U)fN.8ݐZ!lz@$x%}LU@SS᠚=)r&ʁ =p2ߏZfu3'3VEYq9 b=>/\|txKhI"cfk ]U.8lh/ؗ\J"C# ?h>%NJ(_?TeņZCa!g5{+VQ␳7~Y.7e¢3MTH,aЏc]ݬ:)* ՠ1QP8bOʄq=Ǿqza\-8|ac_r )HdžCqCk0jav@aU3q7"6\,ܬ)}|YoOx3 T.#nF|t}dnE]Z?9&@CDDFY{_0pTJkIk'b1h >rΉT 4.]Tߘgd5}N \v7(&,ZwElAKq<" pɹ_ f9.൚q;zCS^F05="OvrióVZG`i? 17d9u* &@P89DeTr&xRh0Y hj,DφG! l}J\XTZ4POo8b_8.? $a`Mp j?.EF|xJp]7quƢ6l)\=%?[qfirv~|UݣPǵ[y¬Ƽ hJ﹣'G?BD(Ní5G;%zsvmm9Q- HxG vϽ X8HZ>\Yy0i>G 8B;C,ː-;U hD"޼yׯ_˗5իW۷ou9'""@SЄF*f*&F}Aؾ!S*Pkp^ et l> -a; >U;_Y\EjiDa=m%<4R n^f"j< l>.as_~W0C5*0b Tw^6b֗9ǖBQpRŞK!. B;gR+LQ{=AxoIKjxhSP^Q^۱.dTHD  hz^O,0"RI3O<;wc-d)w$B~4n:g{ Rw4%H> k++y+zԋbaEed ITI`"4DDDD c0re6ɏQ$fӆiˬ0ވCTVMo2wW/aܸ!0Ua-J!@O-^U&0vyܵT׺k)2.ms'x͇ϑxg# T=к&\ :b D ^!ŁA7Lq/KZ'@Ce_Ј&o {Rd˕Gq+Wyױ xx%2S!"""ʁF+hxvamX`$b)#˒ v\ 6NB2%ˋn5㝱tΰ17x'㍤('>k` ScZb~%fCp̰%x`1?^PIXhs6G 'Y V+' Oޓl/hD 6$G.!+9x g[MbaI~n\OQDAoh󉈈}@#|uLa%94ImY1s ?3m\qܐz 6bpLC'!2έĻcLC;K3 # > ]#XTfl]ri )B^,wH\1%v1R<>pvYkIb/`05؈4RGglb?}yXjmSK,Yu (6`1+/aKM2шb+)Rll,ۖXDDD<Д=#Ba&MDc+ ?)bc,?&mx-9%H=cz&k#C .BR_*0Jrq{))<|7n2b%ӏ\W"PorK%2@c OiiֳcWߒp8(5]426=\~@#|-#Sk,q姐L/"4ofg=a*IT=ctudxN k0`9}qb@S46}T{|ӭRPB3 &(I3qfhFk'L7"<De#[S̋h#;cٮ l1,?A0пm7c5#I55B֚>K;8::= + 2_` 5YW%[ _`T>bt5 @ _S3mW,rǓULۅozfR x?S _-6M#0>94!HM\D@W  uq-k: huSpfae;bW4gmば3s G4|x_FFhB–YCb=!ioW4\ 44_: t{]&pU%6ߦȖ尳0 =NᮂgD!N?RKM0ź*=WބU63oơr*dAfdm8NTGfvZ DdT4%Yqz hjnN Ј>6Yv#$_ѝf&&0qG0?){8ڔN{A J"08́iϞP23p'$ @W977\FJϹ a{rR`$DRo㋭rV*{8*T93ߊд"ёfbM(~F;qX#_,eBL"{pUlse W*2b%RiCdda Kc#ي';lh[آ w@|2augsI4"X||y9^fFey^v0\I+Dmp"vf 0`J|68#tV#e.pqq+$[`ad/&ފul\C FB2W 4~~~PjIuj4D^uTZa*:;flXyY4rӮtt患A;9Wq2;*ݘۖB[gF8<:|CKl~@ĚeRP@a< =-n45]@2#B!BbsZ~xU#eF-\V8xyBa>&;ZKM2#E&W[X0ޘ+< ,M(Wq9\lP8o:2ǁˌaVТi5䭸Q]U#Z@=J߃6Zx]=Ϣh .1{eINxR Dǔ\O9鴤ՍO˫Ծ[U0cbs $\!};T4y`"5wd6N<˫6j9$}]>G#=}](:R/Rj t1'kuCu.63;a[ W8'uZg4CVCgqlB/`Y?hs*4K!dL/O8izjrt}5"cxA3hk c+&IqVyh8 spfQ[v4msr.@ ='q!l4 4_Д>qg6ͫ1s٧ZCR<8&b{/a:κW,0E"gkm/nk pcxmW$މcXƂΤ",_\]6䬠,M=-Ia[1,m~W<Ѯ*0=*ic %!"%rh*M{RmVw!E?JaIK4˪*&ɽ(.YJVHX|ά:4)ZrbrOv ˀ&.=@iǞGFuf ژz0)R@ΠUO&cкj[kcxOp i</"꫏Լ*UfhJusLyKhCU۫#E7(Ş#e5cbs9< ( \wGER4`x-n1g)FơЛvϤU:v7H~{yi1coSJ3.UYf4Ģ$KQ Xf3SX;o‰[(u?h͎119^"] {d [L\O~Dp-:6E(zXbc.ޏ@#gs?-,B EƉ !A%YW !h$>6K`ka,_L$r,l.g'hr&X+VL\=y找ZaT#SqrM: jö^^hDZ @4gx@ĵ@'`Q-45re ˳1Va v45M)kDSL۫7ղY.D΄": _^Au&ϭZ10LuU(Pe^])l<ǥeUGaHfNE\ܑ+M#[5út4./V3Ԧp@@^=;J]p{zYXK\NH 8?3H gNk3FQobf%}")oJxK;g%k3hKVAKaew ,F{Cjx8/1Vsv=X 1o9iH0rNT[<'lrX]oᵠe,mrb ;[" {(mX`Scb8ǎ -LwkXLBhZi@#H vwGؘ;NU1n_>z*Н~U-s6118aT @s{U_ڨ/ &P4h>h^̂+oTaayO ~E_&|lE>}bފp\Ьmj(V^cˌ)_䕵{wG z/Apg2\>ZTL]}!p5d&hf-ĵ8O|\WOZZyN 4DDD4_蒈k898j}4"1vRW-hP!bYS7P?+E&,j p0Ye+;v(0 F@ @u]U$~8SĽn-GZ,-3mfefj.@ͽR7@7*D{ s ⨬磸q8|NԹh)B00d y8K!,3jb?+P"ޟPGfkßmYo`IIAckkrcYF{Pc1Q1pȽN8 TNoE9 *ʢzu̠!b0h[7F \IIln5(m]=²bj,>b`%Sطe;p`k=4_0Uz-0ư2͟ t ѳ,:s{Թ#~[K`3 [3355ihhx&h"jNwlK(#oJ4҉}e9&KJ7>qQ\gmE|VObbKK:·Wc/V־X9v@pn βJSU^2{%6oۄy? 43DKSTلy&zih5+?oq:uoL_~ض{4}llwⰨ?plT {͎w[,pAà!E44sΒ]f ͫ9A Lplŕ(4WB|OCEi3{'7hF}˪}G'aud.֕z ;\*뼠AĹUueXM5o/ 4gA1?4WC 9*HU2D_ņۣaUG@vǯB֊ !/U]6QU8k.TmL}s3~jYvJ6Q®J }nZF;Ŵd TiOgכ'xgMD?;&[Zc|VIrW!g#6oURS-*6ꉹ'aV;+ؾ3_{nҀU P2/g )VΨm^^HAc]`ԄUAM& wLÀhҶ2tî{צ;ꗅ.0pRU&\I1K=|YKYq(8/us\^;ւe]9>{`*huQ%X+&=agq xj?4`g#F3d1grhRJE8iAKC~4\ƛZnxu}귺0-pUnD$hox_B>2e"rvK4DXXf яZ'wp:tK)c٨q{m82E@?|Yb~t]2{3eEei745/_=[1:0laIqUZcرk;r& 4pЬdꈽ#*T)A2_7O?~!]!X'Jrt[yW;/l ڟ4\!-m7kdQ@g" j*BHI*kPۨcx,ۆ];Wã{u(L⧠f)íڃ!! ýq 08rrpMI I=q`#ä?Z4h?~ ;vh%Ώ1FtcNT(̙e;~ꕁEˉ8߿]8p*ͩao o<,=MC:ZVGsxl2p2wƠ`\] Gnw-̫B;^} Kޫv|C1/.h^]׻PƬ몼٪|yeɼ4K\Cƣ| ?ga THȽD4۠hʹO{͔ÿm96pHc]266ԞZa+J.- 0s6<J"ϒ~K4:ãS}TvB&c "9앹0sF䝴ΠaмĊp;gJc<7M i9RĀ"5dh7&#$%ݞ4/u _C 2#'jEW('F"E^>\hOih!/ޛ }x *H/kJA%?h .n^)͛po4zz]½¯~Pm\}45o 7鐔*-J h75W"*(;5?$y8h?okbP%.K޺ZG-6$wXx?<ڕEl'g4VШh7eQ^u[[dB`>'Fֆe΃:G5e^Xw3nh.ko4H[Qb^7#9@l"TONHoK8c\eMQÅ_g&!t=$PTUOzP܈$u ^v9hosp1i켜i(k@R2عQnbe{*9[B^΍g?d2hq"qH6$ؓFqW Ĥd/Oq N_OG9y,{DW<, oYk/y9x(F^HN 52?ԕk₆&ѿ}W(h2pg7p.Hݎh'#ι78l[vhvV7.4[]ӼM_uӰkG=]ExqƓw[Kti=F~ra4hŸ1hq'1SYؾ6꒿fV-Ƣa_>G&-jr VH 4nMƄEDN͑*pr7eHXڈpsphX 1گ޺s7q63T!!%7ep> %,W婸41H/0s[,\~~Rp; 5~5bSc~J4III3f`1i$L8QC]ӱ}vc9"Iuzh5s(t2/0*CTcCX!L]d`"{ܴ4J6,ygkNl>{/j\;úwիWn:x{{sEDAt|,+9!<>qu NI9!Rl םKs֡=f3Hܺ| . =ELI^uL pig+`c'Y#u7UF3T!1pO Rɭs}fRg},=f~,, 5~9jAS\ wcB1k¾Y02]sߢ^ x GlD]KD]i`+/ DI9v=xF<l'bP$ZM`Bs?Yx,.tw0'^Ը,79 G$eF}zH[20im4 ,s#?b1x[[@J_vn >F\x ?sp#qyN"|rp:(u73ܢם"hΈ1XI1F62>]{$&+)?[w"KF[q669WxZL*N'DЄgaJ0QSbyBb#>D5_x̸Agt׬2kd6s ;Ǣn=u'"oj6esj\,A(VƠn-Jm}YĉLj`tFX30eMf8#"aOO/y,cbP59 e"Gewt'ʫ_uBˏ\,8Yֺc>^^5(1!g)c5ر?A{vpYͬK+wgBsuͲD5"Uck:.3jD%\ev9{::_>gCjĊeo] rpH,HZDj^ KUcʒH8Mžln-ugRh_$~tyj nûKce]26GDv+~*xᳵ$=wᴈC{b š4NUaگ T 4X6b}ǧf) \4qxp;?Ç~,w0A< }'c8t]󏽒z)txMV$F{a"5f..guinCe}gf:N*nu\w\:>bIİYL؆Fx|w0ҳO.Kϡ\x\lϻ3pC/u>XlOR#_E9/IL0سg4!z&l"5C$:6"q"'xm#%ޛ"g??'R0O mܵ3I{!3'S5a88~_K䅹ć's'Mc5qbP/.|86^'ъNE J~?N_Aq)xC\s=#rpr{e7#CD͌x꺳qDz"obSЃv*ƣl\A|b:z{\&koq5V<.6 7E_NDe=kE]_b݊.#MXp\2L+s^o@Ipb⽈_=Aq_.#ۃwwaσ,!x/: t{֊ĺE $.4s?~ftsH-UifbJl߳?'T\Wr*aЌ? ~ %9Gc9=k 9)NH?@@ _~G$@+ dZ1~\Ȼ%5aHU_)kv=sb@Υ4^r=Ğ޷,M}  ѿ=h~bzkq䲝=b`ncf $f#>bPI lsg'A3M4'؋ 1HAc-&7!"8ΈݴŹ{dzu7ͤc߸-M0pnYtArh&Z˄X.n#ކbp%ܴw$FڿK迗\@X?}~1Ex>i@hZvlŌܽ/Ǡ"hzy\v,>c'r)wTܘ. ?lkXY 7'< n h4u_lEМAco=G4Qed{ޚ!֭3-&[l[EH1(}]L>^LDEaX5)螣~%noZtJ:>`eȼǼ{TlSҭW*iЌ7NsY2ɉq8ٳgk,^X3~HJ 0GfذaESghZ6f2ȭPL_: ;7@+Vb'>& >9dJV}롲C(LM5h.]?ԀwO?4W|4{b uAS?rpf6e>DOЦNYX*-Qq:јy_;Xt]{[bZ } ؚ̡&}sBEh_ 3Tl7އ*0VU^#u+f}9gZ4zG֔?)Rb\p*#SYL|gSL+Eb#~˔Ccs+IMqռ,:wA<6\n3M5=q@jlD*wOnkc3-kKxoU5?ugq oB F\FLv"I]`Wݒtt/z6+3_9*b k5. F֛6"֭]"SoḘ1g=.o$\\F>y-3EaM%_PDTf$aXnioKyLmFo=G^MB-)VVu,%SM ;4ً=_]skAPQ#fwwo@>;sݣP 9h~{gf3eŞ;4b!S({4 mbA lsoAI_[8|< =' rph*kbk{R1eQkE4Mkn$~IcyUz T#"<mv^2 Gy1xMHcڊiCcRo^lFlDEgb8t^/GAzÛڽG|%;"֝%qSxWwWKTl~1]pZbֵ|c "hzKe|lŠx&"q~YĥR8LIf9lۢ{u$lJg]b-n߼WuX0w3I)7R|4 ,{)MhU.b{ޞbX)>E DH$B.sOE<qR>wD˽jv_1sQ"#d`8jOUcs:JõdF1\6=&Gb5qyfNvJ4cǎni&ܾ} )I"n6Č7fڵHMN+0m4^`0/obmU_WtQBuWN 9W{Ѡ18lFZ J?!8μL\NF㸴M@ywFZ"j:)̪ 3ýj 9hzASLLLR(%(@q=) }lqCӒv GZŕ:ü-[8u[,SsJ_GWav*zyە0hJpYQpŘ3Er~ e1pШDLϪ:+UR3h44OS5/c@̘ kTc<=z+WEF:$'I{MsH">.qx/ {xHgdw|,08 L}[}bP,^-)5*x`l\={ifc,1,ǢT$Il X/oh15e bl\UAI4%F$QGN\I[uhlyms*]H9݌P@PʊT33ײK 3raj\Ka %T2:MѻVw_l9n6c pJ_kdisj6^WtݕX. kKM(-SL1ς犨D-2=c~uk=2.q31MgO9/il޼YsΌt4sTdg#''CΞt^~%M/y}hBdS8+Woz1[(o9B bKt]Ȼ5ݠTt ],CWkIvYwԝV5,h2df]Iˡހ^֦5c lBh3=:ֲ\H\2$d\},{b_cN>L7eUV ,$f$\=d[۟iUR4Ii-q5 QmV bg9#9؍31౜Y8R+-s#VU]w5 &=&]umf9x, L1YP5Br0)wŀ0<1Q{QzyI9[~93E܌vup,YXg]3ճz] e}e@v"]Ot0C1xu2TA"pv 1iaK兗+~E#픪'FC'jJ9)QH/v*Pu6( 1h4D\H8t}Pu %=m`y s`ZQ sG8k'NDaTº;a7>g8|5]`c& Z0sTR@aU -x|!~6uRi{mzn} f`[\| ^@VFxH5Ƚ΁Ѡ1{-g\G-/tu0C1't|5NE3\wڠ&୻2u"ާ2.u|dMRI}Ǩ_JSk൸X/mybs5'jF^?/JlkCkLlsszma&Q?1F(WF3h3`6=Qx0Q vJdf6(W9ޛz{"~-Ig!֟নl/]A ۪o`)+Ӻ*;B_3GWB,-k8\nǺ]1nüsS1׮oЮa58Y)r)`]~&bhPrZUР7XSc᪨!AM&" ?L 4 Nݬ,uv6hdhl{[3Ws].XUG/`˾}:K4R{?bzrv[-PJV=Vag@vx~W+;-̹7HT]7pbfN|a ۛ6U쇍߂sCp32]MwVtY#=kd.KoSp4Yګd05ǻ^q;c}zUx.n~A8z0v- ,rJ\1BjF&!T#y{aOAc[iEZ;c] qZwa_``Þ@eP zۃu1}>'C&lĎ#8~6F׿+ڇMJîw^]a$664mF^f܏wbvp2G&vq- ]샀 = q㓣@Qs8s3"" 2[|P8fۤIyuXs`쐳^u篘k>MwiPhJZ&e_]PҠ7}lqv Gn |+{IyagVÃtv$h8Ku?tyO[pUů&+q#z/G]`Yo@<Ҟ吳Xf#$ouwHOE|UY?o9Teqx/2[+>LJXq@nFWN 9.t5Px4yྼI?65t#q<)h"~o&U-Hx(myfA#MPC:N30hAà!ze'*Ь-,X'/~6=Gal`FJ1H k'9 1ewC=HE]>;*+ tɸ,q71- E.9LJ4(`-8*^/c7ꝫA#so9޳-R0Y&ڽ9jWMYTvBiO#J-_woJְvr6&᠛#35VaXRИW eѬT,sʊ1Qk d729% p *^|OT(NQ"Pv_p3g~J}Eu\GjniYwMQUQcfLD  +4w{in'׷7C_4 KBwRn|(G}#AӰ8=Zq"?h@t.JAsrjk\tIe\* >sTct#383 <5h4j<9*[FxkE=+]qAzx(rzka83r1\y4f1sʼ&);`I{1>saW!:p뢂fѠ9 "h﹁$hT+l5w9 G棇JJ(_a*,Ѷ"c,hR=q_-!7 F71CC7b1h4.\[ϥY@m϶,>ָAaf6g2G[; u6Eat'qF:*~>?A2n3ꮪahA#~$`mdW9|a`Я5LA輎l)Ҋ]wEMbs_lz꾈!:V;PM˕frv4Haeϡ*Ad"ԣ1bcCΎC zo1-0wT4iߡA#߱?MĎ@X0M^U#hqdd}(U7/X4'ndjDsu &Pa8Tu :v%.[R?Ɵe^+:wӴ_Acj{a߽+g A:V0n6*ph; O"$ nJƊ2hr?+w߶ UI ,3F ;o//caX+[f]s7ڸ{Mmw wu{MN(X.W>hROblCU84?h43(^ǔˆe^[wڡأyFf^[y'rFDĠ!/3% >b#Cwr'׿R ` 2eyEםv[mp2?sWn8ut/Vyϱa_ :msEKi=3Ո$M̠;ACDĠ!!g/_ƙ1pUTO;ɄWI 3%ˋA 2-*5~ք"A9N;i]298ƛM3tZwxACCΈ4De !gDD "b0hx1h4 "rFD "" 9cACCΈ4DĠa3"b1h4D<䌈4DD "rFDĠ!".c3"b1h4D<䌈4DD " 9#" 1hAà!!gDĠ!"b0hx1h4D "" wACD "b0h4DĠ!"b1h4DĠ!"b1h4DĠa1hACDĠa1hACDĠ!b1h4D " ACD  4DD "p2hACDĠ!b1hAà!bAà!bACĠz"" wACD󃀃BVw 1h4D " aACĠ!"rFDĠ!" 3"" ACĠ!"rFDĠa1h1h4!"rFDĠ!b<䌈4 " 3"" 1h1h4DD<䌈4 " 3"" ACD<䌈ACĠa9#"b1hrFD  x4DCΈ4D "" 1h4D "b1h4D "b1h4 "b1h4D3 "b0h4DĠ!"b bACĠ!"bACĠ!" ACĠ!" Aà!" ACDĠ!" ACD "" ACD "" ACD]Ơ!bAà!bACĠaACĠ!"bACĠ!" ACĠ!" ACDĠ!".c1hAuCD  4DD " 4DD " 4 " 1h4 " 1h4D "" wACDw 1h4D "b1hɠ!" ACDĠ!" ACD "" ACD "" 뉈4De " q!" ACD "" 1hACDĠ!b1hAà!bAà!bACĠ 1h4D " ACD  4DD "bACĠ!"bACĠ!" ACĠ!" Aà!" ACD0hAà!bACD "b1h4DD "b0h4DĠ!"b0h4DĠ!"b1h4DĠ!"b1h4DĠa1hACDĠ/O" 1h4D "" 1h4D "b1h4D "b1h4 "b1h4DD "b0h4DĠ!"b0h4DĠ!"b1h4De " 1h4 " 1h4D  1h4D "" 1h4D "b1h4D "b1h4DD "2 4\7DĠa1hACDĠ!b0hACDĠ!b1hAà!bAà!bACĠ!"b1h4DAACĠ!" ? "b1h4DD "b0h4DĠ!"b0h4DĠ!"b1hACD]Ơ!b "b0h4DĠ!"b4DD " 4 " 1h4 " 1h4D ACĠ!"4DĠa1hACDĠ!" 1h4D "" 1h4D "b1h4D "b1h4 "b1h4D3 "b0h4DĠ!"b bACĠ!"bACĠ!" ACĠ!" Aà!" ACDĠ!" ACD "" y1hACDĠ=>!p΁sd/8R.p`iKծY̖V zUv6ٖzI̹nmIε̬LwBEGǶ5U"Tb>~OG_O:9 ?yA hA#h@@44 h h AA4FЀ A he hAAF@Ѐ44 hA h @4X&h@mA4 A hA#h@@44 h LЀL h @S@Ѐ44 hA h @4n'`0f׮]'l۶m{nlݺ5vI~{㏠A͛0d|$oqDЀ1 A#h -[4C4=4'4bӦM0͐Ms4 hAsܠ1#h C u/j @3hʘ4!hފ9V44!hArf 4C Cp(6qlAcAck h 4?.~gM纸eO^y1n_~ظXCpwl"hSYfo|{{q{洎>h_[~~$^/bx{gtvf1|u}_9h6ݸlRr7eHAkmEK:h)浏?\ hNBYU >`FǸ_o=Yl9ͱ}l\r3q };>:fD̽/c@ 4ӋYpilܱ_cǽwqU6|CNkIko~W]{s<м6h;{Qb˶b=w_Aw4CfA4 Y5G?s˧GWzbᝣcRҸSk>?|{|# cjwGt7|%{d#68nc‹4h hf E)fYek`HfUj4szY,hA,>Ѡ>hieނYdqjA3112rvzEϭ\F0hN-4*3SLM-bJ#hM*7*0W^AsUj&A34gVΪTVVTVTt"hL-$*gvy5h& 4k^p'l4rLN8hLͬ gI5gvf|4͓vcͬӍ4Tsrj:nl`m.)(lqZ]G#hAfrygќY\GSn;sYc٦v|̙3A3q0@,ltClc:Sn7+[mL:,vV7*0[6ɧf3u˴RcYUOfrΌK-b1Vij!rviqLՙ9hF|Ys>MOT.K{.OOvsUʵT|r}ʍJ>|>p<S\ צ*5Ss|"5HOՙ|٘2mg4U|٬̓YO,[Y]9ʺ*|rAra墆bLm.SK,OmS̄bunViʭgfqzezoeMF/ɡSZr<06XZauj%h3VV3u˴u5Vi7Qӓ@L ҹyfibS9/9trEI fUj"XYb^jF̔[7Vgr4Wiֳ)E(fN:q`~:zQbӛJkysɡc8=*ee+R,KWdbN33Rl5kͨbDM}Qb ڼ"l69nͲ"tVVs<_Zb5fa2-fSkɫ3u˴Lt[ZEM>(`z-M^q8ygqAVs L0 +29dmGh3yYwje:+]Lj|MMZff-ͻ7YF"vJ+Ee3)We53LWje:+5՚|ڻ99t^9E+19bf+2j;zY^ -&_S3ELiʹFșYNlj_6Yֈ)EL,Bfl㚙2fL=YIENDB`backintime-1.5.4/doc/manual/src/_images/light/main_window_sections.png000066400000000000000000003004401477034762000261160ustar00rootroot00000000000000PNG  IHDR4+9܍&zTXtRaw profile type exifxڥYvDr0;5D&EI^Td&ჹCfYWr[lMlBO?y^[ٚﯮ]P_iG~j~^ ln|?f^J\'x ?Cxm w4Mb>Ÿ.b+;}Vo+ѯފ/_7.q}ʱ?ώ~~]1u~wop ]mwbr5~Uz N;5]swr&[~_}⛟!;V8y^?e^rxw,_2s ɖ=^fmxĝQ5ׯɯ&YY)0x@pxc듃K'6C6D\H.;[/aȊ:['.%ؤ!d|S.Gou Oɰ:Ί1?%VbbJ)jjcN9MI%RjiPcM5Rkm7ZnZ\rӝ7>#dFeFό3<ˬ; XyUW[}M(λP;xɧz^{_5򚿞ˇxNp3Mtxlu1zyN>͓ɳ$-'Oǽ}gQy7SO~sFKTؓ2 d.ccrc,gPWè!/7*)LΘcqTWƶ/63<&Wn\7cR,rɥgk !awˑ}E-ک?\tﴨ}[ļgxnP{ QB9!'~Gr蒑e;Ry|˕ ´ذ\s+ߕw+{qܮqk(aʹTb&_XqE/05hTO/^!^O ||>xkXݼք$[ }ATyȫQޖ}Q EvN-y;I>B돏cPDagT0,=ٵ.^%R]&* (MŢn m#,˻Qu@q+HgC=.a ./S\kyA&>;ЏQu?4Պ)7.ANf?(˩-7@{LݭbTeR:C=H Gr(kl;P!m1C՛q0B$F쾖9ֆPX5`?K-;fNiaBÅuJ:xILD'D,T',$ޘ'48ɘn'ԑz{4AK; nvm Ocj,0RxB!zftxaԡ[̑5q &^sF`z\_ & !a}ou# UMg+Bۀ~г)mQZ۞ $NL0"uLrvN? $NHAm@}qAɱTk7q$ٳ DYxKV7LYl/nDڲjN, ^JVD)^M{$xƞvU][z.(\?LQnvNYbsD-Qg3w2q6q "Ӓ%7 t ڀo#U[+sek/FM)T:`l(hҞ⫝̸[&CtY\ֶ :Ȁ{0D}-';ysCQ~Ua;QX@W)~_2F\sAks9z*~FA u",p#5xX5a$Jx@A; *xjIUÇ Yz)u ɍ`':BH~z ҍ5Jм @|\mvH'ɻJhzAPcrGG `on$7}A̓bXǠR,,-<ҘOv*,.OAHQrB0#b'|Ȋ9KaIbߋ3fwF_N_lz>V X|,ݡuh2w0xZT[(( (GW ˆɳuU/ Ɓe^G-M "Rj$xu#$tQ[iTEfA"ludCDjdϢcedc`kS)PFޚDom 6&>چ䙳ʨBK*Y}Iwn ܫcFb 豇 L3'ИUHF=+RŇǤ, ihT;6q-Sʼ5 [gzOC'J& 9~VR^V)`8YhF0 0Ѣw(9@,|U_y%B% |#},P56::Tc$H:j'k-`:p۩xwW|ٕ-*iP}|K99MDZ*eG%LZ% +ۦ>GY\hy^ Pfk^˰o(2"vPh%#҆xJ@HC'b]2{_3*gv RAO,nF[APj؁UTV5&@T/4. Ɏ5>=ݳDQ_ug0k->;:6tv)"A}.`HD dxr W므m;f:bJ pi zTπwTPu]P{$YSP7;pʵ4$+ ))=V#d;`΢Ad@VC5_LfZ՗&C|nOM:'BsȣwBf&U$|I~ DH΍ ˵ݫ);p:gYPӒ"\.2`<,3Ӵ101QF(8Ť: Vxqu,%6L`֪j: b@$.NEZ^:e3Z&)kNfDo GW4aUiT=d")ι%Ei4v/³'%`z M{:P 疡 Tm1NX\0 ^GDQn$L(Ks--ȨSIN `TWR O +$ l׹ -:e]0<бWz<V&D>TtoP?x匌K:glWd@JS1>9uLĄXs$V"J'Wb`-#y>)\wO YG{f{a-!t4rEJvWo)8?_4pOAE]S>`qB4) ;uhTBp.~7]m ${JY@|<ʺ}0Y}HNl8_M-Hk3EDHNǂCu^2=+k9C]0^/HobTU(ӸOh\q9h1"CqkvjxFԘcAI ҍ[;y<IdY,di#)tyobCv7h? ۥ]_.">wpSþ14,[%/sQTAmhb´T;HP.7]${"pS|Ep=V G[z$)y N WWJJDD*Rd:xmHhjQ%3ey>O OB#Qe+sp ޢJBC(]DNe(d^kbW j&y8愍P0'WUܟ؝4m8xBu(l zν|x u b :za Qo84vEdE얁-șxAQ ܵR>w)*sE:ۂ"Ѡ0"+(/d.X(D T 0 d%3;s4ۋ^gu7`'EYtk*ƖH4!?(?7wx!5k!^BUEKszF2# MEHn'jDf7u2)$ed ږkxHL0?hLo$kiey 2 ݗ(D(9+TX&nlf> ?jz ftD56| r0(#BgH 3W}c6:ۓ5W2i'55(^+ b[r"-V~谷٧$pA 4;%@ q VC,,cvZs]r.$TʯݝpmT` $d.iMFL$fl=BJ8=! ozkF+ Ȥsn0(0NH튆W`P- ؙtpOB٠&.+hD죌`Ȓ4 \e_]џ&E"+4NyX0Эh @)'9V sZzB&^AĎFիW1:46nM J v#AqZkL)!ԴF}[ag2(%0-ijzvK+ouۃq șѩ TqEJE5F?qB:0.ѭG,;Urؑ8L:4T)~f9Jz K_ßD9ipT'bH.K~7T6wT*Nu5g"x,;eSM"Dž,nta/ |G犘>UD𢄪KPXa| ς]` iu@L[ga"cf[HtiJl`i>+(;)B A+4H-\[6y8:\E-Ifl3Ԏ:B GB.KH͵Ot*97>I32iRtDuyu:it uMl;qeizJBkl8+c-pxɏ}\hL:iFAsP3>(s0-t0F5zNUdA埢&{1l4 Ww[V|6=$ PܝvK√5R~C1+k,%q[e^ hX]A%D&ƪvYvs [MI͜{c2S;%TE1j;V%oEHI: |BsxLc {E8eˑNS:W"@|^AEJۉH#Ћ?]Q(^E~P7Zʼn$)L8+YOcB*)Fz{%W8ۀ\Jc3>A뉎aQap_Rr|dnR# Ho3?w{đ3aNd2{5°mBfM& +T1fS!CMbU`fe<)Кҏq{BLq:и̽NuRET=L "aJ!euN 0hjQq) +`g I5ZjM}ƍ`7B訉C|O~Ϭ9C(-=񭺛 Y ;kBu4z,hAI6تL=MIK=o vDiW#!3( p֕ O$#ɥ{rԡQ?Їg,~ԘW6_{w9g%EPBx:H2ń)=A=F(+9 %yb ECKTF "BI֓MCp]ć A86T')J2R *SUSBZ%N^qgAo'(Hx G}jb'.45Lȏ{Ibd߼Ygr/z+A1j,n`7C!5D|x~\gQFX-A)'\5YSD Z8iʋ)ܬF,q7g4nHfj-I`Y049T= R-uM# ~܇Zb=KW>A_t9hF+Ay'۶W7XkB0<=GBrH"DԪdA_\zKRx=;gJno)~f, `|ey}v=>; vKHtn~u@ê=L*'NF7yڵn1CzQRP?~F(j`+:IJҐGQ."E2VumUӍ5/F>ԓK6߻ Jו׵eҸ΍ TU#ʰܖ|}F2ZmJN%G5nQ4OaH";RR=x^V*)jr iWR9v!v#%29֪!U8WWg^`VIԉ I }IK(7Փ HiQaDW[DըkzuB@3ខVӹCXg *)jNʽu s{+לɘ+ndg F3z[C!>_wfGӨI}/OhF2Gjǖlw|1@9 뺏OY~5+ڿdJ1_uU?_~nyݼg_fw87|~߰WX D6 ; CZ ho :]M 4;C>ғ6.:?f:UE(KOtf믡8M9?MwSN3|jr,Z)Ev?=v6\SS|Dc^V^:MCB-)U.sD+u=x<Д躭mib)Ge4&^_iP5+I)piCCPICC profilex}=HPOJU*v(␡:YU(BP+` MGbYWWAqvpRtK -bxsx>@hVj&Ut2!fsbЇ239IJ.Ƴ|dO$eao7->q<9A$~  f>Iot0 \\w4e"OlȎ%}SܹqdhV+Qǻ{oO{~?Yr8 iTXtXML:com.adobe.xmp ] pHYs  tIME %odhbKGD|R2KbIDATxXSƵPk몣jv.uUk:nZ[Y7 d% IH{ɝ{9-P@( 3*,%(*QLU]%(G)B!B~^}m-(Za#j?QL!"cK Ki-h!B!Em}їCbcn@l MLZQ}yG/SRK^􅥬rZ7BB!BHX]n Oi-юcDlҊMZ2їE[PWQQJFL!Bskk zSVKp&#bcLj2%3"cLb*hɋ|UPB!g0nn۫dG[p ɍdFjtvDF-2-/U*jjQB!ƠݖWjz£-9r툍vƘԨ=ƨhw1SGe]Zm%.ڲR[CB!B v_[OzjhIܨ#7"6hhv4cR̨iGejEd"# D $Jt.*zJҢ7!B!CMSnwW9AW#U9w*PM-юwA3$5FiLie]˄wʹXiJGBB!B!G ٳCPEwӊKg3cLf*D?~|||B  /!B!DF8p Cx{{ nriHШ3lfiL%U_VXa^ B!BH.!bɒ%֪hMus%5g(q32#bmm}?&&B!BH#7-TRSŀԔ~?&ոZ eFXJXB!S!cٲe9T-5e H&:LL=fNzGGG !B!&GFݺu S~f,4Et5S?c8zyy!B!$=y$PڹEϪyH&UtFq3u4h0 !BH~' >>>x)<==ek1O,c9Wןzx3j4:љZuW3i#G&B!ѣ4uYΪTiGi3ՔhٳpȄB!$?"m#a9Vi0 *zVN/J# Mqcg3%~ JL!B^^^n۲/G``` U.b(JK#\Fzvt#!!!JЄB!܏rr(Mgng3$>fO~{6`%8 13mXXAT.RK+Jcۙvw3ufr@MM!ڢ!~j.歲\?[Eq'׊dd{F-ÇزC8E>T:v3Yh u7 #L/ojB 7 ڷDѰQ4o=M}Btkz7O?5FqM}dzm,o3FB0 BH! J"i}g rBX -[Z&eƤ&rQ*7fۙfU?Byh&-ڠ}hLհ-&FkoM6iܨcܰQcͼW'Yɗ!$P1Ј}iIKZL]!.5† ҜrQ'ziFLycBH^G%/8OkIjēC+4o"IA9rՊ<ŵ1G;yfbK1"y-5 Mm:}v@_IhmfgH>IlI3/8Ѳy4n+: ~Bo:<>n7NNJmn'!$`HS ا)ˑU1u9rQ~3u3菟nė&(4Ax* @#t^t8?ZNGdAh \L+yCi[AMgc[6l&gGp"4}H5-ڵ űusl6-T*i[5G#[cɧ.,$ӴT?Љp{nl[ʑU1u9F` Zf!D"e;G ZBSKkWxcBH^Ғpt  Bpsxyͭ\j7m#m0f|Ed"σ=FLV,4j7gYH}\s`jQ~zSڊj<:pǞm;N>nެ$3ISB !ECw!4 M^*L+ۙZh*h |-176!14v鏁ώh7F&Aat8~4NA𷚎"B_Cަa+L8i'172!Bcj22@_*,Fh\k-eLh*Ph!BInXnD$FyU.l;l_n֪W04h}3'._8}>+B`^hѼf]ƕp:LjW E̪@$Ph(4BФj@ bQnb`. –(Y]uZ6%'"(GjEQQƧӀKñU (Q FO`'4p%i5x}^e߱D(Y Z3z5ҹ[D##VGDb(Q[X| A iZ4_q/RU“ezD=<Dw,`vYj:1矀 XET8Xh7ku=hW5(lYUwƴc2Xv*XEn 9&FJHr׿]=N\AZaif?ncGd1ӊ &߶@R5c%"~ s]T-SL@pBםKT-YEBA`Xhr:B!Bڄ&1OpiMT7TWn/]l=J}F~coYf7 l:`{onh)`~}sh6G`wzfb?aC &Wք.;%]k`1|?>mC [U3e=' 9;5-+Ŵ=wۣ{y6#zBp93-3Vi9=?0Cz5c۞H>"n/@2%`uD-]Q_㰕-lNnuPpe87"4W ?;uc˸j/O$m{XFIpm8rْ#4u~RBf(;n sѩvznFi;R=Zsqe<2^%-'C;Wl #{o氰`&ɠWqO,]ܸp'4G%h59n%v_Fz%-b?-C8, tx.EcW F^o]VW</7I̴¼0*XݏDKkVEJ4lLӍʰHu@ahEsMwB pU\¥QSyR eS B(h 6'dLhLv !Bych-bޛZE-tY|\|y%:ͣE?HB;Es|{04G6~LvFW(bҹq3S ;g9 eY%*a^q#3!4 A׹4̴d14c7`x\REmpy<"c=b`$@/s~(G^/.3yI:=@!q w9!}Q]-ᙑu ̔ ɮ#!B(4!m,xg1eaT_jXfxCܺ;֣K $MN lz,>{y9@7@hDfQլ>/IZvMҀ5z,^ 8g& *kmܺz+ՄY8,11jao촱p^}[E3l:C (T\L4>&d9ڊve Whض%~U/Jpp "G#!B(4`m]Q0U.81ph\K|ZmUoFZ_gO‹X;>)W -QJ}c94 ^ fZ`c(4]H']| pIwŃ%f1}+2~="\wclQQWawQxQu 3.bg0BNyܤV)\fJ'ߡ; ?iEQ3KIl,g1pSE|α[&R3FlWP-(gU?h8?35 #0n{1U/&5KTw=Ƚ;(g̦mޅEw-QXj|UDM/JBߓH! M ! H! &oz9`C8G^.ٰa&66V<ܹk׮O>-/||}}&LFy|M6Qu'/d&88X>vxx8_.ˏuǢN&L^z8|ޗ9} ~7,]4Wu>WޯqƸ^ {-ςUr{/-4=oU[ !Ph2Oq*<폳^d-Ւt,dd(nPaTx]_? Wy`m9sL7غGVQsq$$$diBn޼uaŊi~zyݬKʒ0ԈeC[V^;".{ y/`\`̷fncbb9Fc}cۀ}cCfx.0ZLmp}z)B(4s zJ`5H^:+w TG,8b̈ vvY'3B'$ދIDKĸL4ⵘ'I+ۊNv9;;gZhD!/"R#{qwwϝ;3ghZd2#lmmD-4BRۡgOaꔉ|̈"Qܘ|ٍӌĈ)"ԇ_$4JeR$,1 Y1oP9)g0(ccԐ9Sꆹ ^_GdeԃE&>~$~n!r&_ ?=$zjpx:H^*6 BK=d |6EPaAYy)74YPG_ !FHZj޺u+WbFgV\)ˑq2鉌ʕ+0`DzDiL)4 QKh09bc=93em숯Sh:Qc@XlmzҫGzxsBa3.) >20 ; mk4F>}tIJ}|-]ܐz싐1dFj6u{MS Ь^ZN8OOO̚5 O'_{yyQgj(efIefߞmr5"$?3`M|ZQ>C %ph 1?j/C#m2ߘ$&c;tFyR}ӻ/4zrLh2ì<֋˙A!o/w;15ƶýո'.xM4?^ȉaV!tcƌiZKoO5BjgVɌdXѸ53"5bu"^3+eQKZJu-4e"!D_It7(22##P Cz,r"JԣGiF1_[dL8^^޿,B>2{m+cu$I̐\򕼾 /t.74˔/2_Ohbc7s%8D,V/&ebPB2LІ v4ek3Fgy ^>Od{ԃ~zchqrzB)B:+Lw4ޚ$ `ukf;[ʌ_Fh>_/e&#BQ gGhh'3$=^&,1'mvhTF@Q0S8Ѿ];93"5 ̔I23ul'^&:(N?N%/kJTM5ϩAkDFh~=sYhaTh/Sm$EGBisH7rfzn]rnBl~2evk$GR4YR"1rzB-4FpeYnpɧ?.+3K1kyw8:^v%]?2F'^4 ~aqB'%3eTj u93LDϑ1$2jȤ!2jD3,! {ƌ@~ˆЖgϚ>I|Wo;<8'gΨy4iuF~q.1 d9o k3b?AiR`B"\[t {lE<|Q4Ekl޼9eF`(mngƤFDg< ]1\#.' pﮣlX2򹝶y{}>D82*5Bf"߁=ϡ֖_B&ot9CFv' 8 w&Ha訮rCuUv˲T1G}[GW<^_BjrZf"%pi?XS<,3ijKz5zM_z-2d̈{^ޟ)AY^h,-۷5B\z7kt4ED\lUGX?O'ͅs6WO'ϓ{l݃>Bnr=˟B.gjll0wewxl^{e)6>AhT|'$b`9967rbccudF  )"%K.1Q#q i~Ԉ1^WHz,躕r茑1,#)ž2{|!(""G#FK2ꬽZfD>!wb)AHgkd)oٴV#493bB#q4~GkT;a gqUy8VN[B.gH 4;Iyy'컋\HM͏JuD$A{KF.ў_4zF 9~:߿_1D-*+# bCۊ}d皊y6JZBs޽,AȌ8OqҾ:dHmiiӦSN,\P.HܭkWܾqA#4⡙ar[hD].Xk>Ӊd{JĦհdU{nfi;Bм.gDaI8m2\Gb؟$byX&yzJ-11 uBq%I'5#/X,}(gETtYȈFeFizRuVME4ӛ:Ȍ6шȮЈ}}e7nܐ+"2fh^2"#x蒗HUzɓ'Ϡ޳gOtׯkdYkN~h>'G!BB/Gh\r A;}lE ^ybXGuDh?QgQnrcΡHkԛf*uu6֭[Di!뚪H,2 !l3} 1Az25ⵧ|x#nvT>bL=0or ͜9S#!~bәq\M )/뱛!BIDDK\rmlu-3x|"2e?b )#vZZLNPXDHEƲu6b[Sm,1Hz^P^Y'B!yWhB;U) - $ ׬B!RNƒ<$$B4@&BC!B!B!FUI^=6ZrOB!=D]t'N? LA!e9qJ|B!BCB!PhRSFc͵86klkcbu\p2̯oR}N"_ZB!C$lE+ K/*IK8q؀'YB&p7BC!DŽ& waTT͋t/ˠ-X,o"$Bcis\j>B [- eqt; ҲxeɢZmߋvE"-_yEx/BB!Ph t$$8 g]8uSyB$Vl'{HBd5|9͘X OL7ˢ:wGXkWmҢ2K5*wb(4}*(V9?|Q_  !$=bX%Y"0CˈqX$O M_pY?cZ+B10+>y8v C }-Eo:c}xs ԭ[YQW!zw qru9z~_%,`Y">j)?%%„v_-PTMw).&M}d,lGheCB/4 qx%7^Pͬ<2e>nI`.Z'3x%KÇ\Ct|nQcBhOyņBC(4Ƅ&s+ݷ5,H}btL8z ޸t(l/:~L WSby J lc6aiG#,QZ'T7G pmܺ|{NAfUge3a֟yT}37S)8{ i } Mj'<ǡ'a|_KhdI툽ۿN`Bx'"n(*Y|ٮ {.G-0{V3\)Xڇa/AB1&4JM! Mˣ۲f0+]-A_1[|})\(m%e w}>oBcQg*%j:,> HD s)Y0.ׅB@&ۓ'F~+Bynzeˁ靀j@v2 [}a#tGshʊCXxꂊKAPbOf8Ƣ"EKCpwUj]8臚1R<! ܎M9N)c^D)$5FbSp!4?UB:h; ָMQ5eTE /f;Ù!$IDh]t $9_GbL,kSDEߐݼUH 2I&rz%G^77eot"#Y.u?D%=rKcq/;ֈOt?ѫ,vgllqLjUf50UBFm0ܸ} ‡BS:&>kë^¨ }ƺ`-8q:nݸ[Y8IgU4{?ƦS=>*_LdzˎeCBC!$ r}ء[ܝSoZ̿w+C˲+4R֓Jo]?2xFOF n$BJ;[1;(ToCaQDhM" 3 1GB(V}\4Bcޗǚ(mi"}#v5B :q?VG"V"(]Zr ;ݪ3E*p}M}e,\ j } !|,6&c)eXIG j ^Yg٠cY]f!".,Sڐk1P}ƱsF9sh\Ru9K$$B(4\^fNhh]_t ^Y#"d;%;eN.]3Vߓ?Vp?' Ph!B*z5n#CD!UJqDh mx,zڃ}&īʘ0EtB D!4q3ZK$$Ph!B3Fk|rM:1A,kKVFЌ5II MֶKgT14zѢۗS—PhٽIHG|(4BIr{#DBt&?劭<>F;Ȁt8$ߧə_Cyp]ʾ$YpcP}|,%4x >} B!L}WkԾ.QwlF= -D .i_<"B w5#ޫ3 pjY.3uy`gLڙl~$o0K Mn(0֏|,%4=B`` ^z(DGGBEbu'ڝ>k%wi ǶB9 0+;y./Y&E07/!qǒmH xp=b>yDŽ!^( Ұ_Os|렜C>&FCaH81(eN8#i亓D&FگU$-[>rJ;$$gvI2uEzPhyB#"3kB!dm2(4r?*_LB!BLb"BɫBDiz A[Л`Ph!BH^1<)4BC!ByÄ&?vJx88BSpJ0^ÃH%# 9ḘoAX|>?H> GqlP !BB+_f\ !IPaξ) ðb`S"F,U0T&a&+^*dBlP !BTB#"35"(NS (xIMj9L0%\$yo' ѴIxC(,_h+8'$`J6 &ܻw|H*!׆rssc#)0.o'"&0 MRcuvP<@ i{uQM].aU"|"$9դ}ĆE?lL'4~6Nj*ή8;;$B^'wޥ28aȌ5h=l>ZVCnbtVFxxx>1Nfj+z8k M M!ĕAx@^> Gyysac'מY\a"fM ^ee/bBH@.Q4r{ha|1_Os3oٮf~XŔ;?FP|u$CJQx&56lrWCT11O#$\=aνm\"֬cw3&.: 6 ycBώFђ?chyWJ!$ ~bO$4cE?֣X}(0 t?lPp o uFO?h;r~{9:It]-Xc&5y&.'g/b|cbz$AChK̸ELF.HR$erKWҼH8 i?&U,]#D:A f2gu)4B(4ti{,ۯA[P(E?NIRc+IEx]%5h&-7PtN;BmK}a0 ۽~.|={pA;v /^ǏrSh~4[,@SQ4h2A@(r Y$)ey;c2j ;ÏΨSjͼ /c}oB1DeJ[d ۻkDosgKo/ mwKDd[h^ٍ݅AN9i$V]?K0sf|8orB ˢTGp?:37\BJ3X-VGʔ7YBIPo8=y  p\p[".mw/ Lzѹ}veF~(, r7nܐy&nݺ%##sdDH*" gkwaաK0e.4O4gJA{zC. Az> ״E>\7ī^8֫,,,Chia{Z_z83&J X'Lk*##Z,Wɕ8};,%%6Kqid >ċ/)+8s +{Q9[N ϝ\f V^UVk׮alܸ6m–-[uVl۶ ۷oǎ;k.޽[.}Թsg !]h/]n*wC>7 7~෱& M\Qcg.k=>\̺ЄB2EhBƺ_DL ZߖnQU-;Yok]\~.* 2vl=#3ј~Fŧr+NР*X* w+w0b=c(4AVi8.G"e.EAƶ(_tHH! /[ߴ6Ol@{66g ']~@FЈ ;e M`\|'nkpwt_vl'-k##}8 .jy_9%4Qx{g,2sYfdrTh'/_+V`ʕ:2n:ټy,42sN̈2 ѨC׈iojS ͭth,/wK?-}ݽhm࿽^7zK-ὪuEQ x_g*3V? 8hZd#B[wr lƹ;sA;Ir Of,rʰ;N:C%vtEE`Q=k"i)&#EA{YήN=XP+)ҤI(bÊXPzw y+#ٝLf̴4)=0{Cpi W#(vCdž=gszXipnjHQ4^"dmYZ\-t/JZB<<) &=f)a!b Ш)\G4:,ܢxQG ʭrÜDllEai#\`/!OFP7ls#tDnL8*h(؆*E#ʩ)Xcq#s5lmLh 9f0W)، ,ːuڻ1p`taܢ;FzD೴"},z4 }5x fqר7f켉rچ }ڠ&8Eu\uu-N!,,voOKp.8ALʒnrѸ#Nn K@m#A#`Vuz`@Au2]S 4>CZ`}CЂ`od,| N{NcQjyхJu|õ%8͜S(.h)Xנ=h11'q'AfWwg96hʭN!s֍eq'^g҆-0m/®W4҅UR@#?@z8)KC5 h|nDD%;"u/xXT{iE8r9& &\6At{o͋/Ƽb?3R2z0Tt_NNN>}c̹ chN+7Slɒ%Ҽ͛'|2f0TMCfhTJ"/@Mf:ZZv#@CXH~i}rOx?:@#á=G3\>_ }V2A^x((y3Gbc~&B#>e\p~ދ׌,&c%os|!G 4cYK}Bl:pȒrsqPo7ӃѨCx**4OcO MǨԵDPAu\>(xħ߽7"M~E@c ~a>>~ P ڃvP\,ҥ ■-[}C5qrqƂ[ hJc?n}*moe`IŠZS댦TC̽ZNR}FG2Vw=r룜И]So/C[N)afhAKvT _܁0c`G])^$m6:.%AY50;`yً l۟#ԡ>jWPRERq~HF5wO83q*MFS^ۣ0\_p/Ja&t60ajc_t髟rL>5U)2UYf!Ÿfvt 4E0|)v5qF6ƒ!FcMcKk7\x*&@C? 4#W+>xy(b};?k@wbD HZaD[O\v>f4` ch# nU4u R8ВU jl8"QPV X[!Un tI/pf !ԫZ?aSauWI>1Ѣ>tt롡6jLO~EU' ucƺj[EfCOJܰa)B-n=tuB_ mw8 GsAߎtE+ _uh$^^485B]]mׯ}ͻM81Eh;D1 mDoJSUMQalp~|E'[O __F6Xz_ RA-jtmX'z![Mƚ3Whg h81,J7[؝W!YmX(qՀFy\B?$P\>H NDyjN/Tr9;~A'7nT'Tb/Rp*|}icp,gm+30b`|rL03fQf!EQ\Lլf ШRu촳$@CDfx#dlzyO]?у~3aij44 ,C i_59\/`kcp+Zb:%JAڛ\9h0'yJ1*װC /.pR4t4Tׁ.~fVT]Ea~Gù9q4$IIu JhTܗ yzk~woG`up 6&{NR(E\m}󕗻.hP9\F)kUFG@ 7 ]܉ށu9ßqb ܑG?G y4վF) ؉B9ٜF0CH3p;!oB{3.f4>6hnUاgL[]}<ɤkP\:"(KUjܢr3/h& p,/рn;Gu v\cq4|8vA s'"li J3dy}6(jU]٬"1 0y23UǪL|幚10lZ3]Ϊ4wqdR8; =|24\< 9K`gc yp'B,x$* `a LVŸBX[Z~{ d#-(6̓d=9bl=lj.΄?, F@0fIwY o=#z`o4zp1bVp>A݌4CPτ_4`ByehgaU%sqmq;FH20G49D%^-&|y蠯gV/SPaݕkf'`}]՝3"_І%PPp=;x$AErCtW碃35/k mടswG\P8P8BZ.S ;BzrNfx\ 8ZjCM3m ]q*{ M9Uxg:r41;;gbe|?< vg1Ʉ þpr8B.lVP2CI e顫n]DqwlV M~O@}hFKlVAT%V HftTZ͂hٞ+88BnX|!a![;hwqn˟[qQ^5l3yLP9}>;m/JE"gh5a% <'C+W?4Uj0Z0Sy+z;}a_77sl }IN\{4&Ge@mYS4p%Wq3\T-Ѭ3~~~RjrtT D>|†(cFY<3Z.g⧸fM%҃q)$1#n`= ,6k!SџlVB)'bkXD n<:kףHeKtޭ/ @c V0c{b!$>o 4LICyֱ=2]#7AZtLJ ۲>xMMQЪ IA9KV hd6zNǏ fc6CFaIu<3bR1 X7Υ 'ޅ.ǐfu`O xo6G/|*JvZz/[g9&to:<6XoaI_mOM!4 x0q0̊_̒ȏ=h\ ߏ}Nra65Ύ,Mäeae`b Twc͚'WjV:nF͊0ô4.g/px3l]lVfaoBMAq jaM ix ֎pYwec2^e ŠvExa:K踕$KOMTRɴo9mn^'D2@w5㡗XcI<|/i e:cO_tlρ 4l n/lL ҅~d>gI?$013*E@4$''#!!ׯ_Gdd$BCC-UhXsIäea-&O&Eaafh]J0@SY 40?eۿhoV:s7{jnlVʘ\$F,bfM0Qh0(]RYODSpf=#m/agXmınRY#ss&>F R,XR)XnũKi|""G0C32W%݌?4}L~~gnwV-nN[\^ _\o\*!Lu/wZwo=L86_]cil=K~1\5i0޼4lD@gdָ;h{H^~]103.L ^@K||[| chd .fq:\y)(Yab41鳤}L|^^>}T 6sORpac1i@Ƀ[- PeefT)r5+abnk2X@ZAvkn[;aݖزY:!9:b x,_{Ew;fm#3enb֋q[$sgc{]$'np9pv?bL)8}<*{iٖwwr<[*gb>-`/'@̀57p_=mqk}@Snmmʒ3dc9& :o׮aضmK4+ 8 Y;/CTddM&6kF ч$x^WG;X[`c5z6$bk̇ Epq߂ȗmk%\m`mC_qqUǩݚq;Y<療C@?A1lqw- `sl=fIr"x,t iXf7BE<6#F@#G[3 b#m;}WUqy}7bK&h0Lfbt4~q3 0 C'aZb$+#&b9=$r^kvFt4rk ͷV1yuOB ޾7[)(}#@CDDPücbCf!""""""""@C ""4h!""""""""@C UAٿ% 58ꙡ;^6LփW, Ð6p];ŃFEj2$ +28+.WX{}(.̺b?WgC/,-4@qQ8IE6\? MU7Da _}VJe*HuG\ƠSp9jl$"[8 sAgM5ۄ_N>'R7@Ӱ)|_>BlQCiqt.20}@fiN_ŝvQG Z"],KSx5nNxyaVidW[><oX8&jt[=E`mkSS=PMe~)ݎ.za~8d0YZy5X0w=",VmBCF'xӈs t0~yMg,ڸ"6OULExhi VcXKSpcՂ2snDh`*h$8[S]=qLk 5ɸ(T$܊G|b:Fc20}.g@4K{*| fbi#ؔ SP,$Cx`3 )*Ұ)Z"dy{hRn) ԜB=+TVxw:Gvtg"GF )]?Q>WQfAb3Od &@P/1F׵)J(~}ӛ6c64"|Ϳ<&#PQ/${V= |%&.ghjR '$I̛yu,hNa P뀢U6Q0@a|$쎺"@$JJ 3t m:J(-T. = !3E=уĄ9JҌfzUe2@NϸhJ]:|VacD/ C%@SMa1)ef}@#_KhNC{\胩ltHV0nlcK7}DԢ2 ra;ze ]q ֥9ڵCmmt[Y!ag|)"Q vPޯCcvC̍T?¦^gWP2+Tl:@m:, ƭM\h*GG`Q_ ܮ#W̭m1Fp6Y Q!/Z\ RKfV 1U` hęu:u3>[mk:~[npa<fU/7$^ 蠫󅏠ن%T(,>?N17 M17S phPJ/^%wSK lNI}kB-564Fr9Awwb6ërL!;<mo (;&חkfHDDDDDDDDDUԮOM 7t4Ÿi*gT͗VD yp)[lWp)-ia^rMڮ`hJP[ ~40bTS*bs^Ue~㍡e"?J|z=80'=}rF!b^˫[Wr!""""""""F iA NDbb4KfL-C:X/vL7fO'wi: !Q!Gx'PLT\SX#ӛf u= 羞{W|Kw]Dx'p <9]u5wAtj8}e^3M)3~B{$NGբ13W]5m1m|/rvY+,@{~ 0]vC8Ww1FG^p. j/F+MV4[ps &izl5`ش/>I9цSՁYQp<W "bDt2CqQEkV2W9>Tlr*ĕrpUqm帛I3q9.MDDDbƑ.dl$^fAꁴQ%j,.\ΈWUEbbb@w1HY2|_>|H*WI{˾}hШ#"""j4n=xiJڃ """4hMDڃ "hpm 1H{!@CDT毬#bقo?7at JfN 62#/4hjp(uuø/F9.,߿0pqA@l"4ql4 "/s4xPg?M*1+뿼>~᛾`"R_^`{?Jjr1JD ʀ毿KZO Z&O/[v o$#Nk1'$Y_Ph&oDDDR4߾O86+]_f$(? ԩS1bJ1JOMMXO?Ub$"""h-kB"dǮ^ǣ_H;>҃<1Kjp3C w*~y)F ;X#u^% Ð6p];ŃFEj}h*.WX{}(.̺b?WYC/,-4@qQ8IEҾ.\? MU7Da }h*N_2Kg)8j} cXW$`DdžRP7h>6"2SuY]> vF'4Fx YF#/5hz

r=NW´X4#L49ignE;^1[3բ`:zQSx3Eצǐ0|뻬0!9<6g_A8a!(saU%@𶫶L$#,:>}=p!<4jаA< /͗3}uYsqEbhmZ l ct ;bt3 ㎘)Y_J!/$F3hNΗjTLiX_J*=s]ؐ,A tkV DNw̒wz*Rx]?Bpx`q,Bx 6!<7L9f<¦m\zW^f)}f]hH`st7]^Xڣ '_,B>Af`PK<<ۅ,4|_yȱa\K1:ߗP5`à\ Õ0]WV!Fk.@>ሊ ƥGHgh({p^2~'M0zQ̟HA\U &{HN}/9fT[Q|2DdP'" @'][nZF? B34b<? XܸczC o3 =x#<2WN,@?P3=j(/yu|\g0.f6WԔ3 認%GH'CFmz, مTY'. O. Rc]PLtnY = =V6_@mьk F |<A#2>CC _Y =>lxF |14plʆm|A@av@ lp;E[#M!FE@SrKIY_Vxw:Gvtg"GF )]?yT72 b FxBo6?ש#.N ˶˩/>-2wm=mC^X{GX@}6 \4eF7zos6+=E!w&iЧhMI'uX8 Ree0@)\ڻ''U%L5`xMxɬ@ 4P-AABk%oo0v']4߾,!,Dھ0$z\f( FZf)ƅ|?n@d-ɽ=8pC̄O<)UEiRRRX/txj<1]QRwɫ:IW%ycu8&䠥Mi@K('`cW6nϱk: ~bw81M@S_#8i:l]t9B9ѽi ۉ1\PwX`WB[=/Fk6!e]#hAI =p,1y(8!x!UhDi&k75>BuRwh6^ 㰨%&cggǷZp8%bg<c=paatXͮ4߳q+VӭkٳO|_U]6̗܂OüamfQJVvո/"QF7hќ2((Tm6:y$+ qӵ%6ʃPQ:CdQxv[,K,m*uXPVmڈ۹tj!@j ~Wga?Nʡ6 @.Rȧ0 44_p MiqmB~4@sNSr\p-&),sѝSJ:Ȁ殐,.sem\p;[TPDDDvQ=nOlH ph<ٹ_9ФW`mLբ8 0ӀƖp/ERC!i΁F06šԒBoLaUp*cXPSw <㳕\ж3FŭYAt,xnBps::jh|#h!jQTI~;!)ffJNY)@y\>T9}e4$bxZCǍW4hC4_4C?pqJF+;4 nhń!.hĜHpP()axH)uo`$T'ǂ߈|0ÔFR DD5 h^|s&BVaa^4 [[sѿĀX/H~|euRFR fY?Jwt`kӀSlm HP)h)ǟݧ)+1nQJ_ 80lKUvy]صFLQڨUga-UtVRӐt=%JyѱZ/!?`^\q3SYӫ*Sq9KRrh'4a+U T h6cCBthWTFѫ>}B/loԡ 7oI.P<'pSTr=xvt~'qKzPyC#t2ŇF*]thA_Ńq+'7mʼnX'AU܉jH$وviV=i);.#mܾz|{vcԠy&6@xxقײk]^gC3OݻweW9]'5 hs6QCj29,:6G}tv#kjl[,5j""'vGk5hn)NSLKS 6_[E@P'@  ' ;ye G{Hpm6=m;>`˅Zm:?`}dP'"@Cs[1.7qe88߬ f|.a;:,zL1l^zcGiR k5Nj0rjC|J=tJ,EW!""@CDDDFz'},04 sV[1f&Xۆ .;f)K"""4h@S?xG׉:E :5K~FXDDD-9=an7eu2zn|{2- oǤ;hoC P($LDDDͷ 2]"vn^OϔMDDa:xS.BmZ~qLٲ4wKjy2{G)6 O?43Q%&KQR~:A .plRg5hH-aW ],BoLݶ40`%{2CCÁvv| TWEj}h*.WX{}(.̺b?WYC/,-4@qQ8IEҾ2\? MU7Da }h*N_2Kg)8j} c -|tZiբ8+ܻA:ʽj㔉ADZ}"8n.\b}/&@CDDT-5 aV0j?~w?Lb38pTCرO,z H=Upa"x!8=q\j 4i y3 /"mD{.7-wtVDY;͓[e#H\n|q`@qncX.sTT%@SY_ oc GX/ c~\P8]c~ `N3 uz9 F)^Of2RceE=pwWbo!5Д4\X=V40X!@CDDT=.߄m;wc޽R۷ի(͛ggg=H=˕*6WC#ho \_,)d>g{!ǗɏcS6LmC "H^8T#}Pu^gԊS hD zaa_GFC+JF# a˜87 A>^ƵTdI* >!%pŜynx$ĥ l[;',xQ~%ANYx.[G;kX:} ND@BFMƢE`oo9sHwppܹsRK@ t"L?4q)*EAU4314h0 $#:4 v0H(u@iTQ@(Gx>VvGkX D{%@Sr%H:e6Z`JP1 {B_ ICO41lҽ4c}Juӫ*vzr)`saɛG=?@XXZC @Sq o/CJwBӺzЭ؁$hT$;;hఁ TA"ǰĆ s`k%eg/QK: ;ÑNY9CgYy3\a֋p*U@Mѓagg3E@3E@S3 ,;b˦U%>7DA@lMfteZLzq=3iK2Pve9/_pCHu#n* UM8M3(8/&7Fz< '냸]dCȊq:\{uBC|s㍯%Zh4ཬ }0UN F7][mlP~<$3LYwt1)ٟ%է\.Aծjk|n$3S.E({Pk kWeb1!F*ZaS/ \3+ (UM_AC9 އ7 (?` m,*6*F _[6pq`ј?\LҪa Τ⾲^>BZ#<{̤ & _Xqf /q9[r6Mft|4*vlŴ ssns\:GfMaaFqvfgg`*@#]<nFy\V:M%﹌\WÜ6t`g_KD H+I%?aL` Ʈ"@#Hn4crZ Ј_cu4 z aflSi)·D"}|@#DEKkPjJ70`J,T8Q@xg+mWog[JRU bVx-g<&/F>fv%;p3"v CnSuZA4(fq@SYd|+7Cf`׷Edfa~v)4gX4gFWJAd ""UPw;0Yb0sȑ+8LRU M!̑,N#BfilXHR&D"hz/sc\ΒT~%6TZ,QWPj$!.gYb'w9{YU|@x2c8lw` gq=69Jgh!"@c/Պ))L匟=3Eiq$Eq,Ja6n3D58+TUI b]ZkUW:" XaW#AbA, v:6j973I as$wNwrou7 JEe-R5h;F;+ˡɩ|fPJ+Y4nڣZs8$D G 勍Dn0?yf٣D$&Jfh4/ P}&qs?pUt'FnA s3. ²- #AeI PS,s8aSIQo=b)Qч#VDЦwGϋ"(l_}a .4,TyQ(,`8̽bL3g`̰jJB*oB$"@S Ь^Ј[rVM -%U㝰2 趖 ѷC#@Jfv@#Zf| hrqr QW!$Aږ( %CS;F nԡ:lBc'=<SY=B@.ԃ ly ;Y^8uKFFmPߒX> 3;D_m גt,D < -Fc&FKFwv 4׳Տ!)[ 0jKAg N{Tt0=brET93q'bM(1$EBm608K_P$l Dߛ9x!DǰP\`rX9OB*g˱b EmLy#N>݁r:Wm]ظXC#oB$"rh͛C!g*c!"N.cp>B2yn}#E #ъARi.èBnr6*18Fd%)~ UVh \8|4h /an=95T52ݧ1,:sT\UYC]=3qUniw *(_1k3h8*G>ȭB;oMSAqJjbͪWߧl3q^S0JEuB*gGg|Ph㚔mjbMg}6076fpt>XI~†0tdM&vk?9 zmr %UU`8n[VҔ&Xǯ]Kr&""eg/wCf$0cgg[T^ "9X܍}sۃ|*0KіblpD^ [r'y&"UJp`l}P-'eD\/@inqwQ)sQH$Z8ptlB##rn9qԆJ;&^ !""@CDDDF,l}#&3T 3>MkL~OS`%c' 33g"""4DDhw@# o͛7HOOG^^,9DDDh!""π "χ7nll ##J|ϴa#ǝh!"O fbt5kT* -;Y?9DD"""oFhaʩ.Yϟ?LJJGV>}bgViii000q'""@S)0O}j `vL[;bsfAEDDDV g, <[#_H_Rԋk0[cUѤ>B^-7MAYwL?KҼ#j硩_a^X0tj f=& Wi.LX UCSu{,*jx`o>ēŭCCa|~qd(4U⡷2@HF0,ysmPMu~)Łe6p9P]=M8{(t 0$VXl P]mi  Ko1s9QMI&o_} x:TL9&ٯn#C}W!6.qt"\1m[->.Y`f̘!bʃ B^6͡ʩuBREֽ0vF%}w}JD-͘?|)(҂@#u nZ9$Yk!oNĐ0^D-"j傅ӭqYvcp|_c-I_ј bk.zvU(n9q8Te(AQԄ\%O< x7dH{Kst1Cڊ3W0bƆH(e8#>y m6Gk^NC)&IE7nc*̆oj,?C`l_Q$,Z`|xB}-̟?ʼ1 èh.*4k9|`ߺkp >!"f sPԙ:3Nίި3f:xȑ#Xqsa Und½JAv-12o@gOOIU+wLQ'/hjCKDCz=f6h@aRn>ns_ތݞB+p~w@!_{M 㞇ab!4Eُr X)5̶ش?E=>5l/Ohk7M>.nwGė!N7 _ 3 h>{az}%EV~E5VF[owxs&V1ҊdC6lT!Aۓ+n%XCX>|ظq#˗/5[t[:V1| &(tZae#yhPi8D9ɆϳRBK@!@#oj 2EPPp5 >VN61Bhay8Q@LJ+M.눾 cgb,Д }n}O [6@ի:4.Ybcsr%' c^QnUJ(m-a)$c` |}O|*(O7f97RPQ W\mdi, x6pQ_}Z%wrGlK^^!JT4ycAFrc 31E/z|uޗ/gbࡓYrMmXdÓ?bժUlUDSSS9,,,XIÌ+j~ @CC )N"Tp%.M! @M1RBOyV cd<#v7eB\~^b߆]N)is?*ww# SK =V]Ň/S$N R*D{⍽Co?Y+BrrQ}}V4o+nc4u* V\#ShKbs|"@ 0L'N`ӦMXvmSiM6ջwA{}AY7\ TzZsd W끖Z|ub{BdAW!GԒ hrzکo'ds(ġLLdC(/[F Q6,&2 δCzP=߽W[.Aᦾ4f{!rbpMΫu<[Ol@sP!i!g g\& 9''tYM &\^I<.!@SY3HxiYs-;vZu׃Fp ~! ِBW8)*ֆ Q!KaF;#if 헜@~➦ pE\ٝUN)1⢧x] ą"<) I'k .4{.ĖwuWcμshk+OIhI?yLb \ǍxMv"f3gXef#+vbQ>xfG`L@~}T@C2>DZd()MC7Lkd`.g].Z, f/a8x_On;h>ݴG/q4INB{oܑA~,0 '!ex9 3Q"%JyNu4OBrJߊ@Mp:Wҵ6a.xEUX ,2Jrrsj^^2 8aSIQo=ba\Q te@jV4r12fΜׯ_c͸s:>;!!ggCplDUݾ>e}07Fm) Pxoִ:=ls}rVSy\@7-n< 'fopu ۙHB_9s`,0Tb@0=zǏѣGlXZrrr5kV̡)zcuhu-xi %evʞPQ}ڈ^W4GNQތfG@h-XS ԘHή h^$95h3w@q(PTJuih"2 +WĊų,oJy 7e˼i*o@lVyBƁ2S׫rhpx"uqee@Î֓S1}O!i^C(S*h}:˒ڋoۡ3Nuh7?ffj\(qUn fڝA‡ʒKѵ4Ghg2UZH@>gwS5ui5)[LGG}>-c*ާlm&wlU.^-_ Y!9`rQDnca2(nOr+m'rt1nC -s}o m'q>"|7W(@ =c9_M8t%4DD0<<c}[A=;&S\$ 7LC׆*࣫7 c3NueS#{hA+˼/p^h9Ng/t<5UO ;2OϫG`:iWCd!@CD= ѿ4'wV4q6#&icؙfa9B^MX`\&PѬ;&Z%iXܑnTݯ0/'l1)>[LU5Ym:5T@`2ʤ#r\|]t>OœX-4穡Q0:]pd.̺ZzsgEο,My(#̓MWb^#Ѡp!y@y>-B2wcn{ޡ}fX{++a>wϥp㎈M)АcCDD?{skg.{ WCHσQp}T}>:CY}(% uz( O/<JqSm(]L=⻞hĥkSPG8,eIhj$pz~1d= ^vQHDDJ`dzs\ݹsG  dј q~.zv%s$㢹qسQ"A:Jy nȐ/J/!k{xU@HT|k(46BO Qʘqkh%|\6R/Hj?YG1e\١vSL>"|xݏG\R`Ztdxg6_vOO232ϧ$9S AېTB1x%Qg LvE'QgL38r+777VGܱ_X3HDDJIg*}}F7oěׯ\$s1lQ4Vt v0):E/ͧZϸ~ ٌbshjد < U= *e?An/D@V)5̶ش?Eᢆdιv;ݤ hqp2xɫ\ *E'¥@kR4$=!3HД0l:]=y╰]~4%`KF `vv;C:|0\]]q 1G&ѹFKA@k,THDD1\z>|@~~~1#F7n@IQ^|}B5cɁ_%[io}/ kN%T%̋`˵|%k FF7~KQ "(` e .z;I_ňn#1ԛĩ2M]Gm8;esKrCpEnTSO‘%6ʋ?!WĔ Ju2խ]`xUiEז %,"nA2v ħPT_>cHIDQ%K#-k 7GcM?l%V o]0Q+gS&O TPN]p[_ e@UR*> (MEs=pg\> !gbժU033c'c~‚M6U:)ތEhT 4!!!Rh Y ';B|BwuJc]OZ[^w1ࡉQ??+6?W1| j_x/F7liGQ}IFB}ٿ fy?;hz̳Rp  P(8~/s}r,倦6pJ9LjO詥×Bzzj8V!2Co5]~;':EW@iUPV45h/̻1aB.¬DmG[J%BuV)A^=(ׯ<> $o#+Ƕ4{&>&8g_RuQB=t49Pji"4华aLDD͛7a!g4_'^X5'k=-څ邲K1G[4AHqźѥ(6ڍd鑬\p@15d ɋhK=1ϟ֭[QTyOOZ|.h2L]TQdO,Ϋnp"ŞcSt P@#xyF?Ō=6<,WYb?6!/hN1c3y NCkJԊ7"hXh)5$@S^2nÇ[S}(Äeq.;]v09v?0rC *M5(Dh>ݴG/q4Iw$@K6?_|s%vf٣D$&Jfh4/ P}L\E]6^0ge&`d']v K88{""GXRGs <9@Su=(fJ?b4I0RŔeMMHkԻ l0; FksM(6k}_jgGƂAク fʵsdrVC5J_6ZK @#>h.6Chm 5M)_c`Юh@ <m1t~VRz:PX]{DYH^an(:e8U+Ro^㇡G+MPu>{x&o9:z.=0?]A@|Ʊ.np7Nj!7\I [뷸'8pfǟA9x+Hsӡ`/9/IUǻG<.&z6Q>DU׾QGoq*g7~IF #Єa;KCާCL?o1|vYsee speZ񸈰wÚImS;t<{!nV7hsa[+Jaሎ7  ``фy{h}WF4NX{pAAgҁ[AN `b N&ވ$ %=B=`= ZwBgǪ-S?:w__\i{(hvmP\eŷЙ#g4Y&o@S]1hj\(qUn fڝA‡F[Jѵ4'hg2%;,xͳѻ)M:4^UMYU{Rv%g#*gB r~mfh d5i02\ʙ ǣws8i6C1K+M<N*hк'F/Xok6$o)zj: j 3 nshpR.\M@SxgSq8N4p9)UMģg$ h$%UPgOjPɊy .Vimeyœ"j B6 ",N͐|J߀v* 28 ˞h6 h+T]'EB΄n7Qk@5ArE^ :^TՆvoC~\E4<ټۂE ))=TalS튕>( ͸m`v 9#"94 H3KFa̘0PY@CC^;)!ݹZɔ@#x=o&""Qy @|7~fж*+9}zx+ @:jVM4POs * < ߗ{^"媁8B5QHrHP|ڰΩ>OK *V0ʫLe@Smj=)C#@ڞc;PDG 3v٠)TFx0R~Ax ?Cvbw^5XhJ"b"4Ӽ9txoyFG+ >!z8u$TtP*3GCCDD柔m2HW4iaӦnT9>͸fyo.*P倘_T 4C4 ZsUeN\ CDE늰7r?C%?t* KtYD Z<&-p>̠߃5BJFh{2XZ.E`iJ[JC @?C/S^曑xfgu"u;m I]XylA !mI @#NdsmP_ 9GK5CD{h?/p٨8JHTȐW 4s(` {)rVGiii) 9¯TXT:<Lۚ;1E\ hؓ"a\/pdNl률@Ld*C/5zZ/HdžCqdC+D5 ™[˫TaFoS3 cA_hrʊTQ~3h ^(z=p.!6< pw}?tœm^_6?mx)v=oGFs*T9+zrRho h-@/E"2ol48-0T,n-@'NX+q,9E >TF?b7.GD ;Oqιū{.lHGk,*(d9tB.}H40`+ wÝ7H;8jN77!s5)ytåy O6 jTK,:_o㑄c;f|sя+ 4j-f AGȲ.j1_I>Cyr!"F("77o߾ׯ՛7o})0@ռ{3,]T$CXH!J!""")00r6ɏ'; ӖY?7Ag@8o w7;]K% 6hn{נ74@#ó@֋4|XW\p-`a@.gBp d """bT4ߜ c<'4KAQ'p+B_B"߃W&ohHqҨ;;&!ϲZ4¼xm2O `f):~ WK鄏3> """4DDDD8pu 34zВ DBߛ9mi{$016V]JDX7,c3غy5,MM`r\+n#̼MpXi 3cCYaEnEpK L+2W E?ݞewI;Fu'틐t`mnCCX\=HH n~HAt/} 4̤If"`9|(70Z6s)цxT\v0a)D=X1\剤9Zqnb3\}O6ﺲg`|f/?g1߇bJT~Sn2_Em<68X h a)!c+?f{-9qzY/cF0Yfq&< yohoՌL00^6XI%@CDU@(GT2z͛x"""4ꋵe5<g>pdI mwbhV`bBq-2Ό]EÈ'PCu~н6vFw?i0w/3=W9ŏ4_J^"`ȸ7 ["ɡq B@\# )E4yu qR҃7ƊцVjVJ&ֱm)dsfZI W1MQ`lqf V4_ p렩hH i4_4Fuy|*pU%2BqrZXᾜ{D1έݏV.W(a-*Wt߁ mf^ǃU) Q=.k`f#j)NϾux*8-=gF9 < &` |c9u_ N `bdK[8>9 8ˌ-atD0R <3̈́ϟP}ٯp/,RMXחBExĝRSjy4ƤL?^+wLQ'v>jm7Q8XQʙn0l7a KxbH9Da`O< 3voJ>范[)x 0f$ 01NF3ж@EoNFrfd^97q؆~cl"!gh{҃ݷr+LBuy7€&yl,{RooRODuaxu2F캅ѵ)4y\pUtкx;/k(%*2~PxT2LFWo2_ 3RrAgkMãX4xL'=Aػs?b?2а^8vh6zGc,$:+E?$:rQ X00;ے %ɢʃ6DBxyq*G@H(M +QyhiHh$j4fՅ6hYNMӡ!)79]5:4^!ڋG_^XtmCAU%[w3KqXNƪm0h&&gUa$+Iy(B-ehcVtqДW:Z)8(Xfxb^s>لM!gκPn3 wY6 XwПRCOˮXҫ8WBT|]tcwޖ.o-Iqliq'mk9<-;+=b2NҞhQ_\Zb+H͖C0܊郺*}-snE_]9xHy՟D\ L:*u5fgN?h mD6L3KeM!$!6!C./Q931Iq!+g3 '&<,ms{IJ dqvbNi`ƤY2^2\9vIfb;v}>>o1mayҏggj`L5K-4W6K;l+nL u*AO UuQ^o)4Ѹ=~إT +F+.BS.IhJw'[E!̿ZFľ1erY@;pC碑>FUַ0g0k4  !CF.,cj|JmD=_m0ׅQJ0beiiu&wP{ Rh8i2..@zްP\R@?zJ#4~Ğw4 Hh>pak0g|1,7a*f/^ǽ'-/yj爀3عzOGmmPia`{xx>/,cfM.,px"L4d*Ͱ3r)cjl=ɹi>~Ƕ`霩g/X % MƳsزt.M9KMO6N|BĆ9c  >7EKB{o\㓚AX]ֆU7h١Vh(Ɠa0ͭ"XB#%>fZ_-k'k~y\e,~K74yܼGoc{u@M 跚so>@tʓ/U-/ˏW@j!FЄi9JD{ a\AS¦ `bg#OLE]vX]CiE,w秠@C1ϱqܼ"Nht0`8?\O ˲ K!v&ᔱq^Wm!8b[pٿQEP#(1 AАo ͩS&m\3NvJLg~+FyF8k=v; 'ضl ~[쌷SMƝaY/ԌV%p2{aV#UwazI OGWXAd6.9 &yi.l;-ug=zɬy刺tgkTuFh"f9yo!{=Vޏ.p폸ih]I~PZQ9:D@^o[*BӴ)WW8܌{'VKvǑE=a.q"J,zܰ'Nǖ,7qoj~BGXC8⼏.n@s' Дof8{7ϻ:?CbCTm6na}W=*HBXq-C2W҅PC"=sn φ '4 M]U* 4)tX]TGauds!*kӼv]+BG @zOЗnd]zxK] Ah12]S^7G0G=k/jmۦ*e[{C[-.ⲫI#z8ZV7nN=O/5U!žY?EU}E`ޠ @lT- l$T]5|eLW׷7fUZDEh7+A87 BPAA̭C ZjCPPQLw<ϓ'Op/*bա0#b2|"xY&[AipN@;# kiR dXMNΜsƮ9QICKJ&<)MQ!%ͧnXGӰǖ~jBF  UWy]CFX+Ga O=Ƶd"h.&*Hܮj6OP"ZkJ}VMj ^B&g*rSBJUm%;6A~(Єr~(7?F{>ܾ1Z,.\Cs i 7(ډ~v._e1Y} IhHh>㐳tއ \]z…_8/#M!R|1U_D"PZBk P`5` ;%MY^|*-;;a3i^*M!l/JaS|bKXhѮ)ϙ~3X*iuKfhjX ?z!Y22{X+EkJ[t{+bJ5m 8PD}i@: 90a Ԕp;T p WGEl& 1í(@˽a"Ԅi#|%o: >&Dͬq_0. {)8;Bs'y#-o{ شyǕH}]W5hw&V/9{A,dȼ1U1[I\𫾐 B=?kNXC'}Vrd⚜41PHְE K&'4Ը}Ф0]# rxבb{-ㄧ.#lBc ITK5DJDձ뛆QE%Pquz-e8&#[,*²݊/M 8ԳK1L6qABe z:u1\|m. `>7ևb.\Ay-[i0)@v ̺` xU 5!.X ti sDXWD埶# $#FOqe:j aIa]!ă!YVkt'n03JyMurcdh BrY~yˢ1Pu!,_"$$4ChXS()hc8*b/KLĦfbmqEa So9{4+ŵ8T޷B  +K~ݵD)ʵ,[rr^"i䔁׉R,Ϝbk }>g8 A| N kaWv?Hs/X,SĂ Źmadkn% [U&7̛mO/Sϝ.-"H!A(_ZFF.'BP) eN.j&B#5=+°\xEJͬ-=5쫅ȤG?A%A5AEG"dBcjYU 8T\>~/L Ad`"Zoz^ՠdtfaj9xꂽ^9+!(՝9;ߦl$I4Fbj6^J2~P媴' 2aAz)TERM&šM?uU:lg qiOi&99ؼy3֮]+WbŊX|9-[ccccmmͿ3,[A? 8 jWΡP e.\'6r\I}]bo✗"4]>du_mVM!&^0*B>9&.We|Y*;èExR4c!@W?aUx"!)Rh}%P+4>ܾjQ:&,)H- K0}= МcBs }6$bz6.۱Lh3yƄ"&w8T(םgN~$`{*$'˰P4pxޏ.W_BBh*/rwaF6ţ+סLS܌G/Y(kYBíAsyn[XX޿k<}#[AмB fBxNjBI4N6y*&gƮ04醵Bѣ\<>D&TJ'I 7ŝyX FpW|i&6Av9geLDbG}Nt$O PkfICpxt[̓oY„ufY ]ۮ&)Nhfw9zh-JhYu4 Ftpr-tm ϓs!YR9T B #b8~1Ms nDf!7X`^d* ;/W*M _ȀOD6q/eb(s37)b2*KK *U&gOE}+2ćXƂ`&498lV=G,7&51}PYqVO`ꦢΘ >&4wyy,?F+([6pcdTؠؿrq2Te#.31 2x^ODx0ń&(# a\kgU1qs_lIJ$&6'`#^ʷIwl/^g={nͼ8TSL\ ߴls X% bk,jX+>YijcKf2+وa|Ucc,R:SQ)rEJ2]ĝ$}py:ެZ/_ٲ'gBn:> 3|r3N\=Caw\o [!y~+lW}$>:#+) zwlwsrXyŦ\fZh=ܼ`oЮC1T\p'@!2C#͂,<¸,8N+D 1~(/CsWCb4'^KldO6u.w&ևr.'_RkrCX}p 1_9Kę>9vӻBѐ ?)4y;-TxM"`̽^ł4Ldxςb#?qN/l]q#ZK/5UIb}'W4krѡt0hoXu!D;#CbкUQq/H'qn[OqBceDDr&Z#m۳,8=Ox˂5+; e ZX矧,(ʂBC.`|`ϟXX=sh}اI˂^Õ831|ﳌ B|clN,>U^^wLBܶ,8eBZ^.&4Op`a#[^r!P9Ͽx0 ;C&4{8DH.~Ѧr?g*J0N6b^LhpB/ 6Qb'Rq1NFS+ϝ' ȓ=o3Ol=ӄ'9IA[2mcBSJ}{PxfU̙hɇXfyL'vowh3s,^*q39}hE;c۶:amoR>oIRZWp2ёH ˓;;;ܹfߟҷMWp,ⓊB,qXnAZ[%y5tuk=殺X.Luc<{?p襔O>Ϩ% (rBhVe!{>e_3px HLM :A ~-^qǚ@`qd>K`4~"j,o3\39p<THXˇ3q&J2Kʹl^4 b1u^\i\/A +nf#u Zrc9@< cR_˻V ?4_r/rr6.21[~lTtde6'|qU%IpN䆄1Q[YbX'`wB[T O~m-X(lOƓ$$e`MqBラ8Bq츸,[%yp KA5E?wzOa;϶q$4,p]2yɉضm62zif̘Q, .ze] h !Cak n*z"hO=&.Z6bv'_(4GکTHSbZ47dͧ uok`聫M\I y{t4QAkgXXBWU+R/b|%M}&I(V *BW-hyCzȸ7ɇ%[LXKPN k[Ǡ[}Sh`P9:Ҍ+^SG)e}ϙFidMyp.;ԆY!? jX׳בfU5 gB%4./Ӌ4pYmDG +J#HhC6:km󄦿-@GoQdgW$9%ǎEm3ܔybyDd4Y\3H0y-{$s_ٵx+7Ȱ>(( z'h"d32*c ʱaW(tľc3ڂD QXPD^!Eqk(^+a&y $)m*+^>/H|Kc1'8Dp/P5$L ev4Ϳs( 5X 8FbMU9LZ ޯ3;dNq,fAd4X__1-#8c" C`:BRT*im2γrs-zmF&' 2U>d-^L־Tla+)p8ˤ09uOW3uVw|"fO/|vbLs83v`%B%xu g⺿'OCA}̹VhL`?w65Qu6Gm-x$oaWДq ynMb|YCav'fV;KJ!4RǽĕPKhJ>ӋCǤ#ke mo?a n$#3=Lw MK m"t7HPL;Zd\/zn=DViF"00A"Q&Otix^kaŞh&* ]j o aiIT'42zGqYrׯybP/ '}o +|3qb( . xxX :E^J@m\@,;mLh|S4Mƕ.鸜{>]al0 `0Ɉ sLh"дX"Շ}IN =q?$2DU~y 7mĢ&c4s(d,2$ ÷D`Q4FtģD'v7 /GLzeB3xp+ ߱znpKÉ9Idh>Եep*~uEwI(&4s/! {쟄qq%8J N;)[GLh??u{LT?}`h3q>iOƏc*"V"G}g BYǞq>O@Äƀ'&ofF29`rR9|LNutM;LFÍۖphەRhJ1,<4Yb"eܳBS>-,47YjdI~VeO?G Hh>Th8~@ɫyKs) t*,$gcm˓p*9Goߘ&mQ?_S۾g,Q_)C9 !994~&/=.!H)ĝwIV316r r6mר xz#\&`,в<> q+ ɜ|ׁTrtaʸ]XIx"~dUݷ}2gu2"?rI*Uԡri}" n~!=2\GEvLxWF\ˀ b1dNbbu+=W)te큝; ruA^_1Ⓣk1:H2{@: &n([x`*)Ρvk;(/Spb$u)6÷S2\hdswhYFzjmژq594k!DC&WFЫP^La Aׅf;R  x8{֑y۾d w> ~YȺ[O~s/Zo˄͙1\uhw%K1}{ec~&BYJ+4 ,͛7Q23CmcR}_륙:uj&Xa΍|gx Dgp^\݊2 ͇N& O8" \0t,G/n!BόdmIBo/5/.jDcr p8shrxnF}z!c< OɿwQƷ*D'!h1ATqW¸`NB(  ?0qO$40\ &5QzGBC$4XY6Ԝd;h/X,|+,^pkdÜZ-]58m%'}oHO `7+h[|甄.$MB=23"Ikq ͉'93<.s 4dg#''y{iL &^*CXij1 ͿI&JC_,i'=TĖj.@aB|v>$q;yXg&,F-?tB%M =ECs5QoeŤuIcxe}t @0U%C7@vH9.gb VV.W*.MQ3yJsPO`'a?j=\ RH|<暊P}gEBC A|qBý7u$\~6r8L>߷82:w"Tރ5F5C-MQ$ RL_mC_,~6o2rYв ZѰݵcz7A=Dzn'+Z+:7].*7+z)^nZt|/M@6}1L2?D h2_:-XM`02 g"N.4"|kB|8+Sg߀>DT@~:SIh K_иĚhGI/)02C~./4ʘpIy^kk@@㎹#Eel^v$ *eTGoJ/DjX FbZT-_D"i=XW":.LV.Z15;b-)+f M*@Wߎ}h `ڰ{McT׮`ڴĬ\"Wm+.!LyHab &t!r0&]s2.]N׃ HhHh_rƭ"~2M8zG{ _MRB˅xdpp6LROD, a{\/m'4A9Am ُ^^8c7 Z+X%qP 1ǤTB#D NQ4ZͰF22}wPS,*u4񝃢#o㌓]Z -^V\G7_s@-}RsBk(RS+4X%{-'\p;\ YFV8s班ĐzZieۊ|fWᨇ7;bzDFR{'<}{Y=Hx]uOs]yEkKḬ*kQz<4crq qYfx(\/ bxn Wέ@Tw3(A A ,, fweƽSBWGPr<XMV__mZݱ լpbE`+/(+qAo#jLPgH;4Zd?% <FZ17^14BS.id&#׷0]qBt 4Pgz^\H/ː8 `LQ\̌4$=#szl iVC ?/^C ;Ǟc(vс IBԒ?Df+yZ ^fBwkPGXS2ɇSxd+QKP#O !̼EKPGn~ $4AА] ϡ<۶m+t`0H< u$D0هkLFTVh"4htl? "E bXUV:0J_B}꒦^h|JaLzL;C5ڿI󛊚FXt7Hh !!/Bh޼yT{im{e\Mc~iV+4VH1d) X4-Fh2o/q\ܜ# =R1(j*BI2G:4ӂI{UiІV x&Q2 bk ,(kތˊɼM~IRp}Aho 7 _dBK!jL+4 Lz+룳mnz^l)4IXprZ |1n.`kp}u{hl e N }BvvT?ly኷3ƴfDmj3Iv|W o㷵Xr=~$6 HhHh?#4Xa wY#y mD[Rⵛ =UZ`Вx;7C&O|vg &DѨȟ`] ^ nOW0m`p*C%+kѮ̗'1K-5!4}=3?%_/E+-#E]V/f7ԃ|9\yuQq oT\ۄ:ԂX-~>eץy\LnMQb]Tv3?G'{ì~PQG+K SN_ee艴`f k H s8+:/DZn+y$D}R/Eh,l&ڬVGoTPqB3Aa-Yj* mö5/$4Hh !!/Nh._LZl&׷O:/͗`mw2|u'')xQB7E?}$MR=ǡ=cR'ff}4  BLif̘1ed*&OR\Œ /nu+֝ߞ+ ^՚(~o`Mfi@ oq$?1COi$4A$4AC Hh2AABCBC4  !gAA 9#!  hA A$4$4AC ! !!rF A AА3  軌 hA$4A$4$4AC ! !rF A AА3  HhHhABCABCBC4   ! !Hh  HhHh   !!  Hh Hh !! Hh HhHh   ! !Hh  Hh !! Hh Hh   ! ! Hh ! !! Hh Hh  軌 HhA&w A$4$4ABCp2CBC AAC Hh rFAB ]xHBө(RH2Cӧo[TkSmiAuPK0%q1.{Zg~~Od;SA#h@A0 @Ѐqr h@L9Ar h@3A3@4)gFЀL94 h `A80 4 ` Ar h@@44 h AAp hA#h@@44 h h @A4fY\q`ಗilß~c| | A#h h7Y1^=_ h44uЬ(D@|<՞}"F;:cm_ߒ~;]^%ܙy;Hn#G$㏏I:%6B}_W?[IEr]R_S@4h;|CS"ՙ:s&3&G|gעƬ [;3֏/~ AAM|)~r;q&\Xlm9m'}LErE:$Z.XA^x:3~qS@u#{R7'sU3=~G)_@MX44fy ?hI~?6m}4KK߶ϡys]/^44fy ^77}"h[(ukrtǠY44fy }Aڟz4,Uz OA#hA[G#/WT.ALЬ A2~76Z,A)h h48hKݷ5f+^}9'~8oMS@|܃&k€cAe4wu}B뼹,hFFLpfk^8爈vm3H/|짠44Kg&[(ʶ1\2s_}s;GK.:-7hQgo'zt--vߏ{oה=*pr1 pYA̘,-joj|>㬋?v)[ 􏾭9`);%;5}g0z϶(lE33z󚓫&\x͗}Mu~Jj4 44f)M O6oq_瞬uG&z1ѥ矪?## >jy}Mh}^S/#=ԷdĶ׏;ϮA#hARrt#jmh|\횇D6R{.ϻTˆP߿>Ҷ>  kjxYI*;&̅WWΝ4 h hXAt]׷wջsh@:2E06m>`~e'g 3Q {׿ 44,|yQ{Hn:?Y~*c/޽|Mɝꏽ#Զ?4%!Ws.З) A#h@dO?ycuQb6X{ 礴'.kj8/GUv} @4Mn[nܹs)sDЀqs4FЀV8qqs4K-h4 h4ف7MA&hZd9=EAA&hv5 h j77A,4 hA#h4 hS)g h `Q77A#h¢ h,&h,,h@qs4.)h@c4s̡ h@7Cٳ)ͼyxWgA-9vtہܙ?|\e=h_7ݿ茿C(1V!|,%4KsZL9(^ h h h KX՗#҈]qFq`$獍d/"6g)44͇ 5W[%VYeXmc;|/.xV,x?>#;kuM#w˫rK/ܶXa杸+?=M#nՏ/am{xwowL)Z̎օ ݷȽ}E'hsARفEGQ3"~{8k 5*:1<8hc ׊?"?<-WzUzt?W~oд?wv~x꬝cȺĕ;-v^փf1/11ScbGߝ7,R>77BXv# }q46eٹ[)S~HQ{O dv3>hy_:}&4SL+Myjү{|TĿl:$FH>ec,7XSbVUCKCbUV-,{Av;tggF21kN aB_?I}v&9.6zԞ|4~g+h?_<=pO}\c?>s ,AK&K!hfبr6;4hApA%_gAɱo/~2y晊g,/4M~w͗Ek%zKrՕхS?h UМz<_^֫w4M黭q+4}}_:<ԉ~~AӶ(1QF(=٢ w:**S?=vnx;AkoY-Fs}o7F;먙1_A:$7^q?WK-h5>wv'V{>xt8;K[` ᕠٶ<ꘘ0ޘzq%?#2l6̜hqύvX uz<2shq-oN$&N/1!.:˭D'#zLߣ7z>W$sW|МOм9+?}ɦyԵ|Kzu?4VfxWAEA^tV\XsաkF#F1kR̵qO9$E~9q߬t5_y9Gnk^-ilqG˽E"A_[t,zzq@rlTW9[izM̋SӻKjN/?{FhX"X f΂٪4;w o4M~4@bgv4=m;gh w2$:Mgzֿshiw<V-kJlU O4; zu@^r(X 陼E945\G4u򕏒TVP99*:M9i۝LF6_mXɬ94_}EmKmׇ;H+][o&N;䫦eUGbY9&uN;ͫA] -{%-덢=2:SnV] kA4GSN;W;U`))Fgfg5Ҵ|ko2Fg+Z&uyAo #덢=6sg:Y rQl5!!CSvԑRcRǤMn ^y|_c&8h1E3Y4ķ8hCAFt2:SnN2֪lP)W<ۢL1mbQ]RM#W/S{Iuj~/O}ɗNq .Zav/Zb-hO-RlVlPZfК]Tu5;9ksNEjbG?_ *^H:U+x* ,Zav-Zb-:TFg4ifgըQSd5rNv zu >Srj敐ʔt3ÊZfАkt5WFk2bYSlYd9elU `R=t%^FTFbʈ٬2"g+2w3k 34w595VfJl76N9Wbٖ cj|)`6mM*!a%dm:g3̐a !IENDB`backintime-1.5.4/doc/manual/src/_images/light/restore_config.png000066400000000000000000000366021477034762000247120ustar00rootroot00000000000000PNG  IHDR{GsBIT|dtEXtSoftwareShutterc =IDATx[ۺ?rϾe=[cGAO=&{8RwW[  ~8ŦK'ى AA:؂;\2tWgAAnvp'pqR1&qƍ03AbǏfUAA}Թ8ڏ6Ą#`inUvZ- "rf.S`O?Ҩ v\&|Xa/1f085~x/uxv4d|zj? +ao?Uj7t[; 5MலW}& ~ێefcGi§s':Od/GXa_,K`pa81fPݸ.k` sk1U5.ctDd ԗ#nh ]>f 38,͇<K\`܍wqzl}Wr-Fµb߭D}].Ħ0ʜez]0Ap6ڙc҄ab؉ GWpeCEApUQCi$Z9exqȝ>J=|2Η_`-N+[la5|2vߔDރqC?ILdC>5CDVoaa'\; 2~AļCL0~z8Xsi@)ǫ`12jCLX겞)K7cDܬl3J5|p3‚5Fekc +Ks V> ؑ! .`3q0.Z!eX<ւaaOM|tecօhDN%1q8+ᱹ,d ѣdk.N{*՜H ثl`i1FfyW[腎7N6c1lDL s3%(cM`C닡23k\d1X]c0mm4JuÑeka DXwŚ_ZryuEpt3뫉8P# ^]>@5a0.x6 Ϧ F"s;F 'la|71]Y/_3{[޲ua9bj%D8`(đ3v"-'!RF1Ak |x[PuD~_ĠQo=c\4ALMueٸQy:;3_uf0WJQS,ScSiYbFA&!̮ 3x2OٍgpdD ?{^gj2Xoٺ rv .c,yc`a1B-p82Y5ˢ-DX 68a!v0L4ew݊R,`AaƩ0!an1VCΒMƅu!>x,L~y"iO1@ XqUz՛Aw F09 ϰohw5NSewϗf __ٺU|רӢ::ڧ{ 71# cl;/x٘Kru3e#+FA.0j0f$nP2 >ΦXn03e&`:nE?#i^~ĨⱰtX~'|QFl&^_ ÇļAYx >105^wkh =:eG 3KK Up0Z*:b1L,kb2FAY.0r30Xnl1<?|Qo$0F3\C7Aįw~j|ȡFbMo!yƗe #0l\lBlJ:nld'?uPs  ~Q|  ~mHAAB' NA  :AA  AAB' NA$t  HAA  VЭix?=/#! .׵|5kpfOCm}ABEhJ_U0R_ֶթ֧I \/ģ?0wx9fR1&ۼ໻-?LWy`{iOj;Y*g+xEߋG_m$@c{Q%pv>\5DB>"[fE{/i)X g~h3iK1OºWEJ=>_h\'^GaI1J&bc٩[hRn*Wl,|n >W3|ŶХ/jg8JsH/ہ(eqm~ATe3e, QX w{9}nRsm3 X!Aֆݬ +3;rV\^É;uVԞaF'I҈UQڵ-NePwm'tawG`gKq=mk6ܮo| k+0aC&NTPZNf5!*)]h'}է%O<̩&7 x&nĺx:?ÉEPMٌgDs7;Y%(+@\C61>˘v#:ˊRv_64doT7,?_6,p_F^\7}Y'Bv$S3) 8͏( X9ǰܝ%(D,t q*)E޹, Ra[=*tIcUZ4\ɼL~w!cIY^~ն7]_J =>ƭ18cU}Xr2IO2|lOĩ{\s4"@x3*|rZ_ &'nϰu ӗM"]ૄqYV9v,[;Ų+Rvž{+l nY{_k^3*C}GWMI=4CG|hw$Du]i\¤k5W {4?M݆" Bq='N˯ lf.5.OFɘKqm3]_~iO$vvTLda{}!?\Gjz ^~~74>/×uyI ec>4JcUeJs.!f/ybK"AeWųaXz#ۙ=ĥ VNPwb`pXG^C![/!Bo)SuC|ʖˏ;;(m(ʟޡ[p" MF ]MYX:fvޔ퇓TB6{iTB:%WB7ZQ3hrsky$UN}Oӱ3Z}e>8Pٌ{qv+3} $/×uy}܃himï+_Nt$·-Ŧ 7bZHrH#XnAa;kB~*m*>BoBT&o/U$!QGW?jnkP)mx!fc\Xpkτ}5B9:G[5 x+V3ջ9_)ޕ }sG1Ӗ6yo, W{ח<A8_ߌC~an6Nz}o}zA<3{Y&}eՕ7ɷѷb/]2)"uy,^&/{7y]ezY6:ͲdÝwT?-= هQ kA;rg:g.O%6)tiō?{lm4F6K?J &מv ]6{iT}%4ەi7Rg6t f︀l]/;Z۬͘:JL.MEɦ|Tj. qh|S\ 6oKe"/89۪Nڲ`N\dĮ"AM\{(lѽ~&NT8\·X(ߕܕ1{| !6,Qf/:*@e?:jQ񥞶~{cћϽqc~JŶj[yv}[włZخ-`Yi{Jx3W.d< nMFlZ2_-6->%eSzʺ,^&/1`6_՝TT,ik?;?rًt^}@/Zjpi{gE*!t Dds'bk(;xۇOұeN+ ]g.Q;Ͽ(O2c$8z :n4OpMuezcf<; zz{نٺmVbL}'tގ;kt\7Uĭs$rm%~.}ϵ+||m$P/Y={? WYBxٻbevh{ǃf7՜Zm6ia}9{cdow\W [>П|+eMt+N`G=d#ϟVxE\yd(u}#T>mXvgpz u1 a, ONOߞ{奨,F:o8{ ~iox%g&;%3n% x9m\B|&_sVLCslsZ*p`)zbBOo/)۶\o$F {竷jA|^;Eƭu݄Z2xnؚXD  VF-91%,s·n;"vN˷$=PNJ-OOyيynoޖϠ2 n"Oisd1f,ԊgjAgU"e:؞] D"r^'e܊߮ LAЍaυ"E\샅pȀL؝U9Vل5 ^MiyY7'}GA|/;X wgEw;4aS}FmB-E{>\~iN;XϟxjGCQ*36w-ET]P iN]mт;~@Dx4?wu˜Xv#z.Rv P;dY{#z62i,^^TndVT 6CqzT!w>{g/o7J Td8q^g7KBAbԶ;?3~{ {C6vNώ|<Y{)qkSW1~'52w[Sgy"dO+ o)q^'i}U螻˺6b ٘D i&g~Q'X9+3x\ k_^3zu}#k9~1Q72Gl7b ӢiF[nj"z#t]xֺ]*,n{ʽØXtEC.rOUԷN  tݓqR0& 3鐻lԙ|v]2|ŭx$mm'&s8;t*V;R[(miE ?\‘2jץ `:QϖwHB?^PTB 7w#t96ːL>zC]@78x8:YqBC׎E3JMS%>:0lU^X*:?DڱhB券XAwMg`ˠS0bu2FĤzI-ѲlDŽh^89V$}z[4z%֐8b|78,(˲]UgNW9OqIcsu qsuۈf);!V3`es+vO}`;;,c9t7.ϑ,4!BO()*P\+կ_AU;31vI8l+`*#8%_!xM$I?f;O? +֤/u:yݼ -M{3U^q0*R<@ڮSuqW bSH۪!>wE@䛰&񛰶+7a-oº%_@S& Zv.Ҏc,83QXy{6k3av ܎Tt\NF}v;;ٸg-N0;kgzK+xo`zQY9*r`z#Z+"qٹ|~0"| [iEzZ m"(*]5%7xyj סmm ܋U趾Al+;bwʝntu'RN!.Bl`cqMOF3ESzcuFTĭ||c˕h{s'Vn|lP'TJ5KٚA$oޣkFLgb]%0_zVVS𚒷Z%zEi <E!pi,Y=%G@䧼\!t9T6_A BMU~^uaq0]tf\D/LCOok90(A d N)VC d>^+`e2yټ^ Vgж&:AAB7"MA}ީ]P&CW!{a#AG%Gr=ym/"2|0 /e[wVM:mh vy5>EÓxE]ܬpONA%59$1M^NYecu:yݼ -Mmʹ z/^Ss7ob(cssg (-lx,^&/{6 Q'  ){wP{nߪFUM9qs ?⟳ws"7?Rأ4]Y]Z} u:ytʝ  Mqݤ~*WXk/!jmf}&˰g_g57,7is{kjk O2aAAQ/ץy~FAп1[WĮdίqߩ[8w%+"q& \8{>[s)b./C8/[IA  ho7)׹hl=sLB7q9svCΗu ^/St&A$>F;ιmEaBϗuy)'  t}񌚣H_>MϗU֣ FA?  AAB' :AA$t  HAA Nxюt܋>AA=KCg[,/Cyi1J#,NOpnJT5{3qgQy*%"ȼwkkoA//~{:z ~Omu؅ӏSf- q>59A~Ǖ8lx-"n'w0`EmMϟ{ 4+hfߴk;=:A69GwzW|$x-+nUYi~ʱ1RzxD"Xb{lX()īW/ K[_] I۳ /B7߬!4y|?^ܕy$t mE)n,uU&&Y^a~}G|֠DߟXldbqb1qq4뼜Lٶ"7Ez ?~7h|?G:AVsN>Ʈ)I*j#B>a)3>}Q}dq$ bkgKq4ܬt!$!(hNKJL4SHB'"eJ|>ĴV"X/>Nؙ  qTx}bC?GCHSg躲T,Ç*+ ^s"tG:AWt T8 :1·k>hڪUN8'od}f Olh(֙S;?uKG{o-^ jtH J=e1YUh~4}Ռ!:H}+\Tؾq)^mʄCK[Gka-;P-@[̇U"X?HJďP^FTl;2CǍT`usudc ӣoᕲL9l ;[T,hqDU69-aew'<$t -6/#LTLVG4-G26Mpt=0}AD 82,?8XY }y(D/@-LG]4zxà =z"VgNQ{V_@{=Q mPU8"T2u?G:Ag-Nj\@HQ o90XWDBXDYvr考L/WRJ~}@]F![`g/F8uDq-,׊_zB _^s/y$TOoAWOfRʖFuLHH8 H\;٦eie|?XT-g&gJB_45eo'52w2x76E_߰Qb $CExx ހx.A\V\KY/YhCM9r_ywblfܜt\I8lFҩH/(AYiw͆jb4~~uC3f6<^oYxxIAZį dzۘveߊAxt/˞x#Ovΐ_ԡ927 @iڞ@_6]lDn ~h׭OR_X@5p;yghms'V-+m%c+8 8:7"2E)@&@&Hr"Yet!wF9y-KNj~E .~ Yf:ewRShkkemC{"Of;2/xJďǑNEʹpf6CyF3QQ x;@ȹmwzz`wOBqWHMx<~</o9%~Sͯ K9$vMѵY=l7x(rWj8 ]I7qSN9kd"#1|؏=WO4 u'/~8߰N\̵3pIpİ_esuʧybO z1 MV k||axwd :eIqiwY\ᾠ)]} RY3odK7 ᥸c]Z\k.woRN1wIƱ@okW SFA鞖ze%$t m:XVs R.j*޿ ZOW}>mY۩yVDEEQq'q'DQdFD@AH޻V% T%OHj ZU5f ϟ]환l(1Bnc3M_/e^{{:rrl*)<=CS:{{b4nƞ&&&&=({5a)HI4puc ,*('B̟73MI0qX~_0&}tl_QgL `7y> S&5n]޵"UEqC t{ݴplZhAb6DriScWͯj!J3uη8]kP"ÔY+p=$:Lo~u-(~Evl8Ι8"bbb cO.)˜i uPZm|/3~˵gri9n]i&]쨗-b O{ O BÉ\yм`ԩ\/z䉐ku_餇=~XǍǂ9~_cx?O &Es?I^3WNٱ3'n׌7:$&ryٓXM}Zq7[sWr˵"ۏKk}jD Ǻ8QjוrphʬeB FAl̝+&MqъZ d0m'Ma)5F]U \ 3aUɷ2xYESeu!,}%Ƣ#rޅ;X0e"& lC_g/̢i2Ѣ111(`Gd>M3Z'nTZ+wuvVXb@M-Z/-15^9;Y\LN4*^e 2s&m3?_ػjן/^ČiEÔ%=WH; j8Ϝg!i ^` Bw5 !91}4o|{؏_ @<S&π<)O`̙8ޢ111(̟;#2f^ܚ9c_8 E+h[3~tv~ĜuyX<˂9{jB]WҋMK&OqFC5_ߊÄ1N.(dJ0oDL⍋u)rcO&Hx$V]nlac1> _7}Ǝ ?OvBu>;hמUl&ƑuM y n֍y˫C'gX xE1cbbyQt_30e(;8q_5⾓w`2iy`i"!22̤t=?_i kyv4}]xm1\:p3'bL}80zW{aL3:CUx D⩘3m:cz3*EcX9Ǻ[O{ {>'⣅y)_6 &&ؒ111({:L_ ZZdizv_Z1ŋMNכJz|i keΆKL xuXx0sls`LWĞ!)h)L_DŽ $rUiҪA]ex6,y8ƪ۸vSƒ{.&L78R_&c/ 0a:O?slL2?LkԟuZĸӹuǏ;111(̞5yfΘɤ>pyGKDo3fL}٤'3ܸO>,IKTgN=●qn,d(9TLsSaI4¸z;Ҳ@{Az+m^LLLLD#2ȋ2xi9"31111(L:#2ȋ2x }uxILLLLLAcJ8Dn4Axm&R6ƑTt»8V>z_^R˺x'eqkMQ?wvWHev}m(,8J+ {~H$8D!< [q r88vs?KmCU] bE)%I$“^(kOJd;TDz3FjPXU @XM=o{i/kjdG! ^|w-$HD3[ =W033(L84Jc߮2b7<%Kp)v_?+Z#уxY,d4A P"ETng{JZ#" 2HdQҥM%qrHB.󞝻ӐnRu^d?*tVc{h_懵[g!\ 0zA,cq#K|)j'nY2)Brd vu–^1^O~6w46sF@bol֕Od\: EwPȨ먫μH'݀NM{_׽| >U͸fنJ sOV+A,PGly:Fw J|+JՉ*up/k5pV6%0\d nk{lvX{]}T .rmߣK#UUّWPm@^orH,50ITIZ#U %j} 9` Ag ; 8] 0_Gp"l"g-cECBek,=C,Fסvu9-͙%Ws:DSݞ,9g=  @rɤ^S^",hWrҘܠV\KTZ61V奎tЯ@o=-ϼ\ /5I8[NbMYCqOR$p\gCze9#XN>KȊAb«+t&,?@+A~29bxz|5Qi-EkI=ųlA7*ƿdapuE4Mב'֪&dC)͏UMF䬓9e2bE&$!#XDI먿p&MX 8$rc@<II4H߬ux/_/e gy 4whŤ.o=9K YC{w=3zI{2<1o\EN.`|Ptrl) y/6AE;zgSCBiˍ#S*[g&k@lցX_nXNLj_OuڐvcLڮ(.)F[Nמ΍Ҽ+(I佉Ýy[n#)>:ħ&123ELW4!er ·xo BuĆmoH%WgRl$Uu4~@12rKDYv8{,(KX~# Ǫx'[ϒl ~bߚaY.Y]̖\٬)lkht5\mƒo?N+NÑ3OhߡLG6:IK3oֽAN7 Vաq *s"-/84ij!ppEvK/rg`E h*lԑ B%:G ߡL^ʧH>J" *XfkLLLL LLLLL#.e[x -/3WHGbBYw_Br/,ǿſք Cq{>6 dgӝ3Ph\\y@&3T5um[a-h ˇd4<?4U*d66U[o=h{VDnK(n]{fC)6|fLG U׏b'aa]fCڌE fb l .dX}zv `g<ؼ ˷ŕ-q}"p(Irq3ɜ;Mŕ\Y31HO gn$u ^)ʀ}0xkv}e4eZoL^`S?ۘ{ 1AIpCbsGf| N6G0v&Y VC}pQd=r'\n1vКj2e?`^~,%eŸ_ZI8"dXsӺFayA2>P; \Bf^! / )D:b񱶮w7JHܣr#%ȾaؿVw1`׉2 єiY3y VnYgI9d$b]IyAiټtE}ǎ)~c45؂K(~pw-4 D͗[\l}-)tM1gn@V5Zt==3CimT^s)u&xux&c}]ŚGDrty-mUb ufn}2Z64b{ WV.OS&'S(X`6'tE}ǎ1+b]Vq7H]&h0[V1daTwZ41 `5|J@jLG:ExWwTY Z/ذXD|PWqfoEn8˳ ^^ͭ/~wb# ֹ*҅fzJWd݇z2:f-1g`>fA܋:3t-ߪDZb.]iu5z2+~U64S&2hl^ ;Dډñ77glG(Ao_Z BA瞙8y}[Ou8vxA,b"KAܙE@iY͖၈7UMQwu@,<U5oywC4UaM%lY`hB0>U}Yrޡ acؿC7167Gh bA9QJ#F%fzPb'd0.T&pن2r ⾦ka:J cn*l_^qMŘn Z.òxewN(>U# EpF.JJ ^AcٿV޿5klnGtL֋0#x-e?R{ ,07b0H;=b!w|ܰsgvH8}}2J!08r+EfA6E#Wo ańjTyw1WA4 s\>N>X:X{jwUk.įTk ߿V167i7eZ/l&/\?ڃos[ۑK?Ky-072nH;c!wl)Viw |q+\^Nvf}~,/nh%$nHOm>n4DھO܋l4t_y?&^e!8Y`yټ NAlM~ǭ&aqX{:&$vpY ;kw_Ca#TV5WcEM4 6,ÒrR0#aCe,|.?uX (? 㰘[יEIբb$,s118kn4r}k"j~| aRMPk0\PxI=k$< T9: x%f#VCQ`QdԠO<ش3axثg_0^Ц9acwMդ߲4^tl,D%2?=tM:m@uvH3M Bճ1ع#dyɺn(VN%\j#U<\eqEP)pm  31.TRKڣ!$˭CJq_5 iEmE/&<ۊysA8oA1daTiI IQH:c I>T͍p8&oA܇rRXHNû@/Uo={xqE| k#g}  BXW9vyЩVi5j"c=Bcq24!N ̋" ^4iʭA܌, ({g :zقXG=&fMn nʝ#rDe[|:^^D6ͭH6]|~&!Dzw-ߔGIً{vEru#rWl t=c  Dj Z,K;$oc]а  Gbkb9ho!H2: Rgfrkzh"o/-;QEw[$PۋַЄ[4YQol%噉D0?@^IdqC8c?U݋w叓JQyS &":.l}:ΆIᱳLCt)'# U3n/8".Rŀ $.'k A4RI& 1P?&|扏 M>?[ocO0aAiy)JCֹ=XFz.ҋ%Ht%gш]RGMHOp2?DpF.JJ 'u  xX} &12<(-.p:r qd < "0 i[ wgjzzVEinX$ެ3QWE6Bn24ҜOu1啨*$eH7:Pnw%"gwТҞDe Sms|>D~*huapP?)_/;sHp!(w3햁IkO~?R{7O &m-fbR`9Xq"yG۲3111 M/#MMnP];dAk)mjn] ݖ^N6Ax?Ҧ4#=čp[zgBŅ8Yg9Ꮜ]7grm趣lG+ cئo WNGg YPuO;^=f?ZYľ:b޵]nCegiAs \5 >G{cƣz7B 囌'+WF [4NǽJ`J}J4_ʹTn< ~q*'{D~Y%5CQ"v>J h}sCb;˃XՉڒlÒ"K &͛jXa>7}"p(OF*k<&Ŭ7)ؑQg&> O37> XwXZaLN KDI)ND@A;#4sS{PTd v;Gz\ľ7$Nj8u >ވw wXSpYq 5]*v#A4 /ݐaf LE;~ހǂzVWíK)ch!Sc()+x҆Yc2yjksfmm!8v>0vA* -џ郃 3 6L?1gZoRk1`3m\oDM==blWufdR"H\5~@(p~;PeV85ߧR[R{O+g dAuNꆠ4w[&-k[giN+l\f o/M.*[hQz`WBQu33i=FږE5!u`hBRдeRcrڝqu[0n:R9e@[Ť3Y'O핞[K;qw^rtBћ(xkHZW̓qZO9֦؏ڪ CSm [z-"qƢN&&;HC.AӀ v>-x :'Bii4.+'"0? `䊓.ER`q_U@:67!2OQSG { @,lbZ#WQuI6Ҷ|( ~ﺽ|h 4:: , ʷz"MD`&#UyR,?Zv%}Y<%< Vo$BjI,8#읅ywС8C:/ڲ 62ն〉ߛ4~#m<i-bti)kM-iY<-iw' [=d'"0bfW{$ oM.3\N@6ϻ-̃X9` M(vf]o-دo!m˨oBaK+90X~nxG}Ӭq}TE2>duQ"Hcpc< ^j`ߣy#gs y;Iz }o#n{HObR͞nW8 8s 9%q4Eɕ}gzsb+@,dmE}w8Cp^8oAۃ4oZwIׄBYρrAi޸.6(7Atfr2|qѰRn PKR=󂘦7Í3RSYE8 Eh/d]=913fd֫L Hœi3#mOb&b&&&&b&&&&b&&&&b&&&&b&&&&&b&&&&b&&&&&b&&&&b&&&&&b&&&&b&&&&&b&&&&b&&&&&b7o'jn4AxRAYw_B&b?Aw . "3ZHւ{q8%f֏t^L4ieZ"A&3Ap; ?-FKiv fU?J_ĦfD)5gb*ہë"3?>ߡ2e o3uwkw} 0.[xRAn \ؿdÊxܥb BX$ajQ1:?l͡vÛ^d/| Sj&o/Brd v–#>;@Q%`ŵF Ӑn KJ.Kgu:zgS'-.{Vv]sF@bPw"`\z.vS{$뒑3ueїzO9ho_׽@l]}W>F.v?>*4up<&҉2ޯؑQeiW =1^\N&S*6L$YB&1ѾE3N\yiG;{}LNw+832}<0dHegЙ]#HڋjM3a(,.DCy-*(kp5 m# w?N)M磬OA|u2;,ޖJd}^E9vI\ *Q];^sުB}} tІ18}%y;Nm*[`-UH`$ bkNœrw/-Yu8HϢc$z` v>J sOj?pq$QHҒ|dGSf]it_:.k!3"e o1e1t,؎r8!^ E!y!vj 5ǀaex` ޡ(1? er  XsDYS{ X>4хnh m gyyw^ЄYs ʡ r5>wkM[MAMlEbc8SyKB AL L[/=$r8KE)6lADw+@ldzn>FE)t1;e2'}0 ϟtAwciapuE-3HvlXse b*::9M[Ad߉7Qona ' bsiA|YALe[n0-4Hn\bkr.lb@ll- @Zz{3_cb> gn"-kk-+G1 ?03.]tqg ]8(nTnnqb 4.139(U#S+Y1@5nkټY;T  bcvP$xG|ܰN3s2i̸o߾y5]q/`SqZxtqDKKѵv(mZ3~+|ݔٷY;t Û/o-,sq":Syaf ^8碡(ukkP\pdU/:;PZwnfLn>z{l0)Pi5]AɆ fbbbbb fbbbb fb -3Tgb;xͯ{ۯC'8ku?`LOq_y\1zN>m#WC mDI[=Nz1ay`L b@<z2Q4#3gYm2Gv0u&b=2߶\c Ҥ%? yX6ސ*¶r^swri8@OTnE]q{KI)w{Ci$,ni~ʴW5hX'$2zxq5aj$[=57T7ohof!#vS9xFk.3\g 6imɶ E~_pم(ɽXWv#y;MSY>&Եb'%8QQn\\{Rn䣴$7d51؂K(~pw-H/ 93f料 /Fk.3\g 6imv+\YAz$4~&˩@^orLԍg@MBBD;,O+iDgG;Q@w/2  wUBNip=X יFMo[hI,Nʖ 6gsG*烛-Qf^5msNeX36@._kz3gh#2+\Oq Ϋ3 ysA8D塓JKjcm ݷ`Aйgb$˕OpO$78flJA1[bP>³w<˺OHQ)ĝyQPKF i& 8@[1e Aԁbz%Cf*nA4n į깃C71_9esق7Ym;6C.04!Ƀg"ALN qن2ŜI=Ff&Ѕ)](bc!qfro&:xh|B&%E~(%M߉6ҼymDIG]{:'A]ң>I $n8KzBerlho2.NЛM @-1$)0ط?yEBC_ES1@^*f@=Ճضқ4J:ep2QoVbVH/,vrzȠ{ 6]uKn it^O'!йC ‰mWwqs蛎˒tꩉdEck_uUE9~IBG ͝|bAEWit)7y+K]ީNiiSs4_Z: N}=]vIFwP`ˊ L ?Dc~SP_^R@4tf4ovlW^Qi~s雎_U\,IHHhhhb]R@wVZ}uȰnB'ihFr[|MK׋ 3%Bf;8GN ?GU#o_Ih%qb+|&](<$Xx )଍zZ823*eۈoPr`zq+S+A tP\ڦ(X~IOUI:^O?GXz/_^=feZ823*o [/sWN[/<_tL#m/_h}?<%rHbhkaÕҍX2#1Өҭv/@F|!їT}3Y~,q s{Io{pbRV2gxr<8d2}K&.8\Ly㴉PNoogR} }8#. hBlu`MN}¼MQG ;#UJbN~sAb(?}a52-S3}kĆ=`m/XO:mO zTk/*{yJ= ؈?]-WQZuUWچ?l]F+2qbGbQxg/N4(NNSQ?mc+8f >_pZI/3 Wk>n`A'X!-N'ꔺ4/ۨcELG(뻷or U  Oz#>~}Zg#FN>WmE]֏#F{ҋh|({ PA#ŏƑiT)31_o;#HǓځNh@?!V*A`JtQxw$wcw*u@*kˠޜNq8qODiŏQ LW>Eàxsc-ɉ%.kю;$aCy^%*SC*on\x ݿۺlbƟ823*e$D(Q>$" R |~<֧|:<6:q*#V/wݷփw&#иFF@솲:[2-CN:C;IbZ.NLG(xcf ?jɍS- $ o忽- x/^許pg™l/_w/UC)~uJ823*]_7{r:19}:F?ù?Jr ^~%~X^#RvĻE"mz+օ7+G\Ii?%G#O 쏚qP2rc4C s}mjgr%j蘱l=ʻpV9,e $1`LN^4~4 LJW׌}\j`ёpH[n T8j~Y@li@}zw]qݎ%/GC6j8 FG(xc4 79a |kYej2Tܧ2[)w@y¥8;P\;W. y:*P]Y;ߨ(`D 1A&vfkKhJ 3-FF.C;S >䋉N3)>,Z{s4-Sd{Ϝy_דּthG篬?3$y=$?"AQ9TݮKpU=*9Z6c;{*w^/Ӊ\rutMzm251{0vGMR5ϟ)oHb$9I̹I~cyetґK؉f56(=G;㽈ޫpj[_QM:F/[iOT3ؚ֪WݗdZ஘s$GEy0G˕OtݟHxTK*bQKRjχ5ZJ\xme,yɘb29vO놓j눀5VF($##(>W_cEן/h~#D bb C司S K,v#NJYeUj (dTƅy,qr^1'9vKL=M',1mľ)?JHJQ}^pRv2OrAPR٠ w^׫p[{]5 &5c֬9ɉR:^OwO NxekTҵ>$zyp,B挚vD!MA`OM ~WoɌ4G1I `VWA?o-IMvRu#b:7 sP?8UZm.ݐk##un}k3wˆXrV;]['_.ENϧY֖OjsX6d]x7^5o7S*Fy%q❛WV4Q'm|,ONܸvޅAX4 !IUO,dZbY\A}_r}ѯ.d\_ZS};=^\gcϙyu'V^HN]^qa"z&Svupz4m=Nn4;s%:IJhrNsw" b@"D " QUaIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_autoremove.png000066400000000000000000002010031477034762000257750ustar00rootroot00000000000000PNG  IHDRlsBITOIDATx콇W˷{73o79N9cq669gs06s9G >ݒa0[ZVUuuէVK,~ ?:h͠!r7}j*}#jVwqd-WK GV}Z~Ц;5RaD(hÑM_evuThmB1 Z-14hqqd-}W`jJ*6!VZcZ)  v-ɤRD"S!ctaZ'+.147:=F9a/ص@ x\.tSDƷjHQW]ciou{ {7B?z}ET.`_wBE3M Zh^kC4,ߋ}0X 644VWWWVVVTTQQ1,\L|܃6Nb߬W|b+8.?g֠@O?_AAqR{˝srr@b]:hk^k,7σh_tV_immڹ}S MAA~<@0mYmtZZZ^^^EEZIϟF^WRuttTVVn߶1(|%AAO hFw%''ւ6GB"H{w?AAhƙ'bcc鏇loKW{zz4\.,a@7_o  imTTTBBBQQx8 eEVd2>Y[[ E  L  .>|'3Ŭ, /7pjO>^k=Ǫ-tZxjA݃XpjgYtsg9}Gaͼ3" 2-xQtttVVx8 ,֯7ʢT*% $jmmpw] 3,+-\W/m_D>^ km+/6e/]<{v؍î]v<2x l6mbW-p>,"! / (ǃ222:_u^Y\Vzg%K /kiO K^dHF00Д/և]Xt#@0\Ο;kTprrrY9s, N XJWKoeVso/Y`EBAdLrܻw2, *KKKKyy+c!N9Ϯ?>>޵ %f<#.>#`멓dUeA"+8&NgyykV w2!}#߹;Zy3%,r׬Y  rܽ{իWsA6lHZVVB,oŠe Nx,QuW[ * ^F/ ke1W,[hFrQ`Л.]a~طdM(? {9Y3To2?V/]nUceYhgPku\0kʲzʹ۵BA_ Pϟ'%%XfʲrŢի ay+V!nM3aaЛ eRX3Y2d֝;6~cišq.v z>k J RO=cԝWPי`9N7đ74f^1kƌ]_b,3 ,f99YHrcBMs,YjnƜ?4z ߬ RrKYV,_jb;sYo<<;@A. 1i:ڸ!`۶n8|8X[7pvm!;E}}l'[‹,+=֬\0yOuꮖw;Av+gv,l|UʇvU_XYZD]i*z! /(Ǹe`=,Y7nr˗,骃  ?RŋC  L(RE zAA&Pq)N`=   (Ǹe9`=   (Ǹe`=   (Ǹ__:-  Ȅʁʂ  *  *  ,,     ʂʂ  *  *  ,  , nwWS}]]MU]u% -M\vVH"x].(tZZLTAeq؇Zm0000lhoib FCϗ/bgW_W` N v΃}?}ú?100QeklWr4HB! Cgd5?&<5˟MFb7ME4TD4FTI%=b΃޾ٞ`ƴQa!#DNWWUh$bML5jF#=RGr@,3ٮ*`)H>bN{ȤtTګm _?g&zHl#2='0&o4GU$fgeҿ፲d9 J.P &ZS#Է>qC;βOLe~`AeqHiQ#ǧ; 4cq`p40;Za4Q[I˲Z0 _TTfyBLf 25LU0PI P_ )BS6x=d*iZ(8V cb}JOH0\8I:ښ`t6frB"NH k #=j`T"rrEyJQaagG;XKnv73ڡ MzaY\hQ :iR`]ha5+N_zVp^`# ?LYtG bOnKOu_b.!Sy~e ,1Ӵfn@d$.˫n !U5?JY r: \"܏g?gU_rOSu t [O[[3ZyϚ{.%zfe~[ ?3>_y '_aHDMH=D==ԣGD">z;wbǔr8d!ܩ7%1KՆ*6e[3B1tEu'!/zCI-jmpGk8A,̓ {:ɴ%$GzJYXƑ{YS&XP2똄vvgەE+:@oUV&ݕ`~բO(*[ڕm1ʒ1~E~ҳnVk^J>X|'!Uj(MK)K?Ʒ-$$z 0\8IZ ԻIxu4"RO_t)22"=-[lv+hew[+R,6GV ^GRѲLUu֣Z.aZm"CcV/1X[!tcG3$c'[*8{H=%xhx}lo(ˌ L&QV~H$eeDM )'wyQ_ qՒa~ET)hO||}dlJIO``V:׭ַٖ`==ZG;ZUXZZ "uܓ4uܓ% ڼX9]%_ ze+>?P$grguKPwzivo2"RP?J }@+ _!RUHڊS޿$ Nb&F⺪/ޥiD1/n1%uysb j'!&xՂK]W뾻LD] uG6qjQYEQNaXfv'<=-Oxz؇pMaQ[ZZ;*eшK%?J*.yuҏp?֐T%;#:o@l{Ur;J޾MDܔC e>:vqnqUCc]IM6p|>@) ڪ ګ ŕU3˥*8K^/,͋ E꭛.~(*-z5u7Ħoscö27JCXrdtՔt>EM7Ʀ+Eu )w5 A~MZC ϯ0\8Z!1FL zzcXb DjP50oeUt;Er=/1ioaRf /Z?ڡ :Te7}HgU_s?&2:# 5&.xwyJqey=Ie›QAw}OO`| ˸zXHnNoFVSxbFQ2sބL(j`Ym)#{3M)bv6GԴt2c#_t))i|ST y8*NR|3eJZ'mJ{Rb^P}o$eSRɅݍoߵRY<ϗȭ$ &IJ]nVowEÎp?.~A&F/iϨғľtKH\(+8UT^$&L +; dz{{崲a'#ki%|jƤixp;/$LJm2y {bH`Nx^XD)sIB*K1R4YxNoyۤTG0PppBjvB PXdy+rs[t5(bEjVT1yF/`:L,Gl]d:S73'#%[Wl0ҪR=d}@ͯN ,Uݠ#yY l|jJD)KڤP"2%,`Hl.S.<" |ԗj^E&KW3~_+R3EpН:$(1?;z#eQBo#?%O;aU'%䦾-FO|.R_QTիKXaw[e54N|9Ԋ`t-m [StWiRtॐʒ%{4.[/E&d:J*T*✘k[D>tehsR%Qm*Xp#NVu4FtjAIqAƇ&  cݲj0 . z UD+0#5 0U*JLuX\TDʡC^!I%bO# TJ5F-i&mhof:RJ֑\ThLy:%WB)K+XQqm5M<9[ѨJsiaf roBZͷ2h-i i( xbVwЍpVTZ\Fps/JK2#B]g*P} R*E/_7(mYQow4TUu*iEbRM*KڃTN!jqSȸܚ֎hS.la^Q*kd72j+jLme!_߷B=WW mHYn?נ5 KιNo/r:711";Eio  yAҨMC̿3,RyPI(hQ 7TLzjJ#t;GKm6YȻrC}9أN^aV5<(6%,oNntwĆRqa7XN۶H AZ]<6W. z5}{l6O?LEd2@L ;LW|/ZÆɴVBkFF|6)$DR"_QW*$Ӯ ÔVM%y>Iwk;#3 XF! ֏rhnh耣^4m& tu#6=k^/.Kx"Gfqcҽ#>bJ&zzj ?x͌.!#bQeRP)rasqj,W1)U\FL)Kʢ$M+ Y{m ;?q!%odsAFy s}]-> .$ut %5[^9i>(/r9--M u5,f'M7q"BbHƿu}a I')IW& +1C~RyPY1-ԷI-ՍGc@ @ӏ ?YYsAFuvi^[Sugc]maeph$*k虌~iJR wuVv r|T"V*䓫q0^i`!P_  1w~C2CTf32΃XYGQ7OQ%YGcVVDA@^[[R[[CI*x cŇ7#MH&&D/NB; 5먨7Ԭ MAxE:ZMTSY65։!qQ=d;*Cc%v06(%uRTEAi=OXeLB_&$=!_{KN*Ir57ӒR< Z5,`SLu|+8"?7d4пD}|n١w.nA~YI/k(Z Z_f1[ {hʹu('z,OMT ,PҍF67pY{h2)G*?ߦ@''d^#x=egDBAnVZFjҠ?  ljmmjP)HhhT)045ԍ lhwv[@9ƥ,>52>mA[޾{C:8lf]Uyei4j)ZLD1.eLYArKY̞  D1.e쌍  D1.eY`>6"   (Ǹe؈ L4R˗a#" 2рrKY֬^  D1.eq!`#" .-JKHI@F  ?#R7WlDdR}+'3U&O APq)6"2ʤԑчT"*) O(Ǹg4/#+J+J~^j"?u]A%#%K_"++-iz׫r |L:R@ $vPU^eTaH]",_1hӠL^=5dl\ר&Cm)(0zT>*JqD&Pq)Q^izӠ.p@E{Y`u@sAM>0z=נqD&Pq)F,&AQOA]ညX%L>0z=PYIc\k iժi4t:C0a:he6}`){ (Ǹ=TZ5Q +^^:R(E֙|\اNXr O&pțbQ%_IB|leV~?=Gp E+OqJN^ SPq)ˑG,CZ(>9G &.Ƨw$*Ms%v1c%ixZ.kAE`^|(`Hv}ZyR)e>75JAq: 7E{NAF)bVpÞ%O('Fм,Ȥ1.e9qШGٰ(EnJR(bQ#EZ{ouX8V^#6>i%Rl_[U5JƴaQJYdc%Jxluwx4W_Qa2 EYz{+feq|JrOkwzP s7;=C>з" s)e锍%1,e*B)K_oi8c'3jw%&zUYwbg@=5B pÎ60iNt9OOl~J\ Z&Yecf]ɤlѥ! `?8uJRTBg?}eq>ԘLvbH1t$܎L,ˏܱWE Q A#P߽"R3Ғ><Be8"ZYd;BV Ie;Wh%elILŃ Qv\x>)##)٥]'[%D͋ʂL:RgNVYHw0[(_jtqV\/ty&zZ>4-3gQr+bĺ}7aB'nHg9E"tf75k(7-r,Yˣ;B.H@>>9m nk\X'PSJ#'nfeVeЧY {@+i|tt35-nٻӓ,p H9| Y]Jꠤa?![L&iM{| =*ra(θ)lN kޏ9"X*&htzwv"YY@%~ ;7Y~j(~<%~뎛JK3_ "-OUa^k;4]aҳ16^~_PS_|o aƒrO󤂲򂸫bsDܧ.pEzIY{{ |e0v"_n$_$J?`LL; l$]oYzf2+˰*izɒZW*Ege pe&?7s<Ò)k=lZ"n>o.z\>"?Lu0ɝұj'!Eu/v2;#Ty}2S.ʽspK=Z0|$cP:*@,hۇOGqm'< }2H,۳Vl>X-(Jy(p2~yi  (Ǹ򅳣Q^TȆ {WM2MeYo/'/EJAïs \~jCIStc\uw*2K)EyMbTؘ_VV#8^əq,$sT@lNIpDJ$ JnAM֝z)>M^ iQ3?ʒ'aGkO>vRY#U{p#Ihr)UK~߅l+cj ~c˥W9)e2,lw"~:޿)b3},;/25773(˄#a 1o24>blf`YUs+UKmRR+LF=,ޗTQ=mMlѨ# Fn;yBe}W4j#4T[ODyAFE9O"~ޡQ}Um{5Il_~ד+')eec~ lcnUb:`(K QAy&_h>WWxl^MApvbJiw,zEYPabjЛ6"S`Ce1.Hv'׫TcSYa#Dz[M-Hz%7n?*a(Be6?3iPTU͑:HUG*2:"/Cy%'=\@uO7ؽ#eqxYxˮ(ìyB)G݉kEY';^eNoj%TAaS!.[.=΢z2KWJ?w!6L"+QynGePĶl;eu`,q,;k:N ,0DYtm6W_ȧĦv ^SIB\shk}p=hrLHmFYeqpV,Y/g'e].;C{/@b*|K;cB>1%;V:"['w>ܫ˪jDRVQë%:dq+r{XQJR)a+D*Kw&AOP%7 L)]>E%)w 9,K4| C (ǸͰ(FIC Ux,X)-koWʻ1V:R Z: ;;uH EVdkdCEupfo:2'r7tĒXRY2qT:wHeChSJ\}z7 [ jduϖ&!I1ْ#!Ln9(k:W2Bſ CopMކyMՋ ضWA)Ĵ eQW^ؓȤKox"lPev<\O^*p܇)0Tā{>T7i.NLLa.W) nXP-TCm]G2ECU!uu?P\))Q^xƃX|(&ܢ%kK u"qF8qĬgFʗ=v#!osy謒Իb $\v=H--/Jfi ; +sސw/l~T2,`;2ݷgVV&OЎZY`Ll_eU%= _F2 r^7)GQE-l0; WvsY,jH mNσ͛x̌01~Lވ|7-soĺ3s2b?OW딬KkAYR*Upe!)d\QNU@Qͱ< FlI}3 Pa0+zG7 AՑ|k_k@.wxD=멏 &E~O4ߎEa^+ ̓),wFp.RRY0baVz'ܚgMB1-w ͉݃a;}]\ WWE] ]g%l:#Qf^)6.ו~Z&_Uܭ_#tcGȩ~n[*2Aga' 7;O/ݚu63q,_G(,_Tm|qyfo;z3oJM.ld-pϕ,owP]7`ߣ%/?a˺^|_k=/.erګ3vzKxms"wrʽHxJjTG^NkȼNeoZ4_Ϡ(f6s(|sVjO.\}-E#3U`S]tE5`Wmt:jdAG]o۩gY5Td 2eI0!NA]ည|0Kn|k0ɬєkdh^Tdy>e<{0 2Tf?De\hEa6^̜"<895rL0S&2rKYEi4t:PJYDI*°@"zQ4լrZY:&FSyQYIc\hE$uw1Ӡ.p@EPYOYM~zʞk,Ȥ1.e>z4"qجi4t:PTSi_* 2rt:ۦӠ.p@E`/T16mS\CeA~e᲻ӀiPt8""2e m׫칆ʂ#L,ߡ, S\k2Me/ 1EG㲻r2RZ-AAtJ PYAҨ$TAA4jTAATTAAPYAAeAeAAAATAAPYPYdSK.$",RJ!i5x>",,2< ў!)>A~,5U壡׍d-4Ji岻 * LVG[Zҧn6KQ`J@ 7寿2 zz#_iij`vzz dG5-߼"ʂ ?TcVF6>fa+ OG:kc,aخBeADըqfŘ b04Lv~ u{ kC:DNWWU1 &BF@)C2>RN3+)˘wxe)/)7l_Ye|¾#ٻ PQZ4ݔtE^~إ!_?G@iGJ!jIAe~.L&JH )KiQ## Đ8B7ztST|/6Í/6[苽?zf[n#oQ;{7?@QBݏ索}hQᔏʂ1 e!~ѱgxR,%yڏuѳ2Z~K"eg_`l{,Dr{st%4~;[*~ri,GZpܕ=ܧK~m9N,cW0C]pXRC_eq4I1Xp8e'tw?46.֧@on" ަ ޟ/./^$|ccozīcK|_#Ptzpz!"MxeQ]KԠBe>Ay.7ZzVˊ^6o޼e>ʿ1e#+KAnր ~5PQC%|clg]P)F_@j T_Bon"su}w < ƳkLi__y9 ;IuW:z7*)3;+)\EeA~i.<dv> 77'[27t1ggުYyY BEOMlj qoWuX(E8$k?,5x31lwK{VAXį/sz^B jq@k.+nf@Y>ǎ_PK>L,ʻIkvN<64&:5)P/C,Gn,, 0T25څ(4lSvsԣh9~˝X޻U~Am/VrHۻf)"i (mRm푈x=ÁIBjݍ%(im9CֆLWd{J  =k=Q>Dq)ILċ.ޕ8Zzoz>^?-/O0] %al/lOCƷ@Y=ӱxǐGr;#dZVIgyie9`}ǐT}$W#MKxe-:51,ZƄܒ;k=.0~m{dz2毧Ơ^]Y^ML,uH^ZV&*d/ɥ#k}޹$RX_7*v 5|p?1z H;f.ۇ%]&ATfrm0y:;Xc Ŷwc0N"զ,zMIB?W6bX[1lQk%m}2@,=W>9KH]a_RB/TTyÎ18e+ *CX@Qw;T"C6Tm{,h!~ry>sCj<aB!BR99%mlݍ>ѯ)=D̈́ݙ)؞Bhl{4BT[m-(ܸڔŨU$>x19(pӴ04],Ad#t 鎡!{+1tc)^Z?R>OP)gP>)lTu<[6I?8S|&uieBRlcXi2Tǐ: EUX@QcUe'ct }ҟ7`oqj! !K8QѯVfPрrrY]АǍX-78GpPK:ݶ ,t8 |J]ڎʮ.7줿5S`;<}W2L.\B qwcB`dQue>d-(ܸڔEVp<5~+ȟiDZ3+RS EY|_ܔN<2'܊hkDteAp`F}wN<6=8-Yo|jKU:"C+KY)?Y/uQrUPȇ{RɁ M"(Keit/W*W}?e삩~ +s& [=;|5v}}@aQde)- ݾ.)5!|LMA `^qq r&Ըu+KO$'SVQ#( |TNG[SѠ҇SYuCq,\2{{[BcA?X 13vr~ސ#coh\?[e>PJVW;7o@ C(ҷ.APL ģ}x}uEKSf'ʡW (v>*]׶57T{)˲HzdbC =6HT[Vz n68@c e%Cpu|K$e+H+۰AYeePP@Y@Ye9NaO9{> @Y@Y/˩Sښ+Jg'y_ڧשѬ9ɨIb>22ɠ' >uN*7tUGUW,P_~el,ӨeQ؏|eh_VGGW!@ȉʨVcv6 PApc)cIZ2ʿE6 Bao޼ʤ)Lz ۤpQ~֨&>*./I5+AY~x<Z2JzFU|wY2 Ů,KpXCizVq+ ^A |*eIY!}8ey+@^2>t x/ao A1⌴]7=]զ,HW*D|oe'(=.*QS׋R(Z<EHod?L3+H&e(ٌWxQlדE?Nz5&nXίS؎[1D-,j ׅ[ypPH) *êZ}6EFQmIoޅ f~bզ,.;7C2ƯFs!ys^U]=TyD C9*Y]ܓGK?Uc\EM2.5["Cغ= SW6- t [( 2Ǐgff0k,%R]25551 kO҆+)!w( ʍMY6 o&٧3׆2N\Y6vb2ĭm/?k{rH[Q S۱k.; wN}=ŷNpu=v~2eq% _2im_ơ+D DW֦_u0 o6VKԫ*s/dԫQŋtJqF^},ƭ4&'7^4z ,_|rjS-7O~;3T(vLbjFg7+w&v/,>u.l6\ kلRU̾M=Od^?81rNg3 .;R|foKQqM,yg{i /FŏlHq%L 1ur.͠xN5x -OO65n YBpOWdjɉ(K"̝߮r {yzZ-un̦U9i[6$O tiܝN>8=?{JxfImPsf]֟P׎}qǟ4Jekt (26M+%v |3A饅L}~囗T݅á7 @rرK.WR4 ^ ܸڔ:lMLەHM8kǪh?s6Ǩ,IߗICASW,ũ฽k~ O>]vum/udv` {nv nŰ9Jޅ%{P# R+E͝w#Tf\>?oԈhϽi󛫫:>?1"K=Jݒu&bXZY| ضeRX\7x#D/ο.tKj52Eq,D ;he7@^O+[GRU _yw_>5ZwþWts2 G!e9.~˭FY_PK>LekЍQVrwj* şhtMN2_[Zh)Keޓ}(&wi;O}:qÀ/ RaBCϚDy@Qn\mb*~7!;Aw%xޠO ˓( Ǩ, W"S, nǶ=0bz& W?3Qohog`:4heUf,TſpG[ UG] 0CCkIs8P\RY*ηHijC:셫N$l#|!*g'}H]+k]jbFY40ǐptOA?Ǡ~ (+$"(Kc]5=E*cطٺ1D|}qnicJYz ]I=ODPl[|#ID`ܸڔeX)I]G7}Z_9tnɱ4?½Xxmxuь ^Eѩun=3wZrHK:cCj<a7E.T_]m~@uQUi۳!Cf K~^!OGV6$O:Ib cY "3Yzrf}r6öÕ)Xbiz,V">EYj*_~=MYʿð9 JccA+LШ>)Kf"exERֹM| Ŷa  eCW/&/n {7PW=;gHT̠v-X2ɼJ_4EU8 |[,밍w%ο}Z%koQTp,,X+TZ Ʋ;,yviug4mkSit(kET|l#R]i*LTu<[6I?8S|&5wbW,V ,uTݜB)Z,ts48@KpG\ :.RKBZr*1.7uj7 4+|(|rjSZߑKiDٜKx_?t2t,l9ESX-ӷ&|Wf) .?^k{/ϭieJ$[= yKX}bx{ N)Kڵnwl巵_KkR"G[ZZuERftz ( /YYPcDQիW!zoe`خg g*buQBå .7RLèH[$l-wf D"8@R(!kAզ,zɯ#_GD\L#Jf~ך_8~({jC+K;%_KUCT<ڎai7:J u {FCkQIP, /e`',;+y̭f m璱/~fFYwc5Eu@o:*x6~V)uuR'龘y#c*`ؖV"~΁L]h*q.[/naH4fL+a5 :[j_$ee(2B^H&O[NY>;@Y OeAESk/~vyW}XqÀU`6B{t&ʍn,NS7N}?uچ?nESoCپxɹѭ)məs.Ǜf^ߒ Iqi+u0,{o"NF{Zq|ٝifӷ`ƙz f딼s/13q=s_pڎsJOe};=%e۱;,b k϶;#Pc)XҦ׋y{/.*ޣXHʂP6 c;/U1)x(ý FtaYsQde,-E SK+ٻqI?o QG8ŏЖu%fb`>~`PZƂ(ܸڔt :?-Oxo< C+AdcYx`?$H%46g6VVV666WT`v,%SSԈeZ$HA LJo $qM2iAYo,8!ʍMYkѫAY$T~}Xnc>F.Qde)- ݾ.)5!|LMA^7Wx̃rD,:z ЫT"fhCWn@Y@Y AZVYPtH5&є0obbnbaW淦PՌoW&0I"ۿD"F|^H{Ò\PR]QJY!}8eA1bƂ藊CƲ9#~z %DeT9h+㾳o.G7ʂ3ʂrceNt5 :Y!}8e챘v+-&X0dv6Ƃ~bft!#( Fȥ2 Ѹ(4$},QA'N.w:o޼҇Po]1|E!h1hi,D9ʼżB=n65V17G]7ڶ憪"x eYI_πLa(4GF|#铊{ˊyY/#fa,,Axbl%}Vb6( ,,( ( ,2p9p;Gp{s( ( q9ujU[sCuE < $CK:5reeN*ZYWUn4'tdه/ccAF54(~ee\Α֦a?)%i5(@Y@Y/$ლ,hT< |eAqnWn7 TPBpʂ\MI3>|teAPT'3~+K?@Nu?q3,V^B(Ń,@Y f=yM󝉼]A+O M)HygmJ?'y":uDR|4%i;Jt3 .;R|fm5DOޜ@/9q㡛rL%5Xv JyYat)ےg=#qNY^;s/]Owtn;Z8-je#* VT;ڎ׋d7Soi$}_&UF?LY_Rj> {-<WNvY~gw<徔,aҎ>Q[խ7G鍤,Lͽ*W=upE_ޖ5q6S}I5sZn#V"VkHnROE2?OjNY,Z,4Q(>9]!I2{AMT*74 οe\,t6k<[YNV>44{l٘wu!I[$n>A3}T{Whe,: KsqE6$o,sGOxN޴6KNKŰ'FO'g,S+Ǒѵf<_Sq9;Xޗ;wU:5$ZY^ bE,FYZuAӉ7M[ CӅ=^LFa(+ߡgHT̠v-X2ɼJQYfkn%aʢ 13KDYϩl+FVwۉcY\,`nϓ+V9}ӣmt]No:wDߔu`%p-xT2ߌ%S#( õQg,S# 0M,S%vߎ7ڔS_m%vkHLMNGGcE,FY jeng|G".es֒/u~P CX&s,?eF9e! ]Ꙏ!}~*?a;^yu -v-~KYYE(eWǩo#ͤۃ-okDQ-,l4k[Y~ )g-+zCt߯vZ&zN &S@1fH |eѫ'O~ ?'bQ5}'ĹFTCZY^Eށ8,q߭z~Xʭ=Hv K;vQWRШ^YCx{3m,+˸f:?oO+݂ٴ᷑U嗵v-08V"Ai]Clw!Q21>NX@,('ˢӔmqS_O}!ŏ[y[P/peor.ytͶəیs.ؔDHzBll~vWoO=n͍]͂+'b R2=ul`n_bF,=eȀW]uuWjNK\o2^Hd/oIfƶ8oL?LKtzq#>k;F0E+2Ēm9P⎮,ׄ=-b4p6w_v5 ](x(ý R„E,(˧Q1 (H<( o |O}*Khlq";vŋ? E,FYkѫAY$T~@Z2u=pz "AYPO, Wh鰇aO AYPPXZY+JH5+,HDFXpRxeeEmMFjVHNYPNYuCq,seeJVW;7o>IbY\+ @?( ( C>t]PUV,"Q> Ƃ8+PPXTKBrW,}eePP@YeeP@Y@Yey e!}t9Q( ~`e4ʂDhe?{@#6 g e4q97_G7_FEy ?Ⱦ$$4}K8U|_<t_1$YY`ŝ0m?rHy!8) ,cQIYKk1le ͵n?h(S΋'( ,2Y.7^gag:93n;AV TP\Lnե7lOO\N)l:XeC^ܿ-^W¶p+J}'!c"" sc;6MBXLN o2.8e־k7R[!7IZ ;T5L21>Mn,d$#LxҖwjn?(RXERB_r([wT X`Wwwa?8H_*w%`~sn,R~sWYhѭ, h][owV'LubYBɑd,r:owe3ڬ[RriY+Zxu+}l閳a^T-%w'agj wK-Jߕ}aۄm'a}9B%[QTsfvLC/fvHK#&]F@YޏĢ,(,qc݅4,D\,XQ۰u7z<~x"lvpLj$eqŰyrJ9J􅷲O5D7a۞ M+KjTyfGɽySYZIY+V4:;yM%O~Xa? GbkeA8,B^H&O, |^JhEQ0VJgfմ 21lYvmd,T~fNg*anRnՐ (loQX 54/h~-ffGƽ6=dXʂk6ԌtK %k{7c z) }s̓epz--* 3&s_}Sw=x)v娼s0")yt+#A({Q‡#ΎH4V ;I-"|eA  CQ@+)PP@Y@YePP@YeePP@Y@YePP@YeePP-zNaV1nqI2<rX-:J54+^ &n3#q ZPV`c,Tev:ґW%4Y,&x(4C@YXI MѩWnBejjrb|Y&']`2?J+H\_BK(QQ? A@YX e+$X@(~|eʂPh,@x$( ʲD ]F/tjZħ0­ bEUҡwtg+\Y&BcXR6EƬ,KW]O1ҩVK--6$,,ŪQ{ת} <.;o;x:6C uVdXlo|"lz}lV{}_vܕ,V,#2FՔK^.YP=p2eq+XRc W&t^ݔ+ج*'%.n Z"lz?u5r(I) i>keA~08 GYp*^$]NW,WY.k<$|Dej٬AWm*(Qe[A^eP688RF`r9+xp4 (+ Qf+| pJe!nDX r>PO+ + /+|(k*̢zs *[e2u6kNֻ[^5bU  jrv^yS|RjKV]E-^ZYX,j9eMa#K+ҿZUr9Vu Km(!9~De# ") aW j#,{FY(T0pX"oũS cqT邈Wڡ Ua,(SQ^w򚻊ٜhPI ج>!ڶ|VvUΨW塓n៩zxF#p؜ -gS)TZ#:%-E,VIIY>t]*6ՊÕL-͹,NITʻ,vQ !AVimDx2;S3~mR{H?bV%5[b !_j3@Ye)',"#{|6ЍNIj`ieY;dT0'GQa *bd62d+P3eaepnf>U.OWc^Ms6NJTEVE9b#ߧ誗i$!ܪ= ne5])Ģ,sUم7U̫Z յJE6rQ_+@.JWY>alrmc6k}{F^r7TxzeLc a8C.e;pnNZ#w jAmѸ1 6#x@VuH.&"zlyEڥ(rnMZrE=T1Q԰f}"6FvY6#!(*SƲ,6eJuv`*0t .^ mŢUϩ6PM\NZYW*ܣK%N lta-)yt[,pHR=wAeq䒣( :n,vIq,nUʂʧK+ҿZg -kЏ,o,kS!;Fw| B1Pd$eAj+Y]b,ᔕ]Ӻw TR5}C!oG'fQOyg|#}%F=( (*syŨ3.Nlf`qᨶkf5s-DQ eߺ@zXh5ؕۤm@-Bd.V ]}345PmUMf^RIYms=/?r:{ђJY * DRH]z:-x,)"r ++AY/Pde)de7-,+d'5vUJfz,V5pcx]yl$X]mVPUz.beH,L&M/jBշ\Wמi_UW՜"(\6^c[t]ZYHŮ/['哄iV,1DWUa-9ޒv K,QY "j蒎^{eI=M F2%# _,"+KbsZvrإZQ)a0t䱊dx#n.\,,YFrB|Jի2X£nXu]*^K$:~.o*\6HhZpi.fZZ٤T+?t2sXy a'NT IoP7yg9:cȭ NYZ^ch2 9]=hz XlnG5MVagWu \6ϊcaT(%EYХPS+]MH/en^GW PI =hPK؜Z{e WYJ=j :9|el᱀"#}-쳫xtf2tôD*+bP3 51.G/5Fj|G!]. (sw!ӛ u?(˪}}#LM;v]%N]XegUu50bK٪7/G{m2YY9ܲ65=k+ʪ[!.'^kQYٶH^"M)으⦁e*,ɣgv]OB@YXaR>DĂyXv9Cd{Xp]y XP?_,!PP@Y@YePIes)zNaV1nqI2<rX-:J54e[ŏ3uvK Ռdf*38z5,b1( +): ?^MMMN/$( +î qE+ m,XGMFx(e`%**,AYP@Y,'N,1I;R 26%]]#yCֹV AeLY&BcXR6EƬ,KWtwFg:npJiPP`&.a4j}o MX|`qkW;Ո*qkE9lh<ǬSiɧkfwYŪQ{~fK+ *YKeeecc#zEY(2Ve!Gde,N 3%a,K(W^(AYVU,vA\kyh@C g;+LYn2>`k-(ͪRy>,GYWeA~08 GYp*^!]NN@A ʲj:Kʲ)dhcl_%_xaFeP+Y,n?|e<8ᕅ(k YPq(AYV-.+SXK]vFșϡeSW%ڒl6}՘]T1`8QFqs² ^ ))aɯh̍NYh;Ebmƾ\Z1uyA:5n6s]PݩOwFAy^6==[d5P_ʯl3N7$,|ZYPڬEهE97]Ĝ^[W WNQcѬ g^XWcV`xa6Q]@WZUęQ9Xjߊ&;YjwMB5fa`0"ϥբ* >féz͢[$%e]ҮWfQ +к܌1ɛrYj',,hBUb+(˞Qҭm+ɣKNnisKnyg9WԩPuk9X\dNgSW+g$eYu"2*ۋYA^sW1S!S *isUGE_mgy&S'rXܺnޠ XM5+rUaAPgRpʄ FEO: Vo0l6=Ur^D}*Twhgw+5znn~9)i*5Zyw.43Rة5mdE9MRa4Uz|fJ;4:V_ Q5X-"tl+ϦRFTJZX ra"f߆DBڄ6jy({y\vvuƠW6"yTl0̒s{Ѿeٟ8R>ʲԮT4&Q:|KnGW=/]7du|@(2rLj~ns3,>F ^)3z(9~'#^dަOԠ |PeaeK[nf>U.OW^Ms6NJTY5C-+k|j-kܪ!̸US+UģnB?SNEm WS*qt2ۺع-`H_ ;k51FgmƏl\:oAmA xFzllvՀm-bqj\CƝ>MV^9EY21VVٕr-y3,꾉;wM9chv|"6F$>&&U*4 eq+P1"0;p]KTd#ITЭ)^CKj(jXAmxɼMM ymn=*K^mcYU2`%T#>¦ 5.Z UŢw=M:ܸ~tE]>"¾NZY9ST-Z#la?]A,T4ȍnb&>C4P&~ﰬ$/bg}m7x o|,vI܎\H;CRkThʂP^9S>.PS%l,+99hi2XDۙ/(],Q( p,g"Èʲ{?q싞{[jޭzNA%۲,s,ٲ}qA L  A0 rDL3n r"/S,pLmQXrP(K!5ŅF7t~eDW7f%&~cs#FTcBDaj;Xp-UTʮ;2:z]GAY@Yn¹,T>h4v.əf52"72'=+2-Z\"hB- ԥѝdg攅MJ1͑ÙQZ)-Fp"lb'JNYi}<71!ѕAHYS4x:$YYo)mʂT x2 kR!6.Olr@R?\WYږ6 'f-2Tɠ3˴J,C9Ђ#,v9zT:8(故79m}:-002\i/~rhW 1D¡a""l4Sn-Tz-n9n%Upbzg%T xRvnGIO1)T?,fhyw^;*@*:&DbUKvԮAp0ZrCIF|Q)7P#,@po?Y;ei[+ wjْF;{* DY2_Y677ʂjA]eᦑ/&e͆tBDUSL%[=(\ਁD -h\r"h"8*0ŀEb_$µbeaNwUO'Vّid3H$1р{wm+ea*y@4 ]WwSh`OIQK&sx#d2(( qw֬p%J4~to5K0Qϸ3f $yDUBtx ,gP z{-r؇_\\PW7KPi؜Y/ùF;EchTnI-Ū <{VVM/q e:3Rf5Leԧߊz Z]mWh>bҮQ-k\atfei"gA%` P44C"#z9rT;čӕ3.AYL$XTl\Ǹ zzJ#,o j+T{eaڗmHd`Z8v7'wT|bJ}8P5,cQW6Bv˔Klp5PY-NS4fwcrn-U3ijw6$e!M<_@&+WH>Te}}":d~T2P_g Bܻg7j'6bڙ, ܜӉT&sĒ~Wԕem,$ NJi܎BJB+t:]Q UͿI&PQd̪d\,,,7gVrK}7ڡ',,D ,2tFWRr"gGw;O}VX߉ee. 9hb7G67,%J|$ȦmeYuah2Nu(( Geg%&+uIi&DB@Y8b04Eh(RnH%b~kks}m=dc} y 8(:,( ,,)R b~)r$Q0\( GXeґP ]DzďK#+ X tV2)$+4ۘ yȁtʕesc=Mqx`?iJ$Gsc;[YDG1@3nX__Kƣ[PP?ʲJT(( ( + 777X]߸H.MN-?Q1@DvMDN=VŕAYP͍F2N[fPeK|BG G&S.Bdzee ZL2-F4ut1b[5iEb8Izg7f t! ċvݖr"U 'TTᯯɤaxxEG(,d*mT Hp\#JLnPNe)[W&V 0)h&BDE ~S* VީP<r7 dgx$ZcE2~Me)|  XYP ۇ\YȘU&k-us+4,]Yh"2q-Dܰ09WjC/џAY ![H,AYlv y&bוo;:5 5<(aV۴8kr~{ .j@-Fqvx6R skbݎ}QiѤ #r! &Vtfܣr#Hasʂd5ǏZN%\hUn,wH q^DJ'KQ(J@L"L=G4ĸl&)qzR0SdM~U)Q%bϬ0LT:-p٠Huz<8Z(W%Mj( eTκ,d"OdJBCRI^rekkm (d;eJp%AIzVƢ|ǤjL2!:u/Fe)'="a ;߫EaF~_z+~[wUb"n" PISX4H(aU\ rʮ g0 ,(qL7;lQ`b;fdWj C!ϜE+ą٦IdfFiw(wNPuk;Q`šn*ϐ8|X3eaRsgbf&$}@,}$;k;=ӾP(t;8b>_8G<}b\<$"cE$/Nh)SfECف+E߈j-KPcz2I֔E5N2T6W:d ]4qy!]Vd(sZtP$ w"XlΠz=0 &c{n,#eA2 բILc,+O N$!-/pgyCHn6LZ9P^BڧTDv68 Gm˱D"blֵHƯ,A抩EPC,—"LS" . ,7Cݽ/u]ue!st'2,vaFU)6 1ո3LƣpV vO0(M,XarKh?(+zc \2EGfmD-)|7Er2M5c5.S%rZ\4.7DBo2N KJsGd#kA +U͢bV%&?]}jLEUIǁH,jnp&mJנ0PGCv8"تʩGZ eg`F/L'u8=sTK"ä#l ?Bu;'R{!:ECOt4TCԜ^s2(˟FY* .V &Dt%Jh_׵T2pR =/P1L1`wBpl"[tWtivG68Dn[ s zD6-P5Jg `4JD3}~ni^9d2Y{׎8P;kVb%?S)zL3 #YN^^#aԖE2Nq\_#Ϲ: 9yBwd񀯶2w,Ge:[uhwe U=[ uP8ud>Y@Y 2su9O%i ,L>K2\/JƯ(9:ʲASd709%C$r̍i.U'] +l+'bݺ0WJPhpZD<8;?5lC@*~?J]2pQ2Rr3ٕ}$Y[PiT=ȯZޠJ53̓4ʂ*nceQYȘU&֙IƦMZPkqw'FPPe2ܙ޶U SYZ9N/eߤo:AƧ2nxj#Jg=J 06Nh?,(JVs(TZ%Xoݚ/K鐁"+P󆉔 O33:=УQ3hjQzB28m+E_\xVU 9R6fv@p \*P-N_ԿM>k?7 7|-) &WHEl<\W[* ]XP(7X\جD2D:" \t\F_i!>o+(jPȶʲbΥQ%:ttU)+oBa̙m+ ,D)UP)XLͬRISX0Q*\?z{xP9eB3F8Rl(0qG2Lhr+Imu¡g΢lӍ/Awiw(wN0r0wvD kEEcQϔQI򞹟q9D*1N)=ӾP(t;Qb>_8G<}b\<$7벑E$/Nh)SfECف+E߈j-KPcz2Ijd8ʤS^됁tv ĕ@4vY]!kiMzCXJ7FY@8- S9VԘ53Y7Z|Rj"CH2wfCFu־DߕŸ B̨qS,u er#6X%PSYT98 ´B*R Y*0 GG`Vh&նGw}> ϶,̴ Y$(aSYpGw !au22*iގzT _3HHyw 5"u&`)l<}{zIG/;4;2㉗VsMb-*sO+ 1\,A.[LVaM8kwK1x>4d _ WU2dQ;Wm>#QiQbCD4.~G=m1n,T!0=ܣ!=zga*y( l(K>2pi.Zs="5 res^݀Bv,tҪ؝/RŸj:S nUvݹ,DE[DJ= H]GAY@Y\*jpLlOR5eQbB3ͤkdrEp>UfvWrEEDMŝ]4Sp&Ri wHz2L`q¨@͌#}-.;L"o%8 ҩ{SEZ>-qkct|eg ŴL4x:$}eaդ@ڷ_Y2픥~eHYium1n,(=]œThN_UeYW22-3ʒO/ 1|X_%k KG+FVY7Sk,YUV |}f֛6׷¥crXW 1D¡a""lo@-yYΉqt7@]-Ge6uj(13Ճ¨8"?оEMjw;7&Ϟ.׏]3j7.wkcjTHEdhW`RwݽfIHWR :nDY:dT'eٿvҶShb$܍R-yIȟеا MsMͤD'h2_oessnq70We_^YR=<l=(ˡ{. SMjpTPXNL"Qٖp4q.x)DpTa;ʃz²?\N6-#-g炛3_,J S":=@}mz1R(SSIYュ-{jj7pś*Q\걥p cHj+ll (/Tib&)gȎ7+R)LB]mѪl)ue9&D.Djdveo=I9CZ~/.U.fvgK W V)͙2[7kSTTfyҤV+<{VM/UWNJH}"\'1hevV4~>z&T]LrDTQ-k\at]-_-7XC-pCNNi$lb/Op TWw:+ܐϨڷ´/ +v\( re1(H" ZYTpU+eBe1 (!V5,cQW6BRe&۹,J!Y?Mp5W,&&n.\l"Voey#u%O$ 7Q$Q'L؏U y~tVۓ;QRxDkPPPPP(Y&I&: Ӹ< L&1 "eeeeeD ,2tF(( JSv_/9'fg@Ynze`˥B#,kke 4E&ѭM(( GR! $4G[YV+Dp]̤b~c} ?trtYɤ"<+uIi&DB@Y8b04Eh(RnH%b~kks}m=dc} y 8(:,( ,,)PP@Y#C$&4doD9672d.6,, ZL2-F4uy[b~GK=WRpb)HpQc(P?F -jJa*RfBDE ~/EIfx,hVLp\k +,]AeU|"I&ʲ_Yh"l⸮WBtvG&Q9-2Pl2*&VMSDPB)0+`bUS%!c&R]赸ݓqb.]L r|~D'rV/lCVVΥK7[΄ Sz.U8>tfܣD_) c6~NYP0QT+ީ~K<-һ헥]jtX!1G O33:=УQ3%.yBL33y&FU >rŕ!`KB*=-Eu8aWZ"Dk*  3\SZ6׎Eg>k?*+|0[κ,(phO@YL7Sv .N8X`iDcya'ݑx40; Ä&@$P8YB\ػXk2\fFciw(wN0r0wvD@+^)x$|Ƣ)hMIX" |I*g EnGǴ&)|p4xĸx0HpE$2$d#H8_0"Sdq̈́<W)&Z1$pd)j2Jeҩlnu@:hJB .Q搵4&H,'D}3o!|}BL*mB x<ZUcv&T:,_=L@_]!tl*L C%Ѓ Y-kWz%` Cv Yo( Y2;pm9H$^_P:P?^Y0О+PW5u94"43t[Ya^#M2zK&0K1DpX)1֑4rhP)S$:Ըt4ZF浸h \n\Zb8~RtKNM0-A֔ER,*fUbSY ݵtjJ J灡H,jnp&mJL6'; N1+K7ʱQ YGT0p!3ŵ|o2YuCdzJ@M"we{һg.ECŁq9& Te9L"rԝ4 #ʞIj{4s9TEW闋tיCIqoӉWīwdSR bWV xV&bX]:+WU`}сcv~(KCrks'SɃJٕ(mI> UL(e(S)ڮw)KiNL]w3IOCDU˸m[z~B"1T)Tn^Tz_lgh,f. Z56'(1əf52"Zqt*3{R+"Ӣ%&ήM])KvVG8eaһ{fs$op&8aTIc>`w&f .6N{©t*UUE%N,%FWQz"вNt(t)$čHV՞Q 0B(̤BsSPvj-G ,ەҶs w8I'SvԀJ!`N:,eC$z&2-rF+!rNԢ3Zrd\I=1!FX@Tm** ,;s]=󃊣VQW nD};&Ϟy ׏BegP[h\zN20ѠX9ت%Nt9]Td$=v7fUe *t4/tq(6^nܦV ZhIYj=@+}z,"gvGlR>ڳrb϶As>8*0ŀEb_õIbeaNwUO'&Iijd3H$1р{wzf+ea*y@4 ]WwSh`OIQ(sx#d2(( qw֬p%J4~R%gG|f<[:tx =Ȟ{H8.ԍ/x‘p\psfyto#ּcKx",󻧗ݮ -% *w#WVXbbֻڔ^XT2ִS&XZEla.( ۞L"\Կ)Bt̯VeWu%"}H˯ť Uoqz[+ ΄Li؜Y/ùF;EchTnI-&%d1O1 e"SLg]wR̠FZ L[QA+㶫M6 y񳮐LEΘT7$ ר50:T@veŠ k`x6 sPVfj*bPI= q`eͮ+Z$1$J侎 Rml[ݺr{dB %DTrڤ.GYr풐C\D XNXޥM=J%e M$dtiD%TM7%]!ҩT:sie`9naK+lޕ-'HoŠ@Y@YeeP@Y@YeePP@Y@YePP@Y@YePPnreah$Jd؁r P?FYktD1@Y~oe! y˂kQ|Y.Q_J{{~|Oi>jP?7xJc$P*Kq%8/;sl}xEyN|lgvo[~V6@)EVB1n(a7AKs?<%%wqo+ScS2G?iuwlpSl]`Eu?6l^'z&J:@yOsB2JA *K$ys+K./xivzZƹܼt'O"_n5,cfj|G`n}GFFJSq3EPPPP M%̷T ئwu M'X_[' IYYQj''W*\S }w-g N|H+;̃ognʀ썳USycQNgQXz%y.Mw5cSS0oSe_$G7캒xI xsel1MɁw+6<=7NV#C>usH N>z6e1g lT^glrN ?/LyYm{v6c J/z 1'nRsQcK~˰ejn1AQKi{qͧr1mLC?,ΌSpыabfeaVln9w-:,#! r6c r68650g3|q_kvİ>1/~o@Ya1~md{MYϲg돕17$É ;AߺZ Ϣ`(pʲJ+G_6īe 1Tۼ'aF݂Sf`2 ÂMao[M! o 6dWr@,|qǫ|ԇV?#81v!>Knzhο'8Bit>F1KY,?UuB,}I |L&N5>ZyEj?0$]FwH^q;KtѥHMT@X5پ`uͮ,hH{J?ʛ\߾ٍP0%;'dONu% nXY#S{Ca$'ߝ⽡~g S?Ņ3<* d\)z1QSvwuK4#3yHdz=Uo "ADž+5R},wBem_=~LpW?=+d&9_ RPS/>tcq=lCC6xMk;d,-cnve[mʅӴoZ 'וWs'Q0@CCPVs- SnHj ɵNY|Pp / 7om'$ /?)Qp|tS07C@dƻ; Q;(K)}y=)yXKe!nMqҝY/JQy*i|V]os[Q J=_-C~/f}nveq?EZ7z@P஧fg}D 8;Ř -kZ+ sg>=CSlm];.Lwn;Pީ/#D jO NmNU:~jy7nεPczGuV UON)s1ۉůi,秇ڿ'I])c:j]YAƜ /)Zg?]1~6A- x;.rrnbt"g&5|ӟ,a^(Ы]) }we#S&t, 7yRp"ez6ګY`מt,TH 81m3x3_uHi3w6ec[T1hOنurܝ>Q4%kZ-R_<>s{e15*Ծ,wob\p |q~*O^x:gޓ99> #V=sG%Ĕkrbট y[=wQ5ݍRcrO^~6~=e[aRԮz?}}kek25%{|{RKOWQ4.vr{(_ #-y}c6/>Eu׿n$䖤<ăhV1Cp+KwOM;mnAP`8@{@Y~3e%x\( G* ( ,,( ( ,( ,,( ( ,,( ( ,,( ( ,( ( ,]+y D(˔u,)`?XtjbP(K6Gւ4*$XIJ&}(eksY˔ul c0ڭ$ HB@YeePP@YnDY* GKK sK/gٹEr :tYiWJ{ǏMx71쳰m!å,Dz]}m_Bٸn'^8'it-28|msuV9ʠ[閥_̫~!RD,{ vZ_U¿_lxҸ]ݠ@Qh~J;)EzUU',OY?ƽGi[3״t>V;>h'Ke1~eq~fmuuk, \YZ^M9^k T|EnWm]`,k|Tx@oz>cE~vPr淋roccSL:D☲|զ7U?g_ *>"7G+Vڣ\0\SNS>5ܿ} rpO-zY-|g#UGxǾ)6N[^W{_PBQh~J{N믪.rւtU{kl%홸mzXVcwM5^SkH>D2etu߫~AS/({(r[=kEm۹+(.^U"P~GWl3Golp<.ՍWTP9S {h(>/:C,Qޣ۝˗/2ME'V6\Wq2w|G Gߡu_;+pv_i}Ujί(.pr ̇(?xEu{Ͻ9(2(?@G!R1?\~pFP{?E*[F1@:Va78[N?%\iZu~qFpm'*N~ҋ_Z{]٩K̿ϯ_۸'{ⱡ>?jx[G N;E~}XM6_Ut C*<k1a}1׍{j۽6N ?0bj;S޹"‡|];wo8.swvPpi:+ߥN>k0<,E=[W,+sW.#72}B+{ԛ'??Gϛy.'?6#elxY Nm݃{J(WCxa"EG}e"m[ZEu|:yse£^ލTo^{۹P]?,WS?)=mvU)E8xm+#+Ԯ{Yb=ɻ;߃!|]u:l?~}Mu1~d]SO_WٗO'zeXDppG:^tԇHYFBYW*;\;68@OȹS3\ #?r΋2JLL^z3ccVUg`8 Dzćǟg1="9 < ѪmKf֙Nc(WikJу(M:$@&ٰjH1Ckߟ;!, MyY|YݮGDam~=sLp&fƄ/*xD٨(KQƢ셊H֡ZѡgkE۹Nު&&\OP$Ԧl&TO=9foFȹ~hx+GӖf6h,T˄5t,]U}bƯ߹"|+,o]/ B젿.8QۯoݾgWcGW/Ë/j>.힁ozнR.z{G抐6{f!R>t[Y +h[kT>:{ ?xհMTB''޵S[/d/my6 HY^/׷EB^n[V?=$8~v]~{/Rj5a}]r.cn[ $%_톍կSnlG:!xVUWnv4loجx\B&yji,Z0xe,^8m؊붶6׺=c٪u{#|BpۅYs읮>?^pm6s&VY&λ{,VK_ ie;_/ z#|s;g;hA ?8}Lp?{i?B=/U 8voE>y؛U4R~r5{H_>D2d2\z/f~ke8`7ĭkݺk"*պ+&A@!eADd+L&3 Q}L29d朗Ilv݆hiIknvHҶ/OX]xS_{n99K,7v~mq[z.ZU%Zۚ4nާgJ[L%pIRW.;iC9e2]'.?c|Wk;wѼ` 楎 Hс\Υd:Ls^cSi7 ie{)+]k׭]>{' LtQwN[{ԇ wԏ]:=uOcG3+BeS>YI baל Ž세l *uů%gh;ީ5Z!e(ÛwFYNC߀v:򴻧!$j۝S Mjz;08ehl`ke)g/7L[j,|- wNC~]HUi)m L7z*m{λ6UIRDݡG͊MY]|it.)Ӯg'dN枔}a&'LY4V_7o:LњhR4,:> #G/{Bl$\^xNNp 2(N#XpV8^|q OҠs(k +.E}H]Ȏ!dFc:ΈvgF㿞(OfNaΨ/\ٳ#;ѶHg7I=OWBl #Z%`%STNBVB^CRC)x9æct؃3y(z#~jsM}f i ;mfCƨ eܛq@S3i.$1)۱ v]o&$4cd}fl$ئnf:bgj*Pi9ǒ2(MqZg٧k7HiݲXe|uʒg۔vcSZKA둀YW'=݀?Xahi*İb*NZ;㙲1fcoK1>z<xlZdv wFFBz$pGz2"='=|~ewIҖ]R?$l W2ex[¬%qe/YʏbϧGyQy4ѨBV$z )KEYɇ>|G[g؅6f5n7[f)`OD$CW^io91϶'cPTyscU!w<2h$튾oll\M-;G%iYMeS҄Xl:!I'k&-|#(/-+G]9e6,3נ!qyͭM59Yoeўcqаh^XlVZ=Aa9}\oWuj)PoTdrAlan)$Ȇ[#j{r1:C\ѫ9ѷp_5Wiĝx_NEݓI;9Nex@O%r54f$mv;`χoS90e%B PC^e`@2gw9Ѱh^XjW,Og{J\ڸ}Wеeы$wS6UspUAߴI]6*v /2[Wi_P/9yJ9"{ڕNpDR0oypta6~w%ӻ+W8Ƹs1Jrx(6/ڙK@hPHEא.EmO+' d͘!Xeɺ dž;*gwaѼF6{ oYy]sk|%pʕraVK wrV2,!^.n-|fBuz )âl$7hvB,c#MTƔ5Elk{VuvY:4Uh4qaѼF^H_Qi?+(;UNa'Wؐ~p$,ΤDXIT1kI g$>X(^K ~%Z/7i65 8 #_o>î ] D(dK5µQ 2'T ~IH->[>U]Cb55چj̔!Db޻}nfq}umU bӶ .ϦγAd&1Ke~+Ϩ>=Ȫ6y ) ?'jJIѰ~1~wԖ\=}+&w%BM+R ntZVѨFFFz{{[ZZ,AAf7nh4J<6'O`)WQR  V_YFHY Xsr͕)P/^A:r֭l( D( $L&,o߾%e! b5ݻ0xPgf eC[[[IY XeɁ@!,Eex<._Y^|IBA(KBBBnnnMM ,(^'e! b5%)))//V( lN,>|Eez  Qz<6'|FYvlꉉvR  VGY ` f?YTyp8bnnnjjjhh  QFSRR<6'O`)x|?34===<AA*PTT g؈KY>R{ξY&'';;;+**_(;״s-ƶ&&&xFP( B_ vǀi7E,8 DQqEelbnn<:of( BP?W.0 'KHYkl؄lyLR/X8qP( BBLW`)~1} 72IENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_exclude.png000066400000000000000000002151471477034762000252560ustar00rootroot00000000000000PNG  IHDRlsBITOIDATx콇Wɷ;[=kp9w99pq9g86&0&sP;ow$D セjuWn/5QW*P{r{=RN~MeC#vavkT|Ŭ)T00000000Gja֗Io m*S=:S ````````0-uX_+Z E00000000"A8-.֬o RBN"10000000@uXQ2Wt:JD,B10```Z/_ s\f5EƷlHQW]ciou{LxB?|E..`_wFE+-S Zh0kC4,ߋ}epp0H655VWWWUUUVVVPQ1,\L|܃6Nb_W|b+8.jjjx/gw;AARtwJJJ@b]:hk1k,σh_h4f_ioo~.WAAN';222 =Nb_WzVU*vuuUWWn  ]$4oOLLLjj*XK}}=x8 X/~$$ 鏄?{I޺qpCAfl\t>...##xQ\_,``@R|t+AAdLJJ*))'3?,(JT񺻻=A\AAYd%<<p:;;kkklsuo[6]ve/,oݲi$fAA(˗/ccc@CF,g,FPf6QSSm]v{OhE/{ۯ]mI2.]yهB?^t֬4#  PϟGEE䀁bz3,r\,C*G`=ij Z=G{ݗ{+ִ\ [7o\=aƍ޸~! skaa/۶]7Na͒_-uml AA~Z@9>}ElbE`axn^~\qZruc2߼qy<>$چkdaz%~bΓfJ8-Y*V;^ ݚ|sUS,  ޽,#BS!Keikkglr2 ۥ'=\rεm^xKW[^pjEIB8s-| ( x؈/U_!BVضg VdomX Znye ˰i26Czs#_xʝz9|h9$|DzFULЦe~]lwN1XqW52=鱷vm]icNL?پb̈́+W/bwY|MbYMM/);j A+o}evU&+A5֮ߺFBqeS-^ SB+_$N,BVr`=cYܵoF /:n[zܷf9㹳Ϟ9vQ^0c^iΝ=f8 +oTRQ%l[cmc敫6y?ʣΛVژ6ǪeBYI0MmYb&EԚҬFjk}Km7J"_喖t}:BA PN2Ueٶ cY\?̈WFn[ϋ[ar\t9sOA1/_sqsIXrߓ>㭑~[|-囏gϦ>޾bѯyLysŒe-^D~6 Wowz[OyNl^h#LʲdrS-gE~]c˪o AA~*@9߿?me顕-6fI#7[?^7!Mۮ69p聣G (*sIۖ+{ 4(q"XcsOnXtN;olbo;n֭ KeYlzͧRV,^|K֮l,lWiL|tgKY/A堕%--VQb0$X,Vsssiikm]?+| eݒ;`/:27Ad_!9_Ç@P35w9$lݲi֭]nfWԧ3̄}$EN.PnD."[nd󦑌m޵=pN:2X[wnk"ULO&6CKL+3Wm^v˱O ڞk q+,,+,|-#+~aX\]^Biz! O(njeU`=Yvlu'8 parLU+m|}3X[W>Ll0FOCNګ>9lXq&MW_fWE&YUnvӞ]JCl V.]bEYVXe,6nY5 TJ_*n,_fJi%}演W-JAcFʲaJ Y?87#|[W0#ˮ^i藞uŒjFe믋-]mrz mW\bڼx+m~ӲeKnz W߰unbeHl&*Ɔ׭_m:z AHAI9yUk7 [Aok  ? 3RVn$Ĭ]bc%~'߸Mk,$͒8:=]ᯃaX?I˖n:A>Te|6 cVA@9f,֮ذ~դ\vRem- kg-뗭?TXO?7Ә(ؼ׍Vͻ  (nje  (njej[AAYcFʲz X  Ȭ1#eYrX  Ȭ1#eYb)X  Ȭ1#egF  2r  ʂ  ʂ  * *  ,  ,   ʂ  ʂ  *  *  ,,PWP[ bIKc=GR}s$ܾvsau5CfXCm-M̮?:IFOu_|͗qk _R: :݀&odh{ȬtT{Y]mO˿t'X5+aflXI"ˁsP2!~РryȠm$zӏ]65^ x\XV!syPYR_[5Վ' c(˄b@i60jthɿz==Rte3`~:zX=FN6V!syPYRYV<^-ׯ_,```,J3}D/TXIX_> dn )_ ܜ~oP6,\jn@W~0;gohs߳%f%yPYR^Rhj c18@OK0\XI]?Q@]7KIӲZS >WRRq%%RT?a.<mj 5,蠾PZASBu {ȏ߱,He? Rh?eϾ sggMk̝ka8?a`Lk~< k#Iwgz`0^qɗ:+jTO?a .ESnb@n(hL7#UfN?ҼIZJ*e$,^M I*?~W&=Gfg*Wzϕ # KJ.WHy_g%y28sa餋ۙT%zۓ\ ˰$8[ cb~IOH0\XI:Z?7D^N H kt_z6,`<͛U+%]`-98"&]>G7hﳻ:a@.ƥ7M3*D Xuֳ7叛Xnʢ)?C 4u'1=u_YD% Sػ>2U7 1UuM|t-*{)KQ~?,Nu7]sY!8B. j@OȐcJz斖vzHzЍT ߨ,/kda:?G?+5+ 0\XI:[ ia{`SG,9s}(/kll((/))fɡc",[5vojA9(K[=ӊ>&)uZqM\蛜^$ŀbOׅP&5’ܭc@*7! ޏ5֓HeI)ea'!FMbBʎ9br*:E ;߮,jAq0$?ͭ@{qmlZ>!ADv'}07k穟e9H~V5LRg=mzo !Q!jzÔ|Vtttuvv|&$2 k#IG[39!P&E"Ӿ7oHAoo蔔#T L,'W VCT޴LUuSZGnaZ-"$y[*,K˭xp`9gC֎IY'К. {H܇<>E >]}T(̡|3Gʲ/rAHciSPw N`Qό@nq- 2%zVtc:v/I6hNwϓ}%_w{x9Tc|i&5y(0=Rw;hKG䓜^"!O ʉ'ogG}a |5ڠ)a6 ZK`ӧO}ߞ_+WD;2Ӈw V% =% ZPaLdA”WcYfK߂Cג"jjWajUjh5$45r.4p.u(p`sqd${:^fy]Wr˝`F6 JkC,)!rӐ-xNvo2"RTT8E $}@- PWSU;J>!*N-OzF҆1,io*akij}̮bIUZ59|i XONJ~s}̭)5̽h ϻ2eW^VFLq T~?uB>qY'9%0i, dz|ȩđdAvF*3ꤢ=q4S$-jߧKIȪ;ScF/8 Hie釵`gb_GG%S<&ԫGƠjzpP(}p HJF:N!8 }jyϪ 4RYJA5MB;t2mף ύD>  V' '$Ӑ eѾrԩ?EMW"VԪ CCjE*7b(˛lG)u!4ЪEᩭ9QҚ$U%MJߐˏ **zSUkd KjSkhOԮ4w|_ ݌%;J]-"[;)el?|?lʢODzkQY{Mb"J=撕WCq;Wt'J1XH^o~ ,K&H-Dcx?jT㭤3Ga;'5%(3HO0ʲ;Qe R=,$9)i@}2R:*5 ގ}:d=D UBA!S;TKji{28p=<9+]hdAR Kn(]`J '{ЄFu9ROk뛚X\ʼi| %BYM_Y\f<d~~6LOyK\Rt:AgǠvY݀#ԗ~ҤPwBW\RJiY@YEtPX%0(yE<@42:̀N^b&YMPgJS^UG8(~ \!3ﹿ:(KJ"u_>8AttuvʴEB*~  0Ppam$ii&$aPQ)iJU)av%H%/^LWLU|H5z=5WeeZQ)רȺhJ)LP_TV4V#7d{Ǖ2}VHlq-w=FEtqo?9* M('v@Av'|:g;o!8m-csz[bCC Jc7x.$͌R.>4<[FP!Ν\YTjqcRXXRHy_+Phhe.r<> 䊿yYUeQjo'ܮ L xˤ`R,JVBA mҒ? 4HNjy~NN޸o|rdQ:SٯRR$ 5ZA&,0r4jAؒ' 4e[dw\v wIGn%Wlbr@M6iyytA $PS"XO}b.O@A>yJ% $(`647¸I^@/()@֢R'%@5w}2DHڌϲ^ĖsTRU%W)UڄаvɘZ饒,KjAeuSZȘǤ|p*\QncsSnp km'\.㞤T>VN^1$YYm7PvCڤw% ?UL ˧+tSlSD\%UĒ SKcBÒmO>mxR|w0ztZYˉ)E%izo)zG>y n?*),?C\)G1o ~J3u߀&ăQAR =]JCc'P)k #;qEu G술} ~ erJJ/; {7TC ST6B T*Ҽ; b<ty{hҫť\, ;j*Ykdp/*(+!*J,@&1iYrZS0 . zM5D+0#5 0( B6L|>uXZRBɓ]^/E|G(+2s.RJ>i tJ iW~ThhdjIC{':mVJY:e]ʏ /llkӻlBN4 j"XJ/Z;š(j!%跈ॕ\v!|_[t#n ԲҒ0zCVy՝ v_}ZP^^v~~~bU K15"mf+8\ґA[gwg[SMM:&JY,tJ=Hed ϯkjȌ"?Z̥~MF;2whlVeS;ޯ/v[Y;+w k}ևZŗ)Z=~sKnb}C@Td\r$"ƸR򳎓7{*%o))J.,\8T9:a!wI%%^8;O2;%i{^] pwyVZ/3*؜RT C Q |R)!vw>{۲HAq'Z5x2(0\X몇l4N?LEߑFaD&@vx\nWM\6\&X)U j-"$wVf}|N 1'MVISFf)$9JCNPIrFgPc(1iVE6 jjz&F=:G]2c1 r⃨`gq |_^/*N8]!GfQs~npy)_I%yy1ӎw~V!bRiߐ-8ˡaocj822Rf1EN~-Vx)#?EzBi*J1~I:K(yk<ߢ3sRbGh#rbhO ?RG4jv#*&}t6v O1_rnlal`HP[E~)O/(ax Qs(?{ZUYZ[jYn^ ~dc2 (7ukt,P_ (/RH[JJ>2=.UX܉2OaAeǸh>j؁dBO"#2%NǏ_r6י?+Z0 FʡADd%qΓrj\x۷ouJ"n5@\62U+CY Zz=cԏxy UP%r{|dź|ݣK'_cTvlA@^__T__GI 1AM"!d@_D( IHefuLJ^ԬV  u?:{=$.򟹇vAeJrbX,2?F=%nZʔ*R(7Ed@zY*7 IAOHR'yR||`|DIAFM62!)iIi* }5[ igY:aQ>{yPYRW]UcwofEا7 OV* 㳖z./;2Xζnx M]Lrz~'*²j5P&vkaC|Oeׅ,ЦIy9Bo`  Xi 3hB??'#+=e?  ljiooiRd3hmAWe045L lhwvK@9f,~4:1.:m %c`RsPSY]^(m~sIV!ỳrHYSAA~@@9f,˖.FDAd嘑FDAd嘑^AAcFʲ~ZlDAAfP)Am@9f,۶nFDAd嘑۰#\voyI~NFJVZ|(AcF`8}'/;]*}yPl(|H08h hoKA uU.tBQY|PʲvcѼ7k5cFQU^AhԪy TaJ委˗/5PZ؍F?QU^S&2rHY,8u@],0*@ELn5 hd2cFrpީ(AS P(IY5,k,Ȝ1#e9t`  ó:VkʤC4(kH|M#, ka7* 2rHY=4EeQ)?>JA՛YK0;uv~5Sl:Oc|;| u6P_'R%<5iFPZYEGO[ TGcFrı(N7T|=Ʃ<Sa]Obftrw'*Aa/vcbOS;>$()eI觓KQ37L)= iO}aNet^t׿̬2A[Y^aHnZ#痆puR8OkW Uyu߰gqۯdX#h^Td嘑?srJ2lBd%1N{SsrIYxLRI˵RWP}׃Y:\] vP~ Ap*HC_mrO'+R4Ȩ,ֻ+`MqŃ8$ہ:+<ŧI0G~sϼ⋎D`TWHn?&HX2wg{& {y['+{_>py`6Mh^Td嘑\>v*2*HZcϸˁ>ef&D޿,(߀E)K.ZI"3*WPB*Kd:]heA)e4ANfrzyDlza~;# Uk/u#G]UEyJYtU} Nh{" u*A||r9`y8@xmPStk<PaDPwc;8R(=Lҍɞ}xwӳ2R]#wYoWD+GTeeF*{ų[$%O$'0S]{!%++%Ս3l͋ʂ93R,HZŔ.[)$>wj=GN\/t󰯧}we~ԘEΩ,f,,n߷%ݟ.qeP8^n7 ࢥ_L %;qydV"RR'__޻ՎzCCw>6Ɣ°+JnHeƓ-j/p:o|^7V[cq=5RM!;Rv<np;WCXb5ǡ~Aބϣ:M~/8[2񋂝aY/l`oQo˽ )ҞOoG {-o JcGn9š-t&C԰O:R:B5|g\v&I#3U`+şt$<*Ix~ҍ FvrUfyumyNZz qs@9f,!7MIY4j9ed!Y_9GbT^ͿM~ (֋"TX~:Q>2t1H{33#}RiIY&*`.PR# KGS{e& 7]0I0D@x2/lo$Wr /P.S5 qցFDtP 'O,gkMΖ[u0zѢH O1}}i++Vah_~NeMYx3#` D;Md%-H!l ucظg S,T(హl@ HN wzPFs ]D cLD*c\r"w(eq$v> "/%еO90;ϗuc.yVz=yd}`J4l6ā؆%IlFi7i޵֎7k$2*, .U_LuJIcvĮpzNuPxR#HnBM+.B|Fg*m'\-)z`Aw'd-ld嘑5eѨp;N [γXɭE@"ysuD wƞ)uD8'tet`pp%o;c%Ү%=4k.E\XIF~jz W+ ˭AHV#;&I75fpJqɲT|rBe,7k7z {N{V/WGe4y=N!\MΏ0KgAHeg%le'O_Ytw2v>ιF~!ӑ v>!Y\-\}݅E5VYtdtj0T|^jz4NYIקs,$,2)~X@Y޴ L{攐Rw֖T4Mo`ڸ5f~PF2Ja2z}X?v R.uvt8)OrL YyYI`)6>E8^8GOR# RĬJ ^q(=S.B04VQ뇓΄tQw(q%u <(^T@5y/} //y2~,IYό{ aQpqs@9f,=(r ­$fV+1SO;c2+ɓLC#Gɷ-|\jH4yA_I;#{8!:bAY3'(-պʇ,W zaYԝxF.$P?z9FFe>}.UT|.R l ds$B "hk?Ɖ>$(?o(ɘ*M}rNQL s;ՂR 3.Kr:U}OJJS0#^|~yUUquOFS+k ?\rŠ7Cn'%TTWfck'P"Z9֨ +*T< ķ 7&ݦpa;3ꧻ 55!\iՃ2:%3Ť<KؑrƑyXEv^[LөG\/eezX̫ 3qj'ϧuǝM胄l-f,SoY=_, &bf^s'nr[ ! qu};A{]1|QZu/.C;.Nˊ r?=U{rr 2nx &@'U^-|.`gg/t.7Z'V$@7xߎqpt=iVE933ͽvُp8mx\OIIYzVkd|3b#3 ˋ omSnzr/;Q7QX[@XG5ɲ=#D7D{6!3;5!gu<%Hٙ |OYyqQk '122>}xy tL}hFgŭ:@yQ;V;٠ĩM|_\Yք* 2rHYB_<%>w"8]:|ێ'&pחxѓˎOz`}O5:{ΡKwyظ7GwZq|17ػzL'Sgv9:6'*$uar%I3Fßp^6 iOS5t9QZC{*{"(AعzVG $ƑƯ_¦3/I*>P~JYNˏT*2`W>AKn"돪^~|(=גZx|N_mƒ㻜o^#oԆFvʉTQ=,BRYTVvi%#!*zF). ޑ2L|LpZ#nCwRϽgǖv[nv][@N+FzVjd|6&^p7 kʙi׈syַ&_p!^T V]/bJ'<@W43<] /NFEs݃3e=]d7#]kFggF6wЭj]Yx_tr'7PY9cF&TE*Xu/$eY0]ktcf=,& Bk.k524/* 2rHYGNEY"ݻXuL^Y PӵO7* R=1{B sYpDP)KLdĔE,@]9ORYJך?ݸ8ċ[ҽ@OLV%,]sYyQY9cFn*"sz P(BRӵc~qs@9f,?DMEY\v/k_Hʲ`vc>n s(ߡ,\vc凙U,k,Ϣ,fg`O)?濲*`vc>n ?h,eAA5eE>w`Q0~11c@e@ʲ&HAA/Z*+.@eAAF!HAeAAF)*  ʂʂ  *  ,,   ʂ  *߭,e ,`c`````̯`vFavdggT8}N*heQ*Ey`-jҠ׫U*N߿ۚ*%* +F*/),+. aMKC]GkYP'Ƽ PdV;RW]!s|  < 71[|AAy,)T $SFXPpU;q,t2 I*?~W&WoAACx@1000keIJ1s`kMeRϟ3H^tr 4u'ayh–N$kne5o/deY8nV?{aqz3Y*/tVSj[N`"|L+.?~( -W.4elʓĘ`+WN[t2iM3YĮW]I1,+B츕P?h!E[#qc; t!MOӻɝ{Ԯ] /1} +z&Au?7iL *9ǯQcN>R ggҲg]!}OQnּ@}cp+W8)GB]syq܄Spzxز F_?ARc]^C'w6ݎ:vʽ~;{_ɗ dv"_64<4)xuߕ|A7cin'|Mm] w]O#a_7;`ޫSO0000~UVʲ? 4!j'#(9x/Z ԒܴBvXǢ-dԶRҡoT0!?#xʪ=nĹW݈5冞p&oˇ,\taEueQ^J3-/ijn(K .ҙJf25 [q% MiOjMo|}~U}]yq[k`$"+k2\VQT^w!_K(oh/)f gf(e}Y8rޤ,CpX@RTnʘrƑp>GjIUYzwH\魷_O()/Fr rAY6tSWE7=$UVF^AZ 懞o8SGf~@5|2k.yg3{~V^WWSZ"z!,|*'<ʲ/j{sczX+0x֤[Xִd'=kYǗ\6kR! ]$p=>¢_Giz Ӗ{RBQBSrFh`Ͱe 23AuWCmzLʲTR^Aa.E卪.nbOҍJ,~et?Jj+ H onNYjMӓzU9|yFt`bo,EYts⎁UYOϠOQr!gх;sG5 lNɭÖk-e4j^Y*/llJnXk'['-oӦ󆨚Nu3Zˇ},r_gӣ?%u`~F$6u4?%Zz9H~4_i#[qLEA3]}ݫ-w=A7yq.DGUV||*FFNY)y#j'@`[TWz~zymBC?)-]k^\P{~pL+-L>ʁU[;+^}fj|o'X5&ud^nEM=|q*NY]o? )p=>&Fڲ v=q, }-SEo1%%En5Q<_~DԪmmܰłRՒHಟ[9H>=9lW(G8%Ⱥx)QPUMTkAd"G,nމRt;`:۔m6EKL,]jtIY,=#}0 51[7ӏ1]W n~c>HO^RIc_$WWݶ,L>h2"u?{"SD"a⅍ WBPj'ݪ}%gd<{r'&SVH!X(5λhyW۩9E,*jɁN-'ߏK>^vN0G1JۇG6:UU)86^JVAa >Wq#=-o~uHG:BeoΖW  7t1䔄7U+7AQ%<.UM`:_҈N WјGWqs[:I._e-cA;)wFy* ߌ~V1²~! ܼ~si{gJޮhmmnjmi41a\) $N>(O"X{]Wْyl%ICg.}>Kt_lB".qpٕDSR9-YNW?\HwqMaJ'QR_T+ !Vz.{$yJZJbo\Ycdy'*.)sΦۇ7-K~8{nqKO ~ʫ[]ENY ;js_ÁfT-` -ޠQ9eQ­aG]}>/|kDG\[l.qȕw7^@ U'V8Q}Y ;jqs8Vqmw(kaYA )y===,:cTX-MrJf[QWǗt> P)|ڎv ?k$W5 хmm(pEI?mMMz^v1̸R`ZuR |ZUO4AB~O a!XNFy\Vѡq,&eHY (K__^ݑ!M$ol5vv?eioCA;{YCwmScc=,w`)  PTW qeQpP/^7" iE,/ {Y*ʞ# ie`/ ]di4e!*=e^.-XqJ:Add"*VSxق ; ҎWio\`#5K4ETFC/)ULHVl?J%Lu>/һS%uELq\Xiι0G2Ē1  1QY5$9{h]&ZY-ao]îԠ. rS~5p^s:PX瞲#e.vUΩSvW]WvoXH^%vŷZO2{rrq՘CA,j}DDRo}[b%WbaȅfG4ET&ڽk#&˔)NYn>纒p^Ur +hPZpSK7ާѕsL@bXKDA ,5b}*iwM -͡ jm5#4ETFC/))_ʩu+sN,Yλ9sS+Lw s|Iolk 22EZS5]M"339~׮xjPiꞱIڮ7_5I Fv\qّGܹvb#eQ(|m9'R95JEoS3G*F\( LLDeWʲ';20ÿ 5K4E=ɏ)T" n&TWOqJCSA]xĈbOrvWmLbג~9  cd"*HyUN[+Re! DDT |Z PzjkZWSA]&@Y> e듇+譌MdaA~ZԏeAi魻oMޘ;*jӪ;=tPO_YnN]Xa[hĊxhXpjPi \=Hwf>n0/rbJ^6]cK^[ Jx>I$"ʔ-F(-0^%b3U_VCr:|-=U(˧,E69Ysrf|ͷ~ۤA{A] yTUCˋ~l,e0gfN9}V֌9jPi L2T>Yko)KJˊAvIeeуhQxZRI]q+ޝƶ `")_".l2$NN>yz8`75K4ETFcɞpf}#1:0ߑեqzt'11 ,$_> Qigg6o_n6eJY'ʭ<4I _zLuX#kuiM6J84*{y[Xp^Nfe ])~bĜeeE!ze^^w쌤+FRW]E'\ZӌgoE=q&Ɩ `b)˄S1dQӭ̰uwr1Ph4g) Ew߻.rfnZ3"[O?12uxEREa]FIzFWW#W;G^aZ{h2 YKАwsc 5K45|p4E LY'i =4~gs)Ԡ. ~`[DKl&LC0]9{1+`,&LCehWY&ښ{jPPBYa,4z+#v?OQ^:@])*@Y>Tpn;sHq_~¿5Gp?f-='玞;LBr%MoE~?|l"9\dgrxOעz/[oQF ֯[LSEvf\}*Qr{wen7Ŀ-z1.QH,$YX,(_`WfmZ>ϼB`Qigz35ԥAnɾd; ߒ+ , ij]pCki[f;ӜVG1s-?rbK@#kwf_pVp](VCW@Ye9uvk>cln+ⱆag©A])*2*~eme<) ~ZÂ9v`_,`a - \+{WB[h#ozR~hhBxZ(߯,E69Ysrf|ͷ~ۤA{A] yT甅|$+&̶2,iݗ\U<)c=Գ+lFoPZ۬P_c6Jεi+5-rWO(00l^M!zfYge͘Cuiʄ!cT7 t3Wj{V>yri1:Y wa6{GT$ G[h$r)cAQEUFc+ ^6ƇXbʘ昺se .l2$NN>yz8`75K4ETFcJU2YgL=EqGf R5ʢUX1=~z\geِz5g.UpPu+{0`A—~9S])A]sJG sw;-3ѕ啦8̑;# EP?,.G9Q!|fu]3'[,ZpeyJg*l(rnH(()) qelet|(e]sZ{?Q00v՝6ԠNN2*MYl9ey,͜*Vm[D-R߳%VW]E-t/X!NhG](-NZGjgwSӵq7鯠fy .eE$I/S~nLuiF@Y9eR%zhRA]&@Y>"e( Le驭i9Wj^͟Nuie(ObNc2`ԥAl(C* Hz '3G'ۏQCqd{[ gK*Z^s^bq^^W>|'os]ؚ@YƭHٙSﵨE[/mQT44x4_(gnjj=m4=5U{W8ocIg5qͽ@Y>Uej, vu=2RjP%N[GS#/+O;p>]%tg9oR+ D~-s,-ra|+KyWbGj'y"jPizGB1E]_!ْozwܺ;=J ]&29{MZl>ue9 ,^,I%<ؕY3XTY?LMuir/YNc*CE;6z8e`memz{3ݴ(iO<~$uBү<_`ÕVq/ҮطÂ1ەBcr88Qu',-MCZYb.[Ԥ{nf\baRjoK[-jPi nSTE%-/V%a aRFU$515+0/D.aƞ䔔f$>D,AQBQ?:S'X7N\HY;eQ(K]xVSg3ohX"k8x&ԥA*?,c)#-_؛ǼU~0 Տweߟ6`3D_̜6+ss(Ԡ. P00+KTIRƜR**E,+ff0AO[)Hƍ|fyE .l2$NN>yz8`75K4ETFXYўo7m1uOԢmejլiBYLeɢB]1 N߷{pW&$|93ՕbԥA:7(9(+E?[vO)|koe[}%ee9+OyIVQIIv`eTsSM%'w]sZ{?Q00v՝6ԠNN2*SJY.NtE;,;!kM/~ԾҔDx/_ ͬJiyC&Ͼ8EP/c?t$a{hȿ~N};1ԥAWFV䯺0Qo[n/KMryx?MZwBM\ 5Kur?_ԪPvt(Z[k~0,}9wusަoթCY(:e^OrN\7x'\( ^;sZTe.ԝ~hijlj_/qyo(Seimn"eijlFG]C}KIUe!c!eQ47[\<4Wښ{jPF_5]vp')Z~A|fzxV>yؾ29ȃ]SPi \Y*ʞߍFܜ)|!у{uRxVґNmg)+B}OΖTǭWKZOЃF,%UYq/_?yܽ;1ZI}]xVɡ";{{}z륽2jP~b*35qͽ#L}?LWv׷h;+=,jǣ|r",WJ5ZIuf+KF8@WdM up葑4P4(pJeTG.3,=kM.ve9uvk>cln+ⱆag©A])*2*iEۇt4'ZZo{Ў,Cչf~goMONl~XɋWz$x}[ǗʲBjogK eZ=u7VN)Wg*ԵVU(ǭ,E69Ysrf|ͷ~ۤA{A] yT<*v57wBZ^􏸗sYT){當vȆ<32cv;hY+:eaƌ';^޶O%Wp'|" ?mDSg9mVYY3PA])*2a`XCJˊAvIeeуʢ|H-h93YQ4gD7< "c+kU,%g'6IjӄO^ M MQQW25G2Y{H#*܅{m~`jmg 7VseH[ʢ e4n%4xL2Hr/g+Y5K4unQr_Zp#v{bv4#Oi?r gs%8(˫-鷗YYĸDqw+G\Ѳs\8̑;# EP緔l_Sq/eEwiGM2( VwfP;9ɘ w)K|?,[.6X!NZ5#bnۺn"~5]ˢۮˢ)p' [DW˳r\{DՖ߼|E$I/S~nLui~|$U,i =4~gs)Ԡ. ~W( (Tq( Pє^y5:ԥAl"P>yؾ29ȃ]SPi P,#U=+RWo?G őm+-@Y>HٙSﵨE[/mQT44xدMĭ(ߡ,ݒ\Y_͒7ݮáGF@ ҠIs+Qk#ɇo?,/pu^^`)vvq]))uiWz.t.aGsV8(1tɚ㾞[5iYPPY,,Ky/+6-g^!P=~ؙL 7d_̝GPk'm`v妀N{,N]|yI1̸¤Ԓz헶[Ԡ. P5UQV߹-PZYnN]Xa[hĊxhXpjPi GZuQ!9 ۞*pXrZdjc˞5'gA7y|[MԥAnʐajM#BmWssJ>}IY0fkfe;;(~(Pa`ټl&:Ci2ʚ1B MQ Cs(;5T.a8@Y%g'6IjӄO^ M MQQVvO{r\s\(˟Ӏ=0 Ykd Ԡ. ԹFP,޾kNkO8jqF_N3ÆԽoIT@eV(ˇ|,"HАwsc 5K4_,^YTIn볹jPPHYee,DYzjkZWSA]&@Y> e듇+譌nF5[n1MٙIC f ψ{?UC/%*+kjS30P[Y%5¹% $n]CԥAlV*q,:|5gQ+KyWbGj'y"jPizGB߷cV֭qQb5q}=kƒ@Y>ReI,YQڴ|yBagj25Kܔ}2w*U=g c`ZG6,=ҘlQ+AOyF4b%_0gC(#.Y%p'lUȕԸ?/:];[c̽wǚ*E3ju|u7jԯjEnA8#VSg3ohX"k8x&ԥA*1dOU o|8!x\4ms_8j+ZgW,; kޘW{`_,`jEjGRά}zw6&}M-O[[oќki@Y>Zemd-21eϚ3 o& C 7e01פzƖ^t1;G+xŐ#\K]ey'^ΘWع,{"=} 7̣\:S}Mآ 5;&ഩDO@Y>^eߟ6`3D_̜6+ss(Ԡ. P00d5--SYGTpe6x2B;LY:|HY% eI)n/V-c<[~6yPONYŒ Sf}5Si'Ouiʨx5Ixko~[YMkؒHU-V7Vsݼ,ZejٓM߷Y<:fϖYrnj-ۭ^q;ђeӀ=0 Ykd Ԡ. ԹFF\}Zp#v{b\v^,;G8bh_sȑ1Wff%cԶoϱc^xmwά^Y\ w 3RE3' ox+"/_iI;#*^jLǹJieEwiGM2( VwfP;9ɘ l4e ϳ甅xYԖBT㦾+Әzf5Wi{+|pv3w23jY]E-tnpCrYZuiL#wΊ~u!6?4_R|ޝ|3|zE$I/S~nLuiF󕿅we ZwBM\ 5K@YP( eP( e^y5:ԥAl"P>yؾ29ȃ]SPi P,#U=+RWo?G őm+-}ES\\E?rY+Ppy=^\>nF5[n1MٙICcEwdC;y{YMqu-(xUnIp,f@nW##eiuiP$۹ʨx,H7gK߾e,o/;woj'6fPq, \WW:Xlj\ujJA] CүLb?Ȉr#6ɢ;O//Ӡ] y:mUY@Yƥܜ:5|C6ЈXѰ3Ԡ. Pf,-y6sWuJ<ԝVl޼s6y9;ۯRcXQˢ^fK+ǭJ^;3[آ@YƟ6gəmkM7Vmui2eZS(™VE,^u$\,9?Z1cC;Gz%]ӈz{Y4Nhn-gP,yL4u뙙feN5cԥA*1?RaR'e,#*Pb0eygYeB(KXrvalf ;M8yZUԠ. Ph, 7=IE,;fPSZ#dV.}ѫ[z_gG90(DӀ=0 Ykd Ԡ. ԹFF^uז2-C;Ub/)ig|m[tTjWrduէY7 (;c|~IeR3{- Le]sZ{?Q00v՝6ԠNN2*X0s!+j/7KZf+wf S1Vwkn'^RQd_\i$otIeP XDґ!2:9;jPij4_!ᨹYL|meaYe)*]Cw}6B .kȝ+H,NY/+~vfu]ߤ,#. @Ye^y5:ԥAl"P>yؾ29ȃ]SPi P,#U=+RWo?G őm+-}ES\\E_tm_(*&< .3o9kQǭ^(u-";3iho}^%bPI"ܨeB*KF8@WdM up葑4P4(pJeT2%vˋMMf%&kܢuiʨxTcQ<6j_i7f.g=MHhcV12F3DcצCRfw@wU5Nlr^]eprsb| B#Vc GτS4HST@eT<į7死۬AozQ_MO[Ϳ f.JzF$l>-3k+qXe)m#kM!/{֜}m6ijP)C^5b,q^+k 5K4ET& q |#Ősl.߱Ĕ11u=0Lx^qM/j.֌VUw~%6Nʢ],9;0eIW3&<-}*qnjPi G4d=S3*2~0hi2ÐTٕg5+;i_L?d嬇_TW5jPidC#޺kKٖ m9n$d22AwƷ7eaC>#W3bn 0<SYYY}ל֞q$/0nug 5{߼F6%?mmnVL%>y:cC7R D൲叡,ҚqXDґ!2:9;jPij4_!YL|x4EGMnnsiْ+RڶǾ|y%0f&>,/yGYyY4eWlѣq٢qEYqAnzZrEs+>'3=)g(?I?5!^y5:ԥAl"G,cd+K_֢?.Kz"Gu'0e(Ppy=^\>nF5[n1MٙICcE]ԩ[ǕwmݍK{Me(KF8@WdM up葑4P4(pJeT]φӨ}՝ߖ9-yO~k%b3Uw״;ܣMZl&e܍UT#;;EBL:>E|6/ۀ}=3sڬ鳲f̡P4HST@e`3YjbFNvF o3#]Ӳ3sk5;R~a LleTU=Ky8!avfzJYA'ʂ  Ȅ AA( AA(  P(  P(  PAA,PAA,wWw;)}9Lly6n<_ե/z06n~s! eTE\N>cT*DcP;ŸSiZSw nٺs2p`5l(uDzIzLt/Ã<'aqMK!U -jA3pybpMՕ8/(ʂNJ#ROr F#,:Oj0AYԫoQC@@@@S5eQϔE]Zv:ڒ0nsSĄ0#=ʑd@B]oL$ĻΚM5hLkZ,Փbbu,^}CwZr {>r:Ƀ`mE._hdش77d(@QMu$HeV=T/c:rmɹZ`itʡAʂo4_&kž ȡP T=Գ ,Z'MJ4{Q^Ar ;kjN"3rh0ܴўAy^sB>rm (RJiDo(-אÊ'Qq[!)i>BfWE8Lw#@ A6AlhRX_o\WL<'Xb0˂ , CYK/!OƕV0sd/OWdCYwG=/6*V5{,ey9AQV;e6V?Jc$F(d@@g{U\2v  2Ծ[P=׊^]AxfQeA@@@@@A,z=yA<; eQ5T-R@r- k5e) ;J"W8AJIմ$V.QʱdICӁ!-ܕ3j̈́$2r@.Z\Ř7,R4 eB1)ꒄّvgQOb܌hª7n=iACPM/trb?ʂ-FS֢$c>~+mn_ʢk.{l4*lf @m7 )/1jSEmċaNR~b=!-ee0C_Ü"*V1ԗ}u9p(6@8+2.]Hp.cZho~7zw[(ǟ _f-/egEQ <= "E̋JnDžP̏jj$fmWeL'm,ZTcjO]%:,:bOSVԉ/p%9bS 0W7S&ֈw"vԳ:ٖ@5"#8K4/.)h]3C/DU.h\N: i(++dunL EÐ dtjc hJ+=;Q0k'l라Pt+V|Q:sV|*Jd+rm+#yk^Wp|5quC{MPudtlD, f?qܰEu3pH6[G8gdre.xhG925gQeh?ߎO{5s`!d̽)Nʅ*uN=eqP\;XmBpq[2]Rw,&9ʢ~NO\wj(v]MY̯|D6{^<[)v=uohw΁˼EC\':w, ,̌l*:"|r5;"3QZ|>Wj[gjcfܵ▮2҇|byn,WFӪK v_q*hS}+)!ǔGzsWb}( .΍M/jOkOIz>@)#SÕUx*c%QQEژD`m~s/P^C!.[QDp-aIpKkt/E Q7yZCm)N &w9Ye}ƌzuVgp1[ĥ''~^c<-Iud43~h߈_':|],fjR=~*١,[7r+\;_\ӻztbR5  aW/xZ4a&wP'^{ f*#̛ޣ,# Ѱ(ci|YÜ~M ?a/v id qwodn몖lׁW_*uesĕO‰:юp;ݙɠ%4aׂ(t4U舔de,4\:Hm|@TZ%CW6ZH 38>-oCGY@hrR84RûN>(,LJa8*gɋ&.|o0וU"ұ)a1"S:׵v ll٦P:IiʛqSu8"mgYAYQD놪[!%IC3S};>W7 >T˼D_F9'#cjG\4*>Dt[r&lbaN|*f=+aUKw뛫|#RRHC>H?$x÷ZT~U{/:(ƌELac #&v}"usO}|. )5 j|w4lkSQr띈Y G g,ڵxΗϪv-Fy~83Yjm]W5.7r}fSJ߮G=io+[k7oNME~œe ?3bKH:jx( iKA9Bk`3<㱫#i zR/>W+<>˫`R ?ary] O [$ ܘޗCI|}Ij2C-dYkK%b:.^~ OQ6k0dYXa,l*/z܋6h5 O!"3skJm\>rx^39?0k~[:'uP=_iй 厽y~?Er#; 26en6FhL[v[q峗ߎ8"+Ȧ]B(PT*#HYؼ nq>Y%,֤xTwG{gDIYY"%z/WPkww Ӈ!+cݴח#۴;na74tpa,|no:–jb >KX fCd̉GM\PI9Y(umDZz]ʢ&O[x|~o\~<%5-A}y_eEOd<J3}ouZZtBX=}s-4gAq1W汁d SK(⊵:ǯqsr[o*)Ru#}lޒ .5,k]@Y.1Z!YȀEj~QOv^o.xXtc+I8Dw)';ib~ zT 7x^-vIo҂r7< YdPŌz?1 I;B/$4`Cvu/*j(lO&R) Չt4M3N?h Mr~EYFvw`:POv8Y=#`Q&7īay!v3Hi4p)Q»Hj3RWWOq}OgJ n50dVp++j0 uRE-z~?UZ /|sVVa0fV4_ڙAC&n8DzS9 hpuܢ>bkM-V^_Cm>ƸǣTO˼V~?bxr|7TFC&9ud鴲-hsDU.BD_~^C+vA/]YDz,ƴuvfjHnF5Uf>54_bu]IYKDn|nslM.tfEYL+/+j[vlZCߜy 4uZj<3:ԗh^>xdؠ,_< P‡5klW3,|mS)NҕjL q(_Sh6c\uM %Ūy'֋fu8͗[Ųh IfnkVbqq3$gm?ݼW6q*mwO<7$:Kb`lL=WO .nqP|k"Q eWOl"ŗSOE'ӁSvY 0|%*Xvyz 7zp#&lʴ–$ qtBÎd}&ž֗ŕT[5 GfEY0z; ,L¤I2{b[UiH7k!p[eQ6neEj!8d9IЈ=4eaPa!VyѺ,):hd\?M m+.UmRЛހX6j z"☲9#,U'eV%˃ Orj^EYb+cm~Y $\ۈ|>Gtj@C豏ƦE=P0q|~n΀MZ1pǗ6׳y_.>Qc$wznWwG |WrDY,(ˬ}b.>tVѮ4]x]zi5{GAYlG\"h|u@X~bI.TAYK){7+!W ϯLNO+i) #%9g5.aS.5W}dطya3 bѕ&N`aC,)%׷]L 8i9(޵zZY n7pzحb zAYPۭ>lU"U5$WKY. ; ?D])N-PR3Z vɞUzȨtos2f Ulqg?">1 uI}X\CƲ蜤,-?})H }Jv _L נ, I+QyBA-Նљ.`]MqTe!LK"FXlDžev-.LE 5%_Ɓ:i_ﯶ^'"_OK kZξwH,_fx5̌]1.-bYi Մea0'e>r9Rڧ,NVOg)˞S97c{[QIYһe־zӴ86; SML`:0dm'ζz PO 7s%SYb:IYŮ۷2~s@WtE^kWZj6~bYMQe,X3zۅx쯬YWCpXc+&+|a9^8'z%>㶔f:/~lB9 +`W%{3K&UG,JC"9 "J~ qZ㼒 ʢhJ[ݭm|e~n{C {EcԦKyDP\YKO@_W+sT*s_\1V nlڥ,:Z5o@;+u5}jƤ>ąi]0Mfjx4hl1Y2e;Eļ]N(oJ>{y51ƨ@C_Aʬs|oRC*jൖftEls*qxU%ogg.Bͭb |lb`lLʩk` FEanmN0$Z8f31Kt4`ao$ uy2~km?J{P^yVMN:ީe,+wSW'y@YTsۿr$e؎ǹ 撬P"ΝG>02 =V9L}8|y!Ty5vC3Qf#bA@ dpX/e*A|sy]^(- AN6&D5 +WȨ5Nl{~ aUzC) d[$Ǎ h ~a:T0N9%?,=$bJENrZV"R+S%7 ^a5 jwp'!ēFOY ϯFQQb1ZJƅyWih͙gԃzD])fTo׊#)qPK6iZd05W`\P#j,L9CN I̯! *kOCCov@} *z$=L bk0Vᷢ0/}lS~vZ:%,>id.yLѰq@YW})aB R[fs FוSj!8i]%7u{~[?plm{*ەH'k(N MzGlqR0Lo/o(tL/޴z')qJ 5iSѫ_MfEP= !E*]rr<â6WYCm>k"» lS*f,N21^?Az}bb]|$gZ~PCx4~Hvd\XN~qa:IWJ1/!uuď $ӓҼyD h5Kh3/'$C~UlK_V"?̉U25ٸW6;X=;u:MѺG,GYզTQ(d?U\QjW/I ua. J_(eqœ+,pdl|{#x5jg+bӿnhG_2EHѯ0]ϛ-}9]\0'VVZEYOxηQQ7eZ!^rI]*.sqa:L{>kNLY>g}GqB2Wr4@Wׁ*D*JpEw\'@ykYQ_eA@@@@@@@R*nH=NG<Ͷpf.1 "m,Z5~8w.>lunz>s-M~My5w]*vհmǗoX#qQ}jސXCˆYy=V2Xu˒ÁylwmZ)9jp]1T.ꭟeɑs-Ve$K4Tl_26o׶&. OșWxs٥ y_CژvԳ:Lޣ/.d֌cv"QLX#b0ZcQ.=n)թ7'xM츊f7,@źȈowjb܀aXźM)NJAҪ's\6郥tɦ4:A;){Z,/yxem͉iwy eGieqhQ"٥,Lr|nӲtTc,267EPP#amrDB}7OYv]W< EY6fQ5uCs?q#)vd)QZ"DY\9kX]=ՔJܝ^SU|T\^5~lv_"U6f]+nz,V5v.k8uHk[ev(䃏RUwfGd|46 Pt __f][$(fLj DUkN^XQZ"DY jM-BSތ˗cHiۖje*dU V2\Qt'+%n?d+p3y+`r1MLpjIEϰ/nKI}яRkfa2jNOCb\L-a ö o\$}wrB^7;֎~ޠ޽*#[f32uAljuRrCGj.1n##(a]\+ C ͭ1*n~~ٌYCǥ''~^c|$O}~!XRc@T֫Eb G=c/>/eW>˿y߶d+-L [[k>OM&6R6N #W!ߧl3:_gEQ&S.81XNpdVYߖ{ ˉ y+ũ¨5p}/\/,}vlT>k˚O%¯gs}#5,JRȸil–Qi%#r4UjXRFcYck>rObãzrqX}AZ0#czrqYi=cS"=M|z5Ӟ}Xk|f,#`/ eXݒګeXisS{Ťm`h׍fNY4  vk̀,0r¦ib'( ˂W}LQuŎLg̭ү>LK V]4=?`]b-6} mxPnSMs%a.ɈWh-,ʋM8.` miɷ荥kc##X4\څBZv[q峗ߎ;mqC33skJ^@*`ZTAu{ooKdw^v.`(+/54˭w" f5zmV Q;;` UQ6BD G7җuv-F:x jxeS֢5?42I x%>e&1de f)aoV/i~}֙LUƀ c1A'o.&y~8&Mx-%iC,X Z{W1JG_9|>=]"1>Fy0k˙>'\*fUA4ݸIYM77GKamTw4rg(l\PM+IcW|H9o% z;loa,֤xTwG{gcJ[0wZd~UZvUq0\.nzqhgEm2e Pʰ{kvj~Vw(Kp>KyzfI֙Sقr>u nfۭ4Jbgk:KaW߅:=̰tMœ,G$Q^zta]'MZY ڶ'kH$ؓU4K%Fs+Y<:? z#B7i *Cn-,G ni1M2}l9_Rt2`FJ\*~a@?6z\5s^5 *q3ZXGlޒ .5,;P1˫B۴j 4)/=@nsKmhsu/<_p$+od/d"bmpHYLk\k"JɴLøj(GFRO6Q= M}cӢv) xؽaEHm4{CS,_=eY\fK)Kdo@O,5tZWv@Y T1Zs%xh#T Y<\gdZ،+Lb@lػ=<;29=ɯLi-&Lrw6hzz DOY(oedkqzZܜKdT~x\6(yees5_oLnvl,rp֤ T<ѫ?KLZ3˚ܻ²Xhf -PYURZ՝67eQuk6~)C2LRjsܚbP[MZ!톪b= "|vFk[0Hf@YȪgf(h-,G>BoHtk7[<Mgi&)0ԯb ;{(G&]5:ŇXF^ tKEZSr_`IH3;:qu"$ƌd{Cy`A˵10]( |}YB>eiRzUO!w0U3kLάxC =foy5rUzt7!{6bqE' ,˅o.)vSzFԮz`>'y6<8e%޴wo1RqƼ8#TG,M|:iCr{[ZڭeYisSQpb߭0Qj"tW=U,u6PS29^lK "-}ԶmibDY:8u lH4̭ zd}wW'-"f7nyNKj\slNP5l̋;/ ~ub/_kǪ 7A^׻ :af^l! WzT? g-щq^;E=2 =V+Yy< l[z ݮML53x|uJ,a _9&3ps[1IFJzZ6OӐhJYa})_XPFP4xX>O4EZPĦy;Q&H SVj>d-W ౿fb82p|bb}cKyDmYKO@_W+sTKYvqK(g ]}Gc+R6koWYlbmªW|A?ڿu㾅A䜤=Z=W-3A5GȴyV}{IM6|/﮾g pAf4q|N[m\mZk ݟpHalZUIֲ}G)^YʂK7wj/i]el(ra3hFA]=_Mv?{g2ZLċ9^`~MvCشY4g) 4 #Vw 8Mz4 wĂ(v%Be[QYZ~>t&z2>VJx"h.٦ⲱ~aQs_7 a$&}+ݧ/NMD@S,BeR-o7h j`%$[PR4*>MT+ւa2ŕsx>Q9ͫKgɟ<rS)'ˣ`X2AM1N 9jjrZl`|~rz~YHJ^xʿ237|{ !7W6=BB ^]ͫٶWSO\Ǵ}7kjѼ#2zSr3:ЃcYOYIΕwCJzt(E(mJ97{}êhvJak!lkÝOjwiʲ& W~~!hr8e~^IO`qRIVK͆ö Riy nBAԼc5JgSJaĎ׆6ΞZN-~E,DON`A3O,Mf8 eQ|]ԴD2J71RU'?K #06yuƏfT_|#W{B,_;$*yѷ簼ٖQ#,%kߍ.[SD.,0 !8S$sIg0,oј~&kY[uzeMUi˷EU/ݟ@~FfH/Ћ[R^O=bK8z epgÁT)zeMUo6 g/7To᭥|~  +>˛!B/nIYz9T?[Fќ*_'.5⏣V|_;12&eLP?P/n!s9y0ոn>l[uWզ #1gI@~UeQ:/́ T[ [~9(Ap".Up C;[V-)K w1jCMs>Fv\<M.'͏Wڶٻ['?L_#DQ`()7KmGER/[]5(| ڶ_U/ӹ9c>K{OKtcûS"x?/OK~>wr}ՔKTzʲ{Y[9 x/OT>wȍFB/nIY-zc23=}#;Թ r5 +zgtO@3`b+`Si{yOaeNL(=)9V/߈)& BĔ0ƜER  $r:e2;.eTq}>_U}$e%,03W{ Sow>|zJH_#(NՠDG&֌? 猷vpq:$qZ@tA.E=1'{pP ρݎq9~_?y{L'|dm{Z`OoDvi{ 9u#|?P+IYGrifl^I̼?${y%n]gh>,حj,3:[}zIc㌨w;a|v{ s]{-) 4&#xv:e|*ks_d0y]9?/ڲΖscO+랤x~ڇn)%>n93(ÎtOPPPP')o2%F>ͭ+uKHYMhJ=e.nu]d x;C5"]I@yPcuW",za 8W:%2ڿ|A(u`lSy=0n /K?g'o'wooTU* ?0L|BAv{[qiP^e7?j [NK,ժ@rU4q5Tz3B֒L&#)K`&aofAa_DOwMObh p0{gw) q qW{-) =2aI:N;<Lem1rx;dF&KK.;TJEO:Yu4gK/j?54Q:SHv}b?INJ p-5|S5ܛ)d{f6Qzdn 淂g?Kx?/O0L>]8nU e'_D֔ ONjBfME>Mql,y2xnV)DZRjo|-LWMt{=:>>z|J!vZzo{rGӬ6]/7Jh1*x3W-):bi]UTh2Z Piu+~OGlkdlt\a ?R4,Su XIT%fg4Вud~kL@ R%<;)f7ges)RZ ;-p5Vi|<_nZQu!zu[W5 |C /_\P_ߐԎ9>Of-f݂'#d0Av) OF*wQ6T"J&eЧdZ!(U"'͜z,ՋJbS*gNۭb&RU.z;*F'WQӏq˪J}LzqKP?|'{洔 iHPC*5~<@]<ot^KM wC% *[zxܞ槐I-( r-o7ux=̒$uSAC̈́PP?P/DʵdRZWoO!e)s^ `\* 3-" NtO՜Z=嶖 oO*t$Y-:%K2:zx=_?V,lꅙ]GL;OG%-+-䜏v-g=,bEd uI4x=hxleP~u#Qs;jYs{XM_xrfNAFDWŵx b.+[|5,-Jec e˗88DJ1 Mef.2nIY>}0%LChl'q2%<m/^^KͿ^ ؗ.[ iϹ 2t8b 5[x>mAʂRJg[PƵPP?P/DU#* H (yT$E'C#F}-Usj^2I9b=\=,;qKX/L[YUlE.G<ϿS?U?gx?~O{~d'|gc2=e6^D:$M4 p3UGʜ@lܭ ZbQݝh%fNAFRY\=Az7٭toRSÊC/ 4H(ޫhf2nIYj?~1QC"͈9Q+ɱMyh"v B\܌bTpd(i\AC@dfU teG"ѿo ?n7Cz9^ܒ}oMdD'RA E!ߑR!*lmЪc񂔕QtP#)eU= (v(_M5FJ, &f7p<ᗿju7Cz9^ܓTW~K_\B";h;2g@j̤({+I)*{׋{Ʋ2@) A(v(0EpOe| IN旆׋[RAa]k*ʞ $G`*QQԹ>N j;#H/H5H/H/H5H5',ZkcG{HR's7JJfKǑ^j^jN^/nIYȵcÃ5U%ǍoKj?BC# (%eA@@@@@@QDYeA@@@@@@@QDYeAQDYeAOXUm&T%I !q" ʂ( eI[kS1cia,onBQ+eA@@QJ XJ.#}õ[kk+KP/FQDYi+;R 1,߿mw_|'Zm\EƉ( ,{loN qAX) Xt@Ve" E(rLJL:ʲR~rR#0%LO QLY Y[Yi&lo}#7F@@SCt:˟eA@@-(RSS_~?3LPmv&nմ ܪr:jۧ5,5l ˧,tkuuuÔ E.|g|: yߏQ|ي`Hu\|Q:>@]Hy2ܘZ,-7^P@agxѐ$ rm+oŏw@( o~.KI:ֈF& BgbL( ,AY^?oN0]ʂKؗAʕ>ʢ, ~v &ar҃-1Sr]Fܵi ZrI+ԸeRZZϢMq׏˷U#m ueee﭅em9J?/묍v׳d,TVʖQ@Z|CQw,Ϝ,0>%1K084Ȭ?uE=SB)]NS,5a}9 K{|OMi6h򏚾rdmmYEC`c{soF6L~ ||krdI01735-vP <%q;ʲ4DQ,o^:CY`}(KL 1bj2FUUei7Z"pD2R[rAF涮jME[+]quDF3Vw/1s2eO‰҃D;DB:j֔;&"; jT/ . ZIEU2J =\E)&<r b<"c$e^ag|oӟw,k *ۢG3S};><#06㈔N»w#6re.~*w{`c mLWe黶m;WSZ8*#Kk%ueޖVqdcw-7#5iL~WFʢh *:F/{;R܊ƧggԸ=ʢ1>Fy~쪈I,nMYhQyo:{wg)psG~i/p|VY'(#Cb^/wU]JӉ/+s8cۘe gaygjEY4v x̷YPzѕ$%6؝}~fI]z$Dw9~^W݃s{e{[.,Vei vysۄvlr>@2)6LVUu/%#JkVĆx~miٗuˊxե:F>W4Q-ᶷ CYdI^`kb ("`ףJ"(("{B5 =!pf7 vY6ݙfewvSM%ɾ仭駅tZTAeeLM:jGb8qzUcſV=!j]FX9;,S"P9r&W/ &jSA$}ӫT&F+99M+,nJ=:j hG~܎! ^:'mvmj^陪f7ϭRmYGYpY5Ë1* ,ʒ|eվ,F Et-UGE\^X_8@r-WE@%( gH#JLYߗUC|Ʋz#ϐs1Cr]+/o+jj^ TuVbt?,:;wr1q\I=r]5S' ד|vgg4e>6~Cµ婾|.7bdYR3ʲ6Z)Y {i+%)K"lG.'nRNLMOpU43,ZB.; &* ؇gFY`#eaPBNr~ɢO'9u0;ح, LP:mEJcIooܪ[Kއs8\Y,S]+F?z]ҽʲ{zv*A"WЈ\Kl(.a>P6"O5 Cfdpsj*2Y t`pZ1*X6e%';PB&= &* ؇fFY~@Y'&7 fUKCgr!npDž!%c =4Q5}C@_TpxQf[p:*Uh֦41Id[Y4 )'qa_x\<ح,-C,/weKYɗU3׏Up3w ~[=x[Bglc+̣-,0oY*kSDm)3,ZF.-* ؋mmm}Qr[[_ r,^:gLR-8;ͫI׉S@1kC W 3sE^.!3zL*g2p*Z::;n[*B.Hl%u ]*BWtu7~i,H>]&5 ( -imHQE-]\KܵFMw=oe_b>Hj{s2FRzSj*kYT<"lzBNqk{GG]; #-=#㣣}-U. s-F8ݔTw uWeq9M΋CܔƯ)]796rRYM:MYY+r {%stjb|bd(ͨ_ CZF&XAPY5l>GW3]424ݾ}m~Z swޗVޓx1=C0_1 X:s׃s IOn=aA=oYe 8>+s ]KT]Pue7{10iDmGn[9˕]ndn@wZtuLU7(MoP)S* RӗG7=hŜzq7 ;t) h_7҆'?~@C*/cH0S] w5YI/7f1W.i^~TOu~$^X5*xtԾ:YiP(tQriyeuK|~ը27;S3V-KaMTAeeQ)֦"[ThiT)ၓýU>{}\K~Cc(ZJD-D[,bl }嗡X׶ vT> NJ{QauS',yuiS -* rdeQ$b5 WrtXAPYCY?F4sW̿\(K rt]whJ۲/+>*˟RD Dv%š,ʂʂ (` *JA&, ,,uzrbei*R!Z|L4.kj<8Av|I֖&FGVDBS"癑 <8AW2D>351>2@Y̺i*%!<>AШ;toVaš+ # ,,   ʂ  * *  ,,   ʂʂ  ߯,5%*%>hAA}֏6gP B)/δ6򎅲,/U_AAc,P`-MbAAzGTAA'AeAAAAAATTAAPYAAPYAAeeQe s3=]3<з0;#8F~loy Z##b:8Qߚ+R8"GMU1~:5jɉѡ^lS_lWzJ{h,aلi~{ƞ) $*dc,ӓmmmYOٰbou"| &lG6SyRnէoM)xC/l107g,xe.H1潦/h8FөR*~xGރ?,~iwJĆA{~a>{ H+yVFQk)id 9LA_o6eZS>#ehm殙rl2f~ ؙζflG6uq/_r_lf4嵹g^20xd|2=( UWP^^|1R[~)?;zcP!b/lkcomd̏ʏܢ%"4b7+[fS hηXMyj+% >FT枰|Ҩ)2XW{CbÇ =bÆb$+"4iD;g-pclcΫ\afr fzFPzOqcc'!twUk?&! uց@S?}*byP!bᗇAPKvՇ'͹Y/;7f`fL8Ɯ<3s< t#13 J R#eikujς( s'pt2iNIѣa#$Iz7 C4'ܮGdvhSʁwQzCĚF'ly&~ji=zcRѿ  Ջ  m1+|ߥ?hW{ِIPcMԙB v>M<2"_.?̎'ܸV`^I_{nZ?aUGr|EBfoѯpSiC)xR#eibA@WLm`oGcYJUT8ZB3+!D|mjnDw ?\c9YgņA{f`i ?&! FY~G]>ݘ̘l`g2`94ˌң'ęnoo^<rmC=BePoSˮ;%mG̛3 !FZ4S:В֧Cj*LY66(˭%vǦn1&!3pʙ긠=|"et H.{<'% {5q]PԾݽózZvv!.ƹ̺g5 7-7j7!TcO6Ҟ6Ra)>1=141h$圃_hv70q:לH_?0摁Ĝ_(}#Je 3O7hY؂<6 0{ R#e*gJ:L~VFVrˤڠkǩ/.61df6qT7:: *܁oߦͮ(z1܍8󶰱6#rؑr t%(94(ƒJ[ ^]qutuV&?t d2MN,q]^_Y/t&e1+vPv`c טؘh#呑ИJ7>Ha ݛ te;!R?\$'_ͿH\U=8^(lRl39OydHy4-i J}>$>)zQ?3 jN%tG@}^<*ߒn^={8?i=[Dۺhՠ, bKj&,$|Eæ(ǿ\"*nꭗ'!N8Fy&qBL<@7EhA_Pc,Ue_777OvąV Ȟ]* !?JzXYͯ nP,Bz̞SSd}QgV6GuaDnZKڳ3{eZ4 joE\BrB|W=iW+0S)WvO{|F1"qy!J}[OOpG s 4obrDy;/ȚSĽo$C1 q"GOX<əeJeٚJ:w9U퟼ȩusb؛%j ,ޯzݔ|*9)RɃZɧ'dV)U t5ReLșZ` U  Ջ  m&'!ܦ;ĻxIR˧3AYL@9qXv77 "W(ܵ_6=. 7~4pu@]bLxK} 8(Oza(W3]qzw_o.0o.?t&\c̑wD|09OdJAsL8_ IAnJ}k}tN~rpU%Jb7sfp(SLhͲ\R/Y),x*&s2$ΘI&W)E2q \T*ETbĦ(WkCBas_K{ݼ"۵HV$lW̦(j:"V(W*eYQ2dSiȩjOLUqbUP.W ^%"Qw$(KҘT06  Ջ  *GmM'i=q&EЭȦ2־TYlw`/V\(e 9j]g,'WG|7htt tN{Sv&vyV$#Se wW_Pki9ڎt{C (:Mѐl,R#e)-773|jXT2RB/&*2\ʤ␓rhr (gYu9yU=]݉%xs:"d`U"|JoEZZ*yr){M" ϓ1B\ ]뉃c/:'oTT~{2f#Pmka-[JנiU͕)tQ [0TNņA{f+ Gw0q6Y8ƮށLĻ`N"AY-{{~nJ"[[+F[}|q{='dvnc)QлE IATӻ>>cH|)" 9yWk_[Sco9,/|o.=r"N&c) =-[:Pq ByHY{5d?<7D(;%+[|Yn#&_`P&W?NRd'e`GyvXYL%pN,BTR%h5%S^{VKMH#xbw~J'E Ξ~o",Rf 1FYZɃdQEx#t8{6(ΈXe:ήQCBbÇ =bw0 4١dpk_S{N]YMȤ,|FYM*|͈lA K/:;Ͳm<ˏh=(|O 4Ja{&G-PsU'Q6/d%۲(ԃ}]rXf2쫎eR|u0B%BgolHS'aH0_) &h@H|!|+/8 *>A쑿w05RseGos{@OKăX<ڄ&[Ӹ;&{w BM+j+^ZDC(1RLAzʤg,$uv*)"OTfնtvu5$=t'N~SBX~ /_ Ջ  _;0vΓ+ڏxzrvT1ޠ,o68fZK:wGZ> >Nʒf ڗ,f>i:h% >"`)|d9s*6?;>ARYށͤx~rːNz|e* :s[Noiaz\mΞ&ڛPah8POYo,|e,A=ZB?WGka<*寭XAs,F sU4( s^vQVrPqИV,seX(zmtqѫ(ޮ^VVRf<Ş.d_F0.v^`إQ+zC;z_h|ͨsCU 1M|5A>c)`. AIk#kȥ⺚Օ%V>3 b *b)K+˼v,: ?h$k} A&)ǙVy 'Fdž)dc,츪ޮ̌$LeABb hC[Uz_LZPCʡlVUr\$̌^YAA~fvTT)++'3?K_YfggQYAR^^* *  NY޾}{4eY[[cAA?,޽r,` TX*(*  RY+**@CXe3GY ,sssjGG*  FY>|6* ɶt:Fc,ccc, eNMMV}ϣ  '%666--Upme1`-eH$VFeAA(K|||FFFMM x8 >ʢT*R),^XXAeAA(KBBBvvv]]x8 ɶzVR`P(\ZZCeAA( ohh'3?KVNgATAA777X~`,677ZG9AAw8XʲCYs gY\\뫯/--IMMMJJJHHûw2v-.F^vb=,Z,:z{38///;;;#IIIINNr&00000000l+ `````{žbKZCttt477öꪫ*++aeLb```````V"%(+.147zk$~?/,εX~"999 mtuuۙh8\.F^vY_?KZ"_I\]]]\\mMLL210႕V$(+.147܂X|,Ť,s-žke^X́ 0 p 0 p0/="H`BטX5 NW]cioXίb\BMHR b&DV񽰖V'X (&e9Z4 lBT*[ (a-Zciort:V\ Pa```````hX 0 [z IENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_expert_options.png000066400000000000000000002634461477034762000267140ustar00rootroot00000000000000PNG  IHDRXsBITOfIDATx콅W˻oo]Y=';=K@ $ݐ$Opwwq"{v0!og =U5UUOtd_IT 0`r{=RN~M)| 0`lfwf-MW̚2Ba 0`h0}6t 0 0`l`aZ~вY =tA 0`5R$hӠŚE_,hMh4j* 0`/KyuV p Z_:Ye+YrL&J%T 0`azNW]ciou{Lj-M}}RBd- |>rTB 0`×hZof_~>|}ERAf{zz:N6 0`Zh0_k!UѾ222B D" ߖښ**Tb 0L/.F^vA_k'1[o+?pW OۻAAdT wfaa!w렭|,}Eכ} ?8~vWAA6_'m1555fk'1[o+>|2 F&ڠގ+ޞ  oOR0@3wedd4666WBbJG7;AAhs鯇,oKWZB l6eoOwW  ,d2@CFILO( C,F. F7{7AAdq|]II x8 3-Feyuww;;nvsl?6m\jRE6K+,o޴ifAAy( @CF,og,z^Vf.UWW l^v_GNk٠>moټvKmz?w's`Ͳ)" 2/xILLL~~>x8 ,ǛieQTR"uvv8o뙔 V:[v)põ]+; k`M@غqI_ ݺy5Caa /[]Oa͢,vcl AA~Y@9=zK? 6NB?<8mtr<8]. ]՝ K;,߼i͸`$aa)^9?Xnq `ح\tтߩnr)l&ڬe'czk+VWmOmi AAo޼ə,BS!Ke訮glp4tSV9xbB|s¥ϝ=~KO[=slE)D8.[\eq{^q$[윖ޝł'K7/r+d嗶lYc   rܿז9[o"lp8ʎX0 VvZ:<T῎^`˪NWoXҜ e'Bor9,_񰒒QqXo[춬^f ufkW:36AevbCmub7q;cӊ5׉gw{u޲iŲ-xAgᚕ6. tIXz՞\nj iMi-^BA_ Pwz  <l+ !R{{;$`lY3mr6Cʷ\? }227Aߜsg9}Aq%q 6'eZHϨ ٰd m׹mٰiZ;Ɩeo𢠮T1+m5ډƇ^LrNx} s+8tw7K\ XtÎj-]uYZzMWޕUS:V/ AA~)@9@Y@Che1IE,RYYIg6 {vH=,v ;7Aklm:yC'@P35CSJ5%^fU.[0l\bBJ hϨaYY8u++FeJ eYd\&ͣh6%jRkZ[sݗ-]/|PP^H9BA_ P;wDFFN2]eٲuYPkx-۲g6ò&dBsӧ=Bb^St&K#MiOBwz͛K7#M)yl V|J^ym٢%-\D~IB~Aok-ϫ7H]ۓ+^톝w7cɦ&\ȊXRY_olKgee%fPRueUW˫[ s^d:UCA_P)˺z&e [;,b/KߌPol]f҄`$.۷y۶zo==\a 'eŚ66K,Xjp˺u._ȴy…k/Hc%K/0&B6\nꅖyɊ TEuWYz˖5EB֐w㒅+Vo4,iAA~@9f,k,_OYjRVK҆H7 V-"͢kW9:^.>@[ Opv G`zZ:{Fb\AA~3R5[bJXav͒6K+,YK8XvG#Rkf~͊: 1#eYj)8  Ȭ1#eYAAdV嘑\aփ  2rHYV,_փ  2rHY/[ փ  2rHY٠! *,     ʂʂ  *  *  ,,     ʂ  ʂ  * *^57555"X/$2corXá{luT}5800`"048hmbDC? k~>IϱU Bn v΃b.}|y €< Xgm$JD">Α#CCF0ax ӛ"tr׌*2LAMEL*C+yPYX_3`0L  FY&GǍk#Ik`0L=8L=R ӯt5G7l~:C0oaY{hC:*U+&e?-`a~?0H83 5Lk# O0"s0iE¢\7( Is\j0]-Է={Cm/2oecAeJ%Ě 3 Qslb%.$O>9L7QAjaphȸ~A(0Ln?G3er|hT.PSe(P_ )"s.x=d.y楲_(bgNʟq7B#p~€'ß`6vw|qhp6qɷ0LW >xP_cY .%Onb@mj|mBƅѕMCP_ wvݔeXPy|ӄ-d /T>=d.3*ZP~ߕ îi{dƠ7$vP#%28caDrD%}frTU2x9b Q}`㄄׺-=!pam$j#CơɁIa Jc L*vjMu  '`WŅ)釆 ȷy=4͘ ~L.|݁*.P|OYɝ?Z3 _^յuu]@ʢ A~2LG'3U .$ݝmԄ4@ANK=0@uH'Nܿw/1!,r]iBDFv|n:Q%(K!W70h4O u9)Ŧ+B = A}ZMjjUs[-`T/D]]}GUʒ!8J4S5v^_-~SVߙv]YtnNUm](յ {u|BY{ÃݭlQܱߧ~R"=v#KOC׻ՁqOs,|d#/&(O)' 0|)tuutww|&$4 k#IWG+9!:WÀ A PD&ҾӫWDFFdgݽsRNN9)bBy1hӅ7U0dZ*B:PiW`Z-B;_m/oV<X[!7"vTŇG5?PVKAʲ;t~A>lRU/u8~ִ֬;51 k5DP,K "W'*St-=*.G{4VZm<<ĉ 1&paX^t΅s& qX{9A]D=x'@#qH C?v^{&8 .pc[Z#M[G=>d~HZ&4؃TA*a^Bh3\+EA(4T -GuG-+$Gs  A~YW9r%xO?MWa6u@LFk^Oˊ%Z&f_{^ϙkz$"FgI) o 8jA+"=%NT0zu&_mJ,ozz!I 6Lwh5]0*5ADyghxg*zv;;{ "߃]/w0vl`^s'؃F1APtrMGqm( k˽ {Hii4S.)<J.*/I}~̍ۥ4)ˎ'%mڊh%7}CO+ _ s<"%fQǕ weת#>|#nee8}>׵6U$#oeaJYXՅ:>SkK1j8J?B\VS[Y+AFt̛.+k, h E%aϭJ%d8eq 9.tM7=ZSh9gu-(K`\(S9_$ yBHe1XUZ*2}1TI^!,AY4w!3L{O ڶg */{b򺖆MLB//;i=*; JYD`ЊJ8:QR(s#8zMGNh6Br=wD`tN$#ƒMZ0笨jhू+z ,a)JI0Ppam$imq<6PRS|E1O6[Hu7o}2d:]WU%T>FԒңjw靲qZ魆,[jAkuZgdcҷL KRcJVoFV /hnmi3Rq zU-/|8ɊIeITy@28*ktTfS#4d7h|O^V1u d.)mW)eQP\[DJTœ_ ISs#Zz1udjt0Ft9,M#ˑgU̗'=N֔E zZDv_WUe%$yb(#ϟʺ0bۓf5u K_<^rM!gFO~7Kk*c! A~w"AI ~&,1cJdj~iiKpV!R'V fW旗  B^,s԰,*<@xKk! !VLViEyi6Ŵ L~cݲ:D(`64֑9n_po!SbRiJؔ]+ Q{yV"rx:#UJ%QEo䷈TQx-iqƇ+{яVr+AJ8 k.MoNo΃*)?}H~J=h^ ÅN+wGRFz.ld Ɔq977506 @Å|(OO(ax Qs<~TS]q;:ZZ٬^~[JB帄E5]#4 j={C+8ʳE2dBx*,^IaAeX>:Ǐ؁Z_A";bf#sAutaPw .kSca2?pam$i0b虌>4y*ZN sNNqL*Q)?V` TS5x9Θ5`!P_ <n!t jDzyAe, 1{y}`dUQ|U);FeFL規jNR/ :? N5! '$ }rҚϤ6ԬNYBC׋utڑڪ9^1W!yPY(J̷QAJ -̯y¼@/RB=5! IO[zw*ԑORhTn I3%x̗utk.-)eC=Dc*W!KAeJCmMIQ NfWtˎwq#sJzYKarhp0/clVwG:6DOT幉ڲ:5Pn?{~C~HoIYMs2R "0GJ/ +`y˦5ϠE¢ܬ10h,ETP#ΈCCj)d Cc (nj?瓲з55&'Ƽ@$MdrR ?Zj}NrXMuյyL]UyS] S/2bccFʲ癲  2嘑,YAAcFʲAAcFʲrrlDAAfP)իAm@9f,ׯFDAd嘑lټ AAcFbGlFDd.r*E鹙w;嘑89c#"2|0/K.__VEkA~83R7'lDA~8Er cL*(+nX@9f,nHT_SY^SyiiuUuvyr3S?ן"m~v:NȏcF9_Q*C&#?mC+~޺̃*˺`ͼFPP?1f)rHYvlg47I%RPxBSC[yPyYlH*gdV@eA3R_J ,zNSU20/6Au(e'd6EeA~83R]Q18΃@_Au{Y`j0;rHY  괚y< dTǤ, rHYC:z0ꂻF1G PY(nj}TF=шj^]9Vb-EޛqbXJkRE-5˿f{w(oWU}M**nܪ|eQY>}jN0VVv*G ]Aޗ#X#h[T1#e9~tepp@V}T}CƱBSqMObVפR&e}'$_Jl;~Z뢖5Ws?Ewff(E%miJXajO>| 1.K Oѷ=!gHٞ^_G<^A4%Аc/#XO,cFri)ˀIQrqxS#o-RZYŤ,kV%\+Ax*TJY D_q_¸EE5$\|cI=idx;g]QF9 :A1=Ѿy<cTǡ!rFmcca%;&0(ʿMZTJ^II~ګ!q>kYγ* 2嘑?}r:2`0UʉO˞/2sr2ń>)U>Y%RSE`T\QM,-I%I+?KUp8򶨲HU}DU(eM*ISRY߭.FDUw|{7~42Ez&m=BoD&ef>>oGn䱕_YPJ+TR##Ԃl{i^k 꺢CҊwy;S<6Ƅ`6/r '*$=$9H8NFWιGdvzR`ѕ*nB΃ rgXӕyv2CSڕvh8{}r{vF4jMǓLRaxb3Bۢ ?P)˥g,Jxd1{ lzt͌<۝?=)WyңyGnL_ pzvz+Ldvc$nvHe)wRI"9$Wޑʒϟr-mj,)ՅBI?|2"*p:gj,o nU:vd>[sϥ>$g>;KsNAv]xP3#"J(!f1~A?Wi<:b ;\GNy8Н+bx![jѰ߾$s{>M}(JOSc)W6i#LQS ƳA!z7v#$W d],. (.z DZXҵ?%GTUTqtZR,owwtãE࿇oGx~lQQ; "0oɘʒ vbhxdbTCk578'ie̗  le b+bVс\.iloo,/(T OlFh[T1#eza:b0 v'pz&BPԟXPU GXЫVJ)A뜢✤$[Im1/E2Jn[Պ$#2ʙmLԚ_RU,o) V(|j"ɭ{,+t70#Vo֊!LXq+ξH/*II.)դi[uvׯdȕ}qԨ_x~hHN*w&UW" evhm;3is'WoR^v!/Ug}D: 0Iֶc)6 )knzkaӐ,piPYqK7&Y/5f2'/򌩤dY)* Up8WZ[]EQUJZc3rr@vDPp܎T $r0ᤲ d\v6QR)b]]n{7#< S5,̸'uRv %wQ Ƅwؘw飀τv{,Im#/v\қgH K*m|pXU9'ڍ Gj NAP GUTsż K2yY=^ۻpXTVSځ աŚX^IgŽ N&UA*\RYmaMkezM8bDeM, Cݺu "00tG@YtS) xe)5QYb ׫uj*3Q裁O) . 嘑ܿ6ejrdj8$ĵKGWrn@"?_h'䙎C%/:H:ဏ,H'"`>&0r/{iw",V:5He)² CtzU ǤV4IN aDM0JAHe9_oL%n eIWa<N]0qz` |.G*K|H.'}i,$0]b$d;ݭ26J9ouuu0;ahdyOagey5ZGTrY,#jZ^+Z)ccHY{B7'лBiwKE= [ GչGSenZR}c,JP5/q}lTx`4'"(n;yrtNQGʜSy{1UeѳJ[Kޜp!-"2嘑<|:ʢR*`pS0A^nG%ed%> |nWs!;y9c^ 궷1 WWA8]J+Ky$ASxv\++*|bGp92O8$X_uذ,~O]t&ƗM|Ve|O=I+K{\?%oDY `zejN^anM8=GWtrn/(ΉʒMQoȬ|,/JaP L9VVE't&" 9|nU˼V_ܛ}?MZNaAf9b }7xAbV^qA2k«ID:KhR Z4̓ s#w߈*(L}qmD~)"gG`eɯO* JWvGu<:]AaVӱJܝvz8& qߥ(xQɇ23Rc'д6h"|N?zj|}>"^+8g" %,=5zY5QI9ŕem&Pe|_wW_ | R߃wO?1<^Kh/ikcpq,M;WM fPJ:ۛhݤzae{C{}GMVNae!U{C[l}HjXQ!yvokeC,cFtEqSۻ~8wxfro/xy~}L.[>} XOЛO)K |+-{{u17G7\qbXqWC|ػz]"c XU';:ķ '+uVrE S:Lx /MDBNkSǢ|A{ZX2U!1wױ~S]+k3`Ӊ\*>+A\dth֘ZA~޷qE.e<zܶ{Uϥ?3޵w۶Bt#wuVJK؝m!c]yR34M ׿sx;ٴ ]gwOR^}$)"y}+')ccREQƦKHeyXkls=臤%TSVuO猖afזuN:x_%0n& w-3VSwiժ^T=oN{d&-0TR?xe0XmQY(njU(\&y0ꂻY*nܪC5꠲ P)ۨ(T"s9yPڭyf9k_ж,cF5-e y}yPڭ,̛C5Pж,cFʒf:"XyPk7* * 2嘑O\g0ꂻAeAeA=ޮy< dT&eEeA~eqXݝyPk7,@5e* K( ttAeAf"?2<ѡʢl{jtSe#_'O͸za!*CB=N*7+^T8A s,U]~Re:u_ћ_M/ (O^.UP|6ɡLT'~]eѫUqj\2PYT,:xVu&'r:krޥ7t1wW/7m_`oBpy^z\K;{m>;T;+ O{,cǞ3Rȫ÷SZ%I'~S`/*AF^ $uw՘:eg=t!vPN#kMl'Uʩi9wJ;܋.S4Xz{jEWBOw~i|)yύUuv(,NH_󰞭ETd'& ~ZnmcJ%S'Nbx}RjDX Ҍjnܳͅڥv{7({SZRA}CpInnֺueQ%kk{?oUN,ZnU/Ϧggt4^}=ܽ'GT}5) lAhInڗ5(JM<骞J^짎[uVTzwVWy RB53y%u؛֒k$۟[֟ #5uV!^dtF}xW{;$Н.|vh}d3+K,PYToU=?uo{ܨvZFNv9YG>xf1ևr]XINvJ/O?C.>ө~ !fb¨wÇ@|)-PL uvڗܯ"6Qu%xe`\ڲNMNǓYکKNvB{7Gc]er5Tnc^F_꺓\eE}L~O?H{Ь*K9*v{#a-S#UgNr94E/.<@^H鉡tiwlb>.>CօegcNjvN^q5R6ᬨpt6zfeq"\t+a^ ~Ƒ,7zX+1=aSML+ی}n2Eڱ2Nbd-đB1Α*7*>uߨOq%[SwKSV\vO]$5Ű5c}>)A^w:;V5([t{QrŠ/ƗPEO2ߴl!ǭԈB]ժG-O@ ougDvR:vS]On_JkَmOM^j@UI:g͟Eܪ{nns:Z(1191&f`4I:LL&jpEEYpwwܽ~5NwT*bkxy2m:s֞3ÝQ\igyGԿc<,U>dʍ0K~xCb<LYؑxpܡd> Aghv:u_2}lS1O/)f}UY*,:{)MdQ=|#oeg$i/tg~Hmh ̉8g'3g'~I1uŴ)YœT7iL?IaZ޿N>[#x`7.KM]HTʶ NEӸ!y(}%VY g3]e\㵌_R+A}n}YƗ̒M_R#|s,Kh2\}=>Vag32|_<ީ ό%l?mI'g ߨ;.һm #֥0uswSPc;jck}Ie'6>HYrskٱt3yM&"y [bcAG_h%9|wj-K`64\'YoXEjBDcRQ#m։֙N:@StD+ qhKg,>rER-9L;,\9PGo_Ŝ߶,>)&`&"9%9l;'ܟt |'ع'S=eG"<^t(uߩ~pQl&; [Yg^x豟rCYx=Hܻd rr<捻mɥ,#ܽJMKY xSYJfű^%ړd/ XA7LáKYg4*֞"z P ?PY8rۥ,wА͞\=͞ “*6{Qe'ag>n;*MYDDIv&(lyFobrٍ4.Scx+7XM̢Aw(J*c;'h}9ӵFۊA|[#h~,-[f7ƈKzj't*ca=c#9,A:ح,%GR,,;ʶVZ#c$oqcKU=ʺaYv`ܟR;ӳҩ,,>5{S~c)`;G0JYǂe;hhz?b03FMۙUdmLHxZO50w.1 =>-,lEpZV 9Uu=KlC( 4fyYV}CtCDaGP`(HYLsw}hSvs5 fe ؅#~7+ a3nU1&1/Y<Ͱу'@p;k26ˈ@kǐ|Y8o ,ah58 ۞cfIB[~+' '%29ygl>UevLap'3ܰkٿ?&t@0x8.:z9vePنضc(]l eՄ 0Wme}e>S,`3PN{j5Ɍ$s/?*{:]/+ lx;gwG3a#Բ@35ML=ȆRP_8Ϳ!¿f~:Y) -i'<)rMD GcعarZQ/\ t{ g]=/R#AoϷ27#{.DUƞB 26{Hܧo]VĞs]@7"v ə0w^b>S1ֈ0gi>G8} 58*X*Z6^^ տ`YPc ?CZ{/MwDA~h3iTE~?;Dej slbP_SY|9HG5YI#ض*-޿α6T'mņE90L,VrYÁ |*eK0Rc*/:!]+8>᜖<);s"7tqQs}8cIgƳ ~\ZC^7$=fdٷ:o5:ϯ&Yo%tO>?4=Ovn(t])r ffI"G?]WݞqIN/]ҊsGL8~FFgKnˋ(īJ(M}Be _z{5/qDGWH܁gr'6Б UνM4w樈?bvq>hqBb&v.h៥,Z!;KZ[wr^d0D>pwA[Y#a#Q;Knŭ+[p(fk.g#^܉c݋p1{Ϗ s#o/QNJM>_\9XGl~)?_V_L}]dGe]7zvmr se ڦy+V "eD`e`/ӳ9#fyw!tբej7O 3"WvuO1IP~,=!6_kS|W6+UȘ~:/ {Aď/} i)ͭQyDk]2GnGMOV9Zl(W,raja˗ T|s/`~b#{➭cbQG_1w&1+}+]8˾,_k`PP@YeeP@Y@YeP߹Gnƅy<Үr܃`W:_W70{dY\1~.3q/uװwvͼ:M;4(_?]vdT7W]I!Aa/ |[l ~VvO=H$p(K;c`XD(d^"'*uR'NO򘹙 EshvRkJrS8]Z3m9gS'FܵF_,'Jy2Qzr~82\Gqk.G4vʔveqϿ桸 i|ѽsMU#~֝&بB|-Qr#_~:GL7R+7+ f e99 1 FY2k&Ht}صCY|veI4J?ޡ#}#^P Q+=|ʲxˆm-q[Y6<Ƴ3QvʨϾCY)Tod ~Ė{<QY<쟜?PAB(fioea7MSY֥ۂQ2+ $ybA _^s<y- (>-@Wdz]{"S(*/;Cԓ( ;e[lERDWkLOB(Jur`P%+*||35 if ~ W*; ;o;k1Z #Q-4Bz;?NI,Jc3)K`6CGWǢ<|FHRX9&a|e( ( ,,( ( ,( ( ,|B8qcnWn7 Nem™?N\P ӘeS@Y>xSh__6+KK NNB_bc'U&|>PMUE|<,yݢc.=s6 K*j'_t⛗[F:f[>zIk  P.\6?-y=k~p%~g՝b 'l2ԃD`ڳ(k܌G)FAcg2ŕr1~$^S|[#~;/iuӷYPAb;E|ۼr!nl̡*p33x5>pZ1eя1Kc~LUh~cy{k}nI-m]~et/⮫})o]~!%)GGە_>W_YHk^"J5%$vY!OO L(Q˓w>{EJeOeq:>ׅKY<#q؛BeÇ%* PXV{si_ۣ ޷=4o<ſ|IʳcP+%i1<:O8qſkWI<}g xr皕+LD'y6\SoKRELV7 ]~|z&">Z`5%qL%Pviϭ2kٷxͪ3肊]3y) ?dNzIXm˜kA"dS[ʂi_d30[|Хto%E>g^J~4r#QN,;ntt",!˃%7 bҋT<\":~ m2.Pgh(?fR^Cߓ"/Q챓9Me! 8Ep e Iǟ^+Qj*S}˃˂Ҙ$?'o O'Tb[)4cC7RJ9pjʥjrVV錃`Ŕ;-JV蛰`䚼,3oU*K}<ɌЧѨ3xHT\B8 ZZݭR^OJPtQTԕgD N3XxDׇY b4үԊ*k*?NrlT!FF &QnɎmO?4::$xԠ eosׯyD, e*Skṷr"? HL$g%^\S`eߝ䥖 ͌@&z{%^|ѡ|s#,I8ɏ0 l4 駪\N(^fDZQy*x@{ y@j% "َC=wPLi(îЃwT?׽ AqO=LCYIe^ q.B9bA!xYQr՘Ͱnḥ]gC>[_Η~pK(.pLQ.i\RCYkL_"ʃo[9t; K5u>/yN=Hb&|VyQ$Jy2 "7SK.;2ʲURc?.alZ +EG:CJF%dz+!A 4k6$"Pd7ŪEΨfϦ?:vUN5|+:s+<@((s(K{-%ULy7W j,- KԴ94ùW(fn[ʂʮgvz]cS@Ǫ¸W2;6(2) isﲑpe?}_+#Z>L[ Kߕo%QT2*q&Wg!z]FY٘ 9ϺG`<ա!Tbo }VӳQz|BT(ΐ$A♪H(Eݫ!+w߈TWWk{B\NvQ ^Fɰ0{E:BGTc3ںfíC M˷i︽W_{"E}'5ʮ־em䚬D9wYuI2uq'qPe$Ү5> n.{#TH' pK5T_뙹"*免ğڦ izk/oI#Aeg; ,;TkƦ'T.B(Jүhdȯ,v/qgz{DvF,[1YNePkWkYݷ?nX"8Zct^]q̹]EZT+gD=󜪗^Vl*OܶcԐ.*mp e ŰԜJ3q?7+WB=CA?7DP9:u(1V,_E+]pO4*`wAGf!Axg[yqY_jXI=Vg2DG K{yvi~|ΕUlwM5M wŦa?}Sv ”)w(egjN|}dcUWC\TmD!Hw3Eɵ aW:ogOo'P! $ebWb<^Eܗ%$ncFϊx!;JF%Nk]8w*PA>*dxo MZz sTW鱡'(Br]u-o |$#]f!PԔG(:bǜ|<ex'7@YeePP@YeeP@Y@Yeee<.a 堒,P"n1iT}=2)TZ( %"ÃUb ?|\[|_oƝ #&gOOq̪+ݵ0808"?<kyvd"~Ak/Nlm6=4#6،$+S#Nq|r0i-?`i5.6+}bɜ*kY]Fs>)?oVlI!;P|}aPPC] qb&Ɉ~#M&?`UeeJ<"XȏڸYܮ?]WMsNt=u-=3D@Y~Ke\$|Bǻo,wA$2xWQ)n R> ̦Ue5uNtߦ,uR7nBOҌuY*Oesߩ!^ݏ}WMK~\eO௦,kg -|ʢRGYdᔅt[fZ:$!]X'cdDD?$됩]*;:4COQys L|`ڊ12 uujڤ1mOKX̲6W0Rad PKKP+;"&{Qn mVJ$L:eR6ey:Gdc6sYfjZFth$:YMssfz#Cx6.nXC(fiY=>jun* a5IM숴ߤLήU8\χzib6, 7YE;3ux|$,m e9g 5-]ݲauyfa6ꈵ=#:l1W]{.ڵ걅euδWq޵&qz)%_sLPup w,e~JƩ,eucMЪt-5 -?:+ff? A8%9 fT q۬Ziqi nkj3]C U`C[0M !!>߹!VUqvų;0DՒmmHZtZ2 6tO|RC}r`bZ049[ۊ"#Zm9۔<ʆ;0D Kz%>)ˠJeq) >$=$;uuQ7 Gf9*q5vj%\Me!<ڦ1zZ#XYũ,GGG>nU94bT:Q6`bpH[URvA7xB( 6O7475GVB* Uz:xүs/x- n6״ѱmqLlG R8X#)VݿeUrnei V-݁,4 4pNY|Xʲi*lGuMzռ=˲ ەVm67NR­n7-iU ȻGQ,BWš+Z(5,xHT!3,0(,C( ;0DGGcՇ( kKu]k$,$a` =eڇVuln /E`?TKH3zZr6 [ͣ~'ʭ;0ӰKYm %l`h~9%1M)W*^k:{s- s,.jڵ&<2X(g,#JnX vUՕ%ENZ~{@e!}9ecMSbZd^1u5fJ55uf:R9h4,.1cGY8+NxWg y4K/f2qN͌i`1koj]a` i* C][oݵM 3̜ݳ,ↁ5˚<LcP"LOOax)EO kDgC>ݿ:^ini.8,&5`gɹ[9e!4lߥ%:@XR^v-MWY=S]gIξc1#l [_mf._lmrbwP{ IXllwimiI S d%' gquH4Qz~v妆ۖZFm[;z&,#m]mܚz&6Omm mӌrvs> {ڶ6jYK wͲY/ ,8q;'F\ iTZY_eP0: Yd,PP"?> TO1&z>h#$5e<=;ti<8>_rPP@Y@YePP@YeeP@Y>eq܌CpK8A960L2e>oeģ{dY\외Ma>>Tniò"̲O3^8/Vs ﺴ#ZJ _bMFd@{(|4ezgS5>`%~^'b!N--phvRwk.GZyͪ3]3yQr#?->I/RYC; *^g~roD'\n]=Sw~A,ghA7%(q'3Xeg//L=1_( ( ,( ,,( ,_yܘM%@Y~etű0p&b:SqT4qg'PO,cZ=ןoW s}RR³鷓ЗeIU ;6TSծs;ǭ'O%K_>XKO\MCyҪI0{֧ų^ҽ${ZF :$oK_ڡ3\ccG:?~DYu'n'~> = %>9Z57QʃQG왫LEqhh 6AxwNwuZ7}w TнNe6$zs(> | ,8u~~YciҘƾ/p2nuޡޚg[wrK[EY0݋cj1{_[_FeuQ#ve!UW+&

t>2OL5:I+_[Σ4HH35j4lذܓIȼybbbv1l;VOOBǏ k۶mYl1]nDIKKk߾}n\]]>}ѣ+V@msm%]i??b懹'L I\\I`c~Ϥc<ؑmKDG?TPZʊ*TJSMa3[*SIz:n>}gJ?.k}Дja#KwwwHZ N18ouπ$'+95[%gHzzQ.S2YaD?˹ cr).h6-}Xz7Ubk[#]mS~g 46$Fŋ [nZЦMrW^A ;yyy ,hժkffB]MagP#G :[^lMJ M9Lr]r2Z>+0@GH_.cK粻Θ.eH?ҊlԊB$&&sH$o3K;0 |'OBa 4n=BILl:/IK| 䙝i^^IT$!]]rdOTn⒤oҲj}X7E @ 6.: : : y{ : y  00003Qqaaa3qD: QyRm׈  ظ333g @ @A@<{ ظ003GnnnD@hP<#33sƌSJ1}td޽}r?~~q7ׯe˖:::;v433yRTKKnݺf-V36g 0l g |Ɯ9sv2o/k4nx߾}rvvvڶ<Q =KJJJ`墢"++ ٳ2BӋ-ujvb1˗[XXر*WW 9p j1ZZrhihŢիX&:`/ʪ-*Z]xzYSl%i7b)GIxQIzZ-UGxFlllӦMI:GDD@g͚Uޒݛy=F>(<EOOO1xw]E)Z"heK-eѴIJJYҌ+nP iv6Uԉ;ߠ_K:|(gFr/ܹѸ0yĉ@BHjj*|58g*ߴiBOEiѢs͊6l"@4Aw0/WZ/P@ Q 3Xv-ۡؼy[n=o<@GjqVFԩ|J7 7fdq#``M62vܾ=Q|.EK\+k~J񌌌N:1=sAn QQQMʡCK\z*auFԠߨgL:$n"qqqꐌ/СCtt4.,@ r!ɪ356^z,  9Cf'O~ %aʕ$Bׯ;!*_(Cagg7{l٭Z(ȼo#e֯r~*5VpӀH>e UVR˗eήJ޻wZX@w,ܱA@)\HTk2:x;hر/ڷo_nذπ(ZI,dB}7rfౕSӧfKKK 9)P 356䧑%۷8qBS.'''99Y Xz5aގ"lOU;wbMUҸ@ȇ)*/߶MVŞkk w11(ܹSyB+.^ۧr~*Ϩ πaܤWBq;-axT1`ڛꚙA8TW%5VghaC\Tw}rW`<"+W;ׯXҹn3K*2<:?9fIʝV=7 t CBBNBB=nnq-[Ijg/rlRss4mDAQx"),,,aqbb"ד*t"Q\\)#k7?5V-ϨEZv@"$>$:Z׉HZugpB@@#G*[\"""uW^a{رs)n\]<Qk=-#>@Aya @`E@@<yy:  س`EAA@@@@<yy:   gA4` aag4LG09 N  03g @QjWy:Lw r3g 3fL)/ܾ}{J9TBzzƍײeK;ݼySrjjen@EÇwssS&@A <y n3g]l|A歟,jXXX=_~jƍ۷ON999@QN5Rw0`C<y76mڔk0WYפw޽IΛ7oChG3'OLniJ:n8Rp&@ZX#___???De?^װmryՊ%^nw w1dZիWvڱc 4M=ZPPg/N^we|}fm6dK]Cr~x@ ovõa=b " PTHZ,y [qr-F/w+#@D؀ޭUVS;v,H 9s{ ^455Tѝ;wNCWW7..˗'NbnnBHjj*|58g*~kqy-KXYy:̇0U+ؗ\BƼձ|'^3y2-?=K*̔؝X\n=T_jK\y>c+IebSrY8ٜ,H$m!g j(lVXA:5pLHH`jٳhٲePPUWz\۶m& ^wO<ɌUV?7#iZӧO'iӦ1S{.Wh֗&0Tq͛7666 #G>|X& G%PIF%toц_K&Wo }>S34r!<Qsaڵ㧮]˗/5kFn͜9" k֬133۽{ٳgǏOοEFF߿W^րh"_R?lX[[oݺEg2CQFXa,զ:g|S|L!4FV~PqjAtH.N !g@dⷶT҄|gh0jUP$5LSM<y*ظq8ROO/%%l2rcǎt~͛_x'T6Mp1V仯1tO?ļE׭[s%)hooզʚg|S֭[200.4364/O >}I'Dv |m۩ mUY2썰'yv5,5<Qa###SN̾9A/_SCYYYW^͛7w֍M01uT0\ũ3 bC̻4Kׯ@>tPӎ~޽\mYx:̇0U+B777]v>}~y_:XaGcϧmsTUvTHry&ٽaCXQ\l ;vо/^Sh߾}?a:be}Ն Hb!R| #k׮)Ӈ]f%|ti T3Ver);򽬯BUlFѰ(7F6 T(n}733;wnΝ =zԹ0&lQF3fj zץ1Mg|S]yiRRRdkk{MW!^^ N爤W7R!f ="@(wJvs~x6Ҫ\$LAW<Qsa#))vӦMST'+Cvv6Y$ؤIw!`РAՆ MŌaÆȠSdHJD0H&'z3a>@⮿Mnn.Sx-3< .:\Sb nMtFs"9B^HKv|o(PWƧFCacɒ%Dm@߿OX[[!>={ ۵kGSRĕ+WhV훗ܴ&{3aTq… @)b1Sˆ5yw`N'MH{ !sݵ)f V{jɎQFhh(]羚sNoooI&l200S;]vuss;v,v=11Q6N:/=QҴ 'RMϐC???{{{CM g4<7.ŋX?Q#u\vrjʎFxbSXA%l&3u.lvڥ%1U9r=2J4]R=SA)T!sr"0MN7l79x>33@2ձb2qIOWrj Jx^]|@vX"YͰT=KqDi,׵ YZ發'yk݈t:6HGO'Pz#ŋ7nƲt_@͇_~ENÃ@cnnM7ljW^988ؔڵkroRZQs'ZNVKWr//ڰkJ@ٴ8k䲋< Dͅ Nptt/xB~g g jgDFFB<<ij;wkqqq={0`IӦMi366nܸ# !r2- Af]ZTA&MGnӦMf͔Rv-y=3Yi&7f6uwi"Oo|dy}wa[ 5̵ h3wPw4`T?A@yfOOODB$@M[lݻw||}tuuMMM9aS-D")S 0]i\TZ8uعt ЖÔ*Tl=DʇQVe#ŁqRz |&M \Qsq]Si)qgWΥ9yyy324W 9x tqq166?~|@t۷Kzxxյlq I%L@ 4jHnMZwdO۟8(qҕOuM^0AZco[gh02).h^:3rss!BE42j+5ٴ,XЪU+ﺺfff\S[oy qQ5$4;"+W;Ӫa(5#|ٴDav<׽8lA@()))*Tr(,,!rbbbeT5TDjW6h Ô&% R+;:D{&'ί;@ @zgQy: : <aM@@@@@ ,00 Dр]A g )6.: <<<<@= Y3aa ظ0l D,b8XԴ\TTbee`={TBӋ-ujvXѣ7PHHȁRSS-,,vZshE(mE,feUB狖[][|vXcO9DNI>UJDǎJӔ7gњ5E˖[<<Q<#??6mtAu,SGGg&&&M6S <ظq#F۷/˴ؠPhԨ[ 4si``ФIѣ۴iӬY3ggZrI|`OM!#F:bؖ7V0Є׺TvX}OڴݫNHy< 4sHuy-0k1d`D'ng g jg( $~~~X޲eK޽oxBTС> j0L(KӚ?>d&˴ؠPXZZBԧg.\ХK֭[7N)HNN677^ i}אhc]ޛha;w |~2*6" !߼QvRq/YaT Q_Zx9A7R`fgHRR gϒfd\wdfg#@ @!q~ZMEEEUVÇD 4mtĉeDҧO]]]SSSNvXT |gVQD")S222Ο?g(ԩSyҥ:340*6pz%!!G ~7/k[ۯթvve~@S ~PhaN /5SR;'B@+x@_o,<0ۻh J̎j:J H#F_ߒ0Kyt &MzeA g Pχ>r-geehb„ Lu ҮFFFA׮] pvTQ ٳg%e˖igl޼y[7o@ PqH:Oa 7FAZ?d0DP&q{;*(DD.!\U!ܾ=Q|.EKvy SU'O _nʕ+Ipޯ_?wwwBXZ>o s嚟cvЁܹ`'agg7{lЪU+[[ۺ30ӧAZ.  _,vvU,PjT ޠ)\k~ &OwRgIؽ,t؁<<QWx;wk2Ftrroڴ nnnիWPa aSXX8W򓐐ШQUVj޼`'Ae:30e]۶Bx`:y ܸA"&V:Њ)~Dqʏ$)Iuz_N3XʼngΝ]pA@}+rZ;'@M9dUG]]:zPqBv8T6!|Y9r%66Vt @,yFQ9dUʕ߉=p?t|̈*]iYyyy ,hժꚙsmz0E!v*~vGj蓻roaTEQgΙ4,sE,w\v]%  Dwd0***11yU-NG$EFFʏ .wo߾=Ǐ_"==}ƍkٲNǎn޼T955Ҳ[n٢EÇi ,,l٤;@@ gOmw___5cƃhO?1ouܹsI4:s! ta3T:ubA`zrDEEщC1^ =֭[7oܭ[76a„*ԩSA>rNoDWw!::yfiP3a>@A g Px;vо/^Sh߾}տa:be}Ն Hb!(--o!ay59>}k֬/.]9 MUk0 3g6ƈ\ ŭfffsܹsaG:0֤-8j(0cƌVZA@ @@&@ gÞE$Q+W`2nڷ|g}C.]U"@AA g 8tW6TgW_uvu9dEe;;;m۬0 3gpM6% <""UD>k֬5ݻwo͛P.qGLɓ'[mڴ7hf=0 3g}ѢE|2ZXX ŮgϞuvv rNNν{Ο?1'''Nc\P.]z92$))Hlmmi׮]LQFDO#F j@`@ijj 3y`##;w05!4.n\\˗/'NH\BTz3jpΜ9Ti&"ix-Z0 hf}0 3g}`ŊSq 7 ={؋-[Q<}}}gm6>>jyɓ̘Xjs=Rj5}t"6m3w֤ty ڵkGGZ]v%ߗ/_.Q6k֌ܚ9s&D106%2׬Ycff{nwwgώ?Uܿ^ȭЈE>|XammMSuߟYR Gce"xMڬ/<ty ՏCظq8ROO/%%l2rcǎt.͛_x'T6MFў?fx]O?1ouܹsI4:טz3a>LA g P=ldddtԉw3r/E':ʺz*[nݼysn݈ڄ SN e\\:1#))/ :tͼK~z( DC{֌z3a>@A g Px;vо/^Sh߾}տa:Me}Ն Hb!(--o!atx59>}k֬/.]9 Mif}0 3g6ƈ\ ŭfffsܹsaG:0.-8j(0cƌVZA4ޞd׆3a 3gh7lvڥ%1U9r=2J4]RzW3Le2_-(a t0 Zt?BBBNBB=lŋ7n cY//"Aj 177OKKӶg4$A g P+lpB@@#G*[]?(888DDD0#_1;vܹs?VlA9 <yƿ^#(;@4A g a<<<<<@<<@ @`@@@@@@ Ϩ<р]A g W&@AA g 0l g 33ag 3g> @J"=z+HԷ\TTbee`={dff*U O^h[gBBB8X ؾ}… mmmЊÔ\R",ۓY%Ϯ, n[!ڳab$dj/-9LA' öƞz<<Q<իWvڱcgnڴѣXٳ΀LLL6myؤ.\ҥK֭ǍWHZ,;{b"yeghaN5B.eXR\öB ,Эu4.Wcظ{ Ų\!yX,-)s@ @&x捍͝;w#G>|XM4Z >|H%F'N$O>VMMMaZD")Sddd?^)TZl?~<9ZtQ x0{"Aq'XUToVM-ӆF"64%pUF} MŦ\2ȇ&  Dm|LϞ=ݻw>Հ/Hx?K~{cϑvU8  Dm򌜜'N@sN0D 'O\gsww!LA};|>HΝˉgh#ʵo>0gEGGɫWvjhhX<& +# {M1e 'P ̉gh#ʵ/~5.2=Z<oǎ'xIIIPP3g46h:997mC&Xz5NPNaa\e0ɉgh#uQ{yy1˗/!}IQ<&&$KTʏ=5qqL pAO@E :oիD7'7!TՓWRb[<+ Ń DXVD I6$=qC\~ٗ3*Yw]Gׂ}Z3Ic6_L۝͘389Gz󧸸zmb}g¬l//,Ӊrsȓr}^e`ӧ111xers#|1.@tfe7{Ⱥ]d/I@:\ 9Y/20t^S{/1g 3qrFff&8 k6FZZ]xxŹ ~~~5]]]ұ=gWU__}%''3CCCI!l{ls $ &{~ 0Q{ELg]ɗ/9Ǿ{gW?.0!x~93g'&&Դ߻w<ȑ#(%ɬYA%%%'Ntvvf_:)//=T5,,dK_+==/#+**VXǏ1gU0$Ygo2_U.Et(iX9;uLUYxїUMO}q\[|VE{݊`a/PB3=~4i$\nveQFಧN'W^ Iu8]gݺuYEffȑ#ϟo1gܸq# $X^N;胟3*m\놞CqJw ]gN&ׯ3:n$:ᮣSp}m;vL6A9jdҥsMuJ]S(ik#ziK s"Z8s $###YFaNnٲ? !C,^ش4&OloopB!t wR 00p?۲e޽{!9/dNN9C=/^|7R)\^\b g?}(S.p֡:8ۆ!yWg]fŜa!|qɼ< DqQ #7SRRmހ ,ˣZKOQ,X`СBNRR,ya]~cmEV0WIFdUT-}&TCW<|7ƬS-B)zF(ǜ`@;g1؆Ve6k+WH$-C PXXH<]~=4޼yShpԡ(ח˻p-1gw~Ν|A+ ucޛl3ӻN|4,E˯Qo))pp>`s~g)ۨ3FDDh/ҢEaaa@tVVִiAoXN~~>sqq152bVҗU9#&&&00 )nϐXWj>)xOwScbX_C䆾/uZkO%qF~\.gǫAA9rvn D̜<|> o߾e`ÇY#d2u[Bcuu5:jz%E^"lٲCrf`IX^Ĝ1h<p4ݾkt0OQSóbھ/YV_7^κs_aЗU97339ôA4MSSٳgyQ޿?,f>Y^^^YY&3whlooHб# 7׮]qA@a^"@*]ZXLg5NPxKm`h>HA-Lf o {0^#u`^93hz=mddj[t`ee%(yzz/wuuHٳ=.|dر𾼼\A9s!D+],UUe4t񄧧@:OYw:7_w.zk1y_$t΀1^gs6 s"rPTyoze1ǃ oذAYjamiie;vxFrc<<᠟;fR1uLtz֭BpuZœJݿo蹣MW^Nt s"rK+,,;rGH$fߛRb TSSSRR2qDggg0yስ:$I8gA_:FO&yaP $%%9997qOIrUHTsKKc^V_VF⎾c)ԃ39|vIΝ;ɋrHHsf- )JU::n9cW|/YfذatҥKY-&fFξ/_s(z./X 8ghq25*G0rvR#C93*Z'6KVWWW7440@+$kkk==g^00Bժ6гSrիR98 30gT*T'i{ G3o7}ɹu4iRgziii|'OW_}=-sVWW/[̽N+W߇ر_h1Uk~itwy*:|pp'NDիW{yy2e|P>(,,+\gϞC闀Z)((N6---_V~W8p  kP~ =??4t'0$ r" Ppk taÆ/Вu ܺu޽˷~&}G}D@[-Сݭao߾}s˗/'pG*++G#ȑ#1cpg͚c@XXСCW\/LLLcu L?y'5.YdG8A_S6uNmm-/kSLˤ\.箎_j ڵ x zP+ G@~GbŊ88ޞ+V*1NR  7n`] YR"23܉Y5`|UǏL<^% ᆶw9}>:`k۶mp![˶-gΜIBɖlST*!U!~ms^SSPM {trEp9~8: X:u*ji&(K\ʓ /_}KkPp ϟ?mD/)f͂ӧO?a5_7߯ (* J m p5 D5Jݨx1|R>K.ܒuK3ׯo&}C~?&@JLlS}mtO> 89aÆ]i*rA@osrr`~#= С7Ce2tj?SqpFЕgx 5]v-Y.p:s޽{simFn аpʢE$ pCs9~i/s (,WX4~Ҡ&pG~ZAǐpa 4r߾}WZ+&0?&]V¹ -ҴpF8p }o =f_ʶK \ћno`i>*^S?#HZôZôIZΓ&M7վ_ds/\p<CG?ᶱ~YVVe.=_HP СSw P~'y))@GqĈ@E:$Ɏ;(GP( BP(: B( BP(BPt B!Q( @GP(: B( BP( Qjat0:(@7SAؘ9:t씈 F@G!20::tDFBcDd0:tv΃ mN`tPtݍ m!#Lbt0:(:.FI5d5O4ZF@GwNYO7_ϱ밈kF@ȸ%DY˵e FA#;eTEL K"z.1|EF@GwNfTQr54P\c0:~KQ4F@R[ȿV5_Jo1:;ГŌhZL9ct0::nE$}ҥJ\[`t0:(:.FF]b0:~#A!бS"2P: ;%"A#Q F@Gd`t0:(z`tPGnt4y/ ѹϣ бS"20:蚋ZMKmVt$RڣR'h12MZ-;}%i/5lћmVXHtQkk4X qm"{f!&Hlk~- FދPɿRnLx].E^494tjhr}qlYm9\ob-~믦16(Ȇ*+㑁ܓ1*n,H dd $p|׌gV. y ,PƫZ3+UPI&*$Wv);5wU`n3gT$CI(]\6!\tJTBKP+BTvJ~;=P)#5mQ[5+֛[&?{Wk<ܰ 5KϔdYeD#My|XS8j?ܴ. pҤ={+M-iO9R/Hfd DN)\VدGi1:{#:f]S]|:{\;ͅ!g|IZ'oR`䌜&7cr:%\Wg'Bwܺh-m)irb̈_kB.+`ttŏ@}~\%Zzb3Vn$(wi(kkDY\nB[?ƪ4_R$\B3 [+[? Q 6~- F瞉Y@7 kN]D Y9T. Ohl}mzN[&7mr:%{7G_QP!@Yɭ/U4eKeO`]83wz(-v,aeZ=2j.Ůo# 2td2w6yc&G ˬ1)MNܪMs71W݀0lkJ>^*W-J(-v,a ADFs/E,4 ߨހLmsu赥LCM2qk3FцC.g.7S… Έ1oUp%PKcȎД$lRmk)d`t0:Xt:ya?ROItmxKC% >_Xi@78793wJU`i?Ljk6?'PV]W6j(Рv~- FދY@gG]~O%s<CF&rw`#Q]\>I}=y3tsdprN"yrKʪ&vhL>$\hv'J̾Z^% ,l\:eZ_W0:{1:Z}*^rHށP!G|Si6 \N)p_~>[9Kζ\~( eYm^M` MԖ4" =7 `tMbR{Y )6s]3e[2?'|Қ׼ҲN'Fn̢ՙmFN@at|)n>Z0`t0CG#20:`t(s;eIIɖ-[cccf\n݆  v =x`:'ߊ[u(ৣFZ?=~m;$w*/xO>D7E ~D}:`E;JF5eJgދ3zu&@ ڽ{7Y/++_d ?|8qT*MYh/7//!00X [OǐT.BFşvoam)K}Om'@^.G ҪiGAy"y ta˟\^W&8~/w<4.O1$EK8O# 'uC&.\=\ [T!yص taÕ !nq@__߱crCBBzA4!݆4ee˖cǎ taˣF?>ws`oZZZ'=46y^3ido@ M,M)kЅV*]E+?g,Ѕ-J|e/s' U]$hy#ߊ$c7JEn@2JhʚtatB}.X [~u偯κy^^@dӓ8ggggn=&&nժU4e9=o߾mT)ta˃ z% ߱cG'Adx.>s><[):bgҪ4e9=oDEί @<(lFw.{.cf3:fskh;iXtJx6kЅ-iʟ}Tez-3DHk_W-K~H(, ^$ۦ*%@]❀ŗ)CYJ&]2\6An"-)}}}GV7VΝKˇ` (RC ងIIILYYYFmXNLL 'd|x¬g)FpZ%V]$/9$LJi@ޒ%7o@7rbik }d`gABgG򀦶a&-]Mf7rOєA`Z-#N4{Lv)So/1o@7rZF;>wʭ?3_YyOcnNz>}\$M knn.68hРz:<<:##cM3ݺu(-Lp|ѢE` 2Vg;ɠ*Xsk.|OSV?:w5do[n+"ʹ8(_tvuriXX0:<^Tade"5mg"ҔSvAj&d-rt3-T WRX ;Snܸ֖-ŋC!޽{HHMY=A~cbbhO״!J=wZ"cc^mSmא:{<~Z-ltb:m9}4$O&eOHΦ)'HGSFJ״!JDgxVOtx KMMm~$PzĈ$% SRR={,M 5蔖ɑ]tٺu+eWt3)b 5,HrIf @CeSz ʞIՆ tJ.Q[oltt* x+I2K (S%P6fM 5蔖ɑno?yvCWf۶mWxrRR9p@BQYY2qDʲ}֬Yyyy5zh777 eF"##\N8[&xٳ| }Ktbl'l&[TU RERYroEeaIG'mt2: KdADe:W[NuSb@~v=[T>ޥ돩ԵՇ, ?tB_7e-P %Mq XT[&ZtR[e*:%M-ݺu JOO:t(l?laa!p\(hee5m4; ,nr+VoFjD0tA=ܡgF׋e eeMHrӎءm²"W-93kY<:@4`"$2(ΌFk+eenˀBA7wQ; , ˯/ocO{+W 2ph=K>J'S=~%8I4_]M q$N@I ^Tj(++k׮Y 8I42CKݏ*L=RI ^-K7wpyG[f>$­w0p^.Ii$Ѱn5 {'~D^˥tt|hbploݺ_~555$[[oD>$<~ݥ'{#8I4޽{w2322,8JۤIdn=Lk5;Itph}\>~- t$'oIDѹ ~/)o$IAGr` ;(vC:N ⥥_mmڵk- $NNxѮa{lN ڙ k̎Yo8~nNDÆ [ɜg&Lx- $>:|]$:)oeD_Xa_8I4gyС?vX',=8c/D'yeDsg|mMvN@w4qh+W;%%\Tkׂ8K!'[^kXBUTtphzgיRphw!;S$|P `z=vگ_?lvNͳ 0ḠQ Nͷ )0H;=ߏ[Z޾º&&|2,cAdP4I4` 򥷴ihr((ݪazg:3#ѹ뢃 бS"20:]|(9E1CGa`@Gd`t0:(: Q)(Bd`t0:{ %%%[l WWffu6lPXXKyJHH0,Y2\X.((o "DQ%_pEG79uW#6E#X`IjܒPzҸ6lo}tU`'& d ByǂѩO#1B}|DdGyLop˷_*斴 KT%Y2\X.-W,wJzv={:;;{{{wذa¬<<)},ƾmQ37}2()@ "ꦑ_d ?|8qT*MYD suuupp 4–yfPqw?{tuMYr~n=s9h~oVMSVg$~$E{5–*S2qnKc?pqQiQ7deufL-취B Akw3–w".T2〾cǎ>у-;;d4ee˖bއn9uQZߓAc5K1Ѳ7HƚXFS TV/X#3}FėQG[8V$!ڍRX2JhʚtatBmЍ:WVG8naC}3g3cggj*Ёƾmү @?$kkk ő_o7˩Ϝc홴*s3MY@Oc߶HӟQR)(7 ţ;!S>}[ߪCO| MY@Oc߶Hӟѩ̒qweeenڴ2ydoooX3f 0)KXNNNͧjM~M:=/2}{t!{ݔx.{=1I354e ,v^j>PmHӟѳrڲ"d5N䀟R/2Om:ZYtݗo>PkkuGzB)}}}GV7Yܹsp,X@SET*UQQ`tȐ!ܓ0)))S)++(-M,gffZYYk+eenˀnoox磕5FB/X/,de] |+H@ #Ds933keT&A1hJMZ)ns5DzT#ðYz[jBM qkeRCntKvJTgF sE;%"AcaDd`t0:t:  F@oC0:Ac9 Jv @Ga!бscGctP%%%[l WWffu6lyJHH0,Yn϶h֮]P(, tT}j:}VmUHopYMR&!qI>lY^VfuGǀeρ_~V!:(] ={:;;{{{wذaMޞfmmѫWd]v2dKf̘A ~Vjggg ZK}}}G_X?{D!9SYdsfӟ_UXon (Xr7W׫t:o^ 2qn9{{%Kfcc 88qp.3chayyy]زnSrwZ?Sǔ5Hn"!'^J9E,z^/W/4I?6–A^ihw _g ѣΆt&&&Ҕ5~+++-[&MxgӧOЪHKB׋'c\Hd]/SU\#h7–k/εktP{萱zzzr̙̭٭Z,to[kЅ-3g@srr:!cMܺ:.NAw4e.3wUJ&]زŎf~\tC:Deeenڴ? +1c0 3x`莎ɩCү @믏7nQFu%00)/UdaL6zU>A0#KiK#`W:ES5–KK'?-{d8݃?F#hm(V7N+s%Ç_`MYIKKSTEEE!Cpc)))S)++(-/"@<88LP~jjY?㵰t/, 咱.ߢ) "OT*mq1`T2j$769vLޢm_"ͱ,*@a!v@WS:ިիWjXOOOann.0nРA4ety%nݺenW^yϷ6`>@Wϯ1>k,E )ڋtÏڬ,ڵz 0neI9*@G#Лhƍm9-^X??6SwBSVOߘ5mEҥKx NNNeڼY?kTx/M`.TGGեj}Ui t/d7h6"lYl&[XŇ"F٥6?gmm=b))) ʞ={ ta˻vOe^z_ނ@Wm*P{T#z>I\  (#)l ioЯ@?̈'c2q~_E#5 l۶mWx&zV*Q(...y fʫ=ze2 sNp.'Nj-xy䑪*Kk@zmf&)J젳BTU,eY.gҧ'#E8- ֙kYJK)Ń4<@@G#u@4\v֍2(==}СS-,,nv ZYYM6aF~+V02Çj;::o):@4`bo/:.I!>3i`YmQpSd ˃2__ԈBx>6̎_u!Ֆ8K@G#Щ1$F7$Ι>n_s,^Ê91a3|mQ)PS69teioԵOtP{N tBctPt:*FBw`Fᬕ3tf蘡tDFB#:@tBK@/))ٲeKppplly333׭[aÆB.{x: D`Vnl3U֩ӵmvjCߴEEzj5 KaBo203>:@G#u={tvv۷aY[[{yyyxxՋ큦l׮] Ҡ3fП_;ՆE@W#R̙⁏K\ [E}͘!_?nEF/[dsfӟ_UXo[4hYt:]D&M#good~ncc 88qfa.3chayyy]زp;?#ꦑk"=~.NRg%u "\Vg$~Icc.lYt:]_cǎ>уidggC eiʚta˖-&u*I7W{ٯ*t{2ͅԕ-%9@TU)W|H$&!t#B}3g3cggj*ƾmү @7hY:d=Ã[Wʼn;(l#rc߶H,Pg:Deeenڴ2ydoooX3f 0)Khmm O9Ԛ(tlY3吽ù-fd٫Wt #9B4,?mm>Pkk Z3@35j77̝; >|4eAP$--MRF = 2"ʹ,Pg]7:ҩS}`ׂdhʂ;רJ-.JF䞄;&y^oEiYt:QWӧիW===k2 AhK:##cM3jo@o-ق@Wϯ1>k,E )ڋtq sIkk-LÄS~[zXnt:^7niŐEDDZݽ{zԟƯiC.[ڼY?9rqR& Wᾪ4e /QGS PZnt:UXX]jjj#z#F ,(XY,Nk2)-Xg]uCS͏Skd?,PVGRز):dЯ@bt:_l۶ ODJr>>> e"7Ჰ}֬YyuwYYYGvss_an)22ĉ^]]me:wOϦ99 OOQG/;gA,hiiԘoYt:]Dӛ%[nyӇ !?~|qq1eBf.]մiJJi$X|r+VoYt 0ҷK$OJ4T`){}bA[/SZJ ~!<~mP~@G#Щ1$F7$Ι>n_s,VNr.ȈECM6;k@G#Qm֪{#:(:[@G!tBd Qnt:'B=A!1CV`B#:@&{KJJlli^umذPc?ŁQG38LuC39z,;Ϩ ٜ G&` [ x6mD#{=i,YOmll ''N8`U,eufL-7//!00X [&ڹsg޽E"Ł32qn9)'"!'^J9EΌIj&=T]r=ϣvLjt:^__߱crCBBzA4!݆4ee˖bއNsFƍӻ2Ypȅ/\)eGɘ67m&%9@TU)W|H$&挤ֻ2!'qΜ9zLLݪUhr@zEJ&ݠgς+WzMM M:d=Ã[Wʼn;(l#rc߶H\{dĐh?D8gff~r'}9d55lcC7o{XF#註(l7:@tlU@΍9E1:(: B( BP(BPt Bu?ڢcjmtIENDB`backintime-1.5.4/doc/manual/src/_images/rule_older_than_n_weeks.png000066400000000000000000001673241477034762000254620ustar00rootroot00000000000000PNG  IHDR>msBITOIDATx XW><0~ę8: %1#&D L D"1MbA1*(FFd_DdEdk6wdn\,ͦxSO?sϭ:=UuI"DR'D!BP"D!B"D!E"DuHFFƉN"Duz!ͻw655U7[yׯ477?~X Bm~FA 766s\//׋fϞ>2yGWK}ݗuuuFB 9Ϋ.8q"|rr2KLL|mիǏs G 3 2>kѢE:::ӧOŋ~헐I[`o!##m۶W(¾>ekkkee5-G ^67Ɗ&M;m4JB]DƘ &555Tq.ahOxx8S\\,.uBJ_~Wvvv555D]{MȽ`/ox٨룏>'cE]p= %%]v"RPȕ+WОohϖ-[`1HiaR͛77'H6Q /uhkkkhhPN:{-](b޹sgLL 䣟9&[WW~.hii[H;])((1۷oJƏ?#~N<644X[[Yfɒ%!jӫݽ{._|EVV]R Ɓݵkuɓf?f͚n>`wP][LKKC'i0so02XJn̙3G@ƹPWNN֭[a"u۷^ӦM~ADcoFuu5$\?vzڦ6 |MHΝ 3S))) ,.9~8?OT7o˗Ϟ= djaL:|j +pP 3f)@v횉 A6Ӿ+WpmC4a`---}yzX`hסU@X?]ŋ:tWwޅ&-\ʜ钇b/0e.H[ ^p.ag1e AK63s?/o%0[z5N_UYYR/2_ G 6?C9P<ȫA]a,&'' /u}(\Thz@σ&:#u&\hpp }:OB]Q\޲wޑ.@Quނ J]pB UBYYYPB\< v.?o&U9sxw̙!yfRRR0tU'eQVQ` 3. _ … p3,]̙3ƿ˦Mpz(up۶m0!zW`ph|KꂁCݾ}_)+>ܸq#MH׆ࢅ4hժUӧOp_+RaIݣFyPMM }۷og+ R-sx(uVJ9QO=bw,8va_z:C.B]0+.u'(**FGG{.;wX [$Q> {v9ϟ?pJ^xU[h.oʡMLLNp(ؗ233yBB*BG-V566B 054|hmX__5kexEA ",oii F?E޽{DF dwPy]{aQUU駟N2 QV pC?yKȨ *a$Kn(vq~@?@C ]f 945$$!+Ν;"hŌ N6mHꍡ+uA%''L~0ܹsZZZU/^ ݋ӓGo@eees1j Cԅ,=[(@S7A}8/u?QB2k, B/A+EJ.Ռ.H ZZd :;Pá.=P UX%T!E49A… a V|}}g̘q%)@ g+\ 2]  JJJ%a'l%%%_g@ % 1Po _ɨ )]g0 m[o!Rl+ε0h?Sadyx Y(|0ulнS fcc/u}ߨ0;(uQ.UOQI&0RȐ#pB~VWW" U-*? B Dp]̾L_#m2}@>đzC2|_raɑRfiW/Ǐ߽{777w[~~~^rPƃ0&Z50̄Q!l4."Du!E"R䄾B"!BB]D!BP"D!B"D!E"Du!B"!BB]D!BP"D!B"D!E"Du!B"cOyEM&p{ uω2t&K 7.$ nB]XFMP;w~$ nB]Ė"***С/ō7GbU۶mXp+>\\\L/S3 nB]$˗/=}~ʹ:h".@`DF0a»  u4))wYl޽{%7oJ>~x4 u,|&8M~&5u=w}>w?P&//{e =Z맰p(#̙S^^>PII(8VlpڼV%v n+71.6^jzleXՅ5k@Ma~oo1ˈRbh}۶mC?7x6P<,wv WnB]cL](+? ݵk*###>%]<>m n+7.---gn\r5k_AAL2%)) sG{1 B^_矩 `ƌI1e0n66i n7.}}}jpQŲ֮]+--MUTTܷoE='bۛz ɛo@/Go 9s>j n+7.qUVVJ\fX$99gcD$;;͛߯g` nB]V.$ nB]XFMP."$!p!5lE7=&%scs&7 Mz87M&p" =|8knSW>n{KGFn'V{1^ ^[`;%fA{{lpBR~&b;+Lyq *-^-kgxKu{K^^~|>8_;F[۽ζjsot?-qu2] /V=Ch׷]P#XF&p_0o.BkrA㧭M_qBKbJVhk/m +՛P[wݹ#;we96į&s_~ȑ#4qss\mmmcc箛p>hm#x QO{vK杜w[:u뵄$m--?q`c[~ᶘs뗵p/fnêV89^vG. yC`i&# h6r ̭^SX՚G@fX/zqB_"x{"8 ^7ehU+"A^+X}<Ι6P[[ч0B׹:ͻ8pXY9d,]oGNO saJG4 纷#viL{li{Z`(8 꺧hXJT n:![uWN@XV/C#'n7/oiOŹ]b.]t} b ^-ot sG@wDtv(`O> SD c)4BvL+v0 Q[B⺶u|y.]7y#~Jt_lk=)<ڰUЊ}<=zu<#:I!>>ȑ#?>~۷*Gcbb-,,|X #fӞj7Ѱ{ GrnQAxI-]3<v!M"mz.N1en7{ᖐ8_ܶ^} ().iwv sQNYȽَbMͼ4~J8ٯsTDMwO:xv``H ))):70o{hpdȁ,q}tƁ~\.8:;eXK =_SpvވXnKzu=C]~ݕ@r&d>Gaa+_7JxJfaI[?K> Mo_綴SYpn'''_[[;tכ94lӲ=8꺉 n=E8[@hSp#iW x6Пt|kfn>f TцŎ0M&p$pKumҦ> u'tG7^r1@6&LȺX^nm7;#qg{߅{^n~U dڒ?玎f( ss5j2]8_(:;YzYpD~.׭Vp<m3ŏ:=?n(-!udK]@T/{aE (ۮ8O0oms sCQx0h9k NA8"C3!Xl3 qy7ͭ'y  Q[BBN L/w-zuyIyPﻉd/@VwdՊ!o[eϭ—y> +[{M'Q8~TMm]. v Zo +16h@ +n73R4i o2z /Z *VH?w\tʱ Q&3c@ɨk(^ ٦.IHHnll .Bؑ˧ syiM!.o9E?M8r/uP ,))戌|d[r:_~`uB-Rt(Ln7e|x87*!pp$M`"p ܄EB27M%5" q7.2.#0 nu87en7P+w~MbM& Zcc#{yE{{p9wYYիW?t{{bI߹.Hjj.AwG"ܜwg].LxzC}\ Ѯc/+خ9d5`;PV?#T~Y{XWdvEm!fҨjM+ vArJ<#ذ7U;P̈́m4324i$UUU]]iӦTVV ;::ȬYfٲe'O וVVV^B6l؀H fff 6mZn,tf摈e wI,mՐ-Q^_5c-O5w/ 1NhE+w%'(r^Ztw{L_] GQWq$p3څOKR겻A) Pi*‚5XCS*3/xzm 4:v߭ .B Zl75#:Tӥf63Lk1$$ˮ7IzجüFm˷#P;b G!a CGE2L{ 5a,)cB>U! R(A8C.fpPpT$-Å2+o "{lZP.* iI02Lkݻw/++j&2j+//RLf͛UUUuheeKQ0Pi^.8/ڼv2E\Ʋ;ho{=Ր-:8\ֻVWpt)|$`QמNI{77مS^6 gqS]ybuݤ `'%h/&o6 z^5%.(΋qab @sEjϊ+tuua~[ ̙3GQ׼yddd ?~!ٳg\ZZojX6"psj!׹uv /9wLlptu TS`Aq_.И&Ξd[ Aiz$J2* 5ᕕ-O+[lAϟc]Px<"eeeꍾ}$##Ӯp!ˌ3nܸAby632<Ncmj+oXmfyBw;z^~,=as%=" *ym-@E~K,7 Y1g`]sUf^q=h2Pk7B.K{9+=ݞtÇ o@"ivU7]}D^m[W h3snVdnW(9z#RN1A`-7L] +[v Z^~MЏx~63Lk;==6`PvttTTT` @dŠ+"!vΝ}vzy555|bh3s/a,[ލ~Oxj, ڈR(qX7ݹ'X%t+>u1L=Tm0Rc@dŠ+"qeQP!v7rs[񩋡5cFu33CK.1;7svv~JtΚ5KOOTWW/YDGGSzFFŋ5440;.є)Sdz3̷\KĆ;%i}.tpY~=0tuKB u"0uaA̾&a2%.܌v-.M^V/ml 6H|5!6q->{bb^;nkkn0: U\%|3 ˻;f˿Yw bL.̷\31vnmccccoo "_8q"A!ijj`L0֮][VV' v9p!¬5LlC !:ӗ^KP.:6" ͰJZ+1uZ*{&x(2NplL?qgiI{O)\\8X3}FrvsE`'AlZ0u+j[{4vNOGT׷ ]0z XHaVf u sK,  <Jútqׅc26OCsd_O3ܝH [$h][czC± 0/nu[ Sym-ilA%pBBVXPZ݄n* T3¹_*s&7 Mz87M&p" qnn7.B]DH,#B&p꒤׈B&p=܄ȸD&pIE.$ nB]㛺x<^II /Ĺq,#p ܄ƦjjXUUOβW?~ۛ.ϟ/*UYߏ&b5.Hjj.Z6ec7jY׽éIIzu{C}\ Ѯc/+خ9d5m.l)7-U V?#Q%=,+2EntjiTJ Ħx 9%ulX {;Ck FF.q .Pl B;ӤITUUuuuMRYYI/(##f͚e˖M<GWZZZYYy ٰa~삘)((lڴiݺup2͛hLD,mLbilэ= Jn28ݒXsYPJ{+dI!Z6D(l|Su?ziZ]…7|J-?y,LD󍻡UC{< 6roG,5vm˾Ivaghwg r#Ig{Ej9bV搄W3rLs{xx ;:: @/]tawnsss4cg׬JJJv'(rrrM3gx<]D]pMJ!v!{SHISJJ*'Cg.W\zkmmX6p?q@s9vvrWQz" JwGptuyI7]ހQRgV, Pi*‚{6;譵;nv`=Fs9vvˆ61$(&nM!kj{0" Kpv!{F.CI;]g <_y m 5<v̙ή/o9rƆl9;;_|9<<\dߺ۷oCb@ήԨM;;;yyy333Q;b GQQH,f?ٿ?Npǘnv۟rfýBV랛n߸e!ie8C.fp* i=7K.,NuI܏?N~ 4XUKK (d Tqɇ>z...:{[[ .@RrnoV^Mmn޼YUUZEQQF8uA.]4}/ڼv%m$88XFFm$ba=jjUx]+8u]fh.3>Է5Iw6]'A6;?mh@?*|ݧ8u]fh'3E&Am3%qeK]u չ !@9+77Ғrϟ>|:hAuP':/^XBWWV~m@0g]D] ,Q,څsٳg5bKm3%~g}^I9\yIJ➱nna7S0箞I .y,Hr 4& 'H.>Oks,v8ljϮV7|a/t~rXw"? L7?2]1-7`[$ RIF/=uI܍%%% `0ȢG(9w\LL\NNNwE-Z~B[[[OOVlق͟?ǎ8~ll,ǃHYYz/,,le\5c %%%Aی$==]JJՑec wMm÷=0v_#; . Iۊ[+~BV2DdhǴ\5w=p3? NSonBh~>>+ LȽɺAϳɼ&V=v*)m.@3~Q85cDNOSeHk V4@GW}=GWD2 k!&NK,Uu8v]C3j|KHLTJ N͘m30B]<1.]t֭gϞ-MMM _\pႂ+CchhR#Df] /<abddD/~zgnsUU<=X6pSIG 1|xЭP+!AҴcZ *ǂѮJQu/ö+܌m>gi3q7+2[g+Ag [h&@ f}xH/&sb~\oas7o( Fg~y+Ww 7EӓzhPvttTTT[0… Qޏ?b`MLLfsݾ};}FNHUյ`VԶhtE.ߟo`Kw c? ¬vN-}.Lijj߬|Sbs0ăzCW,KOO]8v!!c0 IJN$O- 1!Ou؅X\ 75܂NHk%hdc R.qׅcŠ&tSq>hY~Un+7A&7M\$ĹI,#p ܄^^#JMp"2M&YHsXF&p u"Bb7PqnM&E.$ nB]/m566.++zǽ蒞nooy8~4  vARSSvIVVXz>>>,h,9WϺ]Nͧիzѧ /+خ9d5`.)e9qwu}otAxO^M2G7:4*ZbJj']:6,}e "]B2:u effB,--͖a74i$UUU]]iӦTVV ;::ȬYfٲe'O וVVV^B6l؀H fff 6mZnl_Wm3ۂ ̙p~mDchÝgK[5dniWWr{}1ƚz'"_WS]'KB Ѳ!G1خd[bAK߯`mb[q]=A{zq<}':o L"ipзnG,5vm˾Qagh09呤ヽ"LZn2h6}>;wN /\pΝ5gnn!^IIi׮]8.'' љ9s&5;<=B.5g+P.* iI0E͉P5y~pǘgcʳZ; R(XݡP]8 SZ8*ݻ͉PU|mk7فB3qv4{V)pFlZP.* iI0E5PUZ~͠0~ )'O>|ѣGOvqqwnoV^Mmn޼YUUZgXVVV8uxfhI___yڵӧӧ69r$$$@EI,Y#V~Q Bok~G.` ql<[}?3>Է5Iw6pthS77hCj=Q{W>ѥ H/3E3OF=/&o6 z^W IV-yFk;77Ғn7d sŋwtu6~[ ̙3GQ׼yddd +3ˠvdeeu$&AmW_}tu-Zh„ Pˆ7rgQXvNz&I68|*L p#}zA.И&Ξd[ +oX3sG:uV8{߅(=/m?lv0Y]Լv~u?Pϐ2MlDzLYxE{W@\53sJGsAbGIk24qө~Y[[O:5; l6BB<>6}|GW@dݠd^YJ[pb]s(:|[_iNm{XܾRNOSeHk V4@G\o8"YX 4L6!O&Tյu i.!;]RJpjfn=k:zLpnoogV&fs`HAAJ!144tssMHPdeeptE/Kk,vUTT嵴 alff=޽eR^NJO'tABa4EKӎ튣+ wk%P8 nF*Fֽ pfd ܁w?>>fEfx7!9 6!A2qs Hal࠯A„G=Ќ/(P׈;wzz:x3u (Ow09::***FGG- !##pB#菬tE$88tq:ܹsoN/O] my󦜜GKKɓ!Xa,~n)z7I?^$㩱0h#J}GV pǁnbm:܌vo؞` ЭEr^Z-ɬwx'oGg$oI`ƮCz?ȊAWD@7Cna^7-ZSCC Mܨ7>8e`%?oR.]Dwn.{IKJJ́ OiA6k,===S]]dL]o`` /fpSL <3b>۶m,ox㍚1e w. 3!~f}- 1ԉ0ԅ1rp7/\#K\Z],"^)l.@l>%Ww[eS{ oՏ!`[RG-f?{&V!QUB/~+ٮon&d]B2"1-5emӿ%|W}3P(9pdq68}NN볔[ZZ-00P 9`&NHrdr`'Ap`L0֮][VV' v9!¬vnͣc;>}赔 ncC;! Sg:(Jy2-Tv`/yt …{n~jOi8X>}Ƨ] i6L݊}`L8{ia$Rzm5[/=M$5  $6 $O"bJ]]]zz± Yϧ9\vwf@0D^I;<H'к}:5?X"VG"1FqlY኷޵JK0_gf-st!Ń[6?!ήg~_/GZP 3r).E@~9.y2I??!Lkspncǎ={IIITuKKK*RCyj&/(Κجqn(\9Ԟ+VJVVo-̙cbbh`޼y222`q镙eP:{KKKmHIJS \ng[o!̹gdh`^24 7ҧWziIKϓn1?Ξ=[RR ;Ӳ999g"]YYSNC@gьg655G]` yMfe{)+NCiHIJ1;iMCZqX!8c'ptEy&1 ݠd^YJ[pb]svl)5(y ьzotOZc&IDV@W5 ].!;]RJpjJ u չ!^;BzQX/,,鋛իW;#ɜ… TCCC0 X,abddD/~z#\r*Ft{Hw t+ GWZ+XXp3U 7Jwض{ŀ[6Y:=Mt hf$1@Ᏸ`kpl~<'ƛPP;%%|J/ hYY!v1t{J܎}… Qޏ?a`MLLfsݾ};>uI摈ecw-[FW? d<5mDz?AW@76 nFs7lOwV|꒸Q9z<ɩ0`ƮCz?AWD@7Cna^7-ZSm&5TNHH^7ygAJCC p8p Plun?䜝҄r\YPuu%Kttt0uaAnn.gdd,^XCCCM2.r@lmm|||0-<leyi9?{ZK-\>oGz8jnݒC#L]o/Ih:!q_h"eaNfv)̷$n8m7ؼܒ:j(Ou5qZԅ?]*_VV]GL,^kk组dD&c[PP}C9hffwN QĉbqUUC\VĉP Y4HSSfݢ" &ڵkѸS sss`/yyyiiӧC"YP<l1O_&z-BؐNH4þ*i-jRjkL8b=]0aK%>HpB .7* o`=,vB&SGc+(ttDu}+~0^߸kfCi3:7@QSScQ0 GKOO]8vaLfMat$?++ yM^6'^~}ߗfϞ*}79p7Mk>퇝/sjjjB%K,9p={P"/][A"p ܄u ~~رnggG8xyf~9e:7ؽ%NNN0lvQQљ3gjkkݻwQ׿DJCw!M&p^TUUEwLMM~XA%)i Zsoذ111,P%˖-DΝ;r nxP;?OLL|7a]__Jh?  lN:]ȉ!AUqӧO2Àkҥ~!`%ѯm,#p ܄utТEкuc„ .\0Qkkkth֭N5en7Px{!ȿ;uppx!7߽{7l?2yyy ߣTWW,Cw?SXX8SPms)//œdbbBU-$ nB]ぺl6|ժU-[`EWW~׬YeJJJ(7o,#rKm۶ D;@`3%%b[dn7@]0~AY?Oa z~kT7Dn!]pНÇ0u)) / R555ӦMC5X,n7I] gFq jrŋ?~=zիT=8eDAB1@[8RTT|zƍ⩩_}.TiBʘ޲yfTG{ cM&5NKKK ?6c˕+WPpYfQʔ)Sˈ8wqqw*ty -iܞM&p'ԥO `3<<򕠠 XVVڵkcc2}H4qX6{{{S0!y7T汌M&p%_???770H%.3, ^1c+l 7Mk<87*!p!E27MPˈ"E2"n"B&p=܄pqlD&p_!I&0 nB]"!MbM&r^$ 77766Ç#jիǏr}˧۟?HMj']Գ]%V/HTTTeeŲQS}5\>noȳv;UR!ue~QX#]s6Fg][;.ᮮo#(=Q߷|~Y{XWdvEm!fҨjM+ vArJ<#ذ7U 8CkҥK׮]x񢕕 ᪸>9''I&N6MEEE$d;::ȬYfٲe'O וVVV^B6l؀ vA6mڴn:YYY jm3H[[ۛoyщe wI,mՐ-Q^/nxj{YɬwB+u=Օ~$- NU^)d4-.=Xp߼;ѹ|nh`O"!vTRc_ۛƮ~j? X6pǘnv> @LLLfggás]x1KJJJիWS7oVUUY,.E]@bu]4/ڼv%m΄ʟ>} PgGGHDz;ho{=Ր-:8\ֻVWpt)|$*QמNI96*Z+CpC~]8hCj=Q{W>ѥ 'V0Mʪz}^~1y`5I}ۜQPS:Nnkky󦅅Cxx8s܇8o)Хr*=+VՅ~[ ̙3GQ׼yddd AٳHn@,wErrrqqq# nN-:s{nna7S0箞I .yxj,93ٓl $V' w#ҊIp6p Mu2!V :?9s..K] 6UC 4ec$W*ɨ6ty[j^5tn$'O/эʂHkΜ93,έh"=zzzeTw؁ *<HYYz/,,le =p!֌3nܸAbХ(@Gu1拂6{ߦLEH8+($&o+n*R F_XEH%!ӮC;p! 5J>+oX3s+E[Ͱwkw!s=icfg S+08]Pί|Tgꍾr0%Ӯ{x5^e׃&smm#vFĹIIIhOKK V>}zXzԩٽ)@g%g٦8"# L6!O#p==uUy7\󶶶RRR~~~853]jjjFF Wd7zVi }vc!x~׭~>>+ L``nPl2,U8vO]9w:|[_iNmLw.liW?5p;?}{O _X!/:{"dҙki"KU]+]L֮dtJ)͗R ;n7s usw#LC}?88x}W(166t %"$^`!vUTT嵴֯_yɒ%^[`:eTG\rWz=;D;+(ܭp,%Z;lb=@y:h02 ܬl0xHn:?C$%n8"0A#6!6ω@mj²:e,z={֭[ԡ~f`sttTTT[CFFf…(AGY1tϜܹsoN/O] m{!Ё`ܹsԃe w-[FW? d<5mDz?ȊAW8MMǂ\ ,{ [hY FxRܷr3xSշ$0RcAdŠ+"qeQ4f~s97SCy` -! `zFkz ??*6jjj`‚zZyiGWcǎzg2 '/dr`'Aqu{&LRRRk׮-++`K^^^ZZzHaV;Rg] w!h2k)='ױ!ˁi}UZ[R3Sz...:][[ .@Rrn3V^Mmn޼YUUZEQQF8uAr<]4󤯯/ڼvө/m%bHIJ1;ho{N?Ր-:8\ֻVWpt)&v̓Iɵg}>oknqw ywv=Vz9*ZTǕOqt)&v̓QO'9[M| u չ !@S\KKKџ?~ajfЂP h3//߹N9.^HYb.dee`Μ9&&&8͛'##,X@Y (++ g j*{#nN-s{go!̹gdk^24 7ҧWziI&2n1w]~6gPSa:?9s%GQAߥƮ4O,:2qֱH&2K=_B]CuFpǒW``CHd١"s~;w.&m.'''ggg"w-ZDA+[lAϟc]tg?66 LPsjxkƌJJJNC9ߑec wMm÷=0_#; . Iۊ[+~BV2DdhǴ\5w=p3<gp 6;{O\F B%U+%هz/!6Ld/Ǵ{tͽWy\PΗPPȑ#0;|~~~DD7э;Ne{{{%s[[[O:5; l6B&RZc誜#|CeHyF<Op;?}{O _X!訷ID],O: yҵ4Ǯkh&UMCkc?KHNr>>;BlTeyi9?{ZK-\>oGz8jnݒC#L]o/IIk~ 7]KSU :<~-Ƨ$3ߒ|ܐhQ /@Gymv:x.bTq0/~+ٮon&d]B2`">52%5 ΝI[C_ׇ0F k~a?E[8q"hɐNHG455Zԅ!!p @QJJjڵeee}`L{KKKO>)jr#FCeR* O YtD3쫒JLݢ (塶6ʴS-OYZҞ}>D !83}ˍ NHGUյ`VԶhtE.ߟo`Kw c? ¬v(KkS 3hoo7kC" yK_]Hlv~~>72ݱ)䩰E?ֵ57. K{ ܂NHk%hdc R.qׅcŠ&tsoX=~Un+7A&7M\$ĹI,#p ܄u!M87M&pz z+!n7{MLn7d]"!MbM&EeDnB]C|6uG 6_$^seeeW^=~75]ϟ?_TT$rYߏ&b.Hjj.ʒˡI~tG(6ܜwg]. ynsZ*Df/+خ9d5H7ůy|]]GPzģ"j>^)w̮m9ĬZRB-ib.HNIgrIR MuLkĉT܌MshiҤIӦMSQQvttYfͲe&O+--lذ vA6mڴn:YYY|s={&re wI,mՐ-Q^_.Ǽ[2k^c2Њx|]iOu廟, 1Dˆŀ{`BPmo=.Y/MKb-T<5=t]+))ڵTAR6uttfΜI uuyyyIBf)tO)%%\uu3fٳ/u1}:}闺kX6pGmOZg+z* .E]@~9.bQמNI<.ܐ|g3ׯ Gz\G.` qlNԓ~1y`5e_bPPǎcww$*pú%O<5͂Lj͊ bCYbngwo@ 3g .yȀ ЧWfABoSٳH.--M>kX6psj!׹uv /9wLlptu TS`AFʃ=]1Y/M`=ɶ@riybu1ieƌJJJ7nܠ1<(u1<l,1_3fߦLEH8+ljQHlM VZ T|-İ&"KFC>]lwB`k|V(Aq Q[myQp`ϕhX zYQbAj^u[;y PѺ}2MlDzLYE{W@\5J] 5sÐ ܑ<|?8{lIIIvv6ln"BWq8wee%s[[[O: wBqf-gϞmjj+"=dh>BlԩS@* [[[)))???摈ecw+z=>h 8c'ptE~ TL J}M5 )+J9kd[_iN\x{Š%4'qtE$ mB6s-0Mdkű RhP%*ffbPP5#kKGzaa!DOܮ^JWߩLI.\PPPxcccHw (lBR%++kgg+"Kk,vUTT嵴֯_?5D,sY )^#>>>85ʳ.~z]]N#F\3!~Df}- 1ԉ0ԅ1r3%.܌v-.M^V/ml !H,;@WփdXkkĩy 9_l^nItfg:ꚸ[`.FW /~+ٮon&d]B2"N+X @+9 85sC0G33sj`'NXZZNa 'R 4HSSfݢ" &ڵkѸS sssyyyiiӧCY-:t摈e w!Dg2k)E?ncC.;! Sg:(Jy2-Tvyt Å'fXdsn`EsE?E!m kԭm ;]?Q]ߊ' v1p7Ʈ`AKm"mo N̈́ܘiAMM F؂qtqׅcHf磛(߿/##SNa9rbsrrPU8eDh/.wYt)#Y$ nB]ぺN<+$$DJJj˖-0D3(v&⯿*2)Cw4 _,AөVxxde^XF&p urssC9s~۷`Yfo׿4i*K._|Ge(>tТEкuc„ .\0y}bM&5޽{~}Ȼw L^^(1Н?D+p`xTۜ9s%+:27Mk׫BnF]h(j , 9KV$SΩ&vr–rzR}>மo#(=Q߷|~Y{XWdvEm!fҨjM+ vArJ<#ذ7H 5 $n[G/m7-ZZZ.]dmm}ڵ/ZYYAsrr4iiTTT*++edd֬Ylٲɓ'JKK+++/y!6l? fff 6mZn~|>ܹsϞ=y<@ ezb٨gK[5dniWWrk{u{-O5w/ 1NhE߃}{3>_Wu>[`Gn2qsMn={jF.e5C! }e(ӄaF#""x<~8ͩJJJv'UrrrTM3gR-aE%A0ۅ N!%%mzzzJII ]uu3fٳ/uȕ+Wlb٨(2N]IGI$Ua4WoEU& ܌v!{FI(TC- bЭ3|IK]p%S8ہ84;m2q'U&nTM!kj{]1" K*CB]\6C wU6\\@]so[%">řP08իW;*r\\\`ŨNȼmmm켻ǃD___MMڄJQDYHPPP.F CGύlM2L]0Npǘnvloik||P$܃QWpy1©_/GZP 3r).E]@ <:.b'VSkX&Ʈln޼iaa!8N[ t\ jϊ+tuua%++s111E5o< `#ādP@c{( >> 3(psj!׹uv /9wLlptu HbAq_.И&0d[ <>g1ܵ ugS{v 5u/,OsEԥHbo~Y1;dP@cZ&nI@ryԵ>|. Iiii@@ɓ'˽;::Dn,TVV@Zs̙aqn}}EEӃ-[ ϟc]Px@E[aaa+HFF] f̘t s͘ԕ.%%3 l1_w6fn+z5?`Ga]!E!5)<~[qk%PO*WF, v݁ fQYynƚ1+!OC-:eýBw;z^~,=as%= *ym-@E~BL,7 Y1g-]sUf^q=h2׌I]P^}KJnqnBRRedd$icc1wwӧOs[[[O:5; l6h Z{fϞmjj+"=dh$>3SN] o5okk 4S3&u}":G>w+z=>h/vMy&P0Y7(y6D*خ@W;x-hƯ4 fL:J8{i Š%>>zotOZ `2 yҵ4Ǯkh&UMCkW\B2fRJpjƤ.E~''ggg{Cw .(((PB1;nnn^@v8lWEEȈ^^KKkuðJ^^ɍZ,%sY )^#>a &́奥OfNvp!I***F'6!D Y4H3쫒JLݢ (塶6ʴS-OYZҞ}>Ha9D#*I, NX"8}F9d9Ҡm6AUu--=;]AQ}#[.p`=]u,HpICͰ\Z7 B]#B] f EK^ooo[VdP&5>VX(!IOO]8v†)8&Cqw–rInkLo]8v؍ͥ|pZ-~YSR.qׅcH;rPא{ܘ#0 Wn҃Ĺ Ln7PHsXF&p u$F7=&Ee&7M.r&M&p"E2"n7!Zcc#{k*U|.++zǽ/%==ɫpth(V;삤풬, :D̀sF#nN;dz{S_v ynsWEFQK`yxplWw}X $SMf@9wu}otAx%.=,+2>yntjiTJ ĦN 9%ulX %`MC+4u 233!VVVfKK˰srr4iiTTT*++edd֬Ylٲɓ''#TWZZZYYy ٰa~#삘)((lڴiݺu~i ΝSTT C3X6pߙV ٢{*^w̻%㩱e;&ޡOF#B]#׏aY8|pI}}}OUe6> }Py,P.nn-I[?Lc{ˠ$= QyB3qGw՞7@ >6 Gw(lBJDeI]wr mYwOZXXP5+//MT1s.D}nq絺ǂ>WC ` q8 Wί|TgꝽr0%Ӯ{x5^eEјf|{Fع!#9A<לԩS{ f!g655G]`2 yM΂S;é=0Iw+z !n, 8p?&>&RZc誜#CeHyFԌI]x{i ŠhnO'Hfa-P0ڄzp0 ܬlPrF<$7bW Z&nn8"PE#6!6k3"5ΝLJ;w||oGz8jnݒC#L]o/XwC5BąѮEڥ)*͖$Sw `zP um8g4 C/6/Zyymv:x.bTq0/~+ٮon&d]B2"N+X @+9 8gDkĝ[8v}>''GY---a(ȗ'NH5<99 i&\-EEE=&LE))kז ]0ann%///--=}tH0.;Cph:pB/RZulr`'Aa_VbTLTE)Qej1.0%ҒTJpwD ˡ`>q7Dpˍ NHUյ`VԶhtE.ߟo`Kw c? U%Ŷ6r7u s3Hss3󟥚 _nd*<)Ф.@Bl6;??K+ w–rInkLo]8v؍ͥ|{xnG(k%85Hh ]8v +JMQPh_$/9M~&=HD&p u87en7PKkD^ !p nB]d\F`"p $" qnn7.B]DH,#B&pljRদ&ؤ'wx͕]zԗ钞noo"ѩiuh(V;삤풬, :47u=:BlT_Ϳs׫BnF]h(j , 9KVc$psjIh6ḲV?#Q_v՞zLC̺ѩQ)%V*V;yFa)(?5 $4%QB]m'N"rTTl:;;9''I&N6MEE^QFFf͚5˖-|)8w\\ttt\x̙3=JHH8q (O=zٳl6.3f͛UUUuheeKQ0dxm^vmOl_Ck8x{PSX)(o_ 1x]D]} l͏> jhL # H.^>'5ԅE՝;wbbbRSSa'}C#G߿Ownj n 8έh" mmm===Xٲe z5;v袦xixkƌJJJ7nܠ1QXc(hSg̮Mk4ؑpGWԢؚH'[a+#MD|L[3|(Q7c/u!.D}nqEǂ>Wc-` q8 Wί|Tg-Ąr0%Ӯ{x5^e׃&s̈́ƒ`Hp>|={$;;v67 ŅnooO=qJL綶:u*>ZBs̞=GWD=zv&I6}S ,RRR~~~85l5fpg8M"׳ Hk  ">6}|GW@dݠd^YJ[pb]s3vl)5(_6+@/hZBs}=GWD2 k &IDV@W5 |%$C}KTJ N̈́ƒ ^;BJ8z(Nիt˔d}W(166t&$Uvvv8"m, Ckii_Ua86pSIG 1|xЭPF $U^vlW]Q[+ XXp3U 7Jwض{_c7+2[g+AxCRe+"x?zkٮA_?o }PPWJJ 4^!Q4pXXرcǨ{Pjj訨ݷap!,\>(Y1Hpp0&&&tݹsn߾^^MM1;wA2 6t#+]Q@76 nFs7lOwWFQ9z<ɩ0`ƮC GV "^58lw/w;i:P+@] F F Mp2ܐ39;;? upYf遡%K`~\XXxf0ۅ32e \ *Ϻ %Xpw `q/ ɰ^ֈst 9_l^nIPSt=^[G]wuL]Ũ*{e_XQo0uM]̈́r൶vKHLdr1 KpBh%Tzc (:7K{{|43;&8q℥% "_8q"E? ɐNH455_a-**0a(JII]+1.077>}:$B8;C{WűDp$JQ?橐pP1O#佸$jb C/1"Fwq "(2;303)iizA9^Vץnwu26geS_Rj\r Ani_X-t72usIn. enoաA5R:oY8϶w*Gns(Q,|Q0hE,>~;duVo`"2&׈ov}EYFL6gQTVV́-_~dYu}].[PP@n*nz+ݭT@HTwټ. @X@wlV}f䩰 dKyT{\! 7[(]ILs&t7[Mnt7 ; s#n7ontww7Jo}Jv9B۷/&;;F뙙dy.t7J-HANNNOuCĄ~7H^Zilĉܹs|.]"xxx4&##122HI ~ =ڵk=z1bld.\ ] ep8yyy(6i4lƍd>`?ʕ+#C5222ruumQ k:unnndmFCvaM2.YDc@& ˮ^JF]v1r*MϜ9PJ Ӟ={;wl҅FBt DEE_~!I2jom6rO>ae˖9::&pUF z3a„v;9ݍ҅@j#u9͛###Gݱcv i߿=ÇLCqƑ f|ŋIi+))#g۳tQ(]mA\.1yJ^^^w?J0]~-4w ٞ>}z/G4ӧO Lxå ݍ҅@j ܄ӧMOO_p!v g͚EՋ03:ؤs˗aǎө0֦---IԥPqotQ(]mAP>֭vIGSٛ7o‘x6i4V_[>}Qw_r! ɨxݣӠ/,0Dwt!Pڂt>;.u/=IgccC>UХKׯOeEEEL Z?*J|u``t1Փt%K~ D}m%Ӄ*;UdW8~~&ytlJHh7P۷_*fYVApH$iK]..n\dP⪪?311ꐌbpj͛7aEŅڅBLMM]ȇ\mt1ۅQ!ԃaYC |>YSXCI^BOϺ$&׃Cɹ\Nb g!ȫӛraYXYY@Pl Wܹs]r $^|kר݃S111[lFqq1{.8cرiӜdss+VKI(ӧOujfDu`ee LRI^!֩ьBj[v=5k䭓.XN lNc/D]?WJ]..n\&yfza{ QZZ 1 udԨQ^^^;l0Bѯ_sKkFFF`A; h9166 iu.fznEYҸ8oѤI*wO8]P ,dHE7 p[X6HvANx-A)%յ_)]vQPqǏ;~z Heee>&**E:2b'4h̙l KzzT*-**If!ZJj.m޼̌ gφ# ))266gWx]<akooW_ӻO07 +vtv~P|?_v̚%ۿuDɫ C4]y1EOm Cf(](]ݸL{b4]F8@z%QXssK;%0IBȊ!>ŀv 0c zz.fzVv4!uͥK)yIBȊ!TISyM0czW-"]vQP:pX,^n]jjjyy9+++a;88zZo߾7J$.((Xz /A2鮤D L&&&0ƿMUTT8;;{C3'OWV:Օe0ۅҥKZZ\5~XX\!v|@ݻwC/Շt!fq~OggS?%J0hDTY<~˼p\E@r ݄doUwϝt>jj#Jvl~,öh 0h T!6l:Ϟ=  . }uΝ;!ﯿ[;k,бcG:edd@!qssϽf[XXСCh``D 삉 P/SSSCCC+++X ŲeS՚vP] QpD8z94gU5ðO~ vdϠ^^7s]?YgwBW҅҅Ѝ˨8y B!WWWk O>7O/=@@{]lC Bn g]oU jQaS yNu+*[ EBB4ڌ9t{% ; I.t7 ҅vCtIonJuW"P`DBwc!PP(]nJ ݍ҅$J z; Czz˗>|WsO<_vmJJ 6m*,sޣGpv ` ʊV#Wkq -Y8WRSFtDk4"BvUH7Hmi֓1oǏNҩ vUgܑn ?9::PT_ger].$dlH$ںukHHHBB–-[VX$[YYs@Н:urrr򲴴/++'522?~GΝO>>s-&NȾ v ,0332eqppp -?j( "_}KWkgC!4oG(/'&$,&NʪYyU$;Q}VM}%$?SES[VH H7Oo˜]^~ i\|>Emh/"悂JKK9Μ9sA UdӳwTMڿjl7Lo>旼xb``H}#QO՚,,2~_[IA' s^"]PCf>~K=pL~~K ^3 x,ʖv7HW||<\6RRR(>}RvSN “'On۶-11QPᦦbsrr 'N`9l΂P!ԃaYJvttvuznq4&׃T7˅JHi6y#]v,L˚VCJ`57+;tt!t2`Ґ;w2۷o.= ><ݹs5k4>4'! ;v,;m4'''j;99|ŊlR: `eeE}X9%Tb@@*]|}h -;tu՚5lIX {u%&)ľN% $׉PZy..DSL&ٳ*22̙3(.[3$d˖-ԑQFyyyFnna E~Ν&/E2Th.1(e`` HQCkP1cė.]U^eeH#OE&{#ܕ ``ɂ@6yt >Pe` }yef4jĆRhHvf |>^Kk~CBBe@Oǎ[~=QJJ .nQU I???GGG`RȈ#|||`ߟ<4h̙3@tT f!4pvA A9ή]S) (Z~ڵC ur|[/pPIs1%̙䱖Y7l4}R*&>8f!V;"N mԮt&B-}me{vSSrui^W3(IiDCWUԵo/JJ\F ˯_|7XrYHHŽ3IrA[[ɫ7nПAJ U0ݰazID뫯:}4ԙ [ὮVswڵ>bu"SɒqTԂ@ͭ s#4~UJ@^\Fm}Ѣ9%qH%n^ٳ:(](]sA\\܎;e7o633tٳ!( HJJ"&''if+&Lh~7o^>}^Iַ۷{td,}V&4&M^M ..VE0ifg'zzѢϧ6d  +["]nJݶznO5bcc/ <(d~C^ {a+0<@tyzF^J)9(](]ݸL,[.555@[ېh9\1 o@UUU666>>>ٓ69/``"((*vVX3K|駝:u Fߛnnz?K %5ArQZCB@࢚aL秨-f0%?zzpxvPY%+&zg͒kMREBBexFټ_ ,>I+<<;;iUe a-((^m"E-u7O¦ yNu+*uw7CɪڊnJW6c݄^@N} ݍ@BBt!(]e&t7҅$J &u[t7҅g7-(]ؘ..J ҅҅@Bt!P-%&&~ן~;nJJ(//_ҥK5NS[liA}yrfuӧhm.8q"92w&_ťKH!`_|EAAlX;.t7J-H?@:k`:bq194.\`dd0 "pHQlhpƍ|~ NǕ+W>G8tQ(]mG֯_Our8dم6ɸd54t.z*w5## ΦgΜi(%J v+))t(?:88/ۭ[7SN$om6rO>ae˖9::&pUF ҅FBtq:w̓Gرw}C 4gYsٸqGs (,^֯_.t7J-K%?&Oa ?SC߲Lq ӧ7BIeiii(]n.JW[O0} .$ӎYH^z.ИcF4t.|2aرc:U0v+++---I(]n.JW[. ygݺunpp0IhCy& aFcmx_y秡|>ڵ -++/$/C`AUTT*ҥKaѣS(]6"]; A ھ};IgccC733#]t~:4\VTTԳgOr$((eVjP1#Gl҅FBt°{ϟ8qJmhhH577/4FUjZZǎY9%%FЫWH(]n.JW۔.]󧦦&%%59M ##Hm޽/^z=Awt!P!ڕt!P(]eent7 ҅@Btt!P(].[t7҅6l݄^@N} ݍ@j$--'ۉtQ(]s !!!7ndcɓ'k׮MIINiӦBSy=Jujh5rssump%%%PaX:՚VvFDVm"SyO>~wN`Wu֭߻k3RR?Ft#ڹsʕ+#iHJJҩ̧OFu޾866h;w>}4vvvε8q"3,Xlʔ)-U2@LL9҃ZGZݲ~Yzx&M8;)鉥 {}^^7sGh` '~/+:ݲ*4JKccYޑ?z҅@j.޽ݻlr89sЃ*Ȯg޽R)D߄2ۅ .!33۷ //%>:00u-Y,%eQVk+ T8!"ÜH&Ԑ.Do+5oTx]R‘#,Z҅@/lNNN޺u )P(lQsqqvMMM}ȇ\mt1ۅQ!ԃSJ |>YqM.[/ Pby=8侙˅ :4͑.fp:5*/WTj/ ?Q(]2wʕ+W޼yQ￁ゃrN\QرciӦ999QP+䥤 tӧ:5]+MHHzEKH^ Q׷NfzxP۲CYWY&otŊgtjfDW{u%&)xL b\(A֬Yjժ(@d3 233uRHlB5jl6 ;w.Dhdd|Y6HvAlA)AܹR%.j}w+ "QGDx&MR( G+ l8}2 Rsi. %(d""ݻ-U2Jl+hx\WKtaMQ&QGF֠AfΜ&/KҢ" ;;;jbZZ-ܭFFFFnY[[s8]vQY뒮w8_2cDLujLXK,6yUPJJ͕+JT^\ !pBB>wNO^;5Q͛@ APY2J Q\_1$ЕBBB,,,՟y a >Y"EΟ?M^ ܸq삒]Vilnذ䪤kjj RSS_xPOZߧ%t!Pb.577hBGV y5pI{56 lw3f̠wqqa)]^Q.iB=KS, \:C^M18{a+07F ==YJWW҅@j%.zH$e.\ 5^ \a[L&&&;vMCMM[CUU666>>>`ٓ69/yE~ku7LyS:ճ!zŪ 6~wHnQP˺u낃)?awǎ0שS''''///KKK{{2zX##{xxtܙqy k1qDdgϞ4Yh,X`ff6e___ccchy}KWk[o<BѤI|>g'E}ɗ&$,&NʊqyUu9Q}lIM}%&' >٭h%?SES[Vt!M䲐 6BU!͉'mtdwȐ!?SZ^zA]>[/}}X! r_7imtdWkղ_׫RAJAJJB..u֯ $UQQ\v%*ٲeKTTԍ7^n:So߾ rw ٫Yr7cǎvMDm'''XM^Jt!{@FFFXBd?&$$XYYhO9F[W3Զ!{Ukְ[']b0doWE7p,QgIc/D]?҅҅Й˞={\zܼysׯ_/_NiAAeC %n)Ya1.dQRGFÆ S(;w.Dj7wӚuv666= s xݭ(+XGG}-4Iܻ'T(CKKKfh/M 쯬3$%d"Oݻ-nJW`*0J>|ʂd={j<Yr \FŴWhO9::G16#A͜9M^RtT )fZ`i7;;@csdd$,薵5ٵk^5[ZvǨS3gGD%M^UԒZ=Y* P3ϝ|LaiWjVsr8F,ݼ Tt~_[ٞ(]t|S F>˿[tttqq{P(T%&&ҳGDDP4%XXXܫ??}. O?>q%#ͬڵXڝ5kӵFKf @J Mr4O^֮-W/Zx?/OEf88H@ͭ P2:wVi뷱+ӵFKf4: JAԚ"]ͪk_@BBedv!P~$O׬YC24.ۼy+fϞ N@@U e2ccp6y5ulrSSSzT qww0a뵸[};WOJW(H wf͒ߧdҘh6y5Knj6vzT Y$nphSQP:sYff&P7$pZZիň_xevŀ7LB2Ȋ!N< y]ƦA zw1:0`ƌ#UZ҄{5.iW gM:>dC^ S@ޛ74HvUaSh(Rww3Yao=@ o ]z]Fփ`XH$ݻwQlt2?LLLvq(lll|||PEE' s^8>y|-w:Օe0% @  vBP(A[ !]n?xOY{ЬAT$EeX/+7W&H%k3% @ ꬒwϝS* fT9҅҅Й.^Qn&rrr.(u/_@ҕ@4zر#E倌 E Annn1-,,Сd400~ vOLuIc*06@LMM DcֹTعBIswMf&"p Q 3B"yW îf"??!K0U?1ųꡨ6hzkj$K~AFt b  *++y؂I]W6xyvvuKf1p܂rRA$/jʫr/99ƮB$R<ÇJ҅VC7W"P`DBwc!PP(]l7JVݍFt!҅@ J@ P@B %13XIENDB`backintime-1.5.4/doc/manual/src/_images/rule_older_than_n_years.png000066400000000000000000001503401477034762000254550ustar00rootroot00000000000000PNG  IHDR4 4sBITOИIDATx} \Gc j<."*ƘEIMTt=j *GTKP@.E@[>fan}ç{]~zM5!B"]L4"D!D"Dr"B"!BKN)))5WWWD!BDMrB8?|J/_e̙{dnt4id#H;!䤧Jү_Cᛎ\(sr***m[nݿ 1+ 4J޽OHHbcc_v.,,<W4BNr4i!C(:}>nܸ)N?ǿZZZk֬F1!cǎt侫Zٹo߾ ;vlII D: OX矣Ss)ķz޽{$ drQUr1226mGM>Hnذ!22ospPJڨQ'CVVVW\_ 4}Fe~q[n100Xv-M ¨テj8Q.kkk`)S@L7 }nn. `lٲ4L(hB+A~iTT]= w9r$q:Vo䔕:f9 * ``oVe* '5BmUvqF^xdQI!ҝiݨz@ےt---8:h {ADoτ.Hĉ ɓ'C_~~WÆ Ti̘1pǢ^z9Qr{=t??gϞ ENϟzA8ƿSN)x&~>x~4ݻw.]J %jEGmX1_v2r222;w˞9 AϞ=kgNvV G8wܳ Ӓ/{;kstr >|~NSEE\f̘I9`xwތ… ߡ crŘR?lӣ1_;pٲeoF߾}a,IzYf-Z;9^ZsU ,~ N_FN8BФ?YQI#'mZ[[ہD SYnT:dȐgb 5j9D3'UXjrh޼y99!a$EM;vlbsA'JNfffp0nMZZ An>_|λ}ĉ Fg@p1rmNN޺u~[mZ.8~_FN0~2rA|afmEN*9:u ƫ.8!*ļkj"݆`ܸqa0wEG_S%K@ЄK%rRO>:E;5 !Fի SiVZv-ůzKM +WtكWnn.Ԉz_Z(֗]p YSH:9 95_U znDDz5kۿ[mI-Ihȋݕ ۛЖ/0E/)Sjj**7A:+33J?31t_95xLMUWW`j999~'Z%'0r@]n{2Taaa9mU]i&h@1~諯zF/ -9tPwׯ`,0o3M/i (~/pwih|I߼yWn:9#%ȃ 5ZCs|#'șttt.^HoT0ӤIFIӒ5bogsLnݺEF%~! t믿` zIHR]:(qovedd@WNP@ O%%%M2]>}P !'OO!C"6\ bx/))הmUbbb E4`'LU3|3gual Bjﶉ_aǼy}8~[Vlذu]"??*( ,,~B/54W=rB5 J\9KK׈qz J(,ݘ)AyX,㏩u Mǽ;0AIE!r,? UN(L SRR{?Y`~@H]UEhB=AhPhy b9 G]_(?r|JNmqe.s̱T%5Q=Onv3r¿8N'Cϻ{oBBB\qq1#]U50qAm}H7'N@Vx"Dچr"BE`:a„ܼyBNDTTggg "DJ|+W0a!B"D!D"Dr"B"!BBND!B"D!Bȉ"Dr"B"D9!B"!B!'"D!B"D!Dt! = bBNuJ"]@)r%D 9M"@L!'"$r!!DȉD..@LȉS?4J@@˗Q3gf_߶m̙3'L0gΜ{(dɒɓ'IKK%⑋1_M 9o^t)zeʔ)TaaaAPK`vvv۷/]{/))~kF?gȐ! *ٹw^i]XM| į&Ąڷsàw*_:77wށ{7WZv 633P8p oߎj:{lP=k%-I5\@jBLȩG^WF-Z~VTT3xyyLIIٳg7||r8QP ׃)tt/9?B233Q֭[-[o>x'O...股+S㏨Mk[ۡz̙3;4W3!k@_M 9;9:::p믿S777# GQ2h ???K.)'0O؇:tɋ/SsjH---P!*ΆpQߏoI&jUOT%HՎ\Ɨ@jBLȩ#ټy3F@sAbyڵ gddPoƿ/p0jȐ!·~HqppgS?Vߜ8q6mU}xذa#F@ۡz6{PSΟ?_yEt)oQ q?H~ۮ_M 9u9Arao fff_F%0N+**SSS!tz<22>.۶m۪U`gڵukC2 W^3Ǐ> `L;,OSM#W&yX^"+WbBN00>q]QCF9{,5z믿BNRC3Fφ> %}jt뒒cccdmTyii)*^VV6jԨO>$,, Λ7H\\̙3g͚CaȆN{54Hd-lYROpc2L!WbBNDNϟ?GI4XL!bccL9-l͌FUrsssdM__???~Z >4 ht… (رcG$r*db:MtNYI ZG S?4 /ՄS .|@slٲ9zhoo_Qib~5֐XG/z;n8)w۶mv!Xl5ԩ.%r|r6l:D.PNx7 fhyφhaaA< oJvޭ<ݪ? 5첳$rIe[QMf [UM=mK ~5!&% Vr8C?pmtdO>SN @gCOz=([9P U6|M*DZӧ޽{SSS7mD ?=ckOC|Y+i.%rJQv' <jkkogCBv$_~jlz:O R]]]-cU;Ço={kqtNwA4O9×@jBLȩKSeD>SR] ...F'ܸq}Jɓ'þcgϞџϟ?:CŸ~IU;0233Wo0Fk8n\oK ~5!&q#龾...4%0Zquu}Ux}Uv$$$y{{7::Xvڽ{;(ru,_%rrH\DD9r"K &r"DD."b"9!@L &DM@L arҨswAS.@ &mJ:7K &r"7 $r!iCr{,յէ(jkKo2ɷKRJ[rU0ai@$~$0L&]H$-hIkub:j8uui՚ů~TV)S)d2$H<ɚ]p&ue!~8׬e_AUeߢ]^_-W ͓1TB94p*˄TZ]4c+/t4HKe ^-?\Cw-ouF BAz|Oa#D}q4p?ש b:.f/Q CTDꙍ%GG jeXW lWy1mP)+P! EȤRUQv͚9kte$w]: SFN"Ĭ@r͚@Z_+q[T@8=j'TjlMWJ5;Epܹ9L_Vt0Y'0u2 "PAY mU$'q?==N SϟZXR%99㎎*޺u˗&*U\mj[U΍\h.aviBD>B<ő+(VIVaoA8E~ն#(_0JEZ_ɡru-/kVakpgt#?ɧ_-U/m<!&'LÇ۷JUS}7554hرcKJJ'899iii-X`֬Y }G=|įږ]MŨ:>rin4ҿ4|۠s6/U4kZ6+d]?ϙA1[8ھ @hWmr?%n ͮ6N~=>f1}mC5p֖k1)E6^]?_{uįږ<|nLJ⧮B@ȩ:wee%cǎ׹wi&z illWp8|%Y@~ ."5*_-3>O$ieډڹApp0lM:7%SN~ETI 9i跭,O8Z "wM Z Wx@92(]MICmeybR'0w _i4jE".$ qt5!' J`iCBN;gV2 }OOO]]]] ***T~r``Tg=hɽ-M ';+}ϼslRLP!f~r`-iR=b$ڇP?>aasy9D] 5=oX~\8}UC)BNݲsCVqidܹ6ydL6j(KKK]DN|x;~x*kM,ϟ?ҥjUx55HFm=L gfwGx%i@hM,Ͽuiu+3d 󼈻l-aGZCSEdB|ƫK$#.E! A7y9NЯr](йsrr`_(⛂CGGŋ4WOH$9r,++2e1.WSRR>iӦaVYXF'3AceT1bob5eV$NaLT5厅qzL](*r7'a7ӂVB_M,z ĐYFerM*U,+~Í'Ē*hvw0uyG8 ߚ2: 9K箫ۧ$ |޽>!!a̘1P a~~>nnn.pkzO k_M,74~ro߾ŝ4W\w, uo=}BU[_@!$kK0usb/[ UQۯ&?ӨXXc }3B鹕_t !Xs8J[\!*(lвZW \ٵ+$zjJ&A:5ta$9iW555 DW 2HrE@,%s3U?'jbX PQE<&UIsXa!!n߹OV =bҦs b1!'rÐM"1BN\1ӫ՚Dp 1!'2"@p b9tnr"D  Ą >WZ4UXXxy;;;///jI $''?~ё[|iRY")**2~ͥ.]s#*,,;u.W^Ef񠯼{0· "U~ ,:.Ĭ\*GsžqYuO節G,*v Nnӂ'TRY")ւYjuLaJ/*u:mmmϜ9sʕ_ɓ/L9;;W__tРAcǎ-)i'''-- ̚5_~AAAѣ/,~AR.(;;,5iK.>|}=\r;FwVotc%fpʼ>mmBThSX틈!I2u?)5*Dk5kvK,G7fgfW V'B? ^3ҽ1}mC5p֖k1)E6^]?_{ug#,#+ kҚz;g2A_Su;w$%%}0SԮ]К{ ͮbv5yرCUrbhfОǏ_pagE.UT ^C㪲m;DO2t3мY*/ (]Mȉoɟ:ZB%rjAp RSE\R6y".A@QI8*W@(A ^DN^3]~wԊS'Ӆ S(&&&˗S66689ǨWL5S!S\K(&45ﬠ=BtϱI>Kp~99)_sRaj1([훖|lmj?QGVnqt)rQï~5''k59u&9ũmӧOS%s555ɓ'dQFYZZ"rk_ ɩky)df6l/9؉Kspi.WNs:li6ySO\&k3;_jO ᅣx~5$YqudfA+7/9 !_t 󼈻l-aGݽL,ŗ`ՐZf*V?x9 !NnnnhWLO4I"iW`gŊQ͸q֭[.)** {^^ѣゃ)IJJJ~[$'v˭^3HPPr썾to'F.&|-6dƬˊѣq_{xGW~awʟ@|ϫ-z;.8f]KƖRonkC\ {/ }*}~uMv y2L@jcl.=ѕUeK*@6M0X0c*VonkI)_@Nї%ѝ;<<ȑ#ΞQ/@dOOO n===+++]"{N18ZQX]TW[iUJ~[$'v*]kqSvn:tM:ujsPqFHY,,,\\\=.C'Nqj2y͡`h#*5b;)E&dh{ڧ_eB\[D1_M09$=>3F1%.@ʲ92 F~@1%(G!<'q M>mB 2?:beB\tdlWrbfYCsԿw_og|d8TpWE "#]~@tpLA:KxLUIsA,,Ke2G*ycHT?'j"@E\6$;7j1ALڔtn@L &DnҹI"B &Bȩ][H.@ &Q$"iX1N$rp D9r"B"1BNH" Ą95Iqq?C]|9skm۶͜9s„ sٻwoNNiK,q22m4.hyذa#F@@kn/ՄSGtn@oʅ'r|p:OMMTHl۶mVkת׭x ^zG㰏,XHVVjs///wEmW| į&Ą:sHm' z:gΜ˖-[Ќȑ#9`ӢŞokҭϭXG/z;n8)w۶mv2C z{{Cݻ<~ǓǓS%'[Qx(p8:<:ğ>} %NB3AR=z@魷?ф90ltTߪK#ˑQSE_ 1!.AN%hqqqpB^^Q6z6t dOHF hA9PU^/D|_ 1!.ANOWKQw,p )CCC'O ֳ={F<| '5yD_ 1!ܭJzzKpp051MIAAV\]]=zD޿e' nnn?h.h=/@Lȩ[r"D"@L &Dȉ\DD9r"B"@LȉH H.@ &Q\1@Lڔtn@L &DnҹI"B &Bȩso>^WWyyyD"?蘛.HxxxIIg >v옧P(lC EEE]!ri&aviBDRq <ő+(VUWqi|B_W;+y!zqZC,,- ˪k}"8$>IO*v NB.H P&](G,oC 'f 9u\d><|}T5ܷo_}}}SSA;A$NNNZZZ ,5kV~uA$ɰaUkGenn>a„_~,KR]]]h΍\)f_O#;+L÷ 1wms8e^r޶Y!y *וC,vsϮ "Rdy K~I}٭T%H8HOX XFc[.++xh%6WS䮩A+$jhv+=o!쀢(]Qfց`[ ?c*ԁrɟ:AXI\S;A J[KPfW4]]?oQI8HV PfVorUF[Nz%bBN9:7d&&&˗S6668$&&~uuu}=}]y𡇇GZ 5 Rɽ-M ';+}ϼslR,X͑C,ˤ@=d4s ƫQW v2!ϟFXܦC|dv/GbN)v~D]a'9<8.y +5"sȩӧOgLM1`2lԨQ8 sA:::<2իWCBh"I&k;vh=UxgL÷|r2Ylea]9{愮W@1AS\ X ٢&|cmbǓSWY׽g3l-aGZʄuA8GnM1kd4 ~]{@Q16Lȩ9zif vVX/7nݺu8%%% Ek:9S/BJt0NנON摻 KMB֘)oq_{xGDTa+oy(XO'yw-[ 7 .IS1{`zA=v X_Wߔ®=d<8/- pKP\NCk0X0c*_{@H$KeT,q>k2!FN|٠"{zz:b===+++>P^^ JRPP믿1bݻ5ܳ6y9 "{:/1VOvP.fSRu Q?4t[|+%nZv;w?I?۶mr&S^ʙon;EA2d~Gw (kie XL8e _-Ns=<>3CZTVakpgUuA⟕TjTůAʹOz &](GL;Sux[[3g\r_=ydMMJojj:hРc2½ւ f͚կ_?jM?݆5) ZkZJGt;~QFO0_~ȥ9 n4ҿ4|۠s6g{Z6+d]?ϙԚ~8 kR 9gT~5,I2uQ8KFG]-ln[xW{|FxWY[Qk64I^BT;_ -Ke2ܔ;v/ }*|^7rhrstk`T2k. lCR޴i=RYxĈbGիWrU2_M,s8ÇرEr;w'|BehN\ lCR냽m;D:3 1R4u>bGWDY\j8ce? hp;HNs6~rגbhA؆ƥ?qf9Dj#KHvw>}]"CbE={Dr^)A]^Z$MG6LeriU@¡)HNJӧJMM=z4XE2}tejUpgښ㵸bSll,hDWS䮩A+:jh+=o!(]Qf!2Q?yuWlH˜ 1 +m.AF]WvwQ㚁QI8HV PfVǯz^ RCaRV9fr}…˗/kb r}OOO]]]]*'&&~uuuS~նLItw}v>|ᑖu"R9ɽ-MM';+}ϼslR>#Boq5!nͯږ n8c*"#/8A 9Vg#,lnS!r>r;痈KzN~k%-ѢWm˔HNo%;q9ϋ:jjjlmm6U\\ ӧs\;ɓe2٨Q,--qtA,,,̙uttsjկږiՐ-Z(jҤIڎ;B\jj/i|{ӓd,ʁ3R~:3sjկږiu>HE|5) v$IWpx{F: ;%5,HK. )v,]sjկږi߅(HȾw >is#ԙVWϔ9Ddi vVX/7nݺu8%%% //0 $)))8~5NN/BCPbtb\j^"D (d=^պptKDrb1Z2n_M,.E} 9Ի=ݧ!"7Y{$p0yr.=^Zͥ8< K8gPXlaj`ƖUXW_{@H$E9Ի:s9rBmS0j8pgM&&&ӁxmgeeÇ tXI pjbkEzɈ#vݹKsp081&@dOxUo8,@/Ty8c+-evr:Gf~rg@|+%*;P/a{"`eYjbv&gf/o xء1q Fi ,.A8+moC7"(~5NN-?p^ ˄:s?z2*)''']]݈C ZZZ&L@ 8p˅k׮,2;95j@ ׯɓ';+riD=nsܧMX+ptc+|] E wHk fevrk:3%|~3Ofuwog|d8TpWE i98)|y=!ZvXf''fd¯U!!vnoSpp8Q:8/++&zWA! GYM &+  ,~+y"L#שa[$߄{E 26EȩC)!!@ǎg_Fٔs߾}MMM 4vX899iii-X`֬YVmh\bذa񇪵f ߿ٳ.]:|p===RR"Jtuu[*4=zt'.69 n4ҿ4|۠s6gSu-i mLj=݆.ݜdzk*Cr@fvipz3jb!]JV@h`[A|33smpjHngLxuo nCj u-$Mպ:z;g2XJ5eaYUr5Ahrϧ+\WWWLڵ -5и7mDOttt AA?G!qt\zTevaaahf .Ĵp vءLN 9w.]up\LOfZ=oS!zb1ESc*Jptp%}}]"CbE DR#TqvYeqitVTNŴW_u([291>Hʮ9uܴ]Ň3enn>uT' 郢sjj*$ .ӧ+3Vߝ;wB҆{ÔY[[xsbĉd5*`55heSS_9ET^6$ptGZX;A҆ ɟ:A91!X '0w _iOt J5슢sveQI8HV PfVE%A҆i/: JZ\ω!_YڐSwz,cĄ|r}}}jSWWGq𘘘-ѢtIVm菻:1r TbroKSS?I j3/Ds8 $VsK-2~!2 ^ 2ĭS`-i]=bQڇP?>aasy9D݆U8UϯFҩ5TmVArW鏻9uh.)) vrre'vSŐ>}*;w)줥M`Æ Ԍ_.] KMAraMЧO\&k3;+8zϜx_u Hk Vn=H!9Ϳuiu+|^SMGN"d?zi)R7Ԯ K8~3 YuhITնm>s 9c̼y&t3gm|ҤIW`gŊҸq֭[ {C|:cI@)IJJ ߠ (r$ eLrJNNիWdddGDfQ9+FQ{(g, \3%cKf * 'ȱK[$dnf/eOzĻOϯ)Я=d<}9/- pKPm(g, 0X0c*R%@NcїdINp+O8:yZѣ,/Sdfbb===G*wY===+++>N䔔tXI;/۷:z2&9}:&*`Jqxc.7{[ rxrz[?iς: rJ5U8W]#bSfA$VZU_$Gދz2&9^V~~Fȩs:7}jԩS b>޸q#,...(dGwʔ)P~5 ᗒP0ѣ+--ӧ˗TR\L^ʟ0: ,{\rPɐ}U)w,E,&KbԶ+Uqgܔ]esd@L6J r J]i{;ًh`!5RH39 9UDF]o?"%ӧйYnєnDD!-- &xذr5Ptpp"~_r*m;(?ȥ 2^Q r6!` J_P@LэHv-72!/c+oQU%y濕cu_og|d8TpWE i98)|y=!_pTu&''&{*?"7pý{jkk!^An4){ttt.^HjbA$9L(A2dllKƴ,ƦZ26H/^i*Q\]]߿UUUtL#42]\*q17Cmku"xgfw e*H_Ъn3EiV ~_Ȣ V$s clq7Ȁ`s͑د讁z ĐYFer򫨍zN\';O%U|$C`ҥ1.,~!Zu_"F 6!!=컸 FL(}@Lw ӆep!8p⵷7{kʦ 3'߻wo:$$$3 !144ץȉo``ĉ ^f vʟ߻w/u­[[\\ܹM& FӷP>Pa|&*A8a~^؎qͰQѭˆFŠ1}p `s+&B*p@i_HkT"'v  K؎qͰivxZ0skWHȩ|>8Sw"~:~ SSSm [Ke~d? 1BaY*/_'h{j_9e+@w1߲"@T~k_bSvN1E  =bҦs b1!'rÐM"1BNښDp 1!':w%. Ht"ĄH&K &Bȉr"D"@L &DȩI% ~˨̙3]o۶m̙&L3g޽{srrO \dɓ t5ܺuk͚5ӦMsΝ{/ՄSvKQLB4_t vkgg}2ޥy9::ks ozŋcjoK ~5!&Ծ{Fh_Wֹ\ޛojժk0]uZZZQMgϞo0Dݱc9_}U׏\@jBLȩ;իT-cƌA%^^^3SRR7,_~á|` ݋~ϽLTue˖۷$''hɓ'觋 `9Q!ր>[opon?j~swƗ@jBLȩ;7'O>ussC1pt% .];@>cɓ'/^NѣG=4Ң .'faȃ9f_M 9uD޼y3B F@sA Q~ #]v^ rFF5o_ |ᇔaPg}8>c{'iӦQp(Gύ 6bt\!Jbbbn޼9}tƇwwyۮ_M 9uD P9 P?J`8CVTTDRC*Tydd$}\m۶UVڵkpCe8yƌ!!!(r|_ 1!0>q]QCF9{,5z믿BNRC3Fφ> %}jt뒒cccdmTyii)5\VV6jԨO>2o(Ç; vpB|;tˣBfvEm?| į&Ą:sϜ9S9> Í˖-[Ќȑ#9`ӢŞokҭ!_b5'^?8wܸqSym( \9:?88D.oK ~5!&2l0tn]3x ȯZm޳;ZXXP>2CDO>wޭ<ݪ[ѻ;Ѩ;ӳD._M 9u r50sСϣn߾NLӧPr)<$66%Tφs5z65Pz뭷s490ltTߪ\/_ Uj%nK ~5!&% D?..Rw澩 ١~ѳAe?ɃPHuuu{ G]CE_ 1!.ANOWKQw,p )CCC'O ֳ={F<| ~'UxyyM4~o'NI WbBNڹ[Ȃ}}}]\\iJ `#~m%!![tqywEm'| į&Ą\&҃#1BNH" Ą9!!'BNDH" 9is"B%{Ą4]K &IM  Ą C:7\DD9u 0UXXxy;;;///H|BrrsssU---tuwwjԽ׷Vj[~FIKK Kp0 gݴK"[y##WPnRu  BX[^[/RږVgp-g@\V]+ 9QN|BVakpgt+y"L8#ש'"IGն_".!!'LÇ۷JUS}7554hرcKJJ'899iii-X`֬Y ߿ٳ.]:|p==gϞZ*:885gggtT;w0`_h"mmmhN\)f_O#;+L÷ 1wmQE33kO[po۬u{GbMq艑 H}c*JptJՎ_N\ yA+v$SX/'Uq$|ܦfs5''0ͧK^dH캉YeqidVTNŬx^)Acnq~TQIP,OјlBq*! 88&ssSR?RSSGUH ¬rYY5C93(&R?!sd#W)rԠMUNsJe[;( GW9# Q?yu7e a?e/M**Y>֟j}eqbwTR!rFfū^ MB؏jb ) A8J 9uu[unȍLLL˗/ק===uuumllpt!ug5ȉ](n . 2|\*72 ?YA{^c|GRaj'`5ȉ]S@3~Or!ϟFXܦC|dv/G.l9j ӏĮ 磟&yk%19Ctidܹ6ydL6j(KKK]$O>L`Æ |`%'^mmm`;v1'%%r*V@tqFmry'.5FYU@\A .KNri{H8ĜTٓ !O|w 󼈻l-aGhsw,H2 SYuhIKo[t)ra,{-9 9umnn>i$)Ί+qƭ[GIPP>66*$)))O81~x`Ç<=)rGDΕQE+F]1p>؊& cݵdl),IC'_4g`yI>>& Y{$p0yt.=^Zͥ8HbR| ')˩Eǂ[Va䤡eא4#0.Ovz~Eȩ/A===G*wY===+++]l߾}С搑VI˿;RQ|zرcz6y Ȟ!*7]&G4^7pVP[99ib@HEByI_6շ g@|+ ȞSB`f}k,.C^9d$[iU䤉A@H\Rʝ WŸrtԩDE1oܸR% DmooːPѣ<7vKf̘xNq<x͎*„8 J{\r@bah~G qI,Ԯ<7XfY}3mnO3.@92 F!1aːF2Hͩz_+^pr~䤫|8IKKk„ (mB=>>GW8Fʕ+o]ƌvZzԩS{99e^׽>'q hOM(WC6*o"1Xp3VrRCI7^]M(T6AWx9}MZ' T(йsrr`_(⛂GGGŋ4WǵH$9r,++2e1.X666@lWQQUbnWWW>u2a4X|18ۻ"Rynjپj)ffDRH֋DUSXх hM 1 *=ϩ(: 2 \sB%~sT\cWb{,]|29U&*E\';O%U|JB9Dn *3TǸ6` |($!y1QM,;<"8MR'r'ιGȩCɩnPc =޽{SB ehh8qD(Emm5kx[݋sTpv~ӧ믿>dH Uw)p0ݱKz{LIqU:P)aLB!(j{yW;.dXm52\'xx`!5@o\(rIϭ| !Zs8J }~P3,]_| ⾐ \Ȱ '8G5 3h봍WMԐ 9@4N T>ߍ,===++ MfvVHSFpy9"u uq8US 2V(Pg6+u#re|iIBN=s!&{ĤMI&@p bBN!D."b"ڵ5t! = bBNdE  $s"7 $r!!DȉA% 9tnb"9 H" 9|>?!!!222%%!|Sϟ򢖴Krr?ʮ[ZZz%8.2,44:;;.TE+cȥ9 enڥ] hVeng.϶떊*/eQ APe_W -Y7 *C,,-G+cUDp H}+ni=jTϔ?ʮ[EeѠXD97#8h UŸ1rokk{̙+W'OQ}뛚4hر%%%,X0k֬~aiK.>|O a <7w܁ǣO[J-~ќoG.Uuݘ;yْN׵ܧ-mVȺ~3c0u{͚(> |?g_/ <77lsx%S*@,:d^YvS!jasD;ܿSk6P1}mC5p֖k1)E@Z^[ow}]^f7|b_MG>~>ժ 2Z9_BNԹܹC#r???Lڵ -qи7mDOttt,ill&n3Oߛ \y~[5["'v=bڇP?>aasy9D]@pfuY߰woZ[  Vm[$'v:sBbN>M̝;v&O,FeiiӧlذkUΛ7:P/ɉo'F. o8jrFm*O\&k3;:2bRcC(pݦn)ЌC@\BuAV'Bayw[2Y\E_ʪ/GKꤘg hyQ1L@3a隓_BNй2774iD_`gŊҸq֭[$((r$66*$)))8~zcǎ۷o١% ^cvb\j^nRi;WF!k=^պpt@NV$7A\RY8~zMݑpva]%@T7=d<8/-]$1)Ep>d$)ϛޜ|Zز qF%lr-.2ீdL6evrbKȩ;wxx#G***62^C9Jzz:mpt}CR'%%VLp^8ɉogE.U<\ u(GI7|? G qѡ7M͓3^`l~} @3i8ɉowV/ԡ% ă80q5G!Gދz<c+$NZ+h&-2;9%ԡ2CmԩS P~`ƍ:XXX'%mmm{{{]GToS_ܺkDpȉoD.U5[q!u##mC8LKb UbA GiL-n gܔ)8t9R=Αy $F3,]\RqtH98KKg?\/-_BN׹!Cfotuu#""AҚ0aJ#P@rv]YB\٪_څ TmɉoG.Uy]-4`N KP:C6*;m~k}T%rb}!RCot/J#P@rv]ƫ٠-J~gNp72Sնmr c.ǏDP6yŋiBe!"hȑfffBlʔ)8sUTT@JOOoŘUfjl2u7&4NvBkܿpvp\*q17CmT"G~fv^\&r8t=.A+mU!|qU@\KWl9@<`JM!7*_EmT"~Í'Ē*hvwpt!Xu_"F *3uYqvHUt6$U $>I(}@㗐Su3gk.PsCeջwoYBB˜1ch0??S700k֬Tr y߾}-,,>}Rc(/>w^4W tYBU[_@!ЀaLUP0\p?NTC|G_O#=O3T^̸f&M! 1nrOV~M(Xs8J 3,]_| Jda37qȯRIu '8~ 9uu{䨡[XXorro*(d~^@ Ry:AMf> de+UԨ[V]]oVa/!عOV =bҦs b1!'rÐM"1BN\1aH&K &BȩS[H.@ &DF^.@L2'rÐM"1BN\1a"?~yyyQKZ,?~Q캥.]j|e~srr||inF4WQ)aviB%-573Gg[uKE{ntxAoA8c_[fQ'W@r\qKfVz}VvJ/*A- kDȩ:wBB!zxx;vޞ}IeS}7554hرcKJ}IKKkfׯ_PP.\UgϞtÇ/׮]&GzOP2{:8riRY7zYamЍcoqʼ>mmBT !׬١.@s@nIm j[fQ7fgfW V'B? ^n;\I)ԅ?{vw7ef}}'j[?OP2{9uPϧ}aJvڅ|mh\j}6m:::F#FV[g׍ C555Ǐ_p!f2ܹs@$[fQG.UT kCR냽m;DO#tsLAAڦ'MDe vVXƌ7nݺu8H| 'Wbccr)IJJJ~{I/l-֨S"W[KbM Z"mz(dYモ?1Z8 ؊& cݵdl),&s3{M,{ ⶰbzĻOϯB y2Ld@cks."8 T"c-Z%p+O8޶m-ֈS'L =zebvLLL CJYYY2dC^NJJ:$ԝoU~&[Q>\ERޘx%n|? G qѡ7M3^`l*6F)WXnFb[owgP>"{N1´q]3G]cqtrZィ3 /'1ҪZ^V~&[!+,,TԩS |hqFH,,,,\\\_(ֶeHhh(xNEp*5&5ȥ6Jq<x͎*lXXDqɑ?4B>*.s2  >3.?Ԩ[Cy6eCc  ?!aːش믤TTo%Od,TrS\.W%SNNNʇ kiiM0%aaa`!>>GW8ʕ+B~As,kԹK=pʼ{}ND$'@}ڄ%(+Lѕ54m|sUrμsϱ4QFxGVn3ZWt7^]%qS&n]7Z+ϱ4!^!޻w //2k׮d /&҄XD#G433 eeeSL166хƦ==ŋcV/: dUSupjp,Aclj@$NaLT5厅qz]H V$s |q@E'3? 5C`dɯ6TA,:?y2L,V^owG2U%rk@Y=̊E'3?ڤj׈SǍ8#x{{gʦ :3'߻wowBB˜1cCC|L'B!(jkkYSYܺuo߾j5a**uRc: R>P aLB!(j{yWGX!.iT,PbukM! }3Bc/~ p9PZ%}\>?(./>UHdYD<-ٵ+TUծ!Lpw5t SSS oMMM^:eΧ&8A: Ry:Ade y u"@T~kղI9uh{A%/ĤMI&@p bBN!D."b"ڵ5t! = bBNdE  $s"7 $r!!DȉA% 9O ϟ?oggE}.ǏwttTniiK਻@EXT^s,5ȥ J gݴKB}Yp3?sqx(|]TTy) UoJ KknFZ_ɡr-} (583VD~Qp4(.G(VߒX"VXT^s,5"ԡ[*=z4&&F S}7554hرcIKKkfׯ_PP.Ϟ={ҥÇcl9CX"H$Æ ?TmOk)KpʺH mn{ۜ2kO[po۬u{_277dooߧOZWdRSSG ^4C!;wD8~ONg6uJjCpE_!>jȘܦE2!N8.~mhe5>N_!%(hH"DdvwTː 8Շ_QI5!CO0b,TjLĄ|r}}}jSWWG.?aVUPDدf_Z%,5նRɽ-M ';+}ϼsl6X*1 ^ Dk~c+T9r%|j5R1d[C?M<_"nY:Ooor N~k%/jhF:s_~… hl^^ڦ!8}4U2w\SSSIKK9pA620 '{VZDb ʟe+B*5=t4D(*JaI6774iD_`gŊa̸q֭[$((r|<88xa{CkP):9ibF\jkRi;WF!k=պpt@N@Dq̼-DTa+W,--UɔnDD!ZZZ&L@0x{}ٿӪ7666\v 988@5^\mRuω({BhO%a%qi8? /wZV$C ڮ! wH4^ g |ƫK$#`r*qtgGgV%)ˡmw>Ca0inF:sӥZittt.^H7H4rH333PXVV)1.d$666@@rxb*KNNcZOщ߶Q\*Kq17Cmo"xgfw e*HY_ AJsb.d!,V 14b,]|29UF&~Í'Ē*Rvwpt!#Yu_"F 4Y$7uYqvt)aLib59uBrjtnΌݛfvBB˜1cCC|L'B!(jkkYSYR1IubR\j ;}1fvBU[_@!$kK0uL X a~*mX%rҤFb&鹕_t !Xs8J }~P3,]_| PfYR1Ir~d2ÁE T>~r*AA²T^6N~rOX֐WʇE ݲ"@T~2!عOV =bҦs b1!'rÐM"1BNښDp 1!'2"@p b9tnr"D  Ą gϞ$##CUSϟjq9Ǐ;::*|]ҥKp] P`X" g,*V|}}њ4W|MK^y!ԇY573GLJuKE{n^2/4|[Y.5 {eյ>C[Z"583VD~Qp4(.G(V_X"VXT,skß5 9u9߿ĉg^ȵkT2ܷo_}}}SSA;,X0k֬~aiK.>|gD"6lj{[JVٝ4WS;FwVotcpy]}ڂ{f938SH׬١.@sϖ3x_Һa7Zʤ۔욂ͮ6N~=>p#Hc> ]?ǔZ3]7<1D.jM]x% .vWq?W'-syA+Jw$"9'<ѲF }Ӄ9$FF.4NȮUH=kEuK~]̫e?&ȯFO"j9?P18BNݘbnn>uTꧽ}>}VjjѣB@@.Cv u>}: rYY5C_+Ą)rԠM ~ 4Bv@Q.cZwz\&DUO {91dMnmvE[EESD%2w8H0C[ZVU|IPVNȩɩD sԾ .] 5144~¬r~ccc. sVCH9T&aroKS ~ȣ%6e9YVVBRr|r?8o>"MCVqidܹ6ydL6j(KKK]$O>\`Æ y9iկŜ9sоW1kuȩ 8jj {>9pA620 E Vn=Șc5{XBcW1kuȩm! !|w 󼈻l-aGZWudWA.ђ:QB~8GnM1ildUrrdrJJJ˃ԁ^rĉ,i)ssI&I$M vVX/7nݺu8H| 'W ݡʃ)IJJ ߒmmmww"KfhbSKM Z"mz(dYモ?KZ8 Hw(wגpp*= s婢GƒXj>>& Y{$p0yq.=^Zͥ8HbR| 'W ݡY flY8~+x.Aq7h#c M,r*DB%aXL8B Dt tl ː۷:zJRPPÇGr9ibS[)yLmȞAKǶ zLiBnTy8c+-?iς:n``ĉ׬Y,~JnK{ȥ9Dac:섪1BH8 Wז`= AQpA²T^6N~rOX&t(jUfq 9uh{A%/ĤMI&@p bBN!D."b"ڵ5t! = bBNdE ྊꠓ& A%DaȽGȉiC"9 b" C=BN\BND9uF*EEE$T2UXXxy;;;///jI $''?~Q캥.]_`eݢ"___?w 9i.YQe㒛7ZX*vt=+UZ]WVV&q*?zVej`GWV\\!wpp ;aaa*rvv۷AƎ[RgNNNZZZ ,5kV~0u?{K>\OO}'r@Ќ]D_!o̚%KSe;?-p;M_Ԙ7dH]h(.!5MjǏr8uguR6!'BND,~]x>V7k. lCR޴i=1с$4661b:ntt4LkjjƏpB*2.100ڱcGW ' E"'bmuYI zw[d(d|^45n}ll]x@7*z)nrWҬ9s?@ȉ!_{՘D277:u*޾O>hv+55u`! G!;w :Uevݲ2kkksjspZ"v8}{0ݒ'M]dAkkHp&Ud]WV^.#DS{ůcǎ@\^^aĄ|r}}}jSWWGY$ 0WU˘]\*G,Z7k̚EKy+.5k> LYqhSBNϞ= Qq/K/pbWN>M̝;v&O,FeiiӧlذkUpgS+SۂJJ _;;S%>|<}yhFLƟ8Asb,) r9sVeL]BND9cvĬH&zzz}233Ջ_&MH322233+VKƍ[n. 8h2X<88xU2n"NoT<%C֡KSjlUDP8h2GMaa4- ߯zu 9!ùH؆ovWLLL CXAOpt}CR'%%Va]KSDdg{o5EȞ!'Ʀ/ܵ G!ݻyxz\":v Uev]BND9uD `̤988ܾ}[USN0`@TT|ƍXXXOHqt =zSeY V";6>&[Sox745Ab8p 8eL]BND9c,ƆC?xÇU2䤫|AKKk„ (}A!;>>GMFQrUwݯ&1u9 vp7pɟf?mhޘkp-J+~5Kȉ!v_ǎuuunݲc|׀=:::/^L 5Giff& ʦLbL{E"֊ ȫ/^YeXnU+Q\]]߿UUUBNK=oI^&'S[ ٳkҕHj*e4`cRXnUW&BM!è(ؗUWr"D-WCvN</{2S+qݛ"'1c@!2a 8q"5kx<~Yjb]Pyi{v 9i.m6 PLse4/u!5rǯ;_M,+2k4oC 9r" ˥jq*4T*1 ӯ&+MDV4/Wբ"izjbY=]BNt Cz1BN!!'" r"D r"7 9p 9!Dȉ!'1BND^~"B%!D ID%BNr"!D/r7LuuuL?KyǏ;::* ]ҥKpݝ^&,~5j}>}zQҚ/&"I._?.y*KSSŎg?ʮ+++\~]V2l~5z}g&m !'BND&~%%%I'Ns߾}MMM 4vؒ NNNZZZ ,5kV~ K.>|O aVs|׋-ֆ,r\$yf,_Fǟ/+- p;M_Ԙ7dH]h(.!5MjǏg_!l~5j}ּaCkWGܷ"DȉHN5uuuvڅmh\j}6m':::d#F5g׍ C555Ǐ_p!~rWMҲ^zeddt 9i"Zjqu;ӓ PP뚳օ+ |'7,~5~uAw#OLT07H_P>!'BND%~9::kb|ԩO{{>}eRSSG pt )QɯJ[/SOH/u.9i.Z5uO'onhljiz:DuA8LV47mRůJ[/SMYZ*"i#DȉH/s.)QLLL˗/ק===uuumllptE"X~U~hA… C n~:\*G,Z׮5ڗx{.W]5 |*Zff`݋%WFhXBN}|&!_/ >w\SSSIKKTٳ 28HII̙#ր _,z@ܷc RҮ!JSii}Z]ݔI$ Ubdddff;+V@jƍn:]$AAAp>PX<88x8~ճ58qbLÇtPmH+ +_5,_TTTb^zv.9i"c7$Ȟ!M?^k.Cw>6d$cP%jXff?d ƀ:BN}jw0uԩDEE17n) $C[[G!ѣG8Uek;v%3fXxq'*saCcbq,!'"m޽oH_=S0*ՍP>ܠ5aqte2+W@չ)Xf1cƬ]^2u%' UD x@pwi(}A ?~5UwXff?'nnؘ!'"m lA)!ttt.^H*D#G ²)Seх\Ʀr===*ʷ*,~5^}?88O,;v ZۻICp;-+djkN$'#kfϮY0KW"3G믲J QSQ2{}ER&??/r"D׳glmmkjj3qd@޽'RCC|L'BoL>^**FIxO%>>dg\1 QQQ'[[.]q7{N"ے⦫W!BHe'09dnj:9J]-dr3a*A1,pzq 3SiDqqqII } ,qXk֭[dQek |һtH$ AWe!knܹ5QNb ENx็pB"P' .F!P' BENe2{pB8N( pȅEN' pB!8UVV\fq~͜9k;;;[`JLLӻ]_~f;wqss1X9'\3vڕpJ +R2rH \wݻ7LqΜ9sε' c˖-#tv(DzX8','gԩS===IɱcǸ-?Yf͞=/,..BL(iܹs͛?~֮]K MvU6))Lfʕ\ݻwŅvhXE8!Pf_pr@.]\v-99cǎ[i!X9;;8qm~_&u(w.o٪m۶۷%o=<"'$\SN ~78W \\GEE@z v'gϞ#GkjRvss#vFډHz-GGG6L8_#Gf adЧO}f0Cz;&пf/ 2WԣGA7| ,,5)Yz5)+VYEE{\PP^5C\c/\^dɜ9s`ܹE.K/׼:u";666_PHHX пf/ 2ce6i믿rk٠Wk.?HHHؼy35vo ^O>0mB䪪 $֦MƖWWWW^yfoyj;hҤIvmcsBϿ'ʌΝ;d9guMwGeee>.'xA2n]Cֆk>>>eeeZ0ҚEvX2п/ 2o7nJNT6 M|R/&'mNLĹ<5xKL~DDA ^#;^^^bvKɒ%v(X8п/ 8CoqAϞ=zyh^ړ4k,6榦BɊ+ .дy_ apg2;;J7lذgয়~" lll]%۷o'[֠,vG=== ^ܹcB,`s]\\KIG!mSGGGvцMN_1E8!P'1YK!ݻwt4(--uuu%d{ ^p[n&/= mr4hӦMF١빆WN'T)SwbŊJ~ 3g8>>݂WQQwl\ZX;c=pB/ 2{D"9~xRRRFF޽{pyС˗/s \w?8$''$^#3пb B8N( #:]B8!P' pB8Nb s(5~Y)t:]B8  pB!N(pBaB8sN( pBwB8S{ٲe˱cǔJawWв***?^__oԬL\RRr@ '1%b**bc?}#48ծ]R ZSYxi.晕ɖ5wP N6_ _7n\vÇ5hgg}e~i48۷jyf%ÇqmX'%R8 u1Cׇֿy["޽R'ǺoϜ+hYRJYNIl} mX'm׃ Loݺ5--ʹL+++]]].\M}lll !oRh򫸸}៕zڽ{7`ͮNK԰zرUU^а|7@C*B&>2 -EP ~jYOZspzTWWq*<<|ԨQۘ[[[ H&Qzd2ٳg bԬaÆAc,ٹD%n+%8MרZV13!F(z b]#jYHpp0v>>>qJJiU,=!F(\[YYq7:jϩmYHԩD;WSSe/+7okTT5+,? #wC pBYbdǎlɄ BCCᠰۛa.Z/}8M|pZ͖;6,, """׼yhfddL2P~~> Bg%2N:]po-7&|WW5o@_M_Ƴg Vb,H{7 ᄲTTT- .H-J tR t=JeV7!{ܲE֯aT]dqC/S>dHCTM_ZM~rVS^N9JV~p pBYVھ}ŋ,XIIdddRR:&&/Mio4W]]mkk{Twz ˖꒒GhM*nM_Zhf%fYrU>pB-7~%$$888?ް СCIBzvv6M_Z"8+powކ?pR+{ٽ KHBzӕ+4}kMFDIaUmpzAYׯ_URR ٷouZaaaa`7ߗ_ n֡C`Νc6:Jeb_i (粙EwxPG)(Pǩv>e~ۘxTmeB%~eggGGGܹۼym۞we*11'44yzA9!!*$$$ [nO+h_<ズtXӧOo+gpoX8wn9p@KP7c?^PV+ur>]ͭʾ3.H >L/__uk+2T;#Prį977CĉF"6?Lu…̒}e%ߗ_8=zԄ/S2޽T*X8w.QUa懩^а|7@2PdA$\'? ZֱH#!Prsp0@p`cbblmmḠFרZ= k2h>ј1cюs\`Uqۤ\_F"dEjߣ14M_jqM'RLS9pB8kVLA&̾={{~zFIp\'`2-geetu8~wc$޹l&Q7uj+QUT͛iUO2q[T_/¨Y]v"$'' !/+++h_3wNb>2 )Ih<2i OpB8J.F!PN\ pB!"PƜ0( :]B8P( pBP( BP( BP' B!P( B8P( BP(TBHIENDB`backintime-1.5.4/doc/manual/src/_images/show-hidden.svg000066400000000000000000000333621477034762000230170ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/doc/manual/src/_images/show-hidden_btn.svg000066400000000000000000000321621477034762000236570ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/system-shutdown.svg000066400000000000000000000051161477034762000237770ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/system-shutdown_btn.svg000066400000000000000000000123651477034762000246460ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/tab_remove_retention.png000066400000000000000000001705071477034762000250100ustar00rootroot00000000000000PNG  IHDR;sBIT|dIDATxEn1Q11P,J/"& ` )HJIH)%;sspw?/٘y<3oB!aZ0o9|6eB!DFcS "ȨY&N2Q!"k? "%4L H!f҄~&sB!.:`e7T(B!35⟹B!D^)4za}ӪU<ň#6b„ f[pB#x!Dd]UM/0<#fףR?M$:w㾵u:7_:b_h *{"?`4 ~3:Ш6_3=6Ds|3c9s7S3d{­_c|v7'sdc.*CߧOOSAUgEglpq=~`)pSU@EQh].uɥ Lva cPJ\=m|lT~BMwTHmSVMEiF/ew6={~ZצMk˧1^F\۶[z|٧2q(to{+>?qcwV^!!!x[?И2qv\~5Ǡ_0#u$:o4+Tc!4JpD$Xsa(̮TԺ^~ٮZF\xp>=5hWX!bbs,҉_ՒNEUh?Ҧt z,xKy;@u2Ј;h\_؈s%^g& _hgD#.1۷oШ(04vr^da&zVF^o^Yr(B#o.rC~<Ј;ߎs4;! C5LֵsFs45m4GqшNmlyc׳k:+:}_+4̳Gl7G 򋄆(Bc҄AsE $գx=uBs, OfDe>QrEyqq$B%4*t!jvz146#!(BWVɔݻЅB L?f!f>w/L]w6=w5}{0 <1Ԍz NN/B!$4B!$4B!!B !BШ_9*B@cHh!BBC!B!АB!B!$4B!!!B !BHh!BHh!BB7ߘB;cƌm'ӦM3}6lHe5}t"Wg%4~Ynm *3f̘aNGY ,@r ζv2aQPv?EJhdk Q-Dª*dT_JRhB{ (;℆H0Y \KbKRÝZx۷oB&DzAB[hq;/?`ELQ(8_Rd~^h|4i߾+s=g.\hbD54q9瘷~Uڵk%Jwݖ;l bӺwnF^nvw}2eʔ\wv ̬'i=vuժU3d'|bN3=m] k؆ _M .]j-ZJͼy\F^kAɾtstⶽ{ЈJoӦ׽AѣG~Hق%4Wn,g1lmm,Y{ٳgۊn~ ?B㏷}Z '`Fp/Mǎͱޭ[7+4 56gI 4ClD=Ee8o9#;wnkȋr #(4G9vawynFTup͊+-(PB喗-[fj+۶mk?pSNs'[gFpһ첋9餓v1bC=q"%QC'f͚YgIO7=zHh JsWG}0c?BmK>;8{]tyGtg}iٲW_ҥ̙37ʃhC=d;묳̙giJY)W)_mЈ!_^=[{챇]yo̶nk<[nUlㄆ;btWSFYlSW*U'=l?@k'`{10u?a־БAh 8Hb#qCێ?>e'4\b9_hmq*iҥUn8Zha;CwyXttifrR e=϶m{3o[f2#GCшXg.}{&MR鴏5ʮ3PGa?Na??y"`2:r>HʦnV;XGET>~MNl2vۙ~tm0n/lQj׮<9.O<9Vhx'u梋.׀pۢعeGuiҤI*AA ln6rJ'PB@hаM,S4rz`,#40 _}UjDGm&kA\PIs195Q9Ahn 冈ĘPY-6 D/a8#pLI#g.q:т1<#%m\K(8 A~6Dטue˚k6e{jԨJիPa_i~= qzWl>VhufS_ON'l;Ax(mعuvE¯L2>2Ap>msriq;dJTDE20`{@`\1 *0nn:YvBå#4p@y}(8 7-z0oa1ݼ}iyiqyߛfmÎ~]Ʀ#Ӽ;P+wM*h˰.l+u AG>pKKX>~E$47qi{o{B ӥN=JhЀu\s͓UTQq"C>5j`b*a}9+64h+26F3w"=Q 1`0ap=@zN#4\:GF~kȋr pB#n{ʋCD7:NlCDV"4M9d~:bQkp ̹0ؗ:u-S~}F,ṯΉkڈ;/!uEh`0q T5sA6%BHSLL2)Don0熱8e~s 4*ą;|MAʥ;̃AGg&2\&1TOݺuU*@μ$Ӱ\c=:i>N-7lN=sUW]e'J".\:>턆KܹuQ; {N; Pc%851'  c2QEQ8pt;dѠcE`gϞv=N@ɝA߮?1]tۯߴzl'4\>u=믿>4/kfvsi_9dCl2/5 '4u< arPB愆nE!2=5t ]]v('OlͦY8YPAh` rE6gDu('4Th=5'ߪ"/ꬄ^hq$Hh "!4\FqG" h' e \FA?Źײ >&'Dq6gN+8rU}-LuVB# H5B7jBT;a"IvJ:+0%Ԭ(P O0[^$r(;עRg%4gQDŽ(nPmdȋx($[GY !Bl2$4B!!B !B !BHh!BBCQWogbWVkGTvYيlﷄELd`MgAo3fgIx[fsMh/OP>eMɫǡ?m?覷gmݺuY_fo޽7Рǎk/^l,Yb.]*P.DSy|ofC"PF7=c(dڵY=;]hP-Z$"pKe%!6P g,7nvAHG.ySy|$4jޞ{AXG+IɫKhnz{_v_ 9R@hό`YnА#UHhbFݺuMŊ%4$4$4"s1[l9rdt۷7p@qQG kG*UwߝoB#Gն~{{M{ҥKqd[A7\ry;kx}*-B sժUv~!OG_# 3<Ӽ+E^h׬Yի7Z>ܳ}ϟxnB+4&L`Vj>`ۚ\|wߕSON:IB#s>;v:u䧟~2vmEMh)SqRV=zH,4}b IBQJ(amnmܹARƈc=hȐ!EBhD3?_;}ga>CD[(#,qtݾjӦ o1o< B*4{o|,X "4tZK\#=7 p 6p5kZ#F[6waLٲezQ"ԻO>SOMNǏ>N裏>J9|vaf2^{^'gͨlZܺ{^g9s6ҤID?̓O>i.r)Aٴvڙ=ÖOۮGmî8e®No* eٵkT:^2{:4k,Th7^ω{ցHWƛaR0`JJyWcĽ'8ʕ+[n9[=Pnۺ ѣG[c)O ʬY6 QF z.`~Fkժiq _6ڢE <_߿$asRWn;3bNٿꫩ<=9n:g΅c~gagG]/h٧OƲeˬc$)F\'pBJlQ8O/4kDbkr3"<>u]o*l~PPж-[a)S6B :ywves'hf|珰y v|!9YEF6B#(BÊOH`PNh`dCqqv?*8J*gq{Ͼ CyC(HB>ydLO14h`{[={ƫp]e*4j׮m,eε3ܵ6ۤF\onMQNW1>)Qf#4@u͖;rB^, 1{lkI^"&?K'Aeҩ~z}Q1d?r4Lsa㺈,/.;(D+`뭷6I&Lh$?BZ%\Q "A.7ߴ 1tЮ7HgbS|~8mDN~V<|V+97nli믿n6mjų7^U~!,l_aÆJD+B8NqFʱ/!?tԫAC{@oޅp;Sl}W(Ap4e+I ݟ71;WƛabX0>SNMmc{zzyD COOWutM)4>CkK#I:8 sZσCvB:GHrJ&11"$a׈hqׄx5c4(R+0$ D`?zE=#1e~:l2uO0N*4pӮt\sQ[v; oMeh i>)SF0}ga:#jB)4hES@q&У D&GsB# c m۶'CCn2CIhϓ+7(%[j+ӷo8WƛaRȻ?Gk_phР`F BP0L[7Z!ѫckAGz:B ;͝o?QFu˷~ M#lqRܿȰ'-\qVDիWϜr)6 W6ٟIF2 YF#4}wV5.uψvb۲E6 : ai]tS698 C!L"4hyө[tR`p"*wUW]egQB#(62Q" ' 6I儆뙧t'4P&U8#w#6"zq pk%8z n#pĕqA:15 =sm ʇټ [nWXa<%A P38 hp,b8v={5_o$ 3 ;N9|7|ׯ_?#A4!+`LhA&yraBoiGd!]sX YbX3˾&"aF/P~D#2Vd1tB`RIFp=pEdP/-B3D3*`aP >Dh0N)!09*Ǧd| РWMM!\T"(4h\R>,B݊& f+4qcEd'b@$|P4L:ulH:;ps CI0<-&ƥ+`  I8A= "&2}8lcӰNͧ쯻:;'!Ad艨k% v0"\8Dw,B-3LJ|r\kN"4ÊK]^\:n91\ `. p!zE0<"ƌl*F3qBU;6|!ʔIbQ0zWHIhk@Ѓ'I2 %3  "8S'xs>w%緟_B"1Zfa Xm\"q:Cx8 F;aJ:&ʕzWGoBh[}QDm OtMf6mhcL6ָVAm!L G/K- %}gWo+U>80#'*Sh$!'{HB#3v9Ȭ>IhyF&6_B#`8>ܳ쫈z*b`BE46 ʐf_ 9REBhȞIhD &m2;WrRy|$4jޞ!4ɒL`Yn-BB)IɫKhnz{8.wI۲g/FBJ' 9>{Fj{I#lu#K'B/oV$mه}yw/"K*lؖ} ЉN2B!D Ih!BBC!B!B!B!$4$4B!!B !BHhHh!BBC!B!АB!DF2_}UFnB! aʕ>B!F"7abŊra\*Hٳ[la&OBHhXv9o֬Y+4.r ̕W^iN93uM~SN?tӢE"%4®ӡCs![QBBcO?:u$hBc̙欳2\r;wnqQh,YDBCBC!7ffѢE Ǜ:ʔ/_,^8>n8sך}FIUfIҝ9c$eʔ1SL"~8s7q6첋=Ofr_%Kwym_4=fڵ͌3W_m3qs衇=Ê#FһvjN=T{=Ӝwyi)I=Q:=X뮻ZףG>˗/7M6yyl^u/馛nN>d7Wfl6v=kDäIl:B頃28$ו۞aRe$kY}fyڴifѩ27i$5$ z뭷rOqO_u.z-]8q3gUw .m#dBHhOh^p7Go;*Dhw}:+N}tg{J7o]DhO=>fX%8sϙeF zшQjRC8~;ξ z,ӳF 5Rq~!"}a7x#xqr>"Q~I'*$By޽{(+c;իۨT /$;DDH Pݺ>FM\ĆtDKKBhd_֭qAFE3 g2Lկ_N@;ճtgǎ8nݺj$͛7/bSD>I6lZF0w(Ï6<MrS 4XhTT)9zkB\AraCq&)$Bu"\!bzkjQD8um|pqG?9DL~~3D?.Q,qmEBC!oݺu6܏hF&A)DHCO j߸tg1nt 'SQbEs&.Lh~DwΝ;G^SGxڇ7|32-ݾqeڱcnj&Κ5 >; 6NHRwnl#NhKF{&b2(fdx+C`ԭ[p(fzl kL6š ;g)2'ء07τ&VƱ1g`eGvMIƍGmP`؀FY1%ɬ."o\2Wኀ3c 0JJ$4Hu/B# 6tbe0vqB?|;lja&^qt"Jd<VN0aьL0 3ّLҥ;b8h K!34StN8yzJh &}QE]d Q{mh-5%z'x-[ 8q6 (86$n$eJ 3#_<.KB!F,+Wf !F߄ ̊+Ry˴i[lafΜY}ʕ+ !FBcڵN0￿YfMи˭r ,0W^y9SԩSUQ$4Rtr!BQƧ~j`:uE4|<묳%\bΝJ"!!]h_~hƎ;h-Z?~9ꨣLŋSƍ3^{g}lZj6$}!?sαQ2eʘ)SDO6k6^z9+޵kW+v}w{n!GkLŊ;l8GSO=ՖMҥ͌3ROz։6wߥ9>8'e[os=;ʖ-kʕ+gJ,iWS qOc #GL{w.~5k,G?'ti۶m>~fm1Gq|;BHhb馛LӦMF3 "Uϟo>`㏛ ~:/Q]wYt]GƱ-[p={43K,1?k}Gۛ? 'Ӽ+رc͜9sLR<Ǎ RzGPX|Mg{jv9!h}!׷[mXtҺukjԨH"46 ^f뛝vs1):`;ҝYĉw-Rh `2=ozݣG <Њ-WQ3t (o  z=zpA:ehr<4hАF( *Q:L%0oV6 4o O?#[Hw>!(Bcݺu3ϴ¢LE!ӧ]~m7j߸t'4p"1,2ĦLĉl?jd2(=|ʒDΝyp.üO? I"4hs; <BHhɠEE32}瞳Q &%3e@ݺuqٲm\{q`CQf"48￟s̍@0 0敐 q\;䛡$ɋc^"9$ Kqqb~3!"$ʽ: qH|7h !$4 Yfd*4I&fv1R2w\tNhB Z.$8T΁<+kHzn6vْS2 viv~s<k![^^bO^'Gz!sA( Ds$B{={~?ZJ*!!΍ Iw>26B "LF~F:a!60BHh3HhHh!(RHhHh!B!$4B!!!B !BHh!BBCBC!B!B!B!hݺB!63EVhOӟ!BhDBC!АB!B!$4$4B !BHh!BBCBC!АB!B!$4$4B !BHh!BBCBC!АB!B!$4$4B!!B bٳ[la&OǭY)Qm̏?vۅ <3.?#[okԩ9 =ȯ|`?J; /N;͖״i9?v:7_~es衇p>cQaywe˖7nknx34gqӧOq7ں@רQ^{a1bDj bӦMqg=}mڊ+Lf̱kvuWzڷk׮SOuN$)۷=.Qs=(;]pp߸oz*ey||pMfml>tE$ɵrm"J 7ʎspnqʗ/on6{;0ꫯn$G܇N:0Z:~^oV̘1Ö?vٿ<؄/9clT} k? Ա֭[͛oܴI b$4J.m̙c+wܑچHΎJxbk|4QG~[p?rH[4hHh:WExh׮5FASq|]E ƃe/R0,4X$=NhWӭTh+o e盯*kf̙v_}_G /7ex}W]tN:A'0GuʶN:֠ϝ;צs: kl;k)eh4}ҤI6zK.Mtew8Gd&M3Ist`;+︶+ԩSm9Rv+N뢌19oÆ S/6>hFtm7JhPW{={o38yݻwJ]޶olv)4wHîp!ݳgO[>my!4z__'l= k'[ȶMJh3X@:* 6lX"Ko׭zG ;i4D/Fu4 >3иFqa#FƍSˌs\ٶM69…8eB#ǏoЪU++ 3\sy"Z4zj#q#"~׈РW2…@q|XPtew%8 8Fh6>|)\ƤB#8=ڎF88B#F #HT߷~Xbt'.Th͹p֭*P`C'8jN5({~2ٶI |wZn/X^iɲ_|r-!TvI O>i@  Y tƷdɒ֩ah0D 'bx1QO8p`sㄆ/2I#PN;duw|Q'6=^geફ=-<*UJseG8}|m:z=.kH!,˕+gL]/=]]7ukSFh6'uWP|8Gw^Ei MIn`_GTTR^hxsd"4NExqnƼy󬠢J=wm>l= kNB#mRBCBF0..,ƑGc2h5jT^=nɆ'ClFn"ANY`(!C"F&MĆkBɈۺ@_ ql*wLF˞pk05{%.޹sew)p F^;F4ҝ .BXD#] `D#Xh.A ;Φ\e]nlaWgNAw:lGTD#/ڤF.~,ˍU^<ԲՖkYo܅?[k7rC,`B#1C ~kK:GpѣGP$s4?|kw3VN<\ωD* &LZh7G|'l\3`h+o0^nBɚ\;'f0-`(qߺuZLy"~|f x2RРcZϜ FFaK8.1܅CDTFY0{ʖ{I֭[ڲn0N\d #ʭЈky!4};/Ǣ}ݶ n ' cp\ Jǟ[z~%㎓Р>22Nh04? sI`uv qu67BBt6O[ٶI a=&>1˸%B X`"O5^z)'4hggDoWTdB4M0l`{(O?4#A'T袋K/Vh+oii D 9.^b*U_Vh(e5c].I9#0yG1kFs~p2/νŠu" 'hGr߸f7{=Ɵ.&4"r+4F^ `芰5ps9ҝ9ZEyPiaP>\/ ĵݨNA߆u?N!H7_wOɄ]d#4% ! em:;utu67BÉ^,氤{$6)G\_eٖտ,W˂,sl2̟VX6r](iU5 eD% WKh<?zׄ #7K$4ii֢ 8Ֆ_VnYAlOKVY~2aB˷X^yaO,L.ȇP0a?)PHhHh!!!BHh]QbCd'0~ce'4f[f0sS-ÿc)[EI!АB!$4 ouKWYV%I?X>02vbe8G`%/)Hy=-_,,(8u!?$9Es^F1 XX{U6(Bc'LP l}/{AQ ˛7t#8|HhFA ?8elj˼E-fͷ|L'}'ZFOYhqBc%v>0NHhA\KeZy]6 ((uOBcc0 *)S)2^hhڀ It WW_v/y8M}TNK4`ޚ ޼ݏwRN^ux[o헾w|*7;Um߰T^ݞO`f.Η1tmM^!̧ٮuֱC'MǕ%C()͏3eYf2LRFk׶o~䭘 (o$/%J7s.8@(H_*tҕa{pYg)_ vH^ ͵S֔㮅2J?bĈԾq7n漍ӯVZtimަa+)'g6ٰDXFlҞ}xj҈3|tb$]}6MD6YB#'o ,3Zcϱt0=Gΰؒ ~ o`lh Lx/_7ڵ }lI#qH =޽{hNh̟?߾㌃'8/˖Ny ES^FI}BC?NhdS6W8Aw ʒ\7,QQ_LZF3+ɥ; 0Cr"_zݫ0ܣX2LwF4_l+? 3i'.8ug}k5~]wcsz!r:LhS}ȴ.+~80: N\RV}ܫL#;:ou:tmC\}΀Go o߾}S\z҈CR^T66YB E[Ap_P@L?=WAFE;pnr8BPη2  q2:t*p0yS?] 0⼨rX7@NbMdz>zzʓ[2pJ}eA1ʹ99yƸ-B{ =ؿ_q ٳwXܕ]p9#=GvD d¸>dS} 5' >nH=tFS&ӿ.!?Ζ<2SqyJlh/S,QFD[s3 s{!+VL;A3rFM F4*pw.z龌֣Ẑ~Lpn(y:''4)LOnB|aat򢌂e #Ss#l/z26 `ƕ{B#ԒF4PIXD/77Hԃu1x XKaB#xTh݇L낻Oˤa `X!;->u0b.].|<3$ Lm&l([ɖ.t:|1rUQ+d=g%0I] >ۮ# > 2iP3׃ |۷o\ £Z7ы?GS"cޡCdqrI!Ϙ'yf;=DMnF6esq׍ҥKjsBa)`0艫Cң $VZF}:W $m^0*;f}RNxгdn uʆ99:v#ÎR:Sw2 >q/-?o>nHqCCWGmqEGB_@>`븿\#m&S\zؐh llF1=2fH%WP4~h@ JD P= oN0LX`0;AI'JBFB5&%2&O>裹ٔM'LwO :ɴeSa&:YO>5Q΅{$_AƘq垍Јk#U7k ; D/LtÓL,7㢋.1w(Ω8vG49QQ{vTh݇LBS'D9vNb7V}8P'f;7mg#4O=TCa E0ٖsyv^?.Oqa&XgF66YBc}&~-mЬUː-N[d9eg_r}-zPB N #BBCBC! D)G(B|K'ް\_KNX>z㏳-|9o5cQ/$׀EXh1>ĕ;&Ch$dx^ӢE !$4p8!1oA_˯LRXƒ%Ch2G2^󽹅F !$4$42翦'O^y3{JܵSךw_os9_eVטCYgӮ/wR'< 1Ǭ5[qkmi*Vz>Zm Şwכҥ63fL˿3>&ἵka. h9ᄵW[4u#Gδm:U_{f]כsK"yoMzΗ(o!-O?t*zȶv}CZ~#f_hf͚Ys~yGH#ެy4}xetC'|'}"vɗM%<̓ճTk7Wr "2L'4xbmyvJʎϴƫa׮&CH%y"UtF:i^1HT7ZʱHHİa}-յmKBc֙-~.9.[/+.M[ia(`>|Uizkۯ7,\k`כ+ˌ̙Ҕ*y5}>pM[bx]b1q*{~?l9,\2QD|2]ų>k;^%IRJ[8}t oС6"Ү];$wN" 4ye5+B}$РN"CRƵ4i$GL7FJ#nNhIr3y8r!*GrN%/wb|x;rC  t[) %^i.(TBCm0pk=4iF %{Gh *-4WI ⋿oECh4n5k+(ƠAd%4|MC?޴iSm_h= |pm|G|~^9$ 3NhTPNzcYa@<8nNoޕ#{~:D$('ܐpaSN9F%DRT~9?oԨQ#WS7-޼k A,;*r BHhXῘr2{uԺ 8 1Ǭ>~M9w-VhTgu:q=[ Q o%KCh[&R5*И7o^C3 mI]WB6|$S N_Ѕ87dH فHpaBP_q> "5w(Q^h}2 ~:TF^6-s0R|15E5lp#uB5_oah% iϐ!)kt^@hs'~^ η6Ɗ 7DCdɵwqN8A. |etF#<26̥F4_ h:" ~DK+A.,DŽR" I_nwN-jl 4st0%4Qa0~sc1bĈ\7rcB#Iwٯsnv9BB@@j?Ss0XvB 8l':p{tO2\Wj! Opǯ2[me̔)׫^i'|f"47xgW~NhqǿenHVhg$NѣGI|?|bLdoBqV'<>M!1p?Zwc&" 3tzA'4(C30\2h0kIEf͚~~h'2lB| &Ѻϫg$B!{|9 x9#mڴC)7q"k׮r,BHhl~L0 ]TƢEϿ~Cy^^i8uvnC 8ijoi&> T I\a qV9!Ll!l 0NY"2x=QThL2ΉBOO pjL&3fA3oE'L$$CA|::KUbŔx;O  eʔ{&d2?a'?8ybl(]۲oy{sC"tg$ y BHh!0d]!F^jBBC !BBC!B!АB!B!$4B!!!B !BHh!BBCBC!B!АB!$4$4B!!B !BBCBC!B!^hnZ!"+4?OЉB!4t"!BHhHh!BBC!B!B!$4B!!!BHhHh!BBC!B!B!$4B!!!BHhHh!BBC!B!6+|0`-"9٘1c$4BOr~YnW~B!28˗(ׯw-Q׊`B8 ?G8pdڵ"d* $4-B#'"{5jꫯ2}dlOh#t믿DHhlrʌ`!F:ud+4pNBch0aYbEjYB1{l[ɓ'-\/ݤ{T\YFIQ#0L{Ehzꩦu֑k֬1wӧO챚6mj "4;oodи˭CvtI>q*BO7-Z(RBVZ;Dhԭ[ל|fw4tQYjU*}ر檫2쳏mCs;9psn{쿣Yf#̱W^Գg:~Mnrl NhD' .Ht, >Ns8}H駟SND FҥKܹsMÆ [omk( |˖-Ih)4G;63UTIO4ɼfȐ!&4رTR(%uG 16mZj_oNs9vjQ+NB# 4x:@/Z(e?BE5A {f]wέG9mf*Vhvygs>>NFE#/K63fH3}ts-}ׂcmZ&M)#Ǐ7[mbyܸqk Tnĵ BoŦjժvvz衦UV6m۶#0ճu[#C#sWPxڎ9Ӳeˍ?o .S2eJj_~ٞs5k#vrKr웮(wzkӞ/t9챹wqG}if9kPᄏe]5k\886uX޶r/JOrN&4c9ݼ7C[k׮93S"»wムuU^\syr8OKG%O$9HDЉ&D$i9F;~Ph8#sM v ꜿ(PDAe}E%z8M)4:ͤ;XoDM}V_!s< :.!.e" yaHHHÕW^i;w05鎟l>hEn{NB:a hFq]wي3|p uax<Gt pFW℘po]荆pǺ^{YaеkW+\N;#?Gu~ РA;C#@( ?#[oM-#*ؗʁs<,rM&-9Q wи MFrl pB#uNښ7owsDQsO&-cܱb'.r8aוHhD< 1,QƐSi0fg8s@ 7llIJ~oѰzq4 >z%aGEfOx*oҡʓ߈.0 9aÆz„4C'Iʉݐ7C^F=uB=~0sg\𩓨ThQC{'48/{Ί Nh(Es 80|noexaD]A9#F1A#C !ڈOHgn;Oaxei`K\?leƆ}Fg貟2dy` $'DH%> J!S , O%e QP"/K?ν{95k%J~-hݺ5+W.SV-`y:tٳgVm~K}|8 "AG~cjԨa}}vs饗s})s^PGB  )Sz3ͳoܸ~4i5қ7o"W^/شi:˒ǶmLR̢EBBk'Oի>G#Ґ9T\|'_? 9s?~g?byرcHpNDۧYf6}k[v B}y/Bg}fӚ4ibоohSU!$4LhO֘ϟcy3cLȑL>=Ș3gNc F޽-Ǝkԛlg`Qti3{/:tF'4yoǎ!R|&¥#mqǐk׮צ|V~- !F/,\{'7Ohyf˖-e˖oYF!t`@Y%4)R$ ݻt=7ݺu $4W֬YͻvjXpB#Rbe+VٳGˠl 5kr$߱; *dE<1}:BHh믿LݺuCODf$tr!!y˛^z)f^ Dh~1,hx=-,Dz4#47WGc޽t^G-DcW^fĉ6FET!$4M0(1NhDf$"4G^#0|UT16l3r Un0aiԨO\0/K:<-Yvm āx~!ǣB*11 ӵkW{ۧiӦ6&Gl mӦ%H 7`EĶPNtb6.2[ֱ(BB#oe'y3&.\#F%4h`-[XhpMB,ǨQrn>|]a뮻.l!BtL@t-ZԖO|W_~r 4uByґ:BHh7"\hxŅ%(eTB!B7{T- $4FhB|] B!$4o%4ΛN:%_ !АB!B!$4$4B t$4N8a_f; !b3eYJ]!B{免Vha)B L+4pHh!i#4Ù^hQ !쯄B!RזB!$4$4B !BHh!BBCBC!АB!B!$4$4B !BHhYn]BpB! ܹs 1jLB!F ބFzӓ}|ZٳS%o4wqG8wyׯt־hժɒ%%W\v7o^V/hl"!=zԶ]v[qUW{Nи㏛lٲ븎$4N:uQ o !F:WVh8F׮]ÎPYh_?v-_ݻw.$x ȑ#MFL޼yM:u̚5kBo[)PM7dJGP!ʕ+gcjԨa{ィBcѦRJfǎ;ש]ɗ/>۽k6mjVj,X`otb-j+fza::dɒ7}/CymfOyM<9L(O.[n{qF~뭷"_x={B#^;DϞ=x'4WM8іņ l/^loapBs 3uT+ǧ~j>l=(߱<;v~vIs}Y!@b/Dڵkmeʔ ?CV|RA{D^xׂ~)h!qQ fqM6-Dh0s3{۷o`##AF퓔:,/-_@ _~zh Rd;\hݺ B\r%Vߞ~G/ф+K'nܠ0C(j_:D`r)K.mfΜv>ܹsw<Æ ҉q`b߾}fӦMEa.ݠK'tYKd$1`Lx8o3s y4RI`Чz >Gk,kyꫡtߠBƐ!CԫG#V+4"H1OheHA}#4qzhxYz4b A71߮ !$4.nFƏǘ12ؒ6e;覵`Lq3;cz)W(7xnpc Xk3q"!u;%VFrA&Ml0'1Č\]2^/xCE.XшO>\~+VZAF$$SALq9n䫯2Ϗ\Y~KFO90J"F{=c- !$428rub8 Xu32SMk}ꄧ@wEJׯo GNh`.;3e$2Fo 4\cdʸBe)]ABxg̺)[qך &$$4@J!h@xB#^RJh .x\%.g#4ʒr(QF\{CYΡ\#4<=ס\i)*A,\x8u8.QiBBCoI@xTB!$42}S5qPi7ln6SV-k'O:غuk;ɗ/{J; ySN tm'4eJ[oͳ͛c\y/^dϞݞV^mO>oݢsIR&7o6˗>O` ҥ)Z)V5 G^ӴiS[? ,;o|6RM5Lܹ6OhSz ?;mB O0I0lÆ }1𩧞 o1qһ1u]믿n֭[g}pk KMn2_!BF ̙3o֔)Sƌ1?~ 9s۷[צ;B;5j5ܧ;>[l! Y6K0c b 7T5h9B׊96mr9Vlݺ5j๊h0XQOO=.^1ϣѲeK[ {ڐx PBNdaܘ2eJ}}Qۗi:)ޝO[oe~'+JX)Y_l:BsYOg9r[® .76m Kg \rS"P) 4 2s3nٳ1v 0uGa؃'07pCFϞ=x ̢aL$ KyHW<F<6zׯu/K^Ž! E,[O"of)4(- Xrc4}o/iCY:SzJh`{NpbmoL< &2mYfY6Dwv<}ޒhʕ+MB2Hqw[É>1;WJ,/׷bdQkf͚~̎T`\r{ˀ!0 (3 x\Y4nb4pv~y$͠ӸǍgԩc*Z Œɻ+۵k׆VJ.]Π1?WOABCS'IJѠ20 `Y7z4nؐH`P5Pk֬gΜich`1xӧOߞ|IkX7UW? 믷yrc$]WFy4]Oh#F3Dg\_qL!iwn{lWh#x2nxb@\ŋ`Lwm946Bw &B&MdU03a1@2rQ¸ V32txK@uX%`y<Xlğ$qt B(1cX&O/fާV]OheW\q O`yk#HժUdO$zPgܩDԊW%"4Oh!?WOC`1$zD4"n= b<ֆ mw~O "xd^F_1x]88>@GՐААBHhx6fW_}}M[` +lDK,%4$4$4Hˑ>[[H^ V!Hsxw/4  B&_h &$4B$<"'#)!BTCBC!B!B!$4B!!!BHhHh!BBC!Bرc^ؕ.y۫B sNE{'oMDlHh!HO2:믿fB-?F&^BC!$4DАB m˗/Hh\Bc;H-]Ԕ,YkժefϞי;w)])PYdI/E *9gdb8*yoL6mLM 2T;6lڵF[SrISNfݻϑ) 4Zje ~1Ӷm[Svmw Y*se-`ٲe֮D4$) 4xRJ[o5'O {M"EL%LرcMÆ w={b9rbe~޽۷ɛ7ɓÎ}MbŊI ft$M7͙8qu3ϟ /:ޕϤILzL*U-Zɓ')U2dHp>kW_m֬YvouԱVP!ӸqcnjcZlireիW#Fؼ7o-pN{o-_G>t.]EbŊYrС|{vν/X jƫ/´ng|l{Žl{>}„磭L'^ d_ь3„F66e{~lg}Z䅶}'x>ocC{n~~ۺuA .lڰ~t-S bCB#FMfpi~)S56Ǐ74-Z0  iByb6y4ri̙cN8afTH߰aɝ;Yx>v^z)Xj5B n<:1y&m۶m ڵk{4֞={ZQ原?5: 6e 3h12ŋ:e&?ȑ#m}zMA! +G|Dz4)_6CDzሷtW{17y5j- ) U +VK/ԺWʟs#bH<){F65a\b]_~a N;oPϬsN\qON'g$^;AP_ӧm 8vHhkOFhx7D3k{G{zOV?ގg6Dh[n;w+!w-].\h?co6mN{\rS"P) 41X{pFPAҝ!#G@n5 Mgֱcd-rylA:|pK'w~{.p aF`I4m4 ;3hK' J6wegΜցx3+4(#>;~s"2_H΁vKܫW/;Ctۏ0xԢ폑qNmݏ3BnK%4ƀȥI,xxx"xgrAY9!PFT͚5 1x7E1,5L>~;ڛ ,[nl:3Wȷ[ `ýшu+6k>@rxg®׮];e33Ν;㨛q\{gJ~1̚5k2+w7+N`bv]Tc9c)3r"k4F#qh0~^f q3)4h#̣@|g`M <MWhic<6xͣGn$q'~m4Z{k'_|1YAx(HB5߆x 6;?}mxywXl9{l( <^nCSgAh&6E4Hs!6$4RV\&bFcӰqyꫡxΐ6j拁ull%֮# `ʲ@</XmgD=8@  xX 2J<.Rh_'N`)e:a`@r$?Œ? )˵\3&6;>ZF&M72FOh9q.|8z`hDP 7 xm̝cԩ+noAW"B:e~'=]S:گk~ȤW[m׿ғ`ix /t (o;?1|J\ >2 cۨ4(s2f!)/FF* Xq2`SxΐQp-Ep0fF Ba %Fs|' Slܸ^s^fޥh K'%eG-O5<IBCe-`@_ܡ\'q A s= ܏WDP^|$3[.]!vI@&_c0XVRF.#9BCX+ژ7~ c2߽G p ThDk~q㚔%uJ[u~K'ڸ_ݓA*4Or <(;?}_k B6b"7T@?'8e cyF,=94Qx8GB#4!"`c0)HhHh!DYЖ= ,/  mȐB!D"!B !BBCBC!B!АB!$4$4B!!B ! رC/DPUBCBC!҅عs"}=7&"6$4B j_ ~z !H[˿_h /! iHhHh!d ˗[$4.b1p@sw.]jJ,yj2gN̝;ה.](P,Y$ݗˢEL 2Ml.r?~s!S vUWŋL'I&fݺu6m߿G޽{[.BUVvpߏ;fڶmkj׮m{;+ 0X^,B֣G ,h| S.Ihlذ͛|WꧩOFe˖&K,>B_7]w]sot-4~|w"bCB#ƁLݺuM7|&%4k;۷/9uꔄF2UT9>}Z4oӦM7m(6|p3`t-4Dl2^A  <]R%s뭷'O}H"D5#H32cǎ5 6^:ڞ={b^sa`کSݻw7}33yc~mS~}랯Xbxmb馛¼9'N4ʕg򆁍HbgҤI^z ñUV5y1J2C 3q\s͚5kN: *dcƌ\rիիW#Fؼ7o-pN{o-_G>t.]EbŊYu铯{4m k:gVպuk[ ;wW} 3朏F:3Xj…rʡ>g߹.ypxBLI3شK/s-äl9?#z'x\y啦lٲIDbf)4(W/+4Μ9cfjN8ad/-- 6c…Mǎ͑#GBK ٖMO?d+צ_ 7``L;6Ư }:& ݥ}L2?~]'zikwb`5a„0 712кŋ: Őuȑ>]C=d'`C18oWh`(_6CDzAtW5ʔ7y5j- ) +V9yРA^)=cƌyaY5!X;6$~^O۴> f9a 裏q%鳑13n^yh0Yxg-bq2x@fL8;Ahydc; ܗ7nq*4~嗄@lHh@!3{pGinAkPF>ըQ̛7~v.o:3u:Xr\pg>K6|o 0 ,L(=:Icnj~{,( Ι3gu ތ ʃ(ߜW4s3s^Lnb.7A~ٙzsc}Y+Lz|v3f͚z*P( Vr!kn83j?MMuLaaLL0 Q6De{nt'4?Ynm+ލ>Dn?;zxn!Bﶃ5{eفL=׷2[Rgpz ֭[@hbEsJgfxW>^7Piʖsx.rڵkg+>oڴtGݸk fsza\\rJ;fk֬YqWZSڳefg٤_{@u5f~>kd2`icADXxB^ҙMb(R"*#L?@qٳg߉J-}}%4/>,-GD"L3GeD@lHh`0(qfcθ0eFXt7h_<nD0fɸwV@1pWc80dF̀|I{޼c#<luxBy4:th={޲eK__fOo0j֬ig*ͷ_ux+h w$"=<`K?MI$,3oN4@# ?Kz,!bh_яBܸ͉"Ɗ;~i^D?H/BALl[A!fFY4 :, 0u5͛77|M Kh8o߾d_ԩS$4*UˉN>-Ghlٲ\vevFO{w)Fƍm > 0 M-[fc4Hs9A"B+UdnVsP:o)RĔ(QºzIwرcMÆ M6fϞ=1]9rbԩSݻY/3yc~mS~}랯XbxmB馛¼9'N4ʕe /:ޕϤILz쀏VZɓǔ*U 2$"8]s5ꫯ6k֬ :u{c&=v̘1e˖vUzuz0?bw\c͡I}pm7˗9؇N~ӥKShQSX1k.{uM{_`ArW֭[̗/m )~wާO0hk3Ӊׯ# i?3g H[nn \/ ;ͥ_!BA[SLkl?n;w7zǎrXPc w.xǻauv|$DJdpdذaQc%!3b@ f1n9ah$Z@;g^znݺ\NGxg:v1`@3B^khkyc_4e9zڵ^&>eqԍF`I~a2@f͚5lƕ3+W">Cf͚~uE;uʬ<[lvM:47hk׮]0w8rP)Kp<3ƑB{ EJ^~/H!3'5XaRi2FOh9q h|8z`t1x[.РGQ~$WħРF.\Up^B#ZH~ jAQD7|S  `bm[!/x)X4i!4Yx_oIh: !`b`# r%\xKN7H1`FNGt.\ap14h%N@cʔ)߹ytyNKʒ#Hs" Ma ~˘XOe;҉;1hp?^Ayq_?Zp`4gp#\0^Cn9풧 (or"'4#S [?\+,\0!ԩSCORBh8OQ |qcJPme? ~|ߣ"5D^'4fx82Bo%br x"`,d=eE 5"2g'4/ N 43yHoM E{B fPD)UX2r\Ä< sd:^ !$4,Dhix5$4$4$4$4Hh$b{B9E[C$(x4>HhHh!DY-x4PKhHh!DA³-2>x2B!HU$4B!!!BHhHh!BBC!B!B!$4B!!!BHhHh!BB# ;#ηtRSdɋC\:w\StiS@dɒt_.-2*Tp7ߘ6mژ  hOg8q7kJkChժ5cL۶mMڵ޽{/x%]uU0B#Z~/1x`ӣG0|of)*4&L`6mj: BB#] u͛QZTF_\ۗ:uJB#@yO SGh`O>zH]sNSR%s뭷'O}H"D$cǚ Z/ ={(sa@ߩSݻw7}5yיaBHݻw~5egolٲ>J~(ÇGxO͛gj֬ic9W"&"4nj.RWogΜ1e˖5fͲߏ=jn}OkoгgO'NJ{& !q^B 1o֔)SǏ-ZJwC<1by4ri̙c;eLCvÆ &wfŶ?#^z@BcժUv`g@x6Ϥm߾^{۶m{^vm`F]`t`rϟ?-s`p{2oߗ/_n ^xPXC9֧K衇yx4GGAr ԛ/e;:ϭ!QlYNI_n)+V`A{93bF\vevJ{ׯ_G_{cg'bW'^Mԣ7n\;Eǎ`̧w}V$8Ĵil;ע-_> /y fAxi#] RnmGanvԨQ̲J 3u:brN茔8tᄗNC~{(p aFyI g< Æ hK'=XQ@;3g @ 1n9ah$Z@;^znݺ\:aGqxݼ _x"Ν;[qݻwOƍ ƞw}7lxㅐ8/ c^paҘY1p_k(|5 oyh0}t뮳ngo>0DhdL4>2^kPF]x;udطYf-gy&zڵ^&>oڴPGxgH1ށY֬YÖa\prʕ+7*ڵ/_#h1Na)=^{mAc4|v3?x3xF^yDTWח#GIr{"8kBY` v%)ݹv^*~ㅐH`P\ݝqa6 ֱ~1/G8D6bظw@O?XE~B#Qfr'|޻7npq .6'4GÛNC&ۣ-[$h9m-!ngό?0N1&)נ<oN"2s=v9G~#6W-vk7^ {5ʗ ֞Qci|4W_}56/5F|1#;#ދ4~Bv:";Hhpxr,"`]^72F#~BW2AE kD ,,6lþ p,k9o+RZ5\lp-[zѤIkXJ"&vds\Apr>Bcԩ+;vH&WhPĆЗ#%)_M@(0W\949`q^ƈо'L['4 #'0BB#YB0V< ΃Q H0O&xi]c[Bt}?T43rft. ѽ_$4N@Uɵ;e]:_/tBYRv$= >ƌ'{\L ۞&'6 ҉;vXn""(/G>uKh[nn^ ;3 m:]LGyFP: xژ%n)#\fYyJ5B^x۶i 7":}vCb9:T t)CG_26Ѧx*Ј7^0zHWosωvO=b/UyIBBCBCBCB"z`]3ӡCShQSD 3`_b LfLL ̣>jgф]Ks;6Xr_=_Jl4H,XRfMm63|?p 6pȼ:ޕuΝMMڵ9޻w=/uհaCg7525j԰et޷o_[,G+W̛7/Lhp=ʅ{ӧAʹ^z˖-kσwxpƌ\z\]t $(B}ƍI`+X#s/gΜ_`ڴi֘iڵ˺4ibƨcǎȑ#_䒇m4\oӦMGi7on?_ʔ)cz!{=oٲ 2cƌ {ǣ #FX֯_?={ _'#J*e-ZdPwy9}ix8أxWֈ8'v}Ϟ=VPF#삇 Yn|rSpak|~mVwrf]vYX~*WlǘEߨQ=yHD~'4>.qafw~b<AF㣕5K8>|1k|Sܯ ={E<,y!*ڷoՉLns4zBINw ^@DhO?0K4#pf={-z̴FA<ҥKC2Gظ2 c+1-<>lذA#j|Wt%B <^Xº;L  r&&^0h$4" 5`g9qDk,p3gMfr4m5A(Kt{b4~a;'O,ðC >$ĸq|дh" ŋBOڵkC- q,9τ l FF=lpwɊ{$M (ҩWbqE\ 5A_9e륄x7®yOBB 8K0 9+Xvڅ ziSY8|ְD^0G0'OիWF`ܓ GD0ObpNaI` K?b\/[,(]#<881%~BrA_bGe^XwʎSvuRt& HХrv=Bƻ^J Ĩw[s2iBHhivO!BBC!B !BHh!BBCBC!HBG'yT+B v^ai/eKwn!B[./t/̴BR.BqapoiBB6B;nUBqaJh!"UPJh!BBCBC!АB!B!$4$4B !BHh!BBCBC!АB!B!!!BHhHh!BBCBC!АB!$4$4B(ر|FeD~*!!2SN_eh>B\sNwe*!wB`| HFEBCBC!R Nfܰ!1ׯYV?p/B0fV٥̀F* ?ج[.!8FBB#6GFB ùsc4( !$42X|%BCgh 4ݻwgφШU={vsܹtҦ@fɒ%h=,]Ԕ,Y2Y֫WL>=a;P} ^{9љ 1]BCBîլYӔ(QoDh\uUKuQ`Aojҳ#өS'SH#GSBsmM6yWg}f?{,YBϟߴl>)+ 4|y4.}۷/>N+!$4;c^ugX eliA ;篿omri$Ǟ9s:tȎaƍv<>qͷ~knvSl٨$܃їǎ3Æ *hqHhΝ͔)Sz3ң1_vU#Gk1 4X ŋ $58ģ58xwъʔ}Y5GRxнQ^﬛bw9 !7h:t:'1'Cuhx e۶m; !zUGCD*UʼK6K.xsO!AYUP3gm3ֲgz C 5jCB62i$ 7c e '4D ;'3{43gδ߉ VT\OrЗ9oAB *Âafxǒg0K+V1 5ӀKv]4|:z$e1mڴs2Sw)|pBK'nFM3@sϞ=M6m-B#hYxKըQ̛7/y_- <%tWxHd%42j`wNlIc"+b+`)9+Z5FlAˌg_۟{иK' .}=f f)ΏǣJ*!0#FHHhsߙA_r%aG.Q…MJ̸q®)ڵk[D^\D'|"N0,\vevDh\wuv^;t=ӵkWe '45~8`}PFY @&3РЏx @\xw}OϳB\`Bgw6QHI$4VNXˎ4&\'gI'jxI_X7FB#DhPBB#hF$KhHhBB H^ ?>7wBb,YAAa-q䱄%r !!7\ 0o,؏ ה;B+ ݋<D۲e5՛AT)w(!Bco@FTpB!R !BHhHh!B!B!B!!!B !BHhHh!B!АB!$4$4B !BHhHh!B!B!$4$4Ÿ;v?ЎB駟JhHh!عsE NO>$!!!!LiÞ_ ~z ! 6m?3a8NB#B?6֭K%Ж4Q$4Ch Ν;K!-˗[$4RIhmw6gϞ }O QV-3{=ܹsMҥM̒%K.} 6t5οo>%Ks i LbF#ሢd$z* " z=1]#A@% AQ9-yHNso]k3;ygzW_Uw$ʇ~h^x>ؿw,4*QuYw\s'߅'lÆ +믿v,:BO?;OB {̮*;cm۶m۶}رckuT3kʛطo_d>!Bcq=(tR/ss֮]LSIh$4DA M> {.}%\^w+VΝ/YS;w7Oql{oTHyA"$;Ù(}WBuVH;\G_vxꩧB vG`ȑmܸ^~eKNpbeQ1a C>}0 CY2ex֯_?[bj9EmfӧO\+^zvԋ^zɮzׁ+WfϞ9v]w駟ngq5h/^IL;ЈW.DtJ,tM1^prq9c۷ &rS~{PzugDZhaVri!v'|]ڴiӬRJ.jĉ܏yvG8; ʎR>taÆ(7"d[S'okK>~ԬYӾKwh>/4ٓ#IwZ^fȈjѶfڵ{ aܸqa裏ce}I{3G4yc5jpΑ2űu9fHz"B!6Ϋ~qwq;wѢEyVR%0E'̼{Gk/?]tE֣G<_vrJWǝ;wիW/_Zl Sl|4gn2EPyyD4>p?&}ƌtFÙeC 4 %D^rZO=UZ5|x~PMNd%"&|NA?83܎7on<@TV'R"5F߾}]qC{D<-[E8+pƒ[d@Oj ]vĆFN}9*V4#UhЈy>Jq$3q='F9oVd@x gds!}쐎3 3eF"#&u)p3<^ :W wJ*W>ݺuc=6wyF˔ %BB9\]D>"z8J&'42.̙#Džo7|iՓWOQ:' 6$4$4տhь]w]8'|XB#|F.8X +UhF8}ҤIY"˗/م# dԨQvGmP\у?[W>./Gqv 7D]xرc80Btnxa% ?xg PsaMPfvϞ=K.niLWرc}Z4H!6$4ѢOgx ]v:U#S?2LTh.b pRVh#xǡVo `TNKKKs@=h.]:u1Zjeٕ ׯq,ϣ:;,k rzϏx!A:`j|s="q~1+O9QvbQͳ%*4XA}>5$4|B~)DAx_k^G 0mT"+S+,`gcIhtؾͩ)A_t΋u F֌XDNW_us,vdyT[vzXЇ!%Wխ[M7'±qW^y,o*KZ`my͞X4S7x#<Wh|Ahhm#?hi+F~27HmF9+ot.LPOhPvlcƟKhD* {}#F&AT zBc_G #Q ZS'B_' wD`ۙy@MNQ%(4/-MBHh蓐ȉB-,G)$4QhWW ! >9 ~(1֋\"΂}@$#'"CBC!B!$4$4B !BHh!BBCBC!АB!B! B!$4"4֮] B! A/4̙#!B >ƌ3,--] 8E! [ҥK>ƚ5kl̙NQB!Dj!BGBC!B!АB!B!$4B!!!B !BHh!BBCBC!B!АB!$4$4B!!B !BBCBC!B!АB!$4$4B!!B !BB !Bpb !Bp!B!!B !BHh!BHh!BBC!_)ԩSem0v?gqQvi"(NN A_8,;eSUd%ߖhO ho02 Ԥ p@]DATaD(lqQ~K E! dTaD(lG.%xE*#L*B#Ѳۿw [^8䐨 T-[ =;vk;ZGhдE{rBc &Qɲ,4ݾ={lH6D KW/_/h{FinbrkϾadj'РI{Bpo8 فHMV!>YFBbG (Tds&oŶub_/nU=vj[Y { BKTQɝy2(lڴɪ'l7tM<َ:B#4.R0`1bs9mfr͛7w6lׯ_>5mTB g5j+"t,Bcʖ:؈bŜ0A ?N7 [hk%uOhm۶rMDTx-C0ChTłAL̙3?֠AvZdɒ|ɋaSUhd׎^:0ݳ-PDE0xAh/7Q#K_6olk>f Ɩ6mw/]:6mf̘o7aΫ-,m[J:k7n5Ӥscgճޕ*+d!\=ty ʒ嫬?ޱN8=d'A瓛 A@o>f:.vi./M8/tLMIH}פ8`{+CD_뮳o6rRn]{ȣkԨQx^ [iwS"bwމ!ʱٳg}!mo߾v%ZjvW^q#W=1ӉP޴')Q?>7?r5kVm Qw?#S$wo۲eleZ҃ rFpδ-[ZODJ~}m~*OT@H+i\sH; u^m9lIQouO^^YnZjXj7[GYNProں#_`͚r1gGhnΦ͚c.[=wd) e2BMNBӑ4$7l ._""nyi9C q~ѢE%9ѣK8p뤟w=CfhTh`9Q^=$9Q0Z@DI}B Oڠpv ځt` .t#VZe_|ᄆ?ƍg{[׮]3Ch`lS:ʟ>}Iի;~rqH'/<߿06nh|M$^r>æQΝN:mL2<r]:k~DA/GkԨa˗wbs"}ޚ4i1TtiaSUhd׎?FZ!v73pl lk>:g++V}1O/?s}elO:ܼ}m {XaլSzaϾpBF5zLcruZ"Eo(W~moۓhPf)#4h 1h 9B Q%sw0XFl( /оkL\81dF5`D6 ;8}zgO<{G) Og"4?O9禮xB#vٰ02I!|.> Fu mʔ)ɟ]1C6qD/F }8`vmw>Z\vwZ T B&7uMV];&4#];!EȘRᯃIm={^:}g"Ѯ:ܴ5;lOԫk/u~YBR6bdk|>+W^̏z"'r+UvB$5/ AHkz!1Vҟ|I/tΆFEᚠ1q1XB@4"| 'u1DFf2版rYagL0r߃HU(amC"y()2:JlXôsxsMp^7cLb[Q]#6H(9QY(}j&Ǵ#OoFFŲ_aȨ8"CB#BcW1?5Ճ['cZI] Ϻҥ3 ?۝]eg+^hB6}[=zt&Ҏ-46F`[RHӰnŞ(SzH1I` pzNh`~FtgF>hh~A3G媮x;@hblOX4lX $|i;l 8mq3]9z>ZZ?~G"u}̜9s9l;D4w WQ?D)O7 *Umʬ*Q'[n<*B#vĂm`3+ô޽#"íǸr[?*gu96pA"4#:V?V7L6i+w:dikxWO\5xOp}4pPk ˹kڼe>m'ƦL+ 4Zq:uvZMR,Sygc [F6hQCm^c&>!`<ǚ4q6+UZlH2}B{ׯ_Bⅆl;#t3M}M:\W=t~5nW+ ִR5x\t`u3_z^C"L_`ODl~'l -2h6iGaΫ-,Z%<|wuVVRIZvuwM}wm!b&[nsH\yފ9ʮ*yof8|Jּe Ǟ{}/yRFh(1UAxBCv iSUhkG!*kִ_O:)Q {@h/XPm g4Ŋ'5l56sصzP†|9ʾ4M&Lj?Mm-yKWU e&!bh"7$H2#S%4ƟWhƈ /MwaV+ۆm]ٲti/n.hlBcՆ-lxZ0~ Zm e5ξ;0 Sgڴ@l,I$se2BÇDZBǠxm^:'4d"6UXFhNl7,iW-!4V(Ƥt[bO[m._g-)39 mւ4t;s}2Kd,^xBCv iSUh%ߖp˃ًġRBh66ˆQRׇے5ݺE։(3 ^b!.e}pBN8յ@MFԎǖhūlʈjo2 矝$t%>D@$ۦ #jGcK `9S">UNEF !B !BHh!BBC!BBC!B!B!B!B!$4B!$4BBC!"Hh!"ukU B!Hh U0B!3h |B!H&hL%dcIENDB`backintime-1.5.4/doc/manual/src/_images/text-plain.svg000066400000000000000000000072021477034762000226650ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/text-plain_btn.svg000066400000000000000000000127371477034762000235410ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/view-refresh.svg000066400000000000000000000154341477034762000232140ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/view-refresh_btn.svg000066400000000000000000000215211477034762000240510ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/window-close.svg000066400000000000000000000035131477034762000232130ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/window-close_btn.svg000066400000000000000000000102611477034762000240540ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/additional.md000066400000000000000000000017561477034762000211150ustar00rootroot00000000000000# Additional sources - [FAQ - Frequently Asked Questions](https://github.com/bit-team/backintime/blob/dev/FAQ.md) - [Source code documentation for developers](https://backintime-dev.readthedocs.org) - [Issue Tracker](https://github.com/bit-team/backintime/issues) - [Contributing to Back In Time](https://github.com/bit-team/backintime/blob/dev/CONTRIBUTING.md) - [Project Website at Microsoft GitHub](https://github.com/bit-team/backintime) - **Mailing list**: [bit-dev](https://mail.python.org/mailman3/lists/bit-dev.python.org) ([Archive](https://mail.python.org/archives/list/bit-dev@python.org/latest?count=200)) - **Fediverse** on **Mastodon**: [@backintime@fosstodon.org](https://fosstodon.org/@backintime) backintime-1.5.4/doc/manual/src/index.md000066400000000000000000000021601477034762000201020ustar00rootroot00000000000000# Introduction ![Back In Time main window](_images/light/main_window.png#only-light) ![Back In Time main window](_images/dark/main_window.png#only-dark) *Back In Time* is a backup solution for GNU/Linux desktops. It is based on `rsync` and uses hard links to reduce space used for unchanged files. It comes with a graphical user interface (GUI) and a command line interface (CLI). Backups are stored in plain text. They can be browsed with a normal file-browser or in terminal which makes it possible to restore files even without _Back In Time_. Files ownership, group and permissions are stored in a separate compressed plain text file (`fileinfo.bz2`). If the backup drive does not support permissions _Back In Time_ will restore permissions from `fileinfo.bz2`. So if you restore files without _Back In Time_, permissions could get lost. backintime-1.5.4/doc/manual/src/log.md000066400000000000000000000011301477034762000175500ustar00rootroot00000000000000# Log View ## Last Log View ![Last Log View](_images/light/last_log_view.png#only-light) ![Last Log View](_images/dark/last_log_view.png#only-dark) ## Snapshot Log View ![Snapshot Log View](_images/light/snapshot_log_view.png#only-light) ![Snapshot Log View](_images/dark/snapshot_log_view.png#only-dark) backintime-1.5.4/doc/manual/src/main-window.md000066400000000000000000000105431477034762000212300ustar00rootroot00000000000000# Main Window ![Back In Time main window](_images/light/main_window_sections.png#only-light) ![Back In Time main window](_images/dark/main_window_sections.png#only-dark) ## Main Toolbar ![take_snapshot](_images/document-save_btn.svg) Take Snapshot Take a new Snapshot in background. The main window can be closed during taking the snapshot. Normal behavior is to only compare files size and modification time. Alternatively, you can take a new Snapshot with `checksums` option enabled. This will calculate checksums for every file to decide if the file has changed. Taking a snapshot with checksums option takes a lot more time but it will make sure, the destination files won't be corrupt. ![refresh_snapshot](_images/view-refresh_btn.svg) Refresh Snapshots List Refresh the Snapshots in [Timeline](#timeline). ![snapshot_name](_images/gtk-edit_btn.svg) Snapshot Name Add a name for a Snapshot so you can easily identify it later. If `Don't remove named snapshots` in **Settings \--\> Auto Remove** is enabled this will also prevent the Snapshot from being removed. If this button is grayed out you need to select a snapshot in [Timeline](#timeline). ![remove_snapshot](_images/edit-delete_btn.svg) Remove Snapshot Remove one or more Snapshots from Timeline. `Now` can not be removed as this is no Snapshot but the live view of the local file-system. If this button is grayed out you need to select a snapshot in [Timeline](#timeline). ![view_log](_images/text-plain_btn.svg) View Snapshot Log View the log of the selected Snapshot. If this button is grayed out you need to select a snapshot in [Timeline](#timeline). ![view_log](_images/document-new_btn.svg) View Last Log View the log from the last snapshot attempt. ![settings](_images/gtk-preferences_btn.svg) Settings Open [*Settings*](settings.md). ![shutdown](_images/system-shutdown_btn.svg) Shutdown System after Snapshot has finished Shutdown the computer and poweroff after a snapshot has finished. The main window must stay open for this. If shutdown is not supported on the system this button will be grayed out. ![exit](_images/window-close_btn.svg) Exit Close the main window. Running Snapshots will remain in background. ![help](_images/help-contents_btn.svg) Help Menu with links to this help, FAQ, report bugs, ... ## Files Toolbar ![up](_images/go-up_btn.svg) Up Go to the parent folder. ![show_hidden](_images/show-hidden_btn.svg) Show hidden files Toggle hidden files (starting with a dot) to be shown in files view. ![restore](_images/edit-undo_btn.svg) Restore Restore selected files or folders. This button has a sub-menu (hold down the button). Default action is `Restore`. If this button is grayed out you need to select a snapshot in [Timeline](#timeline). ![restore](_images/edit-undo_btn.svg) Restore Restore the selected files or folders to the original destination. ![restore_to](_images/document-revert_btn.svg) Restore to... Restore the selected files or folders to a new destination. ![restore](_images/edit-undo_btn.svg) Restore */path* Restore the currently shown folder and all its content to the original destination. ![restore_to](_images/document-revert_btn.svg) Restore *path* to... Restore the currently shown folder and all its content to a new destination. ![snapshots](_images/file-manager_btn.svg) Snapshots Open [Snapshots dialog](snapshots-dialog.md). ## Timeline The Timeline lists all Snapshots which where already taken. You can browse them to see its contents in right hand [Files View](#files-view). The first item `Now` is not a Snapshot. It is a live view on the local file-system. It shows exact the same as your normal file browser. Multi selection is possible to remove multiple Snapshots altogether. ## Files View Depending on selection in left hand [Timeline](#timeline) this will either show the original files or the files in the selected snapshot. You can jump directly to your home or include folders in `Shortcuts`. ## Statusbar Show current status. While a snapshot is running this will show a progress-bar combined with current speed, already transferred data and the last message from `rsync`. backintime-1.5.4/doc/manual/src/quick-start.md000066400000000000000000000012731477034762000212460ustar00rootroot00000000000000# Quick Start - Start *Back In Time* from your applications menu. - Select a destination directory for backups in the *General* tab (USB drive/local directory/network location…). - Optionally, select a schedule for automatic backups (e.g. *Every week*). - In the *Include* tab, add files/directories to backup (e.g. Documents, Music…). - Save your settings with *OK*. - Start the backup operation. backintime-1.5.4/doc/manual/src/remove_retention.md000066400000000000000000000164661477034762000223750ustar00rootroot00000000000000# Remove & Retention ## Overview Snapshots can be automatically deleted or retained based on rules. These rules allow for fine-grained management of the backup archive, reducing storage space usage. The process runs at the end of every snapshot run, if no new snapshot is created. !!! note The feature was also known as _Auto-remove_ or _Smart Remove_ in earlier versions of _Back In Time_ (prior to 1.6.0). ![Dialog tab - Remove and Retention](_images/tab_remove_retention.png) Here is a brief overview of the rules available: - **Keep the most recent snapshot**: The last (or freshest) snapshot will be retained. - **Keep named snapshots**: All snapshots with a name are excluded from every rule and never removed. This is the only one rule that can not be overruled by other rules. - **Remove snapshots older than `N` Days/Weeks/Years**: Snapshots older than the specified time period are removed immediately. - **Retention policy**: A batterie of rules about which snapshots to keep. The rest will be removed immediately. - **Keep all snapshots for the last `N` days** - **Keep the last snapshot for each day/week/month for the last `N` days/weeks/months** - **Keep the last snapshot for each year for all years** - **Remove oldest snapshot if the free space is less than `N` GiB/MiB**: If the threshold of free storage space is reached, the oldest snapshots will be removed until enough storage space is available again. - **Remove oldest snapshot if the free inodes are less than `N` %**: If the threshold of free inodes is reached, the oldest snapshots will be removed until enough inodes are available again. !!! warning All rules are processed from top to bottom, as presented in the GUI or in this manual. Later rules **do override** earlier ones and are **not constrained** by them. The only exception is the first rule *Keep named snapshots*. ## Rules in details ### Keep the most recent snapshot The most recently created snapshot, in other words the freshest one, will be retained and not deleted by any of the configured rules. Despite it is present in the graphical frontend, that behavior cannot be changed. ### Keep named snapshots Beside the timestamp regularly used to identify snapshots, it is possible to attach a name to it. Those named snapshots are never touched by any other rule. It is a guarantee that they won't be removed. See [Main Window](main-window.md) for more details about named snapshots. ### Remove snapshots older than … **Remove snapshots older than `N` Years** - Calculation is based on 12 months. - Current months is ignored. - _Example_: Older than two years, at date 2025-04-17, result in removing backups before (or older than) 2023-04-01. ![Rule - Remove older than 2 years](_images/rule_older_than_n_years.png) **Remove snapshots older than `N` Weeks** - Calculation is based on calendar weeks with Monday as first day of a week. - Current week is ignored. - _Example_: Older than two weeks, at Friday 2025-08-29, result in removing backups before (or older than) Monday 2025-08-11. ![Rule - Remove older than 2 weeks](_images/rule_older_than_n_weeks.png) **Remove snapshots older than `N` Days** - Calculation is based on full days from 0:00 to 23:59. - Current day is ignored. - _Example_: Older than 3 days, at date 2025-01-10, result in removing backups before (or older than) 2025-01-07. ![Rule - Remove older than 3 days](_images/rule_older_than_n_days.png) ### Retention policy Snapshots are retained if they fit at least one of the the rules from the retention policy. All other snapshots, not covered by the retention policy, will be removed. The values specified are treated as a period rather than a count. For example, imagine keeping the last snapshot of each month for the past six months, including the current running months. However, only four of these six months have snapshots. In this case, only four snapshots are retained. The period is not extended further into the past to reach a total of six snapshots. See the rules below for more illustrated examples. **Keep all snapshots for the last `N` days** - Calculation is based on full days from 0:00 to 23:59. - Current day is considered. _Example_: ![Rule - Keep all for the last 2 days](_images/rule_keep_all_for_n_days.png) **Keep the last snapshot for each day for the last `N` days** - Calculation is based on full days from 0:00 to 23:59. - Current day is considered. _Example_: ![Rule - Keep last for each day for the last 5 days](_images/rule_keep_last_each_day_for_n_days.png) **Keep the last snapshot for each week for the last `N` weeks** - Calculation is based on full calendar weeks starting from Monday. - Current week is considered. _Example_: ![Rule - Keep last for each week for the last 4 weeks](_images/rule_keep_last_each_week_for_n_weeks.png) **Keep the last snapshot for each month for the last `N` months** - Calculation is based on full calendar months. - Current months is considered. _Example_: ![Rule - Keep last for each months for the last 4 months](_images/rule_keep_last_each_month_for_n_months.png) **Keep the last snapshot for each year for all years** - Calculation is based on calendar years. - Current year is considered. - Despite it is present in the graphical frontend, that behavior cannot be changed, if _Retention Policy_ is enabled. _Example_: ![Rule - Keep last for each year for all years](_images/rule_keep_last_each_year_for_all_years.png) ### Run in background mode on remote host The remove command can be executed on the local machine or on a remote host via SSH. The latter can save time and resources. ## Interactions between and mutual constraints of the rules All rules are applied and executed immediatily one by one and in the order as presented in the GUI and here in the manual. This contain the potential of confusing interactions between the rules. ### Example: Three years and all years. Imagine this two rules: 1. Remove snapshots older than 3 years. 2. Keep last snapshot for each year for all years. We continue to assume that multiple backups per year have been available over the past five years. Rule 2 in isolation would result in five retained backups, one for each of the five existing years. But rule 1 will be executed beforehand. Rule 1 will remove all snapshots from four and five years ago. ### Example: Six months but less storage space Imagine this two rules: 1. Keep last snapshot for each months for 6 months. 2. Remove oldest snapshots if the free space is less than 100 GiB. The consequence of rule 1 is that six snapshots are kept, one for each months. Additionally imagine some more snapshots because of the other keep rules beforehand. This consumes so much storage space that there is only 80 GiB free space left. This is less than the 100 GiB limit configured in rule 2. Because of that the two oldest snapshots (of months five and six) will be removed. After this 105 GiB storage space is available again and the rule stops. The final consequence is that snapshots of four months are kept, instead of six months as configured in rule 1. backintime-1.5.4/doc/manual/src/settings.md000066400000000000000000000264241477034762000206440ustar00rootroot00000000000000# Manage profiles ## General You can choose which mode *Back in Time* should use to store snapshots. Available modes: - [Local](#local) - [Local Encrypted](#local-encrypted) - [SSH](#ssh) - [SSH Encrypted](#ssh-encrypted) ### Local Local snapshots can be stored on internal or external hard-drives or on mounted shares. The destination file-system must support hard-links. Also the protocol used to mount the remote share must support hard-links and symlinks. By default Samba (SMB/CIFS) servers do not support symlinks (can be activated with `follow symlinks = yes` and `wide links = yes` in `/etc/samba/smb.conf`). sshfs mounted shares do not support hard-links. ![Settings - General](_images/light/settings_general.png#only-light) ![Settings - General](_images/dark/settings_general.png#only-dark) Choose the destination path for snapshots with the ![folder](_images/folder_btn.svg) Folder button (to show hidden files use CTRL + H or context menu with right mouse button). [Back in Time will create sub-folders `backintime////` inside that folder. Snapshots will be placed inside the `/` folder. ### Local Encrypted [Local Encrypted](#local-encrypted) works like [Local](#local) but the snapshots will be stored encrypted with `EncFs`. The encrypted folder will be created automatically inside the selected folder. !!! Danger A recent security audit revealed several possible attack vectors for `EncFs`. From [https://defuse.ca/audits/encfs.htm](https://defuse.ca/audits/encfs.htm): > EncFS is probably safe as long as the adversary only gets one copy of the ciphertext and nothing more. EncFS is not safe if the adversary has the opportunity to see two or more snapshots of the ciphertext at different times. EncFS attempts to protect files from malicious modification, but there are serious problems with this feature. This might be a problem with Back In Time snapshots. ![Settings - General](_images/light/settings_general_local_encrypted.png#only-light) ![Settings - General](_images/dark/settings_general_local_encrypted.png#only-dark) Enter the password for `EncFs` in `Encryption`. The password can be stored in users keyring. The keyring is unlocked with the users password during login. When running a scheduled backup-job while the user is not logged in the keyring is not available. For this case, the password can be cached in memory by Back in Time. ### SSH This mode will store snapshots on a remote host which is available through `SSH`. It will run `rsync` directly on the remote host which makes it a lot faster than syncing to a local mounted share. In order to use this mode the remote host need to be in your `known_hosts` file. Keep in mind that hostnames treated case-sensitive in that file. You need to have a public/private SSH key pair installed on the remote host. Starting with Back in Time version 1.2.0 this will be done automatically. For versions lower than 1.2.0 you need to do this manually: - If you did not login into the remote host before you need to run `ssh USER@HOST` in Terminal. You will be asked to confirm the fingerprint of the remote host-key with `yes`. In order to compare the host-key you need to login to the remote host locally and run `ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub`. The fingerprint from this output must match the fingerprint you got asked above. You can exit immediately after this. - Generate a new public/private SSH key with `ssh-keygen`. Press Enter to accept the default path and enter a password for the new key (this has nothing to do with your user-password on the remote host). - Run `ssh-copy-id -i ~/.ssh/id_rsa.pub USER@HOST` to install the newly created key on the remote host. For the last time you need to enter the login password for the remote user. If successful you should now be able to log in without being asked for your login password. ![Settings - General](_images/light/settings_general_ssh.png#only-light) ![Settings - General](_images/dark/settings_general_ssh.png#only-dark) Enter the name or IP-address of the remote host in `Host` and the port of the remote SSH-server in `Port` (default `22`). `User` need to be the remote user. `Path` can be empty to place the snapshot folder directly into remote users home folder. Relative paths without leading slash (`foo/bar/`) will be sub-folders of users home. Paths with leading slash (`/mnt/foo/bar/`) will be absolute. In `Cipher` you can choose the cipher (algorithm used to encrypt) for SSH transfer. Depending on the involved systems it could be faster to select a different cipher than default. Some of them might not work because they are known to be insecure. You can run `backintime benchmark-cipher` to compare transfer speed of all ciphers. In `Private Key` you need to select your private SSH key. If this does not yet exist, you can create a new public/private SSH key without password by clicking on ![add](_images/list-add_btn.svg) Enter the private key password in `SSH private key` (this is the password you chose above during creating the public/private key pair, not the login password for the remote user). The password can be stored in users keyring. The keyring is unlocked with the users password during login. When running a scheduled backup-job while the user is not logged in, the keyring is not available. For this case, the password can be cached in memory by Back in Time. ### SSH Encrypted SSH Encrypted](#ssh-encrypted) will work like [SSH](#ssh) but the snapshots will be stored encrypted using `encfs --reverse`. Back in Time will mount an encrypted view of the local root file-system (`/`) and sync it with `rsync` to the remote host. As [Back in Time will backup the encrypted files, all logs and status messages will show cypher text. !!! Danger A recent security audit revealed several possible attack vectors for `EncFs`. From [https://defuse.ca/audits/encfs.htm](https://defuse.ca/audits/encfs.htm): > EncFS is probably safe as long as the adversary only gets one copy of > the ciphertext and nothing more. EncFS is not safe if the adversary has > the opportunity to see two or more snapshots of the ciphertext at > different times. EncFS attempts to protect files from malicious > modification, but there are serious problems with this feature. This might be a problem with *Back In Time* snapshots. ![Settings - General](_images/light/settings_general_ssh_encrypted.png#only-light) ![Settings - General](_images/dark/settings_general_ssh_encrypted.png#only-dark) Additional to those settings from [SSH](#ssh) you need to provide a password for encryption. ### Advanced `Host`, `User` and `Profile` will be filled automatically (must not be empty). They are used for the snapshot path `backintime////`. The full snapshot path will be shown below. You can change them to match paths from other machines. ### Schedule You can choose between couple different schedules which will automatically start a new snapshot. Most of them will use `crontab` to set up new schedules. You can use `crontab -l` to view them or `crontab -e` to edit. - **At every boot/reboot**: start a new snapshot immediately after startup. This will add a `@reboot ` line in `crontab`. Wake up from suspend/hibernate will not trigger this schedule. - **Every X minutes**: start a new snapshot every 5, 10 or 30 minutes. This will add a line `*/ * * * * ` in `crontab`. - **Every hour**: start a new snapshot on every full hour. This will add a line `0 * * * * ` in `crontab`. - **Every X hours**: start a new snapshot every 2, 4, 6 or 12 hours at the full hour (e.g. at 0:00, 6:00, 12:00 and 18:00 with schedule [Every 6 hours). This will add a line `0 */ * * * ` in `crontab`. If the computer is not running at scheduled time there will be no new snapshot. This will not resume after switching on again. - **Custom Hours**: define custom pattern for `crontab`. This can be either a comma separated list of hours (e.g 0,10,13,15,17,20,23) or \*/\ (e.g. [\*/3) for periodic schedules. This will add a line `0 0,10,13,15,17,20,23 * * * ` in `crontab`. If the computer is not running at scheduled time there will be no new snapshot. This will not resume after switching on again. - **Every Day**: start a new snapshot on a configurable time on every day. If the computer is not running at the configured time there will be no new snapshot for the day. - **Repeatedly (anacron)**: this schedule will start new snapshots after a configurable time (hours, days or weeks) when the last snapshot was done before this delay. This will also work when the system was powered off. It does imitate anacron but doesn't use it. Instead Back in Time writes it's own time-stamp after each successful snapshot and add a `crontab` job which will start Back in Time every 15min (or every hour if configured for weeks). If the configured delay is not done yet it will just exit immediately. If an error occurred during taking the snapshot it won't write a new time-stamp and so will try again after 15min/one hour. - **When drive get connected (udev)**: this schedule will start a new snapshot as soon as the USB/eSATA/Firewire drive get connected. You can configure a delay (hours, days or weeks like in schedule Repeatedly) so it won't start on every new connection. This will add a new udev rule in `/etc/udev/rules.d/99-backintime-.rules` using the partitions UUID. If using KDE you need to enable auto-mount for the device in System-Settings. - **Every Week**: start a new snapshot on a configurable week-day/time every week. If the computer is not running at the configured time there will be no new snapshot for the week. - **Every Month**: start a new snapshot on a configurable day/time every month. If the computer is not running at the configured time there will be no new snapshot for the month. !!! note For hourly schedules (every hour, every x hours, and custom hours), there will be an option to specify how many minutes after the hour the schedule should run. This can be used to prevent multiple backup profiles from running at the same time. ## Include ![Settings - Include](_images/light/settings_include.png#only-light) ![Settings - Include](_images/dark/settings_include.png#only-dark) ## Exclude ![Settings - Exclude](_images/light/settings_exclude.png#only-light) ![Settings - Exclude](_images/dark/settings_exclude.png#only-dark) ## Remove & Retention Also known as _Auto-remove_ In previous versions of _Back In Time_. ![Settings - Auto Remove](_images/light/settings_autoremove.png#only-light) ![Settings - Auto Remove](_images/dark/settings_autoremove.png#only-dark) ## Options ![Settings - Options](_images/light/settings_options.png#only-light) ![Settings - Options](_images/dark/settings_options.png#only-dark) ## Expert Options ![Settings - Expert Options](_images/light/settings_expert_options.png#only-light) ![Settings - Expert Options](_images/dark/settings_expert_options.png#only-dark) ## User-callback For more information on user callback see [this](user-callback.md). backintime-1.5.4/doc/manual/src/snapshots-dialog.md000066400000000000000000000032161477034762000222550ustar00rootroot00000000000000# Snapshots dialog ![Snapshots Dialog](_images/light/snapshotsdialog.png#only-light) ![Snapshots Dialog](_images/dark/snapshotsdialog.png#only-dark) List only different Snapshots If checked only Snapshots with different file versions will be shown below. List only equal Snapshots to If checked only Snapshots with file versions equal to the Snapshot on the right will be shown below. Deep check Calculate checksums to decide if file versions are equal or different with `List only different Snapshots` or `List only equal Snapshots to`. This takes a lot more time but is more accurate, too. Restore Restore the file/folder from the selected Snapshot. Will be grayed out if `Now` or multiple Snapshots are selected. Delete Delete the file/folder from one or multiple selected Snapshots. Will be grayed out if `Now` is selected. Select All Select all Snapshots except `Now`. Snapshots Lists all Snapshots which contain the file/folder. Can be filtered with `List only different Snapshots` or `List only equal Snapshots to`. Diff Open a Side-by-Side view of the file/folder in the Snapshot above and the Snapshot in the right hand selection. Diff Options Change the Program which is used for the Side-by-Side view with `Diff`. You can use `%1` and `%2` for the paths of both Snapshots. Go To Return to the Main Window and show the file in the above selected Snapshot. backintime-1.5.4/doc/manual/src/user-callback.md000066400000000000000000000101321477034762000215010ustar00rootroot00000000000000# User callback script ## Introduction During the backup process, `Back In Time` can call a user defined script at different steps. This script is named `user-callback` and contained in the directory `$XDG_CONFIG_HOME/backintime`. By default `$XDG_CONFIG_HOME` is `~/.config`). It can also be configured via the GUI: _Manage profiles_ > _Options_ > _Edit user-callback_ (see also [Options tab in Manage profiles dialog](settings.md#options)). ## Script arguments 1. The profile id (1=Main Profile, ...). 2. Profile name. 3. Callback reason: | Value | Reason | | ----- | -------------------------------------------------------------------| | **1** | A backup process is about to start. | | **2** | A backup process has ended. | | **3** | A new snapshot was taken. The following two extra arguments are snapshot ID and snapshot path. | | **4** | There was an error. See next table for [error codes](#errorcodes). | | **5** | The (graphical) application has started. | | **6** | The (graphical) application has closed. | | **7** | Mounting a filesystem for the profile may be necessary. | | **8** | Unmounting a filesystem for the profile may be necessary. | Possible **error codes** (see _Callback reason_ **4**) are: | Code | Error | | ------| -------------------------------------------------------------------| | **1** | Configuration is either missing or invalid. | | **2** | A backup process is already running.[^1] | | **3** | Can't find snapshots folder.[^2] | | **4** | A snapshot for "now" already exists. The fifth argument is the snapshot ID. | | **5** | Error while taking a snapshot.[^3] The fifth argument contains more error information. | | **6** | New snapshot taken but with errors.[^3] The fifth argument is the snapshot ID. | ## Return value The script should return `0` if the backup should continue, any value other than `0` will cancel the backup. ## Implementation The `UserCallbackPlugin` is a class defined in [`common/plugins/usercallbackplugin.py`](https://github.com/bit-team/backintime/blob/dev/common/plugins/usercallback.plugin.py). It is a child class of `Plugin` which you can be found in [`common/pluginmanager.py`](https://github.com/bit-team/backintime/blob/dev/common/pluginmanager.py). ## Examples Several example scripts can be found in the directory `/usr/share/doc/backintime` or in the [projects repository](https://github.com/bit-team/backintime). The following is a minimal script to log all calls to user-callback to a file in `$HOME/.local/state/backintime_callback_log`. ```sh #!/bin/bash # SPDX-FileCopyrightText: © 2024 Kosta Vukicevic # SPDX-FileCopyrightText: © 2024 @daveTheOldCoder # SPDX-License-Identifier: CC0-1.0 LOG_FILE='/tmp/backintime_callback.log' # Get current time current_time=$(date +"%Y-%m-%d %H:%M:%S") # Check if file exists, if not create it touch $LOG_FILE # Append current time to the file echo -n "{$current_time}: " >> "$LOG_FILE" # Iterate through all arguments for arg in "$@" do # Append argument to the file echo -n "$arg," >> "$LOG_FILE" done # Append newline character at the end echo >> "$LOG_FILE" ``` [^1]: Ensure that manual and automatic backups do not run at the same time. [^2]: For example, if the snapshots folder is on a removable drive, which is either not mounted, or is mounted at a different location. [^3]: Supported added in _Back In Time_ version 1.4.0. backintime-1.5.4/doc/user-callback-examples/000077500000000000000000000000001477034762000207325ustar00rootroot00000000000000backintime-1.5.4/doc/user-callback-examples/README.md000066400000000000000000000011011477034762000222020ustar00rootroot00000000000000 See the user manual for further details. - [doc/manual/src/user-callback.md](https://github.com/bit-team/backintime/blob/dev/doc/manual/src/user-callback.md) - [backintime.readthedocs.io/en/latest/user-callback.html](https://backintime.readthedocs.io/en/latest/user-callback.html) backintime-1.5.4/doc/user-callback-examples/user-callback.apt-backup000077500000000000000000000017251477034762000254230ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2012-2014 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # backup selection of apt-get # Take a look at # https://github.com/bit-team/backintime/wiki/FAQ#how-to-backup-debian-ubuntu-package-selection # https://github.com/bit-team/backintime/wiki/FAQ#how-to-restore-debian-ubuntu-package-selection profile_id="$1" profile_name="$2" reason="$3" errorcode="$4" DST="$HOME/.apt-backup" case $reason in 1) #on process begin mkdir -p $DST dpkg --get-selections > $DST/package.list apt-mark showauto > $DST/pkg_auto.list apt-mark showmanual > $DST/pkg_manual.list rm -f $DST/sources.list.d/* cp -aR /etc/apt/sources.list* $DST/ apt-key exportall > $DST/repo.keys ;; esac backintime-1.5.4/doc/user-callback-examples/user-callback.default000077500000000000000000000027151477034762000250200ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2015 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Script should return 0 if everything is alright. Returncode !0 will cancel # the running snapshot (BIT version >1.1.0). profile_id="$1" profile_name="$2" reason="$3" case $reason in 1) #Backup process begins ;; 2) #Backup process ends ;; 3) #A new snapshot was taken snapshot_id="$4" snapshot_name="$5" ;; 4) #There was an error errorcode="$4" case $errorcode in 1) # ERROR The application is not configured ;; 2) # ERROR A 'take snapshot' process is already running ;; 3) # ERROR Can't find snapshots folder (is it on a removable drive ?) ;; 4) # ERROR A snapshot for 'now' already exist ;; 5) # ERROR: Error while taking a snapshot ;; 6) # ERROR: New snapshot taken but with errors ;; *) # Unknown error number ;; esac ;; 5) #backintime-qt4 (GUI) started ;; 6) #backintime-qt4 (GUI) closed ;; 7) #Mount drives ;; 8) #Unmount the drives ;; esac backintime-1.5.4/doc/user-callback-examples/user-callback.diagnostics000077500000000000000000000074711477034762000257070ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2015 Germar Reitze # SPDX-FileCopyrightText: © 2022 Jürgen Altfeld # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Script should return 0 if everything is alright. Returncode !0 will cancel # the running snapshot (BIT version >1.1.0). # This script is meant for debugging purposes only (to check when # and how the backup process is started and snapshots are taken. # You can also add further checks (eg. check for existing mounts # or readable paths to diagnose problems with inaccessible mounts). profile_id="$1" profile_name="$2" reason="$3" printLog() { # argument $1 contains the log message echo "$(date +'%Y-%m-%d %H:%M:%S') ($(whoami)/$BASHPID) profile_id=$profile_id: $1" 2>&1 >> ~/backintime_usercallback_diagnostics.log } case $reason in 1) #Backup process begins printLog "1 - backup process begins" ;; 2) #Backup process ends printLog "2 - backup process ends" ;; 3) #A new snapshot was taken snapshot_id="$4" snapshot_name="$5" printLog "3 - snapshot taken (snapshot_id=$snapshot_id - snapshot_name=$snapshot_name)" ;; 4) #There was an error errorcode="$4" msg="$5" case $errorcode in 1) # ERROR: The application is not configured printLog "4 - ERROR $errorcode: The application is not configured" ;; 2) # ERROR: A 'take snapshot' process is already running printLog "4 - ERROR $errorcode: A 'take snapshot' process is already running" ;; 3) # ERROR: Can't find snapshots folder (is it on a removable drive ?) printLog "4 - ERROR $errorcode: Can't find snapshots folder (maybe it is on a removable drive)" ;; 4) # ERROR: A snapshot for 'now' already exist printLog "4 - ERROR $errorcode: A snapshot for 'now' already exist" ;; 5) # ERROR: Error while taking a snapshot printLog "4 - ERROR $errorcode: Error while taking a snapshot" ;; 6) # ERROR: New snapshot taken but with errors printLog "4 - ERROR $errorcode: New snapshot taken but with errors (may happen with 'continue on error')" ;; *) # Unknown error number printLog "4 - ERROR $errorcode: Unknown error code!" ;; esac printLog " Error message: $msg" ;; 5) #backintime-qt4 (GUI) started printLog "5 - backintime-qt GUI started" ;; 6) #backintime-qt4 (GUI) closed printLog "6 - backintime-qt GUI closed" ;; 7) #Mount drives printLog "7 - mount drive requested" # Further diagnostics examples (use "on demand"): # Check if a mount point is in the list of mounted devices # mountPoint="/media//" # insert your mount folder here # printLog "Mount point status: $(mount | grep '$mountPoint')" # empty if not mounted! # Check if a folder does exists and is readable (eg. the snapshot target folder) # testFolder="/path/to/snapshots" # insert your path to check here # if [[ -r $testFolder ]]; then # printLog "Folder exists and can be read..." # else # printLog "Folder does not exist or cannot be read (missing permissions?)" # fi ;; 8) #Unmount the drives printLog "8 - unmount drive requested" ;; *) ## Unknown reason printLog "Called with invalid reason $reason" ;; esac backintime-1.5.4/doc/user-callback-examples/user-callback.kill_snapshot000077500000000000000000000027231477034762000262450ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2014 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # stop creating a new snapshot if conditions are not met. For example if the # source drive isn't mounted. With version >= 1.1.0 you don't need to kill # processes any more. Just return a non zero returncode. profile_id="$1" profile_name="$2" pid=$$ function ppid { cat /proc/$1/status | grep "PPid:" | cut -f2 } case $3 in 1) # Backup process begins if [ true ]; then ###INSERT YOUR CONDITIONS HERE kill $(ppid $(ppid $pid)) fi ;; 2) # Backup process ends ;; 3) # A new snapshot was taken ;; 4) #There was an error case $4 in 1) # ERROR The application is not configured ;; 2) # ERROR A 'take snapshot' process is already running ;; 3) # ERROR Can't find snapshots folder (is it on a removable drive ?) ;; 4) # ERROR A snapshot for 'now' already exist ;; 5) # ERROR: Error while taking a snapshot ;; 6) # ERROR: New snapshot taken but with errors ;; *) # Unknown error number ;; esac ;; esac backintime-1.5.4/doc/user-callback-examples/user-callback.multiple-scripts000077500000000000000000000010071477034762000267050ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2014 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . DIR="user-callback.d" typeset -i returncode=0 for callback in $(ls -1 $DIR) do if [[ -x ${DIR}/${callback} ]]; then ${DIR}/${callback} "$@" returncode+=$? fi done exit $returncode backintime-1.5.4/doc/user-callback-examples/user-callback.notify000077500000000000000000000141521477034762000247020ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2014 Fabrizio Marana # # SPDX-License-Identifier: GPL-3.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Example script for user-callback # user-callback is a script called by backintime (http://backintime.le-web.org) # before, during and after a backup. # Note: # To allow the notify-send "expire-time" parameter to work, # follow http://www.webupd8.org/2014/04/configurable-notification-bubbles-for.html # To allow mail to be sent, the "mailutils" package must be installed and # configured and there must be a MTA (Mail Transport Agent) e.g. "postfix" # or "exim4" installed and configured: # sudo apt-get install mailutils # sudo apt-get install postfix # https://www.google.com/search?q=linux+configure+mailutils # Version 0.2 DD 2014/11/08 Change as much fixed text to variables to allow # others to modify more easily # Polish code to make it more readable # TO DO: Use rsync instead of cpio ### Init ### # You need to configure this before using this script declare szBackInTimeEMailAddress="" # If empty, no mail will be sent on error declare szBackupVolume="" # If empty, no finalizing will be performed # BackInTime passes arguments on the command line. Name them for clarity. declare iBackInTimeProfileID="$1" declare szBackInTimeProfileName="$2" declare iBackInTimeStatus="$3" declare iBackInTimeSnapshotID="$4" declare szBackInTimeSnapshotName="$5" ### main ### case $iBackInTimeStatus in 1) ## Backup Starting ## # Here you should put commands that you need JUST before the backup begins, E.g.: # stop daemons/services, ... notify-send --urgency=LOW --icon=face-plain "BackInTime" \ "Starting backup '${iBackInTimeProfileID}:${szBackInTimeProfileName}'..." ;; 2) ## Backup Finished ## notify-send --urgency=NORMAL --icon=face-laugh "BackInTime" \ "Finished backup '${iBackInTimeProfileID}:${szBackInTimeProfileName}' completely!" # Optional notification via zenity (uncomment to enable): # zenity --info --title="BackInTime" --text "BackInTime backup for profile ${iBackInTimeProfileID} (${szBackInTimeProfileName}) completed" & # Here you should put the commands that you need after the backup ends, E.g.: # (Probably the reverse of the 1) section) # allow the user to try again later, ... ;; 3) ## Backup Finishing ## notify-send --urgency=NORMAL --icon=face-cool --expire-time=4000 "BackInTime" \ "Finishing backup '${iBackInTimeProfileID}:${szBackInTimeProfileName}'\nfor snapshot '${iBackInTimeSnapshotID}:${szBackInTimeSnapshotName}'..." # Here you should put the commands that you need to do just before the backup finishes: # Copying extra files, # writing to logs, ... ;; 4) # An error occurred: $iBackInTimeSnapshotID contains the error number declare -r iBackInTimeError=$iBackInTimeSnapshotID declare szBackInTimeErrorMessage="BackInTime Error: " declare szBackInTimeExtendedErrorMessage="" # We're notifying the user on-screen and emailing the log file # using the mailutils package regardless of the kind of error case $iBackInTimeError in 1) ## Application not configured ## szBackInTimeErrorMessage=$szBackInTimeErrorMessage" Application not configured!" ;; 2) ## Application already Running ## szBackInTimeErrorMessage=$szBackInTimeErrorMessage" BackInTime is already running!" szBackInTimeExtendedErrorMessage="\n\nPlease ensure you don't have an automatic backup and a manual backup both running at once." ;; 3) ## No snapshot Directory ## szBackInTimeErrorMessage=$szBackInTimeErrorMessage" BackInTime can’t find the snapshots directory!" szBackInTimeExtendedErrorMessage="\n\n(Is it on a removable drive which was detached/unmounted in error?)" ;; 4) ## Snapshot already exixsts ## szBackInTimeErrorMessage=$szBackInTimeErrorMessage" A snapshot for 'now' already exists!" ;; 5) # ERROR: Error while taking a snapshot szBackInTimeErrorMessage=$szBackInTimeErrorMessage" Error while taking a snapshot" ;; 6) # ERROR: New snapshot taken but with errors szBackInTimeErrorMessage=$szBackInTimeErrorMessage" New snapshot taken but with errors" szBackInTimeExtendedErrorMessage="\n\nMay happen with 'continue on error'" ;; *) # Unknown error number szBackInTimeErrorMessage=$szBackInTimeErrorMessage" Unknown error code!" ;; esac # Error notify-send --urgency=CRITICAL --icon=face-angry "BackInTime Error" "$szBackInTimeErrorMessage$szBackInTimeExtendedErrorMessage" # only send mail if the e-mail address is not empty if [ -n "$szBackInTimeEMailAddress" ] && \ [ "x$(which mail)" != "x" ] && \ [ -x $(which mail) ]; then cat ~/.local/share/backintime/takesnapshot_.log | mail -s "BackInTime backup for profile ${iBackInTimeProfileID} (${szBackInTimeProfileName}) failed on $(date +%Y-%m-%d_%H-%M-%S) with error $szBackInTimeErrorMessage" $szBackInTimeEMailAddress fi # Optional notification via zenity (uncomment to enable): # zenity --error --title="BackInTime" --text="BackInTime backup for profile ${iBackInTimeProfileID} (${szBackInTimeProfileName}) failed on $(date +%Y-%m-%d_%H-%M-%S) with error $szBackInTimeErrorMessagee" & ;; 5) ## backintime-qt4 (GUI) started ## # Here you can put things that need to be done when launching the GUI ;; 6) ## backintime-qt4 (GUI) closed ## # Here you can put things that need to be done when closing the GUI ;; 7) ## Mount drives ## # Here you should place custom mount commands which will be called every # time the GUI or command line tool is started or the profile is # switched in GUI ;; 8) ## Unmount the drives ## # Here you should place unmount scripts for the drive you mounted in 7) ;; esac #Status backintime-1.5.4/doc/user-callback-examples/user-callback.sendmail000077500000000000000000000032731477034762000251700ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2014 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Script should return 0 if everything is alright. Returncode !0 will cancel # the running snapshot (BIT version >1.1.0). email="foo@bar" profile_id="$1" profile_name="$2" reason="$3" errorcode="$4" function send_mail { subject="Backintime $profile_name: $1" shift echo -e "$(date) \n$@" | mail -s "$subject" $email } function log_id { if [ $profile_id -gt 1 ]; then echo $profile_id else echo "" fi } case $reason in 1) send_mail "Backup process begins" ;; 2) send_mail "Backup process ends" "$(cat ~/.local/share/backintime/takesnapshot_$(log_id).log)" ;; 3) send_mail "A new snapshot was taken" ;; 4) #There was an error case $errorcode in 1) send_mail "ERROR" "The application is not configured" ;; 2) send_mail "ERROR" "A 'take snapshot' process is already running" ;; 3) send_mail "ERROR" "Can't find snapshots folder (is it on a removable drive ?)" ;; 4) send_mail "ERROR" "A snapshot for 'now' already exist" ;; 5) send_mail "ERROR" "Error while taking a snapshot" ;; 6) send_mail "ERROR" "New snapshot taken but with errors" ;; *) send_mail "ERROR" "Unknown error number" ;; esac ;; esac backintime-1.5.4/doc/user-callback-examples/user-callback.ssid000077500000000000000000000015701477034762000243340ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2012-2016 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # This script will check if you're connected to the correct WLAN (based on SSID) # In this example it will break new snapshots for profile 1 if not in 'HOME_WLAN' # and for profile 2 if not in 'WLAN_AT_WORK' profile_id="$1" profile_name="$2" reason="$3" check_ssid() { if [ $(iwconfig 2>/dev/null | grep -c "ESSID:\"$1\"") -eq 0 ]; then return 1 fi } case $reason in 1) #Backup process begins case $profile_id in 1) check_ssid "HOME_WLAN"; exit $?;; 2) check_ssid "WLAN_AT_WORK"; exit $?;; esac ;; esac backintime-1.5.4/make-tarball.sh000077500000000000000000000023551477034762000165410ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2013 Oprea Dan # SPDX-FileCopyrightText: © 2013 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . VER=`cat VERSION` CURRENT=$(pwd) NEW="backintime-$VER" # clean up rm ./common/man/C/*.gz cd .. # if [[ -n "$(which git)" ]] && [[ -x "$(which git)" ]]; then # git clone ${CURRENT} ${NEW} # else # cp -aR ${CURRENT} ${NEW} # fi cp --exclude=.git -aR ${CURRENT} ${NEW} rm backintime-$VER.tar.gz tar cfz backintime-$VER.tar.gz \ --exclude="*/__pycache__" \ --exclude="*/.pytest_cache" \ --exclude="*/.ruff_cache" \ --exclude="*/po/*.mo" \ --exclude-vcs \ ${NEW}/AUTHORS \ ${NEW}/CHANGES \ ${NEW}/LICENSE \ ${NEW}/README.md \ ${NEW}/FAQ.md \ ${NEW}/CONTRIBUTING.md \ ${NEW}/HISTORY.md \ ${NEW}/TRANSLATIONS \ ${NEW}/VERSION \ ${NEW}/updateversion.sh \ ${NEW}/common \ ${NEW}/qt \ ${NEW}/LICENSES \ ${NEW}/doc tar -tzf backintime-$VER.tar.gz echo "" echo "RESULT:" realpath backintime-$VER.tar.gz # rm -rf backintime-$VER backintime-1.5.4/qt/000077500000000000000000000000001477034762000142655ustar00rootroot00000000000000backintime-1.5.4/qt/aboutdlg.py000066400000000000000000000114341477034762000164430ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """The About dialog.""" import re import pathlib from PyQt6.QtWidgets import (QLabel, QVBoxLayout, QHBoxLayout, QDialog, QDialogButtonBox) from PyQt6.QtCore import Qt, QSize import tools import backintime import messagebox class AboutDlg(QDialog): """The about dialog accessible from the Help menu in the main window.""" def __init__(self, parent=None): """Initialize and layout.""" super().__init__(parent) self.parent = parent self.config = parent.config import icon # pylint: disable=import-outside-toplevel self.setWindowTitle(_('About') + ' ' + self.config.APP_NAME) logo = QLabel('Icon') logo.setPixmap(icon.BIT_LOGO.pixmap(QSize(48, 48))) name = self._create_name_and_version_label() homepage = QLabel( self._to_a_href('https://github.com/bit-team/backintime')) homepage.setTextInteractionFlags( Qt.TextInteractionFlag.LinksAccessibleByMouse) homepage.setOpenExternalLinks(True) bit_copyright = QLabel(self.config.COPYRIGHT + '\n') vlayout = QVBoxLayout(self) hlayout = QHBoxLayout() hlayout.addWidget(logo) hlayout.addWidget(name) hlayout.addStretch() vlayout.addLayout(hlayout) vlayout.addWidget(homepage) vlayout.addWidget(bit_copyright) button_box_left = QDialogButtonBox(self) for label, slot in ((_('Authors'), self._msgbox_authors), (_('Translations'), self._msgbox_translations), (_('License'), self._msgbox_license)): btn = button_box_left.addButton( label, QDialogButtonBox.ButtonRole.ActionRole) btn.clicked.connect(slot) button_box_right = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok) button_box_right.accepted.connect(self.accept) hlayout = QHBoxLayout() hlayout.addWidget(button_box_left) hlayout.addWidget(button_box_right) vlayout.addLayout(hlayout) def _create_name_and_version_label(self): version = backintime.__version__ info = tools.get_git_repository_info( # should be the repos root folder path=pathlib.Path(__file__).parent.parent, hash_length=8) try: git_version \ = f" git branch '{info['branch']}' hash '{info['hash']}'" except TypeError: git_version = '' name = QLabel( f'

{self.config.APP_NAME} {version}

{git_version}') name.setAlignment( Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop) return name def _msgbox_authors(self): file_path = pathlib.Path(tools.docPath()) / 'AUTHORS' content = self._read_about_content(file_path) return messagebox.showInfo(self, _('Authors'), content) def _msgbox_translations(self): file_path = pathlib.Path(tools.docPath()) / 'TRANSLATIONS' content = self._read_about_content(file_path) return messagebox.showInfo(self, _('Translations'), content) def _msgbox_license(self): file_path = pathlib.Path(tools.docPath()) / 'LICENSE' content = self._read_about_content(file_path) return messagebox.showInfo(self, _('License'), content) def _read_about_content(self, file_path): content = file_path.read_text('utf-8') # Convert URLs and Email into content = re.sub(r'<(.*?)>', self._to_a_href, content) # HTML line breaks content = re.sub(r'\n', '
', content) return content def _to_a_href(self, m): """Create a HTML a-tag out of Website and EMail URIs. Args: m (str, re.Match): Match or string to convert. Examples: - 'https://foo.bar' becomes '
https://foo.bar' - 'foo@bar.com' becomes 'foo@bar.com' """ try: raw_string = m.group(1) except AttributeError: raw_string = m if '@' in raw_string: return f'{raw_string}' return f'{raw_string}' backintime-1.5.4/qt/app.py000066400000000000000000002564011477034762000154270ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # SPDX-FileCopyrightText: © 2025 Samuel Moore # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import sys if not os.getenv('DISPLAY', ''): os.putenv('DISPLAY', ':0.0') import pathlib import re import json import subprocess import shutil import textwrap import signal from contextlib import contextmanager from tempfile import TemporaryDirectory # We need to import common/tools.py import qttools_path qttools_path.registerBackintimePath('common') # Workaround until the codebase is rectified/equalized. import tools tools.initiate_translation(None) import qttools import backintime import bitbase import config import tools import logger import snapshots import guiapplicationinstance import mount import progress import encfsmsgbox from exceptions import MountException from statedata import StateData from PyQt6.QtGui import (QAction, QActionGroup, QShortcut, QDesktopServices, QPalette, QIcon, QFileSystemModel) from PyQt6.QtWidgets import (QWidget, QFrame, QMainWindow, QToolButton, QLabel, QLineEdit, QCheckBox, QListWidget, QTreeView, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QStyledItemDelegate, QVBoxLayout, QStackedLayout, QSplitter, QGroupBox, QMenu, QToolBar, QProgressBar, QMessageBox, QInputDialog, QDialog, QApplication, ) from PyQt6.QtCore import (QDir, QEvent, QObject, QPoint, pyqtSlot, pyqtSignal, QSortFilterProxyModel, Qt, QTimer, QThread, QUrl) import snapshotsdialog import logviewdialog import languagedialog import messagebox import qttools import version from manageprofiles import SettingsDialog from restoredialog import RestoreDialog from restoreconfigdialog import RestoreConfigDialog from usermessagedialog import UserMessageDialog from aboutdlg import AboutDlg from statedata import StateData class MainWindow(QMainWindow): def __init__(self, config, appInstance, qapp): QMainWindow.__init__(self) self.config = config self.appInstance = appInstance self.qapp = qapp self.snapshots = snapshots.Snapshots(config) self.lastTakeSnapshotMessage = None self.tmpDirs = [] self.firstUpdateAll = True self.disableProfileChanged = False # "Magic" object handling shutdown procedure in different desktop # environments. self.shutdown = tools.ShutDown() # Import on module level not possible because of Qt restrictions. import icon globals()['icon'] = icon # window icon self.qapp.setWindowIcon(icon.BIT_LOGO) state_data = StateData() # shortcuts without buttons self._create_shortcuts_without_actions() self._create_actions() self._create_menubar() self._create_main_toolbar() # timeline (left widget) self.timeLine = qttools.TimeLine(self) self.timeLine.updateFilesView.connect(self.updateFilesView) # right widget self.filesWidget = QGroupBox(self) filesLayout = QVBoxLayout(self.filesWidget) left, top, right, bottom = filesLayout.getContentsMargins() filesLayout.setContentsMargins(0, 0, right, 0) # main splitter self.mainSplitter = QSplitter(Qt.Orientation.Horizontal, self) self.mainSplitter.addWidget(self.timeLine) self.mainSplitter.addWidget(self.filesWidget) # FilesView toolbar self.toolbar_filesview = self._create_and_get_filesview_toolbar() filesLayout.addWidget(self.toolbar_filesview) # mouse button navigation self.mouseButtonEventFilter = ExtraMouseButtonEventFilter(self) self.setMouseButtonNavigation() # second splitter: # part of files-layout self.secondSplitter = QSplitter(self) self.secondSplitter.setOrientation(Qt.Orientation.Horizontal) self.secondSplitter.setContentsMargins(0, 0, 0, 0) filesLayout.addWidget(self.secondSplitter) # places self.places = QTreeWidget(self) self.places.setRootIsDecorated(False) self.places.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.places.setHeaderLabel(_('Shortcuts')) self.places.header().setSectionsClickable(True) self.places.header().setSortIndicatorShown(True) self.places.header().setSectionHidden(1, True) self.places.header().setSortIndicator( int(self.config.profileIntValue('qt.places.SortColumn', 1)), Qt.SortOrder(self.config.profileIntValue( 'qt.places.SortOrder', Qt.SortOrder.AscendingOrder)) ) self.placesSortLoop = {self.config.currentProfile(): False} self.secondSplitter.addWidget(self.places) self.places.header().sortIndicatorChanged.connect(self.sortPlaces) # files view stacked layout widget = QWidget(self) self.stackFilesView = QStackedLayout(widget) self.secondSplitter.addWidget(widget) # folder don't exist label self.lblFolderDontExists = QLabel( _("This directory doesn't exist\n" "in the current selected snapshot."), self) qttools.setFontBold(self.lblFolderDontExists) self.lblFolderDontExists.setFrameShadow(QFrame.Shadow.Sunken) self.lblFolderDontExists.setFrameShape(QFrame.Shape.Panel) self.lblFolderDontExists.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter) self.stackFilesView.addWidget(self.lblFolderDontExists) # list files view self.filesView = QTreeView(self) self.stackFilesView.addWidget(self.filesView) self.filesView.setRootIsDecorated(False) self.filesView.setAlternatingRowColors(True) self.filesView.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.filesView.setItemsExpandable(False) self.filesView.setDragEnabled(False) self.filesView.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.filesView.header().setSectionsClickable(True) self.filesView.header().setSectionsMovable(False) self.filesView.header().setSortIndicatorShown(True) self.filesViewModel = QFileSystemModel(self) self.filesViewModel.setRootPath(QDir().rootPath()) self.filesViewModel.setReadOnly(True) self.filesViewModel.setFilter(QDir.Filter.AllDirs | QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot | QDir.Filter.Hidden) self.filesViewProxyModel = QSortFilterProxyModel(self) self.filesViewProxyModel.setDynamicSortFilter(True) self.filesViewProxyModel.setSourceModel(self.filesViewModel) self.filesView.setModel(self.filesViewProxyModel) self.filesViewDelegate = QStyledItemDelegate(self) self.filesView.setItemDelegate(self.filesViewDelegate) sortColumn, sortOrder = state_data.files_view_sorting self.filesView.header().setSortIndicator( sortColumn, Qt.SortOrder(sortOrder)) self.filesViewModel.sort( self.filesView.header().sortIndicatorSection(), self.filesView.header().sortIndicatorOrder()) self.filesView.header() \ .sortIndicatorChanged.connect(self.filesViewModel.sort) self.stackFilesView.setCurrentWidget(self.filesView) # self.setCentralWidget(self.mainSplitter) # context menu for Files View self.filesView.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) self.filesView.customContextMenuRequested \ .connect(self.contextMenuClicked) self.contextMenu = QMenu(self) self.contextMenu.addAction(self.act_restore) self.contextMenu.addAction(self.act_restore_to) self.contextMenu.addAction(self.act_snapshots_dialog) self.contextMenu.addSeparator() self.btnAddInclude = self.contextMenu.addAction( icon.ADD, _('Add to Include')) self.btnAddExclude = self.contextMenu.addAction( icon.ADD, _('Add to Exclude')) self.btnAddInclude.triggered.connect(self.btnAddIncludeClicked) self.btnAddExclude.triggered.connect(self.btnAddExcludeClicked) self.contextMenu.addSeparator() self.contextMenu.addAction(self.act_show_hidden) # ProgressBar layoutWidget = QWidget() layout = QVBoxLayout(layoutWidget) layout.setContentsMargins(0, 0, 0, 0) layoutWidget.setContentsMargins(0, 0, 0, 0) layoutWidget.setLayout(layout) self.progressBar = QProgressBar(self) self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(0) self.progressBar.setTextVisible(False) self.progressBar.setContentsMargins(0, 0, 0, 0) self.progressBar.setFixedHeight(5) self.progressBar.setVisible(False) self.progressBarDummy = QWidget() self.progressBarDummy.setContentsMargins(0, 0, 0, 0) self.progressBarDummy.setFixedHeight(5) self.status = QLabel(self) self.status.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.status) layout.addWidget(self.progressBar) layout.addWidget(self.progressBarDummy) self.statusBar().addWidget(layoutWidget, 100) self.status.setText(_('Done')) self.snapshotsList = [] self.sid = snapshots.RootSnapshot(self.config) self.path = self.config.profileStrValue('qt.last_path', '/') self.widget_current_path.setText(self.path) self.path_history = tools.PathHistory(self.path) # restore position and size try: self.move(*state_data.mainwindow_coords) self.resize(*state_data.mainwindow_dims) except KeyError: pass self.mainSplitter.setSizes( state_data.mainwindow_main_splitter_widths) self.secondSplitter.setSizes( state_data.mainwindow_second_splitter_widths) # FilesView: Column width try: files_view_col_widths = state_data.files_view_col_widths except KeyError: pass else: for idx, width in enumerate(files_view_col_widths): self.filesView.header().resizeSection(idx, width) # Release Candidate if version.is_release_candidate(): last_vers = state_data.msg_release_candidate if last_vers != version.__version__: state_data.msg_release_candidate = version.__version__ self._open_release_candidate_dialog() # Force dialog to import old configuration if not config.isConfigured(): message = _( '{app_name} appears to be running for the first time as no ' 'configuration is found.' ).format(app_name=self.config.APP_NAME) message = f'{message}\n\n' message = message + _( 'Import an existing configuration (from a backup target ' 'directory or another computer)?') answer = messagebox.warningYesNo(self, message) if answer == QMessageBox.StandardButton.Yes: RestoreConfigDialog(self).exec() SettingsDialog(self).exec() if not config.isConfigured(): return profile_id = config.currentProfile() # mount try: mnt = mount.Mount(cfg=self.config, profile_id=profile_id, parent=self) hash_id = mnt.mount() except MountException as ex: messagebox.critical(self, str(ex)) else: self.config.setCurrentHashId(hash_id) if not config.canBackup(profile_id): msg = _("Can't find snapshots directory.") + '\n' \ + _('If it is on a removable drive please plug it in and then ' 'press OK.') messagebox.critical(self, msg) self.filesViewProxyModel.layoutChanged.connect(self.dirListerCompleted) # populate lists self.updateProfiles() self.comboProfiles.currentIndexChanged \ .connect(self.comboProfileChanged) self.filesView.setFocus() self.updateSnapshotActions() # signals self.timeLine.itemSelectionChanged.connect(self.timeLineChanged) self.places.currentItemChanged.connect(self.placesChanged) self.filesView.activated.connect(self.filesViewItemActivated) self.forceWaitLockCounter = 0 self.timerRaiseApplication = QTimer(self) self.timerRaiseApplication.setInterval(1000) self.timerRaiseApplication.setSingleShot(False) self.timerRaiseApplication.timeout.connect(self.raiseApplication) self.timerRaiseApplication.start() self.timerUpdateTakeSnapshot = QTimer(self) self.timerUpdateTakeSnapshot.setInterval(1000) self.timerUpdateTakeSnapshot.setSingleShot(False) self.timerUpdateTakeSnapshot.timeout.connect(self.updateTakeSnapshot) self.timerUpdateTakeSnapshot.start() SetupCron(self).start() # Countdown of manual GUI starts finished? if 0 == state_data.manual_starts_countdown(): # Do nothing if English is the current used language if self.config.language_used != 'en': # Show the message only if the current used language is # translated equal or less then {cutoff}% self._open_approach_translator_dialog(cutoff=99) # BIT counts down how often the GUI was started. Until the end of that # countdown a dialog with a text about contributing to translating # BIT is presented to the users. state_data.decrement_manual_starts_countdown() # If the encfs-deprecation warning in its latest stage was not shown # yet. if state_data.msg_encfs_global < bitbase.ENCFS_MSG_STAGE: # Are there profiles using EncFS? encfs_profiles = [] for pid in self.config.profiles(): if 'encfs' in self.config.snapshotsMode(pid): encfs_profiles.append( f'{self.config.profileName(pid)} ({pid})') # EncFS deprecation warning (#1734, #1735) if encfs_profiles: state_data.msg_encfs_global = bitbase.ENCFS_MSG_STAGE dlg = encfsmsgbox.EncfsExistsWarning(self, encfs_profiles) dlg.exec() @property def showHiddenFiles(self): state_data = StateData() return state_data.mainwindow_show_hidden @showHiddenFiles.setter def showHiddenFiles(self, value): state_data = StateData() state_data.mainwindow_show_hidden = value def _create_actions(self): """Create all action objects used by this main window. All actions are stored as instance attributes to ``self`` and their names begin with ``act_``. The actions can be added to GUI elements (menu entries, buttons) in later steps. Note: All actions used in the main window and its child widgets should be created in this function. Note: Shortcuts need to be strings in a list even if it is only one entry. It is done this way to spare one ``if...else`` statement deciding between `QAction.setShortcuts()` and `QAction.setShortcut()` (singular; without ``s`` at the end). """ action_dict = { # because of "icon" # pylint: disable=undefined-variable # 'Name of action attribute in "self"': ( # ICON, Label text, # trigger_handler_function, # keyboard shortcuts (type list[str]) # tooltip # ), 'act_take_snapshot': ( icon.TAKE_SNAPSHOT, _('Take a snapshot'), self.btnTakeSnapshotClicked, ['Ctrl+S'], _('Use modification time & size for file change detection.')), 'act_take_snapshot_checksum': ( icon.TAKE_SNAPSHOT, _('Take a snapshot (checksum mode)'), self.btnTakeSnapshotChecksumClicked, ['Ctrl+Shift+S'], _('Use checksums for file change detection.')), 'act_pause_take_snapshot': ( icon.PAUSE, _('Pause snapshot process'), lambda: os.kill(self.snapshots.pid(), signal.SIGSTOP), None, None), 'act_resume_take_snapshot': ( icon.RESUME, _('Resume snapshot process'), lambda: os.kill(self.snapshots.pid(), signal.SIGCONT), None, None), 'act_stop_take_snapshot': ( icon.STOP, _('Stop snapshot process'), self.btnStopTakeSnapshotClicked, None, None), 'act_update_snapshots': ( icon.REFRESH_SNAPSHOT, _('Refresh snapshot list'), self.btnUpdateSnapshotsClicked, ['F5', 'Ctrl+R'], None), 'act_name_snapshot': ( icon.SNAPSHOT_NAME, _('Name snapshot'), self.btnNameSnapshotClicked, ['F2'], None), 'act_remove_snapshot': ( icon.REMOVE_SNAPSHOT, _('Remove snapshot'), self.btnRemoveSnapshotClicked, ['Delete'], None), 'act_snapshot_logview': ( icon.VIEW_SNAPSHOT_LOG, _('View snapshot log'), self.btnSnapshotLogViewClicked, None, None), 'act_last_logview': ( icon.VIEW_LAST_LOG, _('View last log'), self.btnLastLogViewClicked, None, None), 'act_settings': ( icon.SETTINGS, _('Manage profiles…'), self.btnSettingsClicked, ['Ctrl+Shift+P'], None), 'act_shutdown': ( icon.SHUTDOWN, _('Shutdown'), None, None, _('Shut down system after snapshot has finished.')), 'act_setup_language': ( icon.LANGUAGE, _('Setup language…'), self.slot_setup_language, None, None), 'act_quit': ( icon.EXIT, _('Exit'), self.close, ['Ctrl+Q'], None), 'act_help_user_manual': ( icon.HELP, _('User manual'), self.btn_help_user_manual, ['F1'], _('Open user manual in browser (local if ' 'available otherwise online)'), ), 'act_help_man_backintime': ( icon.HELP, _('man page: Back In Time'), self.btn_help_man_backintime, None, _('Displays man page about Back In Time (backintime)') ), 'act_help_man_config': ( icon.HELP, _('man page: Profiles config file'), self.btn_help_man_config, None, _('Displays man page about profiles config file ' '(backintime-config)') ), 'act_help_website': ( icon.WEBSITE, _('Project website'), self.btnWebsiteClicked, None, _('Open Back In Time website in browser')), 'act_help_changelog': ( icon.CHANGELOG, _('Changelog'), self.btnChangelogClicked, None, None), 'act_help_faq': ( icon.FAQ, _('FAQ'), self.btnFaqClicked, None, _('Open Frequently Asked Questions (FAQ) in browser')), 'act_help_question': ( icon.QUESTION, _('Ask a question'), self.btnAskQuestionClicked, None, None), 'act_help_bugreport': ( icon.BUG, _('Report a bug'), self.btnReportBugClicked, None, None), 'act_help_translation': ( icon.LANGUAGE, _('Translation'), self.slot_help_translation, None, _('Shows the message about participation ' 'in translation again.')), 'act_help_encryption': ( icon.ENCRYPT, _('Encryption Transition (EncFS)'), self.slot_help_encryption, None, _('Shows the message about EncFS removal again.')), 'act_help_about': ( icon.ABOUT, _('About'), self.btnAboutClicked, None, None), 'act_restore': ( icon.RESTORE, _('Restore'), self.restoreThis, None, _('Restore the selected files or directories to the ' 'original destination.')), 'act_restore_to': ( icon.RESTORE_TO, _('Restore to …'), self.restoreThisTo, None, _('Restore the selected files or directories to a ' 'new destination.')), 'act_restore_parent': ( icon.RESTORE, None, # text label is set elsewhere self.restoreParent, None, _('Restore the currently shown directory and all its contents ' 'to the original destination.')), 'act_restore_parent_to': ( icon.RESTORE_TO, None, # text label is set elsewhere self.restoreParentTo, None, _('Restore the currently shown directory and all its contents ' 'to a new destination.')), 'act_folder_up': ( icon.UP, _('Up'), self.btnFolderUpClicked, ['Alt+Up', 'Backspace'], None), 'act_show_hidden': ( icon.SHOW_HIDDEN, _('Show hidden files'), None, ['Ctrl+H'], None), 'act_snapshots_dialog': ( icon.SNAPSHOTS, _('Compare snapshots…'), self.btnSnapshotsClicked, None, None), } for attr in action_dict: ico, txt, slot, keys, tip = action_dict[attr] # Create action (with icon) action = QAction(ico, txt, self) if ico else \ QAction(txt, self) # Connect handler function if slot: action.triggered.connect(slot) # Add keyboardshortcuts if keys: action.setShortcuts(keys) # Tooltip if tip: action.setToolTip(tip) # populate the action to "self" setattr(self, attr, action) # Release Candidate ? self.act_help_release_candidate = None if version.is_release_candidate(): # pylint: disable=undefined-variable action = QAction(icon.QUESTION, _('Release Candidate'), self) action.triggered.connect(self.slot_help_release_candidate) action.setToolTip( _('Shows the message about this Release Candidate again.')) self.act_help_release_candidate = action # Fine tuning self.act_shutdown.toggled.connect(self.btnShutdownToggled) self.act_shutdown.setCheckable(True) self.act_shutdown.setEnabled(self.shutdown.canShutdown()) self.act_pause_take_snapshot.setVisible(False) self.act_resume_take_snapshot.setVisible(False) self.act_stop_take_snapshot.setVisible(False) self.act_show_hidden.setCheckable(True) self.act_show_hidden.setChecked(self.showHiddenFiles) self.act_show_hidden.toggled.connect(self.btnShowHiddenFilesToggled) def _create_shortcuts_without_actions(self): """Create shortcuts that are not related to a visual element in the GUI and don't have an QAction instance because of that. """ shortcut_list = ( ('Alt+Left', self.btnFolderHistoryPreviousClicked), ('Alt+Right', self.btnFolderHistoryNextClicked), ('Alt+Down', self.btnOpenCurrentItemClicked), ) for keys, slot in shortcut_list: shortcut = QShortcut(keys, self) shortcut.activated.connect(slot) def _create_menubar(self): """Create the menubar and connect it to actions.""" menu_dict = { # The application name itself shouldn't be translated but the # shortcut indicator (marked with &) should be translated and # decided by the translator. _('Back In &Time'): ( self.act_setup_language, self.act_shutdown, self.act_quit, ), _('&Backup'): ( self.act_take_snapshot, self.act_take_snapshot_checksum, self.act_settings, self.act_snapshots_dialog, self.act_name_snapshot, self.act_remove_snapshot, self.act_snapshot_logview, self.act_last_logview, self.act_update_snapshots, ), _('&Restore'): ( self.act_restore, self.act_restore_to, self.act_restore_parent, self.act_restore_parent_to, ), _('&Help'): ( self.act_help_user_manual, self.act_help_man_backintime, self.act_help_man_config, self.act_help_website, self.act_help_changelog, self.act_help_faq, self.act_help_question, self.act_help_bugreport, self.act_help_translation, self.act_help_encryption, self.act_help_about, ) } for key in menu_dict: menu = self.menuBar().addMenu(key) menu.addActions(menu_dict[key]) menu.setToolTipsVisible(True) # The action of the restore menu. It is used by the menuBar and by the # files toolbar. # It is populated to "self" because it's state to be altered. # See "self._enable_restore_ui_elements()" for details. self.act_restore_menu = self.menuBar().actions()[2] # fine tuning. # Attention: Take care of the actions() index here when modifying the # main menu! backup = self.menuBar().actions()[1].menu() backup.insertSeparator(self.act_settings) backup.insertSeparator(self.act_snapshot_logview) help = self.menuBar().actions()[-1].menu() help.insertSeparator(self.act_help_website) help.insertSeparator(self.act_help_about) if self.act_help_release_candidate: help.addSeparator() help.addAction(self.act_help_release_candidate) restore = self.act_restore_menu.menu() restore.insertSeparator(self.act_restore_parent) restore.setToolTipsVisible(True) def _button_styles(self): return ( ( _('Icons only'), Qt.ToolButtonStyle.ToolButtonIconOnly), ( _('Text only'), Qt.ToolButtonStyle.ToolButtonTextOnly), ( _('Text below icons'), Qt.ToolButtonStyle.ToolButtonTextUnderIcon), ( _('Text beside icon'), Qt.ToolButtonStyle.ToolButtonTextBesideIcon), ) def _set_toolbar_button_style(self, toolbar, style): """Set toolbar button style and store the selected index.""" toolbar.setToolButtonStyle(style) StateData().toolbar_button_style = style.value def _context_menu_button_style(self, point: QPoint, toolbar: QToolBar) -> None: """Open a context menu to modify styling of tooblar buttons buttons. """ menu = QMenu(self) group = QActionGroup(self) for text, style in self._button_styles(): action = QAction(text, self) action.setCheckable(True) action.setChecked(toolbar.toolButtonStyle() == style) group.addAction(action) action.triggered.connect( lambda _, s=style: self._set_toolbar_button_style(toolbar, s) ) menu.addActions(group.actions()) menu.exec(toolbar.mapToGlobal(point)) def _create_main_toolbar(self): """Create the main toolbar and connect it to actions.""" toolbar = self.addToolBar('main') toolbar.setFloatable(False) # Context menu to modify button styling for main toolbar toolbar.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) toolbar.customContextMenuRequested.connect( lambda point: self._context_menu_button_style(point, toolbar)) # Restore button styling for main toolbar toolbar.setToolButtonStyle( Qt.ToolButtonStyle(StateData().toolbar_button_style)) # Drop-Down: Profiles self.comboProfiles = qttools.ProfileCombo(self) self.comboProfilesAction = toolbar.addWidget(self.comboProfiles) actions_for_toolbar = [ self.act_take_snapshot, self.act_pause_take_snapshot, self.act_resume_take_snapshot, self.act_stop_take_snapshot, self.act_update_snapshots, self.act_name_snapshot, self.act_remove_snapshot, self.act_snapshot_logview, self.act_last_logview, self.act_settings, self.act_shutdown, ] # Add each action to toolbar for act in actions_for_toolbar: toolbar.addAction(act) # Assume an explicit tooltip if it is different from "text()". # Note that Qt use "text()" as "toolTip()" by default. if act.toolTip() != act.text(): if QApplication.instance().isRightToLeft(): # RTL/BIDI language like Hebrew button_tip = f'{act.toolTip()} :{act.text()}' else: # (default) LTR language (e.g. English) button_tip = f'{act.text()}: {act.toolTip()}' toolbar.widgetForAction(act).setToolTip(button_tip) act.setText(textwrap.fill(act.text(), width=8, break_long_words=False)) # toolbar sub menu: take snapshot submenu_take_snapshot = QMenu(self) submenu_take_snapshot.addAction(self.act_take_snapshot) submenu_take_snapshot.addAction(self.act_take_snapshot_checksum) submenu_take_snapshot.setToolTipsVisible(True) # get the toolbar buttons widget... button_take_snapshot = toolbar.widgetForAction(self.act_take_snapshot) # ...and add the menu to it button_take_snapshot.setMenu(submenu_take_snapshot) button_take_snapshot.setPopupMode( QToolButton.ToolButtonPopupMode.MenuButtonPopup) # separators and stretchers toolbar.insertSeparator(self.act_settings) toolbar.insertSeparator(self.act_shutdown) def _create_and_get_filesview_toolbar(self): """Create the filesview toolbar object, connect it to actions and return it for later use. Returns: The toolbar object.""" toolbar = QToolBar(self) toolbar.setFloatable(False) actions_for_toolbar = [ self.act_folder_up, self.act_show_hidden, self.act_restore, self.act_snapshots_dialog, ] toolbar.addActions(actions_for_toolbar) # LineEdit widget to display the current path self.widget_current_path = QLineEdit(self) self.widget_current_path.setReadOnly(True) toolbar.insertWidget(self.act_show_hidden, self.widget_current_path) # Restore sub menu restore_sub_menu = self.act_restore_menu.menu() # get the toolbar buttons widget... button_restore = toolbar.widgetForAction(self.act_restore) # ...and add the menu to it button_restore.setMenu(restore_sub_menu) button_restore.setPopupMode( QToolButton.ToolButtonPopupMode.MenuButtonPopup) # Fine tuning toolbar.insertSeparator(self.act_restore) return toolbar def closeEvent(self, event): state_data = StateData() profile_state = state_data.profile(self.config.current_profile_id) if self.shutdown.askBeforeQuit(): msg = _('If you close this window, Back In Time will not be able ' 'to shut down your system when the snapshot is finished.') msg = msg + '\n' msg = msg + _('Do you really want to close it?') answer = messagebox.warningYesNo(self, msg) if answer != QMessageBox.StandardButton.Yes: return event.ignore() profile_state.last_path = pathlib.Path(self.path) profile_state.places_sorting = ( self.places.header().sortIndicatorSection(), self.places.header().sortIndicatorOrder().value, ) state_data.mainwindow_coords = (self.x(), self.y()) state_data.mainwindow_dims = (self.width(), self.height()) state_data.mainwindow_main_splitter_widths = self.mainSplitter.sizes() state_data.mainwindow_second_splitter_widths \ = self.secondSplitter.sizes() state_data.files_view_col_widths = [ self.filesView.header().sectionSize(idx) for idx in range(self.filesView.header().count()) ] state_data.files_view_sorting = ( self.filesView.header().sortIndicatorSection(), self.filesView.header().sortIndicatorOrder().value ) self.filesViewModel.deleteLater() # umount try: mnt = mount.Mount(cfg=self.config, parent=self) mnt.umount(self.config.current_hash_id) except MountException as ex: messagebox.critical(self, str(ex)) self.config.save() state_data.save() # cleanup temporary local copies of files which were opened in GUI for d in self.tmpDirs: d.cleanup() event.accept() def updateProfiles(self): if self.disableProfileChanged: return self.disableProfileChanged = True self.comboProfiles.clear() qttools.update_combo_profiles( self.config, self.comboProfiles, self.config.currentProfile()) profiles = self.config.profilesSortedByName() self.comboProfilesAction.setVisible(len(profiles) > 1) self.updateProfile() self.disableProfileChanged = False def updateProfile(self): self.updateTimeLine() self.updatePlaces() self.updateFilesView(0) profile_id = self.config.currentProfile() state_data = StateData() profile_state = state_data.profile(profile_id) # EncFS deprecation warning (see #1734) current_mode = self.config.snapshotsMode(profile_id) if current_mode in ('local_encfs', 'ssh_encfs'): # Show the profile specific warning dialog only once per profile # and only if the global warning was shown before. if (state_data.msg_encfs_global == bitbase.ENCFS_MSG_STAGE and profile_state.msg_encfs < bitbase.ENCFS_MSG_STAGE): profile_state.msg_encfs = bitbase.ENCFS_MSG_STAGE dlg = encfsmsgbox.EncfsCreateWarning(self) dlg.exec() def comboProfileChanged(self, index): if self.disableProfileChanged: return profile_id = self.comboProfiles.currentProfileID() if not profile_id: return old_profile_id = self.config.currentProfile() if profile_id != old_profile_id: self.remount(profile_id, old_profile_id) self.config.setCurrentProfile(profile_id) self.config.setProfileIntValue( 'qt.places.SortColumn', self.places.header().sortIndicatorSection(), old_profile_id) self.config.setProfileIntValue( 'qt.places.SortOrder', self.places.header().sortIndicatorOrder(), old_profile_id) self.placesSortLoop[old_profile_id] = False self.places.header().setSortIndicator( int(self.config.profileIntValue( 'qt.places.SortColumn', 1, profile_id)), Qt.SortOrder(self.config.profileIntValue( 'qt.places.SortOrder', Qt.SortOrder.AscendingOrder, profile_id)) ) self.config.setProfileStrValue( 'qt.last_path', self.path, old_profile_id) path = self.config.profileStrValue( 'qt.last_path', self.path, profile_id) if not path == self.path: self.path = path self.path_history.reset(self.path) self.widget_current_path.setText(self.path) self.updateProfile() def remount(self, new_profile_id, old_profile_id): try: mnt = mount.Mount(cfg=self.config, profile_id=old_profile_id, parent=self) hash_id = mnt.remount(new_profile_id) except MountException as ex: messagebox.critical(self, str(ex)) else: self.config.setCurrentHashId(hash_id) def raiseApplication(self): raiseCmd = self.appInstance.raiseCommand() if raiseCmd is None: return logger.debug("Raise cmd: %s" % raiseCmd, self) self.qapp.alert(self) def updateTakeSnapshot(self, force_wait_lock=False): """Update the statusbar and progress indicator with latest message from the snapshot message file. This method is called via a timeout event. See `self.timerUpdateTakeSnapshot`. Also see `Snapshots.takeSnapshotMessage()` for further details. """ if force_wait_lock: self.forceWaitLockCounter = 10 busy = self.snapshots.busy() if busy: self.forceWaitLockCounter = 0 paused = tools.processPaused(self.snapshots.pid()) else: paused = False if self.forceWaitLockCounter > 0: self.forceWaitLockCounter = self.forceWaitLockCounter - 1 fake_busy = busy or self.forceWaitLockCounter > 0 message = _('Working:') takeSnapshotMessage = self.snapshots.takeSnapshotMessage() if fake_busy: if takeSnapshotMessage is None: takeSnapshotMessage = (0, '…') elif takeSnapshotMessage is None: takeSnapshotMessage = self.lastTakeSnapshotMessage if takeSnapshotMessage is None: takeSnapshotMessage = (0, _('Done')) force_update = False if fake_busy: # What is this? if self.act_take_snapshot.isEnabled(): self.act_take_snapshot.setEnabled(False) if not self.act_stop_take_snapshot.isVisible(): for action in (self.act_pause_take_snapshot, self.act_resume_take_snapshot, self.act_stop_take_snapshot): action.setEnabled(True) self.act_take_snapshot.setVisible(False) self.act_pause_take_snapshot.setVisible(not paused) self.act_resume_take_snapshot.setVisible(paused) self.act_stop_take_snapshot.setVisible(True) elif not self.act_take_snapshot.isEnabled(): force_update = True self.act_take_snapshot.setEnabled(True) self.act_take_snapshot.setVisible(True) for action in (self.act_pause_take_snapshot, self.act_resume_take_snapshot, self.act_stop_take_snapshot): action.setVisible(False) # TODO: check if there is a more elegant way than always get a # new snapshot list which is very expensive (time) snapshotsList = snapshots.listSnapshots(self.config) if snapshotsList != self.snapshotsList: self.snapshotsList = snapshotsList self.updateTimeLine(False) takeSnapshotMessage = (0, _('Done')) else: if takeSnapshotMessage[0] == 0: takeSnapshotMessage = (0, _('Done, no backup needed')) self.shutdown.shutdown() if takeSnapshotMessage != self.lastTakeSnapshotMessage or force_update: self.lastTakeSnapshotMessage = takeSnapshotMessage if fake_busy: message = '{}: {}'.format( _('Working'), self.lastTakeSnapshotMessage[1].replace('\n', ' ') ) elif takeSnapshotMessage[0] == 0: message = self.lastTakeSnapshotMessage[1].replace('\n', ' ') else: message = '{}: {}'.format( _('Error'), self.lastTakeSnapshotMessage[1].replace('\n', ' ') ) self.status.setText(message) pg = progress.ProgressFile(self.config) if pg.fileReadable(): self.progressBar.setVisible(True) self.progressBarDummy.setVisible(False) pg.load() self.progressBar.setValue(pg.intValue('percent')) message = ' | '.join(self.getProgressBarFormat(pg, message)) self.status.setText(message) else: self.progressBar.setVisible(False) self.progressBarDummy.setVisible(True) #if not fake_busy: # self.lastTakeSnapshotMessage = None def getProgressBarFormat(self, pg, message): d = ( ('sent', '{}:'.format(_('Sent'))), ('speed', '{}:'.format(_('Speed'))), ('eta', '{}:'.format(_('ETA'))) ) yield '{}%'.format(pg.intValue('percent')) for key, txt in d: value = pg.strValue(key, '') if not value: continue yield txt + ' ' + value yield message def placesChanged(self, item, previous): if item is None: return path = str(item.data(0, Qt.ItemDataRole.UserRole)) if not path: return if path == self.path: return self.path = path self.path_history.append(path) self.updateFilesView(3) def addPlace(self, name, path, icon): """ Dev note (buhtz, 2024-01-14): Parts of that code are redundant with qttools.py::HeaderItem.__init__(). """ item = QTreeWidgetItem() item.setText(0, name) if icon: item.setIcon(0, QIcon.fromTheme(icon)) item.setData(0, Qt.ItemDataRole.UserRole, path) if not path: item.setFont(0, qttools.fontBold(item.font(0))) # item.setFlags(Qt.ItemFlag.ItemIsEnabled) item.setFlags(Qt.ItemFlag.NoItemFlags) item.setForeground( 0, self.palette().color(QPalette.ColorRole.PlaceholderText)) item.setBackground( 0, self.palette().color(QPalette.ColorRole.Window)) self.places.addTopLevelItem(item) if path == self.path: self.places.setCurrentItem(item) return item def updatePlaces(self): self.places.clear() self.addPlace(_('Global'), '', '') self.addPlace(_('Root'), '/', 'computer') self.addPlace(_('Home'), os.path.expanduser('~'), 'user-home') # "Now" or a specific snapshot selected? if self.sid.isRoot: # Use snapshots profiles list of include files and folders include_entries = self.config.include() else: # Determine folders from the snapshot itself base = os.path.expanduser('~') if not os.path.isdir(self.sid.pathBackup(base)): # Folder not mounted. We can skip for the next updatePlaces() return folders = [i.name for i in os.scandir(self.sid.pathBackup(base)) if i.is_dir()] include_entries = [(os.path.join(base, f), 0) for f in folders] # Use folders only (if 2nd tuple entry is 0) only_folders = filter(lambda entry: entry[1] == 0, include_entries) include_folders = [item[0] for item in only_folders] if not include_folders: return if not self.places.header().sortIndicatorSection(): indic = self.places.header().sortIndicatorOrder() reverse = True if indic == Qt.SortOrder.DescendingOrder else False include_folders = sorted(include_folders, reverse=reverse) self.addPlace(_('Backup directories'), '', '') for folder in include_folders: self.addPlace(folder, folder, 'document-save') def sortPlaces(self, newColumn, newOrder, force = False): profile_id = self.config.currentProfile() if newColumn == 0 and newOrder == Qt.SortOrder.AscendingOrder: if profile_id in self.placesSortLoop and self.placesSortLoop[profile_id]: newColumn, newOrder = 1, Qt.SortOrder.AscendingOrder self.places.header().setSortIndicator(newColumn, newOrder) self.placesSortLoop[profile_id] = False else: self.placesSortLoop[profile_id] = True self.updatePlaces() def updateSnapshotActions(self, item = None): enabled = False if item is None: item = self.timeLine.currentItem() if not item is None: if not item.snapshotID().isRoot: enabled = True # update remove/name snapshot buttons self.act_name_snapshot.setEnabled(enabled) self.act_remove_snapshot.setEnabled(enabled) self.act_snapshot_logview.setEnabled(enabled) def timeLineChanged(self): item = self.timeLine.currentItem() self.updateSnapshotActions(item) if item is None: return sid = item.snapshotID() if not sid or sid == self.sid: return self.sid = sid self.updatePlaces() self.updateFilesView(2) def updateTimeLine(self, refreshSnapshotsList=True): self.timeLine.clear() self.timeLine.addRoot(snapshots.RootSnapshot(self.config)) if refreshSnapshotsList: self.snapshotsList = [] thread = FillTimeLineThread(self) thread.addSnapshot.connect(self.timeLine.addSnapshot) thread.finished.connect(self.timeLine.checkSelection) thread.start() else: for sid in self.snapshotsList: item = self.timeLine.addSnapshot(sid) self.timeLine.checkSelection() def btnTakeSnapshotClicked(self): backintime.takeSnapshotAsync(self.config) self.updateTakeSnapshot(True) def btnTakeSnapshotChecksumClicked(self): backintime.takeSnapshotAsync(self.config, checksum = True) self.updateTakeSnapshot(True) def btnStopTakeSnapshotClicked(self): os.kill(self.snapshots.pid(), signal.SIGKILL) self.act_stop_take_snapshot.setEnabled(False) self.act_pause_take_snapshot.setEnabled(False) self.act_resume_take_snapshot.setEnabled(False) self.snapshots.setTakeSnapshotMessage(0, 'Snapshot terminated') def btnUpdateSnapshotsClicked(self): self.updateTimeLine() self.updateFilesView(2) def btnNameSnapshotClicked(self): item = self.timeLine.currentItem() if item is None: return sid = item.snapshotID() if sid.isRoot: return name = sid.name new_name, accept = QInputDialog.getText(self, _('Snapshot Name'), '', text = name) if not accept: return new_name = new_name.strip() if name == new_name: return sid.name = new_name item.updateText() def btnLastLogViewClicked (self): with self.suspendMouseButtonNavigation(): logviewdialog.LogViewDialog(self).show() # no SID argument in constructor means "show last log" def btnSnapshotLogViewClicked (self): item = self.timeLine.currentItem() if item is None: return sid = item.snapshotID() if sid.isRoot: return with self.suspendMouseButtonNavigation(): dlg = logviewdialog.LogViewDialog(self, sid) dlg.show() if sid != dlg.sid: self.timeLine.setCurrentSnapshotID(dlg.sid) def btnRemoveSnapshotClicked (self): def hideItem(item): try: item.setHidden(True) except RuntimeError: #item has been deleted #probably because user pressed refresh pass # try to use filter(..) items = [item for item in self.timeLine.selectedItems() if not isinstance(item, snapshots.RootSnapshot)] if not items: return question_msg = '{}\n{}'.format( ngettext( 'Are you sure you want to remove this snapshot?', 'Are you sure you want to remove these snapshots?', len(items) ), '\n'.join([item.snapshotID().displayName for item in items])) answer = messagebox.warningYesNo(self, question_msg) if answer != QMessageBox.StandardButton.Yes: return for item in items: item.setDisabled(True) if item is self.timeLine.currentItem(): self.timeLine.selectRootItem() thread = RemoveSnapshotThread(self, items) thread.refreshSnapshotList.connect(self.updateTimeLine) thread.hideTimelineItem.connect(hideItem) thread.start() def btnSettingsClicked(self): with self.suspendMouseButtonNavigation(): SettingsDialog(self).show() def btnShutdownToggled(self, checked): self.shutdown.activate_shutdown = checked def contextMenuClicked(self, point): self.contextMenu.exec(self.filesView.mapToGlobal(point)) def btnAboutClicked(self): with self.suspendMouseButtonNavigation(): dlg = AboutDlg(self) dlg.exec() def btn_help_user_manual(self): qttools.open_user_manual() def btn_help_man_backintime(self): self.openManPage('backintime') def btn_help_man_config(self): self.openManPage('backintime-config') def btnWebsiteClicked(self): self.openUrl('https://github.com/bit-team/backintime') def btnChangelogClicked(self): def aHref(m): if m.group(0).count('@'): return '%(url)s' % {'url': m.group(0)} else: return '%(url)s' % {'url': m.group(0)} def aHref_lp(m): return '%(txt)s' % {'txt': m.group(0), 'id': m.group(1)} changelog_path = pathlib.Path(tools.docPath()) / 'CHANGES' msg = changelog_path.read_text('utf-8') msg = re.sub(r'https?://[^) \n]*', aHref, msg) msg = re.sub(r'(?:LP:|bug) ?#?(\d+)', aHref_lp, msg) msg = re.sub(r'\n', '
', msg) messagebox.showInfo(self, _('Changelog'), msg) def btnFaqClicked(self): self.openUrl('https://github.com/bit-team/backintime/blob/-/FAQ.md') def btnAskQuestionClicked(self): self.openUrl('https://github.com/bit-team/backintime/issues') def btnReportBugClicked(self): self.openUrl('https://github.com/bit-team/backintime/issues/new') def openUrl(self, url): return QDesktopServices.openUrl(QUrl(url)) def openManPage(self, man_page): if not tools.checkCommand('man'): messagebox.critical(self, "Couldn't find 'man' to show the help page. Please install 'man'") return env = os.environ env['MANWIDTH'] = '80' proc = subprocess.Popen(['man', man_page], stdout = subprocess.PIPE, universal_newlines = True, env = env) out, err = proc.communicate() messagebox.showInfo(self, 'Manual Page {}'.format(man_page), out) def btnShowHiddenFilesToggled(self, checked): self.showHiddenFiles = checked self.updateFilesView(1) def backupOnRestore(self): cb = QCheckBox(_( 'Create backup copies with trailing {suffix}\n' 'before overwriting or removing local elements.').format( suffix=self.snapshots.backupSuffix())) cb.setChecked(self.config.backupOnRestore()) qttools.set_wrapped_tooltip( cb, [ _("Newer versions of files will be renamed with trailing " "{suffix} before restoring. If you don't need them anymore " "you can remove them with the following command:").format( suffix=self.snapshots.backupSuffix()), 'find ./ -name "*{suffix}" -delete'.format( suffix=self.snapshots.backupSuffix()) ] ), return { 'widget': cb, 'retFunc': cb.isChecked, 'id': 'backup' } def restoreOnlyNew(self): cb = QCheckBox(_('Only restore elements which do not exist or\n' 'are newer than those in destination.\n' 'Using "rsync --update" option.')) qttools.set_wrapped_tooltip( cb, ["From 'man rsync':", "", "This forces rsync to skip any files which exist on the " "destination and have a modified time that is newer than the " "source file. (If an existing destination file has a " "modification time equal to the source file’s, it will be " "updated if the sizes are different.)", "", "Note that this does not affect the copying of dirs, symlinks, " "or other special files. Also, a difference of file format " "between the sender and receiver is always considered to be " "important enough for an update, no matter what date is on the " "objects. In other words, if the source has a directory where " "the destination has a file, the transfer would occur regardless " "of the timestamps.", "", "This option is a transfer rule, not an exclude, so it doesn’t " "affect the data that goes into the file-lists, and thus it " "doesn’t affect deletions. It just limits the files that the " "receiver requests to be transferred."] ) return {'widget': cb, 'retFunc': cb.isChecked, 'id': 'only_new'} def listRestorePaths(self, paths): fileList = QListWidget() fileList.addItems(paths) fileList.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection) return {'widget': fileList, 'retFunc': None} def deleteOnRestore(self): cb = QCheckBox(_('Remove newer elements in original directory.')) qttools.set_wrapped_tooltip( cb, _('Restore selected files or directories to the original ' 'destination and delete files or directories which are not in ' 'the snapshot. Be extremely careful because this will delete ' 'files and directories which were excluded during taking the ' 'snapshot.') ) return {'widget': cb, 'retFunc': cb.isChecked, 'id': 'delete'} def confirmRestore(self, paths, restoreTo=None): if restoreTo: msg = ngettext( # singular 'Do you really want to restore this element into the ' 'new directory?', # plural 'Do you really want to restore these elements into the ' 'new directory?', len(paths)) msg = f'{msg}\n{restoreTo}' else: msg = ngettext( # singular 'Do you really want to restore this element?', # plural 'Do you really want to restore these elements?', len(paths)) confirm, opt = messagebox.warningYesNoOptions( self, msg, ( self.listRestorePaths(paths), self.backupOnRestore(), self.restoreOnlyNew(), self.deleteOnRestore() ) ) return (confirm, opt) def confirmDelete(self, warnRoot=False, restoreTo=None): if restoreTo: msg = _('Are you sure you want to remove all newer files ' 'in {path}?').format(path=restoreTo) else: msg = _('Are you sure you want to remove all newer files in your ' 'original directory?') if warnRoot: msg = f'

{msg}

' msg = msg + _( '{BOLD}Warning{BOLDEND}: Deleting files in the filesystem ' 'root could break your entire system.').format( BOLD='', BOLDEND='') msg = msg + '

' answer = messagebox.warningYesNo(self, msg) return answer == QMessageBox.StandardButton.Yes def restoreThis(self): if self.sid.isRoot: return paths = [f for f, idx in self.multiFileSelected(fullPath = True)] with self.suspendMouseButtonNavigation(): confirm, opt = self.confirmRestore(paths) if not confirm: return if opt['delete'] and not self.confirmDelete(warnRoot = '/' in paths): return rd = RestoreDialog(self, self.sid, paths, **opt) rd.exec() def restoreThisTo(self): if self.sid.isRoot: return paths = [f for f, idx in self.multiFileSelected(fullPath = True)] with self.suspendMouseButtonNavigation(): restoreTo = qttools.getExistingDirectory(self, _('Restore to …')) if not restoreTo: return restoreTo = self.config.preparePath(restoreTo) confirm, opt = self.confirmRestore(paths, restoreTo) if not confirm: return if opt['delete'] and not self.confirmDelete(warnRoot = '/' in paths, restoreTo = restoreTo): return rd = RestoreDialog(self, self.sid, paths, restoreTo, **opt) rd.exec() def restoreParent(self): if self.sid.isRoot: return with self.suspendMouseButtonNavigation(): confirm, opt = self.confirmRestore((self.path,)) if not confirm: return if opt['delete'] and not self.confirmDelete(warnRoot = self.path == '/'): return rd = RestoreDialog(self, self.sid, self.path, **opt) rd.exec() def restoreParentTo(self): if self.sid.isRoot: return with self.suspendMouseButtonNavigation(): restoreTo = qttools.getExistingDirectory(self, _('Restore to …')) if not restoreTo: return restoreTo = self.config.preparePath(restoreTo) confirm, opt = self.confirmRestore((self.path,), restoreTo) if not confirm: return if opt['delete'] and not self.confirmDelete(warnRoot = self.path == '/', restoreTo = restoreTo): return rd = RestoreDialog(self, self.sid, self.path, restoreTo, **opt) rd.exec() def btnSnapshotsClicked(self): path, idx = self.fileSelected(fullPath = True) with self.suspendMouseButtonNavigation(): dlg = snapshotsdialog.SnapshotsDialog(self, self.sid, path) if dlg.exec() == QDialog.DialogCode.Accepted: if dlg.sid != self.sid: self.timeLine.setCurrentSnapshotID(dlg.sid) def btnFolderUpClicked(self): if len(self.path) <= 1: return path = os.path.dirname(self.path) if self.path == path: return self.path = path self.path_history.append(self.path) self.updateFilesView(0) def btnFolderHistoryPreviousClicked(self): self._folderHistoryClicked(self.path_history.previous()) def btnFolderHistoryNextClicked(self): self._folderHistoryClicked(self.path_history.next()) def _folderHistoryClicked(self, path): full_path = self.sid.pathBackup(path) if (os.path.isdir(full_path) and self.sid.isExistingPathInsideSnapshotFolder(path)): self.path = path self.updateFilesView(0) def btnOpenCurrentItemClicked(self): path, idx = self.fileSelected() if not path: return self.openPath(path) def btnAddIncludeClicked(self): paths = [f for f, idx in self.multiFileSelected(fullPath = True)] include = self.config.include() updatePlaces = False for item in paths: if os.path.isdir(item): include.append((item, 0)) updatePlaces = True else: include.append((item, 1)) self.config.setInclude(include) if updatePlaces: self.updatePlaces() def btnAddExcludeClicked(self): paths = [f for f, idx in self.multiFileSelected(fullPath = True)] exclude = self.config.exclude() exclude.extend(paths) self.config.setExclude(exclude) def filesViewItemActivated(self, model_index): if self.qapp.keyboardModifiers() and Qt.ControlModifier: return if model_index is None: return rel_path = str(self.filesViewProxyModel.data(model_index)) if not rel_path: return self.openPath(rel_path) def tmpCopy(self, full_path, sid=None): """Create a temporary local copy a file or directory. The name of is of the pattern ``backintime_[tmp_str]_[snapshotID]``. Clean up is done when closing BIT based on ``self.tmpDirs``. Args: full_path (str): Path to original file or directory. sid (snapshots.SID): Snapshot identifier. Returns: str: Path to the temporary file or directory. """ if sid: sid = '_' + sid.sid d = TemporaryDirectory(prefix='backintime_', suffix=sid) tmp_file = os.path.join(d.name, os.path.basename(full_path)) if os.path.isdir(full_path): shutil.copytree(full_path, tmp_file, symlinks=True) else: shutil.copy(full_path, d.name) self.tmpDirs.append(d) return tmp_file def openPath(self, rel_path): rel_path = os.path.join(self.path, rel_path) full_path = self.sid.pathBackup(rel_path) # The class "GenericNonSnapshot" indicates that "Now" is selected # in the snapshots timeline widget. if (os.path.exists(full_path) and (isinstance(self.sid, snapshots.GenericNonSnapshot) # "Now" or self.sid.isExistingPathInsideSnapshotFolder(rel_path))): if os.path.isdir(full_path): self.path = rel_path self.path_history.append(rel_path) self.updateFilesView(0) else: # prevent backup data from being accidentally overwritten # by create a temporary local copy and only open that one if not isinstance(self.sid, snapshots.RootSnapshot): full_path = self.tmpCopy(full_path, self.sid) file_url = QUrl('file://' + full_path) self.run = QDesktopServices.openUrl(file_url) @pyqtSlot(int) def updateFilesView(self, changed_from, selected_file=None, show_snapshots=False): """ changed_from? WTF! 0 - files view change directory, 1 - files view, 2 - time_line, 3 - places """ if 0 == changed_from or 3 == changed_from: selected_file = '' if 0 == changed_from: # update places self.places.setCurrentItem(None) for place_index in range(self.places.topLevelItemCount()): item = self.places.topLevelItem(place_index) if self.path == str(item.data(0, Qt.ItemDataRole.UserRole)): self.places.setCurrentItem(item) break text = '' if self.sid.isRoot: text = _('Now') else: name = self.sid.displayName # buhtz (2023-07)3 blanks at the end of that string as a # workaround to a visual issue where the last character was # cutoff. Not sure if this is DE and/or theme related. # Wasn't able to reproduc in an MWE. Remove after refactoring. text = '{}: {} '.format(_('Snapshot'), name) self.filesWidget.setTitle(text) # try to keep old selected file if selected_file is None: selected_file, idx = self.fileSelected() self.selected_file = selected_file # update files view full_path = self.sid.pathBackup(self.path) if os.path.isdir(full_path): if self.showHiddenFiles: self.filesViewProxyModel.setFilterRegularExpression(r'') else: self.filesViewProxyModel.setFilterRegularExpression(r'^[^\.]') model_index = self.filesViewModel.setRootPath(full_path) proxy_model_index = self.filesViewProxyModel.mapFromSource(model_index) self.filesView.setRootIndex(proxy_model_index) self.toolbar_filesview.setEnabled(False) self.stackFilesView.setCurrentWidget(self.filesView) # TODO: find a signal for this self.dirListerCompleted() else: self._enable_restore_ui_elements(False) self.act_snapshots_dialog.setEnabled(False) self.stackFilesView.setCurrentWidget(self.lblFolderDontExists) # show current path self.widget_current_path.setText(self.path) self.act_restore_parent.setText( _('Restore {path}').format(path=self.path)) self.act_restore_parent_to.setText( _('Restore {path} to …').format(path=self.path)) # update folder_up button state self.act_folder_up.setEnabled(len(self.path) > 1) def _enable_restore_ui_elements(self, enable): """Enable or disable all buttons and menu entries related to the restore feature. Args: enable(bool): Enable or disable. If a specific snapshot is selected in the timeline widget then all restore UI elements are enabled. If "Now" (the first/root) is selected in the timeline all UI elements related to restoring should be disabled. """ # The whole sub-menu incl. its button/entry. The related UI elements # are the "Restore" entry in the main-menu and the toolbar button in # the files-view toolbar. self.act_restore_menu.setEnabled(enable) # This two entries do appear, independent from the sub-menu above, in # the context menu of the files view. self.act_restore.setEnabled(enable) self.act_restore_to.setEnabled(enable) def dirListerCompleted(self): row_count = self.filesViewProxyModel.rowCount( self.filesView.rootIndex()) has_files = row_count > 0 # update restore button state enable = not self.sid.isRoot and has_files # TODO(buhtz) self.btnRestoreMenu.setEnabled(enable) self._enable_restore_ui_elements(enable) # update snapshots button state self.act_snapshots_dialog.setEnabled(has_files) # enable files toolbar self.toolbar_filesview.setEnabled(True) # select selected_file found = False if self.selected_file: index = self.filesView.indexAt(QPoint(0,0)) if not index.isValid(): return while index.isValid(): file_name = (str(self.filesViewProxyModel.data(index))) if file_name == self.selected_file: # TODO: doesn't work reliable self.filesView.setCurrentIndex(index) found = True break index = self.filesView.indexBelow(index) self.selected_file = '' if not found and has_files: self.filesView.setCurrentIndex(self.filesViewProxyModel.index(0, 0)) def fileSelected(self, fullPath=False): """Return path and index of the currently in Files View highlighted (selected) file. Args: fullPath(bool): Resolve relative to a full path. Returns: (tuple): Path as a string and the index. """ idx = qttools.indexFirstColumn(self.filesView.currentIndex()) selected_file = str(self.filesViewProxyModel.data(idx)) if selected_file == '/': # nothing is selected selected_file = '' idx = self.filesViewProxyModel.mapFromSource( self.filesViewModel.index(self.path, 0)) if fullPath: # resolve to full path selected_file = os.path.join(self.path, selected_file) return (selected_file, idx) def multiFileSelected(self, fullPath = False): count = 0 for idx in self.filesView.selectedIndexes(): if idx.column() > 0: continue selected_file = str(self.filesViewProxyModel.data(idx)) if selected_file == '/': continue count += 1 if fullPath: selected_file = os.path.join(self.path, selected_file) yield (selected_file, idx) if not count: # nothing is selected idx = self.filesViewProxyModel.mapFromSource(self.filesViewModel.index(self.path, 0)) if fullPath: selected_file = self.path else: selected_file = '' yield (selected_file, idx) def setMouseButtonNavigation(self): self.qapp.installEventFilter(self.mouseButtonEventFilter) @contextmanager def suspendMouseButtonNavigation(self): self.qapp.removeEventFilter(self.mouseButtonEventFilter) yield self.setMouseButtonNavigation() def _open_approach_translator_dialog(self, cutoff=101): code = self.config.language_used name, perc = tools.get_native_language_and_completeness(code) if perc > cutoff: return def _complete_text(language: str, percent: int) -> str: # (2023-08): Move to packages meta-data (pyproject.toml). _URL_PLATFORM = 'https://translate.codeberg.org/engage/backintime' _URL_PROJECT = 'https://github.com/bit-team/backintime' txt = _( 'Hello' '\n' 'You have used Back In Time in the {language} ' 'language a few times by now.' '\n' 'The translation of your installed version of Back In Time ' 'into {language} is {perc} complete. Regardless of your ' 'level of technical expertise, you can contribute to the ' 'translation and thus Back In Time itself.' '\n' 'Please visit the {translation_platform_url} if you wish ' 'to contribute. For further assistance and questions, ' 'please visit the {back_in_time_project_website}.' '\n' 'We apologize for the interruption, and this message ' 'will not be shown again. This dialog is available at ' 'any time via the help menu.' '\n' 'Your Back In Time Team' ) # Wrap paragraphs in

tags. result = '' for t in txt.split('\n'): result = f'{result}

{t}

' # Insert data in placeholder variables. platform_url \ = f'' \ + _('translation platform') \ + '' project_url \ = f'Back In Time ' \ + _('Website') \ + ' ' result = result.format( language=f'{language}', perc=f'{percent} %', translation_platform_url=platform_url, back_in_time_project_website=project_url ) return result dlg = UserMessageDialog( parent=self, title=_('Your translation'), full_label=_complete_text(name, perc)) dlg.exec() def _open_release_candidate_dialog(self): html_contact_list = ( '
    ' '
  • {mastodon}
  • ' '
  • {email}
  • ' '
  • {mailinglist}
  • ' '
  • {issue}
  • ' '
  • {alternative}
  • ' '
').format( mastodon=_('In the Fediverse at Mastodon: {link_and_label}') \ .format(link_and_label='' '@backintime@fosstodon.org' ''), email=_('Email to {link_and_label}.').format( link_and_label='' 'backintime@tuta.io'), mailinglist=_('Mailing list {link_and_label}').format( link_and_label='' 'bit-dev@python.org'), issue=_('{link_and_label} on the project website.').format( link_and_label='{open_issue}').format( open_issue=_('Open an issue')), alternative=_('Alternatively, you can use another channel ' 'of your choice.') ) rc_message = _( 'This version of Back In Time is a Release Candidate and is ' 'primarily intended for stability testing in preparation for the ' 'next official release.' '\n' 'No user data or telemetry is collected. However, the Back In ' 'Time team is very interested in knowing if the Release Candidate ' 'is being used and if it is worth continuing to provide such ' 'pre-release versions.' '\n' 'Therefore, the team kindly asks for a short feedback on whether ' 'you have tested this version, even if you didn’t encounter any ' 'issues. Even a quick test run of a few minutes would help us a ' 'lot.' '\n' 'The following contact options are available:' '\n' '{contact_list}' '\n' "In this version, this message won't be shown again but can be " 'accessed anytime through the help menu.' '\n' 'Thank you for your support and for helping us improve ' 'Back In Time!' '\n' 'Your Back In Time Team').format(contact_list=html_contact_list) dlg = UserMessageDialog( parent=self, title=_('Release Candidate'), full_label=rc_message) dlg.exec() # |-------| # | Slots | # |-------| def slot_setup_language(self): """Show a modal language settings dialog and modify the UI language settings.""" dlg = languagedialog.LanguageDialog( used_language_code=self.config.language_used, configured_language_code=self.config.language()) dlg.exec() # Apply/OK pressed & the language value modified if dlg.result() == 1 and self.config.language() != dlg.language_code: self.config.setLanguage(dlg.language_code) messagebox.info(_('The language settings take effect only after ' 'restarting Back In Time.'), widget_to_center_on=dlg) def slot_help_translation(self): self._open_approach_translator_dialog() def slot_help_release_candidate(self): self._open_release_candidate_dialog() def slot_help_encryption(self): dlg = encfsmsgbox.EncfsExistsWarning(self, ['(not determined)']) dlg.exec() class ExtraMouseButtonEventFilter(QObject): """ globally catch mouse buttons 4 and 5 (mostly used as back and forward) and assign it to browse in file history. Dev Note (Germar): Maybe use Qt.BackButton and Qt.ForwardButton instead. """ def __init__(self, mainWindow): self.mainWindow = mainWindow super(ExtraMouseButtonEventFilter, self).__init__() def eventFilter(self, receiver, event): if (event.type() == QEvent.Type.MouseButtonPress and event.button() in (Qt.MouseButton.XButton1, Qt.MouseButton.XButton2)): if event.button() == Qt.MouseButton.XButton1: self.mainWindow.btnFolderHistoryPreviousClicked() if event.button() == Qt.MouseButton.XButton2: self.mainWindow.btnFolderHistoryNextClicked() return True else: return super(ExtraMouseButtonEventFilter, self) \ .eventFilter(receiver, event) class RemoveSnapshotThread(QThread): """ remove snapshots in background thread so GUI will not freeze """ refreshSnapshotList = pyqtSignal() hideTimelineItem = pyqtSignal(qttools.SnapshotItem) def __init__(self, parent, items): self.config = parent.config self.snapshots = parent.snapshots self.items = items super(RemoveSnapshotThread, self).__init__(parent) def run(self): last_snapshot = snapshots.lastSnapshot(self.config) renew_last_snapshot = False #inhibit suspend/hibernate during delete self.config.inhibitCookie = tools.inhibitSuspend(toplevel_xid = self.config.xWindowId, reason = 'deleting snapshots') for item, sid in [(x, x.snapshotID()) for x in self.items]: self.snapshots.remove(sid) self.hideTimelineItem.emit(item) if sid == last_snapshot: renew_last_snapshot = True self.refreshSnapshotList.emit() #set correct last snapshot again if renew_last_snapshot: self.snapshots.createLastSnapshotSymlink(snapshots.lastSnapshot(self.config)) #release inhibit suspend if self.config.inhibitCookie: self.config.inhibitCookie = tools.unInhibitSuspend(*self.config.inhibitCookie) class FillTimeLineThread(QThread): """ add snapshot IDs to timeline in background """ addSnapshot = pyqtSignal(snapshots.SID) def __init__(self, parent): self.parent = parent self.config = parent.config super(FillTimeLineThread, self).__init__(parent) def run(self): for sid in snapshots.iterSnapshots(self.config): self.addSnapshot.emit(sid) self.parent.snapshotsList.append(sid) self.parent.snapshotsList.sort() class SetupCron(QThread): """ Check crontab entries on startup. """ def __init__(self, parent): self.config = parent.config super(SetupCron, self).__init__(parent) def run(self): self.config.setupCron() def _get_state_data_from_config(cfg: config.Config) -> StateData: """Get data related to application state from the config instance. It migrates state data from the config file to an instance of `StateData` which later is saved in a separate file. This function is a temporary workaround. See PR #1850. Args: cfg: The config instance. Returns: dict: The state data. """ data = StateData() # internal.manual_starts_countdown data['manual_starts_countdown'] \ = cfg.intValue('internal.manual_starts_countdown', 10) # internal.msg_rc val = cfg.strValue('internal.msg_rc', None) if val: data.msg_release_candidate = val # internal.msg_shown_encfs val = cfg.boolValue('internal.msg_shown_encfs', 0) if val: data.msg_encfs_global = val # qt.show_hidden_files data.mainwindow_show_hidden = cfg.boolValue('qt.show_hidden_files', False) # Coordinates and dimensions val = ( cfg.intValue('qt.main_window.x', None), cfg.intValue('qt.main_window.y', None) ) if all(val): data.mainwindow_coords = val val = ( cfg.intValue('qt.main_window.width', None), cfg.intValue('qt.main_window.height', None) ) if all(val): data.mainwindow_dims = val val = ( cfg.intValue('qt.logview.width', None), cfg.intValue('qt.logview.height', None) ) if all(val): data.logview_dims = val # files view # Dev note (buhtz, 2024-12): Ignore the column width values because of a # bug. Three columns are tracked but the widget has four columns. The "Typ" # column is treated as "Date" and the width of the real "Date" column (4th) # was never stored. # The new state file will load and store width values for all existing # columns. # qt.main_window.files_view.name_width # qt.main_window.files_view.size_width # qt.main_window.files_view.date_width col = cfg.intValue('qt.main_window.files_view.sort.column', 0) order = cfg.boolValue('qt.main_window.files_view.sort.ascending', True) data.files_view_sorting = (col, 0 if order else 1) # splitter width widths = ( cfg.intValue('qt.main_window.main_splitter_left_w', None), cfg.intValue('qt.main_window.main_splitter_right_w', None) ) if all(widths): data.mainwindow_main_splitter_widths = widths widths = ( cfg.intValue('qt.main_window.second_splitter_left_w', None), cfg.intValue('qt.main_window.second_splitter_right_w', None) ) if all(widths): data.mainwindow_second_splitter_widths = widths # each profile for profile_id in cfg.profiles(): profile_state = data.profile(profile_id) # profile specific encfs warning val = cfg.profileBoolValue('msg_shown_encfs', 0, profile_id) profile_state.msg_encfs = val # qt.last_path if cfg.hasProfileKey('qt.last_path', profile_id): profile_state.last_path \ = cfg.profileStrValue('qt.last_path', None, profile_id) # Places: sorting sorting = ( cfg.profileIntValue('qt.places.SortColumn', None, profile_id), cfg.profileIntValue('qt.places.SortOrder', None, profile_id) ) if all(sorting): profile_state.places_sorting = sorting # Manage profiles - Exclude tab: sorting sorting = ( cfg.profileIntValue( 'qt.settingsdialog.exclude.SortColumn', None, profile_id), cfg.profileIntValue( 'qt.settingsdialog.exclude.SortOrder', None, profile_id) ) if all(sorting): profile_state.exclude_sorting = sorting # Manage profiles - Include tab: sorting sorting = ( cfg.profileIntValue( 'qt.settingsdialog.include.SortColumn', None, profile_id), cfg.profileIntValue( 'qt.settingsdialog.include.SortOrder', None, profile_id) ) if all(sorting): profile_state.include_sorting = sorting return data def load_state_data(cfg: config.Config) -> None: """Initiate the `State` instance. The state file is loaded and its data stored in `State`. The later is a singleton and can be used everywhere. Args: args: Arguments given from command line. """ fp = StateData.file_path() try: # load file state_data = StateData(json.loads(fp.read_text(encoding='utf-8'))) except FileNotFoundError: logger.debug('State file not found. Using config file and migrate it' 'into a state file.') fp.parent.mkdir(parents=True, exist_ok=True) state_data = _get_state_data_from_config(cfg) except json.decoder.JSONDecodeError as exc: logger.warning(f'Unable to read and decode state file "{fp}". ' 'Ignnoring it.') logger.debug(f'{exc=}') try: raw_content = fp.read_text(encoding='utf-8') logger.debug(f'raw_content="{raw_content}"') except Exception as exc_raw: logger.debug(f'{exc_raw=}') # Empty state data with default values state_data = StateData() if __name__ == '__main__': cfg = backintime.startApp('backintime-qt') raiseCmd = '' if len(sys.argv) > 1: raiseCmd = '\n'.join(sys.argv[1:]) appInstance = guiapplicationinstance.GUIApplicationInstance( cfg.appInstanceFile(), raiseCmd) cfg.PLUGIN_MANAGER.load(cfg=cfg) cfg.PLUGIN_MANAGER.appStart() logger.openlog() qapp = qttools.createQApplication(cfg.APP_NAME) translator = qttools.initiate_translator(cfg.language()) qapp.installTranslator(translator) load_state_data(cfg) mainWindow = MainWindow(cfg, appInstance, qapp) if cfg.isConfigured(): cfg.xWindowId = mainWindow.winId() mainWindow.show() qapp.exec() mainWindow.qapp.removeEventFilter(mainWindow.mouseButtonEventFilter) cfg.PLUGIN_MANAGER.appExit() appInstance.exitApplication() logger.closelog() # must be last line (log until BiT "dies" ;-) backintime-1.5.4/qt/backintime-qt000077500000000000000000000015631477034762000167500ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2017 Matthias Gerstner # SPDX-FileCopyrightText: © 2024 Jürgen Altfeld # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # fixing gray window error # https://launchpad.net/bugs/1493020 export QT_GRAPHICSSYSTEM="native" CUR_PATH="$(dirname $(readlink -m $0))" if [ -f "${CUR_PATH}/app.py" ]; then APP_PATH=$CUR_PATH else APP_PATH=$(readlink -m "${CUR_PATH}/../share/backintime/qt") fi /usr/bin/python3 -Es ${APP_PATH}/app.py "$@" backintime-1.5.4/qt/backintime-qt-root.desktop000066400000000000000000000020341477034762000213700ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2009 Back In Time team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . [Desktop Entry] # Version of the Desktop Entry Specification Version=1.5 Name=Back In Time (root) GenericName=Backup Exec=/usr/bin/backintime-qt_polkit %f Icon=document-save Terminal=false Type=Application StartupNotify=true # See Desktop Menu Specification Categories=Utility;System;Archiving;Qt; # Limit comments to 80 chars (Desktop Entry Specification) 80th char --> | Comment=Comfortable GUI for incremental (rsync) backups to save storage space Comment[de]=Einfache GUI für inkrementelle (rsync) Backups zur Speicherplatzreduzierung Keywords=backup;incremental;automatic;restore;rsync; backintime-1.5.4/qt/backintime-qt.desktop000066400000000000000000000020031477034762000204030ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2009 Back In Time team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . [Desktop Entry] # Version of the Desktop Entry Specification Version=1.5 Name=Back In Time GenericName=Backup Exec=backintime-qt Icon=document-save Terminal=false Type=Application StartupNotify=true # See Desktop Menu Specification Categories=Utility;System;Archiving;Qt; # Limit comments to 80 chars (Desktop Entry Specification) 80th char --> | Comment=Comfortable GUI for incremental (rsync) backups to save storage space Comment[de]=Einfache GUI für inkrementelle (rsync) Backups zur Speicherplatzreduzierung Keywords=backup;incremental;automatic;restore;rsync; backintime-1.5.4/qt/backintime-qt_polkit000077500000000000000000000014311477034762000203240ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2009 Back In Time team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . if [ "x$XDG_SESSION_TYPE" = "xwayland" ]; then # PREFIX="env QT_QPA_PLATFORM=wayland-egl XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR" # Empty prefix to use the default Qt platform plugin (normally xcb) to fix #836 and #1350 PREFIX="" else # X11 PREFIX="" fi pkexec --disable-internal-agent $PREFIX "/usr/bin/backintime-qt" "$@" backintime-1.5.4/qt/configure000077500000000000000000000222301477034762000161730ustar00rootroot00000000000000#!/bin/sh # SPDX-FileCopyrightText: © 2009 Oprea Dan # SPDX-FileCopyrightText: © 2013 Germar Reitze # SPDX-FileCopyrightText: © 2022 Jürgen Altfeld # SPDX-FileCopyrightText: © 2022 Christian Buhtz # SPDX-FileCopyrightText: © 2023 Kian-Meng Ang # SPDX-FileCopyrightText: © 2023 Fabio Fantoni # SPDX-FileCopyrightText: © 2024 Tejas Guruswamy # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # # This is the configuration file for the Read the Docs service. # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details. #clean up if [ -e Makefile ]; then rm Makefile; fi #tmp files MAKEFILE="$(mktemp)" UNINSTALL_FILES="$(mktemp)" UNINSTALL_DIRS="$(mktemp)" #set default options PYTHON="/usr/bin/python3" USR_BIN_FILES="backintime-qt backintime-qt_polkit" DBUS_SERVICE_FILES="net.launchpad.backintime.serviceHelper.service" usage () { echo "Usage:" echo "$0 [--python | --python3 | --python=PYTHON_BINARY]" echo "" echo "--python" echo "\tuse 'python' to start Python3" echo "--python3" echo "\tuse 'python3' to start Python3" echo "--python=PYTHON_BINARY" echo "\tuse PYTHON_BINARY to start Python3" } addInstallFiles () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi for i in $(ls $file); do addInstallFile "$i" "$dest" "$mode" done } addInstallFile () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallFile "$file" "$dest" } addInstallFileRename () { file=$1 dest=$2 mode=$3 if [ -z "$mode" ]; then mode=644 fi printf "\tinstall --mode=$mode $file \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallFileRename "$dest" } addUninstallFile () { file=$(basename "$1") dest=$2 printf "\trm -f \$(DEST)$dest/$file\n" >> ${UNINSTALL_FILES} } addUninstallFileRename () { file=$1 printf "\trm -f \$(DEST)$file\n" >> ${UNINSTALL_FILES} } addInstallDir () { dest=$1 printf "\tinstall -d \$(DEST)$dest\n" >> ${MAKEFILE} addUninstallDir "$dest" } addUninstallDir () { dest=$1 printf "\tif [ -d \$(DEST)$dest ]; then rmdir --ignore-fail-on-non-empty \$(DEST)$dest; fi\n" >> ${UNINSTALL_DIRS} } addComment () { printf "\t# Install $1\n" >> ${MAKEFILE} printf "\t# Uninstall files $1\n" >> ${UNINSTALL_FILES} printf "\t# Uninstall directory $1\n" >> ${UNINSTALL_DIRS} } addNewline () { printf "\n" >> ${MAKEFILE} printf "\n" >> ${UNINSTALL_FILES} printf "\n" >> ${UNINSTALL_DIRS} } #get commandline arguments unknown_args="" for arg in $*; do case $arg in --python=*) PYTHON=$(echo $arg | cut -f2 -d'=') ;; --python3) PYTHON="/usr/bin/python3" ;; --python) PYTHON="/usr/bin/python" ;; --help | -h) usage; exit 0;; *) unknown_args="$unknown_args $arg";; esac done if [ -n "$unknown_args" ]; then echo "Unknown Arguments: $unknown_args" fi if [ ! -f "$PYTHON" ]; then echo "Warning: \"${PYTHON}\" not found on this computer" fi #patch python command #use 'python' or 'python3' to start Python Version 3.x if [ -n "$(sed -e "s#^/usr/bin/python3\? #${PYTHON} #gw /dev/stdout" -i $USR_BIN_FILES)" ] \ && [ -n "$(sed -e "s#^Exec=/usr/bin/python3\? #Exec=${PYTHON} #gw /dev/stdout" -i $DBUS_SERVICE_FILES)" ] then echo "Replacement of python path with \"${PYTHON}\" successful." else echo "WARNING: Replacement of python path with \"${PYTHON}\" FAILED. Maybe you ran configure more than once?" fi #start Makefile printf "PREFIX=/usr\n" >> ${MAKEFILE} printf "DEST=\$(DESTDIR)\$(PREFIX)\n\n" >> ${MAKEFILE} printf "all:\tbuild\n\n" >> ${MAKEFILE} printf "build:\tcompress\n\n" >> ${MAKEFILE} printf "clean:\n" >> ${MAKEFILE} printf "\trm -f po/*.mo\n" >> ${MAKEFILE} printf "\trm -f man/C/*.gz\n\n" >> ${MAKEFILE} # Create install and uninstall target printf "install:\n" >> ${MAKEFILE} # Migration printf "\t# Clean-up installed old files that were renamed or moved in later BiT versions\n" >> ${MAKEFILE} printf "\trm -f \$(DEST)/etc/dbus-1/system.d/net.launchpad.backintime.serviceHelper.conf\n" >> ${MAKEFILE} printf "\trm -f \$(DEST)/share/backintime/plugins/qt4plugin.py\n" >> ${MAKEFILE} addNewline printf "\t# Inject version string into source files\n" >> ${MAKEFILE} printf "\t(cd .. && ./updateversion.sh)\n" >> ${MAKEFILE} addNewline addComment "python" addUninstallDir "/share/backintime/qt/__pycache__" addUninstallFile "*.pyc" "/share/backintime/qt/__pycache__" addInstallDir "/share/backintime/qt" addInstallFiles "*.py" "/share/backintime/qt" addInstallDir "/share/backintime/qt/manageprofiles" addInstallFiles "manageprofiles/*.py" "/share/backintime/qt/manageprofiles" addNewline addComment "plugin" addUninstallDir "/share/backintime/plugins/__pycache__" addUninstallFile "*.pyc" "/share/backintime/plugins/__pycache__" addInstallDir "/share/backintime/plugins" addInstallFiles "plugins/*.py" "/share/backintime/plugins" addUninstallDir "/share/backintime" addNewline addComment "application" addInstallDir "/bin" addInstallFile "backintime-qt" "/bin" "755" addInstallFile "backintime-qt_polkit" "/bin" "755" addInstallDir "/share/metainfo" addInstallFile "io.github.bit_team.back_in_time.gui.metainfo.xml" "/share/metainfo" addNewline addComment "dbus service" addInstallDir "/share/dbus-1/system-services" addInstallFiles "net.launchpad.backintime*.service" "/share/dbus-1/system-services" addUninstallDir "/share/dbus-1" addNewline addComment "dbus conf" addInstallDir "/share/dbus-1/system.d" addInstallFiles "net.launchpad.backintime*.conf" "/share/dbus-1/system.d" addUninstallDir "/share/dbus-1" addUninstallDir "/share" addNewline addComment "polkit action" addInstallDir "/share/polkit-1/actions" addInstallFiles "net.launchpad.backintime*.policy" "/share/polkit-1/actions" addUninstallDir "/share/polkit-1" addNewline addComment "documentation" addInstallDir "/share/doc/backintime-qt" addInstallFile "../AUTHORS" "/share/doc/backintime-qt" addInstallFile "../README.md" "/share/doc/backintime-qt" addInstallFile "../FAQ.md" "/share/doc/backintime-qt" addInstallFile "../TRANSLATIONS" "/share/doc/backintime-qt" addInstallFile "../CHANGES" "/share/doc/backintime-qt" addInstallFile "../LICENSE" "/share/doc/backintime-qt" addInstallDir "/share/doc/backintime-qt/LICENSES" addInstallFiles "../LICENSES/*" "/share/doc/backintime-qt/LICENSES" addNewline addComment ".desktop" addInstallDir "/share/applications" addInstallFiles "*.desktop" "/share/applications" addNewline addComment "man" addInstallDir "/share/man/man1" addInstallFile "man/C/backintime-qt.1.gz" "/share/man/man1" addUninstallDir "/share/man" addNewline addComment "icons" for f in "scalable" "48x48" "32x32" "24x24" "22x22" "16x16"; do addInstallDir "/share/icons/hicolor/${f}/actions" addInstallFile "icons/${f}/actions/show-hidden.svg" "/share/icons/hicolor/${f}/actions" addUninstallDir "/share/icons/hicolor/${f}" done addUninstallDir "/share/icons/hicolor" addUninstallDir "/share/icons" addUninstallDir "/share" addNewline #compress printf "compress:\n" >> ${MAKEFILE} printf "\t# Man pages\n" >> ${MAKEFILE} printf "\tfor i in \$\$(ls -1 man/C/); do case \$\$i in *.gz|*~) continue;; *) gzip -n --best -c man/C/\$\$i > man/C/\$\${i}.gz;; esac; done\n\n" >> ${MAKEFILE} # Uninstall printf "uninstall: uninstall_files uninstall_dirs\n\n" >> ${MAKEFILE} printf "uninstall_files:\n" >> ${MAKEFILE} cat ${UNINSTALL_FILES} >> ${MAKEFILE} printf "uninstall_dirs:\n" >> ${MAKEFILE} cat ${UNINSTALL_DIRS} >> ${MAKEFILE} #copy Makefile mv ${MAKEFILE} Makefile chmod 644 Makefile #clean up for i in "${UNINSTALL_FILES}" "${UNINSTALL_DIRS}"; do if [ -e "$i" ]; then rm "$i" fi done # check python version PYTHON_VERSION_REQUIRED="3.9" PYTHON_VERSION_CURRENT=$(${PYTHON} --version | tr --delete 'Python ') # Credits: https://unix.stackexchange.com/a/285928/136851 if [ "$(printf '%s\n' "$PYTHON_VERSION_REQUIRED" "$PYTHON_VERSION_CURRENT" | sort -V | head -n1)" != "$PYTHON_VERSION_REQUIRED" ]; then printf "Error: Wrong Python version ${PYTHON_VERSION_CURRENT}. " printf "But minimal version ${PYTHON_VERSION_REQUIRED} required.\n" exit 1 fi printf "All OK. Now run:\n" printf " make\n" printf " sudo make install\n" backintime-1.5.4/qt/editusercallback.py000066400000000000000000000050431477034762000201420ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import re from PyQt6.QtWidgets import (QVBoxLayout, QDialogButtonBox, QPlainTextEdit, QDialog) import tools import logger class EditUserCallback(QDialog): def __init__(self, parent): super(EditUserCallback, self).__init__(parent) self.config = parent.config self.script = self.config.takeSnapshotUserCallback() import icon self.setWindowIcon(icon.SETTINGS_DIALOG) self.setWindowTitle(self.script) self.resize(800, 500) layout = QVBoxLayout(self) self.edit = QPlainTextEdit(self) try: with open(self.script, 'rt') as f: self.edit.setPlainText(f.read()) except IOError: pass layout.addWidget(self.edit) btnBox = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, parent=self) btnBox.accepted.connect(self.accept) btnBox.rejected.connect(self.reject) layout.addWidget(btnBox) def checkScript(self, script): m = re.match(r'^#!(/[\w/-]+)\n', script) if not m: logger.error( 'user-callback script has no shebang (#!/bin/sh) line.') self.config.errorHandler( 'user-callback script has no shebang (#!/bin/sh) line.') return False if not tools.checkCommand(m.group(1)): logger.error('Shebang in user-callback script is not executable.') self.config.errorHandle( 'Shebang in user-callback script is not executable.') return False return True def accept(self): if not self.checkScript(self.edit.toPlainText()): return with open(self.script, 'wt') as f: f.write(self.edit.toPlainText()) os.chmod(self.script, 0o755) super(EditUserCallback, self).accept() backintime-1.5.4/qt/encfsmsgbox.py000066400000000000000000000074551477034762000171700ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Message box warning about EncFS deprecation. See #1734 and #1735 for details """ from PyQt6.QtGui import QCursor from PyQt6.QtWidgets import QLabel, QToolTip, QMessageBox from bitbase import URL_ENCRYPT_TRANSITION class _EncfsWarningBase(QMessageBox): """Base clase for Warning boxes in context of EncFS decprecation. """ def __init__(self, parent, text, informative_text): super().__init__(parent) self.setWindowTitle(_('Warning')) self.setIcon(QMessageBox.Icon.Warning) self.setText(text) self.setInformativeText(informative_text) # Set link tooltips (via hovering) on the QLabels for label in self.findChildren(QLabel): label.linkHovered.connect( lambda url: QToolTip.showText( QCursor.pos(), url.replace('https://', ''))) class EncfsCreateWarning(_EncfsWarningBase): """Warning box when using EncFS encrypting while creating a new profile or modify an existing one. """ def __init__(self, parent): text = _('EncFS profile creation will be removed in the next minor ' 'release (1.7), scheduled for 2026.') text = text + ' ' + _('It is not recommended to use that ' 'mode for a profile furthermore.') whitepaper = f'' \ + _('whitepaper') + '' informative_text = _('Support for EncFS is being discontinued due ' 'to security vulnerabilities.') informative_text = informative_text + ' ' + _( 'For more details, including potential alternatives, please refer ' 'to this {whitepaper}.').format( whitepaper=whitepaper) super().__init__(parent, text, informative_text) class EncfsExistsWarning(_EncfsWarningBase): """Warning box when encrypted profiles exists. """ def __init__(self, parent, profiles): # DevNote: Code looks ugly because we need to take the needs of # translators into account. Also the limitations of Qt's RichText # feature need to be considered. text = ' '.join([ _('EncFS profile creation will be removed in the next minor ' 'release (1.7), scheduled for 2026.'), _('It is not recommended to use that mode for a ' 'profile furthermore.') ]) profiles = '
    ' \ + ''.join(f'
  • {profile}
  • ' for profile in profiles) \ + '
' whitepaper = f'' \ + _('whitepaper') + '' info_paragraphs = ( _('The following profile(s) use encryption with EncFS:'), profiles, ' '.join([ _('Support for EncFS is being discontinued due ' 'to security vulnerabilities.'), _('A replacement is planned, but it cannot be guaranteed that ' 'it will arrive on time.')]), _('Users are invited to join this discussion. Updated details ' 'on the next steps are available in this {whitepaper}.').format( whitepaper=whitepaper), _('This message will not be shown again. This dialog is ' 'available at any time via the help menu.'), _('Your Back In Time Team') ) informative_text = ''.join( [f'

{par}

' for par in info_paragraphs]) super().__init__(parent, text, informative_text) backintime-1.5.4/qt/icon.py000066400000000000000000000130511477034762000155670ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtGui import QIcon import logger logger.debug("Checking if the current theme contains the BiT icon...") # If the current theme does not even contain the "document-save" icon # try to use another well-known working theme (if it is installed): for theme in ('ubuntu-mono-dark', 'gnome', 'breeze', 'breeze dark', 'hicolor', 'adwaita', 'adwaita-dark', 'yaru', 'oxygen'): # Check if the current theme does provide the BiT "logo" icon # (otherwise the theme is not fully/correctly installed) # and use this theme then for all icons # Note: "hicolor" does currently (2022) use different icon names # (not fully compliant to the freedesktop.org spec) # and is not recommended as main theme (it is meant as fallback only). if not QIcon.fromTheme('document-save').isNull(): logger.debug(f"Found an installed theme: {QIcon.themeName()}") break # try next theme (activate it)... QIcon.setThemeName(theme) logger.debug(f"Probing theme: {theme} (activated as {QIcon.themeName()})") if QIcon.fromTheme('document-save').isNull(): logger.error("No supported theme installed (missing icons). " "Please consult the project web site for instructions " "how to fix this.") # Dev note: Please prefer choosing icons from the freedesktop.org spec # to improve the chance that the icon is available and # each installed theme: # https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html # # If there is chance that an icon may not always be available use # the second argument of QIcon.fromTheme() to provide a fallback # icon from the freedesktop.org spec. # BackInTime Logo # TODO If we knew for sure that the global var "qapp" exists then # we could use a built-in "standard" Qt icon as fallback if the theme does # not provide the icon. # => wait for icon.py refactoring than improve this: # qapp.style().standardIcon(QStyle.SP_DialogSaveButton) BIT_LOGO = QIcon.fromTheme('document-save') BIT_LOGO_INFO = QIcon.fromTheme('document-save-as') #Main toolbar TAKE_SNAPSHOT = BIT_LOGO PAUSE = QIcon.fromTheme('media-playback-pause') RESUME = QIcon.fromTheme('media-playback-start') STOP = QIcon.fromTheme('media-playback-stop') REFRESH_SNAPSHOT = QIcon.fromTheme('view-refresh') SNAPSHOT_NAME = QIcon.fromTheme('stock_edit', QIcon.fromTheme('gtk-edit', QIcon.fromTheme('edit-rename', QIcon.fromTheme('accessories-text-editor')))) REMOVE_SNAPSHOT = QIcon.fromTheme('edit-delete') VIEW_SNAPSHOT_LOG = QIcon.fromTheme('text-plain', QIcon.fromTheme('text-x-generic')) VIEW_LAST_LOG = QIcon.fromTheme('document-open-recent') SETTINGS = QIcon.fromTheme('gtk-preferences', QIcon.fromTheme('configure', # Free Desktop Icon Naming Specification QIcon.fromTheme('preferences-system'))) SHUTDOWN = QIcon.fromTheme('system-shutdown') EXIT = QIcon.fromTheme('gtk-close', QIcon.fromTheme('application-exit')) #Help menu HELP = QIcon.fromTheme('help-contents') WEBSITE = QIcon.fromTheme('go-home') CHANGELOG = QIcon.fromTheme('format-justify-fill') FAQ = QIcon.fromTheme('help-faq', QIcon.fromTheme('help-hint')) QUESTION = QIcon.fromTheme('stock_dialog-question', QIcon.fromTheme('help-feedback')) BUG = QIcon.fromTheme('stock_dialog-error', QIcon.fromTheme('tools-report-bug')) ABOUT = QIcon.fromTheme('help-about') #Files toolbar UP = QIcon.fromTheme('go-up') SHOW_HIDDEN = QIcon.fromTheme('view-hidden', # currently only in Breeze (see #1159) QIcon.fromTheme('show-hidden', # icon installed with # BiT! #507 QIcon.fromTheme('list-add'))) RESTORE = QIcon.fromTheme('edit-undo') RESTORE_TO = QIcon.fromTheme('document-revert') SNAPSHOTS = QIcon.fromTheme('file-manager', QIcon.fromTheme('view-list-details', QIcon.fromTheme('system-file-manager'))) #Snapshot dialog DIFF_OPTIONS = SETTINGS DELETE_FILE = REMOVE_SNAPSHOT SELECT_ALL = QIcon.fromTheme('edit-select-all') #Restore dialog RESTORE_DIALOG = VIEW_SNAPSHOT_LOG #Settings dialog SETTINGS_DIALOG = SETTINGS PROFILE_EDIT = SNAPSHOT_NAME ADD = QIcon.fromTheme('list-add') REMOVE = QIcon.fromTheme('list-remove') FOLDER = QIcon.fromTheme('folder') FILE = QIcon.fromTheme('text-plain', QIcon.fromTheme('text-x-generic')) EXCLUDE = QIcon.fromTheme('edit-delete') # "emblem-default" is a green mark and doesn't make sense in this case. DEFAULT_EXCLUDE = QIcon.fromTheme('emblem-important') INVALID_EXCLUDE = QIcon.fromTheme('emblem-ohno', QIcon.fromTheme('face-surprise')) ENCRYPT = QIcon.fromTheme('lock', QIcon.fromTheme('security-high')) LANGUAGE = QIcon.fromTheme('preferences-desktop-locale') backintime-1.5.4/qt/icons/000077500000000000000000000000001477034762000154005ustar00rootroot00000000000000backintime-1.5.4/qt/icons/16x16/000077500000000000000000000000001477034762000161655ustar00rootroot00000000000000backintime-1.5.4/qt/icons/16x16/actions/000077500000000000000000000000001477034762000176255ustar00rootroot00000000000000backintime-1.5.4/qt/icons/16x16/actions/show-hidden.svg000066400000000000000000000333671477034762000225730ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/icons/22x22/000077500000000000000000000000001477034762000161575ustar00rootroot00000000000000backintime-1.5.4/qt/icons/22x22/actions/000077500000000000000000000000001477034762000176175ustar00rootroot00000000000000backintime-1.5.4/qt/icons/22x22/actions/show-hidden.svg000066400000000000000000000334541477034762000225620ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/icons/24x24/000077500000000000000000000000001477034762000161635ustar00rootroot00000000000000backintime-1.5.4/qt/icons/24x24/actions/000077500000000000000000000000001477034762000176235ustar00rootroot00000000000000backintime-1.5.4/qt/icons/24x24/actions/show-hidden.svg000066400000000000000000000334501477034762000225620ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/icons/32x32/000077500000000000000000000000001477034762000161615ustar00rootroot00000000000000backintime-1.5.4/qt/icons/32x32/actions/000077500000000000000000000000001477034762000176215ustar00rootroot00000000000000backintime-1.5.4/qt/icons/32x32/actions/show-hidden.svg000066400000000000000000000333751477034762000225660ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/icons/48x48/000077500000000000000000000000001477034762000161775ustar00rootroot00000000000000backintime-1.5.4/qt/icons/48x48/actions/000077500000000000000000000000001477034762000176375ustar00rootroot00000000000000backintime-1.5.4/qt/icons/48x48/actions/show-hidden.svg000066400000000000000000000333241477034762000225760ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/icons/REUSE.toml000066400000000000000000000013011477034762000171530ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Back In Time Team # # SPDX-License-Identifier: CC0-1.0 # # This file is released under Creative Commons Zero 1.0 (CC0-1.0) and part of # the program "Back In Time". The program as a whole is released under GNU # General Public License v2 or any later version (GPL-2.0-or-later). # See LICENSES directory or go to # and . # See https://reuse.software/faq/#bulk-license version = 1 [[annotations]] path = "**/*.svg" SPDX-License-Identifier = "GPL-2.0-or-later" # The icon "show-hidden" was created by Germar Reitze. See Issue #507. SPDX-FileCopyrightText = "© 2015 Germar Reitze" backintime-1.5.4/qt/icons/scalable/000077500000000000000000000000001477034762000171465ustar00rootroot00000000000000backintime-1.5.4/qt/icons/scalable/actions/000077500000000000000000000000001477034762000206065ustar00rootroot00000000000000backintime-1.5.4/qt/icons/scalable/actions/show-hidden.svg000066400000000000000000000333241477034762000235450ustar00rootroot00000000000000 show-hidden image/svg+xml show-hidden 2015-12-22 Germar Reitze eye Icon for showing hidden files in BackInTime https://github.com/bit-team/backintime backintime-1.5.4/qt/io.github.bit_team.back_in_time.gui.metainfo.xml000066400000000000000000000075651477034762000254660ustar00rootroot00000000000000 io.github.bit_team.back_in_time.gui Back In Time Backup tool for GNU/Linux desktop using rsync's hard-links feature to save storage space FSFAP GPL-2.0-or-later

It is an easy-to-use backup tool for files and folders. It runs on GNU Linux and provides a command line tool "backintime" and a Qt5 GUI "backintime-qt". It uses "rsync" in the back to take manual or scheduled snapshots and stores them locally or remotely through SSH. Each snapshot is in its own folder with copies of the original files, but unchanged files are hard-linked between snapshots to save space. It was inspired by "FlyBack".

You only need to specify 3 things:

  1. What folders to back up.
  2. Where to save snapshots.
  3. The backup frequency (manual, every hour, every day, every month).
document-save System Archiving Backup Rsync GUI Back In Time team https://github.com/bit-team/backintime https://github.com/bit-team/backintime/issues https://github.com/bit-team/backintime/blob/dev/FAQ.md https://backintime.readthedocs.io/ https://translate.codeberg.org/engage/backintime https://mail.python.org/mailman3/lists/bit-dev.python.org https://github.com/bit-team/backintime https://github.com/bit-team/backintime/blob/dev/CONTRIBUTING.md backintime-qt.desktop backintime-qt-root.desktop Main window https://translate.codeberg.org/media/screenshots/bit_16to9_960x540_mainwindow.png Setup of SSH snapshot profile https://translate.codeberg.org/media/screenshots/bit_16to9_1280x720_general_ssh.png bit-dev@python.org
backintime-1.5.4/qt/languagedialog.py000066400000000000000000000141771477034762000176140ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Dialog window to choose GUI display language.""" from PyQt6.QtCore import Qt from PyQt6.QtWidgets import (QApplication, QDialog, QWidget, QScrollArea, QGridLayout, QVBoxLayout, QDialogButtonBox, QRadioButton, ) import tools import languages import qttools LOW_RESOLUTION_WIDTH = 1024 class LanguageDialog(QDialog): """Dialog to choose GUI language.""" def __init__(self, used_language_code: str, configured_language_code: str): super().__init__() self.language_code = None self.used_language_code = used_language_code self.configured_language_code = configured_language_code self.setWindowTitle(_('Setup language')) self.setWindowFlag(Qt.WindowType.WindowMaximizeButtonHint, True) scroll = QScrollArea(self) scroll.setVerticalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAsNeeded) scroll.setHorizontalScrollBarPolicy( Qt.ScrollBarPolicy.ScrollBarAlwaysOff) scroll.setWidget(self._language_widget()) self._scroll = scroll # Fit the width of scrollarea to its content new_width = self._calculate_scroll_area_width() self._scroll.setMinimumWidth(new_width) buttonbox = QDialogButtonBox( QDialogButtonBox.StandardButton.Cancel | QDialogButtonBox.StandardButton.Ok, self) buttonbox.accepted.connect(self.accept) buttonbox.rejected.connect(self.reject) layout = QVBoxLayout(self) layout.addWidget(scroll) layout.addWidget(buttonbox) def _calculate_scroll_area_width(self): """Credits: - https://stackoverflow.com/a/9081579/4865723 - https://stackoverflow.com/a/76738806/4865723 """ widget_width = self._scroll.widget().sizeHint().width() scrollbar_width = self._scroll.verticalScrollBar().sizeHint().width() return widget_width + scrollbar_width def _create_radio_button(self, lang_code, label, tooltip) -> QRadioButton: r = QRadioButton(label, self) r.setToolTip(tooltip) r.toggled.connect(self.slot_radio) r.lang_code = lang_code # Is it the current used AND configured language? if (r.lang_code == self.used_language_code and r.lang_code == self.configured_language_code): r.setChecked(True) # "System default" elif self.configured_language_code == '' and r.lang_code is None: r.setChecked(True) return r def _language_widget(self): grid = QGridLayout() widget = QWidget(self) widget.setLayout(grid) # Entry: System default language label = 'System default' translated_label = _('System default') # If translation for that term exists... if label != translated_label: # ...combine source and translated version. label = f'{label}\n{translated_label}' r = self._create_radio_button( lang_code=None, label=label, tooltip=_('Use operating systems language.') ) grid.addWidget(r, 1, 1) # Sort by language code but keep English on top langs = tools.get_language_names(self.used_language_code) sorted_codes = sorted(langs.keys()) sorted_codes.remove('en') sorted_codes = ['en'] + sorted_codes # Number of columns used for radio buttons number_of_columns = 3 # Low-resolution screens (XGA or less) if QApplication.primaryScreen().size().width() <= LOW_RESOLUTION_WIDTH: # Use one columns less number_of_columns -= 1 # Calculate number of entries (rows) per column per_col_n = len(sorted_codes) / number_of_columns per_col_n = int(per_col_n) + 1 col = 1 for idx, code in enumerate(sorted_codes, 2): names = langs[code] try: # Use English name if name of the language in the current set # locale is unknown label = names[0] or names[2] except TypeError: # Happens when no name for the language codes is available. # "names" is "None" in that case. label = code tooltip = f'Language code "{code}" unknown.' else: # Add language name in its native representation # if Native letters available in current font # but prevent duplications like e.g. "Deutsch\nDeutsch" if label != names[1] and qttools.can_render(names[1], widget): label = f'{names[1]}\n{label}' # Tooltip: Language code tooltip = f'{names[2]} ({code})' # Tooltip: completeness of translation try: complete = languages.completeness[code] except KeyError: pass else: tooltip = tooltip + '\n' \ + _('Translated: {percent}').format( percent=f'{complete}%') # Create button r = self._create_radio_button(code, label, tooltip) # Calculate buttons location row = idx - ((col - 1) * per_col_n) if row > per_col_n: row = 1 col = col + 1 # Add the button grid.addWidget(r, row, col) return widget def slot_radio(self, _): """Radio button state toggled.""" btn = self.sender() if btn.isChecked(): self.language_code = btn.lang_code backintime-1.5.4/qt/logviewdialog.py000066400000000000000000000224711477034762000175010ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtGui import QFont from PyQt6.QtWidgets import (QDialog, QLabel, QPlainTextEdit, QVBoxLayout, QHBoxLayout, QComboBox, QDialogButtonBox, QCheckBox, ) from PyQt6.QtCore import QFileSystemWatcher import qttools import snapshots import encfstools import snapshotlog import tools import qttools from statedata import StateData class LogViewDialog(QDialog): def __init__(self, parent, sid=None, systray=False): """ Instantiate a snapshot log file viewer Args: parent: sid (:py:class:`SID`): snapshot ID whose log file shall be shown (``None`` = show last log) systray (bool): TODO Show log from systray icon or from App (boolean) """ if systray: super(LogViewDialog, self).__init__() else: super(LogViewDialog, self).__init__(parent) self.config = parent.config self.snapshots = parent.snapshots self.mainWindow = parent self.sid = sid self.enableUpdate = False self.decode = None state_data = StateData() self.resize(*state_data.logview_dims) import icon self.setWindowIcon(icon.VIEW_SNAPSHOT_LOG) if self.sid is None: self.setWindowTitle(_('Last Log View')) else: self.setWindowTitle(_('Snapshot Log View')) self.mainLayout = QVBoxLayout(self) layout = QHBoxLayout() self.mainLayout.addLayout(layout) # profiles self.lblProfile = QLabel(_('Profile:'), self) layout.addWidget(self.lblProfile) self.comboProfiles = qttools.ProfileCombo(self) layout.addWidget(self.comboProfiles, 1) self.comboProfiles.currentIndexChanged.connect(self.profileChanged) # snapshots self.lblSnapshots = QLabel(_('Snapshots:'), self) layout.addWidget(self.lblSnapshots) self.comboSnapshots = qttools.SnapshotCombo(self) layout.addWidget(self.comboSnapshots, 1) self.comboSnapshots.currentIndexChanged.connect(self.comboSnapshotsChanged) if self.sid is None: self.lblSnapshots.hide() self.comboSnapshots.hide() if self.sid or systray: self.lblProfile.hide() self.comboProfiles.hide() # filter layout.addWidget(QLabel(_('Filter:'), self)) self.comboFilter = QComboBox(self) layout.addWidget(self.comboFilter, 1) self.comboFilter.currentIndexChanged.connect(self.comboFilterChanged) self.comboFilter.addItem(_('All'), snapshotlog.LogFilter.NO_FILTER) # Note about ngettext plural forms: n=102 means "Other" in Arabic and # "Few" in Polish. # Research in translation community indicate this as the best fit to # the meaning of "all". self.comboFilter.addItem( ' + '.join((_('Errors'), _('Changes'))), snapshotlog.LogFilter.ERROR_AND_CHANGES) self.comboFilter.setCurrentIndex(self.comboFilter.count() - 1) self.comboFilter.addItem(_('Errors'), snapshotlog.LogFilter.ERROR) self.comboFilter.addItem(_('Changes'), snapshotlog.LogFilter.CHANGES) self.comboFilter.addItem(ngettext('Information', 'Information', 2), snapshotlog.LogFilter.INFORMATION) self.comboFilter.addItem( _('rsync transfer failures (experimental)'), snapshotlog.LogFilter.RSYNC_TRANSFER_FAILURES) # text view self.txtLogView = QPlainTextEdit(self) self.txtLogView.setFont(QFont('Monospace')) self.txtLogView.setReadOnly(True) self.txtLogView.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap) self.mainLayout.addWidget(self.txtLogView) # self.mainLayout.addWidget( QLabel(_('[E] Error, [I] Information, [C] Change'))) # decode path self.cbDecode = QCheckBox(_('decode paths'), self) self.cbDecode.stateChanged.connect(self.cbDecodeChanged) self.mainLayout.addWidget(self.cbDecode) # buttons buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) self.mainLayout.addWidget(buttonBox) buttonBox.rejected.connect(self.close) self.updateSnapshots() self.updateDecode() self.updateProfiles() # watch for changes in log file self.watcher = QFileSystemWatcher(self) if self.sid is None: # only watch if we show the last log log = self.config.takeSnapshotLogFile( self.comboProfiles.currentProfileID()) self.watcher.addPath(log) # passes the path to the changed file to updateLog() self.watcher.fileChanged.connect(self.updateLog) def cbDecodeChanged(self): if self.cbDecode.isChecked(): if not self.decode: self.decode = encfstools.Decode(self.config) else: if self.decode is not None: self.decode.close() self.decode = None self.updateLog() def profileChanged(self, index): if not self.enableUpdate: return profile_id = self.comboProfiles.currentProfileID() self.mainWindow.comboProfiles.setCurrentProfileID(profile_id) self.mainWindow.comboProfileChanged(None) self.updateDecode() self.updateLog() def comboSnapshotsChanged(self, index): if not self.enableUpdate: return self.sid = self.comboSnapshots.currentSnapshotID() self.updateLog() def comboFilterChanged(self, index): self.updateLog() def updateProfiles(self): current_profile_id = self.config.currentProfile() self.comboProfiles.clear() qttools.update_combo_profiles(self.config, self.comboProfiles, current_profile_id) self.enableUpdate = True self.updateLog() if len(self.config.profilesSortedByName()) <= 1: self.lblProfile.setVisible(False) self.comboProfiles.setVisible(False) def updateSnapshots(self): if self.sid: self.comboSnapshots.clear() for sid in snapshots.iterSnapshots(self.config): self.comboSnapshots.addSnapshotID(sid) if sid == self.sid: self.comboSnapshots.setCurrentSnapshotID(sid) def updateDecode(self): if self.config.snapshotsMode() == 'ssh_encfs': self.cbDecode.show() else: self.cbDecode.hide() if self.cbDecode.isChecked(): self.cbDecode.setChecked(False) def updateLog(self, watchPath=None): """ Show the log file of the current snapshot in the GUI Args: watchPath: FQN to a log file (as string) whose changes are watched via ``QFileSystemWatcher``. In case of changes this function is called with the log file and only the new lines in the log file are appended to the log file widget in the GUI Use ``None`` if a complete log file shall be shown at once. """ if not self.enableUpdate: return mode = self.comboFilter.itemData(self.comboFilter.currentIndex()) # TODO This expressions is hard to understand (watchPath is not a # boolean!) if watchPath and self.sid is None: # remove path from watch to prevent multiple updates at the same # time self.watcher.removePath(watchPath) # append only new lines to txtLogView log = snapshotlog.SnapshotLog( self.config, self.comboProfiles.currentProfileID()) for line in log.get(mode=mode, decode=self.decode, skipLines=self.txtLogView.document().lineCount()-1): self.txtLogView.appendPlainText(line) # re-add path to watch after 5sec delay alarm = tools.Alarm( callback=lambda: self.watcher.addPath(watchPath), overwrite=False) alarm.start(5) elif self.sid is None: log = snapshotlog.SnapshotLog( self.config, self.comboProfiles.currentProfileID()) self.txtLogView.setPlainText( '\n'.join(log.get(mode=mode, decode=self.decode))) else: self.txtLogView.setPlainText( '\n'.join(self.sid.log(mode, decode=self.decode))) def closeEvent(self, event): state_data = StateData() state_data.logview_dims = (self.width(), self.height()) event.accept() backintime-1.5.4/qt/man/000077500000000000000000000000001477034762000150405ustar00rootroot00000000000000backintime-1.5.4/qt/man/C/000077500000000000000000000000001477034762000152225ustar00rootroot00000000000000backintime-1.5.4/qt/man/C/backintime-qt.1000066400000000000000000000115751477034762000200450ustar00rootroot00000000000000.TH backintime-qt 1 "November 2024" "version 1.5.4" "USER COMMANDS" .SH NAME backintime-qt \- a simple backup tool. .SH SYNOPSIS .B backintime-qt [\-\-checksum] [\-\-config PATH] [\-\-debug] [\-\-delete] [\-\-help | \-h] [\-\-keep\-mount] [\-\-license] [\-\-local\-backup | \-\-no\-local\-backup] [\-\-no\-crontab] [\-\-only\-new] [\-\-profile NAME | \-\-profile\-id ID] [\-\-quiet] [\-\-share\-path PATH] [\-\-version] { backup | backup\-job | benchmark-cipher [FILE-SIZE] | check-config | decode [PATH] | last\-snapshot | last\-snapshot\-path | pw\-cache [start|stop|restart|reload|status] | remove[\-and\-do\-not\-ask\-again] [SNAPSHOT_ID] | restore [WHAT [WHERE [SNAPSHOT_ID]]] | shutdown | smart\-remove | snapshots\-list | snapshots\-list\-path | snapshots\-path | unmount } .SH DESCRIPTION Back In Time is a simple backup tool for Linux. This is the Qt version. For more information about Back In Time see backintime man page. .PP If you want to run it as root you need to use 'backintime-qt_polkit'. .SH OPTIONS .TP \-\-checksum Force to use checksum for checking if files have been changed. This is the same as 'Use checksum to detect changes' in Options. But you can use this to periodically run checksums from cronjobs. Only valid with \fIbackup\fR, \fIbackup-job\fR and \fIrestore\fR. .TP \-\-config PATH Read config from PATH. Default = ~/.config/backintime/config .TP --debug Show debug messages. .TP --delete Restore and delete newer files which are not in the snapshot. WARNING: deleting files in filesystem root could break your whole system!!! Only valid with \fIrestore\fR. .TP \-h, \-\-help Display a short help .TP \-\-keep\-mount Don't unmount on exit. Only valid with \fIsnapshots\-path\fR, \fIsnapshots\-list\-path\fR and \fIlast\-snapshot\-path\fR. .TP \-\-license Show license .TP --local-backup Create backup files before changing local files. Only valid with \fIrestore\fR. .TP --no-crontab Do not install crontab entries. Only valid with \fIcheck-config\fR. .TP --no-local-backup Temporary disable creation of backup files before changing local files. Only valid with \fIrestore\fR. .TP --only-new Only restore files which does not exist or are newer than those in destination. Using "rsync --update" option. Only valid with \fIrestore\fR. .TP \-\-profile NAME Select profile by name .TP \-\-profile\-id ID Select profile by id .TP \-\-quiet Suppress status messages on standard output. .TP \-\-share\-path PATH Write runtime data (locks, messages, log and mountpoints) to PATH. .TP \-v, \-\-version Show version .SH COMMANDS .TP backup | \-b | \-\-backup Take a snapshot now. .TP backup\-job | \-\-backup\-job Take a snapshot (if needed) depending on schedule rules (used for cron jobs). Back In Time will run in background for this. .TP benchmark-cipher | \-\-benchmark-cipher [FILE-SIZE] Show a benchmark of all ciphers for ssh transfer. .TP check-config Verify the profile in config, create snapshot path and crontab entries. .TP decode | \-\-decode [PATH] Decode encrypted PATH. If no PATH is given Back In Time will read paths from standard input. .TP last\-snapshot | \-\-last\-snapshot Display last snapshot ID (if any) .TP last\-snapshot\-path | \-\-last\-snapshot\-path Display the path to the last snapshot (if any) .TP pw\-cache | \-\-pw\-cache [start|stop|restart|reload|status] Control the Password Cache Daemon. If no argument is given the Password Cache will start in foreground. .TP remove[\-and\-do\-not\-ask\-again] | \-\-remove[\-and\-do\-not\-ask\-again] [SNAPSHOT_ID] Remove the snapshot. If SNAPSHOT_ID is missing it will be prompted. SNAPSHOT_ID can be an index (starting with 0 for the last snapshot) or the exact SnapshotID (19 characters like '20130606-230501-984'). \fIremove\-and\-do\-not\-ask\-again\fR will remove the snapshot immediately. Be careful with this! .TP restore | \-\-restore [WHAT [WHERE [SNAPSHOT_ID]]] Restore file WHAT to path WHERE from snapshot SNAPSHOT_ID. If arguments are missing they will be prompted. To restore to the original path WHERE can be an empty string '' or just press Enter at the prompt. SNAPSHOT_ID can be an index (starting with 0 for the last snapshot) or the exact SnapshotID (19 characters like '20130606-230501-984') .TP shutdown Shutdown the computer after the snapshot is done. .TP smart\-remove Remove snapshots based on the configured Smart-Remove pattern. .TP snapshots\-list | \-\-snapshots\-list Display the list of snapshot IDs (if any) .TP snapshots\-list\-path | \-\-snapshots\-list\-path Display the paths to snapshots (if any) .TP snapshots\-path | \-\-snapshots\-path Display path where is saves the snapshots (if configured) .TP unmount | \-\-unmount Unmount the profile. .SH SEE ALSO .BR backintime-qt (1), .BR backintime-config (1), .BR backintime-askpass (1) .PP \fBBack In Time\fP project website: https://github.com/bit-team/backintime .PP \fBBack In Time\fP mailing list: https://mail.python.org/mailman3/lists/bit-dev.python.org .SH AUTHOR \fBBack In Time\fP Team backintime-1.5.4/qt/manageprofiles/000077500000000000000000000000001477034762000172615ustar00rootroot00000000000000backintime-1.5.4/qt/manageprofiles/__init__.py000066400000000000000000000710011477034762000213710ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import re import copy from PyQt6.QtGui import QPalette, QBrush, QIcon from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QDialogButtonBox, QMessageBox, QInputDialog, QScrollArea, QFrame, QWidget, QTabWidget, QLabel, QPushButton, QSpinBox, QTreeWidget, QTreeWidgetItem, QAbstractItemView, QHeaderView, QCheckBox) from PyQt6.QtCore import Qt import tools import qttools import messagebox from statedata import StateData from manageprofiles.tab_general import GeneralTab from manageprofiles.tab_remove_retention import RemoveRetentionTab from manageprofiles.tab_options import OptionsTab from manageprofiles.tab_expert_options import ExpertOptionsTab from editusercallback import EditUserCallback from restoreconfigdialog import RestoreConfigDialog MATCH_FLAGS = Qt.MatchFlag.MatchFixedString | Qt.MatchFlag.MatchCaseSensitive class SettingsDialog(QDialog): def __init__(self, parent): super(SettingsDialog, self).__init__(parent) self.parent = parent self.config = parent.config self.snapshots = parent.snapshots self.configDictCopy = copy.copy(self.config.dict) self.originalCurrentProfile = self.config.currentProfile() import icon self.icon = icon self.config.setQuestionHandler(self.questionHandler) self.config.setErrorHandler(self.errorHandler) self.setWindowIcon(icon.SETTINGS_DIALOG) self.setWindowTitle(_('Manage profiles')) self.mainLayout = QVBoxLayout(self) # profiles layout = QHBoxLayout() self.mainLayout.addLayout(layout) layout.addWidget(QLabel(_('Profile:'), self)) self.firstUpdateAll = True self.disableProfileChanged = True self.comboProfiles = qttools.ProfileCombo(self) layout.addWidget(self.comboProfiles, 1) self.comboProfiles.currentIndexChanged.connect(self.profileChanged) self.disableProfileChanged = False self.btnEditProfile = QPushButton(icon.PROFILE_EDIT, _('Edit'), self) self.btnEditProfile.clicked.connect(self.editProfile) layout.addWidget(self.btnEditProfile) self.btnAddProfile = QPushButton(icon.ADD, _('Add'), self) self.btnAddProfile.clicked.connect(self.addProfile) layout.addWidget(self.btnAddProfile) self.btnRemoveProfile = QPushButton(icon.REMOVE, _('Remove'), self) self.btnRemoveProfile.clicked.connect(self.removeProfile) layout.addWidget(self.btnRemoveProfile) # TABs self.tabs = QTabWidget(self) self.mainLayout.addWidget(self.tabs) # occupy whole space for tabs scrollButtonDefault = self.tabs.usesScrollButtons() self.tabs.setUsesScrollButtons(False) def _add_tab(wdg: QWidget, label: str): scrollArea = QScrollArea(self) scrollArea.setFrameStyle(QFrame.Shape.NoFrame) self.tabs.addTab(scrollArea, label) scrollArea.setWidget(wdg) scrollArea.setWidgetResizable(True) # TAB: General self._tab_general = GeneralTab(self) _add_tab(self._tab_general, _('&General')) # TAB: Include tabWidget = QWidget(self) self.tabs.addTab(tabWidget, _('&Include')) layout = QVBoxLayout(tabWidget) self.listInclude = QTreeWidget(self) self.listInclude.setSelectionMode( QAbstractItemView.SelectionMode.ExtendedSelection) self.listInclude.setRootIsDecorated(False) self.listInclude.setHeaderLabels( [_('Include files and directories'), 'Count']) self.listInclude.header().setSectionResizeMode( 0, QHeaderView.ResizeMode.Stretch) self.listInclude.header().setSectionsClickable(True) self.listInclude.header().setSortIndicatorShown(True) self.listInclude.header().setSectionHidden(1, True) self.listIncludeSortLoop = False self.listInclude.header().sortIndicatorChanged \ .connect(self.includeCustomSortOrder) layout.addWidget(self.listInclude) self.listIncludeCount = 0 buttonsLayout = QHBoxLayout() layout.addLayout(buttonsLayout) self.btnIncludeFile = QPushButton(icon.ADD, _('Add file'), self) buttonsLayout.addWidget(self.btnIncludeFile) self.btnIncludeFile.clicked.connect(self.btnIncludeFileClicked) self.btnIncludeAdd = QPushButton(icon.ADD, _('Add directory'), self) buttonsLayout.addWidget(self.btnIncludeAdd) self.btnIncludeAdd.clicked.connect(self.btnIncludeAddClicked) self.btnIncludeRemove = QPushButton(icon.REMOVE, _('Remove'), self) buttonsLayout.addWidget(self.btnIncludeRemove) self.btnIncludeRemove.clicked.connect(self.btnIncludeRemoveClicked) # TAB: Exclude tabWidget = QWidget(self) self.tabs.addTab(tabWidget, _('&Exclude')) layout = QVBoxLayout(tabWidget) self.lblSshEncfsExcludeWarning = QLabel(_( "{BOLD}Info{ENDBOLD}: " "In 'SSH encrypted' mode, only single or double asterisks are " "functional (e.g. {example2}). Other types of wildcards and " "patterns will be ignored (e.g. {example1}). Filenames are " "unpredictable in this mode due to encryption by EncFS.").format( BOLD='', ENDBOLD='', example1="'foo*', " "'[fF]oo', " "'fo?'", example2="'foo/*', " "'foo/**/bar'" ), self ) self.lblSshEncfsExcludeWarning.setWordWrap(True) layout.addWidget(self.lblSshEncfsExcludeWarning) self.listExclude = QTreeWidget(self) self.listExclude.setSelectionMode( QAbstractItemView.SelectionMode.ExtendedSelection) self.listExclude.setRootIsDecorated(False) self.listExclude.setHeaderLabels( [_('Exclude patterns, files or directories'), 'Count']) self.listExclude.header().setSectionResizeMode( 0, QHeaderView.ResizeMode.Stretch) self.listExclude.header().setSectionsClickable(True) self.listExclude.header().setSortIndicatorShown(True) self.listExclude.header().setSectionHidden(1, True) self.listExcludeSortLoop = False self.listExclude.header().sortIndicatorChanged \ .connect(self.excludeCustomSortOrder) layout.addWidget(self.listExclude) self._label_exclude_recommend = QLabel('', self) self._label_exclude_recommend.setWordWrap(True) layout.addWidget(self._label_exclude_recommend) buttonsLayout = QHBoxLayout() layout.addLayout(buttonsLayout) self.btnExcludeAdd = QPushButton(icon.ADD, _('Add'), self) buttonsLayout.addWidget(self.btnExcludeAdd) self.btnExcludeAdd.clicked.connect(self.btnExcludeAddClicked) self.btnExcludeFile = QPushButton(icon.ADD, _('Add file'), self) buttonsLayout.addWidget(self.btnExcludeFile) self.btnExcludeFile.clicked.connect(self.btnExcludeFileClicked) self.btnExcludeFolder = QPushButton(icon.ADD, _('Add directory'), self) buttonsLayout.addWidget(self.btnExcludeFolder) self.btnExcludeFolder.clicked.connect(self.btnExcludeFolderClicked) self.btnExcludeDefault = QPushButton(icon.DEFAULT_EXCLUDE, _('Add default'), self) buttonsLayout.addWidget(self.btnExcludeDefault) self.btnExcludeDefault.clicked.connect(self.btnExcludeDefaultClicked) self.btnExcludeRemove = QPushButton(icon.REMOVE, _('Remove'), self) buttonsLayout.addWidget(self.btnExcludeRemove) self.btnExcludeRemove.clicked.connect(self.btnExcludeRemoveClicked) # exclude files by size hlayout = QHBoxLayout() layout.addLayout(hlayout) self.cbExcludeBySize = QCheckBox( _('Exclude files bigger than:'), self) qttools.set_wrapped_tooltip( self.cbExcludeBySize, [ _('Exclude files bigger than value in {size_unit}.') .format(size_unit='MiB'), _("With 'Full rsync mode' disabled, this will only impact " "new files since for rsync, this is a transfer option, not " "an exclusion option. Therefore, large files that have " "been backed up previously will persist in snapshots even " "if they have been modified.") ] ) hlayout.addWidget(self.cbExcludeBySize) self.spbExcludeBySize = QSpinBox(self) self.spbExcludeBySize.setSuffix(' MiB') self.spbExcludeBySize.setRange(0, 100000000) hlayout.addWidget(self.spbExcludeBySize) hlayout.addStretch() enabled = lambda state: self.spbExcludeBySize.setEnabled(state) enabled(False) self.cbExcludeBySize.stateChanged.connect(enabled) # TAB: Auto-remove self._tab_retention = RemoveRetentionTab(self) _add_tab(self._tab_retention, # Mask the "&" character, so Qt does not interpret it as a # shortcut indicator. Doing this via regex to prevent # confusing our translators. hide this from # our translators. re.sub( # "&" followed by whitespace r'&(?=\s)', # replace with this '&&', # act on that string _('&Remove & Retention') )) # TAB: Options self._tab_options = OptionsTab(self) _add_tab(self._tab_options, _('&Options')) # TAB: Expert Options self._tab_expert_options = ExpertOptionsTab(self) _add_tab(self._tab_expert_options, _('E&xpert Options')) # buttons buttonBox = QDialogButtonBox( QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, parent=self) btnRestore = buttonBox.addButton( _('Restore Config'), QDialogButtonBox.ButtonRole.ResetRole) btnUserCallback = buttonBox.addButton( _('Edit user-callback'), QDialogButtonBox.ButtonRole.ResetRole) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) btnRestore.clicked.connect(self.restoreConfig) btnUserCallback.clicked.connect(self.editUserCallback) self.mainLayout.addWidget(buttonBox) self.updateProfiles() self.slot_combo_modes_changed() # enable tabs scroll buttons again but keep dialog size size = self.sizeHint() self.tabs.setUsesScrollButtons(scrollButtonDefault) self.resize(size) self.finished.connect(self._slot_finished) def addProfile(self): ret_val = QInputDialog.getText(self, _('New profile'), str()) if not ret_val[1]: return name = ret_val[0].strip() if not name: return profile_id = self.config.addProfile(name) if profile_id is None: return self.config.setCurrentProfile(profile_id) self.updateProfiles() def editProfile(self): ret_val = QInputDialog.getText( self, _('Rename profile'), str(), text=self.config.profileName()) if not ret_val[1]: return name = ret_val[0].strip() if not name: return if not self.config.setProfileName(name): return self.updateProfiles(reloadSettings=False) def removeProfile(self): question = _('Are you sure you want to delete ' 'the profile "{name}"?').format( name=self.config.profileName()) if self.questionHandler(question): self.config.removeProfile() self.updateProfiles() def profileChanged(self, index): if self.disableProfileChanged: return current_profile_id = self.comboProfiles.currentProfileID() if not current_profile_id: return if current_profile_id != self.config.currentProfile(): self.saveProfile() self.config.setCurrentProfile(current_profile_id) self.updateProfile() def updateProfiles(self, reloadSettings=True): if reloadSettings: self.updateProfile() current_profile_id = self.config.currentProfile() self.disableProfileChanged = True self.comboProfiles.clear() qttools.update_combo_profiles( self.config, self.comboProfiles, current_profile_id) self.disableProfileChanged = False def _update_exclude_recommend_label(self): """Update the label about recommended exclude patterns.""" # Default patterns that are not still in the list widget recommend = list(filter( lambda val: not self.listExclude.findItems(val, MATCH_FLAGS), self.config.DEFAULT_EXCLUDE )) if not recommend: text = _('{BOLD}Highly recommended{ENDBOLD}: (All recommendations ' 'already included.)').format( BOLD='', ENDBOLD='') else: text = _('{BOLD}Highly recommended{ENDBOLD}: {files}').format( BOLD='', ENDBOLD='', files=', '.join(sorted(recommend))) self._label_exclude_recommend.setText(text) def updateProfile(self): if self.config.currentProfile() == '1': self.btnEditProfile.setEnabled(False) self.btnRemoveProfile.setEnabled(False) else: self.btnEditProfile.setEnabled(True) self.btnRemoveProfile.setEnabled(True) self.btnAddProfile.setEnabled(self.config.isConfigured('1')) profile_state = StateData().profile(self.config.currentProfile()) # TAB: General self._tab_general.load_values() # TAB: Include self.listInclude.clear() for include in self.config.include(): self.addInclude(include) # TAB: Exclude self.listExclude.clear() for exclude in self.config.exclude(): self._add_exclude_pattern(exclude) self.cbExcludeBySize.setChecked(self.config.excludeBySizeEnabled()) self.spbExcludeBySize.setValue(self.config.excludeBySize()) try: incl_sort = profile_state.include_sorting excl_sort = profile_state.exclude_sorting self.listInclude.sortItems( incl_sort[0], Qt.SortOrder(incl_sort[1]) ) self.listExclude.sortItems( excl_sort[0], Qt.SortOrder(excl_sort[1])) except KeyError: pass self._update_exclude_recommend_label() self._tab_retention.load_values() self._tab_options.load_values() self._tab_expert_options.load_values() def saveProfile(self): # These tabs need to be stored before the Generals tab, because the # latter is doing some premount checking and need to know this settings # first. self._tab_retention.store_values() self._tab_options.store_values() self._tab_expert_options.store_values() # Dev note: This return "False" if something goes wrong. Otherwise it # returns a dict with several mounting related information. success = self._tab_general.store_values() if success is False: return False profile_state = StateData().profile(self.config.currentProfile()) # include list profile_state.include_sorting = ( self.listInclude.header().sortIndicatorSection(), self.listInclude.header().sortIndicatorOrder().value ) # Why? self.listInclude.sortItems(1, Qt.SortOrder.AscendingOrder) include_list = [] for index in range(self.listInclude.topLevelItemCount()): item = self.listInclude.topLevelItem(index) include_list.append( (item.text(0), item.data(0, Qt.ItemDataRole.UserRole))) self.config.setInclude(include_list) # exclude patterns profile_state.exclude_sorting = ( self.listExclude.header().sortIndicatorSection(), self.listExclude.header().sortIndicatorOrder().value ) # Why? self.listExclude.sortItems(1, Qt.SortOrder.AscendingOrder) exclude_list = [] for index in range(self.listExclude.topLevelItemCount()): item = self.listExclude.topLevelItem(index) exclude_list.append(item.text(0)) self.config.setExclude(exclude_list) self.config.setExcludeBySize(self.cbExcludeBySize.isChecked(), self.spbExcludeBySize.value()) return True def errorHandler(self, message): messagebox.critical(self, message) def questionHandler(self, message): answer = messagebox.warningYesNo(self, message) return answer == QMessageBox.StandardButton.Yes def addInclude(self, data): item = QTreeWidgetItem() # Directory(0) or file(1)? if data[1] == 0: item.setIcon(0, self.icon.FOLDER) else: item.setIcon(0, self.icon.FILE) # Prevent duplicates duplicates = self.listInclude.findItems(data[0], MATCH_FLAGS) if duplicates: self.listInclude.setCurrentItem(duplicates[0]) return # First column item.setText(0, data[0]) item.setData(0, Qt.ItemDataRole.UserRole, data[1]) self.listIncludeCount += 1 # Second (hidden!) column. # Don't know why we need it. item.setText(1, str(self.listIncludeCount).zfill(6)) item.setData(1, Qt.ItemDataRole.UserRole, self.listIncludeCount) self.listInclude.addTopLevelItem(item) # Select/highlight that entry. self.listInclude.setCurrentItem(item) def _add_exclude_pattern(self, pattern): item = QTreeWidgetItem() item.setText(0, pattern) item.setData(0, Qt.ItemDataRole.UserRole, pattern) self._formatExcludeItem(item) # Add item to the widget self.listExclude.addTopLevelItem(item) return item def fillCombo(self, combo, d): keys = list(d.keys()) keys.sort() for key in keys: combo.addItem(QIcon(), d[key], key) def setComboValue(self, combo, value, t='int'): for i in range(combo.count()): if t == 'int' and value == combo.itemData(i): combo.setCurrentIndex(i) break if t == 'str' and value == combo.itemData(i): combo.setCurrentIndex(i) break def validate(self): if not self.saveProfile(): return False if not self.config.checkConfig(): return False if not self.config.setupCron(): return False return self.config.save() def btnExcludeRemoveClicked(self): for item in self.listExclude.selectedItems(): index = self.listExclude.indexOfTopLevelItem(item) if index < 0: continue self.listExclude.takeTopLevelItem(index) if self.listExclude.topLevelItemCount() > 0: self.listExclude.setCurrentItem(self.listExclude.topLevelItem(0)) self._update_exclude_recommend_label() def addExclude(self, pattern): """Initiate adding a new exclude pattern to the list widget. See `_add_exclude_pattern()` also. """ if not pattern: return # Duplicate? duplicates = self.listExclude.findItems(pattern, MATCH_FLAGS) if duplicates: # TODO notify user about duplicates self.listExclude.setCurrentItem(duplicates[0]) return # Create new entry and add it to the list widget. item = self._add_exclude_pattern(pattern) # Select/highlight that entry. self.listExclude.setCurrentItem(item) self._update_exclude_recommend_label() def btnExcludeAddClicked(self): dlg = QInputDialog(self) dlg.setInputMode(QInputDialog.InputMode.TextInput) dlg.setWindowTitle(_('Exclude pattern')) dlg.setLabelText('') dlg.resize(400, 0) if not dlg.exec(): return pattern = dlg.textValue().strip() if not pattern: return self.addExclude(pattern) def btnExcludeFileClicked(self): for path in qttools.getOpenFileNames(self, _('Exclude file')): self.addExclude(path) def btnExcludeFolderClicked(self): for path in qttools.getExistingDirectories(self, _('Exclude directory')): self.addExclude(path) def btnExcludeDefaultClicked(self): for path in self.config.DEFAULT_EXCLUDE: self.addExclude(path) def btnIncludeRemoveClicked(self): for item in self.listInclude.selectedItems(): index = self.listInclude.indexOfTopLevelItem(item) if index < 0: continue self.listInclude.takeTopLevelItem(index) if self.listInclude.topLevelItemCount() > 0: self.listInclude.setCurrentItem(self.listInclude.topLevelItem(0)) def btnIncludeFileClicked(self): """Development Note (buhtz 2023-12): This is a candidate for refactoring. See btnIncludeAddClicked() with much duplicated code. """ for path in qttools.getOpenFileNames(self, _('Include file')): if not path: continue if os.path.islink(path) \ and not (self.cbCopyUnsafeLinks.isChecked() or self.cbCopyLinks.isChecked()): question_msg = _( '"{path}" is a symlink. The linked target will not be ' 'backed up until you include it, too.\nWould you like ' 'to include the symlink target instead?' ).format(path=path) if self.questionHandler(question_msg): path = os.path.realpath(path) path = self.config.preparePath(path) for index in range(self.listInclude.topLevelItemCount()): if path == self.listInclude.topLevelItem(index).text(0): continue self.addInclude((path, 1)) def btnIncludeAddClicked(self): """Development Note (buhtz 2023-12): This is a candidate for refactoring. See btnIncludeFileClicked() with much duplicated code. """ for path in qttools.getExistingDirectories(self, _('Include directory')): if not path: continue if os.path.islink(path) \ and not (self.cbCopyUnsafeLinks.isChecked() or self.cbCopyLinks.isChecked()): question_msg = _( '"{path}" is a symlink. The linked target will not be ' 'backed up until you include it, too.\nWould you like ' 'to include the symlink target instead?') \ .format(path=path) if self.questionHandler(question_msg): path = os.path.realpath(path) path = self.config.preparePath(path) for index in range(self.listInclude.topLevelItemCount()): if path == self.listInclude.topLevelItem(index).text(0): continue self.addInclude((path, 0)) def slot_combo_modes_changed(self, *params): """Hide/show widget elements related to one of the four snapshot modes. That slot is connected to a signal in the `GeneralTab`. """ self._tab_general.handle_combo_modes_changed() active_mode = self._tab_general.get_active_snapshots_mode() enabled = active_mode in ('ssh', 'ssh_encfs') self.updateExcludeItems() self._tab_retention.update_items_state(enabled) self._tab_expert_options.update_items_state(enabled) def updateExcludeItems(self): for index in range(self.listExclude.topLevelItemCount()): item = self.listExclude.topLevelItem(index) self._formatExcludeItem(item) def _format_exclude_item_encfs_invalid(self, item): """Modify visual appearance of an item in the exclude list widget to express that the item is invalid. See :py:func:`_formatExcludeItem` for details. """ # Icon item.setIcon(0, self.icon.INVALID_EXCLUDE) # ToolTip item.setData( 0, Qt.ItemDataRole.ToolTipRole, _("Disabled because this pattern is not functional in " "mode 'SSH encrypted'.") ) # Fore- and Backgroundcolor (as disabled) item.setBackground(0, QPalette().brush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Window)) item.setForeground(0, QPalette().brush(QPalette.ColorGroup.Disabled, QPalette.ColorRole.Text)) def _formatExcludeItem(self, item): """Modify visual appearance of an item in the exclude list widget. """ if (self.mode == 'ssh_encfs' and tools.patternHasNotEncryptableWildcard(item.text(0))): # Invalid item (because of encfs restrictions) self._format_exclude_item_encfs_invalid(item) else: # default background color item.setBackground(0, QBrush()) item.setForeground(0, QBrush()) # Remove items tooltip item.setData(0, Qt.ItemDataRole.ToolTipRole, None) # Icon: default exclude item if item.text(0) in self.config.DEFAULT_EXCLUDE: item.setIcon(0, self.icon.DEFAULT_EXCLUDE) else: # Icon: user defined item.setIcon(0, self.icon.EXCLUDE) def customSortOrder(self, header, loop, newColumn, newOrder): if newColumn == 0 and newOrder == Qt.SortOrder.AscendingOrder: if loop: newColumn, newOrder = 1, Qt.SortOrder.AscendingOrder header.setSortIndicator(newColumn, newOrder) loop = False else: loop = True header.model().sort(newColumn, newOrder) return loop def includeCustomSortOrder(self, *args): self.listIncludeSortLoop = self.customSortOrder( self.listInclude.header(), self.listIncludeSortLoop, *args) def excludeCustomSortOrder(self, *args): self.listExcludeSortLoop = self.customSortOrder( self.listExclude.header(), self.listExcludeSortLoop, *args) def restoreConfig(self, *args): RestoreConfigDialog(self).exec() self.updateProfiles() def editUserCallback(self, *args): EditUserCallback(self).exec() def accept(self): if self.validate(): super(SettingsDialog, self).accept() def _slot_finished(self, result): """Handle dialogs finished signal.""" self.config.clearHandlers() if not result: self.config.dict = self.configDictCopy self.config.setCurrentProfile(self.originalCurrentProfile) if result: self.parent.remount(self.originalCurrentProfile, self.originalCurrentProfile) self.parent.updateProfiles() backintime-1.5.4/qt/manageprofiles/combobox.py000066400000000000000000000040131477034762000214410ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Module with an improved combo box widget.""" from typing import Any from PyQt6.QtWidgets import QComboBox, QWidget class BitComboBox(QComboBox): """Improved combo box. This widget can be filled (with content and data) just by a dictionary. It has the ability to select a specific entry based on its underlying `userData` instead of just the index. Example of a dictionary : :: # Values in the dictionary are the strings displayed in the combo box. # The keys are the underlying 'userData'. fill = { 10: 'Hour', 20: 'Day', 30: 'Week', 40: 'Month' } combo = BitComboBox(parent, fill) """ def __init__(self, parent: QWidget, content_dict: dict): """ Args: parent: The parent widget. content_dict: The dictionary values used to display entries in the combo box and the keys used as data. """ super().__init__(parent=parent) self._content_dict = content_dict for data, entry in self._content_dict.items(): self.addItem(entry, userData=data) @property def current_data(self) -> Any: """Data linked to the current selected entry.""" return self.itemData(self.currentIndex()) def select_by_data(self, data: Any): """Select an entry in the combo box by its underlying data.""" for idx in range(self.count()): if self.itemData(idx) == data: self.setCurrentIndex(idx) return raise ValueError('Unable to select combo box entry because data not ' f'found in it. Data is: {data} (type: {type(data)})') backintime-1.5.4/qt/manageprofiles/schedulewidget.py000066400000000000000000000303001477034762000226270ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """The widget to setup scheduling backup jobs.""" import datetime from PyQt6.QtWidgets import (QHBoxLayout, QFormLayout, QGroupBox, QWidget, QLabel, QLineEdit, QSpinBox, QCheckBox) import config import tools import qttools from manageprofiles import combobox class ScheduleWidget(QGroupBox): """Widget about schedule snapshots. That widget is used in the 'General' tab of the 'Manage profiles' dialog. """ # pylint: disable=too-many-instance-attributes def __init__(self, parent): super().__init__(title=_('Schedule'), parent=parent) main_layout = QFormLayout(self) def _create_form_entry(label: str, widget: QWidget = None) -> int: """Helper to create a row with a label and widget in the form layout. The returned index is used later to toggle visibility of that row. """ if widget: main_layout.addRow(label, widget) else: lbl = QLabel(label) lbl.setWordWrap(True) main_layout.addRow(lbl) return main_layout.rowCount() - 1 # Schedule modes self._combo_schedule_mode = self._schedule_mode_combobox() main_layout.addRow(self._combo_schedule_mode) # Day self._combo_day = self._day_combobox() self._rowidx_day = _create_form_entry(_('Day:'), self._combo_day) # Weekday self._combo_weekday = self._weekday_combobox() self._rowidx_weekday = _create_form_entry( _('Weekday:'), self._combo_weekday) # Time (formerly known as Hour) self._combo_time = self._time_combobox() self._rowidx_time = _create_form_entry( _('Time:'), self._combo_time) # HourS self._edit_cronpattern = QLineEdit(self) self._rowidx_cronpattern = _create_form_entry( _('Hours:'), self._edit_cronpattern) # Offset self._spin_offset = QSpinBox(self) self._spin_offset.setSingleStep(1) self._spin_offset.setRange(0, 59) hlayout = QHBoxLayout() hlayout.addWidget(self._spin_offset) hlayout.addWidget(QLabel(_('after the hour'), self)) hlayout.addStretch() self._rowidx_offset = _create_form_entry(_('Minutes:'), hlayout) # Udev self._rowidx_udev = _create_form_entry( _('Run Back In Time as soon as the drive is connected (only once' ' every X days). You will be prompted for your sudo password.')) # Repeatedly (like anacron) self._rowidx_repeated = _create_form_entry( _('Run Back In Time repeatedly. This is useful if the computer ' 'is not running regularly.')) # Repeatedly - Every (value) (units) self._spin_period = QSpinBox(self) self._spin_period.setSingleStep(1) self._spin_period.setRange(1, 10000) self._combo_repeated_unit = self._repeated_unit_combobox() hlayout = QHBoxLayout() hlayout.addWidget(self._spin_period) hlayout.addWidget(self._combo_repeated_unit) hlayout.addStretch() self._rowidx_period = _create_form_entry(_('Every:'), hlayout) # Debug logging self._check_debug = QCheckBox(self) self._check_debug.setText(_('Enable logging of debug messages')) qttools.set_wrapped_tooltip( self._check_debug, [ _('Writes debug-level messages into the system log via ' '"--debug".'), _('Caution: Only use this temporarily for diagnostics, as it ' 'generates a large amount of output.') ] ) self._rowidx_debug = main_layout.rowCount() main_layout.addRow(self._check_debug) # Signal self._combo_schedule_mode.currentIndexChanged.connect( self._slot_schedule_mode_changed) self._slot_schedule_mode_changed(None) def _schedule_mode_combobox(self) -> combobox.BitComboBox: """Create the the combobox for schedule mode. Returns: BitComboBox: The widget. """ # pylint: disable=protected-access # Regular schedule modes for that combo box schedule_modes = { config.Config.NONE: _('Disabled'), config.Config.AT_EVERY_BOOT: _('At every boot/reboot'), config.Config._5_MIN: ngettext( 'Every {n} minute', 'Every {n} minutes', 5).format(n=5), config.Config._10_MIN: ngettext( 'Every {n} minute', 'Every {n} minutes', 10).format(n=10), config.Config._30_MIN: ngettext( 'Every {n} minute', 'Every {n} minutes', 30).format(n=30), config.Config._1_HOUR: ngettext( 'Every hour', 'Every {n} hours', 1).format(n=1), config.Config._2_HOURS: ngettext( 'Every {n} hour', 'Every {n} hours', 2).format(n=2), config.Config._4_HOURS: ngettext( 'Every {n} hour', 'Every {n} hours', 4).format(n=4), config.Config._6_HOURS: ngettext( 'Every {n} hour', 'Every {n} hours', 6).format(n=6), config.Config._12_HOURS: ngettext( 'Every {n} hour', 'Every {n} hours', 12).format(n=12), config.Config.CUSTOM_HOUR: _('Custom hours'), config.Config.DAY: _('Every day'), config.Config.REPEATEDLY: _('Repeatedly (anacron)'), config.Config.UDEV: _('When drive gets connected (udev)'), config.Config.WEEK: _('Every week'), config.Config.MONTH: _('Every month'), config.Config.YEAR: _('Every year') } return combobox.BitComboBox(self, schedule_modes) def _time_combobox(self) -> combobox.BitComboBox: """Combobox with time/hours (e.g. 03:00). Returns: BitComboBox: The widget. """ # Dev note (buhtz): strftime is needed because of localization # {0: '00:00', 100: '01:00', ..., 2200: '22:00', 2300: '23:00'} times = { val*100: datetime.time(val, 0).strftime('%H:%M') for val in range(0, 24) } return combobox.BitComboBox(self, times) def _day_combobox(self) -> combobox.BitComboBox: """Combobox with day number in the month. Returns: BitComboBox: The widget. """ days = {day: str(day) for day in range(1, 29)} return combobox.BitComboBox(self, days) def _weekday_combobox(self) -> combobox.BitComboBox: """Combobox with name of the weekday. Returns: BitComboBox: The widget. """ sunday = datetime.date(2011, 11, 6) weekdays = { day: (sunday + datetime.timedelta(days=day)).strftime('%A') for day in range(1, 8) } return combobox.BitComboBox(self, weekdays) def _repeated_unit_combobox(self): """Combobox for "Every ..." schedule mode to select the units to use. Returns: BitComboBox: The widget. """ repeatedly_units = { config.Config.HOUR: _('Hour(s)'), config.Config.DAY: _('Day(s)'), config.Config.WEEK: _('Week(s)'), config.Config.MONTH: _('Month(s)') } return combobox.BitComboBox(self, repeatedly_units) def _slot_schedule_mode_changed(self, _idx): """Handle value changed events for schedule mode combobox.""" self._set_child_visibilities(self._combo_schedule_mode.current_data) def _set_child_visibilities(self, backup_mode_id: int): """Modify the visibility of child widgets (addressed by their index in the form layout) based on the selected schedule mode. """ layout = self.layout() layout.setRowVisible( self._rowidx_cronpattern, backup_mode_id == config.Config.CUSTOM_HOUR) layout.setRowVisible( self._rowidx_weekday, backup_mode_id == config.Config.WEEK) layout.setRowVisible( self._rowidx_day, backup_mode_id == config.Config.MONTH) layout.setRowVisible( self._rowidx_time, backup_mode_id >= config.Config.DAY) layout.setRowVisible( self._rowidx_offset, backup_mode_id in config.Config.HOURLY_BACKUPS ) vis = config.Config.REPEATEDLY <= backup_mode_id <= config.Config.UDEV layout.setRowVisible( self._rowidx_period, vis) if vis is True: layout.setRowVisible(self._rowidx_time, False) layout.setRowVisible( self._rowidx_repeated, backup_mode_id == config.Config.REPEATEDLY) layout.setRowVisible( self._rowidx_udev, backup_mode_id == config.Config.UDEV) def load_values(self, cfg: config.Config): """Set the values of the widgets regarding the current config.""" self._combo_schedule_mode.select_by_data(cfg.scheduleMode()) self._combo_time.select_by_data(cfg.scheduleTime()) self._combo_day.select_by_data(cfg.scheduleDay()) self._combo_weekday.select_by_data(cfg.scheduleWeekday()) self._spin_offset.setValue(cfg.schedule_offset()) self._edit_cronpattern.setText(cfg.customBackupTime()) self._spin_period.setValue(cfg.scheduleRepeatedPeriod()) self._combo_repeated_unit.select_by_data(cfg.scheduleRepeatedUnit()) self._check_debug.setChecked(cfg.scheduleDebug()) self._slot_schedule_mode_changed( self._combo_schedule_mode.currentIndex()) def store_values(self, cfg: config.Config) -> bool: """Store the widgets values in the config instance. Args: cfg: The configuration data instance. Returns: bool: Success or not. """ if self._combo_schedule_mode.current_data == cfg.CUSTOM_HOUR: # Dev note (buhtz, 2024-05): IMHO checkCronPattern() is not needed # because the "crontab" command itself will validate this. See # schedule.write_crontab(). # We just need to take care to catch an the error in the GUI # and report it to the user. # An alternative solution would be a GUI element where the user # is not able to input an invalid value. See #1449 about redesign # the schedule section in the Manage Profiles dialog. if not tools.checkCronPattern(self._edit_cronpattern.text()): cfg.errorHandler( _('Custom hours can only be a comma separated list of ' 'hours (e.g. 8,12,18,23) or */3 for periodic ' 'backups every 3 hours.') ) return False cfg.setScheduleMode(self._combo_schedule_mode.current_data) cfg.setScheduleTime(self._combo_time.current_data) if cfg.scheduleMode() in config.Config.HOURLY_BACKUPS: cfg.set_schedule_offset(self._spin_offset.value()) else: cfg.set_schedule_offset(config.Config.DEFAULT_OFFSET) cfg.setScheduleWeekday(self._combo_weekday.current_data) cfg.setScheduleDay(self._combo_day.current_data) cfg.setCustomBackupTime(self._edit_cronpattern.text()) cfg.setScheduleRepeatedPeriod(self._spin_period.value()) cfg.setScheduleRepeatedUnit(self._combo_repeated_unit.current_data) cfg.setScheduleDebug(self._check_debug.isChecked()) return True backintime-1.5.4/qt/manageprofiles/spinboxunit.py000066400000000000000000000035731477034762000222250ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Module with a widget combining a spinbox and a combobox.""" from typing import Any from PyQt6.QtWidgets import QSpinBox, QWidget, QHBoxLayout from manageprofiles.combobox import BitComboBox class SpinBoxWithUnit(QWidget): """A combination of a `QspinBox` and `BitComboBox` (`QComboBox`). """ def __init__(self, parent: QWidget, range_min_max: tuple[int, int], content_dict: dict): """ Args: parent: The parent widget. range_min_max: ... content_dict: The dictionary values used to display entries in the combo box and the keys used as data. """ super().__init__(parent=parent) layout = QHBoxLayout(self) self._spin = QSpinBox(self) self._spin.setRange(*range_min_max) layout.addWidget(self._spin) self._combo = BitComboBox(self, content_dict) layout.addWidget(self._combo) @property def data_and_unit(self) -> tuple[int, Any]: """Data linked to the current selected entry.""" return (self._spin.value(), self._combo.current_data) def select_unit(self, data: Any): """Select a unit entry in the combo box by its underlying data.""" self._combo.select_by_data(data) def unit(self) -> Any: return self._combo.current_data def value(self) -> int: """Get value of spin box.""" return self._spin.value() def set_value(self, val: int) -> None: """Set value of spin box.""" self._spin.setValue(val) backintime-1.5.4/qt/manageprofiles/sshproxywidget.py000066400000000000000000000070461477034762000227450ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """A widget to setup an SSH proxy.""" import getpass from PyQt6.QtWidgets import (QVBoxLayout, QHBoxLayout, QWidget, QLabel, QLineEdit, QCheckBox) from PyQt6.QtCore import Qt import qttools class SshProxyWidget(QWidget): """Used in SSH snapshot profiles on the General tab. Dev note by buhtz (2024-04): Just a quick n dirty solution until the re-design and re-factoring of the whole dialog. """ def __init__(self, parent, host, port, user): super().__init__(parent) if host == '': port = '' user = '' elif isinstance(port, int): port = str(port) vlayout = QVBoxLayout(self) # zero margins vlayout.setContentsMargins(0, 0, 0, 0) self._checkbox = QCheckBox(_('SSH Proxy'), self) vlayout.addWidget(self._checkbox) self._checkbox.stateChanged.connect(self._slot_checkbox_changed) hlayout = QHBoxLayout() vlayout.addLayout(hlayout) hlayout.addWidget(QLabel(_('Host:'), self)) self.host_edit = QLineEdit(host, self) hlayout.addWidget(self.host_edit) hlayout.addWidget(QLabel(_('Port:'), self)) self.port_edit = QLineEdit(port, self) hlayout.addWidget(self.port_edit) hlayout.addWidget(QLabel(_('User:'), self)) self.user_edit = QLineEdit(user, self) hlayout.addWidget(self.user_edit) if host == '': self._disable() qttools.set_wrapped_tooltip( self, _('Connect to the target host via this proxy (also known as a ' 'jump host). See "-J" in the "ssh" command documentation or ' '"ProxyJump" in "ssh_config" man page for details.') ) def _slot_checkbox_changed(self, state): if Qt.CheckState(state) == Qt.CheckState.Checked: self._enable() else: self._disable() def _set_default(self): """Set GUI elements back to default.""" self.host_edit.setText('') self.port_edit.setText('22') self.user_edit.setText(getpass.getuser()) def _disable(self): self._set_default() self._enable(False) def _enable(self, enable=True): # QEdit and QLabel's lay = self.layout().itemAt(1) for idx in range(lay.count()): lay.itemAt(idx).widget().setEnabled(enable) def values(self) -> dict[str, str, str]: """The widgets values as a dict. Returns: dict: A 3-item dict with keys "host", "port" and "user". """ if self._checkbox.isChecked(): return { 'host': self.host_edit.text(), 'port': self.port_edit.text(), 'user': self.user_edit.text(), } return { 'host': '', 'port': '', 'user': '', } backintime-1.5.4/qt/manageprofiles/statebindcheckbox.py000066400000000000000000000032031477034762000233150ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Module with an improved check box widget.""" from PyQt6.QtWidgets import QCheckBox, QWidget class StateBindCheckBox(QCheckBox): """A check box binding other widgets enabled states to its own check state. If the check box is checked all bound widgets are enabled. If the box is not checked all bound widgets are disabled. """ def __init__(self, text: str, parent: QWidget, bind: QWidget = None): """ Args: text: Label for this check box. parent: The parent widget. bind: One or a list of widgets to bind. """ super().__init__(text=text, parent=parent) self._widgets = [] if bind: self.bind(bind) self.stateChanged.connect(self._slot_state_changed) def bind(self, widget: QWidget) -> None: """The enabled state of `widget` is bound to the check state of the check box. Args: widget: The widget to bind. """ self._widgets.append(widget) self._slot_state_changed(self.isChecked()) def _slot_state_changed(self, state) -> None: """Set the enabled state of each bound widget based on the check state of the box.""" for wdg in self._widgets: wdg.setEnabled(state) backintime-1.5.4/qt/manageprofiles/tab_expert_options.py000066400000000000000000000467211477034762000235550ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QSpinBox, QLineEdit, QCheckBox) import config import tools import qttools import messagebox from manageprofiles.statebindcheckbox import StateBindCheckBox class ExpertOptionsTab(QDialog): """The 'Expert Options' tab in the Manage Profiles dialog.""" def __init__(self, parent): super().__init__(parent=parent) self._parent_dialog = parent tab_layout = QVBoxLayout(self) label = QLabel('{} {}'.format( _('Caution:'), _('These options are for advanced configurations. Modify ' 'only if fully aware of their implications.'))) label.setWordWrap(True) tab_layout.addWidget(label) # --- rsync with nice --- tab_layout.addWidget(QLabel( _("Run 'rsync' with '{cmd}':").format(cmd='nice'))) grid = QGridLayout() grid.setColumnMinimumWidth(0, 20) # left indent tab_layout.addLayout(grid) self.cbNiceOnCron = QCheckBox( _('as cron job') + self._default_string(self.config.DEFAULT_RUN_NICE_FROM_CRON), self) grid.addWidget(self.cbNiceOnCron, 0, 1) self.cbNiceOnRemote = QCheckBox( _('on remote host') + self._default_string(self.config.DEFAULT_RUN_NICE_ON_REMOTE), self) grid.addWidget(self.cbNiceOnRemote, 1, 1) # --- rsync with ionice --- tab_layout.addWidget(QLabel( _("Run 'rsync' with '{cmd}':").format(cmd='ionice'))) grid = QGridLayout() grid.setColumnMinimumWidth(0, 20) tab_layout.addLayout(grid) self.cbIoniceOnCron = QCheckBox( _('as cron job') + self._default_string(self.config.DEFAULT_RUN_IONICE_FROM_CRON), self) grid.addWidget(self.cbIoniceOnCron, 0, 1) self.cbIoniceOnUser = QCheckBox( _('when taking a manual snapshot') + self._default_string(self.config.DEFAULT_RUN_IONICE_FROM_USER), self) grid.addWidget(self.cbIoniceOnUser, 1, 1) self.cbIoniceOnRemote = QCheckBox( _('on remote host') + self._default_string(self.config.DEFAULT_RUN_IONICE_ON_REMOTE), self) grid.addWidget(self.cbIoniceOnRemote, 2, 1) # --- rsync with nocache --- tab_layout.addWidget(QLabel( _("Run 'rsync' with '{cmd}':").format(cmd='nocache'))) grid = QGridLayout() grid.setColumnMinimumWidth(0, 20) tab_layout.addLayout(grid) nocache_available = tools.checkCommand('nocache') if not nocache_available: grid.addWidget( QLabel( '' + _("Please install 'nocache' to enable this option.") + ''), 0, 1) self.cbNocacheOnLocal = QCheckBox( _('on local machine') + self._default_string(self.config.DEFAULT_RUN_NOCACHE_ON_LOCAL), self) grid.addWidget(self.cbNocacheOnLocal, 1, 1) self.cbNocacheOnLocal.setEnabled(nocache_available) self.cbNocacheOnRemote = QCheckBox( _('on remote host') + self._default_string(self.config.DEFAULT_RUN_NOCACHE_ON_REMOTE), self) grid.addWidget(self.cbNocacheOnRemote, 2, 1) # --- redirect output --- self.cbRedirectStdoutInCron = QCheckBox( _('Redirect stdout to /dev/null in cronjobs.') + self._default_string( self.config.DEFAULT_REDIRECT_STDOUT_IN_CRON), self) qttools.set_wrapped_tooltip( self.cbRedirectStdoutInCron, _('Cron will automatically send an email with attached output ' 'of cronjobs if an MTA is installed.') ) tab_layout.addWidget(self.cbRedirectStdoutInCron) self.cbRedirectStderrInCron = QCheckBox( _('Redirect stderr to /dev/null in cronjobs.') + self._default_string( self.config.DEFAULT_REDIRECT_STDERR_IN_CRON), self) qttools.set_wrapped_tooltip( self.cbRedirectStderrInCron, _('Cron will automatically send an email with attached errors ' 'of cronjobs if an MTA is installed.') ) tab_layout.addWidget(self.cbRedirectStderrInCron) # bandwidth limit hlayout = QHBoxLayout() tab_layout.addLayout(hlayout) self.spbBwlimit = QSpinBox(self) self.spbBwlimit.setSuffix(' ' + _('KB/sec')) self.spbBwlimit.setSingleStep(100) self.spbBwlimit.setRange(0, 1000000) self.cbBwlimit = StateBindCheckBox( _('Limit rsync bandwidth usage:'), self, self.spbBwlimit) hlayout.addWidget(self.cbBwlimit) hlayout.addWidget(self.spbBwlimit) hlayout.addStretch() qttools.set_wrapped_tooltip( self.cbBwlimit, [ "Uses 'rsync --bwlimit=RATE'. From 'man rsync':", 'This option allows you to specify the maximum transfer rate ' 'for the data sent over the socket, specified in units per ' 'second. The RATE value can be suffixed with a string to ' 'indicate a size multiplier, and may be a fractional value ' '(e.g. "--bwlimit=1.5m").', 'If no suffix is specified, the value will be assumed to be ' 'in units of 1024 bytes (as if "K" or "KiB" had been ' 'appended).', 'See the --max-size option for a description of all the ' 'available suffixes. A value of zero specifies no limit.' '', 'For backward-compatibility reasons, the rate limit will be ' 'rounded to the nearest KiB unit, so no rate smaller than ' '1024 bytes per second is possible.', '', 'Rsync writes data over the socket in blocks, and this option ' 'both limits the size of the blocks that rsync writes, and ' 'tries to keep the average transfer rate at the requested ' 'limit. Some "burstiness" may be seen where rsync writes out ' 'a block of data and then sleeps to bring the average rate ' 'into compliance.', '', 'Due to the internal buffering of data, the --progress ' 'option may not be an accurate reflection on how fast the ' 'data is being sent. This is because some files can show up ' 'as being rapidly sent when the data is quickly buffered, ' 'while other can show up as very slow when the flushing of ' 'the output buffer occurs. This may be fixed in a future ' 'version.' ] ) self.cbPreserveAcl = QCheckBox(_('Preserve ACL'), self) qttools.set_wrapped_tooltip( self.cbPreserveAcl, [ "Uses 'rsync -A'. From 'man rsync':", 'This option causes rsync to update the destination ACLs to ' 'be the same as the source ACLs. The option also implies ' '--perms.', '', 'The source and destination systems must have compatible ACL ' 'entries for this option to work properly. See the ' '--fake-super option for a way to backup and restore ACLs ' 'that are not compatible.' ] ) tab_layout.addWidget(self.cbPreserveAcl) self.cbPreserveXattr = QCheckBox( _('Preserve extended attributes (xattr)'), self) qttools.set_wrapped_tooltip( self.cbPreserveXattr, [ "Uses 'rsync -X'. From 'man rsync':", 'This option causes rsync to update the destination extended ' 'attributes to be the same as the source ones.', '', 'For systems that support extended-attribute namespaces, a ' 'copy being done by a super-user copies all namespaces ' 'except system.*. A normal user only copies the user.* ' 'namespace. To be able to backup and restore non-user ' 'namespaces as a normal user, see the --fake-super option.', '', 'Note that this option does not copy rsyncs special xattr ' 'values (e.g. those used by --fake-super) unless you repeat ' 'the option (e.g. -XX). This "copy all xattrs" mode cannot be ' 'used with --fake-super.' ] ) tab_layout.addWidget(self.cbPreserveXattr) self.cbCopyUnsafeLinks = QCheckBox( _('Copy unsafe links (works only with absolute links)'), self) qttools.set_wrapped_tooltip( self.cbCopyUnsafeLinks, [ "Uses 'rsync --copy-unsafe-links'. From 'man rsync':", 'This tells rsync to copy the referent of symbolic links that ' 'point outside the copied tree. Absolute symlinks are also ' 'treated like ordinary files, and so are any symlinks in the ' 'source path itself when --relative is used. This option has ' 'no additional effect if --copy-links was also specified.' ] ) tab_layout.addWidget(self.cbCopyUnsafeLinks) self.cbCopyLinks = QCheckBox( _('Copy links (dereference symbolic links)'), self) qttools.set_wrapped_tooltip( self.cbCopyLinks, [ "Uses 'rsync --copy-links'. From 'man rsync':", 'When symlinks are encountered, the item that they point to ' '(the referent) is copied, rather than the symlink. In older ' 'versions of rsync, this option also had the side-effect of ' 'telling the receiving side to follow symlinks, such as ' 'symlinks to directories. In a modern rsync such as this one,' ' you will need to specify --keep-dirlinks (-K) to get this ' 'extra behavior. The only exception is when sending files to ' 'an rsync that is too old to understand -K -- in that case, ' 'the -L option will still have the side-effect of -K on that ' 'older receiving rsync.' ] ) tab_layout.addWidget(self.cbCopyLinks) # one file system option self.cbOneFileSystem = QCheckBox( _('Restrict to one file system'), self) qttools.set_wrapped_tooltip( self.cbOneFileSystem, [ "Uses 'rsync --one-file-system'. From 'man rsync':", 'This tells rsync to avoid crossing a filesystem boundary ' 'when recursing. This does not limit the user\'s ability ' 'to specify items to copy from multiple filesystems, just ' 'rsync\'s recursion through the hierarchy of each directory ' 'that the user specified, and also the analogous recursion ' 'on the receiving side during deletion. Also keep in mind ' 'that rsync treats a "bind" mount to the same device as ' 'being on the same filesystem.' ] ) tab_layout.addWidget(self.cbOneFileSystem) # additional rsync options tooltip = _('Options must be quoted e.g. {example}.').format( example='--exclude-from="/path/to/my exclude file"') self.txtRsyncOptions = QLineEdit(self) self.txtRsyncOptions.editingFinished.connect( self._slot_rsync_options_editing_finished) self.txtRsyncOptions.setToolTip(tooltip) self.cbRsyncOptions = StateBindCheckBox( _('Paste additional options to rsync'), self, self.txtRsyncOptions) self.cbRsyncOptions.setToolTip(tooltip) # ssh prefix tooltip = [ _('Prefix to run before every command on remote host.'), _("Variables need to be escaped with \\$FOO. This doesn't touch " 'rsync. So to add a prefix for rsync use "{example_value}" with ' '{rsync_options_value}.').format( example_value=self.cbRsyncOptions.text(), rsync_options_value \ ='--rsync-path="FOO=bar:\\$FOO /usr/bin/rsync"'), '', '{default}: {def_value}'.format( default=_('default'), def_value=self.config.DEFAULT_SSH_PREFIX) ] self.txtSshPrefix = QLineEdit(self) qttools.set_wrapped_tooltip(self.txtSshPrefix, tooltip) self.cbSshPrefix = StateBindCheckBox( _('Add prefix to SSH commands'), self, self.txtSshPrefix) qttools.set_wrapped_tooltip(self.cbSshPrefix, tooltip) sub_grid = QGridLayout() sub_grid.addWidget(self.cbRsyncOptions, 0, 0) sub_grid.addWidget(self.txtRsyncOptions, 0, 1) sub_grid.addWidget(self.cbSshPrefix, 1, 0) sub_grid.addWidget(self.txtSshPrefix, 1, 1) tab_layout.addLayout(sub_grid) self.cbSshCheckPing = QCheckBox(_('Check if remote host is online')) qttools.set_wrapped_tooltip( self.cbSshCheckPing, _('Warning: If disabled and the remote host is not available, ' 'this could lead to some weird errors.') ) self.cbSshCheckCommands = QCheckBox( _('Check if remote host supports all necessary commands.')) qttools.set_wrapped_tooltip( self.cbSshCheckCommands, _('Warning: If disabled and the remote host does not support all ' 'necessary commands, this could lead to some weird errors.') ) tab_layout.addWidget(self.cbSshCheckPing) tab_layout.addWidget(self.cbSshCheckCommands) # tab_layout.addStretch() @property def config(self) -> config.Config: return self._parent_dialog.config def _default_string(self, value: bool) -> str: return ' ' + _('(default: {})').format( _('enabled') if value else _('disabled')) def load_values(self): self.cbNiceOnCron.setChecked(self.config.niceOnCron()) self.cbIoniceOnCron.setChecked(self.config.ioniceOnCron()) self.cbIoniceOnUser.setChecked(self.config.ioniceOnUser()) self.cbNiceOnRemote.setChecked(self.config.niceOnRemote()) self.cbIoniceOnRemote.setChecked(self.config.ioniceOnRemote()) self.cbNocacheOnLocal.setChecked( self.config.nocacheOnLocal() and self.cbNocacheOnLocal.isEnabled()) self.cbNocacheOnRemote.setChecked(self.config.nocacheOnRemote()) self.cbRedirectStdoutInCron.setChecked( self.config.redirectStdoutInCron()) self.cbRedirectStderrInCron.setChecked( self.config.redirectStderrInCron()) self.cbBwlimit.setChecked(self.config.bwlimitEnabled()) self.spbBwlimit.setValue(self.config.bwlimit()) self.cbPreserveAcl.setChecked(self.config.preserveAcl()) self.cbPreserveXattr.setChecked(self.config.preserveXattr()) self.cbCopyUnsafeLinks.setChecked(self.config.copyUnsafeLinks()) self.cbCopyLinks.setChecked(self.config.copyLinks()) self.cbOneFileSystem.setChecked(self.config.oneFileSystem()) self.cbRsyncOptions.setChecked(self.config.rsyncOptionsEnabled()) self.txtRsyncOptions.setText(self.config.rsyncOptions()) self.cbSshPrefix.setChecked(self.config.sshPrefixEnabled()) self.txtSshPrefix.setText(self.config.sshPrefix()) self.cbSshCheckPing.setChecked(self.config.sshCheckPingHost()) self.cbSshCheckCommands.setChecked(self.config.sshCheckCommands()) def store_values(self): self.config.setNiceOnCron(self.cbNiceOnCron.isChecked()) self.config.setIoniceOnCron(self.cbIoniceOnCron.isChecked()) self.config.setIoniceOnUser(self.cbIoniceOnUser.isChecked()) self.config.setNiceOnRemote(self.cbNiceOnRemote.isChecked()) self.config.setIoniceOnRemote(self.cbIoniceOnRemote.isChecked()) self.config.setNocacheOnLocal(self.cbNocacheOnLocal.isChecked()) self.config.setNocacheOnRemote(self.cbNocacheOnRemote.isChecked()) self.config.setRedirectStdoutInCron( self.cbRedirectStdoutInCron.isChecked()) self.config.setRedirectStderrInCron( self.cbRedirectStderrInCron.isChecked()) self.config.setBwlimit(self.cbBwlimit.isChecked(), self.spbBwlimit.value()) self.config.setPreserveAcl(self.cbPreserveAcl.isChecked()) self.config.setPreserveXattr(self.cbPreserveXattr.isChecked()) self.config.setCopyUnsafeLinks(self.cbCopyUnsafeLinks.isChecked()) self.config.setCopyLinks(self.cbCopyLinks.isChecked()) self.config.setOneFileSystem(self.cbOneFileSystem.isChecked()) self.config.setRsyncOptions(self.cbRsyncOptions.isChecked(), self.txtRsyncOptions.text()) self.config.setSshPrefix(self.cbSshPrefix.isChecked(), self.txtSshPrefix.text()) self.config.setSshCheckPingHost(self.cbSshCheckPing.isChecked()) self.config.setSshCheckCommands(self.cbSshCheckCommands.isChecked()) def update_items_state(self, enabled: bool): self.cbNiceOnRemote.setEnabled(enabled) self.cbIoniceOnRemote.setEnabled(enabled) self.cbNocacheOnRemote.setEnabled(enabled) self.cbSshPrefix.setVisible(enabled) self.txtSshPrefix.setVisible(enabled) self.cbSshCheckPing.setVisible(enabled) self.cbSshCheckCommands.setVisible(enabled) def _slot_rsync_options_editing_finished(self): """When editing the rsync options is finished warn and remove --old-args option if present. """ txt = self.txtRsyncOptions.text() if '--old-args' in txt: # No translation for this message because it is a rare case. messagebox.warning( text='Found rsync flag "--old-args". That flag will be removed' ' from the options because it conflicts with the flag "-s" ' '(also known as "--secluded-args" or "--protected-args") which' ' is used by Back In Time to force the "new form of argument ' 'protection" in rsync.', widget_to_center_on=self ) # Don't leave two-blank spaces between other arguments txt = txt.replace('--old-args ', '') txt = txt.replace(' --old-args', '') txt = txt.replace('--old-args', '') self.txtRsyncOptions.setText(txt) backintime-1.5.4/qt/manageprofiles/tab_general.py000066400000000000000000000654031477034762000221060ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os from pathlib import Path from typing import Any from PyQt6.QtCore import Qt from PyQt6.QtGui import QCursor, QFont from PyQt6.QtWidgets import (QCheckBox, QDialog, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QLineEdit, QMessageBox, QStyle, QToolButton, QToolTip, QVBoxLayout, QWidget) import config import tools import qttools import messagebox import sshtools import logger import encfsmsgbox import mount from statedata import StateData from exceptions import MountException, NoPubKeyLogin, KnownHost from manageprofiles import combobox from manageprofiles import schedulewidget from manageprofiles.sshproxywidget import SshProxyWidget from bitbase import URL_ENCRYPT_TRANSITION, ENCFS_MSG_STAGE class GeneralTab(QDialog): """Create the 'Generals' tab.""" def __init__(self, parent): super().__init__(parent=parent) self._parent_dialog = parent tab_layout = QVBoxLayout(self) # Snapshot mode self.mode = None vlayout = QVBoxLayout() tab_layout.addLayout(vlayout) self._combo_modes = self._snapshot_mode_combobox() hlayout = QHBoxLayout() hlayout.addWidget(QLabel(_('Mode:'), self)) hlayout.addWidget(self._combo_modes, 1) vlayout.addLayout(hlayout) # EncFS deprecation (#1734, #1735) self._lbl_encfs_warning = self._create_label_encfs_deprecation() tab_layout.addWidget(self._lbl_encfs_warning) tab_layout.addWidget(qttools.HLineWidget()) # Where to save snapshots groupBox = QGroupBox(self) self.modeLocal = groupBox groupBox.setTitle(_('Where to save snapshots')) tab_layout.addWidget(groupBox) vlayout = QVBoxLayout(groupBox) hlayout = QHBoxLayout() vlayout.addLayout(hlayout) self.editSnapshotsPath = QLineEdit(self) self.editSnapshotsPath.setReadOnly(True) self.editSnapshotsPath.textChanged.connect( self._slot_full_path_changed) hlayout.addWidget(self.editSnapshotsPath) self.btnSnapshotsPath = QToolButton(self) self.btnSnapshotsPath.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonIconOnly) self.btnSnapshotsPath.setIcon(self.icon.FOLDER) self.btnSnapshotsPath.setMinimumSize(32, 28) hlayout.addWidget(self.btnSnapshotsPath) self.btnSnapshotsPath.clicked.connect( self._slot_snapshots_path_clicked) # --- SSH --- groupBox = QGroupBox(self) self.modeSsh = groupBox groupBox.setTitle(_('SSH Settings')) tab_layout.addWidget(groupBox) vlayout = QVBoxLayout(groupBox) hlayout1 = QHBoxLayout() vlayout.addLayout(hlayout1) hlayout2 = QHBoxLayout() vlayout.addLayout(hlayout2) hlayout3 = QHBoxLayout() vlayout.addLayout(hlayout3) self.lblSshHost = QLabel(_('Host:'), self) hlayout1.addWidget(self.lblSshHost) self.txtSshHost = QLineEdit(self) hlayout1.addWidget(self.txtSshHost) self.lblSshPort = QLabel(_('Port:'), self) hlayout1.addWidget(self.lblSshPort) self.txtSshPort = QLineEdit(self) hlayout1.addWidget(self.txtSshPort) self.lblSshUser = QLabel(_('User:'), self) hlayout1.addWidget(self.lblSshUser) self.txtSshUser = QLineEdit(self) hlayout1.addWidget(self.txtSshUser) self.lblSshPath = QLabel(_('Path:'), self) hlayout2.addWidget(self.lblSshPath) self.txtSshPath = QLineEdit(self) self.txtSshPath.textChanged.connect(self._slot_full_path_changed) hlayout2.addWidget(self.txtSshPath) self.lblSshCipher = QLabel(_('Cipher:'), self) hlayout3.addWidget(self.lblSshCipher) self.comboSshCipher = self._cipher_combobox() hlayout3.addWidget(self.comboSshCipher) self.lblSshPrivateKeyFile = QLabel(_('Private Key:'), self) hlayout3.addWidget(self.lblSshPrivateKeyFile) self.txtSshPrivateKeyFile = QLineEdit(self) self.txtSshPrivateKeyFile.setReadOnly(True) hlayout3.addWidget(self.txtSshPrivateKeyFile) self.btnSshPrivateKeyFile = QToolButton(self) self.btnSshPrivateKeyFile.setToolButtonStyle( Qt.ToolButtonStyle.ToolButtonIconOnly) self.btnSshPrivateKeyFile.setIcon(self.icon.FOLDER) self.btnSshPrivateKeyFile.setToolTip( _('Choose an existing private key file (normally named ' '"id_ed25519" and in older setups "id_rsa").')) self.btnSshPrivateKeyFile.setMinimumSize(32, 28) hlayout3.addWidget(self.btnSshPrivateKeyFile) self.btnSshPrivateKeyFile.clicked \ .connect(self._slot_ssh_private_key_file_clicked) self.btnSshKeyGen = QToolButton(self) self.btnSshKeyGen.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly) self.btnSshKeyGen.setIcon(self.icon.ADD) qttools.set_wrapped_tooltip( self.btnSshKeyGen, _('Create a new SSH key without password (not allowed if a ' 'private key file is already selected).') ) self.btnSshKeyGen.setMinimumSize(32, 28) hlayout3.addWidget(self.btnSshKeyGen) self.btnSshKeyGen.clicked.connect(self._slot_ssh_key_gen_clicked) # Disable SSH key generation button if a key file is already set self.txtSshPrivateKeyFile.textChanged \ .connect(lambda x: self.btnSshKeyGen.setEnabled(not x)) # Align the width of that three labels width = max( self.lblSshHost.sizeHint().width(), self.lblSshPath.sizeHint().width(), self.lblSshCipher.sizeHint().width() ) self.lblSshHost.setMinimumWidth(width) self.lblSshPath.setMinimumWidth(width) self.lblSshCipher.setMinimumWidth(width) self.wdgSshProxy = SshProxyWidget( self, self.config.sshProxyHost(), self.config.sshProxyPort(), self.config.sshProxyUser() ) vlayout.addWidget(self.wdgSshProxy) # encfs self.modeLocalEncfs = self.modeLocal self.modeSshEncfs = self.modeSsh # password groupBox = QGroupBox(self) self.groupPassword1 = groupBox groupBox.setTitle(_('Password')) tab_layout.addWidget(groupBox) vlayout = QVBoxLayout(groupBox) grid = QGridLayout() self.lblPassword1 = QLabel(_('Password'), self) self.txtPassword1 = QLineEdit(self) self.txtPassword1.setEchoMode(QLineEdit.EchoMode.Password) self.lblPassword2 = QLabel(_('Password'), self) self.txtPassword2 = QLineEdit(self) self.txtPassword2.setEchoMode(QLineEdit.EchoMode.Password) grid.addWidget(self.lblPassword1, 0, 0) grid.addWidget(self.txtPassword1, 0, 1) grid.addWidget(self.lblPassword2, 1, 0) grid.addWidget(self.txtPassword2, 1, 1) vlayout.addLayout(grid) self.cbPasswordSave = QCheckBox(_('Save Password to Keyring'), self) vlayout.addWidget(self.cbPasswordSave) self.cbPasswordUseCache = QCheckBox( _('Cache Password for Cron (Security ' 'issue: root can read password)'), self ) vlayout.addWidget(self.cbPasswordUseCache) self.keyringSupported = tools.keyringSupported() self.cbPasswordSave.setEnabled(self.keyringSupported) # mode change self._combo_modes.currentIndexChanged.connect( self._parent_dialog.slot_combo_modes_changed) # host, user, profile id groupBox = QGroupBox(self) self.frameAdvanced = groupBox groupBox.setTitle(_('Advanced')) tab_layout.addWidget(groupBox) hlayout = QHBoxLayout(groupBox) hlayout.addSpacing(12) vlayout2 = QVBoxLayout() hlayout.addLayout(vlayout2) hlayout2 = QHBoxLayout() vlayout2.addLayout(hlayout2) self.lblHost = QLabel(_('Host:'), self) hlayout2.addWidget(self.lblHost) self.txtHost = QLineEdit(self) self.txtHost.textChanged.connect(self._slot_full_path_changed) hlayout2.addWidget(self.txtHost) self.lblUser = QLabel(_('User:'), self) hlayout2.addWidget(self.lblUser) self.txtUser = QLineEdit(self) self.txtUser.textChanged.connect(self._slot_full_path_changed) hlayout2.addWidget(self.txtUser) self.lblProfile = QLabel(_('Profile:'), self) hlayout2.addWidget(self.lblProfile) self.txt_profile = QLineEdit(self) self.txt_profile.textChanged.connect(self._slot_full_path_changed) hlayout2.addWidget(self.txt_profile) self.lblFullPath = QLabel(_('Full snapshot path:'), self) self.lblFullPath.setWordWrap(True) vlayout2.addWidget(self.lblFullPath) self._wdg_schedule = schedulewidget.ScheduleWidget(self) tab_layout.addWidget(self._wdg_schedule) # tab_layout.addStretch() @property def mode(self) -> str: return self._parent_dialog.mode @mode.setter def mode(self, value: str) -> None: self._parent_dialog.mode = value @property def config(self) -> config.Config: return self._parent_dialog.config @property def icon(self): """Workaround. Remove until import of icon module is solved.""" return self._parent_dialog.icon def load_values(self) -> Any: """Set the values of the widgets regarding the current config.""" self._combo_modes.select_by_data(self.config.snapshotsMode()) # local self.editSnapshotsPath.setText( self.config.snapshotsPath(mode='local')) # SSH self.txtSshHost.setText(self.config.sshHost()) self.txtSshPort.setText(str(self.config.sshPort())) self.txtSshUser.setText(self.config.sshUser()) self.txtSshPath.setText(self.config.sshSnapshotsPath()) self.comboSshCipher.select_by_data(self.config.sshCipher()) self.txtSshPrivateKeyFile.setText(self.config.sshPrivateKeyFile()) # local_encfs if self.mode == 'local_encfs': self.editSnapshotsPath.setText(self.config.localEncfsPath()) # password password_1 = self.config.password( mode=self.mode, pw_id=1, only_from_keyring=True) password_2 = self.config.password( mode=self.mode, pw_id=2, only_from_keyring=True) if password_1 is None: password_1 = '' if password_2 is None: password_2 = '' self.txtPassword1.setText(password_1) self.txtPassword2.setText(password_2) self.cbPasswordSave.setChecked( self.keyringSupported and self.config.passwordSave(mode=self.mode)) self.cbPasswordUseCache.setChecked( self.config.passwordUseCache(mode=self.mode)) host, user, profile = self.config.hostUserProfile() self.txtHost.setText(host) self.txtUser.setText(user) self.txt_profile.setText(profile) # Schedule self._wdg_schedule.load_values(self.config) def store_values(self) -> bool: """Store the tab's values into the config instance. Returns: bool: Success or not. """ mode = self.get_active_snapshots_mode() self.config.setSnapshotsMode(mode) mount_kwargs = {} # password password_1 = self.txtPassword1.text() password_2 = self.txtPassword2.text() if mode in ('ssh', 'local_encfs'): mount_kwargs = {'password': password_1} if mode == 'ssh_encfs': mount_kwargs = {'ssh_password': password_1, 'encfs_password': password_2} # snapshots path self.config.setHostUserProfile( self.txtHost.text(), self.txtUser.text(), self.txt_profile.text() ) # SSH self.config.setSshHost(self.txtSshHost.text()) self.config.setSshPort(self.txtSshPort.text()) self.config.setSshUser(self.txtSshUser.text()) sshproxy_vals = self.wdgSshProxy.values() self.config.setSshProxyHost(sshproxy_vals['host']) self.config.setSshProxyPort(sshproxy_vals['port']) self.config.setSshProxyUser(sshproxy_vals['user']) self.config.setSshSnapshotsPath(self.txtSshPath.text()) self.config.setSshCipher(self.comboSshCipher.current_data) # SSH key file if mode in ('ssh', 'ssh_encfs'): if not self.txtSshPrivateKeyFile.text(): question = '{}\n{}'.format( _('You did not choose a private key file for SSH.'), _('Would you like to generate a new password-less ' 'public/private key pair?')) answer = messagebox.warningYesNo(self, question) answer = answer == QMessageBox.StandardButton.Yes if answer: self.btnSshKeyGenClicked() if not self.txtSshPrivateKeyFile.text(): return False if not os.path.isfile(self.txtSshPrivateKeyFile.text()): msg = _('Private key file "{file}" does not exist.') \ .format(file=self.txtSshPrivateKeyFile.text()) messagebox.critical(self, msg) self.txtSshPrivateKeyFile.setText('') return False self.config.setSshPrivateKeyFile(self.txtSshPrivateKeyFile.text()) # save local_encfs self.config.setLocalEncfsPath(self.editSnapshotsPath.text()) # schedule success = self._wdg_schedule.store_values(self.config) if success is False: return False if mode != 'local': mnt = mount.Mount(cfg=self.config, tmp_mount=True, parent=self) hash_id = self._do_alot_pre_mount_checking(mnt, mount_kwargs) if hash_id is False: return False # save password self.config.setPasswordSave(self.cbPasswordSave.isChecked(), mode=mode) self.config.setPasswordUseCache(self.cbPasswordUseCache.isChecked(), mode=mode) self.config.setPassword(password_1, mode=mode) self.config.setPassword(password_2, mode=mode, pw_id=2) # snaphots_path if mode == 'local': self.config.set_snapshots_path(self.editSnapshotsPath.text()) snapshots_mountpoint = self.config.get_snapshots_mountpoint( tmp_mount=True) success = tools.validate_and_prepare_snapshots_path( path=snapshots_mountpoint, host_user_profile=self.config.hostUserProfile(), mode=mode, copy_links=self.config.copyLinks(), error_handler=self.config.notifyError) if success is False: return False # umount if mode != 'local': try: mnt.umount(hash_id=hash_id) except MountException as ex: messagebox.critical(self, str(ex)) return False return True def _do_alot_pre_mount_checking(self, mnt, mount_kwargs): """Initiate several checks related to mounting and similar tasks. Depending on the snapshots mode used different checks are initiated. Dev note (buhtz, 2024-09): The code is parked and ready to refactoring. Returns: bool: ``True`` if successful otherwise ``False``. """ # preMountCheck try: # This will run several checks depending on the snapshots mode # used. Exceptions are raised if something goes wrong. On mode # "local" nothing is checked. mnt.preMountCheck( mode=self.config.snapshotsMode(), first_run=True, **mount_kwargs) except NoPubKeyLogin as ex: logger.error(str(ex), self) question = _('Would you like to copy your public SSH key to ' 'the remote host to enable password-less login?') rc_copy_id = sshtools.sshCopyId( self.config.sshPrivateKeyFile() + '.pub', self.config.sshUser(), self.config.sshHost(), port=str(self.config.sshPort()), proxy_user=self.config.sshProxyUser(), proxy_host=self.config.sshProxyHost(), proxy_port=self.config.sshProxyPort(), askPass=tools.which('backintime-askpass'), cipher=self.config.sshCipher() ) answer = messagebox.warningYesNo(self, question) answer = answer == QMessageBox.StandardButton.Yes if answer and rc_copy_id: # --- DEV NOTE TODO --- # Why this recursive call? return self._parent_dialog.saveProfile() else: return False except KnownHost as ex: logger.error(str(ex), self) fingerprint, hashedKey, keyType = sshtools.sshHostKey( self.config.sshHost(), str(self.config.sshPort()) ) if not fingerprint: messagebox.critical(self, str(ex)) return False msg = '{}\n\n{}'.format( _("The authenticity of host {host} can't be " "established.").format( host=self.config.sshHost()), _('{keytype} key fingerprint is:').format( keytype=keyType)) options = [] lblFingerprint = QLabel(fingerprint + '\n') lblFingerprint.setWordWrap(False) lblFingerprint.setFont(QFont('Monospace')) options.append({'widget': lblFingerprint, 'retFunc': None}) lblQuestion = QLabel( _("Please verify this fingerprint. Would you like to " "add it to your 'known_hosts' file?") ) options.append({'widget': lblQuestion, 'retFunc': None}) if messagebox.warningYesNoOptions(self, msg, options)[0]: sshtools.writeKnownHostsFile(hashedKey) # --- DEV NOTE TODO --- # AGAIN: Why this recursive call? return self.saveProfile() else: return False except MountException as ex: messagebox.critical(self, str(ex)) return False # okay, let's try to mount try: hash_id = mnt.mount( mode=self.config.snapshotsMode(), check=False, **mount_kwargs) except MountException as ex: messagebox.critical(self, str(ex)) return False return hash_id def _snapshot_mode_combobox(self) -> combobox.BitComboBox: snapshot_modes = {} for key in self.config.SNAPSHOT_MODES: snapshot_modes[key] = self.config.SNAPSHOT_MODES[key][1] logger.debug(f'{snapshot_modes=}') return combobox.BitComboBox(self, snapshot_modes) def _cipher_combobox(self) -> combobox.BitComboBox: return combobox.BitComboBox(self, self.config.SSH_CIPHERS) def _create_label_encfs_deprecation(self): # Icon icon = self.style().standardIcon( QStyle.StandardPixmap.SP_MessageBoxWarning) size = self.style().pixelMetric( QStyle.PixelMetric.PM_LargeIconSize) icon_label = QLabel(self) pixmap = icon.pixmap(size*2) icon_label.setPixmap(pixmap) # encfs deprecation warning (see #1734, #1735) txt = _('EncFS profile creation will be removed in the next minor ' 'release (1.7), scheduled for 2026.') txt = txt + ' ' + _('Support for EncFS is being discontinued due ' 'to security vulnerabilities.') txt = txt + ' ' + _('For more details, including potential ' 'alternatives, please refer to this ' '{whitepaper}.') \ .format(whitepaper='{}'.format( URL_ENCRYPT_TRANSITION, _('whitepaper'))) txt_label = QLabel(txt) txt_label.setWordWrap(True) txt_label.setOpenExternalLinks(True) # Show URL in tooltip without anoing http-protocol prefix. txt_label.linkHovered.connect( lambda url: QToolTip.showText( QCursor.pos(), url.replace('https://', '')) ) wdg = QWidget() layout = QHBoxLayout(wdg) layout.addWidget(icon_label, stretch=0) layout.addWidget(txt_label, stretch=1) return wdg def _slot_snapshots_path_clicked(self): old_path = self.editSnapshotsPath.text() path = str(qttools.getExistingDirectory( self, _('Where to save snapshots'), self.editSnapshotsPath.text() )) if path: if old_path and old_path != path: question = _('Are you sure you want to change ' 'snapshots directory?') answer = messagebox.warningYesNo(self, question) answer = answer == QMessageBox.StandardButton.Yes if not answer: return # Why? self.config.removeProfileKey('snapshots.path.uuid') self.editSnapshotsPath.setText(self.config.preparePath(path)) def _slot_ssh_private_key_file_clicked(self): old_file = self.txtSshPrivateKeyFile.text() if old_file: start_dir = self.txtSshPrivateKeyFile.text() else: start_dir = self.config.sshPrivateKeyFolder() f = qttools.getOpenFileName(self, _('SSH private key'), start_dir) if f: self.txtSshPrivateKeyFile.setText(f) def _slot_ssh_key_gen_clicked(self): priv_key_folder = self.config.sshPrivateKeyFolder() # Workaround if isinstance(priv_key_folder, str): priv_key_folder = Path(priv_key_folder) key_file_path = priv_key_folder / 'id_rsa' if sshtools.sshKeyGen(str(key_file_path)): self.txtSshPrivateKeyFile.setText(key_file_path) else: msg = _('Failed to create new SSH key in {path}.') \ .format(path=key_file_path) messagebox.critical(self, msg) def _slot_full_path_changed(self, _text: Any): if self.mode in ('ssh', 'ssh_encfs'): path = self.txtSshPath.text() else: path = self.editSnapshotsPath.text() self.lblFullPath.setText( _('Full snapshot path:') + ' ' + os.path.join( path, 'backintime', self.txtHost.text(), self.txtUser.text(), self.txt_profile.text() )) def get_active_snapshots_mode(self) -> str: return self._combo_modes.current_data def handle_combo_modes_changed(self): """Hide/show widget elements related to one of the four snapshot modes. This is not a slot connected to a signal. But it is called by the parent dialog. """ active_mode = self.get_active_snapshots_mode() state_data = StateData() profile_state = state_data.profile(self.config.currentProfile()) # hide/show group boxes related to current mode # note: self.modeLocalEncfs = self.modeLocal # note: self.modeSshEncfs = self.modeSsh if active_mode != self.mode: # logger.debug(f'{active_mode=} {self.mode=}') # # DevNote (buhtz): Widgets of the GUI related to the four # # snapshot modes are acccesed via "getattr(self, ...)". # # These are 'Local', 'Ssh', 'LocalEncfs', 'SshEncfs' # for mode in list(self.config.SNAPSHOT_MODES.keys()): # logger.debug(f'HIDE() :: mode%s' % tools.camelCase(mode)) # # Hide all widgets # getattr(self, 'mode%s' % tools.camelCase(mode)).hide() # for mode in list(self.config.SNAPSHOT_MODES.keys()): # # Show up the widget related to the selected mode. # if active_mode == mode: # logger.debug(f'SHOW() :: mode%s' % tools.camelCase(mode)) # getattr(self, 'mode%s' % tools.camelCase(mode)).show() self.mode = active_mode self.modeLocal.setVisible(active_mode in ('local', 'local_encfs')) self.modeSsh.setVisible(active_mode in ('ssh', 'ssh_encfs')) # self.modeLocalEncfs = self.modeLocal # self.modeSshEncfs = self.modeSsh if self.config.modeNeedPassword(active_mode): self.lblPassword1.setText( self.config.SNAPSHOT_MODES[active_mode][2] + ':') self.groupPassword1.show() if self.config.modeNeedPassword(active_mode, 2): self.lblPassword2.setText( self.config.SNAPSHOT_MODES[active_mode][3] + ':') self.lblPassword2.show() self.txtPassword2.show() else: self.lblPassword2.hide() self.txtPassword2.hide() else: self.groupPassword1.hide() # EncFS deprecation warnings (see #1734) if active_mode in ('local_encfs', 'ssh_encfs'): self._lbl_encfs_warning.show() # Workaround to avoid showing the warning messagebox just when # opening the manage profiles dialog. if self._parent_dialog.isVisible(): # Show the profile specific warning dialog only once per # profile. if profile_state.msg_encfs < ENCFS_MSG_STAGE: profile_state.msg_encfs = ENCFS_MSG_STAGE dlg = encfsmsgbox.EncfsCreateWarning(self) dlg.exec() else: self._lbl_encfs_warning.hide() backintime-1.5.4/qt/manageprofiles/tab_options.py000066400000000000000000000123321477034762000221550ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QCheckBox) import config import tools import qttools from manageprofiles import combobox class OptionsTab(QDialog): """The 'Options' tab in the Manage Profiles dialog.""" def __init__(self, parent): super().__init__(parent=parent) self._parent_dialog = parent tab_layout = QVBoxLayout(self) # layoutWidget = QWidget(self) # layout = QVBoxLayout(layoutWidget) self.cbNotify = QCheckBox(_('Enable notifications'), self) tab_layout.addWidget(self.cbNotify) self.cbNoSnapshotOnBattery \ = QCheckBox(_('Disable snapshots when on battery'), self) tab_layout.addWidget(self.cbNoSnapshotOnBattery) if not tools.powerStatusAvailable(): self.cbNoSnapshotOnBattery.setEnabled(False) self.cbNoSnapshotOnBattery.setToolTip( _('Power status not available from system')) self.cbGlobalFlock = QCheckBox(_('Run only one snapshot at a time')) tab_layout.addWidget(self.cbGlobalFlock) qttools.set_wrapped_tooltip( self.cbGlobalFlock, _('Other snapshots will be blocked until the current snapshot ' 'is done. This is a global option. So it will affect all ' 'profiles for this user. But you need to activate this for all ' 'other users, too.') ) self.cbBackupOnRestore = QCheckBox( _('Backup replaced files on restore'), self) tab_layout.addWidget(self.cbBackupOnRestore) qttools.set_wrapped_tooltip( self.cbBackupOnRestore, _("Newer versions of files will be renamed with trailing {suffix} " "before restoring. If you don't need them anymore you can " "remove them with {cmd}").format( suffix=self._parent_dialog.snapshots.backupSuffix(), cmd='find ./ -name "*{suffix}" -delete'.format( suffix=self._parent_dialog.snapshots.backupSuffix() ) ) ) self.cbContinueOnErrors = QCheckBox( _('Continue on errors (keep incomplete snapshots)'), self) tab_layout.addWidget(self.cbContinueOnErrors) self.cbUseChecksum = QCheckBox( _('Use checksum to detect changes'), self) tab_layout.addWidget(self.cbUseChecksum) self.cbTakeSnapshotRegardlessOfChanges = QCheckBox( _('Take a new snapshot whether there were changes or not.')) tab_layout.addWidget(self.cbTakeSnapshotRegardlessOfChanges) # log level hlayout = QHBoxLayout() tab_layout.addLayout(hlayout) hlayout.addWidget(QLabel(_('Log Level:'), self)) self.comboLogLevel = self._combo_log_level() hlayout.addWidget(self.comboLogLevel) hlayout.addStretch() # tab_layout.addStretch() @property def config(self) -> config.Config: return self._parent_dialog.config def load_values(self): self.cbNotify.setChecked(self.config.notify()) self.cbNoSnapshotOnBattery.setChecked( self.config.noSnapshotOnBattery()) self.cbGlobalFlock.setChecked(self.config.globalFlock()) self.cbBackupOnRestore.setChecked(self.config.backupOnRestore()) self.cbContinueOnErrors.setChecked(self.config.continueOnErrors()) self.cbUseChecksum.setChecked(self.config.useChecksum()) self.cbTakeSnapshotRegardlessOfChanges.setChecked( self.config.takeSnapshotRegardlessOfChanges()) self.comboLogLevel.select_by_data(self.config.logLevel()) def store_values(self): self.config.setNotify(self.cbNotify.isChecked()) self.config.setNoSnapshotOnBattery( self.cbNoSnapshotOnBattery.isChecked()) self.config.setGlobalFlock(self.cbGlobalFlock.isChecked()) self.config.setBackupOnRestore(self.cbBackupOnRestore.isChecked()) self.config.setContinueOnErrors(self.cbContinueOnErrors.isChecked()) self.config.setUseChecksum(self.cbUseChecksum.isChecked()) self.config.setTakeSnapshotRegardlessOfChanges( self.cbTakeSnapshotRegardlessOfChanges.isChecked()) self.config.setLogLevel( self.comboLogLevel.itemData(self.comboLogLevel.currentIndex())) def _combo_log_level(self): fill = { 0: _('None'), 1: _('Errors'), 2: _('Changes') + ' & ' + _('Errors'), 3: _('All'), } return combobox.BitComboBox(self, fill) backintime-1.5.4/qt/manageprofiles/tab_remove_retention.py000066400000000000000000000352561477034762000240600ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtWidgets import (QCheckBox, QDialog, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QSpinBox, QStyle, QToolTip, QWidget) from PyQt6.QtCore import Qt from PyQt6.QtGui import QCursor import config import qttools from manageprofiles.statebindcheckbox import StateBindCheckBox from manageprofiles.spinboxunit import SpinBoxWithUnit class RemoveRetentionTab(QDialog): """The 'Remove & Retention' tab in the Manage Profiles dialog.""" _STRETCH_FX = (1, ) def __init__(self, parent): super().__init__(parent=parent) self._parent_dialog = parent # Vertical main layout # self._tab_layout = QVBoxLayout(self) self._tab_layout = QGridLayout() self.setLayout(self._tab_layout) # Keep most recent self._label_keep_most_recent() # Keep named backups self.cbDontRemoveNamedSnapshots = self._checkbox_keep_named() # --- self._tab_layout.addWidget( qttools.HLineWidget(), # fromRow self._tab_layout.rowCount(), # fromColumn 0, # rowSpan, 1, # columnSpan 3) # Icon & Info label self._label_rule_execute_order() # --- self._tab_layout.addWidget( qttools.HLineWidget(), # fromRow self._tab_layout.rowCount(), # fromColumn 0, # rowSpan, 1, # columnSpan 3) # Remove older than N years/months/days self._checkbox_remove_older, self._spinunit_remove_older \ = self._remove_older_than() row = self._tab_layout.rowCount() self._tab_layout.addWidget(self._checkbox_remove_older, row, 0, 1, 2) self._tab_layout.addWidget(self._spinunit_remove_older, row, 2) # Retention policy self.cbSmartRemove, \ self.cbSmartRemoveRunRemoteInBackground, \ self.spbKeepAll, \ self.spbKeepOnePerDay, \ self.spbKeepOnePerWeek, \ self.spbKeepOnePerMonth \ = self._groupbox_retention_policy() # return spin_unit_space, spin_inodes self._checkbox_space, \ self._spin_unit_space, \ self._checkbox_inodes, \ self._spin_inodes \ = self._remove_free_space_inodes() self._tab_layout.setColumnStretch(0, 2) self._tab_layout.setColumnStretch(1, 1) self._tab_layout.setColumnStretch(2, 0) self._tab_layout.setRowStretch(self._tab_layout.rowCount(), 1) @property def config(self) -> config.Config: return self._parent_dialog.config def load_values(self): # don't remove named snapshots self.cbDontRemoveNamedSnapshots.setChecked( self.config.dontRemoveNamedSnapshots()) # remove old snapshots enabled, value, unit = self.config.removeOldSnapshots() self._checkbox_remove_older.setChecked(enabled) self._spinunit_remove_older.set_value(value) self._spinunit_remove_older.select_unit(unit) # smart remove smart_remove, keep_all, keep_one_per_day, keep_one_per_week, \ keep_one_per_month = self.config.smartRemove() self.cbSmartRemove.setChecked(smart_remove) self.spbKeepAll.setValue(keep_all) self.spbKeepOnePerDay.setValue(keep_one_per_day) self.spbKeepOnePerWeek.setValue(keep_one_per_week) self.spbKeepOnePerMonth.setValue(keep_one_per_month) self.cbSmartRemoveRunRemoteInBackground.setChecked( self.config.smartRemoveRunRemoteInBackground()) # min free space enabled, value, unit = self.config.minFreeSpace() self._checkbox_space.setChecked(enabled) self._spin_unit_space.set_value(value) self._spin_unit_space.select_unit(unit) # min free inodes self._checkbox_inodes.setChecked(self.config.minFreeInodesEnabled()) self._spin_inodes.setValue(self.config.minFreeInodes()) def store_values(self): self.config.setRemoveOldSnapshots( self._checkbox_remove_older.isChecked(), self._spinunit_remove_older.value(), self._spinunit_remove_older.unit() ) self.config.setDontRemoveNamedSnapshots( self.cbDontRemoveNamedSnapshots.isChecked()) self.config.setSmartRemove( self.cbSmartRemove.isChecked(), self.spbKeepAll.value(), self.spbKeepOnePerDay.value(), self.spbKeepOnePerWeek.value(), self.spbKeepOnePerMonth.value()) self.config.setSmartRemoveRunRemoteInBackground( self.cbSmartRemoveRunRemoteInBackground.isChecked()) self.config.setMinFreeSpace( self._spin_unit_space.isEnabled(), self._spin_unit_space.value(), self._spin_unit_space.unit()) self.config.setMinFreeInodes( self._spin_inodes.isEnabled(), self._spin_inodes.value()) def update_items_state(self, enabled): self.cbSmartRemoveRunRemoteInBackground.setVisible(enabled) def _label_rule_execute_order(self) -> QWidget: # Icon icon = self.style().standardPixmap( QStyle.StandardPixmap.SP_MessageBoxInformation) icon = icon.scaled( icon.width()*2, icon.height()*2, Qt.AspectRatioMode.KeepAspectRatio) icon_label = QLabel(self) icon_label.setPixmap(icon) icon_label.setFixedSize(icon.size()) # Info text txt = _( 'The following rules are processed from top to bottom. Later rules ' 'override earlier ones and are not constrained by them. See the ' '{manual} for details and examples.' ).format( manual='{}'.format( _('user manual'))) txt_label = QLabel(txt) txt_label.setWordWrap(True) txt_label.linkActivated.connect(self.handle_link_activated) txt_label.setTextInteractionFlags( Qt.TextInteractionFlag.TextBrowserInteraction) # Show URL in tooltip without anoing http-protocol prefix. txt_label.linkHovered.connect( lambda url: QToolTip.showText( # QCursor.pos(), url.replace('https://', '')) QCursor.pos(), _('Open user manual in browser.')) ) wdg = QWidget() layout = QHBoxLayout(wdg) layout.addWidget(icon_label) layout.addWidget(txt_label) self._tab_layout.addWidget(wdg, self._tab_layout.rowCount(), 0, 1, 3) def handle_link_activated(self, link): qttools.open_user_manual() def _label_keep_most_recent(self) -> None: cb = QCheckBox(_('Keep the most recent snapshot.'), self) qttools.set_wrapped_tooltip( cb, ( _('The last or freshest snapshot is kept under ' 'all circumstances.'), _('That behavior cannot be changed.') ) ) # Always enabled cb.setChecked(True) cb.nextCheckState = lambda: None # fromRow, fromColumn spanning rowSpan rows and columnSpan self._tab_layout.addWidget(cb, self._tab_layout.rowCount(), 0, 1, 2) def _checkbox_keep_named(self) -> QCheckBox: cb = QCheckBox(_('Keep named snapshots.'), self) qttools.set_wrapped_tooltip( cb, _('Snapshots that have been given a name, in addition to the ' 'usual timestamp, will be retained under all circumstances ' 'and will not be removed.') ) # fromRow, fromColumn spanning rowSpan rows and columnSpan self._tab_layout.addWidget(cb, self._tab_layout.rowCount(), 0, 1, 2) return cb def _remove_older_than(self) -> QWidget: # units units = { config.Config.DAY: _('Day(s)'), config.Config.WEEK: _('Week(s)'), config.Config.YEAR: _('Year(s)') } spin_unit = SpinBoxWithUnit(self, (1, 999), units) # checkbox checkbox = StateBindCheckBox(_('Remove snapshots older than'), self) checkbox.bind(spin_unit) # tooltip tip = ( f'{units[config.Config.DAY]}: ' + _('Full days. Current day is ignored.'), f'{units[config.Config.WEEK]}: ' + _('Calendar weeks with Monday as first day. ' 'Current week is ignored.'), f'{units[config.Config.YEAR]}: ' + _('12 months periods. Current month is ignored.') ) qttools.set_wrapped_tooltip(checkbox, tip) qttools.set_wrapped_tooltip(spin_unit, tip) return checkbox, spin_unit def _groupbox_retention_policy(self) -> tuple: layout = QGridLayout() # col, fx layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 0) layout.setColumnStretch(2, 0) checkbox_group = QGroupBox(_('Retention policy'), self) checkbox_group.setCheckable(True) checkbox_group.setLayout(layout) cb_in_background = QCheckBox( _('Run in background on remote host.'), self) qttools.set_wrapped_tooltip( cb_in_background, (_('The smart remove procedure will run directly on the remote ' 'machine, not locally. The commands "bash", "screen", and ' '"flock" must be installed and available on the ' 'remote machine.'), _('If selected, Back In Time will first test the ' 'remote machine.'))) layout.addWidget(cb_in_background, 0, 0, 1, 2) tip = _('The days are counted starting from today.') label = QLabel(_('Keep all snapshots for the last'), self) qttools.set_wrapped_tooltip(label, tip) layout.addWidget(label, 1, 0) all_last_days = QSpinBox(self) all_last_days.setRange(1, 999) all_last_days.setSuffix(' ' + _('day(s).')) qttools.set_wrapped_tooltip(all_last_days, tip) # all_last_days.setAlignment(Qt.AlignmentFlag.AlignRight) layout.addWidget(all_last_days, 1, 1) # tip = same as the previous label label = QLabel( _('Keep the last snapshot for each day for the last'), self) qttools.set_wrapped_tooltip(label, tip) layout.addWidget(label, 2, 0) one_per_day = QSpinBox(self) one_per_day.setRange(1, 999) one_per_day.setSuffix(' ' + _('day(s).')) qttools.set_wrapped_tooltip(one_per_day, tip) # one_per_day.setAlignment(Qt.AlignmentFlag.AlignRight) layout.addWidget(one_per_day, 2, 1) tip = _('The weeks are counted starting from the current running ' 'week. A week starts on Monday.') label = QLabel( _('Keep the last snapshot for each week for the last'), self) qttools.set_wrapped_tooltip(label, tip) layout.addWidget(label, 3, 0) one_per_week = QSpinBox(self) one_per_week.setRange(1, 999) one_per_week.setSuffix(' ' + _('week(s).')) qttools.set_wrapped_tooltip(one_per_week, tip) # one_per_week.setAlignment(Qt.AlignmentFlag.AlignRight) layout.addWidget(one_per_week, 3, 1) tip = _('The months are counted as calendar months starting with ' 'the current month.') label = QLabel( _('Keep the last snapshot for each month for the last'), self) qttools.set_wrapped_tooltip(label, tip) layout.addWidget(label, 4, 0) one_per_month = QSpinBox(self) one_per_month.setRange(1, 999) one_per_month.setSuffix(' ' + _('month(s).')) qttools.set_wrapped_tooltip(one_per_month, tip) # one_per_month.setAlignment(Qt.AlignmentFlag.AlignRight) layout.addWidget(one_per_month, 4, 1) tip = _('The years are counted as calendar years starting with ' 'the current year.') label = QLabel(_('Keep the last snapshot for each year for'), self) layout.addWidget(label, 5, 0) labeltwo = QLabel(_('all years.'), self) layout.addWidget(labeltwo, 5, 1) qttools.set_wrapped_tooltip([label, labeltwo], tip) self._tab_layout.addWidget( checkbox_group, self._tab_layout.rowCount(), 0, 1, 3) return (checkbox_group, cb_in_background, all_last_days, one_per_day, one_per_week, one_per_month) def _remove_free_space_inodes(self) -> tuple: # enabled, value, unit = self.config.minFreeSpace() # free space less than MIN_FREE_SPACE_UNITS = { config.Config.DISK_UNIT_MB: 'MiB', config.Config.DISK_UNIT_GB: 'GiB' } spin_unit_space = SpinBoxWithUnit( self, (1, 99999), MIN_FREE_SPACE_UNITS) checkbox_space = StateBindCheckBox( _('… the free space is less than'), self) checkbox_space.bind(spin_unit_space) # min free inodes checkbox_inodes = StateBindCheckBox( _('… the free inodes are less than'), self) spin_inodes = QSpinBox(self) spin_inodes.setSuffix(' %') spin_inodes.setRange(0, 15) checkbox_inodes.bind(spin_inodes) # layout groupbox = QGroupBox(_('Remove oldest snapshots if …'), self) grid = QGridLayout() groupbox.setLayout(grid) grid.setColumnStretch(0, 1) grid.setColumnStretch(1, 0) grid.setColumnStretch(2, 0) # wdg, row, col grid.addWidget(checkbox_space, 0, 0, 1, 2) grid.addWidget(spin_unit_space, 0, 2) grid.addWidget(checkbox_inodes, 1, 0, 1, 2) grid.addWidget(spin_inodes, 1, 2) self._tab_layout.addWidget( groupbox, self._tab_layout.rowCount(), 0, 1, 3 ) return checkbox_space, spin_unit_space, checkbox_inodes, spin_inodes backintime-1.5.4/qt/messagebox.py000066400000000000000000000105501477034762000167750ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2012-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . from PyQt6.QtCore import QTimer, Qt from PyQt6.QtWidgets import QApplication, QMessageBox, QInputDialog, QLineEdit,\ QDialog, QVBoxLayout, QLabel, QDialogButtonBox, QScrollArea import qttools def askPasswordDialog(parent, title, prompt, language_code, timeout): if parent is None: app = qttools.createQApplication() translator = qttools.initiate_translator(language_code) app.installTranslator(translator) import icon dialog = QInputDialog() timer = QTimer() if not timeout is None: timer.timeout.connect(dialog.reject) timer.setInterval(timeout * 1000) timer.start() dialog.setWindowIcon(icon.BIT_LOGO) dialog.setWindowTitle(title) dialog.setLabelText(prompt) dialog.setTextEchoMode(QLineEdit.EchoMode.Password) QApplication.processEvents() ret = dialog.exec() timer.stop() if ret: password = dialog.textValue() else: password = '' del dialog return password def info(text, title=None, widget_to_center_on=None): """Show a modal information message box. The message box is centered on the primary screen if ``widget_to_center_on`` is not given. Args: text(str): The information text central to the dialog. title(str): Title of the message box dialog. widget_to_center_on(QWidget): Center the message box on that widget. """ QMessageBox.information( widget_to_center_on, title if title else ngettext('Information', 'Information', 1), text) def warning(text, title=None, widget_to_center_on=None): """Show a modal warning message box. The message box is centered on the primary screen if ``widget_to_center_on`` is not given. Args: text(str): The warning message central to the dialog. title(str): Title of the message box dialog. widget_to_center_on(QWidget): Center the message box on that widget. """ QMessageBox.warning( widget_to_center_on, title if title else _('Warning'), text) def critical(parent, msg): return QMessageBox.critical( parent, _('Error'), msg, buttons=QMessageBox.StandardButton.Ok, defaultButton=QMessageBox.StandardButton.Ok) def warningYesNo(parent, msg): return QMessageBox.question( parent, _('Question'), msg, buttons=QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, defaultButton=QMessageBox.StandardButton.No) def warningYesNoOptions(parent, msg, options = ()): # Create a dialog dlg = QDialog(parent) dlg.setWindowTitle(_('Question')) layout = QVBoxLayout() dlg.setLayout(layout) # Initial message label = QLabel(msg) layout.addWidget(label) # Add optional elements for opt in options: layout.addWidget(opt['widget']) # Button box buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Yes | QDialogButtonBox.StandardButton.No) buttonBox.button(QDialogButtonBox.StandardButton.No).setDefault(True) layout.addWidget(buttonBox) buttonBox.accepted.connect(dlg.accept) buttonBox.rejected.connect(dlg.reject) # Show and ask user for the answer ret = dlg.exec() return ( ret, { opt['id']:opt['retFunc']() for opt in options if opt['retFunc'] is not None } ) def showInfo(parent, title, msg): """Show extended information dialog with framed and scrollable text area. Dev info (buhtz, 2024): That function is deprecated. Use `info()` instead. """ dlg = QDialog(parent) dlg.setWindowTitle(title) vlayout = QVBoxLayout(dlg) label = QLabel(msg) label.setTextInteractionFlags( Qt.TextInteractionFlag.LinksAccessibleByMouse) label.setOpenExternalLinks(True) scroll_area = QScrollArea() scroll_area.setWidget(label) buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok) buttonBox.accepted.connect(dlg.accept) vlayout.addWidget(scroll_area) vlayout.addWidget(buttonBox) return dlg.exec() backintime-1.5.4/qt/net.launchpad.backintime.policy000066400000000000000000000042011477034762000223340ustar00rootroot00000000000000 BackInTime https://github.com/bit-team/backintime document-save Authentication is required to run Back In Time as root. Start Back In Time GUI as root. auth_admin auth_admin auth_admin_keep /usr/bin/backintime-qt true Authentication is required to add Udev rules. This will install Udev rules which will start Back In Time if a drive get connected. auth_admin auth_admin_keep auth_admin_keep Authentication is required to delete Udev rules. This will delete Udev rules. auth_admin auth_admin_keep auth_admin_keep backintime-1.5.4/qt/net.launchpad.backintime.serviceHelper.conf000066400000000000000000000023311477034762000245630ustar00rootroot00000000000000 system backintime-1.5.4/qt/net.launchpad.backintime.serviceHelper.service000066400000000000000000000007471477034762000253070ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2016 Germar Reitze # SPDX-FileCopyrightText: © 2017 Matthias Gerstner # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # [D-BUS Service] Name=net.launchpad.backintime.serviceHelper Exec=/usr/bin/python3 -Es /usr/share/backintime/qt/serviceHelper.py User=root backintime-1.5.4/qt/plugins/000077500000000000000000000000001477034762000157465ustar00rootroot00000000000000backintime-1.5.4/qt/plugins/notifyplugin.py000066400000000000000000000046331477034762000210550ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2021 Felix Stupp # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Notify plugin module""" import getpass import dbus import pluginmanager import logger class NotifyPlugin(pluginmanager.Plugin): """Plugin used to create notification bubbles in systray. The plugin use DBUS to send notifications. See its base class for more details. """ def isGui(self): return True # pylint: disable-next=too-many-arguments,too-many-positional-arguments def message(self, profile_id, profile_name, level, message, timeout): # 1 is ERROR, 0 is INFO if level != 1: # Dev note (2024-10, buhtz): # Message with level 0/INFO for example generatet by # setTakeSnapshotMessage() # Not clear to me why the notify plugin should only process # errors. return try: notify_interface = dbus.Interface( object=dbus.SessionBus().get_object( "org.freedesktop.Notifications", "/org/freedesktop/Notifications"), dbus_interface="org.freedesktop.Notifications" ) except dbus.exceptions.DBusException as exc: logger.error('Unexpected DBusException while initiating ' f'dbus.Interface(): {exc}') return if timeout > 0: timeout = 1000 * timeout else: # let timeout default to notification server settings timeout = -1 title = f'Back In Time ({getpass.getuser()}) : {profile_name}' message = message.replace('\n', ' ') message = message.replace('\r', '') try: notify_interface.Notify( 'Back In Time', 0, '', title, message, [], {}, timeout) except dbus.exceptions.DBusException as exc: logger.error(f'Unexpected DBusException while Notify(): {exc}') backintime-1.5.4/qt/plugins/systrayiconplugin.py000066400000000000000000000067301477034762000221340ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # TODO Known open issues: # - this script should get started and consider some cmd line arguments from BiT # (parsed via backintime.createParsers()) so that the same paths are used, # mainly "share-path" and "config" (path to the config file). # Otherwise e.g. unit tests or special user path settings may lead to # wrong status info in the systray icon! import sys import os import pluginmanager import tools import logger import gettext import subprocess _ = gettext.gettext if not os.getenv('DISPLAY', ''): os.putenv('DISPLAY', ':0.0') class SysTrayIconPlugin(pluginmanager.Plugin): def __init__(self): self.process = None self.snapshots = None def init(self, snapshots): self.snapshots = snapshots # Old implementation disabled: # Why can a systray icon only be shown on X11 (not wayland)? # Qt can handle wayland now! # if not tools.checkXServer(): # return False # New implementation: Let Qt decide if a system tray icon can be shown. # See https://doc.qt.io/qt-5/qsystemtrayicon.html#details: # > To check whether a system tray is present on the user's desktop, # > call the QSystemTrayIcon::isSystemTrayAvailable() static function. # # This requires a QApplication instance (otherwise Qt causes a segfault) # which we don't have here so we create it to check if a window manager # ("GUI") is active at all (e.g. in headless installations it isn't). # See: https://forum.qt.io/topic/3852/issystemtrayavailable-always-crashes-segfault-on-ubuntu-10-10-desktop/6 try: if tools.is_Qt_working(systray_required=True): logger.debug("System tray is available to show the BiT system tray icon") return True except Exception as e: logger.debug(f"Could not ask Qt if system tray is available: {repr(e)}") logger.debug("No system tray available to show the BiT system tray icon") return False def isGui(self): return True def processBegin(self): try: logger.debug("Trying to start systray icon sub process...") path = os.path.join(tools.backintimePath('qt'), 'qtsystrayicon.py') cmd = [sys.executable, path, self.snapshots.config.currentProfile()] if logger.DEBUG: cmd.append("--debug") # HACK to propagate DEBUG logging level to sub process self.process = subprocess.Popen(cmd) # self.process = subprocess.Popen([sys.executable, path, self.snapshots.config.currentProfile()]) except: pass def processEnd(self): if not self.process is None: try: # The "qtsystrayicon.py" app does terminate itself # once the snapshot has been taken so there is no need # to do anything here to stop it or clean-up anything. # self.process.terminate() return except: pass backintime-1.5.4/qt/qtsystrayicon.py000066400000000000000000000206251477034762000176000ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import sys import os import subprocess import signal import textwrap # TODO Is this really required? If the client is not configured for X11 # it may use Wayland or something else... # Or is this just required when run as root (where GUIs are not # configured normally)? if not os.getenv('DISPLAY', ''): os.putenv('DISPLAY', ':0.0') import qttools qttools.registerBackintimePath('common') import logger # Workaround until the codebase allows a single place to init all translations import tools tools.initiate_translation(None) import snapshots import progress import logviewdialog import encfstools from PyQt6.QtCore import QTimer from PyQt6.QtWidgets import QSystemTrayIcon, QMenu, QProgressBar, QWidget from PyQt6.QtGui import QRegion class QtSysTrayIcon: def __init__(self): self.snapshots = snapshots.Snapshots() self.config = self.snapshots.config self.decode = None if len(sys.argv) > 1: if not self.config.setCurrentProfile(sys.argv[1]): logger.warning("Failed to change Profile_ID %s" %sys.argv[1], self) self.qapp = qttools.createQApplication(self.config.APP_NAME) translator = qttools.initiate_translator(self.config.language()) self.qapp.installTranslator(translator) self.qapp.setQuitOnLastWindowClosed(False) import icon self.icon = icon # What does this code do? Make the import accessible? self.qapp.setWindowIcon(icon.BIT_LOGO) self.status_icon = QSystemTrayIcon(icon.BIT_LOGO) #self.status_icon.actionCollection().clear() self.contextMenu = QMenu() self.menuProfileName = self.contextMenu.addAction( _('Profile: {profile_name}').format(profile_name=self.config.profileName())) qttools.setFontBold(self.menuProfileName) self.contextMenu.addSeparator() self.menuStatusMessage = self.contextMenu.addAction(_('Done')) self.menuProgress = self.contextMenu.addAction('') self.menuProgress.setVisible(False) self.contextMenu.addSeparator() self.btnPause = self.contextMenu.addAction(icon.PAUSE, _('Pause snapshot process')) action = lambda: os.kill(self.snapshots.pid(), signal.SIGSTOP) self.btnPause.triggered.connect(action) self.btnResume = self.contextMenu.addAction(icon.RESUME, _('Resume snapshot process')) action = lambda: os.kill(self.snapshots.pid(), signal.SIGCONT) self.btnResume.triggered.connect(action) self.btnResume.setVisible(False) self.btnStop = self.contextMenu.addAction(icon.STOP, _('Stop snapshot process')) self.btnStop.triggered.connect(self.onBtnStop) self.contextMenu.addSeparator() self.btnDecode = self.contextMenu.addAction(icon.VIEW_SNAPSHOT_LOG, _('decode paths')) self.btnDecode.setCheckable(True) self.btnDecode.setVisible(self.config.snapshotsMode() == 'ssh_encfs') self.btnDecode.toggled.connect(self.onBtnDecode) self.openLog = self.contextMenu.addAction(icon.VIEW_LAST_LOG, _('View Last Log')) self.openLog.triggered.connect(self.onOpenLog) self.startBIT = self.contextMenu.addAction( icon.BIT_LOGO, _('Start {appname}').format(appname=self.config.APP_NAME) ) self.startBIT.triggered.connect(self.onStartBIT) self.status_icon.setContextMenu(self.contextMenu) self.pixmap = icon.BIT_LOGO.pixmap(24) self.progressBar = QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(100) self.progressBar.setValue(0) self.progressBar.setTextVisible(False) self.progressBar.resize(24, 6) self.progressBar.render( self.pixmap, sourceRegion=QRegion(0, -14, 24, 6), flags=QWidget.RenderFlag.DrawChildren ) self.first_error = self.config.notify() self.popup = None self.last_message = None self.timer = QTimer() self.timer.timeout.connect(self.updateInfo) def prepareExit(self): self.timer.stop() if not self.status_icon is None: self.status_icon.hide() self.status_icon = None if not self.popup is None: self.popup.deleteLater() self.popup = None self.qapp.processEvents() def run(self): if not self.snapshots.busy(): sys.exit() self.status_icon.show() self.timer.start(500) # logger.debug("begin loop", self) self.qapp.exec() # logger.debug("end loop", self) self.prepareExit() def updateInfo(self): # Exit this systray icon "app" when the snapshots is taken if not self.snapshots.busy(): self.prepareExit() self.qapp.exit(0) return paused = tools.processPaused(self.snapshots.pid()) self.btnPause.setVisible(not paused) self.btnResume.setVisible(paused) message = self.snapshots.takeSnapshotMessage() if message is None and self.last_message is None: message = (0, _('Working…')) if not message is None: if message != self.last_message: self.last_message = message if self.decode: message = (message[0], self.decode.log(message[1])) self.menuStatusMessage.setText('\n'.join(textwrap.wrap(message[1], \ width = 80) \ )) self.status_icon.setToolTip(message[1]) pg = progress.ProgressFile(self.config) if pg.fileReadable(): pg.load() percent = pg.intValue('percent') ## disable progressbar in icon until BiT has it's own icon ## fixes bug #902 # if percent != self.progressBar.value(): # self.progressBar.setValue(percent) # self.progressBar.render(self.pixmap, sourceRegion = QRegion(0, -14, 24, 6), flags = QWidget.RenderFlags(QWidget.DrawChildren)) # self.status_icon.setIcon(QIcon(self.pixmap)) self.menuProgress.setText(' | '.join(self.getMenuProgress(pg))) self.menuProgress.setVisible(True) else: # self.status_icon.setIcon(self.icon.BIT_LOGO) self.menuProgress.setVisible(False) def getMenuProgress(self, pg): data = ( ('sent', _('Sent:')), ('speed', _('Speed:')), ('eta', _('ETA:')) ) for key, txt in data: value = pg.strValue(key, '') if not value: continue yield txt + ' ' + value def onStartBIT(self): profileID = self.config.currentProfile() cmd = ['backintime-qt',] if not profileID == '1': cmd += ['--profile-id', profileID] proc = subprocess.Popen(cmd) def onOpenLog(self): dlg = logviewdialog.LogViewDialog(self, systray = True) dlg.decode = self.decode dlg.cbDecode.setChecked(self.btnDecode.isChecked()) dlg.exec() def onBtnDecode(self, checked): if checked: self.decode = encfstools.Decode(self.config) self.last_message = None self.updateInfo() else: self.decode = None def onBtnStop(self): os.kill(self.snapshots.pid(), signal.SIGKILL) self.btnStop.setEnabled(False) self.btnPause.setEnabled(False) self.btnResume.setEnabled(False) self.snapshots.setTakeSnapshotMessage(0, 'Snapshot terminated') if __name__ == '__main__': logger.openlog() if "--debug" in sys.argv: # HACK: Minimal arg parsing to enable debug-level logging logger.DEBUG = True logger.debug("Sub process tries to show systray icon...") logger.debug(f"qtsystrayicon.py call args: {str(sys.argv)}") QtSysTrayIcon().run() backintime-1.5.4/qt/qttools.py000066400000000000000000000601411477034762000163460ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Some helper functions and additional classes in context of Qt. - Helpers for Qt Fonts. - Helpers about path manipulation. - FiledialogShowHidden - MyTreeView (used RestoreConfigDialog) - TimeLine (might be the snapshot list in the left part of the GUI) - TimeLineItem, SnapshotItem, HeaderItem - SortedcomboBox, SnapshotCombo, ProfileCombo - Menu (tooltips in menus) """ import os import sys import re import textwrap from typing import Union, Iterable from PyQt6.QtGui import (QAction, QDesktopServices, QFont, QIcon, QPalette) from PyQt6.QtCore import (QDir, Qt, pyqtSlot, pyqtSignal, QModelIndex, QTranslator, QLocale, QLibraryInfo, QT_VERSION_STR, QUrl) from PyQt6.QtWidgets import (QFrame, QWidget, QFileDialog, QAbstractItemView, QListView, QTreeView, QDialog, QApplication, QStyleFactory, QTreeWidget, QTreeWidgetItem, QComboBox, QSystemTrayIcon) from datetime import (datetime, date, timedelta) from calendar import monthrange from packaging.version import Version from qttools_path import registerBackintimePath registerBackintimePath('common') import snapshots # noqa: E402 import tools # noqa: E402 import logger # noqa: E402 import bitbase # noqa: E402 import version # noqa: E402 # |---------------| # | Font handling | # |---------------| def fontBold(font): font.setWeight(QFont.Weight.Bold) return font def setFontBold(widget): widget.setFont(fontBold(widget.font())) def fontNormal(font): font.setWeight(QFont.Weight.Normal) return font def setFontNormal(widget): widget.setFont(fontNormal(widget.font())) def can_render(string, widget): """Check if the string can be rendered by the font used by the widget. Args: string(str): The string to check. widget(QWidget): The widget which font is used. Returns: (bool) True if the widgets font contain all given characters. """ fm = widget.fontMetrics() for c in string: # Convert the unicode character to its integer representation # because fm.inFont() is not able to handle 2-byte characters if not fm.inFontUcs4(ord(c)): return False return True # |--------------------------------| # | Widget modification & creation | # |--------------------------------| _REX_RICHTEXT = re.compile( # begin of line r'^' # all characters, except a new line r'[^\n]*' # tag opening r'<' # every character (as tagname) except > r'[^>]+' # tag closing r'>') def might_be_richtext(txt: str) -> bool: """Returns `True` if the text is rich text. Rich text is a subset of HTML used by Qt to allow text formatting. The function checks if the first line (before the first `\n') does contain a tag. A tag begins with with `<`, following by one or more characters and close with `>`. Qt itself does use `Qt::mightBeRichText()` internally but this is not available in PyQt for unknown reasons. Args: txt: The text to check. Returns: `True` if it looks like a rich text, otherwise `False`. """ return bool(_REX_RICHTEXT.match(txt)) def set_wrapped_tooltip(widget: Union[QWidget, Iterable[QWidget]], tooltip: Union[str, Iterable[str]], wrap_length: int = 72): """Add a tooltip to the widget but insert line breaks when appropriated. If a list of strings is provided, each string is wrapped individually and then joined with a line break. Args: widget: The widget or list of widgets to which a tooltip should be added. tooltip: The tooltip as string or iterable of strings. wrap_length: Every line is at most this lengths. """ if isinstance(widget, Iterable): for wdg in widget: set_wrapped_tooltip(wdg, tooltip, wrap_length) return # Always use tuple or list if isinstance(tooltip, str): tooltip = (tooltip, ) # Richtext or plain text newline = {True: '
', False: '\n'}[might_be_richtext(tooltip[0])] result = [] # Wrap each paragraph in itself for paragraph in tooltip: result.append('\n'.join( textwrap.wrap(paragraph, wrap_length) )) # glue all together widget.setToolTip(newline.join(result)) def update_combo_profiles(config, combo_profiles, current_profile_id): """ Updates the combo box with profiles. :param config: Configuration object with access to profile data. :param combo_profiles: The combo box widget to be updated. :param current_profile_id: The ID of the current profile to be selected. """ profiles = config.profilesSortedByName() for profile_id in profiles: combo_profiles.addProfileID(profile_id) if profile_id == current_profile_id: combo_profiles.setCurrentProfileID(profile_id) # |---------------------| # | Misc / Uncatgorized | # |---------------------| def user_manual_uri() -> str: """Return the URI to the user manual. If available the local URI is used otherwise the online version is. """ uri = bitbase.USER_MANUAL_LOCAL_PATH.as_uri() \ if bitbase.USER_MANUAL_LOCAL_AVAILABLE \ else bitbase.USER_MANUAL_ONLINE_URL return uri def open_user_manual() -> None: """Open the user manual in browser. If available the local manual is used otherwise the online version is opened. """ QDesktopServices.openUrl(QUrl(user_manual_uri())) class FileDialogShowHidden(QFileDialog): """File dialog able to display hidden files.""" def __init__(self, parent, *args, **kwargs): super(FileDialogShowHidden, self).__init__(parent, *args, **kwargs) self.setOption(QFileDialog.Option.DontUseNativeDialog, True) self.setOption(QFileDialog.Option.HideNameFilterDetails, True) showHiddenAction = QAction(self) showHiddenAction.setShortcut('Ctrl+H') showHiddenAction.triggered.connect(self.toggleShowHidden) self.addAction(showHiddenAction) self.showHidden(hiddenFiles(parent)) def showHidden(self, enable): if enable: self.setFilter(self.filter() | QDir.Filter.Hidden) elif self.filter() & QDir.Filter.Hidden: self.setFilter(self.filter() ^ QDir.Filter.Hidden) def toggleShowHidden(self): self.showHidden(not QDir.Filter(self.filter() & QDir.Filter.Hidden)) def getExistingDirectories(parent, *args, **kwargs): """Workaround for selecting multiple directories adopted from http://www.qtcentre.org/threads/34226-QFileDialog-select-multiple-directories?p=158482#post158482 This also give control about hidden folders """ dlg = FileDialogShowHidden(parent, *args, **kwargs) dlg.setFileMode(dlg.FileMode.Directory) dlg.setOption(dlg.Option.ShowDirsOnly, True) mode = QAbstractItemView.SelectionMode.ExtendedSelection dlg.findChildren(QListView)[0].setSelectionMode(mode) dlg.findChildren(QTreeView)[0].setSelectionMode(mode) if dlg.exec() == QDialog.DialogCode.Accepted: return dlg.selectedFiles() return [str(), ] def getExistingDirectory(parent, *args, **kwargs): """Workaround to give control about hidden folders""" dlg = FileDialogShowHidden(parent, *args, **kwargs) dlg.setFileMode(dlg.FileMode.Directory) dlg.setOption(dlg.Option.ShowDirsOnly, True) if dlg.exec() == QDialog.DialogCode.Accepted: return dlg.selectedFiles()[0] return str() def getOpenFileNames(parent, *args, **kwargs): """ Workaround to give control about hidden files """ dlg = FileDialogShowHidden(parent, *args, **kwargs) dlg.setFileMode(dlg.FileMode.ExistingFiles) if dlg.exec() == QDialog.DialogCode.Accepted: return dlg.selectedFiles() return [str(), ] def getOpenFileName(parent, *args, **kwargs): """Workaround to give control about hidden files""" dlg = FileDialogShowHidden(parent, *args, **kwargs) dlg.setFileMode(dlg.FileMode.ExistingFile) if dlg.exec() == QDialog.DialogCode.Accepted: return dlg.selectedFiles()[0] return str() def hiddenFiles(parent): try: return parent.parent.showHiddenFiles except Exception: pass try: return parent.showHiddenFiles except Exception: pass return False def createQApplication(app_name='Back In Time'): global qapp try: return qapp # "singleton pattern": Reuse already instantiated qapp except NameError: pass if (Version(QT_VERSION_STR) >= Version('5.6') and hasattr(Qt, 'AA_EnableHighDpiScaling')): QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) qapp = QApplication(sys.argv) qt_platform_name = "" try: # The platform name indicates eg. wayland vs. X11, see also: # https://doc.qt.io/qt-5/qguiapplication.html#platformName-prop # For more details see our X11/Wayland/Qt documentation in the # directory doc/maintain qt_platform_name = qapp.platformName() logger.debug(f"QT QPA platform plugin: {qt_platform_name}") logger.debug( "QT_QPA_PLATFORMTHEME=" f"{os.environ.get('QT_QPA_PLATFORMTHEME') or ''}") # styles and themes determine the look & feel of the GUI logger.debug( "QT_STYLE_OVERRIDE=" f"{os.environ.get('QT_STYLE_OVERRIDE') or ''}") logger.debug(f"QT active style: {qapp.style().objectName()}") logger.debug(f"QT fallback style: {QIcon.fallbackThemeName()}") logger.debug(f"QT supported styles: {QStyleFactory.keys()}") logger.debug(f"themeSearchPaths: {str(QIcon.themeSearchPaths())}") logger.debug( f"fallbackSearchPaths: {str(QIcon.fallbackSearchPaths())}") # The Back In Time system tray icon can only be shown if the desktop # environment supports this logger.debug("Is SystemTray available: " f"{str(QSystemTrayIcon.isSystemTrayAvailable())}") except Exception as e: logger.debug( f"Error reading QT QPA platform plugin or style: {repr(e)}") # Release Candidate indicator if version.is_release_candidate(): app_name = f'{app_name} -- RELEASE CANDIDATE -- ' \ f'({version.__version__})' qapp.setApplicationName(app_name) try: if tools.isRoot(): qapp.setApplicationName(app_name + " (root)") logger.debug("Trying to set App ID for root user") qapp.setDesktopFileName("backintime-qt-root") else: logger.debug("Trying to set App ID for non-privileged user") qapp.setDesktopFileName("backintime-qt") except Exception as e: logger.warning( "Could not set App ID (required for Wayland App icon and more)") logger.warning("Reason: " + repr(e)) if (os.geteuid() == 0 and qapp.style().objectName().lower() == 'windows' and 'GTK+' in QStyleFactory.keys()): qapp.setStyle('GTK+') # With "--debug" arg show the QT QPA platform name in the main window's # title if logger.DEBUG: qapp.setApplicationName( f'{qapp.applicationName()} ' f'[QT QPA platform: "{qt_platform_name}"]') return qapp def initiate_translator(language_code: str) -> QTranslator: """Creating an Qt related translator. Args: language_code: Language code to use (based on ISO-639-1). This is done beside the primarily used GNU gettext because Qt need to translate its own default elements like Yes/No-buttons. The systems current local is used when no language code is provided. Translation is deactivated if language code is unknown. """ translator = QTranslator() if language_code: logger.debug(f'Language code "{language_code}".') else: logger.debug('No language code. Use systems current locale.') language_code = QLocale.system().name() rc = translator.load( f'qt_{language_code}', QLibraryInfo.path(QLibraryInfo.LibraryPath.TranslationsPath)) if rc is False: logger.warning( 'PyQt (the GUI library) could not install a translator for the ' f'language code "{language_code}". Standard GUI elements will ' 'fall back to the source language (English). This does not ' 'affect the translation of Back In Time-specific GUI elements.') tools.set_lc_time_by_language_code(language_code) return translator def indexFirstColumn(idx): if idx.column() > 0: idx = idx.sibling(idx.row(), 0) return idx class MyTreeView(QTreeView): """ subclass QTreeView to emit a SIGNAL myCurrentIndexChanged if the SLOT currentChanged is called """ myCurrentIndexChanged = pyqtSignal(QModelIndex, QModelIndex) def currentChanged(self, current, previous): self.myCurrentIndexChanged.emit(current, previous) super(MyTreeView, self).currentChanged(current, previous) class TimeLine(QTreeWidget): updateFilesView = pyqtSignal(int) def __init__(self, parent): super(TimeLine, self).__init__(parent) self.setRootIsDecorated(False) self.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers) self.setSelectionMode( QAbstractItemView.SelectionMode.ExtendedSelection) self.setHeaderLabels([_('Snapshots'), 'foo']) self.setSortingEnabled(True) self.sortByColumn(1, Qt.SortOrder.DescendingOrder) self.hideColumn(1) self.header().setSectionsClickable(False) self.parent = parent self.snapshots = parent.snapshots self._resetHeaderData() def clear(self): self._resetHeaderData() return super(TimeLine, self).clear() def _resetHeaderData(self): self.now = date.today() # list of tuples with (text, startDate, endDate) self.headerData = [] # Today todayMin = datetime.combine(self.now, datetime.min.time()) todayMax = datetime.combine(self.now, datetime.max.time()) self.headerData.append((_('Today'), todayMin, todayMax)) # Yesterday yesterdayMin = datetime.combine( self.now - timedelta(days=1), datetime.min.time()) yesterdayMax = datetime.combine( todayMin - timedelta(hours=1), datetime.max.time()) self.headerData.append((_('Yesterday'), yesterdayMin, yesterdayMax)) # This week thisWeekMin = datetime.combine( self.now - timedelta(self.now.weekday()), datetime.min.time()) thisWeekMax = datetime.combine( yesterdayMin - timedelta(hours=1), datetime.max.time()) if thisWeekMin < thisWeekMax: self.headerData.append((_('This week'), thisWeekMin, thisWeekMax)) # Last week lastWeekMin = datetime.combine( self.now - timedelta(self.now.weekday() + 7), datetime.min.time()) lastWeekMax = datetime.combine( self.headerData[-1][1] - timedelta(hours=1), datetime.max.time()) self.headerData.append((_('Last week'), lastWeekMin, lastWeekMax)) # Rest of current month. Otherwise this months header would be # above today. thisMonthMin = datetime.combine( self.now - timedelta(self.now.day - 1), datetime.min.time()) thisMonthMax = datetime.combine( lastWeekMin - timedelta(hours=1), datetime.max.time()) if thisMonthMin < thisMonthMax: self.headerData.append((thisMonthMin.strftime('%B').capitalize(), thisMonthMin, thisMonthMax)) # Rest of last month lastMonthMax = datetime.combine( self.headerData[-1][1] - timedelta(hours=1), datetime.max.time()) lastMonthMin = datetime.combine( date(lastMonthMax.year, lastMonthMax.month, 1), datetime.min.time() ) self.headerData.append((lastMonthMin.strftime('%B').capitalize(), lastMonthMin, lastMonthMax)) def addRoot(self, sid): self.rootItem = self.addSnapshot(sid) return self.rootItem @pyqtSlot(snapshots.SID) def addSnapshot(self, sid): item = SnapshotItem(sid) self.addTopLevelItem(item) # Select the snapshot that was selected before if sid == self.parent.sid: self.setCurrentItem(item) if not sid.isRoot: self.addHeader(sid) return item def addHeader(self, sid): for text, startDate, endDate in self.headerData: if startDate <= sid.date <= endDate: return self._createHeaderItem(text, endDate) # Any previous months year = sid.date.year month = sid.date.month if year == self.now.year: text = date(year, month, 1).strftime('%B').capitalize() else: text = date(year, month, 1).strftime('%B, %Y').capitalize() startDate = datetime.combine( date(year, month, 1), datetime.min.time()) endDate = datetime.combine( date(year, month, monthrange(year, month)[1]), datetime.max.time()) if self._createHeaderItem(text, endDate): self.headerData.append((text, startDate, endDate)) def _createHeaderItem(self, text, endDate): for item in self.iterHeaderItems(): if item.snapshotID().date == endDate: return False item = HeaderItem(text, snapshots.SID(endDate, self.parent.config)) self.addTopLevelItem(item) return True @pyqtSlot() def checkSelection(self): if self.currentItem() is None: self.selectRootItem() def selectRootItem(self): self.setCurrentItem(self.rootItem) if not self.parent.sid.isRoot: self.parent.sid = self.rootItem.snapshotID() self.updateFilesView.emit(2) def selectedSnapshotIDs(self): return [i.snapshotID() for i in self.selectedItems()] def currentSnapshotID(self): item = self.currentItem() if item: return item.snapshotID() def setCurrentSnapshotID(self, sid): for item in self.iterItems(): if item.snapshotID() == sid: self.setCurrentItem(item) break def setCurrentItem(self, item, *args, **kwargs): super(TimeLine, self).setCurrentItem(item, *args, **kwargs) if self.parent.sid != item.snapshotID(): self.parent.sid = item.snapshotID() self.updateFilesView.emit(2) def iterItems(self): for index in range(self.topLevelItemCount()): yield self.topLevelItem(index) def iterSnapshotItems(self): for item in self.iterItems(): if isinstance(item, SnapshotItem): yield item def iterHeaderItems(self): for item in self.iterItems(): if isinstance(item, HeaderItem): yield item class TimeLineItem(QTreeWidgetItem): def __lt__(self, other): return self.snapshotID() < other.snapshotID() def snapshotID(self): return self.data(0, Qt.ItemDataRole.UserRole) class SnapshotItem(TimeLineItem): def __init__(self, sid): super(SnapshotItem, self).__init__() self.setText(0, sid.displayName) self.setFont(0, fontNormal(self.font(0))) self.setData(0, Qt.ItemDataRole.UserRole, sid) if sid.isRoot: self.setToolTip(0, _('This is NOT a snapshot but a live ' 'view of your local files')) else: self.setToolTip( 0, _('Last check {time}').format(time=sid.lastChecked)) def updateText(self): sid = self.snapshotID() self.setText(0, sid.displayName) class HeaderItem(TimeLineItem): def __init__(self, name, sid): """ Dev note (buhtz, 2024-01-14): Parts of that code are redundant with app.py::MainWindow.addPlace(). """ super(HeaderItem, self).__init__() self.setText(0, name) self.setFont(0, fontBold(self.font(0))) palette = QApplication.instance().palette() self.setForeground( 0, palette.color(QPalette.ColorRole.PlaceholderText)) self.setBackground( 0, palette.color(QPalette.ColorRole.Window)) self.setFlags(Qt.ItemFlag.NoItemFlags) self.setData(0, Qt.ItemDataRole.UserRole, sid) class SortedComboBox(QComboBox): # Prevent inserting items abroad from addItem because this would break # sorting insertItem = NotImplemented def __init__(self, parent=None): super(SortedComboBox, self).__init__(parent) self.sortOrder = Qt.SortOrder.AscendingOrder self.sortRole = Qt.ItemDataRole.DisplayRole def addItem(self, text, userData=None): """ QComboBox doesn't support sorting so this little hack is used to insert items in sorted order. """ if self.sortRole == Qt.ItemDataRole.UserRole: sortObject = userData else: sortObject = text the_list = [ self.itemData(i, self.sortRole) for i in range(self.count())] the_list.append(sortObject) reverse_sort = self.sortOrder == Qt.SortOrder.DescendingOrder the_list.sort(reverse=reverse_sort) index = the_list.index(sortObject) super(SortedComboBox, self).insertItem(index, text, userData) def checkSelection(self): if self.currentIndex() < 0: self.setCurrentIndex(0) class SnapshotCombo(SortedComboBox): def __init__(self, parent=None): super(SnapshotCombo, self).__init__(parent) self.sortOrder = Qt.SortOrder.DescendingOrder self.sortRole = Qt.ItemDataRole.UserRole def addSnapshotID(self, sid): assert isinstance(sid, snapshots.SID), \ f'sid is not snapshots.SID type: {sid}' self.addItem(sid.displayName, sid) def currentSnapshotID(self): return self.itemData(self.currentIndex()) def setCurrentSnapshotID(self, sid): for i in range(self.count()): if self.itemData(i) == sid: self.setCurrentIndex(i) break class ProfileCombo(SortedComboBox): def __init__(self, parent): super(ProfileCombo, self).__init__(parent) self.getName = parent.config.profileName def addProfileID(self, profileID): self.addItem(self.getName(profileID), profileID) def currentProfileID(self): return self.itemData(self.currentIndex()) def setCurrentProfileID(self, profileID): for i in range(self.count()): if self.itemData(i) == profileID: self.setCurrentIndex(i) break class HLineWidget(QFrame): """Just a horizontal line. It really is the case that even in the year 2025 with Qt6 there is no dedicated widget class to draw a horizontal line. """ def __init__(self): super().__init__() self.setFrameShape(QFrame.Shape.HLine) self.setFrameShadow(QFrame.Shadow.Sunken) backintime-1.5.4/qt/qttools_path.py000066400000000000000000000021471477034762000173640ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Helper functions extracted from qt/qttools.py file. Extraction happened of problems with import dependencies. The whole path manipulation will become obsolete when migrating to state of the art Python packaging standards. This module is a workaround and will get refactored in the future. """ import os import sys def backintimePath(*path): """Return the path of the backintime project folder.""" return os.path.abspath(os.path.join(__file__, os.pardir, os.pardir, *path)) def registerBackintimePath(*path): """Find duplicate in common/tools.py """ path = backintimePath(*path) if path not in sys.path: sys.path.insert(0, path) backintime-1.5.4/qt/restoreconfigdialog.py000066400000000000000000000305321477034762000206730ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008-2022 Taylor Raak # SPDX-FileCopyrightText: © 2024 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import datetime import getpass from PyQt6.QtGui import QPalette, QColor, QFileSystemModel from PyQt6.QtWidgets import (QDialog, QVBoxLayout, QGridLayout, QDialogButtonBox, QWidget, QLabel, QMenu, QProgressBar, ) from PyQt6.QtCore import (Qt, QDir, QSortFilterProxyModel, QThread, pyqtSignal) import config import qttools import snapshots import logger import qttools class RestoreConfigDialog(QDialog): """ Show a dialog that will help to restore BITs configuration. User can select a config from previous snapshots. """ def __init__(self, parent): super(RestoreConfigDialog, self).__init__(parent) self.parent = parent self.config = parent.config self.snapshots = parent.snapshots import icon self.icon = icon self.setWindowIcon(icon.SETTINGS_DIALOG) self.setWindowTitle(_('Import configuration')) layout = QVBoxLayout(self) layout.addWidget(self._create_hint_label()) # treeView self.treeView = qttools.MyTreeView(self) self.treeViewModel = QFileSystemModel(self) self.treeViewModel.setRootPath(QDir().rootPath()) self.treeViewModel.setReadOnly(True) self.treeViewModel.setFilter(QDir.Filter.AllDirs | QDir.Filter.NoDotAndDotDot | QDir.Filter.Hidden) self.treeViewFilterProxy = QSortFilterProxyModel(self) self.treeViewFilterProxy.setDynamicSortFilter(True) self.treeViewFilterProxy.setSourceModel(self.treeViewModel) self.treeViewFilterProxy.setFilterRegularExpression(r'^[^\.]') self.treeView.setModel(self.treeViewFilterProxy) for col in range(self.treeView.header().count()): self.treeView.setColumnHidden(col, col != 0) self.treeView.header().hide() # expand users home self.expandAll(os.path.expanduser('~')) layout.addWidget(self.treeView) # context menu self.treeView.setContextMenuPolicy( Qt.ContextMenuPolicy.CustomContextMenu) self.treeView.customContextMenuRequested.connect(self.onContextMenu) self.contextMenu = QMenu(self) self.btnShowHidden = self.contextMenu.addAction( icon.SHOW_HIDDEN, _('Show hidden files')) self.btnShowHidden.setCheckable(True) self.btnShowHidden.toggled.connect(self.onBtnShowHidden) # colors self.colorRed = QPalette() self.colorRed.setColor( QPalette.ColorRole.WindowText, QColor(205, 0, 0)) self.colorGreen = QPalette() self.colorGreen.setColor( QPalette.ColorRole.WindowText, QColor(0, 160, 0)) # wait indicator which will show that the scan for # snapshots is still running self.wait = QProgressBar(self) self.wait.setMinimum(0) self.wait.setMaximum(0) self.wait.setMaximumHeight(7) layout.addWidget(self.wait) # show where a snapshot with config was found self.lblFound = QLabel(_('No config found'), self) self.lblFound.setWordWrap(True) self.lblFound.setPalette(self.colorRed) layout.addWidget(self.lblFound) # show profiles inside the config self.widgetProfiles = QWidget(self) self.widgetProfiles.setContentsMargins(0, 0, 0, 0) self.widgetProfiles.hide() self.gridProfiles = QGridLayout() self.gridProfiles.setContentsMargins(0, 0, 0, 0) self.gridProfiles.setHorizontalSpacing(20) self.widgetProfiles.setLayout(self.gridProfiles) layout.addWidget(self.widgetProfiles) self.restoreConfig = None self.scan = ScanFileSystem(self) self.treeView.myCurrentIndexChanged.connect(self.indexChanged) self.scan.foundConfig.connect(self.scanFound) self.scan.finished.connect(self.scanFinished) buttonBox = QDialogButtonBox(self) self.restoreButton = buttonBox.addButton( _('Import'), QDialogButtonBox.ButtonRole.AcceptRole) self.restoreButton.setEnabled(False) buttonBox.addButton(QDialogButtonBox.StandardButton.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) layout.addWidget(buttonBox) self.scan.start() self.resize(600, 700) def _create_hint_label(self): """Create the label to explain how and where to find existing config file. Returns: (QLabel): The label """ samplePath = os.path.join( 'backintime', self.config.host(), getpass.getuser(), '1', snapshots.SID(datetime.datetime.now(), self.config).sid ) samplePath = f'{samplePath}' text_a = _( 'Select the snapshot directory from which the configuration ' 'file should be imported. The path may look like: {samplePath}' ).format(samplePath=samplePath) text_b = _( 'If the directory is located on an external or remote drive, ' 'it must be manually mounted beforehand.' ) label = QLabel(f'

{text_a}

{text_b}

', self) label.setWordWrap(True) return label def pathFromIndex(self, index): """ return a path string for a given treeView index """ sourceIndex = self.treeViewFilterProxy.mapToSource(index) return str(self.treeViewModel.filePath(sourceIndex)) def indexFromPath(self, path): """ return the index for path which can be used in treeView """ indexSource = self.treeViewModel.index(path) return self.treeViewFilterProxy.mapFromSource(indexSource) def indexChanged(self, current, previous): """ called every time a new item is chosen in treeView. If there was a config found inside the selected folder, show available information about the config. """ cfg = self.searchConfig(self.pathFromIndex(current)) if cfg: self.expandAll( os.path.dirname(os.path.dirname(cfg._LOCAL_CONFIG_PATH))) self.lblFound.setText(cfg._LOCAL_CONFIG_PATH) self.lblFound.setPalette(self.colorGreen) self.showProfile(cfg) self.restoreConfig = cfg else: self.lblFound.setText(_('No config found')) self.lblFound.setPalette(self.colorRed) self.widgetProfiles.hide() self.restoreConfig = None self.restoreButton.setEnabled(bool(cfg)) def searchConfig(self, path): """ try to find config in couple possible subfolders """ snapshotPath = os.path.join( 'backintime', self.config.host(), getpass.getuser()) tryPaths = ['', '..', 'last_snapshot'] tryPaths.extend([ os.path.join(snapshotPath, str(i), 'last_snapshot') for i in range(10)]) for p in tryPaths: cfgPath = os.path.join(path, p, 'config') if os.path.exists(cfgPath): try: cfg = config.Config(cfgPath) if cfg.isConfigured(): return cfg except Exception as exc: logger.error( f'Unhandled branch in code! See in {__file__} ' f'SettingsDialog.searchConfig()\n{exc}') pass return def expandAll(self, path): """ expand all folders from filesystem root to given path """ paths = [path, ] while len(path) > 1: path = os.path.dirname(path) paths.append(path) paths.append('/') paths.reverse() [self.treeView.expand(self.indexFromPath(p)) for p in paths] def showProfile(self, cfg): """ show information about the profiles inside cfg """ child = self.gridProfiles.takeAt(0) while child: child.widget().deleteLater() child = self.gridProfiles.takeAt(0) for row, profileId in enumerate(cfg.profiles()): for col, txt in enumerate(( _('Profile:') + str(profileId), cfg.profileName(profileId), _('Mode:') + cfg.SNAPSHOT_MODES[ cfg.snapshotsMode(profileId)][1] )): self.gridProfiles.addWidget(QLabel(txt, self), row, col) self.gridProfiles.setColumnStretch(col, 1) self.widgetProfiles.show() def scanFound(self, path): """ scan hit a config. Expand the snapshot folder. """ self.expandAll(os.path.dirname(path)) def scanFinished(self): """ scan is done. Delete the wait indicator """ self.wait.deleteLater() def onContextMenu(self, point): self.contextMenu.exec(self.treeView.mapToGlobal(point)) def onBtnShowHidden(self, checked): if checked: self.treeViewFilterProxy.setFilterRegularExpression(r'') else: self.treeViewFilterProxy.setFilterRegularExpression(r'^[^\.]') def accept(self): """ handle over the dict from the selected config. The dict contains all settings from the config. """ if self.restoreConfig: self.config.dict = self.restoreConfig.dict super(RestoreConfigDialog, self).accept() def exec(self): """ stop the scan thread if it is still running after dialog was closed. """ ret = super(RestoreConfigDialog, self).exec() self.scan.stop() return ret class ScanFileSystem(QThread): CONFIG = 'config' BACKUP = 'backup' BACKINTIME = 'backintime' foundConfig = pyqtSignal(str) def __init__(self, parent): super(ScanFileSystem, self).__init__(parent) self.stopper = False def stop(self): """ prepare stop and wait for finish. """ self.stopper = True return self.wait() def run(self): """ search in order of hopefully fastest way to find the snapshots. 1. /home/USER 2. /media 3. /mnt and at last filesystem root. Already searched paths will be excluded. """ searchOrder = [os.path.expanduser('~'), '/media', '/mnt', '/'] for scan in searchOrder: exclude = searchOrder[:] exclude.remove(scan) for path in self.scanPath(scan, exclude): self.foundConfig.emit(path) def scanPath(self, path, excludes=()): """ walk through all folders and try to find 'config' file. If found make sure it is nested in backintime/FOO/BAR/1/2345/config and return its path. Exclude all paths from excludes and also all backintime/FOO/BAR/1/2345/backup """ for root, dirs, files in os.walk(path, topdown=True): if self.stopper: return for exclude in excludes: exDir, exBase = os.path.split(exclude) if root == exDir: if exBase in dirs: del dirs[dirs.index(exBase)] if self.CONFIG in files: rootdirs = root.split(os.sep) if len(rootdirs) > 4 and rootdirs[-5].startswith(self.BACKINTIME): if self.BACKUP in dirs: del dirs[dirs.index(self.BACKUP)] yield root backintime-1.5.4/qt/restoredialog.py000066400000000000000000000100051477034762000174760ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os from PyQt6.QtGui import * from PyQt6.QtWidgets import * from PyQt6.QtCore import * import tools class RestoreDialog(QDialog): def __init__(self, parent, sid, what, where = '', **kwargs): super(RestoreDialog, self).__init__(parent) self.resize(600, 500) self.config = parent.config self.snapshots = parent.snapshots self.sid = sid self.what = what self.where = where self.kwargs = kwargs import icon self.logFile = self.config.restoreLogFile() if os.path.exists(self.logFile): os.remove(self.logFile) self.setWindowIcon(icon.RESTORE_DIALOG) self.setWindowTitle(_('Restore')) self.mainLayout = QVBoxLayout(self) #text view self.txtLogView = QPlainTextEdit(self) self.txtLogView.setReadOnly(True) self.txtLogView.setLineWrapMode(QPlainTextEdit.LineWrapMode.NoWrap) self.txtLogView.setMaximumBlockCount(100000) self.mainLayout.addWidget(self.txtLogView) #buttons buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Close) showLog = buttonBox.addButton(_('Show full Log'), QDialogButtonBox.ButtonRole.ActionRole) self.mainLayout.addWidget(buttonBox) self.btnClose = buttonBox.button(QDialogButtonBox.StandardButton.Close) self.btnClose.setEnabled(False) buttonBox.rejected.connect(self.close) showLog.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(self.logFile))) #restore in separate thread self.thread = RestoreThread(self) self.thread.finished.connect(self.threadFinished) #refresh log every 200ms self.refreshTimer = QTimer(self) self.refreshTimer.setInterval(200) self.refreshTimer.setSingleShot(False) self.refreshTimer.timeout.connect(self.refreshLog) def refreshLog(self): """ get new log from thread """ newLog = self.thread.buffer[:] size = len(newLog) if size: self.thread.mutex.lock() self.thread.buffer = self.thread.buffer[size:] self.thread.mutex.unlock() self.txtLogView.appendPlainText(newLog.rstrip('\n')) def exec(self): #inhibit suspend/hibernate during restore self.config.inhibitCookie = tools.inhibitSuspend(toplevel_xid = self.config.xWindowId, reason = 'restoring') self.show() self.refreshTimer.start() self.thread.start() super(RestoreDialog, self).exec() self.refreshTimer.stop() self.thread.wait() def threadFinished(self): self.btnClose.setEnabled(True) #release inhibit suspend if self.config.inhibitCookie: self.config.inhibitCookie = tools.unInhibitSuspend(*self.config.inhibitCookie) class RestoreThread(QThread): """ run restore in a separate Thread to prevent GUI freeze and speed up restore """ def __init__(self, parent): super(RestoreThread, self).__init__() self.parent = parent self.log = open(parent.logFile, 'wt') self.mutex = QMutex() self.buffer = '' def run(self): self.parent.snapshots.restore(self.parent.sid, self.parent.what, self.callback, self.parent.where, **self.parent.kwargs) self.log.close() def callback(self, line, *args): """ write into log file and provide thread save string for log window """ line += '\n' self.log.write(line) self.mutex.lock() self.buffer += line self.mutex.unlock() backintime-1.5.4/qt/serviceHelper.py000066400000000000000000000325401477034762000174430ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2015-2022 Germar Reitze # SPDX-FileCopyrightText: © 2008 Canonical Ltd. # SPDX-FileCopyrightText: © 2004-2006 Red Hat Inc. # SPDX-FileCopyrightText: © 2005-2007 Collabora Ltd. # SPDX-FileCopyrightText: © 2009 David D. Lowe # # SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: MIT # SPDX-License-Identifier: CC0-1.0 # # This file is released under several licenses mentioned above. The file is # part of the program "Back In Time". The program as a whole is released under # GNU General Public License v2 (GPLv2). See file/folder LICENSE or go to # - . # - # - # # Note about the licenses by Christian Buhtz (2024-09): # Despite extensive research and attempts to contact the aforementioned # individuals and institutions, it was not possible to definitively determine # which of the mentioned licenses and copyright notices apply to which parts of # the code contained in this file. The situation could not be clarified even # with the git commit history. # It should be noted that, in case of doubt, preference should be given to the # strongest or most restrictive license. # # Before SPDX meta data was added to the file it originally had some comments # that are summarized as follows: # - Germar Reitze claimed GPL-2.0-or-later in context of Back In Time. # - Unknown person claimed GPL-2.0-or-later in context of "jockey". # - Read Hat Inc. and Collabora Ltd. claimed MIT License in context of # "python-dbus-docs" # - David D. Lowe claimed CC0-1.0 (public domain) in unknown context. # # Because of MIT License the following permission notice need to be included # in this file and should not be removed: # --- Begin of MIT License permission notice --- # 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. # --- End of MIT License permission notice --- import os import re from subprocess import Popen, PIPE try: import pwd except ImportError: pwd = None import dbus import dbus.service import dbus.mainloop # pylint: disable-next=import-error,useless-suppression import dbus.mainloop.pyqt6 # pylint: disable-next=import-error,useless-suppression from dbus.mainloop.pyqt6 import DBusQtMainLoop from PyQt6.QtCore import QCoreApplication UDEV_RULES_PATH = '/etc/udev/rules.d/99-backintime-%s.rules' class InvalidChar(dbus.DBusException): _dbus_error_name = 'net.launchpad.backintime.InvalidChar' class InvalidCmd(dbus.DBusException): _dbus_error_name = 'net.launchpad.backintime.InvalidCmd' class LimitExceeded(dbus.DBusException): _dbus_error_name = 'net.launchpad.backintime.LimitExceeded' class PermissionDeniedByPolicy(dbus.DBusException): _dbus_error_name = 'com.ubuntu.DeviceDriver.PermissionDeniedByPolicy' class UdevRules(dbus.service.Object): def __init__(self, conn=None, object_path=None, bus_name=None): super(UdevRules, self).__init__(conn, object_path, bus_name) # the following variables are used by _checkPolkitPrivilege self.polkit = None self.enforce_polkit = True self.tmpDict = {} # find su path self.su = self._which('su', '/bin/su') self.backintime = self._which('backintime', '/usr/bin/backintime') self.nice = self._which('nice', '/usr/bin/nice') self.ionice = self._which('ionice', '/usr/bin/ionice') self.max_rules = 100 self.max_users = 20 self.max_cmd_len = 120 # was 100 before but was too small (see #1027) def _which(self, exe, fallback): proc = Popen(['which', exe], stdout=PIPE) ret = proc.communicate()[0].strip().decode() if proc.returncode or not ret: return fallback return ret def _validateCmd(self, cmd): if cmd.find("&&") != -1: raise InvalidCmd("Parameter 'cmd' contains '&&' concatenation") # make sure it starts with an absolute path elif not cmd.startswith(os.path.sep): raise InvalidCmd("Parameter 'cmd' does not start with '/'") parts = cmd.split() # make sure only well known commands and switches are used whitelist = ( (self.nice, r'^-n'), (self.ionice, r'(^-c|^-n)'), ) while parts: for c, switches in whitelist: if parts[0] == c: parts.pop(0) while parts and re.match(switches, parts[0]): parts.pop(0) break else: break if not parts: raise InvalidCmd( "Parameter 'cmd' does not contain the backintime command") elif parts[0] != self.backintime: raise InvalidCmd("Parameter 'cmd' contains non-whitelisted " f"cmd/parameter ({parts[0]})") def _checkLimits(self, owner, cmd): if len(self.tmpDict.get(owner, [])) >= self.max_rules: raise LimitExceeded("Maximum number of cached rules reached (%d)" % self.max_rules) elif len(self.tmpDict) >= self.max_users: raise LimitExceeded("Maximum number of cached users reached (%d)" % self.max_users) elif len(cmd) > self.max_cmd_len: raise LimitExceeded("Maximum length of command line reached (%d)" % self.max_cmd_len) @dbus.service.method("net.launchpad.backintime.serviceHelper.UdevRules", in_signature='ss', out_signature='', sender_keyword='sender', connection_keyword='conn') def addRule(self, cmd, uuid, sender=None, conn=None): """ Receive command and uuid and create an Udev rule out of this. This is done on the service side to prevent malicious code to run as root. """ # prevent breaking out of su command chars = re.findall(r'[^a-zA-Z0-9-/\.>& ]', cmd) if chars: raise InvalidChar("Parameter 'cmd' contains invalid character(s) %s" % '|'.join(set(chars))) # only allow relevant chars in uuid chars = re.findall(r'[^a-zA-Z0-9-]', uuid) if chars: raise InvalidChar("Parameter 'uuid' contains invalid character(s) %s" % '|'.join(set(chars))) self._validateCmd(cmd) info = SenderInfo(sender, conn) user = info.connectionUnixUser() owner = info.nameOwner() self._checkLimits(owner, cmd) #create su command sucmd = "%s - '%s' -c '%s'" %(self.su, user, cmd) #create Udev rule rule = 'ACTION=="add|change", ENV{ID_FS_UUID}=="%s", RUN+="%s"\n' %(uuid, sucmd) #store rule if not owner in self.tmpDict: self.tmpDict[owner] = [] self.tmpDict[owner].append(rule) @dbus.service.method("net.launchpad.backintime.serviceHelper.UdevRules", in_signature='', out_signature='b', sender_keyword='sender', connection_keyword='conn') def save(self, sender=None, conn=None): """ Save rules to destination file after user authenticated as admin. This will first check if there are any changes between temporary added rules and current rules in destination file. Returns False if files are identical or no rules to be installed. """ info = SenderInfo(sender, conn) user = info.connectionUnixUser() owner = info.nameOwner() #delete rule if no rules in tmp if not owner in self.tmpDict or not self.tmpDict[owner]: self.delete(sender, conn) return False #return False if rule already exist. if os.path.exists(UDEV_RULES_PATH % user): with open(UDEV_RULES_PATH % user, 'r') as f: if self.tmpDict[owner] == f.readlines(): self._clean(owner) return False #auth to save changes self._checkPolkitPrivilege(sender, conn, 'net.launchpad.backintime.UdevRuleSave') with open(UDEV_RULES_PATH % user, 'w') as f: f.writelines(self.tmpDict[owner]) self._clean(owner) return True @dbus.service.method("net.launchpad.backintime.serviceHelper.UdevRules", in_signature='', out_signature='', sender_keyword='sender', connection_keyword='conn') def delete(self, sender=None, conn=None): """ Delete existing Udev rule """ info = SenderInfo(sender, conn) user = info.connectionUnixUser() owner = info.nameOwner() self._clean(owner) if os.path.exists(UDEV_RULES_PATH % user): #auth to delete rule self._checkPolkitPrivilege(sender, conn, 'net.launchpad.backintime.UdevRuleDelete') os.remove(UDEV_RULES_PATH % user) @dbus.service.method("net.launchpad.backintime.serviceHelper.UdevRules", in_signature='', out_signature='', sender_keyword='sender', connection_keyword='conn') def clean(self, sender=None, conn=None): """ clean up previous cached rules """ info = SenderInfo(sender, conn) self._clean(info.nameOwner()) def _clean(self, owner): if owner in self.tmpDict: del self.tmpDict[owner] def _initPolkit(self): if self.polkit is None: self.polkit = dbus.Interface(dbus.SystemBus().get_object( 'org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority', False), 'org.freedesktop.PolicyKit1.Authority') def _checkPolkitPrivilege(self, sender, conn, privilege): # from jockey """ Verify that sender has a given PolicyKit privilege. sender is the sender's (private) D-BUS name, such as ":1:42" (sender_keyword in @dbus.service.methods). conn is the dbus.Connection object (connection_keyword in @dbus.service.methods). privilege is the PolicyKit privilege string. This method returns if the caller is privileged, and otherwise throws a PermissionDeniedByPolicy exception. """ if sender is None and conn is None: # called locally, not through D-BUS return if not self.enforce_polkit: # that happens for testing purposes when running on the session # bus, and it does not make sense to restrict operations here return # query PolicyKit self._initPolkit() try: # We don't need is_challenge return here, since we call # with AllowUserInteraction (is_auth, _, details) = self.polkit.CheckAuthorization( ( 'system-bus-name', {'name': dbus.String(sender, variant_level=1)} ), privilege, {'': ''}, dbus.UInt32(1), '', timeout=3000 ) except dbus.DBusException as e: if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown': # polkitd timed out, connect again self.polkit = None return self._checkPolkitPrivilege(sender, conn, privilege) else: raise if not is_auth: raise PermissionDeniedByPolicy(privilege) class SenderInfo: def __init__(self, sender, conn): self.sender = sender self.dbus_info = dbus.Interface(conn.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus/Bus', False), 'org.freedesktop.DBus') def connectionUnixUser(self): uid = self.dbus_info.GetConnectionUnixUser(self.sender) if pwd: return pwd.getpwuid(uid).pw_name else: return uid def nameOwner(self): return self.dbus_info.GetNameOwner(self.sender) def connectionPid(self): return self.dbus_info.GetConnectionUnixProcessID(self.sender) if __name__ == '__main__': DBusQtMainLoop(set_as_default=True) app = QCoreApplication([]) bus = dbus.SystemBus() name = dbus.service.BusName("net.launchpad.backintime.serviceHelper", bus) object = UdevRules(bus, '/UdevRules') print("Running BIT service.") app.exec() backintime-1.5.4/qt/snapshotsdialog.py000066400000000000000000000401211477034762000200370ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2008-2022 Oprea Dan # SPDX-FileCopyrightText: © 2008-2022 Bart de Koning # SPDX-FileCopyrightText: © 2008-2022 Richard Bailey # SPDX-FileCopyrightText: © 2008-2022 Germar Reitze # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . import os import subprocess import shlex from PyQt6.QtGui import * from PyQt6.QtWidgets import * from PyQt6.QtCore import * import tools import restoredialog import messagebox import qttools import snapshots import logger DIFF_PARAMS = '%1 %2' if tools.checkCommand('meld'): DIFF_CMD = 'meld' elif tools.checkCommand('kompare'): DIFF_CMD = 'kompare' else: DIFF_CMD = '' class DiffOptionsDialog(QDialog): def __init__(self, parent): super(DiffOptionsDialog, self).__init__(parent) self.config = parent.config import icon self.setWindowIcon(icon.DIFF_OPTIONS) self.setWindowTitle(_('Options about comparing snapshots')) self.mainLayout = QGridLayout(self) cmd = self.config.strValue('qt.diff.cmd', DIFF_CMD) params = self.config.strValue('qt.diff.params', DIFF_PARAMS) self.mainLayout.addWidget(QLabel(_('Command:')), 0, 0) self.editCmd = QLineEdit(cmd, self) self.mainLayout.addWidget(self.editCmd, 0, 1) self.mainLayout.addWidget(QLabel(_('Parameters:')), 1, 0) self.editParams = QLineEdit(params, self) self.mainLayout.addWidget(self.editParams, 1, 1) self.mainLayout.addWidget( QLabel(_('Use %1 and %2 for path parameters')), 2, 1) buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) self.mainLayout.addWidget(buttonBox, 3, 0, 3, 2) def accept(self): """OK was clicked""" # Get values from text dialogs fields cmd = self.editCmd.text() params = self.editParams.text() # Any value? if not cmd: messagebox.info(_('Please set a diff command or press Cancel.')) return # Command exists? if tools.checkCommand(cmd) == False: messagebox.info(_( 'The command "{cmd}" cannot be found on this system. Please ' 'try something else or press Cancel.').format(cmd=cmd)) return if not params: params = DIFF_PARAMS messagebox.critical( self, _('No parameters set for the diff command. Using ' 'default value "{params}".').format(params=params)) # save new values self.config.setStrValue('qt.diff.cmd', cmd) self.config.setStrValue('qt.diff.params', params) self.config.save() super(DiffOptionsDialog, self).accept() class SnapshotsDialog(QDialog): def __init__(self, parent, sid, path): super(SnapshotsDialog, self).__init__(parent) self.parent = parent self.config = parent.config self.snapshots = parent.snapshots self.snapshotsList = parent.snapshotsList self.qapp = parent.qapp import icon self.sid = sid self.path = path self.setWindowIcon(icon.SNAPSHOTS) self.setWindowTitle(_('Snapshots')) self.mainLayout = QVBoxLayout(self) #path self.editPath = QLineEdit(self.path, self) self.editPath.setReadOnly(True) self.mainLayout.addWidget(self.editPath) #list different snapshots only self.cbOnlyDifferentSnapshots = QCheckBox( _('Differing snapshots only'), self) self.mainLayout.addWidget(self.cbOnlyDifferentSnapshots) self.cbOnlyDifferentSnapshots.stateChanged.connect(self.cbOnlyDifferentSnapshotsChanged) #list equal snapshots only layout = QHBoxLayout() self.mainLayout.addLayout(layout) self.cbOnlyEqualSnapshots = QCheckBox( _('List only snapshots that are equal to:'), self) self.cbOnlyEqualSnapshots.stateChanged.connect( self.cbOnlyEqualSnapshotsChanged) layout.addWidget(self.cbOnlyEqualSnapshots) self.comboEqualTo = qttools.SnapshotCombo(self) self.comboEqualTo.currentIndexChanged.connect(self.comboEqualToChanged) self.comboEqualTo.setEnabled(False) layout.addWidget(self.comboEqualTo) # deep check self.cbDeepCheck = QCheckBox(_('Deep check (more accurate, but slow)'), self) self.mainLayout.addWidget(self.cbDeepCheck) self.cbDeepCheck.stateChanged.connect(self.cbDeepCheckChanged) #toolbar self.toolbar = QToolBar(self) self.toolbar.setFloatable(False) self.mainLayout.addWidget(self.toolbar) #toolbar restore menuRestore = QMenu(self) action = menuRestore.addAction(icon.RESTORE, _('Restore')) action.triggered.connect(self.restoreThis) action = menuRestore.addAction(icon.RESTORE_TO, _('Restore to …')) action.triggered.connect(self.restoreThisTo) self.btnRestore = self.toolbar.addAction(icon.RESTORE, _('Restore')) self.btnRestore.setMenu(menuRestore) self.btnRestore.triggered.connect(self.restoreThis) #btn delete self.btnDelete = self.toolbar.addAction(icon.DELETE_FILE, _('Delete')) self.btnDelete.triggered.connect(self.btnDeleteClicked) #btn select_all self.btnSelectAll = self.toolbar.addAction(icon.SELECT_ALL, _('Select All')) self.btnSelectAll.triggered.connect(self.btnSelectAllClicked) #snapshots list self.timeLine = qttools.TimeLine(self) self.mainLayout.addWidget(self.timeLine) self.timeLine.itemSelectionChanged.connect(self.timeLineChanged) self.timeLine.itemActivated.connect(self.timeLineExecute) # Diff layout = QHBoxLayout() self.mainLayout.addLayout(layout) self.btnDiff = QPushButton(_('Compare'), self) layout.addWidget(self.btnDiff) self.btnDiff.clicked.connect(self.btnDiffClicked) self._update_btn_diff() self.comboDiff = qttools.SnapshotCombo(self) layout.addWidget(self.comboDiff, 2) #buttons buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel) self.btnGoto = buttonBox.button(QDialogButtonBox.StandardButton.Ok) self.btnCancel = buttonBox.button(QDialogButtonBox.StandardButton.Cancel) self.btnGoto.setText(_('Go To')) btnDiffOptions = buttonBox.addButton(_('Options'), QDialogButtonBox.ButtonRole.HelpRole) btnDiffOptions.setIcon(icon.DIFF_OPTIONS) self.mainLayout.addWidget(buttonBox) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) btnDiffOptions.clicked.connect(self.btnDiffOptionsClicked) # self.cbDeepCheck.setEnabled(False) full_path = self.sid.pathBackup(self.path) if os.path.islink(full_path): self.cbDeepCheck.hide() elif os.path.isdir(full_path): self.cbOnlyDifferentSnapshots.hide() self.cbOnlyEqualSnapshots.hide() self.comboEqualTo.hide() self.cbDeepCheck.hide() #update list and combobox self.UpdateSnapshotsAndComboEqualTo() def addSnapshot(self, sid): self.timeLine.addSnapshot(sid) #add to combo self.comboDiff.addSnapshotID(sid) if self.sid == sid: self.comboDiff.setCurrentSnapshotID(sid) self.comboDiff.checkSelection() def updateSnapshots(self): self.timeLine.clear() self.comboDiff.clear() equal_to_sid = self.comboEqualTo.currentSnapshotID() if self.cbOnlyEqualSnapshots.isChecked() and equal_to_sid: equal_to = equal_to_sid.pathBackup(self.path) else: equal_to = False snapshotsFiltered = self.snapshots.filter( base_sid=self.sid, base_path=self.path, snapshotsList=self.snapshotsList, list_diff_only=self.cbOnlyDifferentSnapshots.isChecked(), flag_deep_check=self.cbDeepCheck.isChecked(), list_equal_to=equal_to ) for sid in snapshotsFiltered: self.addSnapshot(sid) self.updateToolbar() def UpdateComboEqualTo(self): self.comboEqualTo.clear() snapshotsFiltered = self.snapshots.filter(self.sid, self.path, self.snapshotsList) for sid in snapshotsFiltered: self.comboEqualTo.addSnapshotID(sid) if sid == self.sid: self.comboEqualTo.setCurrentSnapshotID(sid) self.comboEqualTo.checkSelection() def UpdateSnapshotsAndComboEqualTo(self): self.updateSnapshots() self.UpdateComboEqualTo() def cbOnlyDifferentSnapshotsChanged(self): enabled = self.cbOnlyDifferentSnapshots.isChecked() self.cbOnlyEqualSnapshots.setEnabled(not enabled) self.cbDeepCheck.setEnabled(enabled) self.updateSnapshots() def cbOnlyEqualSnapshotsChanged(self): enabled = self.cbOnlyEqualSnapshots.isChecked() self.comboEqualTo.setEnabled(enabled) self.cbOnlyDifferentSnapshots.setEnabled(not enabled) self.cbDeepCheck.setEnabled(enabled) self.updateSnapshots() def cbDeepCheckChanged(self): self.updateSnapshots() def updateToolbar(self): sids = self.timeLine.selectedSnapshotIDs() if not sids: enable_restore = False enable_delete = False elif len(sids) == 1: enable_restore = not sids[0].isRoot enable_delete = not sids[0].isRoot else: enable_restore = False enable_delete = True for sid in sids: if sid.isRoot: enable_delete = False self.btnRestore.setEnabled(enable_restore) self.btnDelete.setEnabled(enable_delete) def restoreThis(self): # See #1485 as related bug report sid = self.timeLine.currentSnapshotID() if not sid.isRoot: restoredialog.restore(self, sid, self.path) # pylint: disable=E1101 def restoreThisTo(self): # See #1485 as related bug report sid = self.timeLine.currentSnapshotID() if not sid.isRoot: restoredialog.restore(self, sid, self.path, None) # pylint: disable=E1101 def timeLineChanged(self): self.updateToolbar() def timeLineExecute(self, item, column): if self.qapp.keyboardModifiers() and Qt.ControlModifier: return sid = self.timeLine.currentSnapshotID() if not sid: return full_path = sid.pathBackup(self.path) if not os.path.exists(full_path): return # prevent backup data from being accidentally overwritten # by create a temporary local copy and only open that one if not isinstance(self.sid, snapshots.RootSnapshot): full_path = self.parent.tmpCopy(full_path, sid) self.run = QDesktopServices.openUrl(QUrl(full_path)) def btnDiffClicked(self): sid1 = self.timeLine.currentSnapshotID() sid2 = self.comboDiff.currentSnapshotID() if not sid1 or not sid2: return path1 = sid1.pathBackup(self.path) path2 = sid2.pathBackup(self.path) # check if the 2 paths are different if path1 == path2: messagebox.critical( self, _("You can't compare a snapshot to itself.")) return diffCmd = self.config.strValue('qt.diff.cmd', DIFF_CMD) diffParams = self.config.strValue('qt.diff.params', DIFF_PARAMS) # prevent backup data from being accidentally overwritten # by create a temporary local copy and only open that one if not isinstance(sid1, snapshots.RootSnapshot): path1 = self.parent.tmpCopy(path1, sid1) if not isinstance(sid2, snapshots.RootSnapshot): path2 = self.parent.tmpCopy(path2, sid2) params = diffParams params = params.replace('%1', '"%s"' % path1) params = params.replace('%2', '"%s"' % path2) cmd = diffCmd + ' ' + params logger.debug(f'Compare two snapshots with command {cmd}.') subprocess.Popen(shlex.split(cmd)) def _update_btn_diff(self): """Enable the Compare button if diff command is set otherwise Disable it.""" cmd = self.config.strValue('qt.diff.cmd', DIFF_CMD) self.btnDiff.setDisabled(not cmd) def btnDiffOptionsClicked(self): DiffOptionsDialog(self).exec() self._update_btn_diff() def comboEqualToChanged(self, index): self.updateSnapshots() def btnDeleteClicked(self): items = self.timeLine.selectedItems() if not items: return elif len(items) == 1: msg = _('Do you really want to delete {file} in snapshot ' '{snapshot_id}?').format( file=f'"{self.path}"', snapshot_id=f'"{items[0].snapshotID()}"') else: msg = _('Do you really want to delete {file} in {count} ' 'snapshots?').format( file=f'"{self.path}"', count=len(items)) msg = _('WARNING: This cannot be revoked.') answer = messagebox.warningYesNo(self, msg) if answer == QMessageBox.StandardButton.Yes: for item in items: item.setFlags(Qt.ItemFlag.NoItemFlags) thread = RemoveFileThread(self, items) thread.started.connect(lambda: self.btnGoto.setDisabled(True)) thread.finished.connect(lambda: self.btnGoto.setDisabled(False)) thread.started.connect(lambda: self.btnDelete.setDisabled(True)) thread.finished.connect(lambda: self.btnDelete.setDisabled(False)) thread.finished.connect(self.UpdateSnapshotsAndComboEqualTo) self.btnCancel.clicked.connect(thread.terminate) thread.start() exclude = self.config.exclude() msg = _('Exclude {path} from future snapshots?').format( path=f'"{self.path}"') if self.path not in exclude: answer = messagebox.warningYesNo(self, msg) if answer == QMessageBox.StandardButton.Yes: exclude.append(self.path) self.config.setExclude(exclude) def btnSelectAllClicked(self): """ select all expect 'Now' """ self.timeLine.clearSelection() for item in self.timeLine.iterSnapshotItems(): if not isinstance(item.snapshotID(), snapshots.RootSnapshot): item.setSelected(True) def accept(self): sid = self.timeLine.currentSnapshotID() if sid: self.sid = sid super(SnapshotsDialog, self).accept() class RemoveFileThread(QThread): """ remove files in background thread so GUI will not freeze """ def __init__(self, parent, items): self.parent = parent self.config = parent.config self.snapshots = parent.snapshots self.items = items super(RemoveFileThread, self).__init__(parent) def run(self): #inhibit suspend/hibernate during delete self.config.inhibitCookie = tools.inhibitSuspend(toplevel_xid = self.config.xWindowId, reason = 'deleting files') for item in self.items: self.snapshots.deletePath(item.snapshotID(), self.parent.path) try: item.setHidden(True) except RuntimeError: #item has been deleted #probably because user refreshed treeview pass #release inhibit suspend if self.config.inhibitCookie: self.config.inhibitCookie = tools.unInhibitSuspend(*self.config.inhibitCookie) backintime-1.5.4/qt/statedata.py000066400000000000000000000274221477034762000166200ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2024 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Management of the state file.""" # pylint: disable=wrong-import-position,wrong-import-order from __future__ import annotations import os import json from pathlib import Path from datetime import datetime, timezone from copy import deepcopy from qttools_path import registerBackintimePath registerBackintimePath('common') import singleton # noqa: E402 import logger # noqa: E402 import tools # noqa: E402 from version import __version__ # noqa: E402 class StateData(dict, metaclass=singleton.Singleton): """Manage state data for Back In Time. Dev note (buhtz, 2024-12): It is usually recommended and preferred to derive from `collections.UserDict` instead of just `dict`. But this conflicts with the ``metaclass=``. To my current knowledge this is not a big deal and won't introduce any problems. """ # pylint: disable=too-many-instance-attributes # The default structure. All properties do rely on them and assuming # it is there. _EMPTY_STRUCT = { 'gui': { 'mainwindow': { 'files_view': {}, 'last_path': {}, 'places_sorting': {}, }, 'manage_profiles': { 'incl_sorting': {}, 'excl_sorting': {}, }, 'logview': {}, }, 'message': { 'encfs': {} }, } class Profile: """A surrogate to access profile-specific state data.""" def __init__(self, profile_id: str, state: StateData): self._state = state self._profile_id = profile_id @property def msg_encfs(self) -> int: """Stage of EncFS deprecation warning shown as last.""" try: return self._state['message']['encfs'][self._profile_id] except KeyError: self.msg_encfs = 0 return self.msg_encfs @msg_encfs.setter def msg_encfs(self, val: int) -> None: self._state['message']['encfs'][self._profile_id] = val @property def last_path(self) -> Path: """Last path used in the GUI. Raises: KeyError """ return Path(self._state['gui']['mainwindow'][ 'last_path'][self._profile_id]) @last_path.setter def last_path(self, path: Path) -> None: self._state['gui']['mainwindow'][ 'last_path'][self._profile_id] = str(path) @property def places_sorting(self) -> tuple[int, int]: """Column index and sort order. Returns: Tuple with column index and its sorting order (0=ascending). """ return self._state['gui']['mainwindow'][ 'places_sorting'][self._profile_id] @places_sorting.setter def places_sorting(self, vals: tuple[int, int]) -> None: self._state['gui']['mainwindow'][ 'places_sorting'][self._profile_id] = vals @property def exclude_sorting(self) -> tuple[int, int]: """Column index and sort order. Returns: Tuple with column index and its sorting order (0=ascending). """ return self._state['gui']['manage_profiles'][ 'excl_sorting'][self._profile_id] @exclude_sorting.setter def exclude_sorting(self, vals: tuple[int, int]) -> None: self._state['gui']['manage_profiles'][ 'excl_sorting'][self._profile_id] = vals @property def include_sorting(self) -> tuple[int, int]: """Column index and sort order. Returns: Tuple with column index and its sorting order (0=ascending). """ return self._state['gui']['manage_profiles'][ 'incl_sorting'][self._profile_id] @include_sorting.setter def include_sorting(self, vals: tuple[int, int]) -> None: self._state['gui']['manage_profiles'][ 'incl_sorting'][self._profile_id] = vals @staticmethod def file_path() -> Path: """Returns the state file path.""" xdg_state = os.environ.get('XDG_STATE_HOME', None) if xdg_state: xdg_state = Path(xdg_state) else: xdg_state = Path.home() / '.local' / 'state' fp = xdg_state / 'backintime-qt.json' logger.debug(f'State file path: {fp}') return fp def __init__(self, data: dict = None): """Constructor.""" # default full = deepcopy(self._EMPTY_STRUCT) if data: full = tools.nested_dict_update(full, data) super().__init__(full) def __str__(self): return json.dumps(self, indent=4) def _set_save_meta_data(self): meta = { 'saved': datetime.now().isoformat(), 'saved_utc': datetime.now(timezone.utc).isoformat(), 'bitversion': __version__, } self['_meta'] = meta def save(self): """Store application state data to a file.""" logger.debug('Save state data.') self._set_save_meta_data() fp = self.file_path() fp.parent.mkdir(parents=True, exist_ok=True) with fp.open('w', encoding='utf-8') as handle: handle.write(str(self)) def profile(self, profile_id: str) -> StateData.Profile: """Return a `Profile` object related to the given id. Args: profile_id: A profile_id of a snapshot profile. Returns: A profile surrogate. Raises: KeyError: If profile does not exists. """ return StateData.Profile(profile_id=profile_id, state=self) def manual_starts_countdown(self) -> int: """Countdown value about how often the users started the Back In Time GUI. At the end of the countown the `ApproachTranslatorDialog` is presented to the user. """ return self.get('manual_starts_countdown', 10) def decrement_manual_starts_countdown(self): """Counts down to -1. See :py:func:`manual_starts_countdown()` for details. """ val = self.manual_starts_countdown() if val > -1: self['manual_starts_countdown'] = val - 1 @property def msg_release_candidate(self) -> str: """Last version of Back In Time in which the release candidate message box was displayed. """ try: return self['message']['release_candidate'] except KeyError: self.msg_release_candidate = None return self.msg_release_candidate @msg_release_candidate.setter def msg_release_candidate(self, val: str) -> None: self['message']['release_candidate'] = val @property def msg_encfs_global(self) -> int: """Last stage of global EncFS deprecation message that was shown.""" try: return self['message']['encfs']['global'] except KeyError: self.msg_encfs_global = 0 return self.msg_encfs_global @msg_encfs_global.setter def msg_encfs_global(self, val: int) -> None: self['message']['encfs']['global'] = val @property def mainwindow_show_hidden(self) -> bool: """Show hidden files in files view.""" try: return self['gui']['mainwindow']['show_hidden'] except KeyError: self.mainwindow_show_hidden = False return self.mainwindow_show_hidden @mainwindow_show_hidden.setter def mainwindow_show_hidden(self, val: bool) -> None: self['gui']['mainwindow']['show_hidden'] = val @property def mainwindow_dims(self) -> tuple[int, int]: """Dimensions of the main window. Raises: KeyError """ return self['gui']['mainwindow']['dims'] @mainwindow_dims.setter def mainwindow_dims(self, vals: tuple[int, int]) -> None: self['gui']['mainwindow']['dims'] = vals @property def mainwindow_coords(self) -> tuple[int, int]: """Coordinates (position) of the main window. Raises: KeyError """ return self['gui']['mainwindow']['coords'] @mainwindow_coords.setter def mainwindow_coords(self, vals: tuple[int, int]) -> None: self['gui']['mainwindow']['coords'] = vals @property def logview_dims(self) -> tuple[int, int]: """Dimensions of the log view dialog. Raises: KeyError """ try: return self['gui']['logview']['dims'] except KeyError: self.logview_dims = (800, 500) return self.logview_dims @logview_dims.setter def logview_dims(self, vals: tuple[int, int]) -> None: self['gui']['logview']['dims'] = vals @property def files_view_sorting(self) -> tuple[int, int]: """Column index and sort order. Returns: Tuple with column index and its sorting order (0=ascending). """ try: return self['gui']['mainwindow']['files_view']['sorting'] except KeyError: self.files_view_sorting = (0, 0) return self.files_view_sorting @files_view_sorting.setter def files_view_sorting(self, vals: tuple[int, int]) -> None: self['gui']['mainwindow']['files_view']['sorting'] = vals @property def files_view_col_widths(self) -> tuple: """Widths of columns in the files view.""" return self['gui']['mainwindow']['files_view']['col_widths'] @files_view_col_widths.setter def files_view_col_widths(self, widths: tuple) -> None: self['gui']['mainwindow']['files_view']['col_widths'] = widths @property def mainwindow_main_splitter_widths(self) -> tuple[int, int]: """Left and right width of main splitter in main window. Returns: Two entry tuple with right and left widths. """ try: return self['gui']['mainwindow']['splitter_main_widths'] except KeyError: self.mainwindow_main_splitter_widths = (150, 450) return self.mainwindow_main_splitter_widths @mainwindow_main_splitter_widths.setter def mainwindow_main_splitter_widths(self, vals: tuple[int, int]) -> None: self['gui']['mainwindow']['splitter_main_widths'] = vals @property def mainwindow_second_splitter_widths(self) -> tuple[int, int]: """Left and right width of second splitter in main window. Returns: Two entry tuple with right and left widths. """ try: return self['gui']['mainwindow']['splitter_second_widths'] except KeyError: self.mainwindow_second_splitter_widths = (150, 300) return self.mainwindow_second_splitter_widths @mainwindow_second_splitter_widths.setter def mainwindow_second_splitter_widths(self, vals: tuple[int, int]) -> None: self['gui']['mainwindow']['splitter_second_widths'] = vals @property def toolbar_button_style(self) -> int: """Style of icons for the main toolbar. Returns: Style value as integer (default: 0 as ``ToolButtonIconOnly``) """ try: return self['gui']['mainwindow']['toolbar_button_style'] except KeyError: self.toolbar_button_style = 0 return self.toolbar_button_style @toolbar_button_style.setter def toolbar_button_style(self, value) -> None: self['gui']['mainwindow']['toolbar_button_style'] = value backintime-1.5.4/qt/test/000077500000000000000000000000001477034762000152445ustar00rootroot00000000000000backintime-1.5.4/qt/test/__init__.py000066400000000000000000000000001477034762000173430ustar00rootroot00000000000000backintime-1.5.4/qt/test/test_lint.py000066400000000000000000000275011477034762000176300ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """Tests using several linters. See file common/test/test_lint.py for details. """ import unittest import os import pathlib import subprocess import shutil from typing import Iterable from packaging import version BASE_REASON = ('Using package {0} is mandatory on TravisCI, on ' 'other systems it runs only if `{0}` is available.') ON_TRAVIS = os.environ.get('TRAVIS', '') == 'true' TRAVIS_REASON = ('Running linter tests is mandatory on TravisCI only. On ' 'other machines they will run only if linters available.') PYLINT_AVAILABLE = shutil.which('pylint') is not None RUFF_AVAILABLE = shutil.which('ruff') is not None FLAKE8_AVAILABLE = shutil.which('flake8') is not None ANY_LINTER_AVAILABLE = any(( PYLINT_AVAILABLE, RUFF_AVAILABLE, FLAKE8_AVAILABLE, )) # "qt" directory _base_dir = pathlib.Path(__file__).resolve().parent.parent # Files in this lists will get the full battery of linters and rule sets. full_test_files = [_base_dir / fp for fp in ( 'aboutdlg.py', 'encfsmsgbox.py', 'manageprofiles/combobox.py', 'manageprofiles/statebindcheckbox.py', 'manageprofiles/schedulewidget.py', 'manageprofiles/sshproxywidget.py', 'plugins/notifyplugin.py', 'statedata.py', 'test/test_lint.py', 'test/test_statedata.py', 'usermessagedialog.py', )] # Not all linters do respect PEP8 (e.g. ruff, PyLint) PEP8_MAX_LINE_LENGTH = 79 def create_pylint_cmd(include_error_codes=None): """Create the pylint base command for later use with subprocess.run(). Args: include_error_codes: List of exclusive rules to check for. If empty all default rules are checked. """ cmd = [ 'pylint', # Make sure BIT modules can be imported (to detect "no-member") '--init-hook=import sys;' 'sys.path.insert(0, "./../qt");' 'sys.path.insert(0, "./../common");', # Storing results in a pickle file is unnecessary '--persistent=n', # autodetec number of parallel jobs '--jobs=0', # Disable scoring ("Your code has been rated at xx/10") '--score=n', # prevent false-positive no-module-member errors '--extension-pkg-allow-list=PyQt6,PyQt6.QtCore', # Because of globally installed GNU gettext functions '--additional-builtins=_,ngettext', # PEP8 conform line length (see PyLint Issue #3078) f'--max-line-length={PEP8_MAX_LINE_LENGTH}', # Whitelist variable names '--good-names=idx,fp', # '--reports=yes', ] if include_error_codes: # Deactivate all checks by default cmd.append('--disable=all') # Include specific codes only cmd.append('--enable=' + ','.join(include_error_codes)) return cmd @unittest.skipUnless(ON_TRAVIS or ANY_LINTER_AVAILABLE, TRAVIS_REASON) class MirrorMirrorOnTheWall(unittest.TestCase): """Check all py-files in the package (incl. test files) for lints, potential bugs and if they are compliant to the coding styles (e.g. PEP8). """ @classmethod def _collect_py_files(cls) -> Iterable[pathlib.Path]: """All py-files related to that distribution package. Dev note (2023-11): Use package metadata after migration to pyproject.toml. """ path = pathlib.Path.cwd() # Make sure we are inside the test folder if path.name in ['qt', 'common']: # happens e.g. on TravisCI path = path / 'test' if not path.name.startswith('test'): raise RuntimeError('Something went wrong. The test should run ' 'inside the test folder but the current folder ' f'is {path}.') # Workaround path = path.parent # Find recursive all py-files. py_files = path.rglob('*.py') # Exclude full test files return filter(lambda fp: fp not in full_test_files, py_files) @classmethod def setUpClass(cls): cls.collected_py_files = cls._collect_py_files() def test005_ensure_linter_versions(self): """Workaround to ensure the correct linter versions are used. For sure there are better ways to solve this. But migration to a standard python package format need to be done first. See #1575. Until then this test will spare some hours of work, e.g. fixing linter errors (from out-dated linters) that are not relevant anymore in modern lintern versions. Another location where linter versions are relevant is CONTRIBUTING.md. """ if PYLINT_AVAILABLE: version_target = version.parse('3.3.0') proc = subprocess.run( ['pylint', '--version'], capture_output=True, text=True, check=True) version_string = proc.stdout.split('\n')[0].replace('pylint ', '') version_actual = version.parse(version_string) self.assertTrue( version_actual >= version_target, f'PyLint version is {version_actual} but need to ' f'be {version_target} or higher.') if RUFF_AVAILABLE: version_target = version.parse('0.6.0') proc = subprocess.run( ['ruff', '--version'], capture_output=True, text=True, check=True) version_string = proc.stdout.split('\n')[0].replace('ruff ', '') version_actual = version.parse(version_string) self.assertTrue( version_actual >= version_target, f'Ruff version is {version_actual} but need to ' f'be {version_target} or higher.') @unittest.skipUnless(RUFF_AVAILABLE, BASE_REASON.format('ruff')) def test010_ruff_default_ruleset(self): """Ruff in default mode.""" # ATTENTIION: Some settings are found in pyproject.toml cmd = [ 'ruff', 'check', # Additionally activate subset of special rules: # - PyLint (PL) # - PyCodestyle (E, W) # - flake8-gettext (INT) # - useless noqua (RUF100) '--extend-select=PL,E,W,INT,RUF100', # Ignore: redefined-loop-name '--ignore=PLW2901', '--line-length', str(PEP8_MAX_LINE_LENGTH), # Because of globally installed GNU gettext functions '--config', 'builtins=["_", "ngettext"]', # Ruff counting branches different from PyLint. # See: '--config', 'pylint.max-branches=13', '--config', 'flake8-quotes.inline-quotes = "single"', # one error per line (no context lines) '--output-format=concise', '--quiet', ] cmd.extend(full_test_files) proc = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True ) # No errors other then linter rules self.assertIn(proc.returncode, [0, 1], proc.stderr) error_n = len(proc.stdout.splitlines()) if error_n > 0: print(proc.stdout) self.assertEqual(0, error_n, f'Ruff found {error_n} problem(s).') # any other errors? self.assertEqual(proc.stderr, '') @unittest.skipUnless(FLAKE8_AVAILABLE, BASE_REASON.format('flake8')) def test020_flake8_default_ruleset(self): """Flake8 in default mode.""" cmd = [ 'flake8', f'--max-line-length={PEP8_MAX_LINE_LENGTH}', '--builtins=_,ngettext', # '--enable-extensions=' ] cmd.extend(full_test_files) proc = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True ) error_n = len(proc.stdout.splitlines()) if error_n > 0: print(proc.stdout) self.assertEqual(0, error_n, f'Flake8 found {error_n} problem(s).') # any other errors? self.assertEqual(proc.stderr, '') @unittest.skipUnless(PYLINT_AVAILABLE, BASE_REASON.format('PyLint')) def test030_pylint_default_ruleset(self): """Use Pylint with all default rules to check specific files. """ cmd = create_pylint_cmd() # Add py-files cmd.extend(full_test_files) r = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True) # Count lines except module headings error_n = len(list(filter(lambda line: not line.startswith('*****'), r.stdout.splitlines()))) print(r.stdout) self.assertEqual(0, error_n, f'PyLint found {error_n} problems.') # any other errors? self.assertEqual(r.stderr, '') @unittest.skipUnless(PYLINT_AVAILABLE, BASE_REASON.format('PyLint')) def test050_pylint_exclusive_ruleset(self): """Use Pylint to check for specific rules only. Some facts about PyLint - It is one of the slowest available linters. - It is able to catch lints other linters miss. """ # Explicit activate checks err_codes = [ 'C0305', # trailing-newlines 'C0325', # superfluous-parens 'C0410', # multiple-imports 'C0303', # trailing-whitespace 'E0100', # init-is-generator 'E0101', # return-in-init 'E0102', # function-redefined 'E0103', # not-in-loop 'E0106', # return-arg-in-generator 'E0213', # no-self-argument 'E0401', # import-error 'E0602', # undefined-variable 'E1101', # no-member 'I0021', # useless-suppression 'W0311', # bad-indentation 'W0611', # unused-import 'W1301', # unused-format-string-key 'W1401', # anomalous-backslash-in-string (invalid escape sequence) 'W1515', # forgotten-debug-statement # Enable asap. This list is selection of existing (not all!) # problems currently exiting in the BIT code base. Quit easy to fix # because there count is low. # 'R0202', # no-classmethod-decorator # 'R0203', # no-staticmethod-decorator 'R0801', # duplicate-code # 'W0123', # eval-used # 'W0237', # arguments-renamed # 'W0221', # arguments-differ # 'W0404', # reimported # 'W4902', # deprecated-method # 'W4904', # deprecated-class # 'W0603', # global-statement # 'W0614', # unused-wildcard-import # 'W0611', # unused-import # 'W0612', # unused-variable # 'W0707', # raise-missing-from ] cmd = create_pylint_cmd(err_codes) # Add py-files cmd.extend(self._collect_py_files()) r = subprocess.run( cmd, check=False, universal_newlines=True, capture_output=True) # Count lines except module headings and output about duplicate code error_n = len(list(filter( lambda line: line[:2] not in ('**', ' ', '==', ' (', ''), r.stdout.splitlines()))) print(r.stdout) self.assertEqual(0, error_n, f'PyLint found {error_n} problems.') # any other errors? self.assertEqual(r.stderr, '') backintime-1.5.4/qt/test/test_statedata.py000066400000000000000000000060231477034762000206300ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2025 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Tests about statefile module.""" # pylint: disable=wrong-import-position,wrong-import-order import unittest from qttools_path import registerBackintimePath registerBackintimePath('common') import statedata # noqa: E402 class IsSingleton(unittest.TestCase): """StateData instance is a singleton.""" @classmethod def tearDownClass(cls): # Delete existing StateData instance try: # pylint: disable-next=protected-access del statedata.StateData._instances[statedata.StateData] except KeyError: pass def setUp(self): # Clean up all instances try: # pylint: disable-next=protected-access del statedata.StateData._instances[statedata.StateData] except KeyError: pass def test_identity(self): """Identical identity.""" one = statedata.StateData() two = statedata.StateData() self.assertEqual(id(one), id(two)) def test_content(self): """Identical values.""" one = statedata.StateData() two = statedata.StateData() one['foobar'] = 7 self.assertEqual(one, two) class Properties(unittest.TestCase): """Property access without errors.""" @classmethod def tearDownClass(cls): # Delete existing StateData instance try: # pylint: disable-next=protected-access del statedata.StateData._instances[statedata.StateData] except KeyError: pass def setUp(self): # Delete existing StateData instance try: # pylint: disable-next=protected-access del statedata.StateData._instances[statedata.StateData] except KeyError: pass def test_read_empty_global(self): """Read properties from empty state data""" sut = statedata.StateData() self.assertEqual(sut.msg_release_candidate, None) self.assertEqual(sut.msg_encfs_global, False) self.assertEqual(sut.mainwindow_show_hidden, False) self.assertEqual(sut.files_view_sorting, (0, 0)) self.assertEqual(sut.mainwindow_main_splitter_widths, (150, 450)) self.assertEqual(sut.mainwindow_second_splitter_widths, (150, 300)) with self.assertRaises(KeyError): # pylint: disable=pointless-statement sut.mainwindow_coords sut.mainwindow_dims sut.logview_dims sut.files_view_col_widths def test_profile_not_exist(self): """Profile does not exists.""" sut = statedata.StateData() profile = sut.profile(42) with self.assertRaises(KeyError): # pylint: disable=pointless-statement profile.last_path backintime-1.5.4/qt/usermessagedialog.py000066400000000000000000000057241477034762000203520ustar00rootroot00000000000000# SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In Time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . """Module about UserMessageDialog""" from PyQt6.QtCore import Qt, QSize, QTimer from PyQt6.QtGui import QCursor from PyQt6.QtWidgets import (QDialog, QLayout, QVBoxLayout, QDialogButtonBox, QLabel, QToolTip, QWidget) class UserMessageDialog(QDialog): """Present a large messages to the users with extra features. Different from QMessageBox this dialog is intended to display large amount of text. The dialog is able to wrap the text while being resized. Hyperlinks in this text do display their URL as tooltip. HTML tags supported because of Qt rich text feature. Text between Newline characters ``\n`` will be converted into ``

`` paragraphs. """ def __init__(self, parent: QWidget, title: str, full_label: str): super().__init__(parent) # screen_width = QApplication.primaryScreen().size().width() # min_width = 300 if screen_width <= 1080 else 450 self.setMinimumWidth(400) self.setWindowTitle(title) self.setWindowFlag(Qt.WindowType.WindowMaximizeButtonHint, True) # Wrap paragraphs in

tags. if '\n' in full_label: result = '' for t in full_label.split('\n'): result = f'{result}

{t}

' else: result = full_label widget = QLabel(result, self) widget.setWordWrap(True) widget.setOpenExternalLinks(True) widget.linkHovered.connect(self.slot_link_hovered) button = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok, self) button.clicked.connect(self.accept) layout = QVBoxLayout(self) layout.addWidget(widget) layout.addWidget(button) self._fix_size() def _fix_size(self): """The dialog is resized so it fits the content of the QLabel. Credits: https://stackoverflow.com/a/77012305/4865723 """ best = QLayout.closestAcceptableSize(self, QSize(self.width(), 1)) if self.height() < best.height(): self.resize(best) def resizeEvent(self, event): # pylint: disable=invalid-name """See `_fixSize()` for details.""" super().resizeEvent(event) if event.oldSize().width() != event.size().width(): QTimer.singleShot(0, self._fix_size) elif event.spontaneous(): self._fix_size() def slot_link_hovered(self, url): """Show URL in tooltip without anoing http-protocol prefixf.""" QToolTip.showText(QCursor.pos(), url.replace('https://', '')) backintime-1.5.4/update_language_files.py000077500000000000000000000560641477034762000205400ustar00rootroot00000000000000#!/usr/bin/env python3 # SPDX-FileCopyrightText: © 2023 Christian BUHTZ # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See file/folder LICENSE or go to # . """This helper script does manage transferring translations to and from the translation platform (currently Weblate). """ import sys import datetime import re import tempfile import string import shutil from pathlib import Path from subprocess import run, check_output from common import languages try: import polib print(f'polib version: {polib.__version__}') except ImportError: # pylint: disable-next=raise-missing-from raise ImportError('Can not import package "polib". Please install it.') # In usual GNU gettext environments it would be "locale" (sometimes plurarl # "locales") LOCAL_DIR = Path('common') / 'po' TEMPLATE_PO = LOCAL_DIR / 'messages.pot' LANGUAGE_NAMES_PY = Path('common') / 'languages.py' WEBLATE_URL = 'https://translate.codeberg.org/git/backintime/common' PACKAGE_NAME = 'Back In Time' PACKAGE_VERSION = Path('VERSION').read_text('utf-8').strip() BUG_ADDRESS = 'https://github.com/bit-team/backintime' # RegEx pattern: Character & followed by a word character (extract as group) REX_SHORTCUT_LETTER = re.compile(r'&(\w)') def dict_as_code(a_dict: dict, indent_level: int) -> list[str]: """Convert a (nested) Python dict into its PEP8 conform as-in-code representation. """ tab = ' ' * 4 * indent_level result = [] for key in a_dict: # single quotes? quote_key = "'" if isinstance(key, str) else "" quote_val = "'" if isinstance(a_dict[key], str) else "" # A nested dict if isinstance(a_dict[key], dict): result.append(f"{tab}{quote_key}{key}{quote_key}: {{") result.extend( dict_as_code(a_dict[key], indent_level+1)) result.append(f"{tab}}},") continue # Regular key: value pair result.append(f"{tab}{quote_key}{key}{quote_key}: " f"{quote_val}{a_dict[key]}{quote_val},") return result def update_po_template(): """The po template file is update via `xgettext`. All files with extension `*.py` are scanned for translatable strings. Unittest files and folders are excluded. xgettext is used instead of pygettext because the latter is deprecated since xgettext is able to handle Python files. """ print(f'Updating PO template file "{TEMPLATE_PO}" …') # Recursive search of Python files excluding unittest files and folders find_cmd = [ 'find', # folders to search in 'common', 'qt', # look for py-files '-name', '*.py', # exclude files/folders related to unittests '-not', '-name', 'test_*', '-not', '-path', '*/test/*', '-not', '-path', '*/tests/*' ] print(f'Execute "{find_cmd}".') py_files = check_output(find_cmd, text=True).split() print('Scan following files for translatable strings:\n{}' .format('\n'.join(py_files))) cmd = [ 'xgettext', '--verbose', '--language=Python', f'--package-name="{PACKAGE_NAME}"', f'--package-version="{PACKAGE_VERSION}"', f'--msgid-bugs-address={BUG_ADDRESS}', f'--output={TEMPLATE_PO}', '--sort-by-file', # '--sort-output', ] cmd.extend(py_files) print(f'Execute "{cmd}".') run(cmd, check=True) def update_po_language_files(remove_obsolete_entries: bool = False): """The po files are updated with the source strings from the pot-file (the template for each po-file). The GNU gettext utility ``msgmerge`` is used for that. The function `update_po_template()` should be called before. """ print( 'Update language (po) files' + ' and remove obsolete entries' if remove_obsolete_entries else '' ) # Recursive all po-files for po_path in LOCAL_DIR.rglob('**/*.po'): lang = po_path.stem cmd = [ 'msgmerge', '--verbose', f'--lang={lang}', '--update', '--sort-by-file', '--backup=off', # don't create *.po~ files f'{po_path}', f'{TEMPLATE_PO}' ] run(cmd, check=True) if remove_obsolete_entries: # remove obsolete entries ("#~ msgid) cmd = [ 'msgattrib', '--no-obsolete', f'--output-file={po_path}', f'{po_path}' ] run(cmd, check=True) def check_existence(): """Check for existence of essential files. Returns: Nothing if everything is fine. Raises: FileNotFoundError """ paths_to_check = [ LOCAL_DIR, TEMPLATE_PO ] for file_path in paths_to_check: if not file_path.exists(): raise FileNotFoundError(file_path) def update_from_weblate(): """Translations done on Weblate platform are integrated back into the repository. The Weblate translations live on https://translate.codeberg.org and has its own internal git repository. This repository is cloned and the po-files copied into the current local (upstream) repository. See comments in code about further details. """ tmp_dir = tempfile.mkdtemp() # "Clone" weblate repo into a temporary folder. # The folder is kept (nearly) empty. No files are transferred except # the hidden ".git" folder. cmd = [ 'git', 'clone', '--no-checkout', WEBLATE_URL, tmp_dir ] print(f'Execute "{cmd}".') run(cmd, check=True) # Now checkout po-files from that temporary repository but redirect # them into the current folder (which is our local upstream repo) instead # of the temporary repositories folder. cmd = [ 'git', # Use temporary/Weblate repo as checkout source '--git-dir', f'{tmp_dir}/.git', 'checkout', # branch 'dev', '--', 'common/po/*.po' ] print(f'Execute "{cmd}".') run(cmd, check=True) shutil.rmtree(tmp_dir, ignore_errors=True) def check_syntax_of_po_files(): """Check all po files of known syntax violations. """ # Match every character except open/closing curly brackets rex_reduce = re.compile(r'[^\{\}]') # Match every pair of curly brackets rex_curly_pair = re.compile(r'\{\}') # Extract placeholder/variable names rex_names = re.compile(r'\{(.*?)\}') def _curly_brackets_balanced(to_check): """Check if curly brackes for variable placeholders are balanced.""" # Remove all characters that are not curly brackets reduced = rex_reduce.sub('', to_check) # Remove valid pairs of curly brackets invalid = rex_curly_pair.sub('', reduced) # Catch nested curly brackest like this # "{{{}}}", "{{}}" # This is valid Python code and won't cause Exceptions. So errors here # might be false negative. But despite rare cases where this might be # used it is a high possibility that there is a typo in the translated # string. BIT won't use constructs like this in strings, so it is # handled as an error. if rex_curly_pair.findall(invalid): print(f'\nERROR ({lang_code}): Curly brackets nested: {to_check}') return False if invalid: print(f'\nERROR ({lang_code}): Curly brackets not balanced : {to_check}') return False return True def _other_errors(to_check): """Check if there are any other errors that could be thrown via printing this string.""" try: # That is how print() internally parse placeholders and other # things. list(string.Formatter().parse(format_string=to_check)) except Exception as exc: # pylint: disable=broad-exception-caught print(f'\nERROR ({lang_code}): {exc} in translation: {to_check}') return False return True def _place_holders(trans_string, src_string, tcomments): """Check if the placeholders between original source string and the translated string are identical. Order is ignored. To disable this check for a specific string add the translation comment(!) on top of the entry in the po file like this: # ignore-placeholder-compare #: qt/app.py:1961 #, python-brace-format msgid "foo" msgstr "bar" Keep in mind that this is a regular comment. It is not a flag (``#, ``) or a user defined flag (``#. ``). The later two are removed by msgmerge when updating the po files from the pot file. """ if 'ignore-placeholder-compare' in tcomments: return True flagmsg = 'To disable this check add the comment (not flag!) on ' \ 'top of the entry in the po-file: ' \ '"# ignore-placeholder-compare"' # Compare number of curly brackets. for bracket in tuple('{}'): if src_string.count(bracket) != trans_string.count(bracket): print(f'\nERROR ({lang_code}): Number of "{bracket}" between ' 'original source and translated string is different.\n' f'\nTranslation: {trans_string}\n\n{flagmsg}') return False # Compare variable names org_names = rex_names.findall(src_string) trans_names = rex_names.findall(trans_string) if sorted(org_names) != sorted(trans_names): print(f'\nERROR ({lang_code}): Names of placeholders between ' 'original source and translated string are different.\n' f'\nNames in original : {org_names}\n' f'\nNames in translation : {trans_names}\n' f'\nFull translation: {trans_string}\n{flagmsg}') return False return True print('Checking syntax of po files…') # Each po file for po_path in all_po_files_in_local_dir(): error_count = 0 # Language code determined by po-filename lang_code = po_path.with_suffix('').name # print(f'{lang_code}', end=' ') pof = polib.pofile(po_path) # Each translated entry for entry in pof.translated_entries(): # Plural form? if entry.msgstr_plural or entry.msgid_plural: # Ignoring plural form because this is to complex, not logical # in all cases and also not worth the effort. continue if (not _curly_brackets_balanced(entry.msgstr) or not _other_errors(entry.msgstr) or not _place_holders(entry.msgstr, entry.msgid, entry.tcomment)): print(f'\nSource string: {entry.msgid}\n') error_count += 1 if error_count: print(f' {lang_code} >> {error_count} errors') else: print(f' {lang_code} >> OK') print('') def all_po_files_in_local_dir(): """All po files (recursive).""" return LOCAL_DIR.rglob('**/*.po') def create_completeness_dict(): """Create a simple dictionary indexed by language code and value that indicate the completeness of the translation in percent. """ print('Calculate completeness for each language in percent…') result = {} # each po file in the repository for po_path in all_po_files_in_local_dir(): pof = polib.pofile(po_path) result[po_path.stem] = pof.percent_translated() pof.save() # "en" is the source language result['en'] = 100 # info # print(json.dumps(result, indent=4)) return result def create_languages_file(): """Create the languages.py file containing language names and the completeness of their translation. See the following functions for further details. - ``update_language_names()`` - ``create_completeness_dict()`` """ # Convert language names dict to python code as a string names_dict = update_language_names() content = ['names = {'] content.extend(dict_as_code(names_dict, 1)) content.append('}') # the same with completeness dict compl_dict = create_completeness_dict() content.append('') content.append('') content.append('completeness = {') content.extend(dict_as_code(compl_dict, 1)) content.append('}') with LANGUAGE_NAMES_PY.open('w', encoding='utf8') as handle: date_now = datetime.datetime.now().strftime('%c') handle.write(get_spdx_metadata_lines()) handle.write( f'#\n# Generated at {date_now} with help\n# of package "babel" ' 'and "polib".\n') handle.write('# https://babel.pocoo.org\n') handle.write('# https://github.com/python-babel/babel\n') handle.write( '# pylint: disable=too-many-lines,missing-module-docstring\n') handle.write('\n'.join(content)) handle.write('\n') print(f'Result written to {LANGUAGE_NAMES_PY}.') # Completeness statistics (English is excluded) compl = list(compl_dict.values()) compl.remove(100) # exclude English statistic = { 'compl': round(sum(compl) / len(compl)), 'n': len(compl), '99_100': len(list(filter(lambda val: val >= 99, compl))), '90_98': len(list(filter(lambda val: 90 <= val < 99, compl))), '50_89': len(list(filter(lambda val: 50 <= val <= 89, compl))), 'lt50': len(list(filter(lambda val: val < 50, compl))) } print('STATISTICS') print(f'\tTotal completeness: {statistic["compl"]}%') print(f'\tNumber of languages (excl. English): {statistic["n"]}') print(f'\t100-99% complete: {statistic["99_100"]} languages') print(f'\t90-98% complete: {statistic["90_98"]} languages') print(f'\t50-89% complete: {statistic["50_89"]} languages') print(f'\tless than 50% complete: {statistic["lt50"]} languages') def create_language_names_dict(language_codes: list) -> dict: """Create dict of language names in different flavors. The dict is used in the LanguageDialog to display the name of each language in the UI's current language and the language's own native representation. """ # We keep this import local because it is a rare case that this function # will be called. This happens only if a new language is added to BIT. try: # pylint: disable-next=import-outside-toplevel import babel except ImportError as exc: raise ImportError( 'Can not import package "babel". Please install it.') from exc # Babel minimum version (because language code "ie") from packaging.version import Version if Version(babel.__version__) < Version('2.15'): raise ImportError( f'Babel version 2.15 required. But {babel.__version__} ' 'is installed.') # Source language (English) should be included if 'en' not in language_codes: language_codes.append('en') # Don't use defaultdict because pprint can't handle it result = {} for code in sorted(language_codes): print(f'Processing language code "{code}"…') lang = babel.Locale.parse(code) result[code] = {} # Native name of the language # e.g. 日本語 result[code]['_native'] = lang.get_display_name(code) # Name of the language in all other foreign languages # e.g. Japanese, Japanisch, ... for foreign in language_codes: result[code][foreign] = lang.get_display_name(foreign) return result def update_language_names() -> dict: """See `create_language_names_dict() for details.""" # Languages code based on the existing po-files langs = [po_path.stem for po_path in LOCAL_DIR.rglob('**/*.po')] # Some languages missing in the list of language names? try: missing_langs = set(langs) - set(languages.names) except AttributeError: # Under circumstances the languages file is empty missing_langs = ['foo'] if missing_langs: print('Create new language name list because of missing ' f'languages: {missing_langs}') return create_language_names_dict(langs) return languages.names def get_shortcut_entries(po_file: polib.POFile) -> list[polib.POEntry]: """Return list of po-file entries using a shortcut indicator ("&") and are not obsolete. """ result = filter(lambda entry: entry.obsolete == 0 and REX_SHORTCUT_LETTER.search(entry.msgid), po_file) return list(result) def get_shortcut_groups() -> dict[str, list]: """Return the currently used "shortcut groups" and validate if they are up to date with the source strings in "messages.pot". Returns: A dictionarie indexed by group names with list of source strings. Raises: ValueError: If the shortcut indicator using source strings are modified. """ # Get all entries using a shortcut indicator real = get_shortcut_entries(polib.pofile(TEMPLATE_PO)) # Reduce to their source strings real = [entry.msgid for entry in real] # Later this list is sliced into multiple groups expect = [ # Main window (menu bar) '&Backup', '&Restore', '&Help', # Manage profiles dialog (tabs) '&General', '&Include', '&Exclude', '&Remove & Retention', '&Options', 'Back In &Time', 'E&xpert Options', ] # Plausibility check: # Difference between the real and expected strings indicate # modifications in the GUI and in the shortcut groups. if not sorted(real) == sorted(expect): # This will happen when the source strings are somehow modified or # some strings add or removed. # SOLUTION: Look again into the GUI and its commit history what was # modified. Update the "expect" list to it. raise ValueError( f'Source strings with GUI shortcuts in {TEMPLATE_PO} are not as ' 'expected.\n' f' Expected: {sorted(expect)}\n' f' Real: {sorted(real)}') # WORKAROUND # This source string is not a translateble string but has a shortcut # letter. # Dev note: From point of view of the translators it might make sense # making that string translatable also. But then we risk that our projects # name is translated for real. expect = ['Back In &Time'] + expect return {'mainwindow': expect[:4], 'manageprofile': expect[4:]} def check_shortcuts(): """Check for redundant used letters as shortcut indicators in translated GUI strings. Keyboard shortcuts are indicated via the & in front of a character in a GUI string (e.g. a button or tab). For example "B&ackup" can be activated with pressing ALT+A. As another example the strings '&Exclude' and '&Export' used in the same area of the GUI won't work because both of them indicate the 'E' as a shortcut. They need to be unique. These situation can happen in translated strings in most cases translators are not aware of that feature or problem. It is nearly impossible to control this on the level of the translation platform. """ groups = get_shortcut_groups() # each po file in the repository for po_path in list(LOCAL_DIR.rglob('**/*.po')): print(f'******* {po_path} *******') # Remember shortcut relevant entries. real = {key: [] for key in groups} # # WORKAROUND. See get_shortcut_groups() for details. # real['mainwindow'].append('Back In &Time') # Entries using shortcut indicators shortcut_entries = get_shortcut_entries(polib.pofile(po_path)) # Group the entries to their shortcut groups for entry in shortcut_entries: for groupname in real: if entry.msgid in groups[groupname]: real[groupname].append(entry.msgstr) # Each shortcut group... for groupname in real: # All shortcut letters used in that group letters = '' # Collect letters for trans in real[groupname]: try: letters = letters \ + REX_SHORTCUT_LETTER.search(trans).groups()[0] except AttributeError: pass # Redundant shortcuts? set() do remove duplicates if len(letters) > len(set(letters)): err_msg = f'Maybe redundant shortcuts in "{po_path}".' # Missing shortcuts in translated strings? if len(letters) < len(real[groupname]): err_msg = err_msg + ' Maybe missing ones.' err_msg = f'{err_msg} Please take a look.\n' \ f' Group: {groupname}\n' \ f' Source: {groups[groupname]}\n' \ f' Translation: {real[groupname]}' print(err_msg) def get_spdx_metadata_lines() -> str: """Extract the SPDX meta data lines from the current source file.""" result = '' with Path(__file__).open('r') as handle: for line in handle: # ignore shebang if line.startswith('#!'): continue # stop if line.startswith('"""') or line.startswith('import'): break result = result + line return result if __name__ == '__main__': check_existence() FIN_MSG = 'Please check the result via "git diff" before committing.' # Scan python source files for translatable strings if 'source' in sys.argv: update_po_template() update_po_language_files('--remove-obsolete-entries' in sys.argv) create_languages_file() print(FIN_MSG) sys.exit() # Download translations (as po-files) from Weblate and integrate them # into the repository. if 'weblate' in sys.argv: update_from_weblate() check_syntax_of_po_files() create_languages_file() print(FIN_MSG) sys.exit() # Check for redundant &-shortcuts if 'shortcuts' in sys.argv: check_shortcuts() sys.exit() # Check for syntax problems (also implicit called via "weblate") if 'syntax' in sys.argv: check_syntax_of_po_files() sys.exit() print('Use one of the following argument keywords:\n' ' source - Update the pot and po files with translatable ' 'strings extracted from py files. (Prepare upload to Weblate). ' 'Optional use --remove-obsolete-entries\n' ' weblate - Update the po files with translations from ' 'external translation service Weblate. (Download from Weblate)\n' ' shortcut - Check po files for redundant keyboard shortcuts ' 'using "&"\n' ' syntax - Check syntax of po files. (Also done via "weblate" ' 'command)') sys.exit(1) backintime-1.5.4/updateversion.sh000077500000000000000000000054131477034762000170730ustar00rootroot00000000000000#!/bin/bash # SPDX-FileCopyrightText: © 2008 Oprea Dan # SPDX-FileCopyrightText: © 2012 Germar Reitze # SPDX-FileCopyrightText: © 2022 Jürgen Altfeld (aryoda) # SPDX-FileCopyrightText: © 2023 Christian Buhtz # # SPDX-License-Identifier: GPL-2.0-or-later # # This file is part of the program "Back In time" which is released under GNU # General Public License v2 (GPLv2). See LICENSES directory or go to # . # Updates all version numbers using the VERSION file # and creates a new DEBIAN changelog file for this version # by extracting the changes of this version from the # CHANGES file. # # Development notes (May '23, Buhtz): # Should be treated as a workaround that will get replaced in the future. # Handling of version numbers and other package metadata can be done very # elegant and centralized within the Python Packaging process (e.g. using # pyproject.toml and additional tools. # Handling of Debian (and PPA) related stuff will be separated from that # upstream repo because it is distro specific. # Outdated TODOs: # TODO Requires refactoring and adjustments to separate # - the update of version numbers # - from the preparation of a new DEBIAN package release # since version updates must be possible without # a DEBIAN package release. # # TODO The version number must still be maintained in two places # (despite this script): # 1. File "VERSION" # 2. As headline in the file "CHANGES" # If those two numbers do not match the script does # not extract the correct changes of the version from the CHANGES file. # # TODO The name of this script file is misleading (find a better one) # TODO Make sure this script works idempotent (multiple calls = same result) # TODO This script does not update release dates scattered around in # different files (eg. common/man/C/backintime.1 line 1) VERSION=`cat VERSION` if [[ $VERSION == *-dev ]] then VERSION+="."`git rev-parse --short HEAD` fi echo VERSION: $VERSION MAINTAINER="Germar Reitze " # MAINTAINER="BIT Team " # MAINTAINER="BIT Team " update_app_version () { echo "Update '$1'" sed -e "s/^\(\s*\)__version__ = '.*'$/\1__version__ = '$VERSION'/" \ -i $1 } update_man_page () { echo "Update '$1'" sed -e "s/\.TH\(.*\)\"version\([^\"]*\)\"\(.*\)$/.TH\1\"version $VERSION\"\3/" \ -i $1 } update_omf () { echo "Update '$1'" sed -e "s/^\([ \]*\)

,9G&Ƶrڴsv7w2U: A1NR(&,&/C[rJR"BGO2#(c5i4*y )${)VwT=ypF%]l)=uHxL<3^#avVX+Eoe*گ,tϺӤUQ/d{I}?5?7;[c$iɫ/#^5HY[k3QA+8HYZx\=mȏB3١~e:~Wh<GuF;XYw'#ye}Cc-w3#PI7v^2B_t(;o)ˆg*N) .C,1 mꬢ,kG?/_-w~z~JF%6B*ZI«Hpc%PSڿ#ʰ+=-;4ugPwFPbERC0DAP~{P`35gAv=t5f3wW,e6R!Jǃ zJ_eP*Q9(.& xHC IH%!}jѹ3*곩ON]-aSefߊ܊1O63 ^AIS͵Ui(ڱ{- F Ҁc*5mFp.U!Jzۖ`3SP#|BY^ZQG(s*GVڮ뙝ޡ;tWg#б%l0ĎgjSU_xz69XlzWy8C)i{v>3Qc9R]={yQr-CyS) '+TDb1IYůո1}Qee ("ikȎQ?kaZW?Ν౹4s=0%sCS^?;4b}zlInJy<~\W]Ci aq~c35NX31'E|/58@Y>kɳ>tP@Y@YeeP@Y@YeePP@Y@Yeل1rq9dpr(o,k+ݾ *jop~(o,Z8ߩM5j|bF;n\)Nc.=s!m5c7[|˾eO/x{W~JfUe鵚_P):,~T NW$&'k޻r̀$@f>Gɕ=y߹}}PBS?5QfG.YMƴ= %>ԒvȔ;'ͭl/ Xhx\W$xo #/9 l"+{։HD=,/Plg_ g2ŕ?ĹoBWpsw| |zeyǃJSb])Cyu.9(,Ezg$pM@)&?ӷyb!yotjalis9fW^8˼}lpi]u+3O'e֎9_YU#1_e'[;l$-IO8qEbw>;$UMȿ:Is {Yq( ->Ĥ~SGD´Iv&1]mInQu8g$6'Kݏ_-֮a[ʲ8!logwe4K2'[Bu Sy7ĦEm>h ݳA]xu B)b؈o'3ҷ=,`}2=2,O]V~SLlj|⢲Nf0u>rlJY8!\9б%  ee~Jơ,%Pzh8V1 N 9:\@c_v(5;YHTVTe:giR*R~5i4*y [%vdv~nv^oW YzxdL#}V/Ӣy,xA*ÌUg2_(L$E~+.VT"ΩW]}Qu۽>:]V6QT?mSjdlnBЌ HE(%:շY@/QiT]oJJ? , ,{ Hx|tjjK6$õ G;^>0)wQfzP%}Y|heqy^^Ǔr1M{;]g;j1~0J}:ܫ, iTTq.ay!ӎjO gS$9:/tDY7u||{}~LVUP'.eS1<99a51t՗rR:an ډ elKY 0*Km( +03K x(u8 PDLP_y|+ij$5|SwXrǡ.Ws[&yC̣z`ww{%Wx|whgIʆ ϻX}r[|97l_N2.A4(fɓ\:ţBPJ{X(/ESC'*8U(mAFG%"ŷ x6_xM쩶 TJ~|C-6k 8wCcG7tEZ#5J S\V{( Sԫ|wNOYH|]~:M94hzKYfkzGfF[.>PY0 FGTc3:{( 陠F#|K90M+ WVvEq$0nvXBg]sP3Bzf扣^8ve\.M wRbf [j, ~ڮ@ãoW$EQVCժ{[mٳ>Lx7=A!PTܒάK cphiB3魽 ڭ,Q_ D*zj#UE=r1W^P}:{g;p7a#q(PO,cW77Zg5ް7gbzX93?5훲^PaJa{ʲA'^L)Hظ%/.Ay^T\ڹzzWUb8}) }hf'n^f4AwX88B@\Y(ӵsnp E$eUMz|YQ m <8~Q^Zk%µ G;J=[=hT{gD3w.Ԙ3>|,u􋝻͉skF'dyeoOu+R#V1=KjmԼ+bV}0s߹;h7ZT_=tcS_mdnؿmTUar[Qz>vcv'w ol6' n^?qw;i:ЭC苏3 1îPvp-m8?sL]vOϩ<;:3Sm+ia|;ⳍ''D{#n.HEj8CZzơSh e}N,6^Ɍg+CŏKeQ,T2P_UY|y;;īQҡi7^, Քet-5̹aPQYT( ,nˌRZK$$ݣ ]Hu2޺KYeG'y 6?*oniL[1f"]V1[MT1=7iiTTY]Au*FYj4a Dk42դKQqn6jii1y8z|eGĄpuSk̝{U{O[wvNBlL0qq9 ,@(!PI(Kn1swvK"(0>~TO0zZy IbMk L:"*e -Z[5`6sQ)rո-2SΫB:W hSM,To#6`t1GYK5#]PiV.Nt1<2緪( *zV75 [Hibq+S=j, ;t;t)XСpSEd=ʂ%V1چ @62c6뵚fOcO'q;43fY?j[f 4"y޼`/ȠGsz iUa "QY5d7[m8&5ȆLfiO4lgC(NRo/G% є#}*ᱢA>5M+ Vy(M>]׬1.,9<3,m 6^?s"gZ heIq~FS s2_t⺫68U(Jֳe*ߠhk jdXGdai GheYN^!Yƒ{B`2=~(iN9Cw̞n.sKjFoxo4xF*fb(NU&k I~Xf #X!B^z;1DZUmHᢵ3ds )˧'f\SCdbZ0h7yNl*^eҖJYwO/k䊆T}2pKpS~yz'K,ԢF\;:B9;q\'UQ2 Tk2eo5 YC~oLy!|fi}ֈVJ,OͣOVG74NB'ڹJ3c?gRSTaEYB*p]GY(e+h x܎Eji@rʂk7#m'dBd]pEe nKZ, ;U(QBM\PoOYԊ( NTYV'V_cv#GYQd= VUn)K0VY+,G3mAk8p0^(KLV+ m3Ʌŕ;,WkTZm 9?yKRwre+Hx'Gz>*a*KBE)KHeQReO #Gz?cfk5RS"+CAD7֡,*Rf>T0ЕxË>4*("3)'99O0i0 ҸRe%qn]ep0bU6D%h a*K$k+WOT(e!zٜwy- s矓7r@ {5ːnO3bQ? ^ΤM52[AM h^ܪFI{*;Ŋ9wh~AТgB&M]dA1DwK?ޮolVi'X6!5{,gIP<1s(ǬO' F@vniT:b]kP>Ƭƥ<PoOY'FD kT8N ByRK (˞ȭ6i!TF߅Gޢ,mUϤђ 36^Ty_ށ9oBGaeR(!@L)ʰ'ÿa^=T!s-ҼAd뭊tS _os,h=S;ELe9l75uî^~Cӻ"z4IZȀU3O>5,ܑ~|hZ~ʶN+ _`PoDYxS9VK5*Dmq7^JLJ:ntJOs3!pk.gZ/7JU*F) e]1ޙ{Y(#T5K޸G:ܶ@{Sv %(V}uS3S3: !̫vJtsOr^%~EOCi}Lhv3qP}-Oe!vyr|FjMp Nj`dHzgm5kd\AW2L,l,3ˆzyw 7\g|l+8|<]Wgbטp:&z-?A;xWEbTO>)/Q֕t.Ov 1n7uQ\RQyY3{vA(K!. ɔ%DhĈн-A)%|# nP~\e\c/9m+B4b XgP黹E1%-q!N|߽.iD9W=Cr2ΛM|<5x6,+eXl {,O*9N>ċkܖBL6B/fʸQf6T+ڀ,ߞ|7619" ›5C|JYBt&֫,B íyJi#?z+U '}|X2j֥,ȂBN2-Θ\:h%ܘ&H,GxQ^┝ +)VEX}=4155x&#,eeuɕemC+:m w]ByG9(Zl4x'`+PzG@RG( s2BKMEbOqpuL Ef:-ְ\y*sy*e\c,_je jdPm(ʃ1p-g[ ڜ|Ff7Kp!e*Pag-%慧QVJ , TXS omg;RĘձ z"4XBqRr2pV8ur=څPα|_+jW-$׽Eψ@-ᤝ)*JYW%]k-.re)0ׄ0cLhv2 meSPځ[<_%l<,[j>Ro;A/}!SĭZF#u^D/h 6}|ev --V"qӶ80,(;|t(Ύl[FmDʠ]ZP!:F8VR[}%YA"z??O׉T}EʲD9ޟ+f6s5[,ʸp]dv+asfotJvM=7t?ZZLzg2od'>P8ʧ^ v πн+ez>E,_war|fzNg@Y>S/JY#^_̸a3 ( ,,( ( ,%PTy# > '@Y~e"2o64p޿sk vۏ[@Y~ey\ oU7;No~ӗ(C5'Þ-̓W}?Ӷ=~th۴ }]c`[Gkޔ lw1oӚ܍ H=-\er91KN'C+ } E|O51D҃FseIiXh[.|^dY^ݿ7|6+ڗV *K憽8'-3ˇwnKc!vF&z?~7 /_pk.fz|dF[L,Krq,$EpX_ǣ85BA.9`Je-UtGY1%3RPJzVB9CU(F^J,9/\Pj<> OLO*d%^L,!?gٻY6ڇx(>,,T5U ssr%+FĎP,^D?>=5"vwU*}75اBaiu)3|DŋQ'E( "JYC (F9aPWY uQ,ĐCz6 EfsħL(K ǤYy堬ꍾڜƄҐxheYؘe'RV<3@+K|L;mM({]BcO8,FCHVn؄tƢheO\a'_QV}Ħ9tWrPNtofߖ!7A+KYr73_ֲ*K[s?O*Qv7z귝2e\x(,kᏧ}gLc;bB6jZ~vMcCbxllTC1BD1MqD>;+[+wRTV4H&nM;bY>}p}`G;=Z[3S*YOkJj;} +n B;ץ,{{9ԺLUh?pSІؔ2zC}XQx oJFjriFZFGrP~h-bgsP @}BZ^#k.llAgQ\ٶ#]GnvҧЦ﬒st8HY3i9'Z_/6dz>飀vy.Yec^ kmuK &`ϙjܕ6 ?-x'(ajvhgNj_rU-ۄtjV3C#'Ð|B˩V:ۚ%jU+@,1^'(R6,<PVY0XD>~?&'_]cr*~4!5=xw^U+ M\Tz(t|ek|F턿 ( ( ,( ,,( ( ,,|}Bq9p289Q,"6F%vwE sPGY G5 fefP7 =;>0 r=;8ev~O:Fԓ >g_?iL3Z[?18)DŽFoXGځIE \e&rJ:ʲtoI4gn,-A:f$f7儝`1k:ZxLnVQ/O,"៰ͪ;EjmU paDcEQn[kc(X>f󓟨84v57 }eQ2fƄN$ PTC,RߢUډUsf3-W"3(J(q6A6Ҫl Fqe]>ҥmh" 넺I@WJ ˣ,|~NNi%~SSϰd.n 2uѣ6ʒHiO,ln(Kω z/ W:@Y=eQI֣,8Ybe!md#3f^io:&tRC33o6V.1jI#RO F zt >w0`6q["]Cy89ІcRlxd6&D@6z6r$qzToM9h]/YpmN+ZYZ3>дRm$8u x͚bӫ>C6`pkX:'£D/[0f4-B:|aߴl3O M4Ns"]5CIg2,YMR (Kf~)eiUD)K=mTi HOcP|ĺAfu^Ǵv]bxv`VsEVj|_1;07.,A(jl,_d=Q, &nf!<@y z~AuDOvptV45%<A'1 &*܌f^3t;'6OiQ&M3gb&+TiT<k7k0N QΙirA.5}CE!\ՆM.Z81SK~>kܐ|zb(n55D-֬e( s~7֪EM Q^],m9%qFhJN 'Ü;;@Y9eGYpDB-jD 3|~_#cRe%+@6*Sv^Ӑ54k(x6nITa-gۇaheI|B?,}۪43Cz&8JV%T}qZz&YXY-',v3zN-D'(^ZY-i蹤UʒNY5,IO8@YeE[dIe`{be5VY|anw9"8]*zZE֣iU506c%ѱ+˲y$8ڦTuTa6#\X\) 1Bzu]ͼFuXNL|PDY|!eq'Wg~rH9/k,T$hQ@Ye(eQ,=?2j~C8VmFYHY#.eH <)!21tOt Okʒ+ev{C# ]7{C[Kb.2zb3 6 + XZNiQ,VeCD_N V0Dһ&rdxOgh糰G\ 9:#LD]#Ma8kYM.-ͭJmd82Ss;-J[~N)dԵIDCtGc}nvUomC[ۻG rţcNAk87~r̺~1hmml`4avVH#ֵ cj\k OsYe >{zbtHLİFg,t!~(稸aV2PoHY0XD>~?&'_-bc!H`Щ@! (˷,DUO7灀OAL# 3,,( ,,( ( ,,[+K/2^O^/N ,`]q͎KxINO>ij @Y~ke]h_mM7*3¯ l糵-QT:_7`~}L.w t ^=jy7ׅ$S]j D-͒7_l?Hz'5 ;)j˻l=Z;}6+kM'b^Y 7e8욬?+?_!rBr{wz?nP%= l]r8{_L0S*߲ށ+YhM-_PHqtjZ/gm?NhS>:?u =Gk3ǫ<7w7񤔓[-YL^UU:*3|zǞKELQѺ=9,_97;n)6/`>o瓸'뽀#NE)1 /eqm?5k2bOh~Hˍ;_9_,A>NEu.;_|.ѹTbME!*$-Kпݍ2.uqОԒ#)JXYEBZߔZ;LU>ָ e!GRNbEp}]EY^uT#6eߔXYѣW G|OYz3#*ܟ.SUk;ޓ}iÉٻ+*թR$,ĩo蚾ꊳu]f~9+D5beI)7(Nà7uuo>oe^ev+Z-$%n]NO[v5;t9ce<۝*/ NLYVZ-C.\[=ONd XeUou\(c3gG8eBӘ񛬣s[o. ^s "~Cӻ贩zB+½mK<6VZ᧣`kwv:,~eUY>}wP "t L*`$ʲʽ9VW 믔3L/:vO4`ڈ07GSEf](}|j({}+/mʏSXq[q;+SЮ7VցHFLZ-`"py*8} e]KYG:ҵH+gɲ,vնL zw*ҙbAgq|>EgBN5ts/eʾwW#8*X' +o{crMPnŅtΙ OTBeLo~yW(W)jz܍HsP<\ޮѤ }pfZꕎ|>\A\.zu](ΜT'K u%`;>}TXb|X}UD& W$Cqdh||S.1Rq1p&ߦXLV?xN0JSƿߪ//Nd8'%wtMWp(xܻD,zFYBZrqhe #!=Ax.EM*y ]!\1p7sι"[ &KyVROtZ!z %F~Dwb(; (k)*|4sN = KNb_2jq(x2+ 눐HwkdZtу!}`+Kx%HdqLFo̚A oVF"f֞Tm J9.YvP}#Qp\߆ J5薟Gֱ7pyZg3]X\d#";!ePS(ѹ6R&*}'4ħ}Q a+CrW ޓ)`< eY05[% cZBr/2OOTɔe+^BEa[ \ڈv}mktwȤbT6B{hL~*nz(]_vEY<˙PYklzurB۬Q݌"d(:1e,b%6x'q <9hwxRoMQai7Cnx,( о]põ8"^$)]u>xksptETNi6``(]+Gqdc;Ɔë(rB/؈$_=(6'~j],U 9,ɤvATY'ṁcxmi,d#Of\s0_./q#Յ4 e7? i9dak ] i8NLYv>݅PЈ7V ssR]ƀ/kߪ^ewv`t%7` n,g1.b!Tp,L3SKQʢ+.uQɔOY2jV)%,Q3|#uYY-:o=\?0fBk}}!H͌wÝ:e\1ʲW)K\%FN:UunÑƑh-o(˦,нI|T; ) 3EV*eIPF"LEξh<@YVq{UY;eu; ,)Y{Yvȟ,Rb-e p*d8zֲzQʮHzAϧ#7rQymcCz u*f])\Xeʊ\S%\TvCY(bzнF_Aldo7pWw2qkCJ&J>"Wݕ64#cC}\|,I=:M{Z~yY~R,>v+Q,{N11^υ}*Je7#F޻mrS ]1r){څj[; g_ޖ{i(T_X%nȳ&_gأRek~-|QߩW):s>-4Bq:&t.f!Vu^_T-,GRZeɯ+OAinĸ, Y&_%~Ky;>_Yw6a8X(S+ڟAo_j烔hB%OqefdbLX=c-s-?e[Uu[bۣvY%>uw^kMNu۱Tv辠Gկ;Qfa {'1< b^*nPל3{-9^|d5k|K|eOVhїS:} +n vF棼[죍;‡,suxig9ڄa*(ӫ]vXYp;.ռ9F|k~޼kq$T첛J;,HY;ә͵{^BNeGV R8x7q!u7bs ]Z 0%{T^`ceϊU%Ny7eql^rP{YjBKZ/ϖaM酗K3Rwc|wCʓw!dΙ_'B۷s^=dINp{R55Iy9ORƽ)8N }17 ֈ(v[05OwYa$`/ij)W:x"f'p7=_` UBcƚ\9ngz[Er<]^o 5SƣC?%r:nG[~ۅ:3ZNcoPIA@YeePP@YeeP@Y@Ye^P >/$d( 챔?DnƠV5]׆t?#pv>[{>ђK5wB/zH~sۗ Q x+?t |ɰ'o9.xX݂?mX{JjSȟ\N}FE'9s lwq:Num1o%ehx* ,]__x%~p9DN_nu._ *T: 0S\g-cJ%U[;p% |>e~%7z/my9伮FKA:yk Sw.R^~љo;~t_#̫b}m 12M?-B9׆$xRɭ,R;ϭ{q3rc*z:orQ Y~H)nSdW~X˥~DE_ńm'=g q*sQysܤkZ rQt col1d#Pq3Q[,ANoWR^+4+ON>]PNZ&<.f!N%@lJYK{eqE;M s"ee!i)fbKz"jn~tkerʂHu% &w,vBw}z4˹۟.}Ty_pdʲ)2Le>sϓ%!VvYҪzs,(>\Q*C,t9Q=:Z?GaU7Oz͑k7t?9;N{Ѩ'$W{u=ږCylOokwv:WW y^;Rd\k%G'wVmM T,.a?,@i\(2qe_DLp// W'e\ xnTHKYV-whI^9BzQ}\ JXA;=+L'˪YSixΎQW^#--3o?n{Sx=eʛ_ ZŎ#+ :ҵ<:7 ?R|%)K[9B=xʲ*y#k)۪:Q (BSKRʲC1m.>'N=d]5UP+-}x9=7rq 9J`==U2wLLu_nTrIÍRʺ(sR[,Lc&V(U}r* ^)6szx_eS䊞8(L;)`PR;"w,ռ˻뮔k؍"ʒ}Q\t< `"`Zrl|D-)̉'4}#'ĩi|LϘ]ePܭVU}Pn@YrvӹM}Cv5,䢴&J/6VxL|$ɺ믕s2JYCcJqŪ/R_ク Uiw[I '. |<]"͂rdgxue`CV\A9WU`P@:g8h@?ɠAnĮ9#b0Yz̳"z_£Tm= vHEODW\TTgof͖S}5m=JV!}(3^sTu8f]cTY\!}Fr>y*};O6tOCw7[`OKeӱ=106PųjbhY>q Ժ9b$lMj]A/>I])˂i)>* <|PS~z~, 'N,_'f~R&~#ۃCN.mDYG;bc ʸkF&])6F(cOգOMocª}%QܛQ 6^u˸zr\ nCt8ʨ;ɘCZZqt:,~ ѭ .`N~fl۬dTh_˽&3ϋQY+f-K` !$E J->}''[u ˙,Aʒ)(%=+ !+ .OL,TvHPsW(KvHt!gr*˼A!O?^H ^!<[K=?~FVϿ]HpdʲA. o;0:2Aae\{7, R0Ngz8TiPfxPnk @ƕUmtIC{?r₍ᐕgmlʾr9ZYV wAoċ.eɨY,Xb˸VKQʢw/?.`># $e9šeLE+ P\BODS#ya'pWws[,t%W8퐰x17U7ݪQ0ߙ?-e"+~_O-'W8Ng- j )?Ywd661dJE71*bvpaF+ 's &YLze1b⛈cmDYbK׽څG+zul'9hca\)'_ܫOKYw+K` *mTM9&u,yE[=tb!= E􎲊O?QRr~05 G٨ɚV ̷OM7|3Z..V4R1 ;:FQV+f,=֗$f%/&Rvp',ڎ;-_F)0 7]h[VgUkY;S^:_%8,_Z_Z/ypTW0 KES?H<&/ө:W*G,vb5V;"DWʲxqJe_V;ξHElv$R{RKi w~Gm~NaNY^{ɧ5DX<5~pI߈T:̯~@ :aiœ33Ӓ֗m^mX?$b };T_2Q ?N)ʦ^:4O ˬȋSe9mԈ7zģvѪCX^fȽ]>( 㸆ߺ)eNvO3Lt;tż* r\tԊOفr"Z,rKp!nΝkw]p_{bwm)#.,Ɉ W283>*vBWaZ1GVJ,vzsk!IUt+1͎zԽa!u32"g"2Vse)a屈sN^,.uU_ō1tigRwg$̋[%c!6uW2!өԨȞM_F8J|%HL+}~]Y">;uckãxz)_Xr^ǼcwBy؆h y۷O R.s}]b2!7&;~:EYp{*se!b޽+ο!_`dZcB4(^8# 1wJgB7V̼pO ƶޛe--P׸]1D}QK\ u>.2ړ&uz,:XNɭ'?LYLd!-_(ߍq>8N uS@l_g0ov_?/Y| \tx(m:SYV( )Z֖y'fqb)stOil5jN'nt3*!8!JjXvG~#t?#['il{Lvh[EsFP@Y@YeeP@Y@Yee~?Bڬf`:QA?A&?B?ePP,"+ 5UE/ r=4[u ˕ߝvw85Pe9Ge1 uU/zؾ|47P7s *THlprOYQ7Cۊ_[izIne0OK%S_BY{ܬhS(˹) +|ų86,4% z-'/6:iNox$ c"D4(vL酩]mY'\JG5#ƭA̸>)ii[F(OFSU02 ʂoMV{{{__?MePTo bVxU;GԦ̺ɾrjaP7wLjY Mb먩Ҕ3,SMT6L5oߠ,r+~퍲dgU(eX  @s9S5/FcxOm9QF62nwWWS އSv,&@utU]_u~,)dC<|y*^ӄ`5xN ,,QbЍmk&D"j M)/z fp<2 CPH(رuhȺԜ}#2qj݋@\~ܽ}|]̝vEl6GN=?ӪȌPľҒǔ/zt Skٽp9L/Ǻ֑C{oT>ŎP\qbћmbhN@>)=[CDXVD3\>, VJ'H)[>rLt (a2|)u*>g O)[57CEF%8ay| _];GMĐvvpMOϿ`/tK^u\=ccW>6 =Zki8abRѵqZY}w8(oc؜d*?4 *4aa~}5NS3nufN_Ui]=vހS(y*Kuy7ʂeZƤ^Y=C~up,o Uq|Y' *V?MN fB'BJN0"KgN6 %aAËh<ґtx~8Be]"X1f;~Rƕ'm!~0sFuT&%)Hw9x(1S;BE,BwmBpo}u(q2']|5C~(NpޔʀvևuۡR"8!QwuV,pzd VvD ӃVZRҵiDcc\ĸROye<.כoZ%$_YFZ>^eD<M,Y!WNCy/bPlfnh`yͱ&^y *TCJGlV)F;x5}cޖaciRMt[|uuyqnFe+u%hW sZEqseӬR1?75,+N ,,Ue( NeoV*/DF3d(s4fGBq˖g틮T+)G/.44wqbEW-Z.F"2ܛpR0c:z9U-#xV ̒.Ca| $LS//2|E+c"EmkwO UrW M źVK]7e2}zT69` P͝2}[ l8h,:yO~xu/dD>TW^ٽӫ v^0E3ΣK<,ⵣ@+ 0u9 fuf W֗Wtԇf閃-qkeJc4WޅmeP,5( NvnBn.X|D,vF@Д ZY~(zFk 3e_B~ 1J^@E2,?5Ȯi~r"s ̙0Wn.5pPrper6K[,:6 Qb?̱,扗\V&ܕ0+EwbB.0ÏFu]8{0+}eb֫7W)qw-id]O)Kٕ[e鮯7 m)K%jycmucuI)vMz}FCY=_++6UGQa0l}j*iw,]W 8%( 4U{,8ٹ)]'L9O!7pu\Y gQZ}g+9*1z (RiJfIcʲO R}e1=i ? bla~^Y%sq,;ύueu4&u(ܵ(‡ɣʂ=K_Sԛ3EIJ)ata(b嵉fDo#b}؏EꈲRQEbM#-@ш>֢_: eӽu<^MZ)=D9D+Su0RbP̈{+yILʾ*އ^*նɄ:P?pJPe9OeiiFYp,"J䖳-ޱkDQ@B ;nDz5S+Ч:}o\+5HVsʶP{%{vo]<>ŠNe//*fgFU~*?ƍO9q2bRWih-xu]yb~'8O-TRMUc67,r (N|~V24e90-e!fyXu0fM޼ٳ{cBgސ/YY0uaIFLj7NP\aB8KhRVĶmoŲw V0,8cƅ´(>ѩo7!f _M_e8CݪSڎL7$;VR3.ƦW8qmy\T Re[F8|%Hew_„~I}ZNӣ,&h>`a۸1|Qrյ]c[TM&^eςfDOgJe}pvCY0zbf)AcQtEuP.a8X_k>i?)AYܔ2uґVOۥ#"f%ѪfF[ eMM78~h}yUR,fQ6؏T;;G8%( `o+'bB6dgZwļW#]D)mPF?>*/9oV0fWqJPe9Oegb/f3"Y-rZwEX i$vxRVݧmۜUpѰ_GYvf1lVI{ePPp*ˢ|d+)oXFo lV]Pee եE͖ d)ˎl2 IX6MF @Y@Y3붷 -J}T{z.~ @Y@YMkˋʅ9[ԛk&_r!7O^ TQ{Zd;( ( ,( ,,]YHl408T0e"PSU 78N?,?FYF}C]D,˟/_ 5@(P^ϾذД.y@Y~SNYYtL.ۘI :/VֵDbhY#~d7 U>KtA]/7:E$-CMe+~퍲d'#GiB*vTu??-}\کU8=cNh\%IY΢WdzU[i~wU/]7Dd}Phxt e~R]^⍲d+]+DA9̶hĈ{K :uu_FZHk^ G5LdYIxJl7 CJEx\:4 ^2n$"t9c?GWĽNHn!!r 8>!fB-Hc$ԯ:8-ͅ,OYjʼQe]6[&Ɯ63lN+ĴFi"'E9,P͝2P)!9ء,!}XiH@*4= @e YQΑJm bֻa\^iL/(}Rr)rPeFYpSM|6Oqeǡ֠nY%>)OmYOL,vF5L᫉@tRik7]Z6lGyѺI/- dKvXoE`eiFYpS%P89=;'_U.Ǖ%qR1 b3(?$pLkUYHr=ɼٵi d}\`e /^Paq`; HOu{B #6ݧ!*KKC7ʂy˲QYHxv ց~%ЄiM8b Qr[ϸVJv##i_7^en6fOrIσ\LB[nIw̿'拱.ص#.2|VJ5Ğe"/B(`|hFUšO3qY#Oο G(ֵ"Gːڙ{,ǔ;,~ɠPcv PsVf5uґVOۥ#"fEP,,"|{8 HePP@YeeP@Y@YePP@Ye9YFQ=QA(ˏQ,"+ 5UE/ r=4[ccl7UIĢ_a NPWܱl9^ĦÛ3e{Wڻnd^H6o~"8VZ7a e(Q}Wg_qlXhJ^| uLv^"[γ3^(@3eAJfo-bz;"՛Ȋ+[0 CPH 9gZKdj]%v}V^B^ey?p2ʢgr H,^m~B,+Dj8+ՍNNxԶbk)|pWlE =0>t,LYxůQ̣d^H?MHŽg1LH7eY0?XYD{m(ν G&(KE;o';EYb?: Xm6=Nfvtcvb0 K+MvhT qnغٟ}я>.fTWTZS[uB*a'L΂p5ý 4~0j_ِ A9b6tr⻗dمeb5q (M ZoD\Uv,hg PDYKQ{ekw((ٶTqobx`xAg.}ˈx\+i͋Aa3&gN &d QO,)OKKƍD69 JPu߿wy} ) ?y<;V)0Kk۰j!($W#OyrD:I7ɱ@ĺձsbcX22S( 3ݏ  gŃўx<֒BAӻAnn%Sx&jҸ,mTJp}Ǒ!T2(޲WQ74_*Te9r OEmSVE#f|Q̔h^B_rkYѶEwøR:K]M_ o''P%»OqLY ܺtrir)OmYOL&º| 1SG7=DW*6Fp(ev('! 3뀧b=ãQ"8 .lZfqex4:1_+mk뗂ɾDWJuDe\EÝر޶Y.*+/3= {eɮi~r"s4LXWPj[,?4U{,8)Q( n%wEbMGTfP~|u3It9hPr=ɼٵi d}g,pxAqpUÑӘ}l)aKwᴗ͸WGR(f$e:R|QнtSYA!G Îy\qHYWe9Ih BՇȶe9PRGEQ^"\-O8Ƅ( ,?4z,8,;wف^4&1ӄZω-`!k8d =HlZ; '1ΕEf+Ĺ!WMꅩC5Y|xTbwex4I{t,Ɖb?ʲOcEY̋U1%4ؖb#ktQ:jb]Ft{,д, eK=8#FCY\;0Ǝ,,S%k{s(ˎEQs|_G%9ݲ]"(Oeqܚs\x(8]bbD>Jmu-Sc)eqÒពE;+ ;Z026:>=0gd,VcS!H$}%qȩ,TĺO:5#grm]wˣ&5Lz_@ `bJgfe}/Bťw(e7w 6@Y~ s'X H>?+3) n)'9߱981_%Ivб|!{+{&gMeMT ( ( ,,( ( ,,( ( ,he!mV`kOldPcJCMUQlO:3e1 uU/zؾ|47u ~I׻X׺r)-ti}90.sx˪ _E|!3Mo4ɭa__ZT;cٰ3sWm?Aaz]ѤfEa?pe Ũ׾+|ų86,4% >IޞTUkqKr}2Bj q.&Ya ) i8>nzᶥh)1}6 a 9IN;a6Oe<˾}Iԋ Q"?--b ӫuއFtٜ3(7zd'+ݼ2T,rS_O_"HJ|%XgSBZbPE~enKl|΅؍siwpaQ؛Y/,+Dj˅U;CX7Z}YνWeNPq"PPˊIӯXzKbeg밲x_U|%}VS9je9KJ nÕ7ʂyVBs[nۓu$KDj!_nr Z'ߎ eӃ2>RPRǦPfٛP=~h]/`؏kRՙPʀ߼<DJQ߲"#{Q}8woX iatZ¾U }slE’Jݳ  {T3%+ ī|FE[N}&|x⾤f Y(Ŕ*/:((B%tDc',˽ooG pWI~t87Mz2?RDC윖%U:{SXkL@(mÑ@/JgwϤFxbjWm VrPPlN|"d'*~Ur]w4NtOIxnQ;vj &:ʽUY<6`ZY7niNjwXYj{6mY 7(.wDC0T-[,?ZYKQ̣Dz3fŴP@;⁦,NZ'Cb:;?.Yv,Hĺ+pĖq>{,O<"u D(Zi!l}qhrvzl/X6H팰O4611&E<V¼|a~qh.}ˈx\+i͋Aa3&$y.>mJ$ yTCwYrբ@{jT-Q]M՞imT "fLN`x_~?3TLg?W<./{2@V ߵF,ybq= s>ӣYI*ݜ~\YY=2VvDģ҃q$Y97(5da\N:ڋ`[IC" U?}v.fi3) v$nxrRm&vh{cs_6UG2E䴌ȦxQD>$ҷM-@Y~Vy,8'e!כrб]'B'CФ ro q1ݼ.?ۥVpɸqd*e:#߸J?]x^JasDm̎Ya7`%v4wq%oI0kQz) >4af @I#IP;Fb$nˈܾ7k`+.ӫL9._PNW8͟cueOn /He_MArĐ]Չ ͑ ) t!]ZafET}DW.:$/#}Đ7mDeqWe" z_@S,?XYk*Q̓(\:wG`fU;Qa*W/sGb`կYꭲ'^:4|-A)f%NL&bq ]֠Bگ u{ʂ CA?EÝر޶D  Xk|okIçsw4vJ®7`mSN p^Yp) m\tHPN U:U7ï fbBV{阑<a,}b jjpegIܵ(Z$'Uey,ڞ&6OC[P?dBnxeTW퍲d'$ظӐnPrg*sgo514]¸Ru,0!7)ˑދ؞J J3O7Vf\^xzaaF6ҳRS EbM#e' {,'%VCa@qu3Y#y( =>԰j 4xM(92bjIϬ,?Y?msNH)MFqJzW2;RQ]\iO)6Ϫ,. /\>&gF1<(ˁXiQFcʢ%}xle9y,msE-S]%,[mFY`@Y~4z,8Ge!u߽\<;6w` QY9Kg?R|Ymp܅-ZGRIgSg4g( {ܸr  ݽ@w_}²;,Bٔ%P_zתGo^ձ RjS!-z (z[KkEY7;6&K.!fj牡L^=;qݱ7Y:O#7YwNn4D n/W(lVeD&Dw< 8E0 T= NYG5frעz[G8- -Úheq ylZcGDU1?do)WmR-͡Gy۷KyW!tlm %dQkOo{ rW EJyE:,8(~PsTf5uґVOۥ#"f;ߟE9 8"EȩĶ՛Ȋ+[0Wmw@F¦⧳}L? SڲNuM`_7E˿oUa%lؼl1EU5ĸ%Q +Id!(p|,5`lp)7zd'+ݼ2T,rS_Oo,nur£7Q㧼`f9+Y^Xoce* {~-1W"EYhFSFeV+~퍲d'(8]D((eE[@Zif雏|~w]?uw,zKbe,g밲xeT*n|e(}獲d4.\؞{̤;"R r/y;&M vdj^kB"Ա dp,IYŸ0Wdz:(jLJ:3TOeF7ݘ(VXr_iNj[F)ݺٟ}quVZZ0ΙŃ6G(E3UBeq!Q*5E8#xS}'@_;L/nMH^>%szr3xͽ²vMx\%U[]P.Y5RǥrHKWM*yHO!G5SZ⸲/L(1E[N]1/zcbRp+(Kuy7ʂyTXvbe{sX<Дw]^>$cye"/D}4b>˄'e;vxT鄔<w7(pT֭y)2S*zҡn\FɉU+-'H^%x*X2x<ΡP_$}E|T:Qt _b~CX2*a_"U""Hq b4C'ogge! 8ӡe]"X1f,.>mJ$ gRJk:RƥgSVE#f|Q̔Xh~,5Po,Ue( NIYܛm:}??aQYiLXT9ƍʒ7$}Ե( T.>rA6H-e<) O)UYsoqo9ӶzNxwzFZHT#1xV#B ŮDq 6gC-o݂%ñȮHD(EswE(OCIJh7Fu.׈璒qkP,S( ]Ƿj*c!O.1uڭ+Kٷa('X-tj٪`a9XnmIYҧPhb;Bگվ,& -l[a{|y2뜿gj lN qHlZ4)L yL:1ER% ::rpqq_Sfdeybܛ/T)ewA6aZzXD+KP{6e )W!浪90/Ģ=y"VAPsSƯ_(_ۛOXLn !"_Dâ޶%:4_{`[aӾF]Ew. ePSEGOgV"qVYOVu JmZmƆn̴%>Uj䐊m nR.ܺܔB=#ёQw#QeנT*hkfEQs|_G%ŝxL4L6 ģCMV') e-~`fȨd%$< Sי%"S,J^&QTmCb6Jvh@nVJL[pE*S$]ݓnLETf,ʂ nU$1A S3 Q}&PcoVpHw,Ps~`h@0w󳒡Ojg:1찄%Ԁmkãxz٩_Xr^ǼcV6խ(/\# j 3ʂ{kثL_6,6d8RoM6;!q0-%8:Ա0)'m&7.e:bM7$;'择)ۇBOwr]_nRɌq*s//ű=doWmscuy_tU8ei4JrT8’z)5nnwꎄ⒆+}B4`9LiJs8b!ܢԲ[( a:POg'zi" 1B'zd lȧ\ \tx~ձ Nh~ (7Q ?>=ٓZl~A6TĺZ-Jnt3*о=Tc&֭XI͔ `WB+̠fXK~1vz%|{v;&,{ݵ ^ (?QYeePP@YeeP@Y@Yj1 :^ dY&Pa6ժŅٹ _¬fKe'l,_Vm˦TFd[ۚɨ~ : [d@ >?^;;= fanf6+cyF=N=TA78a?MYl4T(Nltr( (PQPW%~˗/8AsCjdY)+]>"6Eޔ n1$??3}r-]/}űa)y]pmH0za*BW[IgtTnޱ۶z3Yqe f7!uҜ0 8"E-p4B;/JuAIѰLC|eyO/6ę\1"2tzI ~\(e!tXe8Wj* OB(Y=x}R5O7VPP,( NIM2Baz&baGų&b$TͿ||?eƀ|Oe(}獲d(ˡTu` =ȤF_qj'T ݋;&TQ)bB&XPJ.齄*^C*ﻳP{lfd3dv7+6wT΋t`eXSԑ-ć./{| t_<Ɨ讒,rm~m_Y$}yn7h,\=^Y6^Zc39} 4ȎHVzrBo}X9FW.!]mKFxѦxN L.INTo'/G5~=Lh Z<3.of%%[%6'6/!fK<,>s_[ٷR8S,0ce1ݴq ?[V:ݲf6|e@x(x.S0gOlûH7ur򉩙 D8] ;>>* ,KY2SO,EV`F) U m]ȍO=|tʚؽml6[GGf%2@]bƼGBf!oills3ua‘4l|4T}+dׂX~*~nRYdXY6GRr]ײn}gW bX> "[|*mikm v VT?k9ş5ܮ=mI>VEӚĤi.Nᶶ5&žҥs/4sEʂ *R( eqɞDCMٯoVvv~۫ItևS“-ȣi7ZUD6Vj}8I*t]a6̐ C$'bjIrae9pah_YdM/,ɭMq,CPOWaV)a2P#uMS"t\}G yw؄o^6@]wnwahDy:u?}BY{Lh䲃Hp"+ >,VE0őXnj\3x.m+[,2HdɌ{̫t^A.eFY`(qعG k%o![rU3BGE2*7>p}>d֎UP#9».o5 J4-JDyYe*P_P&cVys] q/[ Xbc>woX_!Wl,AwM(h.!&35CV|E2'* #*i318,gfaX*'YT^$Oe9)ۦ0ٳt®qж;eH$[[u:,\$e)g|ziӸg86 fqr4Vo~,Fʲ*ev走76+}`d"ƨo0,k~WȽ)o!erTYL[b`єDe9!'(GOd}Q82ѵbj3·ʂ r(?4^0mB1(Zm eNxT:ỏ݇_j5?{)Re ?uG/ 8Yr(3. 5<$=g:vH 5,‘dIgeQCz"Mp K6 Cr^'-j0]A[]104W!3&fALNVg̗V+PӁq}wboIS#˄P~0|J U₽ޏygW|'ؽ̪.~a(7TS50Yj԰H&^(Ȫkk//X .㶷7Ẅ2r-=C9WXe },كwUw߂`F򦎎cHfnNv!Ԋ֎ƒhwKbcV"3,ҕ Kb\?8W^,Bf&* _J;I8sl[KnS׀IdCBm86ԖnHohOs!}xcBWR"^,ȯG@6]" e\mo*4#6mb(un5bigqɜKOTd,К~G1TAPY.6Տ `-htxT">]dވrx*--\i%-}`>2,`r|v}4C捕|Э@ln=z<#GʣޱaXݼߡ/K r~̀ݝ'k{? >:G'݅a!gB<iӗK>ښ݊=#uLBzC!l<0 J.H?-șm Iᡇ盒g`}' fFxx頲&'ޟ+&6"naaMLe۴p8u0}V"gc=Y  ryE"7;ZʊMQ]񣣵I*E<#YozecT"ʂ *˅QDDRBNV@_AecHFG3[f{ʂ *ER 5]e.n'6/3ATTch ʂ M<6p\&V'F*T,+KK9A.*Ӭ A.ɍART"oL u#\t{&FWTJ * \TAA.,   ʂ  * *  ,,   ʂʂ  *  *  ,,   ʂʂ  * *  ,   ʂʂ  *  ,,     ʂʂ  eS-9% Hy^aanAA87p.eue4J,    s k+BY*XK[KCuy  Kmei{K#H¹PAA *  ,  ,   ʂ  ʂ  *_QT8?;< -J%<wzS6ڲMtABgRXkR87%3%b[%Η9:<8=9ajT*ӓCP!rA}?;_:Y}fe N>SO^L">Gʲ0739> oޞ C {eGSc051_PC"r9zў*Hmn{3ӽB]yfPE`);o;ΑtmG<Wc?j bK&†AFFژ}|;+FEPkӈsɞ}ncm HNڐӖy娇f˱њ91`gڹ!r?hǾʲWє.yb0|dW!D̎D0%b%|7? )K;ɔ a ݃qB^l\lb^v2ۣtZHG&ʞ4{ЂBIPs,m-& ;rqug?T/6|\D.b- N7ڨWwrCvrBwswvi70O'$[]N^81ZН!P^(9RnS=Ѧyi3=kc"ےтG9flUk+߻%{CbÇ Exhy.;7Ց/v9o;yXKnLܐНPf96 S vf'- >GPhhΎ[;3[gy9=GφVPY7<j^_Qdf4WlxgwojҮoM}#J5-|́նZ<{ƳƤгw*>A."{m&H]7OAM9;~ :3ݡ>~;6;&uo + ˽WZRe]bnһfVeB6_!lӜ3S: >GTW}mɇw9¯tY}n @Bޥk6UDu ig3if1±͜CbÇ Ed`hܵ?&!4JwFYFcN㷝W;^mL̿Z y]zVq,!̽6N@ B3(Kt FiHy|d5d~N.fhIAϑ4VNJlmQGߗ8 ϞWigkb, pW<.lCr'1.)\ؘUjv!9|\Zo piɬ{ͷpAV{GRW]u2%Ců"BQmԽ!vA u_ȵv!df.ۅ~jhੴj>USs2Fo%f?5wveC8"@5tt-ȵ{jdi`0'SΜb*6! UFzSq]`Zu{WKIY55:(slUGGF)ޖF*˦.z!6 e] iOɝޘj2JbzC"bw5tǴ'j\kCkP[{X^ )ZB ḥ6tnJ d3Mzp˭oXUW:e1#Tv{ԝw(;t~;-4#p;ς27~;B|^?f&ɃFII-_ ;l"7>"Y[Pi03޸  Ջ  mh[V'՗ChӪQ7?%lӽ^I/+5[s }j*KC,ip)۩ϴ϶Ӟmڴm?IצZH? bPClс sB86EQg>6{):h ̢mj/P^(9R*M}@rˢLTx>H<.YRɦ?FՇJ{JXYQ nи ,|z>ȝҧH"$*H,Յnl,ȑ {S c@2JoH )[+nxT)<:hUS2SwMXHu$*%Vœ R6D^u 9oKӦla>ZX^l JV6Y.ruf!Wn?VJl(KpH״#NIc2PqbX-ey1=7%a;`*^_T?M;Iyz&DoQe{(]7UwySGyp;GcrNIk)P"F_AyHY*ˊM2'9i(ʭzq̓QwqԹ!Wlm)E1щ =S|]*u@-կHkTY6 >3+է{? ' E.t$̷dp@+­-޶Cpˌq$r+!jxuvWҩoշ]ő<(t@Ƴj]% PE*KʄybPPPP!r1;#d䷇8 sגeٖB: Cna $xNV'y y08. yz OW{s!67| 7 G<)93|&iSPs,?ӟNQwN=x|KFyb8 d| r-vE*ے ǒ@8Nڢy $&R3E]h$61ZTb̉݇NLfXۄ|]Z$_o rm%LZ(˪Y$ʼGvAWk2| q2(b ߁$2]&|bzC"bw042Yd~:ĵx T}PM]IeHv7f>_LAP߆u}>gmzFQ(:U:KD̟x,;BZqnqm#(}w*[OjE=lR$x 4>PFmNi )KYq63§`E9s"ʥɃiX&ȤRKbfA,fK, 988{ϊg zz6澶#OkEє;5Ek"B+b(*!ER ?=K% X8mk[Z+ r:D]q.B|>g666֔dǽIx_]Rmk(r$%"X\Iȓ% x:(˛L(_eնmܪtzs򨈭Og*SRBBbÇ Ed Gwq6? 柽WyX*q4КpdV45UTlLAg6({϶9P̳4څőd?:/^/OLlbh'#يy&y&l+M8\^pER]牙 `[^{7mT%rsfnyȲIztbGFWhǒ D(K咘ك`Qc Zfe 6א>wlaIJ? Pٕ X^lj nFr6Y>\Cמ3[5.C*)9QMݮʢ}Y>di[G۶Kͳvk$_P S<8wE2fT˿@ϑ|φ)4ЃwW"fc nSLDUv~y]kϟ-Ɂvܫh؏%PP!rTIC{x;?\ PӾ؊veQRFX=We+LQAqt/O4!9Aӽ,E{ԣE} 7jsسtc}eAbzrb\F;/9sUS( 3A/(Zb+9E(θOS(ucd+ɹ2V.zmdkPqy)ޟ]M *B&eK)vf%ݽKeKt7v)l\l{~d5jRUx%릱JMs.`. yAIyז#eEUe%kj 3)ק\Z[]i(eEGp\7>ݍʂ  ȟQZ0p0cE.bX811Ӄʂ  ȟQz0p0}eh4*jkk 婩>TAA655+Z6ATAAdffp\0?K.X {Ya{AA?@~~`#e9,s6β499XVVӧLDDD|0` 6?EKQW]ciou{򿽽=ã·~P}))))((ʢC7iii)L$c```````V"%(+.147" ;B ? ra_555UUUr&00000000L+ `````?zk$~_~rh/aI 쫧ϟ A&10000000NXgbM ?:^va_9+`)XL&]bB&F0V'X8v|Ul-Jv!eLHBq0 V-147Le9Zj5+. }la```````0+`|,1PIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_general.png000066400000000000000000001451731477034762000252430ustar00rootroot00000000000000PNG  IHDRlsBITO3IDATxWK]sϬufN91sI6&sB9g}[!7fgi5]խꪧ[-?J*>c```````5VpX?+Sd?",vaq{ES0b```````¢/X?+N T c㯆(hÞ㛾B ZZ{Z$hӠŞ㛾5EVPR 9ƷZh{2BYl}eppv]d2T*HT!XX p 0 p1_-a/ص@ x\.S6GƷbHQW]ciou{y_~R]`,v*00000000&<"F^vaBhXY,G+`:b$miiillcbAXx8X}lb-_勵о{޾A}AA& HEwn_/(((++w렭rXDNJgggA~m~>ΛܷmDA!lpعc۷YYYEEE555k'X?,W>~h0zZJ<6xր+}]|AA~}I6Nf~1?DGB%oݸx9! p@3@6Ξ9U]]M^Π?^  ݻb0p0gZLb ww].n[|RDž́WX^nq̆ 2@6@9>}_PP6b8et* 9NWWW]]:p {~"KO<{p ^KNw^8lq~@3oߊx=s,wCAAf%='3?!fZYJD"L555kzdͪG%Hi6Ji;R׮^:憫W-tܝ7_v ˰ų:? ՞Ϋ_aos{d  ,<ɡ 6NByle" le-׮p_Xx!P{.@{w ·X~݊QDD_tXqa6tys~bnp[w7%ΫtrvYVn==K&X$AA P{~:;;YBQ]]XnEOxg! -.tKτ?iH=}B ahUڶ6[]ukd2B\"  V8}< @9޽+9[?l"$lZUUDoŚUKNPsUUX5 kV-lFr1`I.tl8ܯde=+\V;@ӆ+V,̙7rGwƚ =9,N$G N+떬 E,T13ʖ~wv4ى~;rN!~"%g^&Wձ -Kxxᚭ4Ptd>lҩ7n Y/AeyEff&x,8D"ZY*++WanϮ4deAx-5t޵ae?v0^`YyN?`p^>8_c Ɔ[@ Ds[]U7,v( >ϒaeJY晖I2M /hmOJ59TjMEW!o///pd7  n݊edʲa=F` hhZ/~mÜ<ټ s-?a0,=0\3b08|Y3S*בU N v΃b}?~ò?000fQikW7HB! Ca8d0|4琑\h4#4FӴf\#h4vPS!'fЊ=tT4 =000f9 t{#Is`@oFgj4R6j0#~%i \WVV* SSAPѺ TA/zVH=d:PN-ʊ K{dpac n;^Q]si4+`ᄄb`7t Fgih&'$rr`FRX3HңqgH%+/TWt}sCׅ\V%EQJa_/W9`<͘ l-$Q3"0|* S]1ؗ!d2rݛ8{ȴu_Ye~9?jȂDŸZJrQX󣔥0O@eD#QpV}\U:/L[>3X/wֵu5͑G]J AMʢ Af33 }3R*@NH_@Å(iW=ND|رw$&WUV477r8lQޫ7ԋsާVȗyl8ŀbOׅP&5’^o@*76 Zui+HeIێ͔ bFʍ>SŚ$;߮,ZaA|;0`gU|BQ{͇Vc8?g穟yHYDR*\3c<8}zV;f4k?,100]]]!!!ݖ{ HJNH䠬&U?0*i\R +O<|RttTvV[쾑9)e+d[+R ,VWËA. zy9@'<\4ZEĻm/Ư^bZBf7$8r%\H>;fe͠7+7]IĄǏM<->avTGFF6Ku?QV~HIʲ+vAoRjUO zҬiuMaDy9w˽"-SΊ &VlE.xzr[wWUB %=w8{JQ)ja^2p؛1RmQVxƃNl6g'(/u) VK<P !|\;ئ"Xc`%] L7Ɩ7޵(LI}JaARn]F  q^%sLRY*4n?:Rn!n9|?4HrСpx/;0\:[ 'FÃ^eXio'bѣ_}^϶ygJddRd_U ZS߾ c>$DGgz& ZaMݙ~y[u} s^ONP_~C^UuĐ"9=E=Uѳf$ <t=7584$H|@YDɤ롦q( s۽${HII.)22Ftg$$ΦbW'ƾ򦺢/2Y 4T7z[Òi:=5|YՂs{Wrʢp&|*=; ǙeU5eb|ĕp{\X^m¬,[7wutU*;ʢW\'<7lEQ̦<ӸrJ7'GFMs=%*2E5)KJ!_[¥Uٛ22թ"1u] <!iE"#?P)^GW 4jAU[:-0 eJu>瑾NbjppPw5$⸏,+rE5yz5> r䊡U,0JI+QVyE2@ibdAeH>v*$EePj󶚮hPA--(Kx²gyEPX&HKG0}Sm[ A~90@  0Ppao$ikn&$aPӨijרa~%ȤO|zfzjʢBQYʯӐukzs6zPn^K[ĕč؞YXj ?S!AT=bs=FҐnrT:YP\0ӚMlR=$!>~Bfm-p%or|RfF(Zܐѫvj珯,9%**Ud彎Jt-|+ y~,zʢU#. UF+d`HN)vP5]Alloe'AhAMۓ̈́%yN y_K͢tZwRSg] iuza6,B0hy%Yxs03R #GN8l.%AU۪I&f4o&[,j禀)zXnzO"2S/`HT&ym XFml?iB>^ak_SkrRYj_K*KRֈEFuJGZ_I-hLzC+#2UKX?f\!onmi3Q~ :e ?l4IHeIu#4mfW@Y:ӪL)ёۥj4'oRymW(eSI*)"SQĦ8qQ`vfz_՘*:YB;q\ddrHC:ϴV!WГ}ޘNE ~\Hv’O>K),(LH,&|Lݤ$7!6?jVQO#$w{hrQZbImCsSP'"}JgālWiY7Rteʒ'{ X;VJsMz]IZ}ٞh5;!>7ԗ /q&71>IE?YW"EҪߘ4jAA"[Qے~++`wD_V(eQ n:,5 *ۮНԷܶ-JlN#+xv:ȋ*sG92j¤,KNqy8(.%,oNmuu RIwm]$kɮՌ+ Ol6M?LEd2@L`s<^g-< .i  5*jmbHRHs޿VEz>M&$ӭ 7),52!Mwk=#3 ИF! Oph5?kh耣_4k. Q>Bl{&^\qśp;Gִ{G}cБG5Mޓtv3O1}zȸEi^4DGJO<3rdԫ:#UBm$M+ '?EzJm)I3}I:G~k2-撴xļhy"ûϟ?RG4iv#.%Ml*v OƆQ_rnnjal0 @ÅRNC_PRÈ.y7s{]a3u=d2΃boOhnD?SR*~L"#2!NƆ;w^,K}- FƺC KLӜTJ\wWtwvX/R!cJ镦!pŬ Bnh3p|~z UP$r{Ldž$ĂQE}TIuVUᘔS:;Gd"g7}76և466Ps .aLR7axf h/"Ij$\IOoYGE](S24ᅚ5h5CFcCmZE+<,vIMNHĖǠMKREWAf 2[}=aAeARLDY> >0&Iw:do{afnh^)(ΠE5fgJY*ET{ݗU=[{w#|;w ;{Jd }Z뢒5UeS>Ӂ) aGEAqXi^GlrrZ4CkWQ5E \߰gI㓝.~r9)4/* 嘔i}VJYv>^Fgڿ,JL)˕jYO>KQL`;AI|첸G 7=4=KO=}t-W#Qin7W9,Afg?ߕ,oб[ҿgY{=USX#h^T1)e9{ĔhI|.`T26'A>X?ͺ~`=xyQ)4mbT&'GZ͇i&¢ǃM$=hz3Wc tPc1 *IIYLaM,-J֓@+w;VЛʊ Ubw_XH)K{7?&JbBXu˟pbM`2|AInGa-:)3'+óNZ.K=KheM Ie9TjUlILŃ`.}Xgp'tf=>Ó߾BewRRSā.q{T yRHWM5߮@RY$,.oJU}-PiG܏U&Nfn#_Q-$ؑnu'=/cɉԆn$Up ZwJՓ+m#_fڧŐm=|7Y_gL0AOUy; Y\j7I]\p53l('m>.t}>%jXKKf˅ w "5|G +0.))ˋ>J-*̍%kqܧ92NO?e'BHIo#\es*X0nƇ| ƁB! q?"30+Q? rsn_ őљԋhE):NySPY_[!^eW#4jt$-/81l 1{t]-?&7hF3=o@yf ƱRXʢF \=k})NSq,|XV!, n0B5a6k>LfS)$c~fSgqb:1`(O *KR{'C c #lJR_#\=*=zt j'&e醕JY8tYYP΄01tI$a-rNc;dy=REu!Ss˟rf&Ҷ;\@{sGY H8$6ͥ砌;BjS%aC+)8yg[ʘ\E&h+Ӆ)™G\!IݒnpV޲<0kީ"45QktAnXkd|6uXf('IeVo{m ,(:-ȣD~d"+.{'y%<<8lgo薔C^!.x'a`_-м,OcRr3"%w`x''anHme2{0"a((eIec KU=+nTY11e!Eո-Gx }'$`XSK.x@T#-R&,sAr*IKͦY< %\VxPù|+6YNwƭḒ*vܔ*]oW+װ~ ?,b؄M*KXv?$l$/v ՚AD)K%y^.~g]^.tK r _6^#KZLq:a^)|kXWAԂiCedNQmj>ʠ]=iI6W-&!ODd+y9cJ~Xqs4g9;= vHƯMͦn@LwtÒ gFvf`x/XxŠ,>^]U%SE-r$GF9o!4~#n)1īD*Kwt;( ْv{]hFļVAIʩyϕ |BŸTnah^T1)e{3/+Q WDJ٠dEo) 6,uuL`+_?JYgYQZ%m!Rf iL)$jA'qȩN`ĶJWd>aO9bu&7n䇵wǶKFU#x5A^j$Q=(jIWbeB)fdD^ U^-?+Uܞp؝nR+m%9ξ^F&2~͍THGuODflFpoHeIgZ>JY7 6ۘs=l#h%}c \@9&,ޚEK͑{g! [-Oh?L.)Tя,F]o~VB^emMeaJBfv,eAۯ'W4ut%9bTv!|'7 6c-Z~maYܛ suhjJ4EIַ0JE6'7߯2Ԇl*IM3ذOV WbcDQJPVX- qzxƝTa$vѵFS> .9:H[g=:ND]ɡMpC?[qRG]߫jźcw3\WT{D8&7&Ùpaq ԑ_`+tMS ^i#c^cɯQOKIeyX7n[ xt!ҎՐ- qr;E\XvJ QZ{[j3~2G@vQr6Um:v{Ol)]rT~ÙǩŪ`bfoR1{k_@**m uu=[_(I`{(E'LUȣD(UCWZQG!hB8 hw҃p.ȶ{*0/y.nI1y>_FAl:<%; ':\H#W8 x_{% IhP?/srSc_&D0[<3L!zJA/pʃ( Ԅz6SkV6OԛuΓ|>ujvA~Fr,f{ mȽܢ= $`V܁ _>ՇVwօ[4j%).nwho_i獤6gg`-xߑ@N`砌ɫK*KYU_Eq-wnGZVT'x zn/LHJO}p6Й /Qή|7.t"܏CSiyi zTf՜jd|0k_$eUV%mS8{~;ܫ+ZyNfYGK}_MDUF&}8AtC)JJj(U{)_8w?!=0zkȶ{Q0#^bVQNңcWT{A[mfaiuEaS8^XͨS&s嘔D>y81ejGYfP B. xp*Ie9WeA;PI܆g$ݚqo껆G^4pxԈa@f_JNAG*KH:C% zK\޿v5׍{E2or¸3nF͢ S]\*5v3-puIm}ۙm!>uds' ͻϼoߙܞ.&kܼ\L#k~֜)~EՅS}wi,7i!q ~#sr c6_-7^O=0hrZ9A*R Tv(:ˇthDBU1e4#=\In[aN.)fSdaqMUfąyQ=_xMg ++כּM؞ t o$9=on ՗]kFgΈ%`^'w'UiݪYГssǝ|v~yQY(Ǥe_MYdR1L43wfzfe]fN1+n|o(0S9Yiм,OcRED?f@-.a\`ܙUu9SvfYj" SY?FӮpD~.RS?fA*H ¬i҈e'ie5v ͋ʂt@9&,Iq5e x}̙ ;3 .nX錈z`L1)ey)azf.0*ʺ`a3C8e"?PCYs6( zf.0*ʺ`a3м,ȯ, ee1;g.0*ʺ`a3м,*SAA~%Boh.J3 '+kFʂwAǪ(-BeAAdZRPYA֨ PTAAPYPYAAeAAAATTAAPYAAeAeAAej}mMM uM LF.OѠ??A``````L0`4 2{;Za>EeZ8lVOW4aJe ``````Uخ^ ow'ejimت Ư,c^Ï"!tT%ׯ_G-``````JTh.BMe*RYVl },_000000~:2ƙ(iq>15B$vRQZ &,Gv!aKs\c=?)*}$G"$Nʊ ,ϟhGl2bbVOg+=cil͈qEAeti'YRX>}~zJY^ >AdjL PkHefROgh koo+ۢv^wve)gu ,t@|ao3+ ̊n)eo|:Epwb6ۉ}ҝFݮW+5+cܷ!ךvU:ÀaE#Lwx+8\MlH'*{.TyY&ejXY@Vv>8-zvr'/r\Hg(ωLsJ񓁕pb;)bPTN}m?b ' 2_9tPxx8vwuѷ^φ`>M"KEG1/-[ %22nw"2ݝWTY.:$4'NYY4ܬܪ'%b-,W(K~N&,,P^0D6 *qHVrهp}+*?&] IC[ bW95ե9YUWvW64=G07]m_b[4s#sAtuu 0*̞0L lRq gb_xio\FpޗV>p5ZpNNop%6?nSj5W}bQ!y6p=]*CYД|"Rw|G*`iM|8Sh5+r|P:dfb}Ct w{Z ,k[(e鵛AA/CI}HfROgh9 cER#*Q+ f^j卷7/UZU-0WJ9Bb:Oٗ  56ϲ67_=b~3 !y!jwwa0 # bW|Vho4kuWL ,RuONB\O\;;Gy۬r + V.(n8#KYĖ]fYRdDN!ePZ@*Kbn0H28008(-e ʆ>F(V9Lm~p}7I tLIJtEv2# ȴ pAO s(̤0"eQ&X!OF6˶P eP( ,P@Yee( aJc38-:uGUnɍJ2eq(?e[mBCZ+9T`r杖V45jQvR~Ξkdr FJOrl8'*#֟;f_IYwX! vl ߕRv]*t7>6'Uf/P,uܠ,´>εclQ4Uל)x`^YH->bkGSI FӾN|ZbW ]g Ɩz~v |&uto}}v(Gs.ʚGG9Y=XG ]Vң,|?.e[!nv.\{U7$lXȜ. BYX]NWg bxkp eeQW^%FFnoΔ*Y遇J* %J[yE4ܑ)w䭷sG}]};Ml]L*}LJ:dȀDgx[|]<qI tý<嵉 8]T{9oNFptVǨz::ssO)Ve (==㾦^--̂!BPWN:(%SCf e) ӗ`fSrJW ɹBCLoR 4^Q*I8㻴f],0k,,ڶ;nji>);ϖvd 9 IʼJ[zUCi/yGtۨaP`Bg{aTqeTU٦FٺJlIvG|QmO`y)-P?]nԨ=)N{iM#̢,cJɔ..P,,)α !>Z"۵k,C2ue0m0QM8?M!۷nW3,RU0# vkvQE}@ai-\2N70Ī.ʆ'wpX9 ?eû?Qc$/D2,:Z!]aeR;ݧdNӖGaSUegaSEʢ9&MC2C5w ^#IcVYtK܋b07H2Kk,kSYt&AGwF.kE\f}aEcnLr\U=/öRK}Z=_L2[k S31jҭ7ˇMUqrp(lCwR|vڹM:ˢcu StVIMM+eEHN-mVY4K _C\dx`@qdn[3t8yea(%(w[V-m06P,,_)duذ`Q Ka ^PˡG-1kИf/UWn3,qQ\+M[nxż>Q7fOqq깼w\]Anw~ۙf";v;sϥ.}۬݃HC*fRU6(ޫ̨yeejbt1Lw(Ve,[,]v]MnTk;S/p!u?ѱK(Ď4ğ DlxBi@Y֨sY( Pee( P( ,@YeVBkTʑ! !Z-eQ+ۚ2߼N"@ƛF]ձLOWg}MuueyuEٗP_SգdʲT 9%cm&! "iczޚƆ汷ogff>}A޶4אd,Q yh@ (2S'M6݊Fb3F1kw4& rĶN(iÃD'Q50 QbS166cZoGuPE2@,DSFKHLMMӤŅP( @ _MYyeb&̾X"f̐d,V7n75OX;ף;ޯwn!?N߿F7 <WLqr03qkB U(KQ~1 Hx>~$ūWG$bvG$ eY̼-9IוEc9 apm:oz7-7T D /=+"妉zݤVHD?D6᝟uWsR,a(GAG,'͍99921d,S]сM")˔*s`Z{}!~7k|eᢅHzRт0ODeɶ y\tˮOߙ-UD%?'sLN$Y$#/B$BYV,3l~O"聩|e5;%x۸3ů,g)fOlQR3-3kPYEʫ+K Ro8m$_9CrQܬ2Ѡ,g:u q;f@GX@56^ ;N"td,Qimή<^cyW"ݼd| ;~d'73]o.˸G bqcr(._s^Yf o'0O ~CRȕⶊ~ܝ|Y`;d2tb.î6Jy9nCyw;pYYˁUZCG]_G>{os2?+LzȓʹMF&{ 8Hvnd{'ye ndiz)~+4[E3O7[/MbeɁIqDM8Ii~-B}|M(\] G?;PT+(KǽƗߵ4'{ͿkNl:!H BBYo52m keUU3Obe]׋8UÔ*cfAVU}e-M_9l%Y{ZTV4u)edTՕom_4c 7Ѧef006F$r|5iHyYYq+|+;#&Q;\A*p3L}{AY#6-Go6rSͧ&Ԕ,HM%$]#GX7W:I(zg>ME{o\';_SWUKfZIUUi~q)_\!/,ASL;'ROՌwz$"is ڢc2kϐB @YSe bem}6(G&G8i۵Q$٦_"d404?f=w sR<:i ^䝮Y̨|?q>MpKAi:oh{zxE(7̐~(0F@ y S7{~Io殺lgDݙ?o!dT}YT fB^VY>MԞMa9K]Uo"M ƺ~"9(rX_DpWd^Yc;'?ZNs@^UnU|2_3b{ϼe$E$BYV,\ iŒM d읡ݳqv'Z #&?4qfemsG׋oH:g`;Ap۹{Zqhe-0ɮǫ?Wݼ(\S=5*ιӜr׉\&!OԞ+"OO #IfDZR7fHYcl·)7[_MY>s#JQW9>&eURN"M4^,4 ŹX^kOl6.~ no,ɉSSS|i;,-ks s wm?pӦ*{C: 6dnqI$瀲[ǡXw]9?[yZhFW|،yed![Y|h-.LY,cAlbl( ϵ IY?5L5:)6 cd\n+ڰ#6ڧimqLB~=w:{B)6n6^swѦEkV,f W~asl$@|_ʒ?5޾{7)t!:tscϿ: @^#IHI$ eY|r?;H2e45khGo**K^Hh׉"Wʪ*NZ.ea mp/!Tߚ~ha%֎h'D"S/ͭUQ^QOLqX$ O*(,+L+UZ1QȬҪo5~!,A+r\k6i:}<FfBryQ\T5~{y ry0Dyhەy<#1g֋6ʔWTȳ"W,f kX~ش>\Vy);`y}ɯr̼ka'm28etf $'{{iߎ~Jnz lxz| ϭK.oI*D~H$Y(ˊ@nꔅ[H~:~1v"}X?.2k;+$,u f<)WaúM=S|4tRdqad9`Y/Fa6[n9S.,\P~>?uoWIêx^?;iGX3=vr_kHDzvdjeתS?%Ǎhk/HDkD?&O)Êj8fszG^ΖO˥+BV{]s&{l4dqR3?%|f omK1Stœ,t7c& +KRBǏe9e*o7/-.\_rӿ!H"H$Y(Jˡkႅ!Uo)CFE ZY_FONNr#;WFY" 1bw~{4 %k+ م8cH"H$Y( hؚ'gYh&L7זDs+`&BG ZYb_L~ H+e4!###ŋ7os9߿/]Yי_eWrMQkaIPEZnMTwUDi hy1kx΄O^X;WёezXt,hi T^\R\D]fEy9ٌlp;zhގIPʒE @ 㘞^BY⢟x;VQhZV O#lF^_2 I$4$EG&@ 1<4zbܴұ,QZA>hZ#]j4Žc,5榤ء@qxpuBlow׻&ʲwcZ7_kG SŻԚ (iR{iIۥ\j72 M ?K^6S̰1[t$Ԕ$.CY_>n\?m.د,|a|lI_BY=e( ,P@Y,e( P@Y,@Ye( P@Y,@Yeʲ4`CQFbt|a7J|m UQ$\nTkN\Po,s\O7;K݃%7YhEn gCKНrNtõWݭCyjd,,Pqݮi3I#|}29P=^:_RRp:^T:Tlm rȄ>%k+}J7(lOz-&N^F([G!):󹂲߯0]\YvsxT}:RrS9̌2]; rmy[Ö;u4ۗy߫ߋaXFh-yvVY{,afTa'STH2yǸ>(us|ʢmy»LMlc ס!;;Ȍj" ^p—M=Ys=.^n!6j)˨ng9NJThA_C]'H͂zIDPSYT7M%ٛjۢl`0][QaGg.=7c_^fFYF'>(7kh㌅ ]uQE}r|ʢ,+>!1 \dBPؾCs)Q/)姸y1!ܤɲʢ)X;RItАF;O`z5f2Ꞷ>5w\SPN0O[4qRJ ojb'ъmLtU^tςWGsm{Yt,hM$;Jթ&RR~-ӕJWK ߛ{ܛi:F՘|3d2=S:?O . o?]UCsϥ.RB[n-:TQU'/F52敢⻋qT9?֡"J(IDUbzz:!6jbbUuR?,kԱ wMeAC]񷫟P\( UeDw+O:AUOP%ZLv«-eYJEEn~ypCqq ;YUafRRRX8-d3_X˾,c8׮oQ|0vį"ۻIT}muᡯXfvT@m@YPo")Ecxo+%=\0Uל)[]M,DVam>*L>qrj+˗e B>;}{s$wk4LŇݬy; ʲ6!$v;Oiҭ 3[S.'rJ+*+jЀݷJo,3OX8s e@Y,DeSʲ&jps*/+d'=:-իsDYǺt "e@YVFӖv6y0p?DK WFusO,2Q-̆fz0ñ^f2=?=wӂ\3hC?s,M6e6&e`iF3: 2?+l/'0D&3fbjq{ޖyQh^k*g'w5UcsgѦtiV~SÑ hEdua)Aqu~׭C 66ӂKlT4,*>: UCyw;pUro.Wi1Օ^$S.75l!?_|htnՕ[KנqՃBM;]MY-R.V"+'c_'U7=%=1)p>NZE+( B.c-J53RnP7=%qԅݮV2>,)MMax6_uJY';I(əɾhdG#kʒ.Y].ܖ?x[\[vZP{geΒfG?W4ww31%"w3&S61\yNYLV-'%2<'}LFUsÅ~VP**hU+˧̼ח7,.4pu]y&ű²سEu\ h(\(^nOx8QŸҼAef NvI$;:)9?IjZWvF"'MY}Mޣ?Dw$+1e)n03DB9\(Sk[{Qb)҂!=~ .M kKI#eq[HrMmC4mFY "ﺕTTQ=%ݗ`8e %zBj4W>ߴ@Y,)S!(1i'vg4uf$zu#Ԗ[* MԝC$ݮ}5)}i$xH9I#6QR,zTST fR~pA rVYUnŻE>%_=pBO3lA"AUE聛 m 0V^/rzܭY8U$riz$sƠ,Ntzd5:ZxGiZ5Uy<ٟ+")"O'Dnг.:@ٞ.V;kZYE|Xz _lon1U/cP( E_(-S|I,bܚ=U{r~((SR*o,S1n~G[x"5ғ+RɮIkIn]{a0DP?UYLU-EZmwTeJ[츷?my>12_YtxDy>davv'0Ԯ9e:Y$~ֳDKGDMx' czΌ* ]i-E)?eʮ` e,故S;Ҝg{(dTY/RhWrR螋^9t? hӵ*eenRWS)/.NF@Q=sc7L_NZUFIZ 4t_MYU)E}[^ByD~:,aV*gOfbfQ2V&E+/ߏd'71ȯ,7+j;zG9^,ќ)K^EFٟLM-,Po,mdORa`VJM@FUyk %ٟ=8ʏϾ~|h-Sg~m YW3f5DvN ǹ( /Yejmؑn|g e';Roz v'e{Ti\"bI9^,-efmW[ZYfؼ]EUc xhWԢ!+u"'SqۈGħ_zDv:TY( Hن ;P6' xe o ʢ#^qAAY,PeW m)9EOQְfT&*>$+bZ+zσԂW[14+ܿI^fYyag֋6ʔWTȳ"yH*&/bϢBk?M4ֻ]I3zޛWOӚ샿~p_XY䠕Hd{4>&S^1\y_vq--( i'=ŔI#?gjT݈,(.{"6,[145^Dx_Z29 ;h՗/ծD"CŕUe~0L %fr<2"?9B~e4S*${“ * ScJ՘}(˨-n'/HwTϧMo)!޷FXf #E9](/N)Wbef%%lVn]XD op b~c,ld]s ~ Z_&~h'Rv4[vEXA/;=otٝVj_BS故E۞k;l7r (SsmMd e'3\r0/ۺR\0.QEOOp {l [2,bhr0M)S?&\BY>񋜟f),ElhO> sʋ~}gWL+9s*Xþn_,\JM WKgw0ZlNYX'jR_}_ŶG^kVbe?XTH3 qj( '.5YkKS:P( .N\kMԞ斄Q05 wEʲřhi/צʡᮈ;O(_jd(#%Iц`FqT9?֡"JU[sSRBOTIbxpuBlow׻rxCE| eѱ =̴݊פABlTfjrob;T9Z* J rNOL*Z"O( @Ye( P( ,@YeYh:SC_}.;#n<,Ӯbn݊kW_Ȋ'cJM[ꃰU(M'ӝփnKx` =?5w⛾0'tSd3)]Z}O}̛} 'ߌ|qRꦤ JeQV^t6jQ#Wqik {U**rkعVe}HڤU7\(kU[J{)* ^}iG쥾Vb!Lop/~[3_GLS/Jvnל)[+3zF5*?4]]>Mc{ Eؓ9Y4LwDy/UVXImf3i|AJ͐i'=wN. E{ǯ^\;s3Uo_IY%26U\sHje*CBnyh-WgE)?gO7f'k~N=r .jEVAO0b;cCLo\< b|{5u 堈!<c/xKsY1D&s;Ĥn;]9e?<&dvFf2pw|7ځS>?$㘭3Fɘ-\e8/wE&ϝoW[pœw^Hl-QgL(qV龜N߮V:.ڕ֯mIzն,d n*Pn4tO._WK#N6m)nՕ>A\cl_8 V^gu|-13e"elЌV@"e$P k*) tlvQQ~fE/1e{2o察ܘPԼ줈ّrcZ"}CyE9q},fW5D)ǐ H)١dnV&HhlollU?7YyE w8>AN-)//|rԑlj I_-,C2auɻ]:EddvIEaUo FɥHόhEIvFj͟k7Hx\LOJ.+Nn?h,+( vM7V] ٓnq~e!kcbϹ5?$~aɥՕiie~{EIB 7E_쑇yoE]Aaم{m)I`d3FK1]} ]rp.ѾP(כگe7Kj`~e{ttIAp1[DKj˝Z͢!u'D.:@buLۛ[b+{^%@YXYodWTUW4ih`J9JQG;_cLϫLȝ+17;p{%:YUt-$;!_2Q:V46xؐg+[EYeQ_r$w:zɩj6LUؾTrJi9pЊ, 0.,fy -n_GWtV+1%=)gl&2ǿusʢ\jfXҍ=(KNg65~b'/ PjZ鹁rY67'O) mzkי,\lN'Y$^0|0H4/8";S3z <]x?_7DEcjZpe P1 jܵZxq-6,,+jbB(JsvbI5, fٛٯIsSKl?P ^1]ĒSǠ,P?e 5na>g. ^2 /)Eo.g/KmҮy[QPWt،h^I_B=aV, w)a!ޕ^M,jhνbeYjY(_j(;dKi]#y-_&dO f\oT 7!we( lW|Q?w }S>}j8 j+WmGɐgA͵޲}K :\$_GY~~p﵌ͤ%0f40H)693$F/S8 /ݮ5\.ˇ.\-d~L[eGwZX<-=$au8j/'W?G_5_,} :lMBڴ+WEZtqAlYD,snABscqKV-7_˧rlちKmhހa`ʥn( [+n0-%:_\w,|Cyna_(ySPQ]]Up|}izIQ[WTʣvZ+ 70:% ;>,<|Ѫ]eYN#R 97(W\#e{u~Q~j|zjPGƥgF_dpS$~_UV#؁#VŹɯr;&W zSJāFWvfrM.eDCmqRJs>2P^\Ž,澎~Ź:u SǞgԕ']NYgOؑf\0Na-LN?,*ʎ>Ey&g]*5aæ#eCZpUW  6fV0]I!V#qr\^_izr^sLlE]HgY~d(|'de3y3 G xF7=!,.FJYT22Q3{rw '=lwc\3]ɸɋ_6) ȯ7NBeY\WZ|qi"ȝ\\^Q~Fbr0cf_7Ż-Qdĥ+ksO8RH8 檖%Y{@It=Ays.oH)ٞ;Iy{I]y*\e꘶-ʇLТ@Yp2*"O:k,ND LO{˥J׳ -1GX﹚Ң-ј#Mw)߅% ;uubSªUxht}50 __ύ_7)~.], ?~KХN3Õm*~Vv5Q/!+CT ަwx; Qm=hַ:eCl|`~q:. ӝFJBDRY0I#BȀ]3S5]{m ayqjE, xQl# -?‹kjJ#(w=+ʕlaJ;Klp?%onqO-w8nP-㯊{~ sZ|r޼b;wZ )`\ ŲCȳl[.z^P> ZʔeQ3WQ'EjK#k՘ gq Rv/ VhMZ`j-k>s`*T}5q9H?W7\!ȕ_TLtŀn:O>k?e||߶\eSeD'^'JS{g eLV0EY g'f]\_!n ?){fK ;Q0=* K~dv @Obe; bC)遴5Cs}i\>8Egk+J[y?9?M>U4 eEv m<X Ue(Jx5Mff)ѝZ\>9?kӊ;%eqyК50ar\nP@Y,@Ye( P@Y,e( ,P@Y,e( P@Y,f%Dg?7)H}b]j3uk^{1UeU(CeEI n"t۳$ Yv:<ҨU?^Y^y]P֠Ї !eQU^eT_seuV%#|J+r#N;[r[H]BpnԬ',@n+jʢ{xAfZ6,m?x\L;^$xP#(sLY N tАYBY#ྼ_ wfE}|eDNCʢG3{_jYE nuxf KDN(^yee.& v.f-9恷Lj4s*kk+,r%ݓzԖOٙˢeiOwr6KOo >YG2ʆXm?,,\G][sZ]|Ccq%v2R8n>nįiOW=_s#l'[V<8,m.-*( P( ,@Ye( P@Y,ʢc2T(:Y,+co|B 'i|ߍ4ՐFbnEGks#)i}Gi@ +X񛤉okiꄲ3v*@ bb#`A;KNW]^ e1KIQb 4.ߩ/@$Xܞ.vEiq,OG@ +Dk+ i,f)!e4(f zmFq n0ƍ,Q 7Ke1WkdO{(jO.=@ )( i,fΘ1S BR#P_&)ۺ/,LjxeL NSxw8e"1i,fL7UeRG=,FNo9&8?^Ey3m) 7rևmcޏvH'43mt/NnL$[/q݇_IA , EzG ]D;;I %>p ϼ޷M63̇&*-b Pm`GO0vp|EVE}]|{F j,攐h&ƵQ{~;zܴjlkʵ;?v 4:?;ϠpMS/d ʈ,.UKE<~"h$oIcPGX{ި^8]ycR^"`+$*;𸨩gV'A̷{yEtk-͕=6bT{Ru ݈U&UgW77f=oQ~"K^lYƌky4}hsQ=u䳴PVYhcY\*/)}$ {fYkYNdM՗<Ѵ!d8R&f*fZn:<5)M9L|9jQӼa,4zIXIwmŢ1U6xws+;l(wcǩ~3ћ5=<|҉Ȓ7fX5i,=(nZ).ݔ>$eDl¼sj1o>|Fo4^d'^ Clϓn8SZ]trJ3T l'AmT{z\kSN{&uV]Y@N¨l O|N<<6ɍYc{5b;;[5Q7y̍yHӮR=b4RcY\*)|M`N3RW^󢛩K;(uz4v_g:d9JS^;zS6tsƱN3QVs:݊U<ʶne-Y?(T%Pd0WtGe{"mxdѭZIf2%wcgSzժR1/4@L1 ʈ,.ɵZfQ8J!Ò*N}Čn5‹xj/z~+mNJi`BP5zU^ˈfChk~gfWYQvN5ύKP{*P32:` Poay%e_$Ϳ@9XVIuP)tA>=XO4Ӡ뜌y bEܧV*(@%4s7M#[ 0ѾK]L cY\W=+F橽j&*2ωpW[Gwki٭. ~jk4`uvvS"uZiPFdQftE_q>\|*msY<6G%Ԧ61񴣣ǧ)(ryC4dDdq}-K^b}$$eQ<}MKSX#q 1#ggҧRdQBdAeq}KmuѠרEjQ9g]:k^[1خ5U]m,.ɉ1(~Qb~*KNNWW/!DlRzJB^+i8_Y`CdDD@dDD@dAdD@dAdDD@dAdD@dAdDD@dDD@dAdD@dAdDD@dAdD@dAdDD@dDD@d@dDD@dDD@dAdD@dAdDD@dDD@d@dDD@dDD@dAdD@dAdD*,,,,Ȃ,Ȃ,,,,,,,,Ȃ,Ȃ,xUYYYYYYYYYYYYYYY" " " " " " " " " " " " ".TxI` F,u߆%FVo21>ZU^LbR.  QHd4Rji.+*J j($PT'!" " " " ȢQFtuvv12:WȲvh:[[f{`]&cK79 pH+f,λ<" HD;(4׺ uLXeai~ڽ`3=FӮBfZHBNbE~Z"OsEiFh}I.)!w2,fQK YjEZXQ4b λK{fGyW!uNɍ\kFUBq=|1+ܚyg!V,~~BnLwDZ3éRRcM JVoR_[%rWq~~'!K[Cq$yUov?=џ4o z3nqS{f FXfJ[pfp.{|m>k-έnI%l!L(1¬aҼ41e,!OL Ν}T7k^ry6/xߤ%_XKlFG>'=W]vë pbM@4r|u{^̧f?o[?Zub_k:<-.8W[,湊s5j?\?Rwv|B_-Ʃl|7e8۞~.:0)Uq$ǗR5a_drUz08bHk?$^:]TkوA Zt}1Wx~ JxYHS&Oi`hh:dd٭#;Y~H[06E?gg5CѷWgԸ<4V2ﴋ_VXSi\6z*O|r͒zBӔ$e𢡊pK}ncOs~SX,X+ J--!W9RS{(TK#:[l,8}*g`O5[؁qu5EV3INN?}w~h1ZL<<8808<1MoCw1yoUޠp$H֠-Mu-ߴͧtﺻs:֋* 1:-<Ƽ.'5GdۮO=ͲJjΡw^tQkNUY&"˜L;v-lhmmN:'1ڙKiEcO6iZ?t6ݣMBc-8s;X4.@՛fdnfT5WSZ9kt9lEjŜ,k˚:{֊DkUkҕ+V5']&\O0<9DÛϕ ^޼`I|Лv6;ۺ$zKՖj|Œ|YX|ҊDj,%"IG3jM:Pk~8CqjY;t۪4b6e`ך&MϣlWxӜ/3Yk%B' bA\=c2kzcRt$Ncͷ/߷oR_P[mvZh{V/K-.{q:iGjQUHyLk^Qis&`SV;MiVi:277ӎ݋6#x_g2W?]58zJtS%/cn8x!q9xdiPevAxŔKKI/KEKB01'[ż.7²g'O}~ċތyz0#ɺFT/ Ejv7@/^j,eEohMF8[}F4F8SVc:f Nƶ[66Нeg)Ѽ0_u%ݏTFh>m4bxUF Aѥ4:-?[//H bJ2'ys…uQ#˖WpANEe֧~NTO9`OER|DVoRR^$t0cޠt0mwOOgՓÌtњUgٶws%||ƴ2JSbSꁗG-2:)NM]D<$Fiє&Rڱ{frtݣ(K;/O2vNV]O=M/ϸ11NN;mPzy?QDcv*u z;yE5 +~`-|jI 6!<_7=y1.mNV^`^g5ϥ c{ON\Bk%[xkRdJTGٶͳu튳%v4YBޥIhov,^t|F>y.;fy2ף4ҏQdiuydÍ{c㋫1H;O|vy䊔QXb7bϙyV'bNgucj{yd}m婥)r}OdZO6b!fi`kAzE9VtO/Et jJZQ˿oa;nS[ۡƷsUKUfvYc[{^BBޛpbuxvM򼂮I[ԃꆆҤތlRU3O]JJjcƚW2ZTKq7ƼWԔ}R6Pt8 EyO|- R5V|s*i#d,VǯhLԨ&QI-kl/MUi4 ciQkZEݣ4:جOOۻ:`>_J%E 3b mv3Nn .ocnGCSkkK>N+\AꉪKlլ֯owwf 9;%>Fw3ӳsƧ<󓦶%k?ȝ-~>~} ꣓G[x0?GYLJJysF>xp R{(ߡ7#RxO'^ (T< =O۾牰"6ʙ7َO+ȔJb-ꡭw_~*</syZB0f:9nJdC|zH[ݶ? }ibcg'߲ąDžFޥ?"ô?D9*EQ')4NRXYFt(.ڠ۟NSd9Qf}3AO;v/:>،\hBmF>Y1Փw֟3{OޭUf,3RdmIСb 8R4$s5QXzyaѷ꭬zvMS)b Ѿ_}!f6hGoh~P}:L,!>BvSY}գjKIKL4CZO-R7Pdy1?oEj5<( A@AW B{F1ZO ]!(hE5::mwYg3Wb(8r!@3T3z -I+, Rj6XS7PdJ!)%h~B^]R2ω/M*lhy U@ڱ{f[R%u&N;pS\S?c ?‡|>]E}i}XEyGEI3QB96KH%3l6I!Z$h_`J\ H?_h M{M P{@PKgidD2F|IpYwq%=_O|ODI'TiC2'>|i*#5Z9=SZ)ǵTZ uUŋ_Z_N]3yCC:]:=5YkY`s^Fò;3WOlׂHHE:?vSj:__6]1ت'(掏lWφȳs/~J}KmuѠרqr\<%N9]dvLe\b^%]eK:f{`&&ǜx*@bmg]kl:G/inn@gE,j0drbd4 Ww/Ό491^]QRV\ Et~;mBVfe虩gf MpK6NvN _u[Rn"l?/=%!/Rڱ`kin/{s; ‘Xc9a穥k+k,?m1z^Vdɡ?655=YL&`p,>}jiiAd_Y BiA"(KP\A2% :({P|! ,..Rjq|yʉ:)ggggddS7III RGAAAAAAAq]D`@Re J+(]PƠAyc/S,RxdeC\__O۪*///+++--IuJ%(QPtA u|$DR/Ykqϟ?&i[mmm߿D~'&(EPDAe J7D^qS"P>#H-Ο9+_|mJTzPPPPPPPPVDxA J1(iPp҈#PJEǹe?"ε&i[###߾}*a{BAAAAAAAoőDDAe J7C,F(P2E"ε( ,mkzzzJ*2"NPtA eyRʒ\FM(JTR99VÃ"ZPƠAyc+""ˏS`MhZTNE$DAI򆫼$ L&\Ew#QAI򆫼B)N7IENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_general_local_encrypted.png000066400000000000000000002221541477034762000304650ustar00rootroot00000000000000PNG  IHDRlsBITO$$IDATxWI;?s {ql[lpGlpg8`cL2s9JH8|nI {}׳VWuuӭş?>S񉊏:h͠!r}b*[.,bZ~X4e #ƷZ-,2E_M6jb5,FA /`/ -+i^?@*_"A8-./ lFBE*_ kyuV p Z_:lY(e+CCC lZ.d2T*BlNW]ciou{Lh-L~J&`[iPy<c> /h^/_~JM`l6v*00000000<"F^vaBhDY,G0+`:$miiillcjAXx8X}lb-X|Wqh_M~]<AA HE,(((++w렭r_?}e``+y{wx9ns  Mk7objjj=,Nb_,W޿o0zFd|>v~W6{;y{:" |6{/666== <l, ?GBO?&o8{y8  |s@3@6Ο;U]]M99lSG '\lW. xẕV'adߥڶ6.[]Ʈ 뗸(e=,_sƥVny |ryM\? @9߿K9[/"$s8ZUU@oú5NRpVl6TX5),p#9tIW.tw˼VR2BcUNk aUQw`-Xz+coɾ6m'vT&+="|N=sxj{M-Yp_M7tZnXGo+VXd3K7^~̂ =6~^ Sqݨ(P0_,BLPi X-ٹ^Fo%PmYa yC~K{ϝ=vPk` yk)8 KQnѼ_ۯqn˦MKzy~]3L_cfܵm9ho3},pҭgCܶ%v\E%Wq -ookt4P[r2w[hv^y[ZOT[P_ TrDFFfffb(X,m5XY-i' XȂVZ?9ׂ̃OXC'A=X :yC' (s!KIX|ʧW.Xdp {M/]~%muUgTv]΢,ƺ+^FeJ+eY`Z&ͣd66bᒥPkZ[s۞Kگ=Cߐ_^^:/ AA~*@9ܹB+ 8TeF׌n|ab ݽ4ӼnIsO>z$Ų<~͙Ӈ-'a sMFjS\ m70?K>Rgɼ_񴕼5|>?>ca?nM( ,/~]KiM o<^HmH9~yߙebudR5Wy~kò/ AA~*@9n߾G+oV݂m E~G4y.j'5-!OǶv-C A,XPyY N¦6,_+FxbmGk/Z-=1 蚅 GdZ;κ VnȰVV˗X,`M/{ɇ._rz+eYdMSu~/_z! O(,Rp!Hf[[[7_i1,](WϿ (rǪQQ2 O믐Rp@P 5$lܰn%V_lnԧ3!/"E2Ifnٺ~ʽdRSŮk~۸zq+7n l+rx؃"߫7n+V*oť:v/ AA~*@9^x6Nb7C_PVlܰj V.9f`?~-rχexeXC'A#k~ܴi}{v~cN<~[g)8 W:޸l_]zg7.\bIk>,Xa"bZɇQZs[0o޼k׏_n,L,Km:SJ=qerϫ9ŋVqްnޢNezV/ AA~*@9,.߰~8V,_o|w_|@A.{ K}݂F ._}]wn;v,x<Rm[hU&'EFyB;;eM,/[`oл&:#v ȿ~ m)+e!k걻A?yn.,UtbAcZʲv2Zq \HeSpR;߀[vC%vc b;M&kx~o"5׮]ggze>ظl5ٯq7~إyEVrʲl2keٴvݒ2 b)}xWʫ+=:lT  ?R5LȊeU_\鿙,d|݄Hܶm lCCe-o_7oMkөk֬_t9y[Ou-gM&\zE+[/CEQ0,]jMV !%mE\oؽ%-bA'cZʲzҵ1+,h?F⿱&!WX}ͧqk >S;ytB?y$CCKAe >XaYC?PiXgk$JD">a{q`xo4 a#8i$F:i6B5F|TcCfؤfPO,ΣcF[#IkpPoFgj2R6j0#~%Y y뇩c2k fC+<,6(}c000~L3}D/TIؽ]>~dn )_EҒb\7\([v!zr%CFZo y=d6 ;*M*ˊm9>A-000~<:&i [# Ǐ0jfu)i^ )P (++s|~YY\.7|<mj 50DeB ">X?TU_ЛlʹSQZtֹ>(hq)}' OzBH `4]q?A#LWʩ >xP_cY .%ES/nfPmj~mAjM C$jVRYtϺe,|3e1 _=k~^VU!iv,jA9L;AF`t=b|F? oMlޡ[З:"υan'Ef/d u$%N,7e,+` k'=!pak$jLNH fzGm#J]ZS]RVZ RłЋb y^T:G3d0D}|D.|݁*W|O{YClQ; C/rZ:fWð&e}[w A3# }3?S*@NH?@Å)iW=NTrĉ%UUV477r\lTOՎݚNT R %9IA.NtEBCOBP_ԇVS[Gan6pX Qti*HeI)ea&!&MbF΍9R%ڿo4;߮,:Qaz70-nGe|BY{ËVMm8?gyH]@R2\+k8$|V7a, ,100]]]AAAݖ{ HJNH䠬&U?0 TҤdRW=+YwpF礔%o X=8X\Y/Λ7zC:LCU~rѥ* u*dwG΄{[ج,3~b}h=$!>'OdCrz[r̈f 7<3,{xi&NX>?7˞ͪ݀5mΰiKH&1}?FQqr`&\W+SNr ^V4>v$GccW Lɗ 蝄_xjsn+A i;=M$;),8BG h`%\ rgՄ65;rvOG1E9lJ:MP(iK{w}>\4Dmȋ=Lnt䝢qa}i&,Zz)菐}KrȑPx/;0\:[ 'FC#~`k`HĢǏ[|;zRh?g}(:Sz"$G0_s:VDzJ C&~LtQ\vz} s^ONP_~C^UuԐ"=;C;Sѳ fّ$)<v'I\N!^,id{MG`ӈxV5bue=Dx@IN\ducҮ(JȮa)ljNezBpGe7ǿ"ͬf+[ӊ㢨n[ÖkZE{j8'!6;5sKohryer$o*5=13˪j J%V1g5Qrayqʳc7]JlR+Qm(VRqӗp;$/xGK*#RYm*K~N&u^Y_zׇ4j7ZzŒ sUՇ8u-M7my^R8uu\ )u%ww3j8K?@|-(awީ$\~[ZXWYZ/1ko'o J%leq>ez9zJYECa'ڌ{mOv A~N:F 0\:ښ!3FL zz_+Ǟ(?=]Չ50Ιk]9`ʫ+7LP>K 47:jlN3j:Բ:}GVW_r>%6F޷!}pwEFymuaCbT~ܙp>]iuMiޠ,/1uV ),E ʢc2ߔZ53*awdbFPf(ڠP\im)MSI.ieu5'3_(} O,hmʊ2e\n@ڔd&5PfG1kEY[KftFUn+OdQ3CʲMRV[߄׍ RY\C+On&Ct H+¼]aRoX+ʢ$d8GN> SS/YϨ3DHD^~!(h /S^v%nj0(: ɇ(`6ԕؓ7uʎcԶ(ʄJ o!?n7zVkٲ ,FI, K-wɘz:b6ݨ ύDI} .lNHMNH! "?}رc}6nFEBX׉̷ 6%*QbJ_:MSZ[la㘖 )ڟٸ@6+3 9WE`ıbwcߣVIu܉-Ou=;s*`eZP]}D,'ʔFvfb(UXa*5'} [#I{K# !ԸLڰt#@{4+'O׮;v;&Y.O5+7Sگ1eS+ސʢhduZRrf3qTtP_TVQ,P64B Z [w ȨsLYiIlٺ`ߛ= zseHq/ƽ#r۩JAYRCFYQFYi#,=L<XGLzEX˱Ogށ˨-ŵY*jjntZ'LbbFitic3lQz^NoPVJ sJUa`Vtǥ0or  )(eyʢa "PFj B/ i۞n%|n7wG~]Z63ՊyIl uOVyn@/ʦE$wޜG' ɨFt f.%Ae5d47dV*,[VTQ5R@YJ`= ,~)JI0Ppak$imq\PRS|EL64"^jo Joouue^#"55J~9,}JN-%Ghoi1rGYj=աyLxɻ*טe,63+jnz7O?MU-|4ɊHeIЫ>Fp24*k{tfUbS"e4&U ˻6ЫŔ($5ҪUqCӎV0d};3“^F4Kw3e2Śoyf5o8nGTe8E0GwZ,Nm NTr6)U iY Mrd*0ɌN/kffdc+0PҭJva43<7k8ZZi[b*PkVӣ :c4pؒ"X?mGMa^ZqՃZ.)8{b*2? 7'Al^TYY8z;؆ "5Jܜ|uE3ttvwH*mEj*RO*KڂT^!I[KfDbaCgOO[Uv )dJV>0QYvԠ̸N_cMc_<[Y;+7C_u=p-^d%g[ʢy9nPR_r.|~n7}asqwԤ>'e眉U1-h5œ EZ% s2Vް"ZSʒŇC%-Fr#tRYrOT=o߹l?0[fd)N+x~6Ѓ*s'9rjҤ,RKNIy((˫.,%ͯlwv~ǁm;{^ .!Ou^Ɲ:h꿢pakkn~XOFL+0TDL6jJt%/46\ ,5R"Y jt56$vW$VE|S/PkaVaJ+KD絉5fgDz5Ud@})gbt pUϲN|N6k˙냂9I 0&訛0P{=لd4$ }zZg7Ԭ.YBC׋utajv߯E3yPYl J,QAJ -,0e^˥zjBRkoiɓ>IN0=4xZҘwn HjYbhh=o<,6i).3wofEا7 sOVZ ӳF_g;چMŴe('z2/N;Yj\5lo{Ȍto,o#) ivzJA^X$6=WzAS^6!M,edAζRA$sa[Z)iV!gcZ_?Џ55&'y b͛Wɉ0Dh9a5UVU7@M8$C+y,rLKY, B@9,.FDA{1-eYbo  cZʲ|RlDAA7R+Wb#" 嘖_AA (Ǵe ؈ |o@9,Ħ ˩,+JH@-  Ȍ1-eqqrfeϟ>17jւ  3(ǴQ^R(I!+J  (Ǵ?>@-$"AkS}MeyMeٜNWᇬ h0ΗȌ1-e=eED 2<bVᇬ h04/Z 2rLKYo񛪲|4硔E* s`>Þ75*uv-u1-emjӧs0N;=,U!5- [SYS&2rLKYvLY~@-.F}`pU!5@B#㔉,R{vMYY>uhe1tZƝ^.nX 4/* 2rLKYMQY>̅xm{s=٦0VАNзt~Ⱥ`af3C, 1-e9r`_r~% r̈́P ZY7Eޛ~bػ^הRZ>mуrU_SJ)iJbvGk7 Td61-e9~TǏb'?ۑ us3{m%'LH)РFkoz۟ʿ7a/8V ʷq;TaQIGb_"K5-O׫%3\8#~3n}@)((nkT-NnWh**1,m|B.Wk͋ʂ8R'NUYB1;AJ/.KO|y?۾2 fe(դ,z#k|pT.0uRD7O[_SJC)K+ߎ'˜UUE5$\|`6\:H_H;(/nYPz֙ӣMj\ĥnc^wmdiĖ r=SP^_grO܉-;B5EeAfPi)',2I<@s$1y1v 8 A^C;|\=\ddTĨjMK[<"G'wE<%rٗh|;Wkq:(ˉrՄ jr<L:)0RYZd_SJO+W;Vʊ UWm_TH)KkJI'JbBTuǗp`[Mar|AKLnҶ7a-''-}槓;q@9,LIY>|;ܟ vr%Qhۙ{)͍om'}oav*$xECNWKq >n%*z<:3첂ڦ0؍z L5&eQ*#LH)|z|wʑ|HjL9}xi x IY7Tf;p.+}rbu^WP<] LnyKVjL0{ɓGnS>x <3S;ݩjxT+R @Y& ? Aۑ+EtՄmnJ^c: p"N"Ty vdZEntvMl6=rȥϭjYǎt;x ,M^R]v?:(rvC;72hu1<>Zvw7iח6f1~ѻ `r#E8)QI^!hG7:@I{Rr;ދԪa-q 5%7mhEW<@5G@hzk$, u9^6f)r/7UBuggz{GvdIR7uXf KZ %q'Dbtd++KvKۍ,eY@B>X[/z|-m6\P4$\|.QY(Ǵ SG1(KO0;͚IAN~kTUW܉,= ǖ':j:p8Q$7M/:utOGAVxAΕ C&eQNKP ^?W㑘{,+ӂ b⢂ȋ[nɄwĖS %tɔjRY~oB^19SUޑi\Uޅ y8/-nRY$m vbl )*NˁrV$p?qg*\,RBFF_/R>GܗyփY=YME_%/₌w)erR)T?P6޾-|~1YOp%*0/yhϫUdq̈́ʼ7 awTkB"k{n4 c_LN2RYjnjlnn}Yo ^%k +`yVXR^]U:(tϳKJbo Or scnAJnS 'g os"\Ot˥M/ \J#$ ۴1S>z78R*`!"3 Ny07†Fh.w^lF/ nyWڲWj"(˃W'm$=dMо'ŹI@NΤP b69QX^S&WX\Io"_%iw^{h[Η$<~^(#3 18퓣CP4 l62Aϳ+k+22 QO^N1-e z+Kq(e45`|mЄXPVq$%ܷ{Ǖ`(UL,:~iŠm ٝ;* TpJCRG)KrtI($ P "f"0Mb]VP} қɕ3l*wAl :Dl}T'Kɺ 7}zOjw'=خ¨p=_,}c;~QO탸=b'p(j#&e醕JYtYYabI'Her&t /d+BV/cg$ fܭ&Ȳȝhc cl\,q\H HNRMrPFr"_I=aC++y\; Y'Ţ&h+׳\™ǜAonpVy`ּW#Q-Ddjֈ@%۰$#m"%mrϫQrO2*vUQs(eImOcDat]T\ O&J..IyvXR}ˇpGqD4ɠ/8 j|EeAfPi)kS]k)Ax#+i|V #"\PDP=1 =VEBxeѳc e͝ݝ1SSwYt:Z‡eE_*5:)$is/񕂒K0ՈGWQ$e.5\N%z4/Q>zg*%e9+Kbvw9';VhlImuEuC;WaJr.y†<k8هA^vJFmD܁T O'Z dn߃Zs;(e@5nWD_Y袇SpB/ݒZ"OV0Ar|nV ;_"e `*h) ^-{BfLRh+yl>rIo>taIO J;C[/(mइܭuw ]u9W۰$#'E./ ~"3%{+4ԫ2s%y 5eq0-cD)CEd]W\!76IX|lIۍ<~#;L>yyVAIƭy~ BT'nah^Td嘖ܿ8 W݄ߝJxe1ȋ7ߩS,MM/\`AU~ʁ߯,,K(VK%# 2V i,$nI'ȩ^pTYn%L۞4 a.~vF$Iw̦2RTR=0f󤢎]+LS7O<~¸3*E) 5RU/v&Lb^F)K})W,zO-/` -Ivu[en~㭄rTp\U]zxQqӋ˩lxFXi;C,Q#u䕑V.vחT5IE-Qd >(sYf 0Q=>̇[*''n1)V{ӎ;;MIYjYyoLtzP5ů R+0%7v&v[ dF6O &y9@x-k{[t`hTI{QW[>Kw(qm76 *oo"Jw>^/h~OB$<~#;,xM*K:rQY(E!Aw-`Ldf嘖<gq" R531b٥Uσ&0Zx}\TU[S.LY;y5)=e7j'A츙\Q@+QYz։,ҍo5* T߅b%0WH$a3NQ:,.O^o}XLJen5 8T-9fp`S氢~1$jk?Ƒ~Wrf.D;6wR9E7~ Rθ7@6x(p(S`?`L;zn%J5QR%w>z>][T2HJ?Dx_/4U/E򺸪Du@!8]l085oCG #5)r'L\etNAP~*SJ*zpw+3X^ b c#[H*h3rX% =Bjӱt}:xN%ˎdF6/yWy_[RYW &lSL' MRܝqT+Az[\ƣ[~ˏ {[py= \z_s%IP?#srSc`"L0LZ<3,JAP |wƍ +]'t%YY>I7;|sÝ3 EiQ' ˥$dU܃p_]++«DKhR "[$̛pu+1'779&=A8&3 9(NY;il^>8(sRG+ S:p|6 3~gX|*%N=Iu7&F=+=%GF; . ӏ^fgˁp=%$^+8^g" &̾"dE&fUV%mS8{};ҫ+ZBnf.oO7-\|{+dl]Mptg. +1!Y0jxɼ'Y컬w.1xlcdFeo q"܂$d$>9I0q&xQo2 K+ 3\ߌ*kY8e"3 (ǴԔ eK@-.JL$䏇[I*˅, p]J5<0'֌vzR5t; Sz:nVʁUw"(A8{\O ,J/!ij .$-}}՜7  ƝI06|oUp?ţq[c:j9"!SxvZ8]%qE;ݜՑzK#.즿?I8yl{.K]g 6;q эt=ysۖ}_Wn- k8ەn;. wosz vWAN}V+'>(sR}MaEx_9&v29#0vkˍN޻N܎+R*`6u~`75lʜ@U}BTS}oWOV# 9rlU%5bw׭w2SAV v̈́ٴn.yAKמ Eyt5Z&͠͞#ԖB_vѭj=9~}ky q@9,Q̧?eh.0*u;ƪ󭊾'ׅadf]#C 3(Ǵu$s*?@-.R]`ܙU!2wڭ&̦7Y?hOa.gzgFpDfPi)KltԔBY E,]}WᇬiҰe?hO`W35u ͋ʂ8RW?>Ɲ^.nXٌz`Ldf嘖$l"s9잹 ;s ?d]ݰF!2P?jusٽ]swz~Ⱥ`af3м,ϣ,'ԅcuw]`ܙU!5@ ,sOYAVTaq(?O؛b``````|8}9`-HY  }ʲܬҢ*}"TAAf ZUU^R ֢hNNI@Rʂ  Ȍ_,+(-ikjjo<TAA+73uHP*ʂ  LRK-B> AA$]VDY*TAAfFQGHu, ̰X H(LJJ+QYAE ւʂ  2!,߆s7mMM uM 578}:eJG[ khp?ahl}Tatu?_鰬 9Z5+aZ k]ƫ ƜV /}Mu5STΎH3'Qgtu|3+J+ ?Ǎwz24OMN|2QUV)կ"YiC,߀ʲb[Oiy1d&/*KjRbڻaȊah f@iۄԟ^YTᏢkDHEirPi??r7G;>[R|#s`'>ZY`|&M ~BА~@j*BR*^E2 rne#dn)+.:`?~vc#=kn͇.idG^[bV('Im0]P28cѨ \ UW&ſcʢ u#Oqk%a>ە0O~>Ԕ%}ɢ-S6|v v<%=1~uYIYj 8,s)RY>)&g҈4R#He1 ZF˥X$疲h R/yw_uive)GM ,t@|fo3+,G|X?b````̭ |RF LϤgO '%Bț,rT" IUW>>׍Ao"RDכM\N8w#[ S]UwR[|:]y]-1PyX"5+7эp:\l7^yxjr:^Zc fW9 ]]!(,2l$UBkj\&%b!(̜SyMo" dx^.S7Z-϶>a9)NKd6E{^s^ZV^3v&,I <>M)(͉jV-/;s:"*!rDG*u?$ʒI) pTŤ$ &ZKz{$TWG_B; iXx;Al24'Jhʆ7}t6zכ` 7nZBYSKmýĶ'@daum]Ev/3D1 O:.k+޳,,y{WIBvw_^BXB~"+ [GD3*|* )Sw9Xy؟/xU{g}0/H l 5ʖջ6K yYcaުD<1V¡ၶG,kaa>2~EhdὡuZJ;'Yl,ykG[D Y9Tl+vA\̯pTMEnwdp-#T}#kKaak?`>s09E!˲zHA @S8C{<s8BP߿%aX식"_X:oYR_c<0"pwo_4b9ڷs%~>}je$sN?S_?b^CܰgkwNm6\dA@HHHHH_9$z\$pe1 }R* 쟼!r%sNQ5sB1#,b%僅V,Hti J8 o֮DaX@Feu`6!q?F_~lHd{KEmjAӿyIcaQ7^_@70)^q|c X(9X\9g hIE6g߼ZȒ;3t7to^fܥ<0JA2kӗ8ߝíRxޭwH/aܜ!b K@ٜx|YM<e7@'d>A?҉tyVg"<&l\1eAdvO^/ TrzR~֕w59rI ^0[(:D-Y?ԱkY,꟝_\0jqUNSYj7YFioxb޷&tKYL㯌?_p,X:?7w7s>#Rt/f"7jE=]XZ\4jy[@Vd /{7Sfyj# 2ᗺ;ϭIj;eG.rgFg8q:-?͔`촦)-j_i/2>8> ˵q!!!!!}k(/\$pAw^YR;,)oRslUkb.I P8#Q=a/2N%g 4f7ڱ_C/~zY( H?Q5Xj_XSZKly0>ݾO5|SB>+g /,lNwx0f'߷\{BӸ{ړk4)eKLAd) VW tͽ ƐJo7r)E; >҉+""YIOSQ<f\ouu}@28v'4v9BrH$=1V 4+^'@-}"*# {VG;Ǝɯ ? Q$t}y>^P4/hʇoz E09w' ܃%]rifi sQuW6ͨڅgYra`I e>"t֢`P^*ϊsTͫuʋ^l|1n4D07Ηu'78[ sO#Kjz'=?@n%'č 7yU3ͅA׀y918۽)at{J+Z@5zL?p |7r6],;N@x'NoPh?yu4갆/J 3ȼ+XҐ&m jK&gBa;{^|"189#,W2 ;>Q5nk1-^T~^2,j2~ [lrWr/3ƏGE]ɦ_tneьPW452AǗ*l/[ j0gp?~ו0ԗ[ TrOŷ<|C#hh5y# +VGks1׳' =Pom^ f/Ns0h? LNܓ;`e6X ʑOY>W$nvyU}⾖$.9۹Kju_T,~qN7B|9]oKu-5Ж jQ .":rP,諾25sYFဨkIx} zGT+_pa >ךּ|Go--\Su%}ݢ%sb-vsxin($'䉱¯T46΁9Ew`5'G7>р"G9>̨iO4!̑'Ǝ^ϯðI m(r5~WWJ{cAeS:P58$l^Q-=Ota] (t&ՎJ;`D`qQG8n7dsZ{E5i;H=‰5(OπXͯu O4Q0Jil,#&ޡѡ'+ BȢ}=nPQSʄ,f1!l!cra& gB| '5wkD)梁bٽxBO*F a9oi^Y(vJ)%ɘF#HzCRJ'Й-/ gAX!jGE/ crQ6[,<pR֞fhTאָ,$w?j@NH˪VMXrfKDu]d {#u Ϣ jӬqkH#kd]~(wH?ոm\v$$5r{-ƀ蒟Sq{o\A8ʃ1=jjN\%~#>*B0WC=oXO7Ƴ8gwI\dr<hZunycV"AJ+xѫ' |0wzy]oNb;gK!cսsJ®C57XXE1KĂԨP|VkgX,EP8/7Nam=͙Kviˏ.״Hlݢ,6m(?q\j Jna Oꀴ@|6PHAs-Ǭr*GȢдPl`QLh;؂3.&v,#c-n$3K֕ޝ:Rgqqi̙CW<ZX7KnXij%!Ab 'H!E\^ YAl B%%،ѣ0WDk@wHYu@GsYbk`cz\f,sMof &q[n{Vw,nQ\)r\|mΗ6 iI _YNoK,f_X\wP=:CɈ,A@{-Y #0fll,8-| 0-zd03ڷJ3 N u,ba<ü/=,e|P9Aky'ًam~v91؋Y] O@}tyS,Y |R㝩Y|XVIYraX5QidaۧMZeby.tvZD:Z~!˰ٯEf\\Uv>\+OF# ]d9bF!]Iv.(r2%(da5zSȪ#e_5G BkP|!Bb9=bzCHhBnQ|:Wׂ,j}hܟu\=U@,Ɗc Մ Xvg_vs0"{CG.ht:hآ),jb3PS7#ԏ.@@,&&GCE[oJZ~ohxH\Ya-@ Z?69=%Npe_PqnD&!vE/V'#=[$ځ-2a 7ʆjDc7AA 63+$qkD"nn3lm|ZMixJ3OR9Y gZIp`Poo2+.\)n{k ]AuZ6uPB8c'<_yu/oo,- r1vL~CϠX$0}pp{}Wηoa7l:c,'o@ˬkkag(k+O0KyNYl-pLzd|R:[ss9ӵK0BO_o%ֶ=h8F|)yel5,١Q#@ U sE<655/̀,zS[{b<3N-קr0vԵ@۝P;b?&L30elܧ|vqvCⒻ=/AdrJ:!oĨ&5丹~x[,5\Ab[uph|jr"7fR2,MשIn9Jf8F#Q/ b8YouB,R=b>"zdRf_jXwk<}n ^|pLB\\RFVuۨU߷XoWѽB8 M7赵ziBz#2@F|rop(5گYEs^=sl^ Ջ̸?kk\R j"Pwz wt83mGϜuǷ%O/֩}d!Fkn4xm[PJ7zeEPЌRA"g[ 8B)Ch Bs6 ,T>#"Ody^(;@ه~UIXN,OR3WYXȢ[]uV]/g\0*f~EIo29а7PG:.50mLO5l,e 0 YE1oŕ(wzbà)əa\{)0pgBM畮 wWbgEm-P|#J%2qb¸mD@.,ĶaVq gHz%vr%ѼѽDH!3Ge>h{N+sSz"pˢ]I` ~^e8YІ)RGg4XsE K=!qw?mx ҉jЏP#S !doG2lbla),p+y̽7'==5{BΠܔr 'Θ? ! Bwz{aϺeA'Ly,'\~Lba ! B$$$$$$$,HHHHHHHY0I_\5ig(|͵;_2b8#lB5AEÁ?|%b1i|Un_{r=dGB: V߽{'; ,)Se ]5x}m Phl7?gZ?ȧ Su߆_ތX(6KdouIpB?I$F;~i{<fbvP~G  ?zri؄7^`-X9ާ |&ְB|VR|tK cS­xd}Wr|-p++|>~ExxAvvSetf)9F2m *jEr(OeLy|}{~S{/FV5}ORB=5x :ٻ~3;|a_ܒGpbϕLN8)3*eCYTJ3# ]x< fo'&zJ+n,z?5JRcxF8LtONqLs(5jn&k/ xbUYayr5R(NEޮp\;/"?\Α^|CYdQӝmv_US5gN_JUY2d*0?Fw8 "-j%]d+ ^Y\Yt&kT鐜$ԫC5gy^jeROg Ff7v.Ԥz$\%ה愁\3' Y@رA8DXyS+7<,(hXЙ2Uo>jj,|ZPrI{IX ф,:͖TBD|bPPKF8|y]PFatzvXD׬J'qNk寯JBG36R| [zFd,Zz[..' M%b{a9{687|ER{My}:JOs8PIC|jBu3ܝlڅQ6sjg+@θ//g2䞤$5j^ck BG<:6[J~Xmdj;G<^N9s3vfS޻sSd,+;ƕ,.VHd3u-:/(2lwHF0 !b'{ lU߱tLdѫ'AҺ,pŃpP?[T"jկlx~@v7\i2UZʒu0TT~? _'p͚c@ ]^/묾 UNDlle*B?:XU{#e )%SxŭHk4 !d| :Y-#n`nz }hyaf3ң'*8X`ɸ\W5Cեb%P *3v6jE?f6] sŠ 6K6?Kk].8#}9mWt62ݶWnB8.>4"4R; HG QaySu(tqVZbs~F foȢfr9e`g | vY:Í|w~7ʱiKnXij%Yl.W8j|vG (:JƞS{ +TėsR7HjD++2, B3(P !I?1c`ed6X!Lca>^֑ o44 ˨J/׼3eEe5ma!&ӅVKc# J;˓ÝC'}|d|$Drw^5vfFsR̺"懹 _ʇzm.! J^ w\1ec-SAmPٖ Fozb)c]Q>!d9rƆn6iێT{ϰAջeB,O;g%9|GwzN;jYg,T>=r˅ 7S|xΘ;3TdAB/Έscc,;eB\vZˀ#0ٽ>9n}r,r`|ti 0Ơ6Esd /uOPb4 YH-R_0k֕65{183Y(Zʩ3$v6^Ҧ5-I/y^,g ]QOܵ3rby ކEoðmOaApivj}pl?aa77j(B|5fm+aa@VW\Y&w&x]j$]אY]+b9I5{vɎ\ʹd ^e"y\.3cE0?vB<; :byg3V֕,|uMEʗ=`v[B,fg n`2PJ0k#98,,FUjvqf;aFܝ|at=+zJ񅽂EC.s,2XD<U%Dv~:<0oʬH.ceA8?P(m`ZvtAhbvv4Ą,xa*}w_#pNmAGWQG!۝;f/!ld9<2;鵛"zd6.ҙ-Voo3e@vjㄙaVzd6 ba^6~ fYoxW}p1f~9z9:533\;YsEs'CKQlwf&e'AWMN<= dHa[ U2# 8k# ~80$C{B80t_Pl(J22\Y\aޫ>˄,y;~t1QOG#kp K钙fؤ7LOK%3x'vpB\dx^DXN*62SqϋLn}T( am9[48Xge8BBr TTЌsdk^E8cXiՂ$%;]h`H֓y){*ctI ܬNE.!ʒYAT>wγh3y.3j=!Śxc=ZBv7㝹 #``EC،tw{ ag`h"c4ofʃ1vZ!jbFiˤ9ERO!KK]0%j*AM fYh%\u+x)fRT4Y ]w AGgw52|<ҵCXKw>LDOb'lz\h4!x9kWxi0 )O/'X.<)k^3W\Vv׎iٕզLP (:ǥbB%baec{Lyu4XZ2ab. )bQD,7 fI$d5S6[2c!mld!S d9Y0~HXڋ ϗp!Ux)w${g<1Vy>nnJLJJ(vQ84>59]ƃ MѠD"Tߌ`KZNcWLvQ. UsZPQRtH&lJda^ٕ]fnb]vD0c!][zQWk؞0t.+ޙEM-0 G pgZIp`PooqgS딂8ಡ6 ]5]9D}P`u[ʉK48V\}EvX $ޚ ޠ W7lWÐj7R&) XӪ}xZ.ș+G6BXw z}*x.xFOe,u۝AK?|lrzJRl@l㺰ajnޙH?}/8VӴ]js 4׀_O4,/YAĶaVa^I{t܋+QZ3oJK1t<1G@ lmͺ\$& dT/; A;׾iXQ9h'پoK^uJ(_(fQ]c`ܾm^B YvnuB;zR>\8sKc fM)/˧.,*38zOˍyR5I/MV~ja{XFа fLY(CڏyJgqZ̙~jݲz/1|n@rA,R#5Zs7H0Dc\Ma'-"a9 k#d+sݭ멸D/T똳xqb3W_O OTfIVrV]ޘb,5ݜ z;q%]9 7\k3/ 6gؑT%ЙQܺ`#Y1DF 1V|2qBETYtk-W K1*6uGdcVP(,BrG3Q !_azB$$$$$$$,HHHHHHHYk1! B$$$$$$$,Y dABBBBBBȂ ! B$$$$$$$,HHHHHHHY !!!!!!!dAȂŞHpwkmMeVzD/y뜊@@BBBBBb) 9Y"şanB<5ңg# ķn[ ӳ8!B,W=JTvP_vߛȂۆ=Z@ !fnuRl!#XE-Օ2a`Rv83{YEe$! B,ғpB(ډB_vW\gRހ,Z!w:V&~q:oSG][rj/utAKSMRΔt,iHb 4zB,(ˊ HV3K%ݾ Y0c8*bNg*'JCi(}rpɄ?wNjW&Їy" /(vIKl4g#6\3lBiyRu4}_XD-B1?r2D=DH ]Lk+#_ڣ#SsjIYg!\WA0ԗ88E-- pvqq޾Y4pṿY58e OKr80߂1%dDF+/4cK`.Tԑ|ol SYxltJY{ t鷤<+r'ɭdx\@ш\'1CN!RwICI/_3Uйkep@\]}N|WKoSS3!組 MvfָFlIJ؅#8zjlk#zaPy,at$;pFNPN{OtƩ !jFdo`\HHHHHY:d!vopvM<)RMoPY")x[!Ւ<66n6.'#?_~N}P2O{捪N$eW}K"J'䔧W_Z1|NKKk+Q!pER=y7Ѝ|V&n,$(jn꿛kqE^W$[|cgly%a3E!ʄ9ԎdY !׈,$FqK~`GGx$AwѵA$z8b `5M+֝ҒK ^YjЊ9dxF 3B @7 3x)wj[ CMȲ{H }+0vEwHIronv)wlBЃMO4Jˏ__VugB|JsT?g(X!RrsNrd%t),HB-HHHHYNd-< 36b_4u$l@Kvf:X[[BueP1gMGREw4+_ȝvL CpB=Y@4pNm"5MOQ>ƸLrɍb/j/mBn;aEQC.79}*FdQD *U ᧅDj4)DwCIu)oSR1eD+V*#O7p ҠDfjCoܠeo>(1ӱW=y/x3VqVc swu$QkM\wFEUbIW@p7}PUjc"IJHJIng8XlXsHjŰW/(؏@)#hգ7!ؤhoہ!h<lWE2=gB=:YHV2sA%S:BcCHHHHYVd!uB,b>^ [o\Y`Ö2/)0F[cAܛhj\6Q!UYJq;9pѷ~qz5}ԥJɶՊ\89ȍeXqk.`ׅeg= +,W߰߬@C*GFR=Lay=$弊gF}R.gRY16C@z.~I pM5~ olc' ˾+ƫq4w }y Y>a|ЭA7SyϿR}!)L-*~ jLdrr|X^s'{''ٖ?gHP@+@n%ň,y'ǯލ_-_ZR t+vZҍSBw"d#ޓ7! @,g8?}KH-m/)zі˃MX!$Dh@ODgST7 ]۹0gyWa+};-/N?{MLYO:bܼaOQ~#,+MQ~gO8~Ѝ=:o/?zDY>.-taFEc $@qEw'^}QBS`]#K/97F<ɱ@Ώԑ7-XD0G{;{kJD̿{gʸL*P"Afdl7" ?idY0z"&ԇ !@"4"dQyo_*?£P021!i Y' 4ߗ&!?|Pw䄥<螘D#NN.GOs,Ra,H#f<4Y>99y?xo6`,psέ9G~*n=JZUm^qwF$57"0"G]߹9}wH"Hwqr3$3_=#d:5',Q-fP5ַ4>~&oxUfhxn|( \}|{P~o=D|;9ᤧ>N?dH^v᮷_}!ל99|R( _Y|Y 3 #z5SwfCuue:3gfRx 3Ze|qdiۨV54 0'[ 􂟃?:}O|2PF$~"wY~g30dyr=u1cpӯVb>o"'~ڗ&(]׏J8h^|ު9¨qGNŴLj-9O<ըғorE8|8gr{Llv`OAGcC|$v?Kv'r|{uAN)vs#Yp@̂ (|J!alxo,+űUtJg4-^ՍXUmyD؏= ,B/,\b;.rYOym{\_z+d^(?R5nq Bc^:}OwrigfOYïoto'pÐHCOr&f"'8BWa)E$SM(ŀ*w "' aaEf6` |ث ٷ^,fh/,-ř?/q?/NE% (" M۷hdY.KjU58eUYq"@gᄃ.w&q{pApY,_Y蹮]KAQ}={Z~,ðx˯Cd/91 M~L. 5+#OB,& N:׵dG Q]qeY_KS`q,q6ڻÑKdPDnvm՛G#RF>Y}P^b` Y=wJ=ewv ?n]f3۸7r#S߼Wl?L d,d r>ǸMXz'@ߜM|bFKLdy/z &~{H#;Y`zUAzƏfCz z2wN tG\Sp壦;8R7Vr._o:ҿ~HY3u|da42,Ʊ#ۨے#o /|7` VP@ Ç_(^yg=Ͽbzfz̽LO7:/#la4/s7@?b -@Z,*/?,t~)^e-5OρgsZٮleak/֫m}=`|J \"8'l-%S/DMMuY9z^+On|y84yaA|Nֵ6UmGWy~,twi:s8Mֲm=O^4V7n׆v-';G `๞B^g_?[&c4/P{)˚ gbM 6I^]~awK&9muxsn[zғ$r^Ucks}ٽL#YV{ /O:Gܣ^hpgՕJ4O ?BH|JeǺ~Sf~(>7cW4 |o37wi/ bj?9EQ<{=wV`sgnF‚cM}zv=e T5=gWzV[GڸmKlwǻ^?i~+GɽUY^dkw|/CHђalܿHB1@l`e)a8rE䟔 !no8acwG͚)OhX('T~_4<s='mLkዒš1,C8X2%^Ϲ+,uZKr/XƺƷ=-%OH]kyhH|eg#E $hd<7hkca5`נ z^g0.{KџxqaI ̾{Q42@ Pfʊ՚~nZ2,U&| WbqeE5fAY> C}y٪%=c@|+僼'Z365VI˨Ch<-?,ҷ,?r?&Sͺ^og&YE6y9L۸xM7໠BsFdQB;tpGh*c9eE,2Ml[,EY^5,O(JkdY^9nˊ3`VUmNLrC^Du4}T gd6pz1m^/lwKZ97Zt Jk*3jPzAY 'UFHfNBYXРag9F4Qg%4ZI`ze4#xjͰ*ˬ}I#3IYeocrYߕķosoڣSYwuUJg0*H}jaaىќBN&+ ;5wNEyXqtqEat}7ouh5d5sVvO V=WA^v='aP1AYbLF3ZZ 7kb\#( tU@|P(ˋ o@YUN@ >kPΘP3ZB Z@Y@ P( @ ( e)LL*S^1Ms,UEe!^ . '$|fUŨa@ P( ! MVZPt !eY,AwGM+֛v0ٖoxq Oka2cbIaK|N˯ K]n9@δ:,![sLƾގ"˂^3MKe>ljX= L6 &jtw^Zɪ~!9{!mDA@ PAYӇ Fdd5 aZycmEM̌tlki8H|,ź*.<A%?C,!Mݽ=ݽ TYMyoB|oԔ3t{,ZZ['*HL'+K",,x g/g{3<+P̽ J/wSYp:97sB8Uo5?[Gyi~Y.[]⎃@ P8e,+ɋHߪ,fF]@MF$jU*ʢkFUVTµ@ jLYP!s=WQT@ ѾQ>˞{|faĸ=''/;prLɓ,:/M9iƣ,eP( ,P@YeeezfZ5] @Y~e=Jxԅ3ׂ.RN=~4,ꬌ۲ڪ/^(_xAFC0 $6*8,V=s9싵}_rSdχ5W.}*Zj:NPf!0SP ,W.~,;\аq<է[k컽ML=p لT}ywi|XeY!AwGMWL3 ~&\~v2'NMe*,tŬ9ZnIUUyQ3O΋6:8;q+!.GSYL3muJ6@Yvey( ]l-eѷv%vkU+隓"IDޢfYf8=qkmHlw)Y֬j>-/:Wԯ3,r+ZFO1K,M0~{Rj' Fݚ~(؅o0p=2}';+mzCWT[$]RؽPbín8j>{؄^kM=!KOe&e:s+F9, wDOul7'rgk*IY`cɻ-:%o-?$O|Qb# ,+5 qߴq Okabݎu wqEYRo\ye,hN8ףf|0V[,56?""ng[gJҥ -uymWBn}e^2?n5M466ȊU@{SòDXZ[RDFr҅n];ߙgGV=v$$Ka]V*&= NLiD|VX[Qӣ2znRMp/Քd_CY\wt OͦX1H̕U':QXz~5e\~fP$ȤYKCŭ=D@zS|xweIf$33yfKE';`O܎dKeSBx/4]}oJaL^Sxя۷ 4s+KwQcY%gBh=o}fi*7$ c$PQQa;layc&}3.k mH$gZu+%^bLz@s01nMzs8+ɛx\hjjwRnI+q>Z=CSCk-7 f]i7-1@5r![nUUfU&KvץnUYdtǜ1>Cֳn!ʺaf qlyq<ڨk@c|JU]e(˯,i7EYb2;J۹YD G|Α.vB"8M5r6:,;UNy1/CRBY߾ #_;&!6ԞO6kgYuuj5%pJQl }YhtR~èأ,-&[sFC͎oS0.y]zxVBL2+~/AD*bTd°R)2eqy0z )\>Wz WKJxI yea&o#$Fki8H/Pʒ.B{IƱ(hl Ɩ]ݘGbUYcjըJwN|`jc@<Zfg;::{*L!Gb\TZtݢ,[h+v`jG%ylĵIn,PMD%z Gnl! zWIe(Ī|X>UDYw,AwGcU>6چDEBw-aiNJ킇67n潔e(JX ]K}nvP_YYrEYb\Zy_nt}~* ՚0]YiQb85w&v{&o1t,<4xQYab6MSYWv9b-@Y>꺪u)X'?aOe=x_r 70\c}FW02?2W|ƍT7~kږs23) 7^G;gi}zL]67D݃_}ǵ/;˂~ &5t!IkЙ콴924'>Ն:sBEScub/ɗ?ߤ(9*䧀&5,kVw䞌ܷlQ=yQS}Y0f&9K t+wwwq‘}5ި|p;ý3bЭ΄l˟$g|VeaLFZ%.~%EuUɄ?%è::f>e"7VkpYBE'ʗ ;QE5{ 67W\)G|ve_wʌt߅J'+ Ɖ[-=kBGߘpe,P@Y,e( ,P@Y,es5gΨӮA!u(o,TW6ׂ.4굣H k+^"?>:ϳS_;I>agsrztdƫ$T14]{Чepa8%1Qi Uw'_6j&Y_e$hg G]玸9b5= o{~Mܘ}L{JG]QGZ~o{BCت2nJ WЬՕEߙ v+fYaV<h*,Nhjt엹ji,![s_Cn !+%@x|)P+jٍ]sO~>s8~>3Wrk?KE^뇫o jY[׀SWSx2b7zTHNt^uck_1>MEܑq<|K6|}1]:+ʦ#,?lш3Iїhʙoa{UŨa{_SIQe( k6 ^mzT&*%ȧ'<|Ax?=mpIRq}Zxf +WmkD^]egjUyo;ґQf 7[ G^Y['&th~\ {p!ƛ[ZXVD,|H6lZcXm_pw= M0Rͷ غSFC 욺j掙, ҝ">bb͚g8>cumǝ[}mr5u[mn܊^[= e1O?$YB 1 \ڹ;66n;>G:+Y mŊ$]0 coP*l\ZWނuM'ɖ&z[?KHǭWx\XOa,y.R. _rN 7#ZQ7K#ctƐnwyeY3 =ݾ*ZI櫽%(;`OO0wɺ{-v6~WMebo=J뤫H5h1fʲaS/c|kGzdMޢ|D|ug#u?ߣY.eWZkᎳ@gUVRYɚ?I:\:nF;z v[%>3 cNTr轱8o䪱fpH^P=#wߐ^/J#B$ 2!` U/|,"[ ?K= wxRpJ_<)\Zt6w"آzaؙviiUCssCDI{rzo KҺʢA-)Dž~x߁^*o]#U(rkr_WS" I,lloo-)id̦(9[*//Uf )~5ҵъo@e4 Ɗ}D"ݛXG" K/ȇj\V)m22ܲgks.tYKY4t*&v3*f![.\5.AV].X=Ke 1ki /k+jzT_ۑlLVSu*@[~h#_utHg^#;N$I[{x{nD4ZV]ZP0mZGYt >fImvPoZ,-O5']fege/riN-* ;S{PB\ޭnlk,*ү*)ZoK%Meyv{&Lw߈y1om;YZ[WY_aX*klm>DDζhroY]Mqj!|#׼BW_ˬfc.Ke5%"W*Ȅ^)8HsYhߵՊ]ӄ^\U\کat-}d4q?vO3kǪsi꺪ǂD2o{%uQ(G21:r__~P(ʍG.j ֖pz Q,FƠQ_A\⾳ ||zi _)-mе{V=O(-znqE.nfkCUbxYchŧ Y[P ]>Z-m!XF+P.pśеsDfWa:`{:Qիa=2L(Y@H1RzfY-UVwI;:b-p.Ϛb'$" 6o |eg껾el\kW_ v/Jfݕź#5]ܱabB\N-1,a5M>*]4Sud3]qsؕE$ LYة`ϰ}kϏڙ93y/zXBفw31?:hG M/r5oK$sm==U|畅ߢ,\WR',Qx' 301le Nutv N陷lNGH籲I@aJ\9GfSի(K HnWܼQ%w,pWQCG"jubi;"[YWncό%4TY$PqWS9L󣂖~PYAb&0 u$z3ZUA(~fP\;n s~Kj0CwjtNhQ~(%.{o5wvw7f,e^%?WbE-{'e1 %$hʸƯ~&MݳaXk&.x:׎j&Zθ Ӹ~/e῀Pf,+D+ |4;+2EnbEk"yѴ㯦Mt]xq'\KnQ-kyfr.id:^T1LXch)°7>chy=6,:{ip- 䚱.DJna"2nP+qVηpH] /ߛߗw꿱 盩l&؇o5ti#ދwQSM?tQ ~'z2|-o۷bQkav)hv*ߜFHv2lЬ:~T1OG I@ cN:iȚ+gw^R >BY5עo>J$˧ޣc*kǗf;Fך%ƌ0T(s㸷ӾF]}yߍ#n 7sWt H3)ee=@YޟsБ(Ƈ_f#3F.pGz*<5﹘QTQUSUpJJDo䢐 d-m5Wj/m!96鞴^VYT(gT+eG +ڊ) z60 iVN*3Ε,6*ֶNқhdEθqmơ;|' xPNH/Tk t&>j7w,s*Va\^Wv=\ve>uБř{ޜتafW3i($5ܝ겂K'JǘSދwQ(l[&mL;QPQ]+*<fOE%뗩>J%j|i\&-̪=ߕGTYּBX ?ﺧ0~z^~S.ӛTU]ܙg,\2^Yێ뮴 ǜ_PT m'<ܴB}x. |i] K_"߲mbtadXu=W|zK1X~Lg y&ۗ0f|S=]meW#%L8SP_]`ɞ !e`aۥ@ŒD.hz(|U:T( ,P@Y,e( ,P@Yp(ѠרiKYxgelie`*G:-14eU,SPl0ey1_X LY<7,UJ( 6XYf, 7cH>`p"9ǏSe:g)1ck,T_5 zF5~k`(ˋoVGkeQ2?SNY̌w ͨӳ,5)W.,kMz~kk5Z kW,-Iyc<~4˵tZ,ZQeoI;SU< U1Qeiz͔XY3=ܺqfUoF~Ns>yl}Bd攗=k]QQu#.ԝSq&3l*I%˯UPkVFU}Ё^:ygkN ͷP9q?_h7]ϴX3E,wrsw[N2ai-ZgB(w$Sާ52B=\-EQ*( * ȏ&v(S:]M%reˁio ޗTN[SMeLکBi#e +dږ$/Y:w 騑0:exiu]mbٵ i |bͻGhֈچ|7נ!_5̚d`R&*[\t=9GQ,s̚յ{8˱? ә3,9]Yi*)u*jf@Di(#p )?d­vAtYc#YoYCY48 EV;ϋƥq21R+)z[4Fe6tnN![&mmC r9`,g rOrsblwIA']*Yd`vB[e6TL.~sFn-ϮUSM]<'?u0w8V4i(+:Vh`lu쎇&㦑^ynA[ooe1Ɓt@[n-pdѤY~u~-sζάu |mRGL/KwYMhftw;XA}hh|e[~pBTC/ti=e)H_nL[-Įnth-^VP,@Ye( P( eeP(hi5*z|4*^44CN"',_3zzჼ zKÂ^3cBg!'P}Y!d4 BĂܬqœǏffI$@Q>~*B5,/.{ir99 e2Ъg:˗yssOf[!'P/5 2 zB7 ͐fII( [ >\sEΦ=e_tju/_]Fǝ?b ,_4VRUӡd?}5`_~PƼzh4 S(U>2?npn,ey&jhfpm  Nӓ_bkՋ LU})ʅKoV ,KnhDAx$i=!>k.w̬Yulbq"}_F2~vɻbNnɕ|.$YwRs咊SvP( e}e L+dyea'9Qɬ򚚢=r]XD{SZXqGOwoO𴞝>!|/eUPL3_= dzMGWS)ov縫gn?oK/=ziQ?Fʢ, yS4rr3xiG7v {ZU6 UUɬGDAgU4Wf&$8#,mWW+͖*g| 9Ǔ] l557TesV>;s]yϓwu2/=SXw1yey,]NvA氜tT$sPæ1? 6m+b'TL.q9٤7 aZycmEMl΍\i]U~r#'TF¨d'iF&Z*nq& SDNY2QYhE{( ʲe1 ܢuF1_O0tQ(4kjwRCs]GH. [_o>y!f@9ƻw =zR񛮂?_^})Ґoz4|Fr*=~r>.)}Lz֍8UM[ZVj x^gUahՕQ ;-yNG IIC;+,P(ە|YcskcnVeQI`t>]IgzEϪۯ q ;R:eb&Kf;YzБBܫ>EV 3kx+mhlo+DECKgGSk WߌW Z\W@~|Ζo|e[ZҼBϼ}޽_;Q}c۟xzP"y,b絕Kt_̭kmN pM+UK^a@5iiC~B" ˵ɭN$_nJPBvym}}Ü#U{~s{eC|AfV~:҅Zi[euvC 9{`qf1i[euv\n;UHH3P(]yɈt:˗SYfH3$b$@Q(F_GU3e>E!~oiDN~pNBY P_A^jFI-yEP(eO=yir99 e20 '%Q_.yŅcO 0͐(˗5ӹOӧ/ i3',eP( ,P@Ye(a|#e?ƘFKo$\2mcδ$% +n_jT2t{ C)J{~Ьjɽ~dH+4fNRJc2MW+|515W⏤umɎ˹}%ƾأEcƍ|,ׯt \Kݝ|1E n\2P(˯ kXoNvǽlﬕ6O~+UTt(Zs0-t[-oڣ5WMS%)=b!da&p=9@W>~xԑlz Oox㇝hPf!GhU`eȪ'l4k\tˤ2Ň޻[;b[F` !핚1j$$je,,u_oaS ϻNG+;ء\¨/Fޡ%` FS4ew 4r P-?pH6d.oͺ_++CY;6- hJQjDmag7̟\gT掐ݷ{w=~\NU>󁪷HYu6la„;J&Ϳy$bM*p^k(Knhn흇_DHD,(UQ( -zwIh9@{lN=E~[jC[{ %?k_Q?,\鿊,%yYd+ Kr7fL4)ȉgE, s,;-=و>$6CTm떴b_L'OHs5g /]ս:bls<3e Mq~טP-cH>/s#CPK]9afa\\"fm8!.rj3v/$qN`呓{/|/zJG~2tt&̥'}񴲸<`je5–8' l]a3/6//koBE4Sؕ^wVnق0m[.ޞWtb^M'G3E`ɗnۚes'$kRR>!h`N^YMz7-L2P3l_qq ]濲% fNI3kb߆Tm]#ׄ1q/ |c8ʋN,zD#v3b|]j|N"cM]}Y0;zG>r=k,x3Rp/6Y:ۚO@aDd=!Ȥ,3UZ[.nA¦n5ๅgW6 KX5(d({b DVdK,KiЕ}, y[Bw~w>Mq񬠒/l|kF8").zhA,< k ?\!l=:t!UMM5a ZuMCr[$ln q"!W]g~,ɹ2}q9ڣS]y`-9rBAٜB2ms~oj%׻YOKb7..kB-@VX%emKR}odxY'u0 E۲@} =,u8 tmAYXfw ˍCpk8W\h1_-X 3~3Z,l(I 9,u*ZPnC$mVEć63{abߜM; λb,œ#&-,\sY+Y-ˎ5ptt5b~l:|ƏG/ˍHgH*^&|jSKө GPhAцN= Jh|*!|[0%T[cDIhf MLg޾y,*b y}_nKlÅ C1`e>,eHCtiy;̝) 8] -H;rQK"ӏ'D#).;QdmMk&2İGOs⠈3, &Gˉ踒ӦUՏyf(h@q4M 239><&l,'eYf[d2y_,酛!W&FY,Я:6t 4gq t·%|_Xy_dgB$gby;;=CC \N,FOU $wru7OG_N?,eȘ^9M IdJnMpxr%~꓌ kr|9#\|1dԴnӇ\wqL{=C;%3F:?=iZcSRϑEW&Ydsth$tEbużB2Øͱs8 WwPpCp5-M!0O+bv?Kr Ȳ& `N(pkp~,qAt y8,HM" gZ·3Z@֓T KcY8vrw,&EVWWz:k*M^ doXíjl28$>nrl94\yѥ2,&GOb9utՏf˧@L'3G"-0v?G?+k,=fE:Urd\ "{[?]<gr~ltFf g$E#.ULs|=gBrBSg;Ydkю<p3ݺ>h?V+q33 g&38l69.fO.'-dcayB a^܅}[k4mfؘYo#Q{<;pQ M96,wv8<gt>ɤ Ѻ>zcGlBuZ"olT &w#YN"IȢXi|iCxny5M-Wu1Ⱥp] AWooAG}9oAFR] Q;ߚuY|F(ۼrǥg \` מ7yZt|UmG.݉-m6UUmGTXT~X?쀳Ɩ {]>BlI|S*- e^Cf( fٕͭ-op%G;7=˪gIp/@"&L7"IhVPϋtK/O :>}s8NڢSkTΑ88T=L2ڨVfK- %$UPWSmzr( W&')|`IOUa#$)]kB._rK5OGtxG9P)%bg%U76gt32͖Y_*[[Wl+|5;iD?;ȹ ˸qIG8G6 jdv8Ƨ [{:^C>3pU-%Hl-:5A?vׂX~,il%B]d[WNԭ}PGRFW;Ww̯8{cNkyؚ9Y.N5r}W>83r`&&f6wV0{y2{;uy/B]o:+M—.5';1MZߊC3˷o>8-[~u׎}X\qz̐T1/ދk]p#7ةjކt_~R싨6>[1T覍6~h]>]:]ē57+%k[/Jd'w$%SɰkSų Oܘ[ P=eqhE:^-?,pi$yJf|ȭ  HY<"&ݝryO,uFږgovI: 㟒CkgcbF\׾k#˸pe ~WyW}StY+lwal}3bVrS &N,F9/;;(MK q1ǹD}{۸&g&B<3pTx93=P]ಣ{gl\Z_Q#ReʼnumĿAdAd}Wu|.˿.vo\?^@ub!:ueL笅g5U:}N%~!X+Ȃ'"lГg7}d Jk'צz;!v"Đk{Τ ?sָVeK]mU]}:ݯΎ,G " ;U-f|ܔXucovD]#gjo3żi)6sָV%3_r ^=Nh[ 2<4 X:" BP]Cj0. BPJ\~BP(Rc'̽]ZEdAP( HUm$lomuw.// P( _J!M[Jc^cTl)P( I&57ULNȤRj[.N C6 s3SXl( B7Z[ PS}Mwg,lg6,/-UFI" BP(4@@Z "lWP( B(iiHT8ȂBP( 7ȂBP( BP( BP(" " BP(D BP(D BP,, l~vz53?3-ɰPNpJ\,HlKoN$GjK}3)K$ YFOnom_odj{{r|lxOc pN鴁W> dS4~=[}Õ,HRuۮd LCpɚ~ k?o1`blnPP?wD_ _FQ}}MEGvy֏B]888_ƌsƸ+-t|("A]~,? LuOf/v ΗU+otqf]0)b% ?OxuEl`y;8j' {P?wvmoya " #~FtYHG&~0Ϋ~t+ShBAJ!s,¦z(#ӗ4bav Þb('"$ehp5䂠_~O}X|:>,ϧ1nϋ3O 7 >G"hc9fڑNu5w/Ɇ B^0#G/]?ًB]D / hQN* %t9/j ; Ƭ3+SGyI~ R T#die0љOXzӬѳiWTMҳx6i{bݮ^ݹKA)'_zVUw5m9lowWx6ߘ-@BCPQܽq/K,r{Ӯ||Аs@Щ3}*c׳؍g&7kf3oU?UŻ:/gKĐ3\%=F ~jMc,AKH/!KCmɇ{?Bvw5r ElwS,b}?2{m0MHBxBㇷp SYfELJB.8{s-> ^ ˿+g=|Įd b~f=cU w- bbPfN,|xz "]ςh$BpMÅ# V_=-Ms]H-84_53FD B̫ 6ꤜrG>W7ݷ p䎨򾲵.':IrG ,;td=yXLR.d&d)d,d/:> u;h?]^dQ4;zEQpح)Svsy ~SX9f\f)*EֵtWVn9 Y&#fci9. دId/>U~]څeF^:#~b]{x9]Ɏv3lp"Bü ]̈}g t6Lӟ+tҚ4H9BR($FVDQ/ԙmfK6Y4,QN~Il#;j!;;siT|wFljvVj@~eE91 kv #JQSu^Ş+m{u2}F"xP_cQ{D܊8- r=ilK٤gc8h6iV<@-!VZtTRdۆ=X^t|("w:FmuOG!P׺ͽM^vX׽ZAt-vf F}z"KKMivI~'ǻi>?K ~M 뻰,7mxn=;baNϦ(̗Њ^jV4΁=fמ0@H/!KU:jyJ%G10i^V~/n__!%]rV lP 6h5uϝmJ듩eC). ɵ#׍t%[և5'UlԝtXtu[JUZF>*fr"ݕ؄wIFqPiV<^SIyX([yBfNL؅ELJB.8{F`*ն='ׯXe:7mzk:%]uosBp8^.dy$NGvq$ ]h'iRwRGg,ۮKSHDxl\;?*TlSjw?閩_Cz!Y*JA!2QAj۪:ȧ u7 mM/ibvCE*3n ʕ ,5f/s:ߏGnLu[ݯmH$q %]NaqƧ[[ж* 6NxXn(=,[TnTTA'"_Ⱝ\2ޕ-`#=L YtSdI3?Lr2 t,r/yģxQ-dy*v }àns ܕ7]HgrB}K?hhvj`NS'OM&WLRqnE_4[Oڑy0#}dA}cܙ/DJ b̤ƜYBr>Bz!YʾNѨْ\R~=oZ @! WBj-x$ٙy)ܰN}zS mD K˦ֵPdݍ`>H9_ 7N~I\a*WD:GI|aϦYvX5nT%sszf<ҁ"+oXWu w ih$j!!;i )%s, m.*/'9bB.Sų%yT&LZKPX-kג OT {;s_GՋpMꈂꢒt 1\!7:W%rzoqېe]45 r*'DZIVn{Y\S___][5-Mȵ2_iI,'%2lܛ 2&h: ˖USqXqRlYY%lTө.)6?um2SVABCPQBeA䍡nD7vtd{]"_g%Rx u6w׈SBv7%Aքw+4^(l*ZpA68sv1<>gqڅ!{bvSPӻk>h>>`@}b-,!?s}H`-y=E7sgFIF5)B|OߡW{΄HBxלE Ǘ Ծv= FޝȾLln|I2rWFN'pHYtB=1zץOF9az9uߤ5ZIֆ*wf/ni(t^]4ߚr%'x`MBO.0R eB0"\5b, p"i d:$6CmX^t|("wС 8^>Y:XNd"VYdy߻ 42 )qAK}_-,Ͱ]D8;^{E;C)lOzNNT%}5w+ Kfwzld / Fߋp*=уh3Nbxi`R)B|+ۥ" O9S'a%@5_)9#Y0yCې[ٷ c!{P?w:m.;g vJok塊P*&zJZ)fbҸ[R}k~6U!h:+e,IěRKdm2;$%ȎMl.4 K c!{P?w`"3$v{{$_/u\]>=@[q,<-Qql(ݧo3+zpjy T'd0!/3%MbJ"orBghV뜈Hd93[ l$GN;P:3*t*]U*.zXB9Y2@>xi>> {寭Rѹ%\biqU]΃C\ u1R@N ^x}|)[y\wG{FVz)Ob &+i.%7=]1NRmoUWtCPQF:Y;i/(]Ri'zν8? 摐n6ҷ!\*,-XY^Ԩ7`ɮdEn BPNXL"*yQzc' g6\y[K )Iz;SP_E9P(w8ӆ[+ߌG2 BJO+Bfm\.VVVZZZN,( BPg7oRSSʀ@CFILORL# " BPߏ,, P( :w}6dY]]eBP(AoߦL‰,bEaD BPY>\QQ" dQ(,¡mmm,( B~Ĥ|r,FR"H{{;" BP߃,@ !bYYP( BNd̬bhYZ"HND BPYjjj@CFILL RJ{~~~ll BP(Aܺ: ` CdQ[[[ccccqqqbbBP(A† ` Cdh43455ߏȂBP( Kfffqq@ !;88jag?Ͳ¾ P( B 4(da~:xOOO}}}iii^^^FFFJJJbbbbb޾}؛7o^q @@@@@@ !YRǏ@-W}P})...((ʢC7?NKKKe, X`r~0" ;BCﴵ B////c X`r~0 P_,kD8s||::: VZNg,<EKQW]cioW,Pda I\YYYXXFGGbl t @@@SnFEX˱ϴc-5???777،Φ~fzr`AHx_a?4LdEc-؀V[2L,NW]cioW PdkQ(T*0&fLd`hhhhhhhh?3Cx`qE ` +,hdjQTRT0&70Y$X#rh4\u' 047x(K HIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_general_ssh.png000066400000000000000000001773241477034762000261230ustar00rootroot00000000000000PNG  IHDRlsBITOIDATxWI;?s {ql[lp8bs8qζ6$9眣PY gv$Dƃ=YZMUwVKωOsD0ƷZ3hxE_Gs|a ز_+Mb[}Z~Ц;5R1`~ [}ص`S -ׄHjA-k勾5EѨPQ ƗZh[2JY2L*JC1```Z/_-a/صP(<Q1G/ƗbHQW]ciou{LxB?rER.`_w6NES ZhkC4,ߋ}ehh0D677744TWWWUUURQ1,\L|܃6Nb_,W>}d+8.jkk>yp@fW/OAAiRx`׽KKKAb]:hkk,σh__ݷgV?AA [\@0vmtfffaaauu5ZI,ʇF`h42wwwٽo3fo'oOGAAofoR0@3wĤ4442GBbHg/AAohƅg333菇KWZB l6~N AAȆߨR0p0QBFÍ@ANl{ <l̄X?񺺺\7zmrwo֯\~E7nXq!  ? ϟ?~ezZ \.i-~۸j‹~%vn?: \u\jpՓl~ }^8RL!  ?$O<'3?!fZYT*T*:::׃LȺ5],k kzNÕHirׯ]>k׬z⽻ߺz!ʕ ;'Mk'OtttZfy =~[  ?-=Φ 6NBybe" lix6_z貿\tYtUc6# M vx =4+l8 a J<;;;K]'d#no.n;JtptZNN-2˦X$AA P~:++k( Oʑq`K6Ҝvלpi^&opN\r>[@[m8 %k.'մr٭ܞ7wop^&\ܛKx.ܸVߜ0.=lڴKAA/qW^Y~!Z1[*IgeF@ppCzeHU\N;\feCO0 OK,uOwgˆt JVFhHڿi:8lZj"̼ Wwe;ٟͦĎʲw0>ѓa*d;G6wݴaْ tCgvnutI~[r"ݞ ,_j a ,Xc  ?wލeB+DX 6`lZ3eKw_ m[j.exeH`,eàCΟ;~Qk ΂ugpx?h&=:&pݢyη_c.V;06-YvyM2 ׷m\j𛣽N4JZބ,bA%"""## &WG~GɁU ːBg:) w;tp `kp6nXrUV/[` ֻUx"E"Ifnݺ~}YdV3Ůk~۸zq7eKҒ}|݂y-w\~|Ӻuϲ_2x.Y`l K9ev=e/ZyJ;(ݼENotVܶ/ AA~*@9,.߰~8V,_o|w_|@A.{ }݂F6\l`6=vxx rm[hMO&vkw1K͉,زK/[`oF:=f X m)+e!kÁŠene7TRw}Zn9}^ S1-eYfXxV\\?x.}\2 Ქv;vܲsx r.-;ThRV-rZxuvv\zSUg7;&t1h5.,˖,VMk-(1# 3&>җn|-R_K~ꣃMj 1-eYz)XτXf`_uI ˗M!۶[|h?!w 'd٪vv~_[l?Ӛt5.]`Ξ?XnѢL 7q݄l\Dr2h:j5KZrӦUt5oIAI=~e+[ [Bok  ? Rի%Ĭ\d65~ ^H_b$-Xz^5W@$VV/Zh&LwseG1ۨ]+ϵ  1-eYrɚ&ee-oh2 gW^XXrMSLSA@b_׮Z6窃  ?R+C  |W@9,+ۃ  |W@9,˗ف  |W@9,˖.AArLKY.Yփ  ]嘖_ՠ! |W@9PYAAeAAAeAAAATAATAAPYPYAAeAAAeAAAAAATTNmmjlmAi_IdR1:%bV!߫Cͬ΁?VÂq`$#' > Ӹ§T?@X(r&odh{w<,6rݝW:,)tşV1>:f^_D*<:ơsh\08y$tl.]NSʐ"t|TcCfؤ`O,ΣcF~H7 R35F R6j4# JNW(xCTE`1 k$fC+<,6*/}c000~L3}D/TWI=aDA2L )_E‚ܒ"\7\([ Is\*}`h~CI[>^`2&EWO?P|Å1<< ul.%€hJbRnG痖rwK᩠nPSuUP7ź0O!9a!E՛q?V [3B?<.,uq~'$.l$=]銓 N9@tE%NDZN/q).*fƊ6ynHٴ0`IdP7ʢ{% `)ˠfeDL]eQ ʘg 2m/5wobvմޢ(A~. s8&7{I?'n#L.!ZeU}O>2Ʃ =NH_.? [#IwgǏ0:MC39!0BJڃ? L*~ZuU%JiIIOwXKA^7A\|] ʄ79ݚ`JS[<͘ !dEw/wȎE8~S}61⛔Eo-1g0 }3?S*@NH?@Å)iWNTrVV755p\ԝ)1֣7%0HS4im<32Pl"tГj=ԤV4-Qز[\?HeA5ޅaAjrRY$G&JY{ISfѰsF./3+N{ ͪ,-HǑ`xծ*P"T~e)y20Y>^JY1Y$i K5 3e(eRtvvvuuY S} ÅA@]M«`ߠT֤dRW?{žwp8פ%g X?XO,=]xs F2UrցZOyhBihw~^.\`΅!qQ'3|2[16+ feb?K4ɓ)+op9=]͕9LfxJL?M: )^&:^aQV<ύYJZR )N[C51򋮖{5Ğ,;fr\>^YgvexR.GE-4W&_6rv[|⸃T[|0(/8Fxp%6?h38.u/N:[<G hˁ;;ߪ&ױNӑnm׬2eqS?Mo{@Fiws!L4@ggܮu䝢=!(4Tr-ۏ鏐{1|]$i_9zhHHvuvg.l zmͰ&F#AeHXt ܽ{^\EG2P'WDU–wTphړnFC,/[/! "ESVĵ Lf\PG=V!,K$j^MͩH~F،´1UlyoZq[YZl$ՍsrAU1}"o)[#l)6wļF;+^wڑUtG&fVV旴IVqg5QRAYQ㡷JlR#Qm(VR~˗p;$*Y/D*GK*#RYl*K^vu^Yrׇ$rzzÇ]a;N+u9ee-Iv 2,p.j/7jja*p~ZgꚊ¤G bwXs]ImCmEIdpHx;A(>4A^rAYOzXXAWG)KC&eѐh{wĉz|icsM}Ķ'mQEBΎCe}$3|% &Xf#Xi=RϯH'ZjLPZEgkrkڻʻ"-ӆD5q@ FGU`B SZ?ZZG/ʣ7RW]r>) 'ךXoeމe5U"Qa gЃ%U%)/xD[eZ=, ?]B&W=kU7fYL=hbKZYlVOsIR8JRq}{(>:WEHGkfXB~CGwOkef4lSU$&3'+W#eQl,9*[W; )˞=JZ!k)zG^7APHeq )WX>p)Mz¤,{޲,W6EI:p>%uA_ r2ӠQ'4g,첻C`BQ^|1(JJ388+RʢTmM+77@k}KxlЍv:G[Eq}e@D$`c_JֲgmUJY%餲, @1 j'[[u ?7֓'0 0\؜Z'CE*[D{m5]:Ơ7&2$Z7cl(Kd[ec磔\~J_:-SZ[lء1-Ry a`Q;{\P }0 RɆ,]-/+F5D)=A)COtT]c',defƼ"-ek !146$MI6iN%1:$r}QbHfL9_א$,YjZ^Y ]׉1]UBFX ݌;V]-"G; )uJ6XeQslZDRtʑ٥+ccjd|>(dKC]u [Jfb+88㗄_ 7?"0e9GGteAt>tqH9]5u7<G- j[#vN+T*Ֆ=k@Yv3,Uk&uf1PsG(`557BԨ :N7r WN:e+7_?~g̚VۓgY:9n/h*VN$3OcZM/K*JIeQZ!,,R3Sk8c@M/zC+(K`!; ZvOuL^iɂ`em{eo㭬+`"@{ 0͗NU"#`v ޭ;{XHJrN+kuT7x5ly{P6"GEP-ΒV)5#T̨^N#mHd4.W%ގIkgeÂv6_dS8RYr+u%K]̴>Ryz&ܮTDg]COy9{k:;߇~](% mo2d_}%GMeQOZ3/~OPՂiEcVrL1ce TZ͂ Ɖb@/~/oj;"!OqP?EC 0\IZ &xyF H4LٳtP'юN檿,+Zz-YNc0S/j=աc#kiyˁsQk2|W ~u.luխO##:丷N^t=/-8 LQ$vuj;oaqZqڊc̷, "[yЂHF(eH=JjvʢI’[$*v밄:ZO+n>_$ yBHge1TqXd`"ԛpR.C JYh b'=H g[ *Ɲ{ b򾖆MLB//9=*.8 ,JYD`Њ ut ɗzo:zM{NX&z8 plb_l eϊJJY^2( Sr9'0&x*AO F:7 h%5%hWZdCI# ൮֭Pt[3vӳ,5"Y NQHeUjtjA ,*F+{ K퐍٭ԐZКfTV;21Gd&?%+]\YQ}ˋv?D]kTUunqOVH*KRޠ"AI0ҡU=d}@#KgjinАHV1w+d.[CSҭ\SDJTƒ ILSsba)-`vdD%V6d Onfd&55ߤje1hzu&܎>K-,Myʋ`<~kKYۈ=O NT|6eqe]ToI/,{]v#:հ,?DxkmQ ie[S:7d%U#S`֠PKNHA~=RÐ F֨U:dJ 0Æe;J\&sHV)-[i56I˂.XDGR˻ ̨Ǝ.Vw[M+\B ,]J\.b%5uvuԷnGVQD@K?P Z8eЙ?ӎ71ki8E܈/[kǵ2NٕpԉpYZQVFdeY< bȴŠҜ =6T?U⦴櫬6p37|ݠ[BPi3,R&utɩ=Hefb'wtwVfEBModQ?AG ͌ͮj`5T7;3Ҕt+x ^G߃DV_r,:-/^z%%xSfx:K}JIyRO^zޙhWYӂV#>BP䨵jIkҭ ?'oy -5>,|8TR9`!wK#%G4A7h7;'fuɬ,(z_ IvJWEjYSRSjIӛ۝sTa]Bmw]|+b[ A~"Z7diG}O^FS [^S}Cr6Ҙ&`z^"udQP &9LW>EsCbYȲVMMWc#UYJiWUvp*):4_LҔhjȸVޭHϠ*PBcl/0šLnu£y|ωu҉U1:]R~ݓp9K̒'=us'eB ;=T^!bV9E%lLgFO,#23Ulz-OI#EJm"M+ #?EzZk.N1}I:[yk%"̼Xfhy"䧩MkepiHJH/y);Gdj'xCC/975606aHXWM~)O/(at Qs(<~T]UqZج>[JB 4:5]#4 jVpgi /$I#_Bx*|2GfAeIb[o?>:ԁZ_A"9bȾ yC}#G.^ J` [#ICmՇ!ӄDd%iS*v\x7wutpz'eRJY1PRLtv\1kBP7^c1^3C2C&=d.2΃b[YA"Z>:+R~sL!;Gd*g7}7464Ss.aLQ7axf ip$h֓r%=f5uL^Ԭ TΡ~;*MRRq01(uRTEAz,rQOMHjzBS4ɓ # zJjoʑ I3%xV7,utko-@V$ϲC=Dc(g!KAeI}MuQAq}'fWtˎ}Oq#27Md%0=kijj>6u`t M]L[rz~'*Dm]HU hd ԴV!3yۏ,ЦYib`hp#x>es 3hb 73;#u?  d65t6 j$ J4*%L9͍46b;;5R~4&)m0Ak޾OJ!bGKmI\j)'Z|ccZ2_0eAAd1-eYp6"  Pi){{lDAA7R˖b#" 嘖^AA (Ǵe5؈ |o@9,6nFDA{1-eq 6Mm\NEiAnfjvz8j=AAfPi)|7?'C.|鏹Pr(?AAfPi)ߣ@.1C&cAAPi)#;=?utPU!5-%2rLKY6{OEY>(uAQ*C ͵2Ckn~Ⱥ`af C 3(Ǵe*˧OsJY@al(3zVᇬ hT,ln@fPi)ˮۦ,>}@-.8zv.%(U!5- []QS&2rLKYOY~@-.Csz}Wᇬ h6 S&2rLKY=ee8סe8j.0*uvfyQYcZq.m!VÄt܅>C k4>BeAfPi)ˑS3e3$8D0Ni&̅Zʢը){B(f+9٣&W=*hy^W5[)O%w)fW]~T~vÞAeAfRGOEY&(Kj#Ag臆l]Sʢ0wR~ZM&?oV}x+ƝPD ,l%m~Q%Ẩ EUkwJQ{y~QDeNQ B8m]%5Ĭzoسn'9\w4/* 2rLKYΜ<6Ue G3v0429(7-kz'Zo`PlVrMoy<[e s'ETsˋE5[))e}ۑdU_Hj“ȿf+ ,׫$߬.fݱ#8[9*#wŃ8b)81/$\|{s,(9LVNE6KgF@B6fbz)M|xv3YGwbde <)cyQYcZr̩)G pǥA pJyY Az?/>.p>B2`dPՒ{/9:o= W;Hm"*|tj/N 벿;-nhQrL5ayP~ARGZoR s'ETJ*KkwoΤUp:De]DUP#$MOIeU%=ĖSعܬ,_ = OL}AlV~aςbZY䳩F"RY.%XzuyeG}$Qld`{/KNqu+EeAfPi)KȅSRA'` A{b8(mq߽䊦w׷lРv:8i x"ChM N뛪u >n!DT^U]myQ%G7hԲKKjCz F,30)R1i,BOaų;P{fbPeZS[vq7'4E |O`'J;sI]2z:%WDexձ7;u|;EipbFqs.{^Wr{}Y<OEp'vd>=˝G5"(e_B rRlI[?~BDWM5 'RY,94^OJUwx%P9]\OG!\df#"v\^%"؞nu!e KW>?WjC=kͮ Zw_ ݝ+m@nڧ͕ͤl?v?I _G8ԣבG&Ndߨݤps#T^t plvx9ѝg%f>[jհ8Q~6k4-b?$G5_'.n` oPn]k"g'RyYμ{<`3Ǒ7j KX % 'dBt$Qޙxƕp !F۳uzXL,A}/F\ m6\P4$\z&QY(ǴS0%'&,('GUUwbW*IJ7' F7eރbfM`gGrFIY ju1p5>i/5 M*(*O ֈa5VrErnAaNRPE*&)+"g7]rj {r6˼#߳/F^@*ANm!Q٥E w;[Ոw&¥b\.Q(dT1zz^8ތs]j*z.{]W_姿O.˅wK})PYfOan ;rze{ub5|Qp /WՔdWŗ@YT̽Z.7>is~FE\Z|?I/(Id^rr6j[LɑҼV jZ]#}bH]1b袊_ӮWm$<~T]/~؞p̙p z]1!06ڡ۱Y5uh~Ldf嘖^ו|wh{ϷUD~n߸-'K)_~)p3pv',z NqHj)e)Ci%%s^u CJT&2WtMeT>Ma}j%VNꃡ\B.M.I=?pr* E"*KٗwÇ<~㈻ÞuTmI`'V;1)K$)eYfeB;)DMO"7>Ln;\rKfWօN_ƮrQ̸[Mde\fc il\,q\H HNRMrPF=DjP%aA#+];Y'ĢFh+s\ǝ ]oncpVy}iaּW-Q-Ddj)۰$#+ۮEC eTXuî+v0zgJ r,G tFjDz&,';VXLqMU%EU}Waʕrs/{Ž<)#_:$v";@*6GgZ d!n߃s;)e@5nJE_YSP|ݒzV,O0A2|nU;BU`A/{ .;5eG[+gKz K*mxpTUY']ޱ߬xGAYn3 rJ,ޥfSS7r7aIFVF6/v` hL|' "PrSm̹Wt:-SʮơTv#m)5 /J*K!ol+( ْyG L^y}'AIƭ~qЙ C^$W'nah^Td嘖ܿePW݄ߝ xe1 7ߩUlhKY[^qpM޸>(ee9QDY\*,E\XatJeɨ,qS.:WHNV4IgWxʒt%lz8+jHePgJ,T v554i',';SX$0\a+Pbg$UhԚRYb;Dr7yEDɐRlPv?Jx^-A5o!VXե'ʺȺs7b'idH8 9RG^),eaW]iqi IeST@v>iCe"rUΣ{BLfTOBᖊ >K GܾNǒdonrV&C0w|A^j,q|(j_gbveÑ'SªNg^ 8V^-^?(Ww̕.GR%9F&rAͶTD'邦;?I(y7,~/,/IYkȊz opDfPi)wo'Us? 6xURQUY"ar DZI5e9ɔePsA8[QS]QѭHY=b筤ڸ`ZY%KIM"81QR>A]/r`YғsuPJ62,Q[Mm+k̭"B>w#gt쓝qڙZ'Dp8'zl)`cqg*USxӏ{~mYwfa/E'tW9:F&RO"ޭRYFJYdc^;魸He)$NS5b]mNo*LT> ĶYñ~x 08[(yp8~\S #v5<(<e -r9%<<':~><ߪDRA}*վ:HI]MTӑ0s/ovdIjd|*uٓZrR0AeGו? `8i?.*l1m"G*=z"j;F8n&k{*07~1nI '~)O2Fro_fh^Td嘖<|BZ~%h=?0OOk򣿃xXvRe4-onކ_ qe4o1}o2rM#gt-eQ)0ь_y ذ,J$GN1%hxoⳲ' 99)I,A_0OܲbY9pj/zyYW}AY28ū ss#")'/7'%:2&qg*8g+ob@T{Qnoh>Uʕ`'ee%qb$_p̋Sңϓgދߛs ̌gFr'<@U~Z=NTZN^~Vb- c瓩,U1 .nwG4m7r_q7윜zیamwJ{cߑ_ONrF`㠌^_uT^jޒ+0?Yϩg3bp&\5])N vߤ(x5G/ eƥe%G?HSZwTe>{ћWv;;k'lxj~nn*d5yYձ Y%I9@TFy Ξܢ t(K?K WrbtxU/I,נ33JזpN!cgf{~e?'b$7=[(~Ct >0;1O73٠īK|QPRU^ǕBfTQ_)Y@9,g,m(\juQ*d"!< RY.`YFC;T9K$䴤?<˓z._Жq ȬkA />]QW~ Y's,aOɛkЮ-HOXNw&]Xt'~6Gm>H?ሄ+]\$}#u侸@g^^0m ~XuuVBpn{ZͱΜGvy9U սsd+׳Os&( .6rz'>(פ}Mm."a $W;rLYp9MbqF0vk͉N޻Oގ-r{a6u~plʜꘐU}TQ+ޮ蛬F6~SҕOS| kν:[b6|?2A[ s]\P4  {7jҵhIuAuXcGnwɛOxS{ryFdHך;G Ye}:yUIFvgoq^v'hFh^Td嘖D2l"I`3׫Cew/A{B_mlLh524/* 2rLKYD0,#( "\Ɲ^.sݺKolzj?r6g&k4~`Ldf嘖DELMY!RYB^_܅x~Ⱥ̝v* LlUv,3YYм,Ȍ1-eIy)Xe]`ܙU!5͈pDfPi)Kb\Ϧ,B>3׫C k4)Y@9eAYP>9wqgWᇬ h6͋ʂ<,B]x^VWƝ^.nX 4/* 2AAoEyqH-JO o=ӛ2h! O^euWfdV x}Ne  2chԪʲ F3h4Z[uZ V*r3SQYA+E%cζfXGR*  23twd  > R_S)QYAI X]|E57  2תՓ(^DeAAd&I~3h4Z;J AAVkA :AAY,+)))999jm-, ̮,mȟimjlmAAi,W[Yݝ'' &/0\aJ%?000000xiSaZ  ]ƫ ƜV /}z}cm51>&I$wqݝ,ߌi},?a`````<:&iqʒ>q8bk5:ZV+'+QTH?<.,;7c0,0QN>&FEE }a!v`7ZJ̢[Y "0NJ,0vh ],3iT$ KPX `,RKڪĸsLY!nTvTVRC|߮,Z}Ӱ蔿p?A^oG2pvOknĶ݃`6&>H\O# 2h@HMSHeH('I_H(eQ|e`aRF LϤO`MJ$Hcё7Y2D*u斲(;w~]f;θ]uJ:Q+~ȗÌvδ-ե=^-GNgj} 434ݽ@gl:Y-r/Ax{\P^w/լ,Z^wLxNemeƳ.ǕbT~I%/;R)D)WH*Kj%\cot:PO[5&(e& 2:;;G Ea. ɐQrL",ӎġTÁn^+;x0%q%iuzI؁Z}ڙNQ}ËQ.я`Hr*M7YoJ_`('3 +I/( S>04QZ<HA ey,W@YHI,M3T3u yˍE$"QE-Bը ,#H"5"* E9LuF?^ pxj3MrHsbvG8x=M?_-yt8[7sI⌡ԤY: ^tL㗞wT҉㶮GOoT*: )fZ6O!%kH^Z 5`* lhԢ*U0n(rT, ~Ieٔ|;ސ%4JBEa' d6̥[bP8@U$(,ZRE>|ܯ1)IM'g6SAgPjVїSP*dրPmj |2zm6ѷ봵h'Q*ol1$I%:T ݾbޚB^KuQWtFq\ncPPۄT TT"S>6eDzC,?̴$|6%D(IT)֘^-7-RXE0PʢUb0+kDzb1EDv 8EkZJ1qIaJB=^VSFNj%-FPM:%EyB(:+[ʎ^6!*f@Y667qҒ?{ @7i rDUQP~@YeePP@Y@YePP@Yee@Y@Y~&J0}DeRov/bTGB|X86NN]yS>F ?cnvv)2YK' _aHDƾJ%6Ė98k0aUndԂPrZ( [ZYd|aw6DQ^pXi+(ߢ,릿>^,EBh?QA-, 8F) B#jꖪljJ0^5BͩjZGAYMv1/#&Ǟܓn9a,J b [ 2B{EMΈz\Ozіpӈcvep{7+ JI-hNdt0i2:ʲEŏ;LUY1&aEJ%XG}>1t 'O7&zRYR7O# 5Fea8UO>ɗ+ 3YL{'GyoDa[BRs͉|訟U2:ʲ ;l]6OPE ;墫UxēQ2eY#Vu Z\qxrR:'d$FXCk) b}h5gr|J-*@9̱w2FŽr0*j0-]+$~Je٬3cܷ|ֈzHwUңˁ. )=oSu_cC/;߭,HV0a\{Dus?9\YUwIڧ!>T@YPM,{FVmR?QD8chGT"Sw=yQ)ۉaCm*e_Y.k?ʂu] 24'م$( ,OYTC^ɁZ֟z¼R*Š}-ʲ^VBM[{t;r>EJ ڕ rG.OedCH C9ʯTe>a\:Gu:eyWb1d%FecY,lwHN(=ȇ.ie!t:\ -*3J( (&xv͞~q>|^Z,,( ( ,,AF*IB`+!rd9:u,[T,NON@ 2e;4jd9`g9u@YH ؙiI}=jRCf%  Lj' 6A\ʲEIDy}[1DBAq~BضYr:P-T,D*d-wMAضYr:P-,B ~PY A\Ir( (  Aee_2( d9u,B:X^" SF@ue穇#B P?_e6׮!yJͩɹGW3l+ :oXNZ+Yzìzrg,rV\4nFJWn~ΝɊy^YZO4'絋4ߖ5+27fY C 2gs }R)n}ى{mTCKg9Uo1- ?[*hy- p@Y@Y~eek+ބZ[0k|>'5a^q3䆾^Oԛ؀=wf/,Iʼnٽ3qr?(&#fuA~sw77'cƴ0Ź؁W5)7>-5 mK!,L2'L `^R]*a6i/Ο1lN4 [CW*˂嶣y%I01zey[S ?\vB^R7Š,М 7)ZSaɵq =׋wew,.AYLVq?yqz%YAI[Lw޵_`-Z!zB#9!]Y,E&L6.u$w~ߍy|]-7,ev( *\ZCӹ)K, YP0MY'1=cB#i͌ =Dyf!NbGBK#BRYL5ȹls.[,.ÜQ3-ax}Py*Zy]qr5yr٣Ts:=Qy2͍}0z}sNnq?O54Ƣe^.{e%Id:(QO]RRa@Ǩ,HUNRqeen\'~,Uv:󦸡<'! v3wLN+nz2~BOV3bᱱdAYp R]G/rƊ5E<\-v9#Dʒ+yC[?qlnV AP^0w0ԊK v!db{wdzew8rUo&pQZiuy3NmpYL|-,k{i ?ؽԊƆq>YK']QR-۰%fsl@I6S9 u7=,0Kl  u+ʫI0 -,[CYZY]O14sflh$'Mˆ4cYV^/ j R^y% [[9%Z^Y,󢔃dSRe3c9)9w-kVvȦ}QFE$zaرbaE1k͹x,Ym(l0$c\܋Ɓl eyPTh>离AYa Sqn儸M0]mUneAqiE5 K 8Q$jp dW4w*׶qQG{0KϻՊm:_T(l5%^EcvEI|AY-nFP$1S3-(?OYf%XBR^ g=`aQ(:ak+Z垲U|η?PYU܏NvY`{--+xe~X18ӃʰUecYWJ/sGc]Y߭N%Xz͋zem_ ^Lfqj~%jf=3Ęۧ Pqw:S抎!2(:\]\֗V;b %:knd5DRY ͔z"2+*dٌ_'w8\+Br J^Q}tZY)[xai.~~LÔE/ y_mN9wme5HYc;3CK1jeu8+] *B0)c??O>;aG-{f t31>Z`&Gdw Գ 3;\b8~;ʟ4ƻnӕ c+xFFǐCTS{OE=Q(_*) gV%f wQ/]Snl(eGu6o,2&)AY׌!b0 ZV[S>=j]y iuM溒3,RT$(KU9}?gк2?1)K{~kn{0Ҏnc/~^VV%0iC͞nWڃ폨V|0{{*v]hK {[ʩIiR>mgy%cHqw.Ň ]YU=)8 vUs.8#Ci2N1p׈O5%9YQ7r,1lu#{g!㛺{S0<]mpoŒ~ wk{_rJPlrqUmmE^>ʢC  ?r /eqa=ì75& e;Lrw> cjo:-kkz<[@U΁lZ-4偖á:R;V.;Gnqw + ?RE$?I?'sb{SO=nEzUSY>#ӆ,$_t͕lYiIsʋlqFbeyGcN4} $\<U _q^I|_+"ńZVSZ30[sUʲ0Qwa/~x{D;\]7#<ፓI wcc?.F>z`{ P$@@@@l]eUEưu9<]YwXI-ʲ9s7+QC/T۬2; h@eBBq;&i`Wfo3u7,a0Dw,tV'Kͪ,ߣX @Yܯ2!BglbK0\_o&e1݅* ,Zczʧ&%Vq? ʢWXM#Ϙl{~ʓim9i;'w;k&3}X,x_o藔~ XD)B `GXȣq tz}sNSʟv&X1cFe uud,r*jRVRYnz2~E',dJ,1A!e<9J*M#Pflyd1n4e#W*e(OwU|8}?[!YFv yrddO+˱j}е1%|z7SFmjZ\chn|-5uEǐ^U c>^%'֘ѹe@Tl;<C-* ,K;/ #1vMt; (Pp &#qh3p[-P~YYÙ'pvIǼ1. r%9]TX=j2ʲ8/N9av1,e[vHԆM0;^[[}*~Уb ˕ԭ߯,ʂP!Eb el4 k]C|(uYaμ/u6K+ Q$a-e=ud7vjwqKʢUiqw@QʲƲ6q=cyrꭜVB\z >e%`V!ej0U}~>eaA0k(˼4;c=X!u޵`@jxƏNڍ P9hUgv>n{eR(T`)vSICKKkCzAYTq~8s+(#'V,?kX+0NneKw`Wp8y\Lw=&`=/p؅#\v`{(Σs*yn^YkZY!~(d76KK^tabElh2e~? *n_mek̅(P,ĸz HTVmD?^3}.t+6P1c\4eqA7嵏HliWӹrX^YEO6dYa4db=y( @Y@Y6''UJb e$ܬbE¢l,[tQzY"]3PX(NONlq4P+ щ_?]b 9EWJ_ R3&ePP@YeeP~pJDRL"ReP€l)4zxZZ %ȥ~gq^vzr< ~ EyY=Zה_YO#C JD*jP+mnvbbaaCIa WP4ףV)ѹ~Pg4<4ǔpvmBm477kd~W&KI' Fdžew܆+5t!Ά,,Jz: z$¼́^\"8?g?_d3d^5|C Fr0=5E19MjuShͤLQkt)z%:jUX4,ncꜺ:? d=b!AZ ~LONDKV}K?ߨՒ"Fk"VSht:c^5-/ (e1:PH]Mi/W,lbY׋k@M6V ',u5UۉWܝ(߮_U&h)S!K A ʔaz5-6MiStD5(.V|BgM+9 @@lBeaWWЖabݒPYX@ɮEղ2I5BQax-ղB9r%?SKV]ȋ9a`$N}k?~ }G8n zbzKz5feYs?$+ǰc%1M/8'zaPi0P{?dc} wccsa.IX W:sz10 eEO\HSV '-շ_,3T N (HVhT}Z@jgZbP(Yi"oN? 12Ev~hwT LÙ!/ ZZxə/qJY&2oM/evf^@otB?йEg/'1x&W͙M:X^" ~)eYԜۍyŏͪ>e˲-v*GńoY53QLOH1cͨ,FenAAA]]]YKs3UE-١ɨy5/z{lr O-G)xp5OO=].eeY *va>OY~;Nܶ,S8z;el @Y~e)/)\n,d F+X́7_,ip㠾GA{1G^_\VꠔEK)QSĸ^F Gtw!zkn\ IeABw6]C/.OzԫFW(KiQ!Ҧ<$vČN_(g5aլ{tzsj8T⬫iyݽc.[k64y*3TN5hy- ?קE˔TtӁ|QQQ赋ϧ^ƾ!tiwL>*z{gZ"_r.eQ+^Ub7UsU< u݋6;Jog#/)Xɣ &Mܫ1+$\>@Bl+4qxkuxh ʂ65Q%Wlȳbe{m,Scɺ֤Wr^Rb[D|:i:YK@?^YʊB ze#u1EXL-hQ]d[)eA¡A¡ |mnNPgG;-F䓾2N;AB1x|p^;cYK'˓0?w{ff[N,) BqNFĨ/~,g5^12ɆmٺneS\KeY((IeIӑ:i%#nwR1==%.t./m5:;ߨEg0e 53ZA]IeCs+.q-M HJ)KrJ_;`Piqբe5).2Q Z`M/UtnHY}WY! /O+=kU Of 2?nwH@(#}<[;RIYLBYKMA$;~._YGY4 θEs_Ypq-"C ?JmT脕őL -骑Xԗ_f710mK zǺ]W&1aX~UmNBͩHT> tgnN[V^M"ac87}͕eqV\W\Xb6wکoC}O<6S[ᢽ{5؞c8m-o`V'r:yf }YvIbnc^7؅qg0q9u薚֘t]lω.>gBXb38]uQ{X\A Sv,{]heeYaFTW?>u`ceeΪirjv \\UP1Juj ~Ei-[,YgJ`DVB7 ٖnP'&ڒUE$ň$%H8BYtAQp4>* ʂ]l㡽)LhH| 3J{[-؄vF B % }Hn9grGfʢtZȯ.͊Dú;6*̈́ŠOχdY!OjJ]pd 9x/ͮ)+J>;m,yj4yfZN)K4:ק2pމ޷q )ReCIpfDJ7=9N5~)I!, zDG?&@R GroK6g\qin]Do|qBkGrB!F-44֕'D/CiT-mkݟO1|Ɨ5Vcek(˕R糎[dVYڇEL+CS!8,zy^ű~qqթ3@ݐf$>冱8^fy|:;w`>bQ$4ԃZŽkYF>x`{׎/,PeMֆυqYKKzeav$G_j`!14; 6M8Vccrz`mv fj)ek`i+g*N0h{1痨>y쀭߯6CFXOy*H,0=d?+r{FXU^v|iΒhw,R]?1nM06ѕCQa.*PR;K /31%4&=2_CYЕð Qa^sRY{;4E- xYvڷ,NjA?~f!c16wq 441X$?&'~wH-z.|"xf?g+ugKHyz?v^3jHY'CC!d!M _v&:Jpb|%e.t~hIqTިz:ƝnKƥkE(K^v:VgL^TA 5V61!bveq1࣪.#=RbBK#eb'&$3v%m zb\T8R rEB˲&~,iS|P1 & Eg[t7Rp &#VeWVxZ4Nۆd݂W Hf4rJeQ'_{V)9$.!/c&%Zpb=~CP'0n%b, =5pϾRF޻c{#XCY+e :~=30?c ݂1}Zc'1A,7 ;p}99u{_*6zva^䍎(V.)کQcc+vakkj> Y[p$3N'>BYG1,\uYm]Ys)}woo{t&fYǯ~3%?',gL5yF+K#g—.ǎ;{F4x?UYφ缑wnx`U{[ Vt{5㙃줁S@ +6ѭ,V,(wv \ABMʢL 񓹫zD$Rr5ewTZYr2SKE{jc!8#8u@Eo]BOGje5;.ףV8}_wOF'QMM*u -˛%Zrn8>/;OSP!-:)Oli#7"Y+⬨Jhy&aR %vsy# ʂvP߱y]CRZcYք(!W8e9U"+˼( )3>m]K3'+iQOuMJ3}͆'(KnV=ʲo_9_NJ\t́^Q}Jv|kK&| Gk>633ĮA|+ڙ>͈q J% _~WO[]_YuE՗㾯?`Qvz,Bi,rkjJS^>vAB5͕qY55cj?Y-2d-iȱ mrJ=Vv g$9wV'F:^IqHH/*ʬQM%&q_@2ʢQ؟OtzIY? q%AY>[>Y-bшf sy kWEltWlYLr13]al]X\a;22隻GU_,daSjRKd=;k7ySe^>ܧJuKʲW^a`YU&Nu~RJgR^KM.᷊}N;iMtuS+ O.1xdim ?gVreTĝ؃~E&ַ휬4lx]o;9^˯mrJ_Mʲ0ٓ9>:d9>ѵb`>1n>(P[VA"%sWыoiy͍ZJTRRiUA^Dִ UA8 ,(YP2ZvǛ쳹8! C"bg%VT=:۞ܭҬ,{(fה&&U+Rg e&QU!0iCJB)nza'zn9 ^nPMuĞqSa̠T)8we|002CF(l͑Tǜq}͓ۡN`䯈^^2tb0/ʂ]N}xe??t+N8icPBP~w8:<'OtD'U5UY ˢI۝؉rF+{>gظp+U˿i5u$ T|'~q}9cK2W+ =}a;+jH^Vsl;lۗkର Gz-f#U>%=DɁ'] Sv۸xD*Frp"?g~q$5RgLsg>ʢ'81 djr;Z?;|ú;x]fw-c.nJVY%EWZ]I>8=kHl+KVz| uE2?_|1/]$4??CfIO4i(u@+FFe&*Q Bjc[C1KdPR-,Pa-G< ayF(QRKsD5j)3e&9J?g|meҌϳ3s sN CDDKA.i$fRC=0`v,I=w?KaLMҙ}Ӑl<ӳT$X g) =HۤG*!4jIC}(p2 ݢOvCԠ׽&]~Ow=fan')g(KFj-+J c$en} 3D=I;T@i(j&R+v 0V4P5-#GARZR@ Pi7U-(A,(_ª/&5) ʯ)u]+ѯJ N:3ܦ˗/fnoPSfF6gc{UW>nP^#)ލ}laWrǖfo $c (Kzg))7v%~\*v_-]e,/Tے/Ha&Tn 1I=%%O~ZӐ賌HD[ATe(АB D,j Je{(K'tTyk Y%+|U O6evЯB6ǭo*l>?F@=Bz[1ɽ~qv19.oއƖ~눶V.x&RDꖕ@.7(} zvm]m z][G,ݧ%{m#n+5^,oCoRw3R ?:Je[(KfZX,g]BtلR3Zczߌi^J*}@)eAgU,f%m}eQ>ʠznuH~7RtҠ^r v~N_go,)UGݲR?Y)WTѷge[r\vCj[PSi:]iLMQȱt oHe|ZZOޓj R< F ʲ-hԗ$ʵj8SC˛Rبm[zYMa;ՖpgdQQn@_T-?#]SQ~67e q̢lΐ13 Y } ]6Okij@G j8AGT*l,Ņo 2ă,te3JQt WzD/א8 J r Dbߙ, P l_ #Cډ/ݲ ;UqYi1dC3,|>mM0bETa+LSLBZFIu@Y 47qҒ?{ ߿IKN@gHjA# OEzrBq~y_e]q}J*4Se:9.SaѓJJ{ AY9@h*x⯹e4C uڪ]PΖlP~@YeePP@Y@YePP@Yee@Y@YeePP@Y@YePP@Yeeek5|CP͊T2(l]eQgsMas"QZ@,HY?5芍͒xEWPed wݍ|8?T{92(q $tۉSJ;A4Ep LPjFrCIz"WtƟ50 THe^.+MHΨj8aogle,9!?L!BIJ`pJZףFTvr`V.ݣk=*FC{㏑k/|( /Hٔ߸E7H#jiQ;b猐+U}Tυ>q@Y`[e1: !Ͽwiz[rj8%ʫN hgȭ2,J{?y%8@tA2lFj9~|e|[eG)XخbPvJDRض$"\l^Rq8/;=9]_`{RШU,&m_A43-iGRj5 AUҒ&,C&e.B@@@@l 97@YMT,D5P! p''t,fU * T),,,[eΝ PPPo@5ZpɅyu[U jJkM>d-g,O(ZږqGar3儬酣.j#&qi4@Q }x%Wb!( (˖V4ǽ#^&pHE{JKsSܿ'5(˟-PPm,ƻn}DhzEWa?B^Y/{t3"aS 'rmXVsU -<>0OMU|.ǯ7M>e1݅* R֙0 L-fRX7q4"n`Sޡs2F\{w5Z@~àAY`V( (OWuIھ^W J. BQ+ H{V+f,/}dVTUU~o۞ܭ0m:x/ͮ)+*ʢ$ӂq<(_M%"t|V"/oj|`4JihoB=ሻ)d7sNW+DĚ"M_m${Ͻw{}v)!"c1 6l`IL0dAse$r|`plV+ȍ \6Ӏaij)~꬏lb{*6 ]M d,~k] [k琜!oB]mGl+ cZ;Ji^YGj!A ("q3DH'*v|m\5'QSmIxU/)o9a&aGojE%wG ySd:rbt9't IFRY$_m`gĺ,8,O[1,ʧtSg9KPZ#nr:{(t ю%;W ꩓ad[{gto\Fl!A (˗1ռ~pSE _uFc7 5 /iVΉ]eQ)9~ 5!?SYٷ7ӗE! x^57d &ۘ ˴(rir/TDXYvg>繞"ÿaUX9'&|EDzΥk*_om E14Mgv5*wNWcz½?~ B $P7Y6[b~ˉŖ\ǻ?唗4# ʢP̕z3>s¶H3r|ɬl/bVolcFF5M ZYL|#yQVڇ8:6'…"0crxܛ~{ =f!˻aVB-qtHqUOO,7S[O~k:'IʃS!A (W];/d.r IDEx"( ٪lĸ6ĄM:͎HzYʢM7Q$vQ8-C}{y#s@s"nh .(OE҃aPb4 0c$H |]ee}]R\[9BQ'E.Sz!àEr,%lH~WYH{ e5.+"Oɮ,kVHBv x͵%- 4D >[_[Խ1cH)KwG6OV t$=ʭ5osʆlWqyO1 $H@YJbܬ,+ĚqB2]riL=Ebr5\1wgtRYTar罇?"SSmZ6EnM:؞Zβ .$g$[3-\#+. 1YD<\mKwEq6! :E朋 $H,,^m#rb^KOA $PPKB<77<^̙eѼ|_e $H,,_`]Ȣa $H@Y+KqA.!U $Hpplfj.TH A$X]z}t@)+.X]Yq+$H +w sk,ʣ l~n>IqAn]UG), 5-ԌOM@YeP@Y@YeePP@Y@Ye9\tH(D$A(,ܳ3ٙq=y @Yeylc2PK,;G«VB4Xބp7|F2o&Z9z˛}"yfleڔb!7rz|$WOb&G g^ PK,_GYjE 5FnJQucc]E^RL\͜V4wv6U[ dD"_i}pkY&eޕ%=yKY$]-]u9ٌI60\r 1Ͳ9u-x j jOC+r}ӊQR%"gxW-*qw K !(@npWsmw;wLJȌDߤv RA,29;f{zP>*'(}mK3wESY-Nd>sHtK⭑vɩlK*^; gs33>7w ^!4{-2-#o m<((KVZyKY› dz퐀#,k>sc"']"t=6S.{1^sJO]x>,d;,%sr|ūH5BFwqKiU]g__gcUMPf:![\y{oo7ˍ+算4"d[Bb!r˟\"0]3ubϐb$vB ׄ .[<cM0}Y5W=4ҡ,U}CCCK|ȏ<8-%~&3*Ѧ,;b1n]XEzŗ3˿l#:zMb*ϕԳel+)b,pxGN dDmv<Njy\,<4|ieL=teLWǸz^'*QM1rz=N(%CvX)W5 ųrI'u -틵F1[%Xg b\ϙp8l ]y+V ﰐm|X;E4-o6ZTw?dcxGZڰl!SV@I('lMi"yʋt IX"FuƔ^92y*>,3hA1S`T-~fB2pp3eVTIx=O-IDeެ}j?k(K^vyv!tӀLİ,"<2mD>uXFv:\Ea-*bmCWRv1ee^|(S[5ǔ)P6>sd #>uV62 8:#cӰe;# W丙 )RM,au+x/al>( (WV( ^휿ˢ\x7ۗ]h3\Kjh`)7 fR=D qC3dxvA;3e J?}㙎Gʢ!E[Yؓ܋fTU™Y2O{]1J~nϰyAVCd%t _ HG}n!j̯vMš5CQ8'5cH卐mB,Q).} X~%qXƤVD3BnSrP?LY$B`yiGSwpOӥ,ҡᱯKj[Zk _2G";eʂ"*uM!#+'T?`PScBB)+&3nDu-|GXfe$gNR9=!ф#h^vZ} >RY֝7mɁ3,kf(I_AY XDu -HBewź(4*roe{&&K,1SXwpȤjeYZh+& sa'oP2\TF&a ?>|qeX_WV8T]@Rg_dQ׭5P|펡P.loQ,G,eP.Yf,9chUB]e಴"A::Vc-jX-WY0rT",S~e(f-ʲF`H X,\eLr$EIeTJMjKBAe! mQoePBfrzJ( $Y)}ǔe}MEH","jg;0/?7Y3^aU V!" $"ZPHJ s+ߕ+)XŴE.UWv@Yer|4;U_oL&ڒݝYi)uK ?D,|eejWZZQV<8л8( Xߘ~3tW$^ 235>;=9735?;078?0c)D(Fs~G>;ƮwMGZ%8Enoo7 7ٸONn*5y%MWd-k`([j"+e4e(MeOg8>.nj൏ >S>{h$ "y0ʊ7=m abJlm6rLGľ_m}V2)fk^0 \eQ(EϮ  T(˧8^Q;EXl3\1|hYb}%+QOͽTqt]L>>MYrrJmll5%ߵCV-*sK,_vrXA V9{DJAe]]MYnÐK_^mHɻv;Fd5pʲ_>Nj]JM/WP˨,}}yJPOfya$(K+8nƯ10,6˓ҝI_Iv4hvo_b?.*#ߥ0YĴuFZj8B$5N!rV5TN;&JWI &'\'B3 (e9Lee|VΈ9ڙnzct 诈:M!IگP]{!3/㞳*˶0=,Bs$3̜^hMulV˹×[wN9˶;&G"GbF1v =lcU6tؓ @jUd>T1熌qW@Y> p:Vtgzq* 3(KohOʚZ+kߎ)bU,jQrj:;2Z INwe 3"N n\L Eu抴 sFɶzb1ɯxeL›Vg* 1S]Þ|ךhbŕvs;|̛좋ZzuJ:j6Q7 qf$"2d y4$ GΨP>lc|^gQFL벮?) 0ץ,ۆgrB]b:G5cs BzQTuk[k{_.6-kBέoZU. .W2ID;UKS+Ot+VdXe38{1"TSV޶$?CY}Woz5TO( +k3Eu葞/mytq:R Y{PQ7!*g)pđʒ\DJYp L3፧y5ܖꒊ'*[̍,tcf^KsUV BWJyjߋJ:+|ߗ%^suSOB&n ,evp,U4mvTg8^uu6V *6 9d|)29.#G5͗z 歺%B>{ A30*oji̊ta)JҋWA |"SdZI<~߆sbSjxeQb7P?^w3犫{H\mgsaǐrLJHeE6XwZfIFH˓=unuUk:,x U)gI{=qz s`0Il@ٲx%t?DơM#׭b͝j&Q1 '![U C%%}]:nA$;k5stB̡>yNljG!;M둮<_Ei[U1tgJ!j;w*a>>0Y9_-7ɦSb1ͲyBXn b1ngꓱ\ 4.R-Cd#f`j_(4O%/yh-H 3ᕵOӝ)p#eDъ@+Є-|# ${Q{1݆o >T|,E͔TgTґ@SP6-g+X#d`y^=K׍SY#R~&D|W~WDc7w,ιSrEeΗwD!ҜP,1RJ.rV?} 2@nDztGyTy]LvIʢ?2ǫHr-[ (_>sb ڡ8BE'\?Dg(z'/~yܐl|m TNĞ|յƳ3SW_;.2: YHجs`!dq?{QFkt dPv< `߮_Vb5aMg]q'cO6oavBYZQ@ |o s2܌(~ZhjC\<$|vW cf5)鉵FLק%ܞ{P( ٢kO*7BC#cƦӭ,YE ;yԩַYG.PTJ˓B]4hъ!cxܛzt$){tq(WH|P%6VV8UE̽`8GMyF)N(ˇ&)je? B:m[XY,j`ةuQAǿ\剫*uΫ,⾸+2[rO BRmF V"BLvB! t"zlLš5-xDZ_#ͷch4bi"_t x=dռ$ݥ8Gvȣ'g$SdاlۧO1 2|%W|1e.pC[e9#XNz ˍfd$BET@Nĩsǝ3@HƑ:\OJ{hvlN\@ZeUd{t>@uR,1sg;BoK ?`=5 nZ!M!&fi,.7qOu pUL7N(e=rqG "2Lq0wN%l$x4ֵbC "$+6*uUԁoLx]=j]P{!dk(:EA̖"}XFyϭ/-^QOY<3~wo_gc^2[-Wrz{{xŏM4FN"1d[c9X62ROeY[`Y#m7wb&ЌF>M+ {&1oZy5Ѿ-$Tg+v&83},7!*f8=\w)Σ,(lQ9Y˶'F$7qyUy<$2MXn'pZk*ǥ3gϟccY%*㯓c'ZBP3 ͸z^k 'pp>c"'BwJ<nvxE:㡏 ?ɫJ8"EHv}g_@g]OQ]EڋJ6QBL~kKk:U4q9EqFy >z:6ɤcE޶4?61Bz yU0IR>{Oae{>/Mo^96ch:2ZU/cY&\m*e/$Qx FF*r+)JoY7+LKݤ99S o67_s V9IBM,ǘȴp&Ω,Jy 8&rfJX~5` #;c /CsG6I)+&KôץyD>us'[ꒃ?v+vVvv@jDMt Ih!8^|HuJ-=ZSw򙪇.fXW<" Pr_qPNjgTz2p=c9Oa GPSęV>OY)g:Ǵ,+q~gmZ6E|Bu셚w=Tܬ`?,V7= s9tj;wʕXM_mHvWm~qie! V=%(9f 3wYP;fB)E?/]$W}^8g높ETb%,˘v!o7پC]y% |.kP?^|}K̐c.Mͷ8;0SfL|젪y?P|(ZHYBoE ,_Ec/9sJPP@Y@YePP@YeeN( ,,( ( ,,( ( ,( ,߃Vx%yE-s%:13WG)bt%WzyN| eQ xȊdM@Y2*l&񒓣FdSo\)oHb 8iQd4,@YTJ7X>Bq Rs"]M+S>EB _B>|>b-5dy-C  l5ϋϮP!?lCasEXXjCq jryҳra ߣڢ)E1N3rQ'Yx͌(낎ZS\s_rb 9aS wE)'X[FHpU|.riôuKH'%g @Y?eƤq| ZቁGQ*SE0,]nzݼVB6hK5_XP{5l>Kd[Lvf+eޔ!]rG K5j) p@G3}ZW|b*?/'Yo13ێV>fg) $PYf/](Vz]3Ųp L^uV[D@Y@YePP@YeeP@Y@Y2X$\ VopU&C?rALBL|HDёw@.eJBaa1 1 򝷯3]Z?35AeJ|ӇObYQ$G$(˷XZSY:35",UomnBA bbc@$X[*D r6! ha1 11 -]J$|B/@AALB1 -$K  [n*dl򕫇=qkV\ W!݅tYht(7B4ܷ`uLqQ~W2/;ZB:+b0~Zຽ\ʲ=`3vK;$BH|a&[lI f5.z2[G.iX  kKr7B.o=1Ȇ"[~Ue], s{ѷ P?zXZ Mb MZU^0fKuwЕ܆%t$w|*%RM o9eeeee: 3fr#1,u<4Ñ9526mg=@Y@Y@Y>ZYDuB56~fѷp/pWs0ö;&U+arH4=oR@WYy<F ;W_ ]UoQq 'rſ𪔲&F,607LLjM^2'd-hٲ֌Aʢ-o-3 3r~-'KC*L|r.f{KVzEq:P\/iW;9C*hg&'Ўz *5H63&p9މw,b~j5Y&rGڔmN}% G,nh2/+U,ܮ1ty'U*'޶,3wnBd9\gdx':,f!e*%=/lqe_P0}Y]T3e=&Ȥj}veQ,ԅ!st~]ssE+]K^uu6V je\(V"0.,ify?}7oOzOɫy\7RF[k9kճld=,мz~G;''6:RXi?Job@?/ )L`VKWGMM/<('x=:~''OzeGS.q}M龿|\Cv?(Wmg=vZz\ޟމԏ zh2t }qeNN M7M6ie/0@YԳzV+9KPGz W=Uw;hgfLQЁOzsꖕ弫zzvy{gK%3!˳91! ,F{^s6g==aCeᠧޤmgW('ӿ~S4YYDԑlSllЭgRL~m[aI:xx\2HIe"UDm `b)[YDƧb\@Y@YN(Kջʂvwg,ne!ʅ oX!pm[!>UYO)K52f҂hSL>{'g=ʃUN+ˀZYmT ]%f#thX,k]1 '@ bh\+?+_fcdo?+IOϭQ%P/%r~ITDWZO)?~ ?ewdet O-#i>,yS+ W $VnPɋ)KoWGc} erP(t4bi:"_±I;1oqVTTQud~f=Eo g8ޟorUB;Yye\V.t M&Fmt ]7z ĺU9/ډۆ$]t|ph,'+ϥ,TڡMPmig+{EzȞV=L'"!Qӟ25cW a3M M($]-IXӲc5D1$%q+|}ʐ3beQesc]ow(6^\3 5L-mC+& BW㺅J:V[imOc"[k 6DF>UƩzl7%utT vw^_Ig:~WSS>MG͛ѾwXo[CQ lT;%ۺ)b]QyPO ntu+G {՜pbgmrIoON -㶶6UiQ8GnwXS==}Z6LEQ3Jj8E3Vfr/9%eh 53h c1}˸-U}E%(a!˲&><9 c[]"y93"TMYN*yyg ʲt5W7V9C弓%cqW) 34uA*WZboX2[}s{} jeX`"S9?bg=9sm+oT73b(:гI)3zuaHLeG[Y_yvoԾ:$dcZ2-!{kO<.(g99+ [ߤ>veC+7&wr595z?eg)ߚWdQ$Y׋ffKq/s9ᯥ,dJ_QsV7"򺖏Mr֥, bu3j3')ٜ^Cjхg ( `.u l_ @a>H,,pu{)`}i;Y n}@Y@Y຅VrrxTÑ  bmqA.!Ar* $KǕ !VLM@IR[_]f~0<,CC>>>/~ rI#e+R! ₅ٍ53H?ZALBL~tLҿrZ_~WwY.J ds3uQ] rfgaa1 1PV/I\Q*%:,lYq%~00.gL6UM1vian?uJuw@Y; [5i_\"e,[SB.kki. ͍u\>?; QeQ^3gnf Nm-SFNM%mq~/W5q.,/-T`k%J0X f$,-^ ekTV67`I8ϯ} eD@YeePP@Y>FY b~vztzgq ˏS; ' ے#[rc^=V)d˥,8"'G޿ON0nO 17+?HpΛ6ʦ=54oыo\:']yJ,2735>:Ot:\B>?N/9_c#n|||giO$e4/|_M =(T/j6@S:x^A4uɶK,=]k*w<:O,Z/G 5n|||gis op_EJ1S (zLZ[@&TA h$2]"ei5'xċ9S9}/[p[>ME^[A~$VhJS5U>zn8& *{ ǚ<.)e%~~$./'%RVn.A_~a:>p[>M..t_AY ~èY!l8_V4-yK yyԗHYx $Jg4EG?>p[[vCR־M{oFzAý|ï|}{9GVp/!?e*{d"ryˋK}XO{1-j^vLd.xf@8YQ.e/]}w9|KG?>p[+=+o"F@iW? ^n8e-y`nn^^zq9ytwP%ťDĩ}i=E} IL3{YcGR煐__[žgNL2f|t?jS'ƞՍ-QS/ϧ͢VQ#>n2Ňn||N=hEOiW= o'󰽜}\SH:~7.:^xaRoZ:QLΎqv4n9 fPYAeLdx21{ɾOgoүl9/qyq/4Ukݑ5"dq߁Xe[K;b|1WdFTFi]3vGml*Y ];8v觝^-v8|{Ҷ҃R/qӮ kx}o] "ow0ӋB,&Q|-aàmzX{,1w3ʝ eY݋HylP=!{YY҆׸ԗHY8ȦF)eq{wcsk!!M;۪v,-=G r]" ՆWSvŵ^5 ]A~}}!鶃1iv6ɯl6t25+u焻ɾv;e16 =a˛'>lI nZY2_;ڦ+nژ0l])TWhQTRPxI/nˆ{۰YϛVYj l/4;PjK!:h[PA* В\](p.s/ wwQf!̻;Yww`Hϳ%&}}'/Ϛ gQ:Uyo#prg,ѬOk汅T"($ kے:\UΎNTIÊmd5d)>Xw[[ax\N)(=\6[oD5r18­mp#*[`r;AWv9^?{ Kɓ~xu\^%b!ۤ-1,>:V"1oy#u[[gߓ?Zțno̾qFF}^$t7fr:rRYZdgò]*kn흴ۻw1;;0i;i"1A['otŏ7blmb 0)z~]*P @]]jdR_"e./ߧQ]oml8>d<6SɽdqmS9)BƮe] AafvMyl, Rꏔ#dMlnmCO^}c 5_OEFaR͒ݬXYFu #D2m憐<^5 h2&=yOPMu/Y;Pറ~{=ysSu[Sɱ7J76צsԷ'.yD)j*%jT:Ǘs%Gf8{dkX /eꏈ+?tmpkk8Z gjbbu<Uk+kVM)&^;"SyXW ϪU՚|0ޚ\MFM*˫1v:t/>/Y;h ot{=Y1!枡7zɢrm]1%/QW }ϭM AW7.o3 ~*e7N).t.~.a'-`Ȋ?o+NLLo|}R|/ 1xsC+K\{n*YSCGA,Lb/#2o$_58T)ȜSqqRwRwqyq/%:ek>s8װ֔+d=7-QOiXB$!9H҉E%|H6v 1}ͫȆ"ՂJ%'u!n@ގj.Y\RmTQ}U+(%\XDE(r@~gfY>g]Lvg>N6vIҧg]o<嵚OFc{NgD4;k2OFJ6뚛 jSnx<ӑYW־t,?+btD/n N,Go[ÏMKӮ9.\¸y __9mѶKUl>6)1LYƺ 1k\/ ʏb/%P4GPI u)K}mW/>|Ggم7~u*v%EK[ϴL(.E~f*Zڰ;vGOjn̸h[EUsGOo6)x˴|\Z}|淪GY0*m:Z}=S+Uv1RL9(֞,[2*[07V08UomG[fs,;%|_(hh]-E']k$ś\|#Ρ"(70fݑ\n*bSw?E{.h`ERGz$q{ۅ*+1XSw2FIws\VΡ,gzlvd;pSwb%掎;ƦAn r϶7Jd9ѷp 鴫M{07!9aA/GV+eMJn齷HQO)7q=:J9lXo c=U`#)ZGx}H;qb/t9Itbėmeۣ~T6Zg=I9Fg{O&xUC' Gw6g1p!{_:Ӆ~qLt%bV7Lk yVE ݱYOOf1y8'٣;Ҍ?de+KӔ·x•úLf,Sx!_9clp'AY :]Kڐ9߇ERGz$谨&x׊dK%ڟK|bFP&^nʒ\T}Ʊ['#YzÉ?P_;&v/evӮ:Ypz*E ?+.ˎgc%6xӾؿeM_~ηWds1}KVV<XGA@hP )ZGV|]z n;O2v*X!TXe䩖 z# Y;*gGây#b=~j,޵Nt˪K WlȊ>ߠcb})+.&ERG_2:\[}.U_8WV,K_vby`ggʕ  LNMM-((hhhC`#p A(6BBAD)KZZj e>) AAk,/_~:"NVYNPǏARXXe,,G(8~  Q"( ?YR`0Cɓ'< e! bm%##d2@!KYFYl6) AAk,Y( lN,^h"˲n =|  QV<6',,^WQ<=99ӞR  FY` f?YR@ 0??'榧GFFHY Xe)((s L'%e  ̌ A6RRRb4a ؈C~7Xݚb9AAk@eee'a#MY^S}tι>\___QQQ\\~4( BP K( 8L{@!Y`)oPN|ƪRvꦨ< BP(#E%` x, ,)/ituuc[mmm---& [olll੧P( B ! 0,.W.0 FMoKBXP7εh_WcVOOOww7$IP( yE%` } ,)+DߒhXFGGO =BP( ee DF]1`)W`)hZ޸M8b۱lkrrrbbbgl1( BP.9Q+`p |C_7bI`&ZĹY9lfYy,P( BYY4:]1` KyMYkx<؄(2 BP(Py:!Ӏo,{~E(,m-~zwH\ BP(IHc4|5e k B\b) BP5Qi7 ,=AIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_general_ssh_encrypted.png000066400000000000000000002245531477034762000301750ustar00rootroot00000000000000PNG  IHDRlsBITO)#IDATxWI;?s {ql[lp8bs8Ac9眣P=ݷ%!0!}׳VUuuӭş?P! fak9嫾b1O=bwe-LW,2H{}Z~Ц;5P1`~ [W}ص^BgZ o kL[W}vAkFQSBi <:A8/`e v-e2T*P!6craZ'+.147:=Ƶ_&[.`_kPy<c h^/_~J]`l6V*Z00000000&<"F^vaBhXY,G +`:$mjjcrAXx8X}lb-X|Wqh_]~]<AAHE]+))w렭r_?}+y9rc;  wa ][߾(((X 8Z~_`F&=mv_  ]M hNTz0p0_HH, =}Лu  ٸpL|||FFFee%`)X*VU(Bf755ӝ  TRR6Nf~2BYbh4r\ tww{y8x  ? w?bRYx<^gggmmFM6qsm+/_`h +\6NT6DAdؼ<0YF(K__Zl.QSSm\~E?sEw=> E\u\jpl~ }>^8RL!  sPOFGG䀁bz3,*J*JUUUΎzeݚk_=@uz\ .wõkV^r۷޼rexeHr䎻i&bډ-uBߖ"! O (Ǐ:_u_Y,89wq8W^*쯻;=!;]V-ݸaը HBCASB]0H fQNpXtyR1aR 7H,[N27ǵ]mMcI AAoÇ_,BS!keikktdsv0 Ǽ45'mrڽ [6\lWt{VNy--\v 2/q&+`=7.7% elrϥ!6sZyA rwyBg:{W-lxԑS'< ,)S-N竕@?;r"VػmZش~u(hl=뺥ve4הԦ_Z6,#ei4^ۊKJin.ͪlrx.Yh`Zgo]niiIWۇZ/A{nxx8( ,$UMa_3 E[ӂt҈lFX΂5-o#ǎҀXǦ=sIJ,^QVHCu\pGgS ,;5F^l]`g@al $:nd?bߞ7dpuIG/7ou,Xzʹj7oޯymXz! O(ǝ;wYYzzzhem*5[оm|&W-ϗ;xpwK:Ӷm|ˆA ,):-N6,_+fXBuGk/Z-=1 ؚ dZ;Ϻ c7ndX+|KW?B*nɇ-_rz+eYdMCe3~/_z! O(,iiiPp!HfKKK7_iQ,](WϿ (pǪQr`2YN믰eÝ;s0p7B/X:;Z6֭\dժm@;q1Dg:~[gptqy`,J m\Sԓ}VQYlEڵvK%4g_`޼y ׮n,󗌯,Km:[L=verkYŋVqްJ7ooӚ BA P))˺7_9K_~A.PB."_l` /ؾg?4Hm[}Zmh"#=x]sbzҦo8jiٷ_?&qB[ʲJYp rt1gY<5[؍%][N_ TrLIY֮Y3U+8.V 5Gmlݎ;7HܥKFmhNF%V6T!')U,^vgW֚D&)eV~{]JG~[a1 PeKY+˦kl y>=5?#&>җn|-Ros^ヮMj 1%eYz)XϸXf`_uI |˗ۍ!۶[|h?!w e٪vv~_[l?Ӛt5.]`Ξ?XnѢL 7qݸl\Dr2h:j5KZrӦUt5oHAI9~e+[ [Bo$k  ? SRի%\d5~ ^H_b-Xz^5W@TV/ZhLWSE{1ۨ]+϶  41%eYrɚ&de-oh2 gW^XXRuc=Lc~ԃ@b_׮Z6몃  ?SR+C  P@9,+ۃ  P@9,˗ف  P@9,˖.AArLIY.Yփ  C嘒_UߧCAr  ʂ  ʂ  * *  ,  ,   ʂ  ʂ  *  *  ,,}:-AĚzG~u$InknuK}:Z΃b4:b```X VWg[s# $^D(0 <4cRf P2 b@흸A~!?؄awuA?_鰤?blu"Lݝ[#T"y0t>Ga8#1Y3lt9M)D`AMEL*C+i<,6?l1geytPSek$aLFj&_ z4үt5CgN*aSFN.5V!yPYlRYVQ/Hݥ0Uni\`#]h!YMY'ZQ,|7e+?IӤ7$vFg~|+$ć0o0+w%IQ.yZ%~/e)$_w͍p>%gU>}&>ikB*q(+tAu~v.斖vyT ߤ,kda>Ӈ`裿WrB .l$-ԄOANKOuH'O>?>. ZHfnD,y\]^Ҙ>W3Я3#s8 Ŧ+B = A}֓ZMMjnUK-U`TD]=}6^MWF*Kd(H) 0q1i3vvS)]}gyveщr{5%)8ڔ^D@Tj,Y#?OR&=NK!U;kaQzpT7SqR! EGGG```gg5!ї0\I:ښ $zX}ʚLJg_z5<<,3#ݻN5)e)jZ'VO,V+ ŀ. zy9@'=\4ZE;?mnl]`yZcޠ8Ùp>%he z|X%bI+o p9ݝMٱLfxroetiR=Mt QJ'xyvueFUO֜|6gHqALߏQ]tܫ!e)1{ eʢ=?-sW"-%=Ov9(j~N2p85RmQލJl~g'8.u/n#y *|%,Xwx9Qew-EMcp%p#~פ4eqSn7/t}^z^*cn&+}:NўX _N*K'u[m#$mpF A~ZW=5| [^{k @`eHXt ܻw^\E{P+WDUwT‡p\Z׊HOb`U ߝ*U.oA:=zrRBZ*̭J #DFYٲ-En,4 gqOʣ`팝/J{Aymzt?ʒ"Hf}Դ% 2o%@YX_-V^C@D ' 59|y 5"s{[/3'=HxߪVjw}TTJ4΄k¤=Co;fe[VP/viJYmeޫ^TǤTܬt꼲ؿUqJǏ;v>wӎ1W>AW457%A>h'Ǐ#JH*,JAx\+WYij q'azKϕw55ŵ㠶vqm~eea|h],ΧR[X,V7GQWK)KAhw4;q=:>bV"!IGG{>| [^[K# ,SôG pzOOW5b s&t#5[9m]p]iCY"R9_ GTN|v*t0A}, N#XH5XnW`呛+{9 uZS~;22îbTz™p>CqeUq3ޠ,QuR }U`E/od-i*VfdRIJ{ OiPF-,681L%X|ף\=53,!"#)u}҆D&}1uwf$3Z铵dbFU9Ҥ._<Ӥ,{v+jmAx,A!5Laf=PH7A,ԛ&ee,ZN!L!}t# "(?b :)?HgJ䥗z nA@Åj\FmXiu[ God:ʩS}ǏcuwZ y[,KmɌ.՘VSޒʢidvuZRrnʩsQU&]=j=١r j|ͻ8&U`dj=o2|4jVVxޕq=OO{ 0͓NU ,00rM;e =,$9)iʣuDu:t6Ȉz(KڃZ\ nѭv@gcudp{x*vkfTAFֿg%4.W)IcގQkge66_dQ8RY+u%K]>Qy{&ܮTD9g]COy9{t0w7P7[[dI~qaPl 4> FI>i%&H?M\@Uzl(˓fy[mG8(˹Rŀ%Biٳ (K4 J$'p4Wꭋ ?T@  0Ppak$ii&$5aPۧ4j@@~%eϞ}Zvd:5Wee[ѧU[ߧ%i`B';~`ly--o97[?`{.jMFo|* ΅mc-9#GeyeK1=1=:~T57<aN[Xywry֢X&mK1uH/ 63BY4fxZڡG>;huƤf:,VmQ/<@R3ϲm*NY{LJ\$20TM_)!,[AY4wJK~O ږg[ ;u*Ɲ{ yb򾖆MLO^|z:[Cߓ_p3Ӌ2)eA+›щ҃ 'O2Aiv2c6.)Aj8 &fio&-WX j%ϗ@: ,s~)JI0Ppak$inq\PRS|EL64"^kko Jww:!k3=22]#"5-%TFTҥjw̰v٨ZO Y?iցZOvh#cy~DfC^5p ͕UmrZLԦ^ev!Whd$Uu#(cf7<@YU3LhIי2 ߓU ˇЫŔt),5ҪCSfXr32a+3^'5Jw3a2Śyf5:nGU勦z>ˁŲ%"eCFGbʬo©Wog )8d:0$GSD崈5ngDz5Ud@}Igbt pU3̓NĎ-钲랄rd4<S^4K)-ʃZ`AAicJ8 _N$_>cv@kAAicJ(-ʗˤIeyiAcJJK<4Ǘ/ENFD$hn*/*/u4Bgud]ݰF3qDP))f(˗P14l (3lVaN k4[v@9,۷MVY>P"YwP򆺪[9Yl7oaXT_L/SR];MNY><4ہZ@] p 鴳(yUyɬœ h04oUy)N1%e?gY`Ÿ z}WaN k4F)^@9,|b4 贚 ; s.nX 4/* 2rLIYORY>͆my{#٢7VNзgud]ݰF3!Td嘒 >8/9^f>CTf\,Z"N)C[R=iу0؛sU߲RPN̪\e * 2嘒8zx2244>0.iv{;dn9pIzw࠭(FI,qs(eרUq-obflG0牾`UFTpʑ؟R|VҦgiZS_Sɑ >HT4tӶ;YZJ̪+=KvUA (ǔcU1|8NnC#r sR^=bkR~= c?B].;![^goJE)Kߎ'¨YME-[I(e^)nu1#=  ]IP/WM)}fp <.e %WTG_ŀSXyq&FUs _ruzaVHm"*x|j/N ;-vk A rT5nyP~^REZgRqs'DTJ*K[wo΄Up:&DEmDMS-$R!nu1!K8z0-j&sYY &&n7i0{z3ʞEgRDx]J(겊FIB:+X!^~~Wh3ҩG͋ʂL;SR g',>NB pdQh[Io'oAv:(`D9 ۯ5V>@l}LJ 뉨ښ hвKJ߇B1^uFRx1B-LʢTEZK)KSX-#9A2)) כsSM"\yЧVVd mOO.=w ʒ#T끛ɝ:o ,RWH4 ȸٗ= +9=>  u"̓K3~?˝"(e_B r{,Ik?~\DWMΑ5 'RY,9$^OJUw=SusRJ)C1FF])"ؖnu!=qK[>?WjC=Ojwͮ Zw_ ݝ+m@nڧ͕ͤl? Q _{8حבE&Ndߩݤ-pT_t gslҮvx9ѝg%f[jհ8Q~6k4)d?$[5_+.n` oPnٔn']k"g-RyYθw<`3Ǒ7m* K5[ % 'dBt8Q+MvKۍ,gYb>Xۇ/F\5m6\P4$\z*QY(ǔ勓('F, 'GzUUwbWK*iJ׳' 7eރb&MFagGÀIY juj|,|/eeoJAl_Xqi Aݫj2aݭ܋y2TMtʩ*X4S@.|ϾWyu,BȒD91DeT&@l_-[Nrܙ rFQɻEx]{y0v=%ɼE0v]}[!W.R%&Cg[vȂz.z 9_FVAf j'܊ϭ(y{2D6.${|UAN0Gw,,#ĻƆƦLѓI863/?9_Z(G)Ey \ByEfQQIN͝wi|vA~v4YI} {9C^AfܝNNd&WA!N>&[{..*M0'Ja-X''|S) Q~]=4`SWNwVlF/ nW꒜67j(*W'm ռ`K푛iyMV#mr$,-$7E"Z@6E{X9\$ig>{hdQM/i׫VjFg Ed?lK8L=L*yEuL؋bfSׇS&2rLIYB]RtAl7BY4wڟo4yN;?egz}c`,V,:~qm ٝ;,TpJARC)KrtN(,? Pu" f" Eb7³l*l 8Dl}\#uP rq oztIw㖓wlWaD^(QY>G n E8N;ډIY:!Q֛D) 2+ w&ƨ)%j|T!Qigb_t!?\J6ɾ.du2vExJan",ke>2Cߛ(}p_ݤM}&:_ RYFU[^::riB&:ʣabS8=m76DlyT#HkB,QE7B!_5A#ݳU%}9tK!oxWD J30<'jah^Td嘒 >ek֧p?NE_07$7XfX0?TaI$썮ڄ- U=;V~32crB.KNWc<#BIF%m|sRPt*m4aK 0SYnj6eO^*♶ǂ%{ƺڱq ΄Up:ST]YAQYUrܜ˞-t '׫vɈrO8"M8gYf&,CJYPG[Ǫ7E)-M` 5,tǯ[7{Ů@(i~@-6}PF) ^){B ˎgbV|’Jm'/s2vIw,wk7^QP; ܫ5 袺/nX'E.ͻ ~GB#z%{+$ԫ+j;2sy 'u1-q(-ȣD)KEd"ˮR%, BFӽ.(Gjgo Gb'Yl{Pq^t&I=[v@9,ee1U7w\>0VY pwkTQRz>_b0NAUzځ׫,,'(VK%cV' 2VA),%n Eg ȩ~pĶr=ro!\ oQY0NJ%jRY.90'E&ŵf:yq d0  c9T0~*&/Tv\*I:D޿b%4A2'!^uOWKyP[#Vuoɾ.ǜL/.3 Yb9RDבWB*Kh@Y[RTRLR#5EoAoP }|8r)#|Now gcI2wk7Q59+nLU!AUw}A^,q-<(jogb6e'SªJc^ 8V^-\?/Ww̕.GRc%9nF&rAͶTD֧5;?Q(y7,~,/ Yīόz׽qopDP))˓w'oǓU#s? 6xY\^YQ"ar DZ'UsA8S^]UޥOY#w[e-mm5qK"1QR>A=/p`YҝsuPr60,Q[m{+j̭$B#g4쓝~ڙZ+D-p8+zl!`qg2USpӏw;&;{dG+fn%'|s,^,E\P魸5Ie)$N|S5b]No +*MT< ZŶY ñn~x08[(~p8aLS "v5<(#T?e -r9Ť<]<)':~><߫DRA]̮*ռ:HI]MVӑM0s.ovx jd|*yٓZB0NeGז= `8i=δ.*lQm"+G*-z"j;F8n&j{*07~1nI '~)W2Frl[fh^Td嘒<` BZ~%h=?(WO򣿃xXvBe1 wn7}o/Q0 Ի[Lnp\Ӡn=98MhKYTJL4cW%|6,;ߓCRԿ7eYYW|ӄE,Aoa{Wv;w F 𔼜wy]je;܉jd|b#2 ˋ skzrA=Ͻ9e|!Pt#,S)m>@{ef= "N0Q#[W> :AHh(UokYo8O׋90 c_%7OJzwwD] b%d|^ƥoB"?n9aܙ NA; K]o{΋7;qQt5sۖGe=Vn- ߫8ۑn;/'wwlszq ë '5z,fS IeyTmj{/IU SV\N2L,Z#;wbK;ܞ2MCf;m>xmg2*&$jU৕ʾw{'ߘx%{6s.ֻ *Mg;f\J'<@% knč܋N8͋ʂL;SRH泟MY2 L4wf{d]fOn|gޚ00Yьkdh^Td嘒`NFYc.( "\Ɲ^9Yn]%`6Uʚ=O͸F)^@9,1QS?愲A*X홽,œi[%s'+ie͸FEeAP))KBMYB~oklœ h&#)^@9,6evƝ^9Yl7L~`Ldz;?炲@-.|n/clœ h&͋ʂeAA{QV/ƙ,?4sb``````|8=yY`-3HY =򒂂ₜ =TAA ZUQZ֢hNNA:j"'#AAiR^RXV\0?A Hiihmu4*%*  CwWGvz^?`-u"!AA 71Z|nkS*  IʇxZ=i, L'Ibrk*PYAfeP{Xlʂ  RlxTAAf]qAe>ȟiilhiFAi,3WZX]''  ζF/L3\ aJ%?000000fyicSaZlk]ƪ ƬVq/G}}} 5UT1O#?hGenTUNc˗Q 7P1v.BUyWe_UXSCV88R*j+_G03RQY%n cǗ1 H L_U )@V `0}ZN֨g&ʢ {U%Nʊ x|:>*^.}Ħc=3iBlTTdGn}zVVrR:Ys+48A&rtSIIa}ssX^ݫ7$vF$bV('I"-͍0]P?cѨ \ T{;˔EQF8LhGk%e>ە(?O~|ҳ2`^GC?}4 (d^H&]}۬4EGiA8y8qFLO ~ 3j 704UBA L0QN<]ѐA*RB.JdbT,d]ʢ"'|R/yZv;4fY?2.AB" ʋs#<+ [oz!4/%^l˦(%[ihIY߼ެ,Cs%:::;;;-, QBhr♔)I i,:&\&HE>j٥,ʎ𝄣ctN43v^N kc%hn?(M3D/{uiy mg!ae*S 9>7)+s׎_ PhRsjO8ov7Natt%),cVnKLUy۱G9'2(̼}DžCx͛3Jn;30{2qǝ:i5a2q(E< &wL7J^RKg?~2^ORT쏚[AR:ea nAdvrѐxl?wYJ!UVe2X":e&1uE|;ttHNh |N3SKt&ΦQ%Z#¤~YR~YqV`Why 35W$:RYn1&PܬtJYh%f^!),GhU?}T_p!mRM&t,[o }8@)5 81v\/ihN{ρUY[3E5UũdOda 3(,?=S;Q{ ?H+;6cIͽ7#@t1Sl`p 0fBB;Q/-qwvW!i$΍g쮶̜93uGD7ZQ U&os@7eSk!a4/| ?@d ,.,bXxx0#[%"k m;Cy{!!!!!mI G7H0_`XH(G~`le!{:FP; gYLXg:F.alwͼP7.4oaA.tS<~ow(|w/,;4 IRX;m0?H^_^pO/UyoC^y:e&F^e[[\IB`qsW,φ2[Of3Z`g0D+h/@T[sxG)gz|,毆te1ԟd'"a80u,[lAd!<{0_?(5iqU?4D  )vwy  ۾0׮oCdvpax؎ß7!o?.-.fJ [ܝQg3Y ~~_kYw<nׇ;U n#PZ_5 2f0-ig[Zվ~'1@XLh|(՛?;2a\H(O,?ZYPȢըrlWv&[Y00z%ت&a@2o'rHp |KLCqmn׌LގuiXӝvPFb4rZ["  YbVOy 3 ^%$̘m5EȲD3R3x;G/z_3ME錖SID:F/3^,{G(&hr"T/h fE g$/LהR!ٴĈiFlӺ, זoteĿa\C$ 'je!Hˆ,t-"?ȢʦtܟM^ō&)G>Q> +c@R S_ou I, ^5 |0v50rI$ޖڦq3ښ~F$nի[ž<g߮jWpN⊁,eL]o"tN={N7;awCuˬ8|JTԙ2eт?qх]bQ_Gs 1p{e劗!z#`gtl'le="^m|n ;=⾎]ͮ,7 c ȫ!!!!!iCc D i}kj Yv D,\`syOďW[d~gyN'1/u`A5^̡[x&K1B{iq 8gD~A9zXXB}\=RB]qkAWt_.S'z=&ȆrwR ov@Mv~wx1Eܯ(&eRIfDH O_^#'@;mҹ6/ ưC^EOv4#7>^9x-LEWixkͦINplq꥞0G*Ip8U]kbS(O3٬cHPQ+˧Bjd վbޚB䥖T_sby k/dE$5#!!!!}&&Ƣ'&!Z q{ȆO,oߘƲCY>^5+tSʢ#S9 LJГ= $(dQ!6t, !,rc!'Ȱ؀SԂ([%)!!!!!!]RHG}551LԮޞNLjjE9/$$$$$/UiloJM BY&HS}MHHHHHHH5O5c(B$$$$$$3 ,HHHHHHHY !!!!!!!dABBBBBBBȂ ! B$$$$$$$,HHHHHHHY !!!!!!!dAȂ嫓jaFR(#J $$A宇φ>g/[~XWbnݬx,_>;EY ygdžxwzgΊx8A>I3 =5SA9-nخɍ+ב)7ɼlb!hA@O i۟^Ja*D5mO+ZC$`\S~~G^!YF Αl!N?,!CL̫OY[9FL*Y_OrA\eT MiYў@%x"[q+p|oEA,ɷ;VGs|rkGG%{g藞l{BL! K2q'oHՂMIl*ėY'.Y'AȂB$?[$j0tmpkSՌ%w*;攟N[ D426"6޿A)e S %46pB !L*pE]aOp%A֒ynUʎjF n8`Gprr! ^d! B Y0G'E;QMVkYU)EWjn|A;_1CkdLʽIql_O=Ό raP'{Dd?k^5lO|/=*xM9y0D.xMdr/ompy8a)dI(L{݁tmYA0cn4/Ϡm-N p!,h̑]zdʼn!lE]Jt^BO~cTuG-jVWgE9rMSWWEI,"-Mj]y"zX|-&L/U^i2Q8@cꅶ;ID:3=d>xn^ɔ9b累btQ ә 钩wQɨt%̝JiPSE5pkuGf F_ !L-iWz*Γ-N*[H5c[7QG3U 5vIRD{h=?g(@cKD;zF>:P9-,y蚑d'ƅ5}1Ƃ e.wo혟uQ"v'^xIK(ꐪ/5)`䵀w\eoAfOG"Mo e8}PM=ϊ8."DaV6_l1;ApDO3|GR wt½M]? D֯RE?ɢlfB'i1MW1l`+L *q+$:h2W=^~kHC6f#"ғ勒V ESFxH],? ;益0 iߕOaSy~oJsgR/"fjGrFƲhƋHH)Ԛb `{D,KL&ۛnjV`W 氍=N;s@qpvpJzE#BqYĜqr ofSCj?FLX.iT>nxtlHP@4#iYBQW41.wtImei QłևÞIY{5 $G)0Bkba[E3`bD{7`ǗdžzuDȢjM`MS^h]Kv=tfB+t܃"ܶOLeS_KXϫ8īG0&vp$+=x "v1$\Nҽ(΅Y̞j6toB '5v2wk#wOr.c<]!Dɹ]8 |δB2YɏxSS.Y| fZt\)r!PQ! z`X!⋇GE#0rQ&Y|> pJpQ^W"AABZʢ/nG)UcGd-@yMd yua5JX)Vr`SfB}RݬkDGѴ\$1@|k& Q%?)1Dl1kfj#rbn*p- 9ê}l)Ե"t%0@m$Ȣ]| Pyi(uϗ_SRs_adcPlA=Q8B]|N\ gƫAcSjJf@=o3@E$`n'gtY.:v1E 8el$M;uKT/zd0NJ]-f簭WFėCgWxHþ|yElT+-vQ=NYAGVz$rظC01"l،ø.,n>V'J}!vJl!9c,g(mRco,v> +-CkZ-S"hga0;}HDH>Z145Ǖ SI,E`}-2d5lXm#Yªn2xA-d㭤/#ptщx{AjvWL>asanΒs6-]w Ykd ?L6!TEX}"d9HsTyGBl8dm~63Mf`ƲX߂|T+d-vEi LǸuʫxBmA%Q"eڈ d oYCڢɅYlpb"&>s1(\*:f;m" ͽzDoCdHYMP;#2/kUܶZGӞl,gn]io1S;O9faĵmFKba5Qb[.bN#G\i]Rw$%'2G܃@X[6Ja%k*w1΍,HGGL}.Ȣ_ms&K}!686/:U(9?,D1 :vez{-D_ch&Vx1Ct)@,OIc$'Vr 5f^3CXy%gcHZ 713Ӻc8dwL̴Q/2Л͢Dtٶl,V)`sဥp߂|԰c8hG34:&sݾ΀[29=5krbpV XR<̎W, |EYJf 3)s ,iv Q͙#B}[qsiCAtq0A#(N2!Vk xX*/AxaԌhu:r`<82Yqn'WP3pBMjn-9_'򆀜HḄkOMut +K>.Jݲ@r3r5Grj0}IJza&5beR% cQm^̡{Fw`Fw%਑jmɳho'JX;,l0JXmA*%;=U&I)`Y?D;8sCAs hÌi4!,ޱ1|LG՚)a/nbGk;J/3ïTMjY}GEVEwYY4\r7GUS38;X$8XD3 ɸ V᣺;Rk/Sgm ]|s^8hVcl0hw$BX/Gڽir; 498|RزbP͵@+4:rɞ$OBm6! ]g\l[(<4=(Z{Pz-t޽0H (42MYx|^z,vfqGVjҖ dA RbyUFf9Ι"Zl 8˽Oa@:3RMb()|Ȣ[&vw78G>k !ܲٹ)tV3/j!d9 Z4\gS"!dAȢȊP]=>QֵُL`/FKB1Yθ7}ȎeJ$,Y !!!!!!!dAB'AiͤEt uׯ v>evijjńkܪG;Kkc3t 59yZVeε?{Tx<ngރ?;++YN),l.nsQhAL8$- ѵso1A5ni5OR: ͊bDZJ,Zx0$m:yiL abSMʅ) (]GÅW7 |mV)B\vMn\NU.>KJBSJx%*_,IY.g_mud,Knac5UPmI;A~Q%㻺 Y]KG{6Iڃf+Ϸqr%Fxň`~$1r]8_z! ZL* d7F۶\M+K{qS7QWowHdGnfYcE>_[+w4>**j ֓Tc<n=n񻚫ˮe?SAkGG%⾎ڢxE": N5%!DZ @>rjȢBm^bnJB|pnNu؟r,{3/Y~_mQQe\=4w頶aPμ@waXU¶eP:rBr;|bF5i)[\~ HB|eA @%/C4/x¨!Elұ{`yq=EAym <Ύt$ %̐E+m,} [ մ@~EpD||j^kpN*F-1dWM=ϊy2K2²|ldAŴ嗂:gTSSM͞Ppku!ܴ9C~NԊ92̒󴫼djK'j9T;b 06,Yے'Y.U@jqSgJ㰤 Ҙ9`2qQ `$cswoQu{DN͘,Xm.%ݝ4̽3ٕ J|hpţfCbuk|O4#W~T+KXblNM,EbXaohǪ~d1B$.ȅtxXNƚ\f3j2bj̋1F_ PINޱ7ZVL^iΊ ppMSWWEI,3 խy6A0"y2W:3o4¼PdZY su.(0,*h9E E,YC^I;$,h,b-qģcC|XC%m^XdQ[{y9kc=,)[A28- {ZEcZ(a Lp~cHڙ7E{ `{΀tTeO*pUS"A= s+;9-z3#Diw=XfsW^pH"zJ|9K(U;߮#ɆNy zKcaZt@] {j Ba$Hcƶ-]0G] s-S,C,^S\oǸNIBSt[@S9>p \kj|e /?2*GZ !ӥ9bQd!MPajlN[ḚvL?Qԧ"?).h'>z+;tKf#7ʼnӼ{\|Uc#m[j{'0&>kg 0SzlL9y*'}(bIfz|F0p3SbY 4DN!:p$[ '<|;ct}W-إr4}UW| A\ |GMNeYCd5U]`9EW؝$1@|~pLa%n FeYfq$)Cd׉ }U=?YlV'3Wф1u'_44"˨ ׺ˢU$ezuls4OB]pռ?1:lu22\ZO,0OB|A&K10Y͉zHu\Phݯ!?xwA.xet YDѹY SrzZ(M:}Cr z}-N.ĄwQCd&|3'#WL>asad7.:B_3GҎ-7>щB؎х $Ȃia>Lp@/Cr+-Z <@$̻ 4gf-t301vGun2`y>K̘O! $Hc|p JS׿dWZy|N1bd9 hA&[ 0ï iqdf}iLAF4.s[kq d6~N&XY~9m!c 4368j6\sc1Օ2JD!~=jlm7(f C,DX]mLva?3j$u ǑLU#+nQfYYa0h^f8`/# dYb9G4LQ!BxJG;I <;]tPhD;Z:yDt"?PЙMKW(̹Yt+`Y.G4' pYN,FhčN-Itϓ'3+}/n'z%CЗC=™>.(Cv~6<(]0iqSeVAe\pI6XL@eF&&ArmYxtr:PpSY[WQ.8d6ǎʈ5pԜ PnMzBxɩ-`k3̤ l tJgYl,K `߳?Y/QQh,o&9=ӳ/"(.2_KuRK´{!xvq dHa{!*j; _x:$dײcH':+X 1Ҫch72^Y\bFݯMC8B5K:'Q~뷣eA` C<6)#33SlJ_4^Tb3N,G>c~8tӖS cu Yf+Όm[BaYiyR<{?*'?YN, 24c<'Gg\sʊ ݢ3/1חnĐ=#tA =\s,KFd/rgh6k$l*3x 9WlBj .hqtNN`q"W%G;ȾvCҪ`Ll4u Vfr!zdJ Ŕf G/Y-Q 9/0[Р!+s0ՖHPPtٙj{{\.TY]Y``ܱnX|O Wi(З?,ŧaئ+'BrqjdO,-C(7b%=YjHdvVD~;`D=[ʙ6PgY4.v6Ƨ'zD)s4M$XbIk^J|"^ScڅjN7kDbu^{: vn7[#'mo(F`eFiMOO1L_E z&KD1uK )=kI[ {+Ib{rY#`P.=|ć\A+.mevgŁ)P7(>#j+1s U!0 ivd MNNo],>qaݟQY_w/Ƿ`*'ʂL%/yAag h+:+e{.1X~_əy7|ORU3}I%=Y+On %Tg,Z"ZN%gkdѭϾ/_=9$N ?[&.|;AYJT"w5UC*qBuX 5 {D=,j:{bda< O.Fc6PYlS#IfnXGB,ޱ1ZG՚t,TӍ8_r1_*wb俄1 (4 z",f͍ݿæ~L2cyhZ?^Rsn$ydG}-zqctvJ"f9/CuK|4CľI='`ޝ0֬+/sҀ_jʼ@t]VvBKA mɳho'jMIhO95Nvk-Bi;J/ R%.|~9|V% EX~M̽M,XTg1.NAe,VM)/PӍISj`oI~Ɖ qft&w$4aQ $s&Pٞ[-:/0Pe75C4}ɉ$;%K9t$qmX[֚BXC&'J k/ƶ֑S )PLN p&\*^fbڢq#6Q5KM66%28i3'o'sFS;^䏘q2t$$$$$,Ud:5;$f(Du d>]"߿g8DOguoLpc+5GE5C=eRb4fQdBIna] R|Cp B,h#!!!!!d ;Ꭶ.)@-5dxZ5"2ZwtGf1D{}L!Btw4RkĐsdK5O1|  !!!!!dl4C/0"} 3;OV'DESj;FiYyQL3SNvel,N,xq'5)F6^V]66'9/k#!!!!!dE) `ad]Ѫ繝j n;ljagէBxdK`Qߚ*l-h *VCI>9L¢!HfiX IN&̄Vok-Id*ⁱ-^¤MЂC@ޙRNoNNߎ4B{}-1~i#\6)33lZou]2v,9sLd.v2d G EZ sKБ|~Ȳ½d$5;}lo0-—M .QuIIȧAGqDcԪ)9hW9TI60cDC~j5+%0}MwBd!Qvd&^xΕ źpd%[P7&Ǒ#!!!!!dDz|[+j@|DȦ dr!;9Vr˚4B,aiR3\4%Ccl dABBBBBBBȂ ! B,HHHHHHHY !!!!!!!dABBBBBBBȂ fJ)W)dH_JNF&LY:,_4*Ųte#CMY:,_H WM˘^g1/C07a6om}Wkr!dBVʹWW/qx]"CWkr!dBR`@PEFEn6}29}&YB/ Y 8K`~ȂL:}&V! P@&LY dA%mYІLY|Uc=d}FS. D j\=#M YB#d$bMo6n~ `efM/looο?fAңͯtuX?#ovnƨl]:A=X|6>;?(D:BQ϶~&^"NQس3IGxk~v; +$ǯ$Eٞ1b+:әB|ea4Jˁse3_A";xLrg+u$pf$3gK)|iJ ;w]YedfC(["P/k}ܮI#lߪ_}A@6$ײ_yeCvedJp#便wM.-M==gA:u!;p†%ZnPμςwaRF ܝH+ܽ-#`iѭ9ߒ(̆_Mp.V:)krŖ#~-yNf][?mz9vI]ڶ-jo+K;6u'}҃^|L5\o'i~hYv/P~@ AEF5J9U`B|a7yU>O0NɏxSS.7"g~ʮ }Y`H_VŻ\O~uڰ,[6/ 9c۝sc`f4N\7{֍I8קY@@&~̜xgqQ?࿪_#z9|k'G7F4dp+mZ*9S#%Z_+.378$$[z%ªӯ9<1AOhg˖t}bTS!^(@3)TpIz-{EKjb'n+ Y{; IWFF/9xYbZy:|[,]a;8=B ˋ꧔JdQȢ]|b« 3f)e ?b՝9˝o>[to|p^~kKdMO7OJ']xWҏciׅ狖]>eO巽:_^wΣ]?F߯<=Yk*FYt꽍AM6f\3~ f vB|p VtcY´N~Kpמo܊ߠ_0{?"V0jB&ژLkADω\Y|j~C@Gb/YU"K@qQ^Fd%1@XꁯWpc\1(GՇ;Y`W ocas. y0gw e-F>j"P㛹3.Uϭom:7E9^/kdF4o= %_8c|2uw40P,:d_eW|QֿjIS&Wb—,nߪV0~yV;?~ PQ%/ЇYnE}c B,ğzDo%C2oGܾ+Z| __SiGMsx*=ly_VbEƿMed闟wXw/᧫Slu C,Pͽz~lDX5d!0YY>Ȼ/;~SJ_u?~rOz֛n:vc[,f3ibQ`te[mdQOOKk+ ,d_xỨᶵ}ZQЗ,ZiU0`&n:f+3sl)/l7"#PEM?*zU4[^w\;S?Q7a_uBL-lY3ˏT3|'^確FuX'#Vr?~~{5d[II3vpr{5W1 y6-{~ϸ& ^G|8ًxK 񛞀ҹ7AVw3 ,s`. xޔ(-T~OEfbYu }]3mn0# ܧY~+}bgmh|zr*M^Mp$> _ VCّ˾׭A#=/IU_2m+,);}]0ne=HΞ??G)Ds++§|8z;uuI#>O7GюL]j>|Mj׎,D`'kJD/FԳȢlcjxU9匡o+$|%z?lC#jM,3:XCckY(`_oȲ7PrI:zDd=쑅P] O*(C4laD}pGCng,-}%>Q#f:䵮U3(+| |S Y\~*9̰?;? 9Y~Y>Ae+GeeF/1}!nb,A3ߜ!N|4:匡wĀG "-ۜ텶3<0TcaR+؁&8n^ҳ*Զ ߹JkWjYKNr~DM';BF!`?ޒLm_ٰ:Xwb;tm:1m(~ C&Y:ovC 82:1m(~ C&:!7{ѴyduY4:d_g,!CcuYΌJyOG22/rSe=]m"CWkr!dB3eYR.ۃyLKv(d{m/77޾yLm_!CV pLn Ũe-}{c۷䐾fCV!%0޿GD䐐!CV l ! B,HHHHHHHY dABBBBBBBȂ !˗*5*\!!!!!!!rFkFX.:ۚ_֢ΐz:[Lh_~}u 8t& ^M[h/_jj}uoml_M&o~&Of$fl_}} 1؀ .܍+6bzQ"̌DW|͜93Vďr(/~J!~qĴ PEI.@Y@Y @Y@Y>}_g,gOzgֱ6ؖhX/N{p/m`r$>8IT}K( (UJ #P@|{+hթWS_%cU+Ye\wbɺxmGȷC݉'E$@@@@}E.tEְ}0Qnܰjzr$ BaE^Yf oP([^aVgl%@;9Qej+l\ @YBI ' /."Nv͆Wl5/Y,v7{?yT rt$ߎAw \ @Y~e tjiKi|BΗD. CRj]̚-eU}S`jFM{KaFS5Ɖ> ŹOT2Z4 ۝ gw?N r#f̋"1tf:(v[Glv͵60PCYkV5Eկ/bA,`TW얠|g0j!v^h6-UeՔej t| ៏cZ\_7[Bb%SM{0@4N,ӊPj=\ @Y~e54)I"`fr9:Seyo,lؐ"K%bea UlԩGWP]?AhXAYntk]AuVo%vyUӘr7VY@% +)Hm/{cfv+g>,feUf'p{.,?__+ګ#Yü4vgRpPPjSiy75vsZehp|Է.=xğl'eZ=45_9Bdn* -Albe{!eeb֗fxCԟmD,?SqkěڦڴNew|.ʲ#^ێ sC}ZYfgL鑞>1t,j op~ev^e#; ؼv2[lcf?V33ș|@5hLݱnDdEfDlS[_?Ag]_ @@@@7"2b;U57]t*1m#_ A@@@lHeaz8[{hZWV,{! @Y@Y6bb=k79Эwl.,,IYҒHx1pœLIo7?b(¼,,s-LKˤ3S_QȤYiCc,s IIQ~>P𣐖P=/r)L&5ckJ@P~@YeePP@Y@Ye`=RRrF WPkmjlm M >$ኰ6[QoHanf@/zxJlo+23J{ksOxlttffM񱱞&|K֨_Ԍ$Io7c7*35ip@۷F{;[׺EÃaK>LYfؿs̜O(,(ˏĀK܎6-6 Ys3Iف`@MVCfHz{@s! #2iQ^j?ma⢅EG/zÃSc9x?104n3M9&314M3٥X/Z )2PQq4eY]]nu˿ңCcm5j2 ŷP@@%'L_p_%/}˯~EϸE_3FD̘?&Y0lD41/[e)/?#K&~fbYۋ'+&k+"hX_ՔJ(X^Otɕ/z}{LTS+K,A ʄe;7aZhbll 3g SP)(]=5Xбa|AM@Y 6*X˘cywaY2ٮꘚS2TX؉‚ sL (l1zMFY_!@X^ϰe1W6G0I_?6GU|AM@YLϞfs܌k*Սmi/FƦF bj2:#yɫؔf3RT&)C)ˌAx|?2EubVgl%@~8wསљ@YLml,s{5rGVE2E")dSL=ъ/31vQ#;\& e.Zb3>3ق|hz^^ ȡȵz%jyq,6_,EL)olf r>ޭ.2CJx'Jg:eVnzx}VL4G#wgrvesYk@Y~e)-.Xl,UhɳC}> }s/npn k슋.z};ecŪ)NcHG:1xd/=AOʂej_Q5E%"~^ڛ#cԟwQ~aeMyRG+ I~Wktƾ{Gt1r%MLSN &̕w^Suc-x1U^]]Vxnrh֛h1<(\Sgo8>|822٪̴mU?ayԊl'e7ՂW83r:*VZ$t&wYVY ~2&2==&wG[Ju7]m bw:=f`ZWv\bme;ٝ- cӺpf$ooc6^Эb8зW<1$dݸ8}AhwD+bp&EgW^( 1FA ho rQo>#{̡ۧ3C9hR#'=xYaa}TxgalCu9e b=> ɗCiz (A.|z"n7,4/>WT~J\ZE#72XTS͏7n3cM7+WE*~|&悈0yolimC}ŻKδzQV]Sxz:+4QK0ՠ\0֋vD@ evJQUTV\u{ asf?njj* NPsɖؾnnMkSًL<)yw-^fE8Z6ueg$x^J*Rʪڹd j*mZRtr;Nlh 3ZfJ\Ưlhim(}u 2У[+Kq{ $]nQF[gi04Řs]Y])m?-w&*gtBAYEExǝFH «z?SXWU3͔̭FZH$,7 :BR,ii{ ,)0sHF0B{_{^EWjʼHڇg+t8_CA]rDoO( he)ղF^" OS͌ti}5V)C+X1Ku [|?QY tu=+?mrjMٝ(^;f Z\RP"*M'vUY\ZEgDcu=d>ϯH`b+(K1Gz.kAʫrI.k"RV]tB>ZgJbnټ/[m]r7?;*e*A$фp{9`)?HtŇņ1kJf;ft7J;If)jNF<8ˇ8wbJeYTqv%9cn^:dm^2 7~D??#k=d^[mD8,N-o)@PnXrV,j%Դ=Fg$]Qpֿ̎gϨp ͑R+4 ijb!ڦOz^LYE Un?nZ:4 1.%(عxL8Kщ|/)I.bkxðaN4ff.wfubavزnKk6Cbؓ ҙWCiЦE]JLw+mUsŢfxiWXN߈vxZY%a7DCTf\sJ *ˬᶉ ~Uk`-j4Xp;n/Ħ_NU~|ce)b&Pq)*KKU!Ub*!XOWr,Y~+sgKij_F\вbڏ( GF! %Ɂt|t&^tZiT.8./Qܬ4\N'.{ǔŴ$cQUE$ٝ,Qw]VU%R1 gC.gZ;kRN9"gbr(x(_fd/\imu,b=VW}IƃeX0(>#, אjjYյAQr#5\|64cnFyrב>ASKEח9Z"_,6cqq},SWF\"9ND/vz )ܳ/UWnog,**d}S[ ed]{◠t| hM3ּ~?W7fm$fhVo%vyUӘrUe~Fykf̴, QD~+ʹ1}c%v'JWE9GϰjY3}q""QBZ+(i}_|-ڎ'ވNgCvoRm0w4L2],kxZSoiU%'CgX ۉ}K?% _Gx-e54)0,F8"'ܣx^jҺ涖Օ' n?yĝ*r, UK‰]8kV'(GX=fˋWiy75UUDu>7 #>QYp D7-4Gyq|v0sd|DY|bדeCxL-ш~}vA]G%m+z9[̫6kٓ"_x]E=&+ ;Q˛*Iu2|te%'3uz.2cn=Ӥ]8;/1x|ӿ%K">lWʷ4boqy9 ;fd76ԋ*<_.\kѿތ1p8[P~|-PEE*7%!67dB5Șa,7r*B?/C]?Hu}''E&_(,+JW7BH+~ȹ %s2QAr9: ݷUCɑ('LXQ邜.T)*>8_&k%̌!-_?>wHYjN>b_'*Aןbc"M)i!elP@|+ EY6]h՗!ç\prCԵמ1%GR#>$xϕf쌱*Kkʓ.m&PdKYfƻ3T6; B8>4\[oԴuvE\AYCYoY u榋~y_C >+]WZ_߭on|E zu,Kjk<_-E\b:b(]0ŭ\v>Ka1:Ek杣{ر)..eh|EYz6Twv`sKgRu#5owᰛص;\B^E+)ZRWωو[f5ۿP Iy3?~V4s`oY:"rry]cK(᠍EY(i{pi4;Wxs%YBAveurDv^w3vuosly)JF 1^ RYCWʊG~szD:9;;2~uvVKoGb]wrӎ6؅Nw8co9n'>GG=wnaM:l鞲zvT1ӓMzx^0?yؾY1Sqdfɗ yj0vyM37 }s [&]᫦?UY=dj9fffFqb~1m&Џo,i[VI'ME+tق?wKK' [./S!K.J r?>>[fee؈SStqXNk!44/`40 G+Ѡᆐ\֚#A˙fxU q0bDJr5l7k!2jGHeo|ש\ Grf}gb:vjt/ڮv76;/lYmb=%][V _-V*m+~=.ӴqmO}_%p&}vZ;wX |QƎe_\0޹dkq8[P²;.)QƯueOT`G6,,,""ml.Q$3ng~6{c[?ul_Z?|i'a5i:"nJ90Н]X6.ʒyJ(.M3oߖײ_l?nK*/?+?ۢo?6Jom1PSRp}ߛLozoEEƎ ,E,Bo"q8[PCYԯ,Md-S6`.88Oӷ L>)o_MR4Ug]*WkT_?XGclb}o,_.򥟋 <~ǫl eyܲҝ(مZTYU)άHvDG}Zi Uō~źݹmE:k^ FedقʒPbl[AGW!l;R)z.2ʂB.LM+?iyNmW~zo,i Akit)ppcټ[Vs\ Vk/qf*^QdxYu(O3WOebGeWXچ֗iؔLm~Γi׈@Y~ kKs’͜mARKߨj德4`;>6V\PsZZ)/ɔvC pY-+s'}I:Cl! oް+@iMx-t^Ym故Pm5C_eʤb',ulltn|.t[a;֐2,e4Ϊyg:5Io^> 񯞥&'t5Yܣ$EY "-9(/{_21>-knYܾ}[> /jmjhmi&9.a݊ezYN5w,|5t<}nY?> ŀR5Ԋ*kqV_Y ( ,,( ( ,( ,,( ( ,,( ( _,B!qZY,ch5j04 U֢,#à,l0eekԽ)o;4pRe|obYkYr)(_;q(o*fB# vS}_qg4NMAYeEv1,t,99bHߢ+66yM @YbbB QzVReR鷆UY\j ^t_s e7C<98x\NW0cP_?eψ=z'ulښݡCy9-WⵤB-ZʨkC'y֮Ë-9<#w2ZT̆!l[xXޖy#ԓKqrB,\YoZQ*BeY,x -Xsp\=xlsPn0[y1/yWkJVvrvhYhj0MPA)a('V!{Mj#ci: *mim)lBCE V)AHiɥ#FV gHJGQ:_ӐF[&A^z;9?Dwy!I=}j۵Jm^o0PdO>znpj7v'RkujRQv٤_l@_9T)KH FM d*}Ne +( ,E}Y!CL[FTe3eԾ, 'JIinpZ4jA?sZߡuA Wޣbԉ_YM zºܢEj>SgmWʏ~IfKՕMˠ/ L܋26jkYjVR^[-JIŖ“&IQYi &3;A;PFJ-)}-Ҍ~, (x~!؅iԭ54N+N^ 稄O<"tA(7+KB/,k+K$cKrRƽ~ \l,tQ=VRQ^xZZ\ceC`7Ӧ֯7T\BjL>;R2d(9>`t<ٲnWN*L&eg' xQ¥ CL\IJSAI $fgNYk;`i4)EU¿gЃNֆ!j80;n.ބlN{FhJҗMv/%5l|Yfm ,h k_v^YLt%B[XAYz:r3޼|ؠiߛLZ&ylQ~GYT*rU\|B.$u<-3݃νMg}\vˉu'$It ӱ|z,ǬF] ;zJ;zeyPA/8{~֨敥[XW"6W/d4Je#?UIoW_πwoh@26 l8JyAngLZme6* X a6ӒL&P`*"  ,( ( (]_c b-( ( (g?M뒲V!_(]YTuOx8l5ϑ[-reQsN6[+"Z{#y6hK0_%H·?*(5N LuG֝\:s&PʦgAAx !V^arjAQyh )08_:āE ʲB]gߵ-*Ii){ {U+ӯ,wZ΂')pFrCQ&]EviV& K :SH&aہfʪ,5mbܳQ(a=r:_&VTMO)'! u=d>ϯH`bդĶlUOlV`2cϺr`g@D|<;k6'F)1SҘ=buϚu5OOzz)O-O,å?CPuˢ˿h+/ YW0v!\C.<ɬ(J,/QNrz"YVe1{'4sd.cIZ#E0xꃜE rreUyݫg+j G-.ڦOz^m?nIL'ӶP fa%7ℤ>:bIѓ}xբ{OikxƔd"Jeʢmp>uzAyEEyac.^fDG|OFTs7|Aif JqQe+.xTj`RqkěڦڴNewdFeԈɩ@~FƢ#Ҽpگuğ d&:x9vD@YawJߣch˟E8sR'ӏ&$ra_wY;nA}l=_[.=( (AY⻵:RϢ7Cub2_(,/JAN^n>HWJrҊF} G d\'톢|b;l** o’I=,5mbZ,n^嗗_ e2?즃*OO8'2rV ,3+v{Dķͳfc{b>љ N0( {,Z7,R!rD{_a\AY՗w! )˅%A+˩pyoP2k o )0HW\do^[MZbv&n^̲3l0/K4å?Ïfm -:E1ib!,rRX- WT~39E z]|QT^*j7BW+ }s_/ ӳ O|.) W9RP1w~BFUSŝvg@۹|ܨYYY(CZjaʼnC`e{w z֝7>@>ҥ]2ȹi'z1oڕ*x)ˆ1ʲщmƶVnoee -Mmٷnʥeám}Aڮ4ګK%-9[ a6AY Z)/ɔvB!e&@YNwd%eR,uiW2iVZ@(( 0P$E$EY~NҒ%_\jĄLL|q ( ? ,( ( ,,( ( ,k@uRFPFYKz޼{ڝW'KFp(_,")PPj^(qwIo&&yOUK p(P/C=9X~A{z;&=_T p&ԕ7I 0w=$|d,PYܿ3 ,5'a'4:CVY=TMmwuYYYQ0ӳs2_dHN}~WRpeـѽOQl5e1HyM/--I||nﭶ';_^[[UY|+B.#ϩ,zY ) _lP})ʂ,@|)lKWpG)(߇K~J) oHNz +( Hi}NX0iT?8V8z*bZ7HE}.LdBnHz w?Amy䍸Jldwv= B6&ȑK9xiWS)zr*Ѓ{ؤ5PgzdL!gpB 8UuilWLzmeѴ?2>7k 5uœ'l).b-yVTT[WЬ(? ]X/ϯriRGVބ= LmsجrAqʭ`.ʖbz8DՂ6AkStf E|6<,,~de弍+/ W迩]pDH7Vr9RZp̎֯bk~b)M1FzD ^;EYt-w#;j4_^Pኜ/,Pz hP_w8[u5yN^zyܮU[a(y=hZ!R榮vFBs47ݐcde tR\YՊEu$5=7b 㠃Cn!P!+:j99_ۆ>Gp 9]V dl}iٵeG9,,CY߼e1d4u|-Dgep닇s-!:!vr/ 2eYgV p_7 qp|Veϰ OsYv$؅K}ҫle${Ŏ׵<؍v?l0s<`Bee?~/ +ӗE'I\MŜ(sA=!Ppix?n+:zg"38P8_Ru i@Y@Y$}d6Yןld!ӯ k[[O,bԉ/\>\p=;hq+*rp&;%ru)%wBar*ZsYeaB).y{;6 *C|w7!!=]'Qp&4Sww8'7,^ӤeE-PAVYWTi®U@YN,jKoqÑ7M:$,<|>evt`Ov&9-xp^f>KYFrb +TFn7@Y@Y&d\P.v?]u}f( ֚Io¸NL O>2bha_+ڶ>󥯾߼XyFY]o'&\ې'xIum'w|8^ 㟶G1ukPI^f_S{ 0uZST0Ty9V1DEG;:}o (XkBv#wwccXY &AY@Yd%;~nivFi^ߝrxfO;#NP\fA~y\)uECzq:B$$&f .Bvnv/S~(4\K*U p,,e k[eūdo{%e/tײW4_vO71ɯTŖE_#;Dž64Oצ'vymT$e[m2ܿȏ)K犙q=׺,~//Ti~ndxbžq멉3'zx⾑N0֯T#-c%s ~9_t55~ q"Nq5 k\aw(] 2>*LvƷdW3\B< t4 [_]9O:C2T7;=qBYu*ʲ»{AkkϮ",h4/okӳ=:ʹfGܾơ{YWOSbkD>Y)j*tˈckw{bG>Ků\1,L ygp"yl(ꁽ;l\_WϊĒL}x t*DžX<Hq_vmbJIQY.ž7}€^ET4~k2oOeXYjwުh;mf; ʧf(;UMZ3T @'>*j󓞇ﻘ|ok(O{rUTMC#U P9 5QOVxAO5qJӭv11rm*c' \\Y\Feۥ{жuTPoB_EY֖a/W)汋SN`|nJr}%Ťaa~~`[9{hϜ f~ھZ/~u>\s e!fvv꧵׵P[襍m<^ <*Oad 8L@d/[fA*s$$mLw`LƶIJ X`lJyn1q+/^03{]6qP^-K# ϭM@qM=)exo]A1qԞL}v2aR; -* i$δ{7-bnH,7 X~-&nzSYGv9ݞfwQ],iHybɎy%j/}*r"ϻ̠Zۇ7AKo(Qv&MZuFXicbq?59Cܞ؉3tY*'HkCRFDgTW@oɔ{w`5`(<+Wd'*F*b~ Eݶ7vcu7o7-ΒzT N Zjh+t9CݬQY O+ +wqSճ_qךpR,~qXbL'bUhmr-iO= np1.Y)+GCy"?,g(|?f7?5r3xjL03sֿaWub_,l}[՘Ćp-g,.X$syQVlM[=VO-+tˤ2# ޒ8Ï%I`+bP9Ƀ >"V~k}eUת eIxݝM)􄲘VAM,1*W^9ΞX7eB-MhQk@WsuHoU9KY UW@,Ǖ";p5`1 T yƏz^{s]E' Z.=cruݎl㷷r3nP$;]?jP[QG@o+~%ZkVfB]^`oB4*FcPoKm@FmpIm-}JF\r$UMKiH/,~2#NLWqI0o_V bwa1XXJde3߅/7ZC͉]3GO ɗ>{sȽYJ.kzѩYmz~UBk3xV2}̪7 Lc٪{Mt$ͳy/bȜ9}' Y67ȵͪcK۸3$1[a2uƉS>`iA3"r Z:̑ \­;#75-'g]#. h3G8 7s zS2&1 ]+/pקec OYnd!agurs[rj@\,V6L*g(y3Y'Dolɵg\󦨓ul}bNniG eYg+[/ 'Nt>HX}=6%I&˗*mN`sbJ*(l%ؔq:O=Zc  Gwb"AeAL굳")Y +AI!pKX |=ZY) %Nry ;,-1z KEnQ+v _r*gg)N$ϊ A!/ mw&Wt͉فv8>+nҌ3g'ďq3^ W6 p*+PMƵ,IdJ5, aKkX|@,ԯ;A+p^63WU +y3ʢY,++yܶ6c mt't$=!E2Bx*5Z̕cU>nyn&3ͱ.a5Ȱ0MOQP{,u\P&H'32u:xDŽ\hX/:rf3W~qtQ$WY(=n %$7bpD-3,7d"[U^5H~ǵPz#x}'&2ovz$61C 0,GlV>p.Σ,҉,gr=[gɒyl ']lwA Lܺ̕#ko#u#Ϯ,N\oZ",Uj/OQN ~ߎ8zJY!zd~k?,lp+ޗ6IN V1k33՟@Wu;"83zH:*$ ֛(S'ֹMml'ED۲]‰3=26:0)x?&7B- pwn=wToX g' GcO'V7UGvl{!77<<Ж`0ى+~su2,2j2Ȍpó;;yM) M5-)m)!&Ғ^+GhDKl/{vɦ/L1'5sH|MN^UZ王52r}u(쪖 /W[P( Jq)Ao7y- [ <^=!{ȔʦV9J0}^ Hԣ n{'[]\Ҿܧ9.y5jDž|5ڠYGYˢ}nՖO2C-V@L}N ε,/[jUGƁZ<+mwv~s|1-®ZBeY.kfT(&"N}h_gJ>XNK {'Rgl5Oxn8[(]̍5Ӛ:(2,-U ,[mΩ,ri P=?TGfJvlxu ie0P㠹ݝ,q̗ypC,RY^"u\[P-~kdOH1ow`1XkrcFSMtO1 SWlW?xl'ړopo"Kscޮ./ZȐ!&Ga="\oet@CE))TX]#%C335^WiG+;=kk˿ |=3%Rjǔ9E4QY~ 'ޥq)ܕȏ42okVaX)KCM rPRIW{kS]4%;2tia2E[EYmYm kNuZ5@[sCogXr/.7WFI"AA`q~$a}uR(Zkq*AAXj*;ښA@.   ,     ʂʂ  *  *  ,ߣ,r07248;׃8#CKs2 W_w8g-̔thOEx5ëI$KYF LMlooŨٙ2tcA++HpF|}7_XuH3m*S>+NSK,Scþ~6N;~ӓp  WF6ӥCٱ_^|xIC}ׯe9et~~sPCm}3re{[8tk+ؖ{C*F!k. }|i4+:L:|¼}M-A5V5@&>?fiu-[xC*z?<5^!?Oy%НF0yX ő43q9):}&~AA3)r}g6DV>m ^=Q7!mҋ~bo\Y9Fn~תCm㼖 Z64lgˍCC(X(^lNr|~"6ڵC[ < :u Nu͜9`66RTlO_,\lLn֤_`+30\l:+=q\_"eii{2rOGC|cpWkU3g1 \Q_,rS%!?5Zj2^'ukeY6al=gj?P!r1;5{{?M@ j<e3漃Ѓ}ȇ0x3o󟲟^AYs_x68ۀF ;D> r5!f7*\lCk!a: Or5ais) FS)QFY}XQfnKZjO eJ >̮hMݭb-Ԝm6 *{ 7[3feʽ} mNיZ*ÛT'>Ԣ/e^to&5)v/[ɺ jFN'%.yR!§Q~qW2񕏽)󱩍_\ZC0#/6|\E چwؿ@ZpdGvwVάA-Hw`>:]RݝWK mTnݬOI .hW :h9ȅ~~~J<}9!ۋPl 9~^;oeyx/3_9l+M'L<ݧtHv:LB~!חHY몙Jy{~^ٲR ۡ7%!]fc% 75'#;Đ7b~`lK7;$P ML̯wwVnlykWgcn(s 6]0vwu/*.a M;lXv3nrtI3Sb:gutU7%!k䮨XT$iTI͋i:],[3b򹽷mBgrc6 E  ŋ  WG=MV۹_1K,){b7¹f[ ^-l&袦A`(Tot8s5ڟc2rBg?> >ȡ=x fAݛW6=y=1zј$>VhefRx/;8b>?sڐ DR_vS#UD]Q/ԙz[9[:&Ud9^ jbbCA:|ůE|4g{.,įzMQLM|,&øBZbJ?,)J]#.ys;֯|]5'v C2vz)ؔ8Nn[r٤$ bTv[tQx7հŽpsr#Of>eіf`xC*bw:SU[ݳc@!>tӺ\(r#=toGW>HQE+KMyʨ)2g= 2@vz_3+1wwk;3h;SB8qބ6yA4A5}B/U}:<zvRcElia~{PP!r1;0@(;[ݳdJܖpݔCLTmwK4Mkr+m\/v><&L˱v T0mp7!3v3݌BqV'SPkoO8w\@\o&_x+4ldhk_3 Ge9vTɶKdy.ڳnΩ4(6mHxʒ1)cުW(M(R(X(^l#3dT]Bn(iȻ!+l(KXH) n}/pT h.L).h|{9y/3PMwt_i~T?UU|.=}b(k|*!T/C>җXڶ_xCtڀT? 4&tʙW /)KէS*vA/Ql~Nj\:]gJ7 x-0/ .|pA GL'byI3G2z.+aZ5Q7]B$_nb|h19`3ZGrZ-,k #j:ׅX<nJ(ԬZ?#nX~$eI*r_4 ŋ  WQ+]M,w:ЭP,[u-,_lwcw_>HT07}㢍v3xzpqT_ )>*GNV3##߆so3I79Ī)I+˳0xiN[KG6>NNyK&aSTPP!r1;er@FA& Gӡ;U?4QeD<>,H2D(Kh] b4(` qy[UԌnJ AG&*wAȶ)Q6/h?v/=`zw;;od5΋y9?TC1!f:6?un|hG_BLB<d/lied؄tJVԚD2${ôꝷCC DC }T>S8-ϔh͑ʸ'ͭjw"m4_;eb8+J)Z_N9sO҉-p*6=sIoj&`- )Ai¬7SS ڴl<|y޺h3'='˦tQe)8, =i1ʲ _7~NVB;(Sƨc2] ŋ  WVMLPn%#1^[޼ݼMH,$niV9.8W͉ A KCyLM>γm;$teoKücw5C)lOLT%y$y*`⾊y(b]ݮ902{;Oe{-/ A*9V=f쵓R .r \_"eXVGTAA"l>7? %{)$S\ꩼh iN< 攐{o1w)L*\PVg+;BiKk܆JZtA+_wFކ5>.p'<9: ֝x L lNx&HY{K ӑ ' [=A.HpFe|s: r-􇜞WΥ,?ST;;;2L$͍vtt_YAA~bW^eddTUUWyTAA~TWW6ʂ  ȥS؋),, eyuff&( ,$E,266ʂ  T0VYL(\.geaaBeAA(۷oAY@CFXe?,jZT*xww7*  ?GYrrrjkk@Ct,Elnn...  3%!!!77Uporppr,D B, eIJJohh'3ѣ, B*KKK}}}, eIII)**jjj'3?,*j{{> +++, e(++kii'3?K,j   s%77ぁ!;<<ka=z4:{3|AA'PRR{3CY) .gY^^hnnsqqqNNNzzzJJJbbb||۷o_~īW^b```````V"%(+.147:=@Ct/dK_|r}Ң|z&;;;+++333t Xx8'C,`)rcpwx<^]]]g Xx8CoN o*ˉߜU úzzz@`՝Lt````````/Xy`}_!~B+ k-gtK,krrrbbbQ&F00000000<"F^v{-ȑhhcZر@X]]u----...019 ߋ#s`EL|_a6NfQdc-V! a]Lkc |qNW]ciocbhE.*R 1"ЕV'X;*FYζR P(r&d:Aa```````\$tEU p 0 CrLYΰZ͊ Ď6100000007 0 CtvwߞIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_include.png000066400000000000000000001124161477034762000252430ustar00rootroot00000000000000PNG  IHDRlsBITOIDATx콇Wۿ}w=zܵnyϱqB"D({G=FQHekBH=@;3I%9*~X'{ٳg&MğT|AkV_>+VS0]XŞ2_j #Z-2Y_Mv:DŠ%00000000jX Z_:Y/ZV`AO&_"A8-. FBE& [yuV p Z_:Ye+ Z.d2T*Bl NW]ciou{Lj-L}r.`_kPy<c> υh^/V_~J]`l6v*00000000<"F^vaBhTYGd}LG"`---555L&* -`````pbG[_ǡ}vQWW}AAfHE]ܽUXXX^^A[^ m-`)~D^JgggaA=}lDA*lwؽk[\\lvvvqqqMM ZIА`h42ٽ|AAK hFN F0p0_&HH, =~tߗu  ٸpLRRRvv6ɤ?},_j B(얖|]=  F`r0p01BF˃@A%@6@\޾}[RR6NfBLYY@^ldx<6y WXqây7nXq\3Ɉ  dٳg ` !`#Q^Va3ꪫssna6ZsٹݢGOs{.lq^pSd\Sw?~p4Y2eFAA$?'3?!fZYT*T*D555z&eݚkp=puJzi_|Ҍk׬zwu-敛7._X5W\flDt^;Jgge ~e]$AixaLLLnn.UgpΓ+Y z7ٸ~ꥢˁsp_mҍVFvꅉkVq yN뗺Oe#aon;<[|zn{me^MH |uNN_gU *KGGtfsu0Dž|4=5'\rڳ֌?wa;{|M)@.Y9*n2Y/n~,ܛł叽{o\jo\0.T=WmڴsAA/q޽W^~~a3ÁNZq[*IWeF@ppCezeXC/Nv]nrkFo/70 OK, ޞ֌Stσ*JVFiLٿelurڴrժEy ^Xv?Mۉuĕތ VO?so ˖,^`:W-w`Kۊ+Y_`RO'h mp\γ`B Trܽ{˗,` !`#?^Y!cq,[ꐻku'O (Hsak)XzI DӃ+,rXjǦUM.[^!%muմgTv_,ƺ>FeJeY`^&ͣl6%7bᒥRkZ[+rK:=Co((x|g  ?w܉edʲi#kh0hxXYi?OmeMr֌gN9v4źRry[i+yk% |4|qJ獛'QX^ |.xېztyV(˂7Mu >[/A}+K__,mXEf :/іwU E]ͺtl_0ߚ14d!zu f5lmbǥ}oF&v|T[x=qi,\8j':~mpvrF̷Y^tk=/ xK>o+("eޖm)^|g  ?dff62FYD"nmmظ~妍DZtɢt_U@˿Z%V_X5&H+fzu رŚq 6nXrUV8.vXsUbP8] n[hrSSk~۸z' +7n +rx9&߫7a߲+UᆴhŅg  ?/^HOO'(u+6nX5U+[3O/V2eXCo4G Ja͸iA& lm5,^w㲅~u2d۸poJ'a o^E}_gNk:,ݞL>Қ{|݂y-tt^~Juledre^a2sn{_5oZh +tv:ֳ^ S1#eYv+'b2{o{ re]o_7q7ٽcwC&amdIw]qr& lťM-ptp}#~ H~ )e!kÁbϲxmbjʩ>m[. TrHY֮Y3U+8/v[ )e\! `Kέ;'a%2cˁ;1)&j5g>?j˚k׮sp\pY,"uoN16.rov}WD?SqEVr;ʲl2[eٴvÒAaeee'ePR}c~+[ t_h:UCAP)˚Kz&e2G',b/KP/l]aҌ`$>۷۶n_xI3NʲUk7~ۯΛq5k֬v\teW/.u-gMΫ&]zEkm!ed k._zM !%E\o-o YӬ $rHYVZ/rŒ/uo,eWXNXUOc088  'Z2+.\ܟi:Cv%Lݝ>{#T"y0tFаqd&#ӧq s#>Q1L83 5UFvo`D$#hBsWb D! B'WrZ?h2բ_A}Xݳ7mV%yPYRU^bj cŧ18@OK0\IX=>|QH]7QAjaphȼ~!˹_^^&ˇf9 @MFm$P_ )"3.x={y椲Jckfʲbg&}{ˑ8?a`|d{ FF NaVND:Nq)-)~v ZnSUu|K3Re6/ nBgoh%E[WS [e+e?DaqE-8I#m{1 ;wf%28s$xdhoN-d3iW7{2~8"!8!a`|X_ F##0:frB"/'`$5_z6,`"2k5jޞnfA\񺈧2DQoz4C2X l-lfVsE`Z Uo`)$A̔L2r˛y~em&,#$YvD@s'7Է5*v#k$گ,E; 4\ \OJጂjd#0U:R@aYɝ*#C엻/Z:amsW3&(YYt"!LCOԼ ҧO0Ppao$l& rZ"NTr{P]UT\\T^^rm"EdFvt*PBn` i}Vٯ0H"^sSMW.?]zB?Ҫ8 [v,=0LoߪLWI*Kd(=L) {hb֔oC,hy1GuBj~uDvaەE'?BTUǙ`xա"P!bUm:RR;ägm]z)Uzw<;aIARnҍC|\tuuwww[|&$2 {#IWG+9!6ML&}'׮^κ{76%,񥝜~k)fBx1hӅT0dY*B:Pi7W06y+ ;DY>,Kۭx330\ דa{آ,,~b{h=$)1q%꼄fW;-{W"-%=v9{M)jQ~2'fu@"HȰQ^tރ p' 6b^Šn"dSPYx )aqt98Dž*גd[Wwx;Ӎo[&&nG}[.`>]\ R16ǕzS'kKHeһQwN؃|adl|ѣaaa𷻫>Ypaolo0 [`HĢ'NX};~_PtFD$K'Q$-.I~񺀣"SrY0D5wgbՖz2rPktV˽ KRC!D{wwgki ͼs!#8bc狆D`4{ptI^{:=MÚ[!m( k {Hii4S.9""FvUd&$뤜NTe$ž}tBVES]qFkut|M+nHxIuwy5l֠*"wИ? w䔭ZݻFF;ϷW3{VM0=*)/,k5㮄{ÔgǽCq]Jx\+Q(VRyk qqze=YD:GK*CRY*KAnu^Yzw3U= Lix42@l]yrZ7]ݤTUԵ6U dxXYpR8uu݉-7R+j똥)w0kUj8KGF]O)*Nypē vGv6_y[VXWUV/1MvD"&$)r:~Ɵ1΀~FTtTu&Bs$˞N!yE;q(Cl$=f88/7L ZYV[NM Rtm7ucMcԶ $cE9]TL!AZܤkCתLtJM JYÆިt\]S7,dg%}HfOYZBj? :IsJDTF<'S##RZ:vrE1nY{w.TƁ>h5jյ,2@YN+F 8Y-a*5'@Åj\FmXiu[ ح' F|ԩSrǏz{ǥAޑJ>p)|FW^FĖkT8RYTZFH*KNZ )ea)'*Z?Wj5@}Z)GB^ )l (je!09f= Һ Abۼ}q{[5kVVrޝq@{0-[NU&4ʊ0r;4e=,$-5u@}6b3*Z ^:dD=D]FA-UQ;Tsˡ:yg8p=<uDLqF6Lki]`e"S.mT:7R;|ֺi%ʒg,\Y<+9]VX4dg~6BOydMx\QϺqh"-Z7P7;۪d80(KNY} $g_K3c @SOܤUcɫe9WԱ@Yª=+W@YbYP"? 8Q*'M]WOw^`[$bhO|at! .$m Ԅ2 jZ N Z 4L/t\/ю]OUYY 6jkZ.`IS/j=ݡckmy끸g5ٍ[*Wٍv+$9''\]ZrGb@'/9gc{tnx]$&$L[H_$ yBH?b,:ë́R僡p_J3 )(eyʢa &_̴w/_ Զ=Flݠ"o)CwP(&kiؔ0zy)'l uOVuNoP"VTщB`Kd̃xc5; c pޥ01:|lbf@G6iºgE5,=PC/xSr;W 0&y*AO9  .$M0n JjJ=Ђh5Ɇ~I# o}][V_M3,ckD U|Fɯ OѩmDdzlnmRC%5:PwdcҏL}KWǖ,`^MClWf>\5)7 qOVL*KJޠ"!)0ҩz4FP:]!A;򶊥 #wyFzRIͥ>Ed*Au\05">"2 |ά_E6Kw3HikJŠ}{ԕ84<)q =eQvBo#<)"O;Q gUTWe%&UP?~nR_Pօ7[Xgt{hܔ`rk푁p3*.ĉ~ׯhYq8UVq%3 *SըWap^)RgV fWT& b @^Y,AtaYTxƅ9T/*c˾cJ++JsƦ)un dc%!@ÅAqx!z!FZQtɼB(+I_9v+rT"}"Zj䓖E-ݐL/GR{b#"b2ʛ:Y="^jV(eVBv%(&"2wk8ZZi.- A DNP_aCQ1DC8J|o,K;Q-*AhSخV^"Ut.0zxGVsɛ v\zQ\UUwI} O*ϻ*~c^jGV-iKb|!?Mh^ÅN+WGRFzɛ.lAA H_g048 FKyz-}AI #k_߈f5hokiijgzi9l+ 2 h7ukt,P_ (O3<\HA>m{]Q3{=e.⠾OnD?ZsRj E6;GdZPg7 uGx"mjl~V#,.$uayBg2߼e*9=Gdž$ƂQE}TEuVJ1+Kl6v tnLolnll$5\˜n@6TH_Dh4 IHkf5uL^ԬӚƆshbCf%-%I*XRQ7-J)[TY"2g ,KԄ'$=ko)S>IN0?4񴤱n ˭2ų,sbhh,=o<,vi))7 ҿD}|nO)nA~ t?YI/k)Z 47Zf?688`.C9=?eDm[HU hig{ =V!ߤ|Me׹,Ц9bd4?{A~lOyzٲ4HX>657v j$1[oR0崵4M slhwv[@9f,>~46%).U$ -qRaRsjcVa+jr~{lt+3Ry:ǔAAP)ˢ Am@9f,KAm@9f,˗-FDAd嘑^AAcFʲ~lDAAfP)˦Am@9f,NĦ\NUyQ~vznfDEi!;= #1#eqsq|0/K.|'Pf(9Z #1#epٚH.cL*,+~ prHY|6ǥ*Ç??}gϥ175[K1#e󝎯@"a'6P(˧9sp1+@]ݰF?Їւ|s@9f,;=d0-*HB|CB)˜9M 5s.nXbki@-3R]?5UCzǏ~DP9s8Lv}C_MUNȷcFʲ'(p:b2Ʃ !e (9ԵݰFS&m嘑ػ{:bi5sEYF~Dhe3c.u-l7w> P)KHi~0ӨC0|?r'oLúȧz$,sp̥5·>T1#e9zpʢը4W/,/5hQ/y/9[qyPT|RPr)5uע$d4vx\!&o _t۲F#?gA9WbOlºFubߩ-oW#qYn} W5,Gl} 3uݷŕ,o; ~_ٳ=#+E9lB P)˅3,Z='Ax<13''ml aq (ٔ%P2b2ǡ|r^C4G޻͋0=9倘sf'n¨m&%[̋ľd (!*:W.Or޻ EMm2ZS~B붣s %P~{CrMQUe^PTD)KKrIR-5E2#pb[McrQ{ݤmq'`>t3*9+7;=х@n汕ٳVT#,>ˬ#"I(x <6WCIlϳ4/* 嘑]8;]eQ*#k=@{l {0{x-'K{_;F_.yyVđx5 ׃Hpz;.<,ǃ,^GtHe/dP8~o$Ed%%?yy $CA)K#avYwuEE ˜rfuINV%,zH`QjCe!Ս`G_T0+9S .K:ܬ,NZq\8vwٛߧJ/F'ir|aH!*eٗ#ip.ޏ=2R%^*moF^c:mB*h> v9'=ۙ$|Jz y{KͿ3Ed;2I^;M^S:bw.'ynҶ{ 8yjč:8rL~(Dž.E6 k)-UOODrRD +0,W5_/^*:ó ϳ y_GwmG wYmRg# Bz…p;%])zwƝpM+jd=_K4~:\Cn$rn#̘>Tt~MtrHY]8e1p;Yc^'l? $J*ʏ bRXW9Ee9Gw+ -6ą=,&$n'b"%ˑ̢6R&j/./ h) V2(˱|j"ɡ"7>CЙbhHr@6DnTV^t'vYGĞ7lm^ ,J,jӐ(T%S^|ƅCG'?*WM}a:sIo%hL,$?$\*RBFnR^!|.p}Y `/uUFAIa~\H)KRT E$ P)KRNXOxp&@ٟ{9_t.)Zd (KZ c<\\uI2lq9٠!i0*z-2Yȗ+ː.FڨIl}ܮ3~ge<֪}ogd®Lv8,pLxqiϋz Rp:vbtJY*,\zEY0v&1KJo5?N*p>Iu-sujla슆Z!UQ=7x%g)e>R\M~0T& ;K%v3JX$Bt6,cSO.Je{er%7NyrVIWbۃF \WFpqFprk<+0nj0kQ#6[bBt|Ò&_#CΦ%I/Cͬ Lt^JYr,#oτ: *`|Jf %sFqlJq tML,Ca)^]]%Y[^xj^3PvACl%RX}Z$EW^%7~;( ْyG L>e'B;,aSv>T1#ew;|:ʢըR8L$ǷKGWreZDT{o+|$J[O&3_tƕC,Mm4uY$H8_~WYP[u0=b;T\@Ef,Uc,0AYv"EN S5!EyW̭W `Hpˇp?_$PIeA8"a%IJ8wa&##W`]4&%/TN\*K=DXbj aK蛒f )$] t *-,Hӱ^~x08Z(}p:~B6EikYc7M)^O2RY Dvi0; xt!OՐ-&vr;&:|y,VHp-9=U«{uЙp?#p6 :泉Sz\5ۆm%l%ބޗ֨T{ՂI*z8q%MpwgvAܠG+# ~"mDg<"TT1#eytET<>Al>|;:9;7 +^6+Ytz'�]<ũ : V _ ^m~܈N+K},AݓjL^YU!쁕y҅>SOR`Tdf/u {}ݶIbD8mBuOƝP Nn2(oI}t vcד,JAS \n /Rs sn$N4ᾄߓsRb8P^ޛqYCwߑ@NG`7Mg#Wvud}jqۂ¬;\ -"*;unRoUڍW}Č؇7n&MĖ3ߤdۉp? NQo {ߑij} _i*US\UUV>'hj֨ܛ^_Rr@X\6sɲ=$\BZ"}6'/#AwW %Hٝ}navrRv`Lۓްgﳳ'>v|"_2u#Oܳm7Ɔ!s&{#8)W2.YY וbC* 嘑D<}4eQ*d"!2xj~>kcRxV~{ [CTJjtЛO)K |)-{syo~n,0jo1rZR:58U8Y"|2~#(9V-@.gud޲{O.^Yϥ߮3EuڶbL#w> yo+i,c"'5$\m ^tQy?+=v^NmyoNI ë">Ʊ),cSY%<5CGq>C֝JrQ-Ì -/ZNoʫ]|wP%0o&P-wz\ g2&>,ȋj͡cO=;5v{5{/Fn # Ԣ5_m.` SAԞwhkMӣXyث.U5'~_nC* 嘑x:e$08"s@YK]i7V0=^7G{B]$\wм,7cF&:b:"\*S%ϙ1֏n=`6U=&"p;-k52NȷcF=-e y}s,',sp̥[wYww6VoYﮑyQYo(nj%9tE,P9,sp̥5·>T1#ey;ev*2eԵݰFЇʂ|s@9esٽ]sLǏ,Pr(9skaaYcuw"U@K] k},O,0G1~teAA"o2e9и?(}ĀAf|G Ǯ,+FeAAFTg  ]Q)APYAAeAeAAAATTAAPYPYAAeAAVʲ"AA0sGYG100000d;攲c.* *߮,b``````Řs  s,>~DAd1W #'ΕU_iDݒ7~|1_ F-fs 'Z朲|U3:/5Ď |n(,yrb;AƑ|t_[Η!vc/5# $|0הmK×k%_iE)KazM´N2-mmm}AVq_9 [얆~_jwa'枲242f4̵/5H)-Vv"GZ2p*_b# 暲ưYYƑ- SOt҈-.~/#jj`<0A+UӉ8oMz:/o ZY0!#LDxhdl锅G8Z4t=F?6 AߡaYwBnG"; c(ʽE?N&KO嚲))B{t~6Ѐgvy9Z|H'W ;E "wנs r{({u!:RNA  9ö=eްR`.bU%ͫ"4rQG*K4fuQ$M,zIYvޕ87DPüIy )L5zHiTAn^BƤoÏY5@Sgh CoTr@FID~v2 OUlh 4tEΧds0=zPf*+8 B$ e &| Ȝc)Kʒ49<1Qtw7;^tL&rUgȹV8h2 BIeQқ }14h&m5Ob9;Vh|޷sF('BѲFanl%'d`;Mže1Uʣnve.ECS4h_ƛ`QzTŞЀ۾-smu 1L|Ay n" s,F`e`4Gӗk4&m-ĶgAθ\Jk LAꃡAjެ,!ڭ\:h O/4>{kwfٙټ{f"s8<3T$ "H 9'sMr{WU7;3.~OU[57\FM>yvbN׬f꾀f]Y2-/E;7} Km-DGCn]E\3l!,-85e (9k8bqSkTUcmpUN2\x$ۤ-_eٞft8+ʌs}+,OLCqR#-x,3$ea@=gqH]:OVvEՃ7JReR, pȔ&V1lͶ^`s-y)+jZ^>>wn+Yx..QQ}^B!*MYZc5e):ZqY_d:Vywpg+<]l7_J)3T|fy,ͲG&)ʸ5'OIMw}HUYrceG)Q1eG9,wxs4e2t*S|ot7ѣ7B3e+[G977UQ?fRp~OX2XKa}KDa.}!.<3 ׷VQSlxf֏bNu!"QSn .Y%%#&8el.R9񇲌ӗ\pj/,3Ϯ4EkN+tM.7@9aބz/\wz1گ+~c/SiysyƢ#+Gyj&/vn*.~]gԌ L98ӪM;rԪS+wNlReB)wm;3a緩UeW?UjΎc.U>:1sKjr")!GVѕi}h-Q^&Q6ڰWLoᴊ|MY.O~>9=(`,L !2J[YN5_]"5$% MW.-ҵ᫩ι6|dTV]eg ]r*ֽfYv_}>HSQͯ\5Do0|嬝v,Og_9PT>PevخO2aS@zUw336yu)4b֭m!Kcu_~9# #6ꏟ}vd\z>Q73vίr:_?|,ǟԨ*S/mW?9}!=JYj+R{.9Z/h973ӚOOi>9Ą'Ҫe:(|{9($ʾy#OVŖjEwWɳrP6E7*kaА-n 8L`7oFERsOr)i) <;buQiFw#NR>2vETa^u:84$nſ3|2bۑawNcOWɮJvSdkƓo]:b/TeIι2sG_->|5(i7>M{#B~ (eУ+KŎIm'7||jIϏ~xlэG4ְϷ~W9c?eφ(O7F\ʩ֖> lWTS~z ?v$[<>0`PԔRo0M)QW̺8b𓊊ksQ~܂ٟA/ ̸vO _Ixi|dz2 /ͫv7a𱴪3|4ԓ2@0|𥔧6Qg+ԧU9T]--OWgW?5SDx6,KgǓKjQ/Y{VEj17%qdx_.SVOg䗩[aYf؞þ2|ɧ rM i|)D+2_-rqeeQ _M-\°ſ2fYDI{+$B~XTUQ%/xe^SwK>Si6G xJieYU.dO˒vɜ[U!s>5~uTg҄oDY&̭*IR cFp6$~ (V˿/N(.+]GǣF&%$!%@=P-6rn3};,85cït76탓6+}s;?1|>\\Q'd2bvRQ}EU=J<噮,w[k/&!3TS{Nqy?wgGW {WJ9Y dVjOPU 44PC S _O.*~FPII(˯#TeJ+/M!e6$n>_t;={y>7~Ul6Yߊė%)G tգ-S/eTjr$ֿ?J+g 9^!"JY*Kʒ0w/vM.6ȝ_ u擯 ]v 523/dThOK5[Y^2|}%8ڷ >yWe=a<6)Veys5exi/ OG:p%0(ƙ?*ucEwZյ´"Jݨذ#S?e+yc;snN\y+o zRQ?7|墽Bή,KʟcekA!Ū7B 2X,Osw cS8O{2AMeڰ+%; ],)<3LTr Uy--Hq?3迣|3m0 Mb5e 6y6_U{ښŏCvϵ|+ v5 \Z=_"'ی%μGW6NW/@쯓w]^Uc򙾷_ׅ^Txz8~-A\j鿳aBȿ!JYJ D~+ KßGO,gn,;RPl!ȀRgyBP0@AYeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPeAYeAYeeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPP^NeePPeAYeAYeAYPPP@YP@YP@YeAYeAYPPPeAYeAYeeePPe>e!BQB!|AY!,BAY!,BAYPB!,BAYli(8#-B%*!POY{]\Xۿ;P g*.|%H  + Oŋ=uxA9=gJ=˗7*PPRY=l϶mx뵝+&ح֌T UP^,)I ŭ|eKȵfL=[P7{.}'#gg$\0F[Qkʁs[U/XHՒEFVmmҔ%驺(N?s|_L?0!2t료ٛ}bn&G4l̺VB~GJ(}Z.S1?ȟ?7Κ~#$7\-U [RY2vVFJmvkWjVxv2dMLY2vRq[=sgͭ,V6%rVt~Iߛ\ޙmL65>>l:j%h/2ߔs2|N%2Vgg~_{1+oYSgx2=o裿KdBv-dK Ӥ=u40gaP鴕ߜ+Rl4' V'o&(wbJeg{niPa,iẖe9c椵*\酾śY`zMPqTcc e2VNcqf}cԁ*޹)u^emջU/XH1}Ǝmi&9PaEo[-k_ZsOLRyb~S*C)+"kNSڞ1ʬE6:,wBڴJT8vLxUd|@'iϥrm9&.vKY ˢjmﭐA"fXi~cF.U{rNT25,!V^É <),kؽ˧WZɣTԡT@-T/Wr4hoVGMY{MPFo)’Z5Oz]>vVVV~`2ӥ[۟RUV<{`qőLP)ZƂs_;fwq>=9U]Qi5{)'r2K(ʴj7W>AZ*˜f0`2jstb*9WAe7&^8B#oWZtAYvtkU:ʦQbMyꥑQEZ"55+SO<9>iHe5C9'&?H{X6*1MMeʦwⓓ,s%4<(ˁnL5F[v>h, ]3T1!WҪ^u{VNwJwK-RRHjTAMuFyi2h:vn߮'BbcîH,kzUoT*(9׊9MVUFn*7m4eYP)(ˎ7fC.Œ:J::UW[Aeg]${BȨp.IdB~McyĪ!ԓ9__}2t]td˾}p'\qAI[g5o%{#KzT݊&ϜFOn5|̳O˕юZ9ˮMZo6)9=ACP)~[r=\Q7M,uo\o( {R޼ƢDggb~UT*ƪHMY 67/D/133-'R/SZ%=w~%8KafI{C`T/Y:<ѻ qjwQjoܤP J{(TT{qբ`殯)/v>e,>mXAjP^,-2VltxmM<<(YQgjkã8[Z(TB +E㌎׮\8C{ՋgCKJRZ%W* !B>,BAYPB!,BAYPB!,( !BPB!,( !B>TemYxI!;ƦEYKeWB!=cX*JK e+"ejn"B$VW ekIJ %B~;9!^$A?( !B B!B!e!BʂB!e!BAY!+b+Jr232g'%:&xo>-;m󆢛'RNxpjg]8)g%FX,R9YEvw}p=+ΔKGR_@FWNoϾ~P瓨z:1==͑%\ޟvlGR^Z,?W^/^|隣syÏiYeHS-j{p5&Y1kpm+W7iuT?aHSkcPk]UY̯i+yN;lϚd\~ic2xqcۥmxqr~rOvovnō>ʐԧYvnʸ;+ǺS&nW6D.lPOGmvv_Y#ee:Ӧ+[\rPQegVg}̦ ҳcNSFmOnƔ^.8$77Q\\fը*gEEE5VWm߹{8+;#)x6R)mRR'E_7ZvpU] (>v]MN}s rچ+Vݫ;u\q~}ju\TϯuwIi2-X|Ice7.w:ImiʰG־Qͻ7[km絥FG~G^$" QMkSL`鲛K9dVt~2zcS*Q0GۘlrYsޙܥleY~kX5-[驊W5Q<{eWS?e~PE)eeG]U"%,=f77&mLol +stP;:s{7/E>2kmm)>[%լwu;ݐV{Y= -}Aκ0UY|m;;WvDMi?kϭ_vvs6.1n 9w+[ϕ-[c7y Q;kڢvj Y#e ٩{w98LBt6/Wz1?(#~svZEVvG.7.z2sc~w2L O-Eּ{itko-MWGcg󓓕aS=sշ*⻵Ce1 -"[iFg68[K4Śr2lSJsWwV/h +st"8zoNKeM &QF Xxⴗ\eZ3Uʳ:2^q reYچyRwv'T<3ZϬWJ\gW]O]N1n*˞w*"U}&)>sfq6ic|5z󴖫9n;y<+gZӗrrHYȋԦKA^+iY99+)6M>[²F]]jk.}rtT;b-pUY굥q}J,9{FK?1ڍهD݋9&)+BT𬤺nڛݔ}dTk`L'+7?|c ](ªlHeQu,g*#>jrjV~ $f7K$1r=ujNj% +stDu^x'[](Sv$v4$oSTʰb.:K%k}r@Ul>./1V*ʲ"ﱩ;io]q(jNsbyb2׉.mrl2ll-Gߘ ʹ욠*%2m?c0Zہ\"fwoUfcۙY#eѮ}kѦRdεfbZnUn2%k*>6t?&jPZY޸ʐUQUܳEwތp?*vfTi;oo`܃7MR-憌 2MS]D'}sɨW(2vWRWNwژ9mL '꿡XLqd6֤]0m;.7Z1U3jƳRB O`Ҟji*Oy!^O?^c;6-4\?sVL=zSËΝl_hvQT)KxICS,Iui*RSJPKӿ]>}g̬,>m6w r UgoqȅKG9:xD:^dc]N\9a*ZRoޠ)ˑ]9r} 91Hd))~~CJݬ5w-ifq{S+㽚-G9.r]rT&:Blfޘ=b74Ν2ζRvMY6/Zi8b2Q,j4[kbڜ.;LTWκ)KH6G6E+GzF)k zA+VY*nqv\Xt|oܝxw_/lrc "+]΂ Zy:մWf-rnGpU#%f7IG<c}AՀRSnY7V,QEo%raB1jtf9Ӿq~{NIΣ+ꐯ $C DY;-Z7OC # 퇵]"ֲuRWZ[]DӗY{&blxpp8iѶ+˛{@&FI\!^,hts}}㼶ԯz[E@:18<iނ cGcr:rv/mچy,u]ߥRzQ}]M<5ព;z%wY!]itPވWw,j8^ВwAhʢ}!rx]wg_iq7OZ˻~u-gCKOoџ\z{qբץSe=҇ƥOpFEd>I#xc#vio[znSc[$G%܏GĺHiBbwLcvgD#ewBckk\N7Q }%ҧ=sԿT[Sy]tB wfcS؁ob-;UOMӟuZή]j5߫HO zsʅ#xo>;m#C_\5cҚYWșhivt8ӧo,B!?{={lXXx؈8X땥e!BWw"6B!)˾}MYtey!B!,?w(,$}*Kss,( !Bާ?><<\ DA 1 q 1 5(hll}izx;A q 1 W^ZVd255z)Nj!!!WtEq+˛Eva٬ޅ"8F_򒲼Z\...Ã_(tWR4۷wIENDB`backintime-1.5.4/doc/manual/src/_images/light/settings_options.png000066400000000000000000001525571477034762000253250ustar00rootroot00000000000000PNG  IHDRDTsBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:03:01 CESTDŽ]ԭIDATxXIOI6`aw* 잽{={BQAPADZSJwo7$6w#֙ٙ;駟~*CO@P "R"fWbbĈXS%ExQ  ^w.LiF<3y{ U^D;fH= d#GuQ4aAA'Nw-uTKu$S,=B ZOE&M,T?^RI^LHUH92  ƧOf nn}WUT qfq{%{#K2  :YM.s?C%z%"ial$7ƞDNGA ˵Dqqq2z(PSj$琙ڪHs'$$GHAQpz"39wJZfpڪ*L P\w; A@c"?U"U4fs>X+)VԮRM.!A_{pY9 ]kt/p4~/ \W(AĚǏkFmqx) U3mHj kWPver&Zee"Aꄟ {Ԥ& MK;sGWD>Ӷ :vNn+faQ$G(=w6I$) +h ok kWUCpH 2#A!kْt;)6iߵuQfw +{ڢM'u*R3Txi)W-I$ ⇃{'^GNmmmcǎl?Sg"9\5&ݨER5[[=]ee$AŅ%]`ɖi={HRt ٥j^+$%|6ÀѶaФ8R;vGmЪU[t7KċtIa{| mZB]g8돘ug\meD,?vRmw ڶ}{tVqn qzbtbo뚀]Cj[N(Km}[رH"!s#6Zw芾V㹔2AOxxc⨋DrpA$G(P=.#kgIIDf^{Vmѥ[آ+ Q{qn[Wi q#.MfCջ':e݀ i߫$־}t6\mw}eeiN uD!ЯBjbz2,߉{q`k70΍nۤM{s7-t[{ڢȝ{Uikic)ίM[v+Mnӷm_~?nctɜG Sڥc!6:>T $Bݹ'ɹkV'.<ـ7H 2~=Z)g0NؖX{9زri"H Bؓڃ mYi5{Y%).&Uby҇{1ƞG,xJTlDR&a7Ӈ N`ci6":7i88K. ax)bc 9 mBK+1<0 m;i"^{O$gznG;xm'Pr8H,fM逵y~21]$5Mِee$AC7~+86^ Ʀ F/v6h=zيח= Ɋ /nޕh8X/Mga1sYnR^d̹ ㇑ɽWJ"ɉX~kцei22 Lbi^~c3]C- 8TsI ? c1 j>bQ\&*l=7`Æ 69"z9ͷ`̹/,:^5[7;RHMa|#2AdM"9ZuN>&]$5Oi22 b\HٮsG80BPl{-_4+Za0E!Zñ~,vL 𔓛Xo,INl&et(< [~h;h7F)?I,<O"L>I?X~1FqnG[6C۳vtQnݺ\O\8BbSRhֻ&1c|Q: ">c[5цD ,HÏc}ZXwb<`L0 O(7TlF,Ewn̤M;>nr#>O:l5z'Hca/;tFmؿ;aWL"ɅۣۯF1yr?Dg#Ymuh \$FMϽz⮭AVmѥ 4i.)Mx|!J$UngngIWgl7aKHD& ُ#+H|tRXk`thc =+qT'q:Aر'؉bo]c:&mW혇1:-Zw@!Eۢ{>ԦZwW~wƘ>#{]kt3 ^3i۪$GhLoth;t+1ypweӌ=~0{H,DAkDR$*?s[+ER?MI$ (8Ha17A ;/Ћ DDD|DrXJlʛ@ $AmzD7ĒQ' $AnͲ:ǟSxuR=8+'ZRIɬ$5QP…@_j51N|&q)= Sp9;7G;N?JE-'G^nMHcw\?ODGG],î8jY'kJcY웕W___%R{ L$ex PBc aaU,7ɞac+#i: {=x$#jtW8K&"> z%)VMXTۡ:e<a֛ۑu!.|pn={ iC?S/$A8"D>}Z++,+5 duIY0mŗ{^ƢT Er{J^ ߭131-n.}d#a,@iW˛00c^~tŹא˞b{{ 0ea^wwߋ9emM!)<ʛ!ي cQY\e,L18TN$kYQ$3 WmQ#X; } kQy)l묏CϤmz/svpa ϫB LX#9 e  Pv'i d}p "؛PGoJxQwy{$GXogz#\ރߛ"]{n&<N #75v%2y9BCpfkmAv")* A`HnXi"͵ ,> ^{G/צ!ޞRp &PGTxwCw:Sla!;о%ma)ow݉ٝ*~;^×C.p^ HJA{ݬ8mS(uE+(el .tؘ^){bMa*ԘTV_&b;GWU}6Z[am[`/G>BZ {tKa5o;ۀd$"YW b61 B$ m/MFat煭x`T9!MQ&if+plje~ǑLawGt (n3; W߅}hΏXbCL~".MaKʺ?M$@K!OHˬ%Bjf oH6UD\A2^ f%;ouTF΍$R&Nd#(#Yۊa`ɸ=fZhꡔKш m_H"yH~ʾ7Y.#ζG(H(x{wGĀ6 \yl)wy}ۺ^cPZX.wB;c!g:`5p3hO.K|b9'":domCkB_>$ YD=ʁ9{ C,4`4mK4S+ElϱWqC]+]_U &}غ7{sȊY Ù"r($i֘t SS 6cGN 4['TՂ_>]V^VXq3s< ~ȷrw|9$&&֭[yl@eB$$Y$Edhzd u0h,)mmw~M$ӄYIxH~d˗/gƳp]ܽy@{%O/9yCvVgZ@d> gE2sE(?B$k J6W$rMA {FiV&SF.IB+H ǫGRkU$B;e1Mƺo=1J2ccnC!(%k 0ƃ/PO"T[P&\{3P7J~fTJ7[u}/q:ˊ{o//D1iiQ$eҚZœ䯷6"I#;1#"(A( Hqqqxi$Rv6۳Man"){"'r>[(>>AP;42=eEi@@:7%p3f4儥0ĕWg_PBӎBoDS^m]K ވBXnސ{LAz`~^a❹-,^GCc}-`[D_bA-#Bw%)mQ0:`AOzNVlcpr6=m" LZbx-Crj Q"; _8a;d9[{Oϲp= $_V3+~)+Y w*V5"RvSx4Ă.6ƒZWQMdm6BSǞCN"~Ũs|չ<ʹ.P\ Vpტb`Ɠ8 cSHI {e0;z[Ôv"\zuCG퉏>PH"E[\Ŋn dyIuLԴ4#`]lgy"A=НOwE܌'{4Er$Ҳ2, r?nQ# $YS=$CԹ9PSBn1zskN"9~OX]?78^Lxa=[)J vQtQ DzM-QqG,:}`n&2C xEo3Α)߬&'''uϴyJD g *(:jސkg3i< Ӫ2"iMrUØ% X٠J|I{̚p31s <뢬)/}Qb3uP/[i 4&Y 8A$&*k$CIƟUDN啓I ssq!+$$$A|&,<{/.2@G1e<؈`=*<sp}8sbÍDDD |ڦ T^HHAPL"I ,+f'AG:J[ōq4\Q@{,$_G)^9C7ʢ)$$Dkr\qiGH~#䞢.y W'e(RNp83\ZS@ _I  @"IAAHAA$AA$AAA"I"IAA  k#AË$'EK/I  ~xzh¥ׯjp(cNfKP$p--_tzs_zׯ_jp¥WAP:QQvDNy=@HP"5TC@@!AiGCI!%T\9pa J'J3CҎ%I I$I$ j(())IIZH$Q4#()III%G#$5 f!A"I"I""e!jR HƇcq6#w &-SopV_FA2DiGHH~C=/ 4A 4EhZI#"p l#<I99ř/eYA4ӈUp] 5lW{\[)RJ|x<̛aU $7=LQ,l:S'b9{SdV1Q7!slqq7`bH$%oz(9r}WwDPXF\eňeH>cns ?E),uOгryOEi`[F1%j÷7Ϝ'æ@l+%$v"s4h|aaj(o}*h5pK:7E2Ea 4(jm~#Ef oni>@e1LQQ,?!ºq Okwž^aTL ;Rɂ$Op|5 EQtun¢PN,@6+p5EK;eʴ_:g/ "`d|'jVzUeضo[ HMfCx{/HP"G{@:ޖ{\.Eh]B^:-{E q^>><j胱;CeqG?v×zWn8XB`9ham cV LJïs"W.el(nnk;cuIhĞLmuE4 3iWXuشJ<_bph:6sL5B%g4$rH5&F0i7> Kސ4ь ϕCв91LK] Uسgz楌11ÐGJi%yu;ƵrEWDq1"b45('\{eƹ#:\FGppR8 D$I1f#lk[ٲd{Bs.cWZ}8T<`@_1h_,uAZueܡJ'6fiumq`1:8j]"mс(%0͒;BByCH3ͦQ咦 `Kxl"aKB^&C|&aDik]W6GE!2Leοȟ$ZPϔu#n q&JtoV gX솭Wh϶Dyai_Pt6OS|9u1\x0O*&zF+_s/0ͱ"P9:lOl{1U#Lr$$Բb^-Dό\X q1)㳧Ad1gT(FO #u̙X05xڷf&H܄ `JwŒ#.ps9[BP?N plcaɖ ]aφLȓHJ:śa8tĴvV`*)bQAT g)8#1Q{?I$[8)Hӏsu!z(ħŹ`$BqGwm\ID24B;ѭ>*v[^8j"+ðܖJqwE XľgI}ʕ+/t ?5DFNeQۘAߜ\CVF5Gqx PsK~?3gpbha蕴DpvuQ a"Xkه>0o2|:kUàޟh5lz1G5wa3dh$C j)TĩH18CAhk#w1tpQWBHTB)t$c=p| U"yuF#ˁ)? ǟIOw4nybxe*::8%0dE/&A\'uGp=TRBE{8$%?>x9"S#x}ȭSv힔DDR`Ft-c6T\Q")' KF L}D0,P |s;'t@ʖ(jb˲a>O&_"Yc:.ƩB1abJXs m, q8{>9V[D2LOб4à`Xn?Q^S6Ɣ YSZ$uH3iLk0Vp:: FvD2/۞(emxf :zNC8@l1nK2ҟ!ַj6_rE"&^SGNe,kY NVLiU+QGϜA aڜ`L;`k/| S<-Y۔=Q81$[,MI>8?Q}@o ׉J;aOw !ʍqW}mvUrTÝ>i#>NV]]I4[x5TV#Ǣ(z>ה'1e'%7ӵpol]Mn"6nmu6^)&ah-vC`Cq$ަjML YƢ}p۝j aX|2=C#Q" خţx) ~zD2 s=}+$2/Fa[a1 AXwK}.('0j?62ۮIq*SÜcr#Hf Ax=0p|U¢6IɁpP} ;$(11؂A3*.̈́5S^`sV~"CHJpsAC0q\u^qޘ\gټ v6+ *M<ϞWؔh /%Fw؆;!'YwLHNb0͖TW%raM`ĥд lvR 13.γLI(3!lD2!$T6 r.#C$}HfE2{;F;]WYG5phb = t)ZER{jCh^j~w"}@uX~~Dl6s(7#HodXobWUe5ZBcte@2YSYDŽ*t/>>օXP=K-7ӵto2%LbH/$ʖI҈y)fQؤrxuaѥʚ/-/Vg?(yهb?1籸WC5a.tV09) qױg6kތFj,@(FQ!lhk AI;L|\4-mwg)LjNWi &c#P˪G]q(vp#WIav N8si3vؠ;.QKb 7i݉gBaÞu7d+adY|>t ` , =eur/$pq 9fՅI3ɖ)Ġ NQV>1(p( F2M$Sm;65,a"1.j`ց Uk9n2{;ꚮ4S0F%av܎1$H4#~<*-vy=1I$ SIҌDDDD M nۗH}yKܑSzHHHH~| -pU NfKޓHP""҇((( J;B')$D266QQQ*J'J3CҎ%I HzxxayfگxAA|fH$iZhZhSԳk  B"IAAHAA$$AA$$AA$$AA$AAA"IAAHHAAHH~&q &  (o{2  H~pK  rH"I"IAA"I"IAA"YD2!/.ERGO  H$I$?w],X?HG$gBYs# s@"$0@1XT7H$_a_g1V)'$ D 1;AS!*O;p],/B&2II  H$Hu!*QUnS,},*ZYG;Y8Mes苌PNt ƿ}D]M`e*c\Z HyTkX1a l? N!ߝ¨EPaI?H~||vRF"RN "/+Œ`h6oRC%a"@hd[x $AA $ \\\}O"-I0 Ŀ,†0Ϸoa'akg}z$"`IWAOjb{e&ÒƆqlb K=H &uG`+v~7~oRZsp3I~dED25$◉~GWU}6Z[y;5Fx\A^r Nk=+10ѩ$AQqȐ!Y>{Bi/%'0 Zo~ʠqN}P!fwN8c5Ky t/ OIG1(- k m'GYQ}, LN_'tTU \]oW!B6hI0Eb_T°WPpȊ&o.t8[ LٌšEԚ\z Kak| mж"-(A4;/1-,^G =z[1[5؄V"}8>}RRNE"HAwz$pn{d.7z?HNͭ 2iy{a#TCA V{z6&13/$4&$aUsJč's'wb}Źfֶ6֝#^RqWB^!X Я ͅi,=*2F}{@_^^ ?qn&ɴBs1^f# Q$?b +#%^ #vK=x+AuL=yΨ["=Ħڸ#d\[ǶAMKc0%//nֶ\.W#{XdN =Tv:ƴ(i@T OT2o6Ƹ$jڎG2H:b`&փPŭPn$m-`Vc:&5AA艀 4AA$$$AAHHHAA"I"I"IAA"LFAD;ѣGw^zSAA_kpB"=$d];AAė ]%D  3$AA$AAA"I"IAA"I"IAA"I"IAAHAA$AA$$AAdqpdlH! M]/҃  H$\Db8g !p~TX(O eyߏ_?R)M ɂ-AK@(:2ɣHׁ͑&ڄ2*^$.cJ̿dJS D`3`!(~I"p]vQuϏA)aeq-)HHHA7IY2 Z:>LrB!ÎLMתжWrfC?(X :) e")ޫo>M%M`_=> n>9 Kїi* dPm +l*! D2NyfV NdMvMيJ8Tr IZ&ۼus>(z0ͯQ!5WXSIW^.{Yuv]{」Ac+4NB >u׻93g晙L9XNu`G ZATk)+2`E 6WИ*<+T_髤Y)ADUHqF}S'DAH_ŔRŕ"_gR`Y- ղ_$9 &ͰSER"E`*Cd>ǺFbj/Rzcܯ uu9Hb֠+g@ 3D(/,gSهf|=qP&'ai3D.U_>8lA}I_[[<Q D60Z Pz5`-1̓AQgso 2\P|ƺ?܌&ܿs̔a"\&ݎ6{ψ*X!!8v *1(6?+zy k7e΢_PHB1&c_ܼyS=5f$ȈKpOy @A)Ӿ~IՇmآ1m!– Pof!ޛӛ`.]1FM6f{T,>Pl_7F4GYo sl|Y.MAA"x8?7|~]PPP &fɴd&D6n1PT.>#ɑN "k7_],tScEtyZT|mK-)M_k@3[xԟ=u vg;mxӋ@w `P"\r@Frq>*]AXs8WY~1--ͧZ$=꣡-!,5b@于(``ALQx/ѹG2kr|3K{ n{ĔaW yԜ7uBA]χ=AAHH$AA"I"IHA$$AA$$AAA"IAAH~H&&&x^xAAA@KJoR$Ç$@"AAPzҗ#I%JNNNB   &?Hr(iMAA7)DR-Z  (DD  "HRII  II  II  II  II  DD  h\|Y3eZw!^"VAA(A)$222oΓLH~H*%2""BAAy!<<MAA|JJDR67I嵩A&l$$AA$$$AA8"gyi?h;j:]VuT>C"dͽ;wnbȊ4gݓ9y N~knAy(dw|!l:87NK^ZP'#&`>?/qVǹ-=ץ_q\¥׵ }'?I3w7D= ou.3amNDə(77 UFͿQc$H~8"[؟@$1"6ٶ$-hV"\E$%g1r3o~li\,x`\>_'yWJ(e0F|1\ǬERթ1'(8lx.ϥ>Q|ߜ?Ta0|ƶnj,?2")*=|]Kɇ6 S$kv|~k߅ߺo=}q~lڴI͛Ulڼ6l{1|S$xw3,ō@$OW]ˣHf-Ԕc%@>[qL(}aұh%ϼ2x4L:_I,ܒBzi P\8AbVp+H]"?f\}Yyυ;pIٹSGTOB"I$dv0rRz-֯_bÆ ظq#͛QF=z4ƌqaҤI5kK"C"{ڛèpB&</' X  ۚb)3߹ 3fUy7J2\$1S>Xq!4- Sل4$ zv0B;~m0ъQn`O )+MqҖm*<1>6^Bb~Սait]H29O7x봥xehݧ)ˇeZN'R4g{e! qGa}V1YT+TH2"ɲ$ZHr͓~ªhn1+c9E29 k[Iʼn8N$4DIK1\Z9b,M$ hԩv^"Β%&.vGr5BgaX\#Fs"ˣʷ]>f*h~qLյ!LhBF0Fq :۟Xמ=@hn27L5 ɓ1|p 6L#Fȑ#UhJرcU(erhw4(;-͖ s +jQ<qGVEnvw*MDPN܀P@PmfoW` VH);*Q΢]^F51j.&%5(>*pobfs`r d>0n(?o%ְǴK -bCu^NT.577xA腋920k /+ 8p4_cPLR0|nGR3}9-F4t4S}CI}.c['}ZڟX_0.l(ڰ?ᅧRIEz9LHȉ'Ea$?H*77[wA^sIF?ed\DRze J}XJ!R9M6BTTѸJ(X8 BR=147",^ g9.2r䳣Q4}i;g`U{,v^*NFS$Kƨ=|.Bč@ aH*t!V?_{$9ݝo֓D2 EaF"8L7"6_.gX08;m"5IH&`_{N$k-DR]?(Pc,C$5W$NEREs9+BmOGVr:F41qBO$gji_dDDH`"4o G>=1˟am#1DLczc `G1gr.u_4xE02TU:8,DcSyˀpDiDHJbZN̾,ُ.f:W6I }+%ײ) ױ9x:ck9 eEeM LIJ<"Vfg@d-3Qi'p[W<Տe^ѽwҋ!Ii8"pq["iHeҵlc匟~WOZES `?( G*A" 駜g#g^9 T2 ah.og`K+s0I#VZ 'C`GrmA"}"9uT4L$՛ IN0;kW+8^kiߢrF2.h1yF[4T8h̪ĖXp3\}&<^i?ǚB`D,dqv0P N6ǐ+^P7{XeZX&5Dޛ#ضxZ0ϬF'4a]o9##_[Q5F[X(SP^oWi9k^SW̙8u[ F;^k7Op~r9h5}+O# qj[rw=Z2( _"r<_F|WtZᅠ@/ls׋8K.0sxruxGCa*ɀI}~3]XwcV"`)<^ڹ}ʵ90YT<0?T=ib Ʃfi=EVKJFpm^c,vFxEJ*hVp)pL˵?]*W\'\Ƶ+gqp*4įG}9c ZDR7dBٴsN''gC%G2 L* /3:%7砲@R%!_[XL=tO,+_}ҫ+,<">:s2im ηFwkxzC:" /YmGDH<^ n֪ֈːo^‰=z~ yER l GS|57_a~dqx{BU7[ ǚ®tC]iKi:QEUb~%d_B rl[ mƍϥ*6nwke5u5a(o:Zľ2{PLءlq8x/YG-Vs7&. +9I*Z[kSdbРAL)S#I$L;o!#Qԫ8/?h۝1?&?KGď.?ɆvYI}"8}tw6$S$MCZaIBZ X8~b_Sd\\XzFڰ 5n5u肚-V{/4]NK"Tx.sZ*Ή씇@d S'G"? ~nT}ɇx_KyiI$& "-!"F  /F$"z=5  ʭ[pΝrD;dL*&AArz3R|I  oR45W>rvz:4޽K"I"IA.sSV^$DD  !$$  $$  $$  $$  $$  H$I$  7HHAAH~HP`AAқH$<{ AA&?HrLU2~F05i?kI7~AnJDR3XOX117R@`-d7Ud۽EZw!@' D2"%1Lo@gX4ņTɇjwāD{ f,Aɜ0kS5cR<>5j{ f.7mg1"TV*SrX*mcXO=|DL=zN[yI9n(e;~}i[;f,Ċ 'p[vR?,.^;cOi30AA$`hJ Po1nc(h LJU[bNW &#t+xX@sv0ۆA kxک ɴW`ʂϚzY=׺<̄ `VC 5]r ?AA$UAA$$AA$$AA$$AAA"IAAHHAAH~LLLǏ3x  Ёҗޤ'I"66IIIHIID"!  $/ѣG$Jf BAAAAMJ"PN*   B?JoRZ$ӵAAQz$$AADJ$$AA$$AA$$AA$$AA$$AA$V*?PBtt46AqM=ADDRHH'<<t)_1Mu $̂i$55 r m{$NeFІ26( k j$$Ա$A"I1@HHRBЀKMHR H$I$:k|ƢÅ 0iGqH@!{wg%R3]G#$A"I"ģ 's-ߺcI5/\>(nE V>Ev #s4TȢ k!A)'g5C1$?n"%5;çlKB=").5lY$/{g0?h_ @1Fv.g@ć/zXnbU}cWm~gqD#+n'"|0FIaZCDD;E(̃I.0N:=kfb# !*Q :baXL3$6o *s8{w,D*Vȯ/>Cx}?ıyPB>wIj$?H&91 jYWWguQzDKE,x5 /iHx-7c'-yk8Հ*-3-~qL$M|ob(]v6RC$eG1; k̂ڃ[ztUulJX;#YC̈`S%@U6,]$9/vư+ ?:o$Į1\Ka3C F*n5agLz-{l }AUն8^>`hq/cĸbO\t\\OE2{-ME|xL 5gCa&C`T5Y2 JڈmPPl.c&Sv 1{rq<0DH&ik#!]3x38C  3X$x+vƜ#0K"IDɺ+pS"3xi J 2ERz: `]c8X\ʳp91MG2 ^Yo>~ 3 ܇[pV8I:_,O*40õ6D|PhIlz~x]L~' -!k?73`Lh-"J5&!pf0-(F,aW/X<0`BBp`nK ²`:@=֨=prYI/ p7x]L45ێ#w?-ƨߓQg-D2U$ 0pU= 6wX70mh BNp]$}Al+b7}19]XwP|:T~5Ǡ{$%xpp8 *Cͷ%>əp8St.m[9`]w5~wqA1jvǴͧS6daSAY8fgPh_xJ.㌑&I+אhҶ&4hE$=vG' 1y9%xV5.S$[zIki[蕍`)*q! Ծ=\+a Zٙ6+dx,Ar[<]!bXP*dQd&Dj,['6M$f!R&'XU_ $--چ|A"IDIAq8~<Ο~p˘|+g.Wpr 3(>"'p~n]QAw$B$$e{X QaA<Pxq{kdAYg^(|7[fNbZ`A>H*b a݈OI}538q!re*^Ks#)9a,* :o;v%aP_< M.#C D2lT56CEH񀑷= z#7č_A$<̭!F@j;6᡺Qz LŸ'BLF?(g4 yGI"IH{$cV R䅌bq'p3sBD5E2) {:썅TH>XR@;`.dP T`vslaQUA."V.]$D=׵pyzŕՈf겚3ʥz"yU"~:<3 l6gJjCnkؕ\w%:lH pէ|O1TLuD2c= 63<\HTS.x2>kߪC$,!^$Z:³HD=|eVD I)nͮƢ-vXھ: e7.+'>IBrS<A78٪xMY*̉ a͹6 A8aO|.tT7}IRJS3gGT$3I8?!&Hkǒ vNtrĮV;䜟ӌ]yt0Мӫ'8,DcSy[D]œ\G+g#Cq2xvc,B)v~=zE볃Y26p.mWp#SSy-Fo2 vA"sږGW{ljƦS<]K!0 ?q-8_QX!wá])f D]Nm_]^LG#1e07 IDjJFa^c,vFxEJN(K똥Yw}`|e?-G̡pa Sq1 'gɟbyx,F8q2]9WV$ڱHn/E3,*ێVU>#E(5NN T?S oBzj3[:Q6DRC`ZS\7^"0BNsD O`|!S$/O{1Ei2bzE~~k<Deg3%bx]W3|0gkN /8vi_%Lx` vW<~I~Ѣ5D|L+cرת0  a쉉 9#xa lw~_4+17!,*ŰVTzcB:T|X ۀaޔ5C Ů?AzNq `QB\JE$r_\LCoz JۘնX.} n̮Cx)2 m3XEoIel ZFdbmX\IdObDmgX)NE`)/s)/:M"IHW$WfN\S H$I$c!h&(M$$ԱԱPl&IIXDvA"I"i8aaaԈ(cbvA"I"hիP!(Ν;5 IIiDY~_e&~Ÿ6ADD   $$  $$  $$  $$  $$  H$I$  H$I$  H$I$u!=unB]v~|}r|9ciͽRSpEb@S_ų ĬgfIQD"FS4\c^CE%F#>JL]ƨT0EN$Vs-8Zx*F? i_& "K8W/j̭ݧ-Ú%Ŧ^ꃓɹ+Y+г Y(q=,#59 L0)j1>kʝ0?GuW.nX\Pm/x\SVZBN׈I#eLrep(vD$dk}V!W6B,,ǰcV(Y kc=vǦ0wKM>Bru*8w N鋲F"T_8;S3p7'v`^0:_GoAZ?'_0Cy{pGԂ]Ũ:ɴf[tt n­;xI,!6Mm\GUrdޫe?䃐pbt(Vw ܇ue:MJFcTU"Y6Vsɏ V6ip> PǪ xv 0~a0sYz4 +Y|?:q`''5e",Ys/U~c~+nbfs`SYN^:W_E'V}agʕ\NH*"j~U0?R7u`9lUkG!ŀ|e, CB,܆!mDӷD?Nل,(MQD&isyq&8Q+;G|1#=f_ OΜĦ;v%wIQg'1rUUfp X{ .k7$ ڽf\SBme##͔ \Ik;/%]Ow])gs]8^Wq7vUkųD?b1_].%}Dp|zA.&B/|>hR}pBQJh`w ĶG\)ɸ-'e1OMCGLz9@_n%E`a+le J l7 `\O;X̼ YOOɔ` udQaέ̎.7F7kx!"Q69;S)x>鳋Ku̓eu5  hVŤr@ety6΢["^} r3p=Y.Ƿ|I_"xI4([榰rpˠQ3_v5m߷˛uW=')af[;_sCHWOم)ړRnXSOZ%a&_}FZbز㈈exGq{r+;0>ti+Cϭ 164R?f2Z !Pɭ0,M-Pb~Q>aPz5-bևa0(39ۃ")5Y' N*T$y2ݎͰIdKA3e!@cN "liL뼳D#vKs.bw|>T vD6\NH6.&6Fs&¯_ܓPH>YY߱ץ4K(mE4fl٤[U1xJ`4EPw9wVitQ69;Snp$UJaZiV/ a *b"X8 $&ZܓI$? df0]nKۑKQR=_\ojs:/=q*e5D2|e#@ |ct>7Ow]zE{BU m7"*9o"ep50Ye#14ap;K|i~^]áQQm#,d@WK6)s95]]Ok]Z2E?Û͘si}/ϥ]gew8޻01@ݺ;.k-@E)[@hZ d<"YGwd_(}jbo{N$`+>ppY=u*{1I$dX 4Rtd9j9bϱ9Tҩo #Dpi")} (t]W;.:d-eVkIIBERǜtucdV>+x"LIL`2"$+V$F\aHR6yt_=\\Qn/!ßparYl~Ƕ6w!ct=yu XCQܸ &FcOg;= CeMh[8󰍾֞dX#T-\S$Éo^I̸veK~Dܙin&x%B40Unc^eFkB'K7fiyqq h,p׉ }EY?pOɞq 4#Gf+fZZZ{=p!½GyHz s}JC ߓşBnS9v-,عRԃ!ɐԐ?X/s+\' @pLi UbHplxY(kbsx7dILL^ ^Vkxo;%F_l9ÇwalTA]c9 kfF|V%|F%z[DR6 a@m\S%硙7}fL:qU&`ˏIQxGJ燣ǥnfl8,ѶM0G Uk}}]?VS`nXo+;C ̹p^5$9g| >c m^ɽkJ IĝC8/e#9$ {L"]8ph?/ 3_ uw]h+.ưr?OKUiLl+q0,۵\5O`9ĺ_#C(T߳%yoP? G8?`}1~]c(BR\# ĝmFcѦ`o[+$Ж!_/$OLIq  J&MG୘1Hd6 I:`+Eლ_B--Z|W J?W坘eA3'vyPI?80uBk \C徛Hmڨ[ J ja>2z˷Sx*?h\\ %V@ϵM}'(|QFhкGS^U<0ݕZijL|ÎjJ t>1am};"yx}ڣ>JN8{q) )~+[B ibvssOG5lblhi-Yx@rc^gfLc4oE^n eN+m]Ht^|ҝ`H8 yKTç&at'uw cD(8v-c#?ĶEtniub> VVj{񮋯JJOȥ<%JJ(蠂&7|3]L<.QQt3t#Oҿ&B fbZ(Z$p_1$Y{ v>cĬUذi-= ^1Y:ChyQX~6q{bҾ7DRw ˨Q)N^ؙa-Z; Fyx km2NJ((Ɛ$""bH鐌  (y3RvvEQ ؛p_b^vZcܥZ`ʩg][(y-nnaj}5T/l6սQU^x֗hL U Z[&妴cY`0}G c^>xM(-r|]Jy&C9c w+Jczfpg09d|<"atU;8ԚaG|hR~z/k%|er#mwq5C!C2dԱQP8Ho>$չ +>q}c.bzcW(Aikm3VZCaɗHc=ܛLA4g U8TǠf&#ۊ۷a&kΕ{`J/ƠzCK<~XN)Bfo!g3?'I!i_{]`eSOljbbX[D:g4V.kM k􄤪 KW7nZO#*UEkίyQM\aUwLBhFǏ%DDD ld.*)tFoaѻbivT(̏o6=jŴ@Zb{#lsZ@4+QV\]&g~(*vD!jWܐCxU3HFiJ5}CQA*pj|-88@ea֛LcG7پ!IDDĐn{mU8+Q \14:T֟aKH愃\>[zJ>< uBh<4O\wsiKR/j*tX'ݣjMi ]0zA܎Neɨ`̯FCWq r}2tb Uȑ1H~a~DDD {h\]yNh-? !, U쎊N*t&NGs}RQ )S* 5$lg3$Rۡݚ t#mXi0BUfCr'T̰R#H6!;ASuV1G*iu}([g'0JoB늢ǡ[+UM`*B7Ad?~؛D I"""qɣUhE͉_Y#bO)|5C!qYk8[+1o$_S]z(D!""bH2$7],nS_ؙEw ?DDDĐdH1$DDDD I$C!IDDDD I$C!IDDDĐdHnbH2$ ɨ(DDDD vCRruDFFr """J~bH ._ ""PZq#R""""H$vKǥKp\rPbZ""""2O%~bHQaHC I""""$C!ɐ$""""$1$!ɐ$"""bH!uK̽ޘ3X=b&4Ņe>$C-Gdu/g5>}L v*u_q:3,1$GIwTCG9461 I""""\/r[Χ-FYM[c9t-cH1$- `|z 4wn[5S3L;+rAA'-n(^&/<ѺEqi|ގW*|(Q VC2f$nkN&2_ ~K!~CѪRhY_L؍񜡉!)!woԵQ|ŧ˘ʼuzc՜8n\"D.36`;/KYCUj0Kn.E<(z,!ˇ=԰c Zjfp3Ɣ*#![EM~|4lvߍ OZ.ΥDDDD 4W _Z*RB⍦kO<޸rW_x) ˖t~#\Tk@]HDX,!Unz&ힽ:DDDĐ̊,4R+QnT("UmI= #̺gt;z2/:=Jvd_U!G(Vm_Ť*i=g`"""bHf^G&˯~Ɵ akP0অRAx? 5v!r>.Ħ#$#|4e1~?voD,,20 nU}2)$Sر}+ucbH䈲P ǃSimFa`o’3|;351$3#$_~-D{uG0"Ko T =*Ǡtd(ࠁB;UsM), eAC#wѾeO8`jv3q7p*5bl6 YB 0L,gj"""bHfժm""""bHC!IDDDĐdH1$DDDDĐ$""""䫄dxx8\ׯ֭[DDDDdKb7Đ\t GDDMDDDD&N{|2CR$udd$bcc( b7ĐiADDD6~bHJ!).ADDD6 I"""W I""""$C!ɐ$"""bH2$ I""""bHf0$Ϝ9nm&6ٳgEH we:ub!!)V;ǻ6aHfqH]b0$ I$C!S7CsKj{2rCx{XK"`H2$PHĽm߭&Ɵ`=qm0b-ڝC?}n(džzC]2ԣ IoF9rBc\^WC}!ŒB2,gԯ ^`H2$b'({+$EF^VBe&? Izp[S^.$+NpR[D؁'Jhtٸh/p}(nQ8 uQ*-BrH ;'6n2/t,郏JS5PJ$G=E3$ߖGF| ._nDiHE/7ؾ,tƤ;`:Ѣ ;H!j3VckF_ g4u /̅ \ `ږ}8}zWBP1,|D~*vv`1hm Cb0~W)ɷ-$_”:*(+3,iLhoХ9[<ÒZh?[Đ4Y1Vq0O;{<~=f܁(. {qtJ|\dZɐ|CRHkMiU0bq}(鍂np偼VP7G/-$^ߵ|!U+(jT !MlPzIB I9& ªm)7F[+8V=/8ToYv(gN˜zФ7&ՄJ"RՉաRGy q'eBH)38C|zC2l]}wang#jV: VV%;=6vO=$_9M*+T+-گOX_D.\~z}!Vx$4o?}:d'Bfo٠%'YHƟI e?4E'_+D`|8N؏lLBR#q. \_Xs/!#נ;{BnƝPS!~.\*-|gۿG Z%[wbW*?`H2$~Z: n^Ѩx@CX0\ViK><6T`BDZ4ܵ@qTpCǦP; ߝY mD褖qs' eayR` 2wvjVJzAxD$C86C!dHrppppppp0$ I$C2C8888888޹!6C2Cٳ8u6wfy򄈈&$Ő$""""$1$!IDDDD I$e<{,<6gܹs?cDo=K .լc/߮_?™ IbHC({X\W]ryu0Oi\4|m'd&*V[qt!8hd9B̼C㧱}Ne)ęE!K >+n?i?o1$!)EٖX HSZuy;c&SB2Mï)2o.nkL\&Ifo]Hx"[{p5E'wFE|SDU yUV{#1YpG-WD'Qv߫?4&.|{2c(.b3A?HYL:,Sn&N$$s~(r GR ;Ƌ|5VKNcTtR|} !<>DWk|=[vǾ=s;z'[4*T| X㠟PFg,/Æ/졮; Iȳ xmh;26)32vA2QBi•s9'3NO@:Vy9u|댸McapҪuE<](ʇoc.uӚ兦P{,gHf,`a3 }n^نu~A2Pſ!sv&>ɫ:mt3+7lĺS04n'[T+cҐT/wa׮$]<$M!ɐ$oC1Ƀ]1Z;!obL-gXFc ذz>kt/K^o:$0g#niq#m&nbaDu'XٗD Яy Y9xQRHBpsղ =` ?.Kb߷T|_U*Tp"B餅ֵ(tόj#qjSrvk Iْ._cKLuF_XC^[ۄsO1CӊEnBee~_fܰ!gp{^TgM( uº,O3.y~WC#BǕQ23lT (P~/,>A%rȖܩjzCݻb_<Ӻ^\V kᇍw^{hd_R*X{^oتB0]HZ"C6Oh-M"|#&iPSҒ}бFVB[y&#[C uZc_tYqKx](nQzTֻyZsZ2 ?OކN`a&m+|aG0L\ _Fop;!IWH<;$)RѩZ-}>8GxO,~;[|='=j6J7 J)wa@CT(Zc< WvY爉˘& F eSDڸv;FߋI!Yfԗ]WvPJ .wA''1,ʒ'}RH @VH]Sji^sXp%qbXZyQ8g?BV A=w%^dlslBĩX%{(cE?'< I4}7`VpW8㣙WvW0+yL?op4"v``y{n:gu\"I_H.T6Ƙ^Kyz 5co?vG*84[;ϓ^ F/p;/ŨO<.Ja<ή!{\`춡/E>@y$႖xod/x] mW㾙=\VNVp&4 "_b,ȷ6$_ !97{;gw`Wbıobqbx }(bq~le]fw10 |"qovªU"P96; >_D9aczeD'kԟvqElWnjTb$[B(b,OER?Dww3gʎ8/yyD垭.*_ 51!&_].Q: W%݅m^5*vx#ᾧF886*׶XPy̼ó' "B|>4_X>Bb)?ǞĈ o1f>+K`yk(}Ly /eKX5ίƨ.p5fB9$-fCC'eHx=q'JcϿ{u.O&|t6~YhUۆP˯?Sdpډ1d،d>8vaMwz%y4^OԕIRˈ2w[1[KzͿp!9" !"#>” ?{#!'K~Q77M5 GN%jura]! tIQ0uQd ש=1!U|*x@m!?3J(rJ)/jrX}<[Bɢat*z꒽oN <6F IwHB);=lm!:dtKa#05ⰴn#W&Vʺ%?{n!$sV.-v|~Pe4j[HêmjnӘTW"F*.Xh!qz~wcnxGNm^(7k;Y،1]]h/=/򸒅P~F뉔BnK煐 CRm?CQ%6`a:eE8zA ' 9?!0 Μ9{ObKSqy,V6(s#㾅\d6$K!rH ŕh5dr,.ލLmMĩ ABc!i; Q ~B2g<֚y̔<;*wLlƤ+ Ůt#f[8Ǹ3n1k2_Hlmr]g`끓=ֵ&!yPi?Œi݆D5æV[ ItꁊN*h1gu Iz?CRٝo02·ۭ}s`%Z;sVmFI8 zflSji&B›\m>7(? /}nĥ:u87VxhbdO,S ,+[%zt(J+zc!̇deh@~R4'(*ZX*d5:+=l5=,m 0g^Hߟf·r#NJK|搌eth97:l"4m?\*Z7!)ۄAYJ1Xl>G Sڎ\ZN䤐<›y;p4̇I jl(ôI6z m}jqvx{(8hPfC޿.t]ϰ61pۊ9uZgEš9MC2v:>Mk2!$(g̱w5.s\luE`{PZ%'Syh?=B ?? aS?ލ$:c!YAj·3$x69r 3q KG\Vp,cGH L}&L!>ݮ.6L\; * |̆@GoYqD|J9[B+i rCq 2p'<~A!ވKf$aC)1~زn1& k1GF~|jl̋KoB&ByҦ;vcv(QeߐbfرC&d=7<+PX ;wox}8,dnNoۃ7`]җ!4u"o ;pUI!Ū?aӮC8zx7~m8 mƚ%S1EIY9A.oCr[t埜c8$kÿq4<= T4rRί0<0>1Ϳq:+"l.eb^WC75[4W6cp_j!8iSj 73 {ݷ!x])q%vZ){26dDL=ҡ+"ɢv˘'P;5aD.LI(F &se!Ÿ́$e 5lD Iz7BWb5wy1#}{mBR#]\x>[VY?;w'7fi !YR-!I!b_r OVlp $1$L6w1&E_:ְM$_CR\U.Qf:Y:ҰGg3o}{ o-- ",/̐|=FOQ+lUJ»AwLK#Đ$dֿ}`n3bHj q90z3CԂƐ," idi$1$!I=C}]")nS,^82_5$KHTzՐRZRuZvk/ƽVTETҸXӸ;x99  jj j J >2ј^iO5VIMV[jRUte3nYXj@ƥ.bC~`ca|,-tRJҝ*.њ#=c`'"""WbSΪ# ǚRUlJ WVj:s)_mniؐX,t6Y-I/K]--`eYXV10IDDDDWCե2ce͌K }eK!}+.5IDWi;,6RI*nwYLdiO1|dK(I[A݊412(*˂>h%>RÕ," "]Jti!$Ii²Ơ-4FqieyY`^2ʖ>zlUv!ƥbC~F\Lw/[m JJcT4 K1U^*-[(ǒx4.4qUv~َ5"ҸJFjG!?PKcJL/4l1*JwR%d)W^iWɛNJѸ Cm"-EԎbC~GJL:˖N#[BY$* Iw," M""""<*,F/ْGc<-#3۸9JLLt,(M2IXC k1V*hL]t4&RƥEWIENDB`backintime-1.5.4/doc/manual/src/_images/light/snapshot_log_view.png000066400000000000000000005122461477034762000254370ustar00rootroot00000000000000PNG  IHDR4+9܍sBIT|dtEXtSoftwaregnome-screenshot>HiTXtCreation Timeпонедељак, 01. април 2024. 09:29:25 CESTZQIDATxXTi_`CDNLtuMD^UWtV;10BAf? 03Pwョ{y9kaW!`0e0c0WaR֙!  %s|}@j_0S-hyOG~m 2&:Dg@d2Kd[-촰'  E;׎3 Of,7ĆClL2MC2E"SdB*(G   ~:1:,qԒmI)P   }qvl]2Ɏ蒛bP@hhȨE&hKLRRE)(CAA/v,~L£-9F-6=6ڽ5F1zeF;L+N-SіZ-+eʩ(\  izu_6ҒmQQ{kSIAQiQ|k34chЙCw =URћ}  Ў{k jB-6Zb[9MM3Ӗ[225]G bJdAAA w39s!.NEs,54By̌>qRuկQƟo߾H$HNNϟ GAA@rW;͛DSBN&Ш{g Ɍ*ʕ+ҐD   #w S?gU5%UaHjԽ4:ͨ d gϞ}J=1AAA|wύ-Ѫ~y>$  C *qԪxN;әn)PU7#qx~E  32&15r;EhJ;SvY)r}"Aˈ>YѠa,]}C_p^^ĊAЬC A }4 C:7'Omz"x+ߧ80 # b7c;&߿>I^uvŒFį|LCcbȑ3rigjg<~FY%7At! X MV,qG#lm[6V4쀿Gid$xQg4ktBkL+q#&:Үe:ܛc:k]h/}{:Z11[M`T^͛C0h-1B#?+S./- VHΥrarV6O`dw:ƻъ4}cL.nܛ1=mL9 w? | friGABEh\V38j e`B "'DɕCX3{$5on=adB ++N?e#щwt}GQ;G#2w>*,ᩐ&0dZF9]>ȰgDs CW#&x*ӧBf{gf12 ; !sn9D &|>?yVvJEo,6VP+X͚˽1컇CQd3kz63)gCT.GSFOad. UPA4.NjHwctDͩh;pw ԲKhhό)T#w$i,TknDڇh6BsP%4w E8 ʿm1{MW߶sV@5iWbtVm;+B~gG# YSŤҊʦIAErP`E$sap]&0A,V[eهg83Bh-l*My<1.Exo2=T{#9x/?Ƈb L]wYi8Z~,0C1fx鐧yʙr{6aP#23?@8W5,4sCEL#xy{khr {St0GCF:Fh׾+w]}]yM߯Z޽9&D,};7mTxX)Uވُmм?cHh}voɵmvh# ,[aκ~u*zFbwD I838;V@{=ANxk;gchזhfm8T:VMq(*ict@sφ7F΃1cC~d@ 7N)_Ga2^h6<>ec{uENCV{CBUFܛ™hvۋ{3ca>z* nd J|I-"nN!Qnú#_[c1Xsፖ|dd/#:͗UhyAֳp =AlE.B3\"ڕtnM gAĘx/clðcd3e؊ <-3uٖJh~תttBhtAS $9D-ЮS'k.v0[ҤA˗/s-3eBSA\4z A Wt!Cڢȹ~y։: mό)%4ϵ GAA6nʗa3fFrZBSF8AASs'ʔˋ[vShu M    ~4>qW   ~"q   Hh   ~FJBCAAO 4UIh   o$4AAA@-O&((AAAA ͷo@AAQAAABCBCAA AAA AAA$4$4AAAAAAAAAAAABCBCAA AAA Gƍ8uAycj m'_x?/j?1  Aj m; /knz Aj m;  Hhm' !A A$4?{X IAĿ\hd ӷ+^Sq|)-v+ZwG 8_AYKh7]%Ci߮'=(3q=JZBCV;AL m9F0E8[¶X5x قpEhRpV㍴ ^zb_ ^ć~8HhS0Duļs ռ0qyhZ|>,ńH}I_a@Y>f Ux/4. [EG!oqWOofDdubw7p6OmSoB}b[Two0l|mfXV'1vAb͹98ڿUg߃J?ҋւω{ bCV^FҷB#y|O 4C1iZT0Vlm`@hS nMb|#!j6WaW9ĩ#سC&W//1bix]}'OomÜ&J\&l05Cq0QBy;sPx} YOŦɞ(bGyC<ѕl ^6BՐx#J`Sw,yPg6_C 7\/9w wclk*Mŵd]jOX Jb=`D\r/s;1])MJ`fWⷩsw}7ITˤ!h35)P9V/%5qyd_@h5Hco?uͥ}8^G hS sC Y ]=+f'R AP ()Ij D<(x$vk FE̪S x-R E^T<99)4@߿6-(r]V|.VNyKBcBe+|]gH8mBҨ\ 4FZ_#vcHi+Yڽi6 8p,Ugm4IƘR\8D*NKiO6i{Ҟbc+gTv&on>y;&a^?"}5y6;ɝ?Qg'S|}rtI 3ACL< Uʗ4I{ )E-mJ!b]UO[Z0F5E=u@A'~z>~#GEJXTK UpzC8e1zR~c͐ƨl '@Dr:a)`]¨;6>3mCy۰9^5x+[`+6v"p9X쇃qR5KyOf=!++ai[f(R >Fz!X޽!*XCBh[8<*:0`_6bd?;4dO}q8Jj SyT(bvӎE; ju 铄DP |{{ n$|Kη8 `;7Ť5k{O"lpx˃yrh&ԶI *4qP6'Pk/q unSҤqa\ nc,W'Ϲ|ŹGyfkQay$eAL1 "WNc1y:z\T~}\M3l_zpaWg4;} йq+9]hxf"~b 5c\2BF$ _mI5L*k)84.qLQ-By*zŘ6B{:B|]mq#Kɺoﰮ%ITߨa%~n/}fACX4H 6QaxUwUb+vn+Fղb^/3`LPY6|x«4 $R&N=r$.+x-KSq12wf2`=cÞn);ƨ=pO­R3Bo >}HBgկ䨄Ƣ8lg޹Ag`AܱJdopS4q$䊁[NY; 5-9prVQI _ -g 8wxd!}{@90wb]ȴ[4~n"A'I#_mЈw~/׶"Z߽H3p/07\si7<3ni_ ҷWMEM-"\T3_Y}>[kϯU[x.df]}?O93ݜ%^y2zr D\O)0KʹY.N"UؔިQ!>+w4YOW)1_ELrLмϡn&a~ߦ c]J+`ҕ,ˤ>( ~[2ܩ7qO'ͭH|i=L3mFGz,Aq$'Bvs*1, 㱽YT쫆G,_gLN\hVF՝YGϳ|,|py^X(VeĢ=-9/bi!Q#(:2ƕzݳ t ͇Mt\h3c{~PwFLm_V&"q2z jB#:ވ|. GZvBvޕyj'ڿ)^2 !V]tu2\y8H6x+Z+,t*sy_<(Upvb jfi"W>H+|c U/<`m>wuR?#F<GF xǙQ;jcSZ諮,~ Wq&BuxI? |X6Y纂K[!g/Y,qO,s=sM8ݝa^c*d&+#4E(=n1Bc^E$4Ŀ<(ИRhрoN(%`8po JGh^?q7eO[lim^@})gķ1 p.V;6.^hd1Z!裏%gJ9@*)6F%Јo/E~Ӱla9Ѳx5{`Inิ_~p<0 cVna^= 59puH$-˶ĥuG緀#8\uݝ?O]@!t` jp׺&qJc8x \Y-657l Us/ iY*4Gpٟ}\ajV T)O G۞Jcu{chte^<1$'b9Zyh*Aėpql_8 ]Uߗ=)AץGxzFf D\JbLR/G)^1~]zGT㧲&#>w;|l,zgUnŒV%!T´kJ!NYKwع y09/}H)g /ZpP&zǴ]:+ gl3ȴ>,qhѫ kPz&9UU A "8 #i9t]|NaDw8pe:n!&>pnz6 *k X |nK31DeZa8zŠC0=d MqABM J+rE%t9wGO#4'f\NcU_=wc|Ǻ(h xf(W;>U|g#ө:\,x01Ad툒U:`bо!ڻq2p!/1E=N4&/[ M-U}2vۗ>LlYE<𭊣vŸ^+`k)#CKmh쫜d{c1DZ7I\*^V 䙢p>y(!18=,۔qW!43*,˃٨l|D/Maͯj*IdeG|f4mm,3./:e AĕF9>X xz&ZV8N0t| ;Ab|K­eP ){dߟ paT#|P|MhG^<N'aa[,aΉ5E|!*P^ʄRhv’>S[`HR^QԼ;QN$/8b yTn9$5"/{7Dyl1ߢ0选!-MunEoBsb紷Y M|$EJh$!vmŘs#AzQмױn=P E<.Hw`hcPFGx~[ mR}_=J7=Aңg)#!A$4$4# % &Ӹpۇ:!zAP#Ԇp-j3|"d(V_ !GABCm;A JAY AǸw_@ۿj m; Ϳ'XyAyoj =m; AAA,$4AAAАAAABCAAABCAA AAA$4Y|2AAAD~)!$  !!!$4AAAАAAABCBCAA$4$4AAABsQ$4AAARB#~)'5$4DCD07Nv3߱έRvP;?$xvs@,'}ͭPc}sG;vQ ?]L22b]Hus\1VZkئad?Χf]Nmm;nS$Wdzl^GuLW}ɏ髕h((!gS _ǪPZ#*smY<,!4Cy}e#%-vEKV[goLmc?5Zǒ,Sv=xa? RE9m1$5$4D!ې8 _}ZګYW\T sj~^3ZU!tgwy)bYaW_7xο/#_1(oǎQV+\6=B#?GC wgXAi.p?*47ž4Tk9Y vAaNy/7v[JYsj]C,q[v㎡ XDF"__R $4p=zAOpO^zJfRG|KiD\E"'=JOA ?7E o!SKasƳEÉ98GXXVħޘ W5~b R `8Xy- ,Sf=q}Z0#sIh&VXXA7Cc$ ,:շM | \KZȇSut]9e Y~JFȃ fr&h}ѶL(p"x+o`.© ZO:Z_,w@3WC-gs̊\bZcչU f:G!rpE ] >r]q[ڠcWNwkE +!.m9$9̩bhK&1QDgkcba3(x |/qIMp%y{L’8y.'wE(52Pz#X՝ $&0C}x/BZ0{Q2 8Gr Z2/bq*GWeFzOҐ./^D`WBי/_ 2Sg|=vOy+-4:[Th2}/.?Fز?TgAP_>Q׋h$}Žax^h$/u!p`ĪC8}j'f5sHK/aތ5ƺ(=gj 1qLͽ@[něxīdIftTiG?A2g#nU /Ȳ= SJΞچI8ؼMK=, L l l{OFY-dY2>'1V6AY&}_TŸwu|0ږj|"#qQdiYaL.ҿ~G@7gTd %?e|C($hh^F=4YI_+Xv×LBwlʣp4@ՍL!Gi郎TTHcG Q zG]N2)S4_Tdy ¢,ֺ_Mda_6ʗҜqa;b}J95#=12 eG4R$Gg5c1di2GP &eP@k\ e# ;oBZn^IT٠_z:4F֔ #8\Lq{bGk/ er%4)0+4cl[Xط-dnL2ỏKzcQHW엏sK˝P|s7 M= @'VL2y:C) +>\^L!4נ8x&.5SZ~t6zcR'a{.ׁcU\u_ *z=р*†v$boS+-I_2tMBszx"Lݱk:*I]b{r Qttpzbp2_V(@8 5ngY" FhkD| Inc+EG]qi1q'$E`e:˱$wu:wŽ.k32vab 'i9ڟܞ(1c@2r\z--jB#K~ 3J9S ?>n=Ç]Z!4Fl6a^g!k}eE'&\FZ809)& Clj G# F3 —:Fhld뭭a/6s#849|Agj #i}ɖ}؄fL`aߗ;o‡N|y2/u;9=>c`9]%sr\!4bt1<~{Q.V墼1; min10p M?fS0oF:'X;}OzL ۀa,ed]cN[:Ф(LsH9ӳL]Mmhg3CoKqQf5rf|?.}!zO'r!>qa0bٗR;wn1rFlYqH ?\1z R,u+q: $T!x\>L8<<9-8vP4g/1B'Ӛ`;xq"٠߉Լ۟C# /;T #Lzh~ t>|&ɯ3h7C/?(,4쮅bc.>/x8 2- EQЮ#O(fcDs,+'ϖ뿟,eh=i]}T~SldYҞJ9/"J9ԟ?/hC+M&;Yh4URpo~-`Qj}H0CA2|ϫ ;_"l-z `7T^{lkmBclT ZBҼxcM] :>x]B3$芃Iz^,ݰNh;bh@ցETK]Ig6B#:*he8(\ٳ \A 4쮅14/WCh6c9A(n躱.*μ pDؼn>"5%!+ڣ3 `ށ\wܭɧϛi®3plE564iu aQdl*{2c4=U {B2,4i )|rg/"^#6䀩W04xЅvA)6l{%ܭ!OQ~rl[>1! hKzq|- B7y*g|q8Ts$ƋvX\ u3Me0NBSy~"c0b lھ+wFE^-e9!S_Y>T\e/=%\מ?i>FŶҮ@m3w6l߆U@Ukca7f76 ͿjG1IiXy0s3a@Ǭch2M|nB3Yz)HuomP<P~WLz 9Qg0 x*)"UjD$1tAn qze{iE;G~1sDQ߸Q#sm9)+*ѐ5=kٜ<4ԝBat6Fhrr\F>ӕ`k6uy?'jڠ|3*C)n{0p:vFY`{ 8=?IF1.+݃âW'7lĠZ9\օ&C #FAFx|XxIkZEk2|l$Cp~㲸^y-C״*ۊ5Ծ,9ZUoG oEԧ ο "|,^pȢ6e) NAAА M۱˩$F~!'i|&l1OAABCBC$4:S $4y,.ľ_\A$4$4AAAАAAABCBCAA$4$4AAAАAAABCBCAA ]l   !!        !!        HhHh        HhHh        HhHh   !!  Ф {NrP2/1섚ŭa*D sde$x&uQœ (m͇ϤtC$)@(h~}0u Ϲ{K,o 3N.0Q`߇g}0w $鸤oO`XDroH 򂊘qKYMs?##-\%I홮Tn%Sy#c.ʡa^o Ks H8EDhV_ڧO}++f9\l9?ABs _<ořqǪĊ=[\ZB"_O~8x4J\yE#nhm/bL)͹U ®n#ߧľf66&!hot\*V}c tfu=, M6aeq8MjJm8v8[IMgѹ#ӗ -e~Y!fo'ZĖ(YWy@PBTB~?_ŔJ</¡{ |MϘ꣍3PO;?xq2^hZcչU f o8H3JqJ[6B>Dh>""zٻ3[å"nW+jOGP|<;l!8\ zdE:pϙ_II&VԯaRLtc,Ͳ9J!,=/Xy`4vǥKhiij+wu>^[) ԩ ZO:9g6\R%fXha[+>8]uv* PeY]5- 0AF 5ĒR.|͝P7Nxa!HX~J 2mKgW7Ch] 5WiZmZEb,k|U s9{v2eJ~60R_)gk)CU1qY .c3|bu.Q8X 3tz * j|=zHߝS\lQxY?FYYp?OB#E!(kS)*/ED ]lc J>dJR Xˇu%]|'lx̜k}̮*@Q~H]@h_V"I |1uTZu,Hy>=6>~ϑJI!wő-'5墈 8͂2[{Gf'hQv)_#W }N_ep_3ű(-2IAZ<^>zU=amE'#qo"xNh!ճu"^ċjZxؠbt s}N-#ik1$,ꋓqr\+iR#U7}~=x?t0G5/3:F9U_RmtTiG?A2g#nۈp,m~XѵUPur +aQ} Q'!O# ̕;w&mOGF8 '6OiLaZ3m#e5=ʼneuQiK⋑5틀Wn2sx.a] VŜ0 {al ,"l{ͽ65"_Uo/{"ȗգ̈憦 IEuasהM8փ ޷S4˜CÞgq!lc3iẔA}m5k*ܶVXƱ)g/x{w0vOHhɉF Sʁ_v2BTg{bd@?|x7Nst=U!Г Ps#HdTw> 0imoӃAPBXK2M`og;X،~%!dF5 ǎW۔+SPɴdѦmOu_KЈ/CI/z/F{RGy^c_˔K#g$D?IF7ӿ+% ˌEXgg(-acO[^5&NcȔpu mB>nB7 @S=m!h12YDsfvEBE4+H4gnz~8C*۠x'^hW0愥_L=J'*3ۘp%󽞽 SBULf(Clfnfw"|P|6ǟwDo̱L "{&`|Lq PdqZȬ;RrϬ#(rS+:fsʙz5Θ5)2 jR E7gؤF5dbD\E!df?_1)%lɉX-z#M񷬏XL$@B5pMX | 7-.MɁNOܯ Mjp8+?"\w'1gTpP#c.kiLf>J~~0EKg :k]mh%!e9VMn3kmK`qm^3#IzoLv'CҬ;DJ&y`k>gU,8p6wTԀ __uŗ!3o|xy1lRh_x<KҐLLׂ #>oLƥq=_)l} Q~t"F>F53qM9cV3F)ښ b Wi3|Y MNH^p0ĚR@Ym.2mgSy֔3:*]Èk}RCam uAzYY,CՍǞch񾉒x0 7=[ K( 'HhUhdq@(x<< U= 6,$اؗ. `@hd'4nZ_95fC-U܇Nfx- r=|T |/qe_lsտШ\;Tn? #I?]W ٌNh/?+APqn$ɒ0uz'LUM`kò) +E7Qe '#ԁ|Q%e\&隢loWk=p*ٔǶ069XOꍩnCs! 7C_hϮ A)%ko c7|tW9K 5LzOXp *Uxw;-iݙ#Rq0YzK蹇X݇6h q|\RhKO"5%!+ڣugp0cH|e3;aYArBNrqx5 [^BlS^N^cP_ w=@ ^FqAhR&R^eNY:gNUczySnEUgE&eٸbah k&5S=cҝ8󇗣o%̘1@/al hwD}llKQИe}š xU:6,w\p2Nۀۣ;BT}/qck9\"սUu1se:l#_"8xbtz5Tw%W; 9x.ǩ?e~[,ug)"7458-: G]EZLh4UlQg&8w['+uUL0t~\M e8p<ݍ5seeqZ=ի a͵kCBx!>Q|s8^A&d'4DFhטN X x0-TO(9.PF-VDYxޛhgH 364ju@|FZ t-)kzր9FZs|?Dph#C}moBL`TBTo‡CY:{'d8;C1s>.m!Nl%oYG Oz?P(d`^3+ĩW0nQ+b釵놢+Njd-Yn"&Fz<4Ф]];{؎Yس^z!xFʿrozT)!pvLBU<Ł Q![ogg7H#-'ë&F0Ҟ$.Pfep]3!Vbq}px:œϼ Avz\ E[W]3]c/&fW@hu3O^==OױEѻ&6bs\l;H#pN[ !C3s5г3lFY ?Y61dcyh jo27Ah b[qD ǏWV|WMH k Jh"sK<蔲燎\07~pv=#% KGApŒ'4-P_0~8i0U3 HhEBc %osg;7/>`kbDBCOF2q}8ʚ̘ ,+8ұFY#v]=y-!1`ȟ[,~xv'.A؝3>쬛b ) ͿShdHz7ELJNdjlfQsU "HAO[,e3Wt"fR͡(۬*jd%ĸt>'O2^̍0s(2&Ks H8EDhfN&n|!9T+,]D;LΘu;&EQ),hZs?Aа~pym3liU5k+܉3z:32Lē_ B#b6nGњ 1;AdQ odߠd3/E^Ě}c tfu=, M6aeq8MjJm8v8[IMgTXDK0h kQPAy^-LǏĖy=P~>UZ]?B¢PwMWpw JhtCY}K *6k0g`=Tv~)J>A#j'!Hh-B{@! `H>똈5=qĚ_x2lZbK,^< (Pq\*k?ßbJ%̼iG 44sDc A5bD mB40^/]k{k)i7~ЈJxUk M&شW _/{ W MdJR Xˇu%]|'lx,Q9 PnfR-WFUHn3_}|)g#OٻUjQ;lmq:ED9L "8 <zg XーrL.*;IB,gBؖMw~yߩP5^SffB#KymaSo.%( 'HhUhB.+ѩ=xƦ(`:b)R}^O#&pi_s仄,"DRBcREkGqd4qI͋Ar ZrQkv ՃfCQʙBcˁSp|hT$8- .KL}saQ/| ѹ]q&80^&)HGT=amE'#qo"xNh!|1z|+CIEuasהM8փ ޷S4˜CÞgq!lc3iRӷY{J46&0<X kck!MV"v@dG ;&n=|Х-8zF9>Y\><׼5 yt~X\ Ye_qwû VM4FGk:7x lGt?+}m} =T|M`Œ$4/4'# :,oC`ހ(afs]7ߧfM 89L{/n܎U Ib-29wFfᗒ}fGZ7 Uճv1d7"ϧפ@x_\E6ᪿK<= ̄L8ǘ yZb|vx)YD㯤_tY*I ^u ׺qЊKhC5vB>DE#Ӻ'ܖ;&5C y!P/N(S K@Fh7=a"{I>Ffh[n RpE.W0U߆caXi~TNUx-'4U9QE4Bcx=ɾLay֔3CP7~.,}W8-+I@q5&y"4)~&g/߬n=$)3.-^i*c#J6C0S)'Hh Fhdq@(x<< U= 6,$اؗ. `@hd'4nZ_GL ͯ 4C_V4H6<_Ǔ%ua<Nǫ֪eS 6[!V~:`o|APGG:j@:0w5 *K$]Sm5^*{ 8lc[k eޘ L3XO/Y^14(qs14iZ⸸6&?а?vKw)(1Gk$O5EmUvL[3=G$=Oa>sCmln;= :"xiF9Eo4M:=Nа8#(,×$e:?9=m8S{ AtW ~yp[6n_4W仯 7VNaUΒ1VFaK:u`ˉ0+x JKHhT"N>MjDʫ)]S Jbs^/BM՞"p+J<3?l\z 105B1~N ѷfLИEŗ0~];Q>S66}W(3NdR.Waz/؅pb,-UO!txEĈ[Bn>W||ꦨrƯyן+ OTGaY z3ǥӫѧ,)gl!ӎEb\ʶÌ{q`*xn#ka_pybͪ#8[ʫ5QLLgaڻ-`.pŀgqZB_$rf:c6Ĺ:]Q嬛v3slnU:cA=맢} )zB17SY0J=#Hh @h/7=o2kq0>~Ě섆_)+*s<4ݥJ3Eʞ3{,ci6y̆1Yԗ]U 1AB%bMp6HkN7vd'OBh5y8.(՛aPuNǞ ?$?P̜ jt[+CEh 3H#WYa>I<Ř\_xfEPß8*cmR(b釵놢+Njd-Yn"&Fz<4Ф]];ҿzݱg C()>G:RB]RV현#yڣN'X3/ߪ(~<;˼Ai9>^ 41<4iw]E2/(4:bA|V jzdp~.ں2J)5Ƙ{11˽Bhsy}=(X}޽ ]-7)P8k|JY'^ayh&DE9[Xa#4E`א$0Xǒp,܃<lJcЬ$cpsa$]4uM|nB3YFg M k Jh"sK<蔲燎\07~/2n {FkKc4Ӄ,%4:k/P+8 Bc %osg;7 >`kbDBCOF2q}8ʚ̘ ,+8ұFY#v]=y-!1`Hg EFwOHQ^ĤDFj\&AO B|ڢf){ǦcW:v+43Ѽj1ؚ3wBv3qF2yu\F02ұEQf)-hm#HhGh?ϰ#8V篭8xp'V0fZB"_O~8x4J\yESw$_ĘRTs_%EaW_7xοSb_3s\S|B }\kŎ3н 8049ȇ}PO7YWu*ö8o &5- #FSa-|-:EDAYJhx0aq?z[@Esc~_TJj% t )^o Bq0V-ЈΆ@PPB2#_Q^9Ұ3{ª|硑!P⸠ј $鳎 nO;ZC`G M9g_h\/ 1{;֪%Dǥ3*TkF ~H@C3G;$XK F0&DS/#5gxv3 $@ىW?8:a2.. M+l~%%}x(x?$4.4Sq c|"@1' :RΤA=QƙyiŹTM)4J37fg8d%- !"W4pjϊmgޝQ.MwC/ZP{:e$g `Yu="OS PHII&VԯaRLtc,9۷&% hlyK8%x 6VX(qyZڢZ rݲrx+V9u֓qrzt1קunoq֊N?q7-S1,.ڠd^bITuK>N;wbxPF_Y? %%}3ëjq؛!.]46PRi1sX5KѪ9̜s;2uD?3۵ء߸,lXmyMVnzeJ5Hɰ?N $l. 2N(}wNq2׋'E*^f}`m>9z=@p?OYlFCQ|S8Tl'^j$88=|S;K/}Ȕ OGJL(}NXJ=ܨX?.[ nB53+mW3_GSnbU(bFw]mp!}PP"wZ14ÅM7hٷf!DY%CoQ둽]/SS4^@h)4aZ$ᘢoiEYvYw=u'icRdQe ,L{ƔFQ2H$_[bT MJA VVGv bбO&qW[?i36}@-cpYN ev'qZ'boS0C`5*0$sD/_&\X<0m@g3st;5:.| <(G#zȿ8L "{&`|Lq PdqZȬ;RrϬ#(rS+:fsʙz5FD,&E,:bv%Lcc( pk+xX?l{htoK)&PqS|F(MatXNVa-&8#xtQ"W~j.c er"4}4EK 株Re˰^O`8c^5ۆV|]B8?l9-t&*1=ƇL=t)4Zӝ u}q"E%4v؝֣ fߗ($4?\h04f]}񥀅&mfZUxDVB#CpPJW 9((މil}Qޭk mwX߄y0"I=oTƐJwT̯.Bu/z_eV!p&F|4Q圌KJ+{}S@E׷*4Lpo6q`nKor1"HYvL[mGph"OZhrF'ּ*gnpi޸qbG?*Q PI: N<θ#Q 3Fb1Rrc|uЭי^[1^)k6@h DRW9Yg.cX7Mt]z v 9,rxZ6H_o@3 {t=DB|+Lж%&&\`V Ǻ!!°Li FrS*'2"2}Ph 'ٗiyXZ{ƾpQBö&;Q`u ?1^J}bgS@ ;m&Br3M 8> ,a_>\E.u}q) (@WC`K !;F,SFN&'둾Ff(h5\ UF߶E΄+gc \nni NOT |NjY(4c/bR=p…Ԝ MxWx\N_U`͹(¯dj[ѳhEʙbmcH=z3`{; eߎւ=4ٜÔh(@^6|l,{h #^$4 ͏)qe_lsտШ\;Tn? #I?]W ٌNh/?+APqn$ɒ0uz'LUM`kò)+/DGtՀu` k@T+EI.I(,j/ەZOJ6eﱭ}zRoLE&șvS,/F Ydĸ9UBsvUM4-q\\|Uh륻YJ瘣z5LzOXp *Uxw;-Qd8$=Oa>sCmln;= :"xiF9Eo4M:=Nа8#(,×$e:?9=m8S{ AtW ~yp[6n_|H <7\Nr chX r!ۗ48ABSB#G`]B0^6gzouabSs&\dSמy͊*gNMgaיs8fYi*g !.*KX@?X1} vUYoɗ0<w`2[05_)* 9ًE׈MΜ55v7^C7b)LMckՌHfhC&߆w  wؙqiOy vnX[_5wؼn>"5%!+ڣugp0c}) y%4*g"Kw"߳8nV^,)`Uk#P  sǠ$zz FE- Ф፼ u}Y(d`^3+ĩW{oÐE`B>K?]7%X=^$mpseOTw15J5G桁 F(qtHvJvǞ#4 0U{УJ!wK~Xcj)Lh:`|,idxFФ݅wʌ#[ ,kY,/WGwX2n4V^Thʼ+y+cv,J}˲G:pHb1z2tޤCU$vBEv(Q#fx>硙obzRv|8b7gQ|:,s)!C3CZh]C~ؖ {aMA Ad`i=Rq@Rqc+FϺ2n {FkKc4Ӄ,%a/"} Z鈿9̼AcE)~{?۹tSf|>&F$4Ad$X?7ǍSѭ)ʌ#;k0oØ V}&_ThdHzU]ELJNdjlfQ)' ER0qMïtĿWhbgyb5gfx HhBCAA AAA$4$4AAA(@rgvB0ZHwUYG kXG (mW]g4QUlφ׆PXS.0QR5v Tn)ǥ)l#,ˣ~Y˱lߐ*hOP3nPQmV52 UZb܎y_k'WrF\9CKq}UȒ%\ֹKpm$""4XL3KvkX3?r%E$4 7Oؖ.ϰ#8V篭8xp'V0fZB"_O~8x4J\yEk&+$Hh$_ĘRTs_%EaW_7xοSb_3s\S|B }\kŎ3н 8049ȇ}PO7YWu*ö8o &5- #FSa-|-:EDAYJhx0aq?z[@Esc~_TJj% t )^o Bq0V(B#:nCA?> qzd0$IuLUp|8bhbͯqefP֑r&}~b2^hZcչU f o83hHqJ[6B>Dh>""*;9\.^ptŧHʳ# ,uGV$c !9@eLL5~ ʘ~gh&gB#yE:gW-aOx;.]B#OK[T \ֿS[2VoJ9\Y6-7B-Z'ۜ;%q|Y]5- 0AF 5ĒR.|͝Pwa!HX~J 2mKgW7Ch] 5WiZmZEb,k|U s9{v2eJ~60R_)gk)CU1qY .c?{gWcOuιﳴ,!Rcl1d,c1u[G$'!b%keKIxt9wT}?ޏds}]u(F}78_t@4r0:|H hL&F>;/wjxB[TonskLf^WIn`[ϻCAʊh[B0H]S6;xŧ_2*9 XLCԺ(W/C:f;fV % }C]~yk. JLИf1*Gnw򇳈N/lY7eP9F5BF!Z;ChQץT\Xah4)bǁO,て0uz؃g*{ce<0vkd ;YNba Ƭܛcx]?8pV֣-΁ӱQį_ jIRf-.=cј0d7W3G+{z)$)8x1Z)((ƃ|I*#vYuQǙȸwaMyF-hw[My0[QȦ!66"iE 4$ - PJnĐX! ǒ%5KffRw9:D=QhFrs|\ 6dYz7q kDq4c!u)Eo.ӘTpwV &>h E0cf>caJ{'ef u`'fa]`ae{_=ֻ8KZ@];īἸ}78_t@C)[!` s֞6{IH>o Ԙ ?o Gߖx32ݍ2,`7ot&@Sk `sAO܏5ZN苰B3u9ǏaƪVܓ[meRqmJ \cj~OE5̅4bK {RoktǾ5&mHHi` GЎjc?us!`˨{OåbS!bVX)7 3>Ghl'Ơ?tNd+lmA0LE9D+АcqeD SRbe[SՃi1cn RaVه]kGB^yȞB@+5'ShPuC37w!ꅝ3>/Vqeh4U 4ZJB-\> #1t[F@;HnK|FV!L=/OڃC ?{ kLǏCjc9CS $ BzB=v3Kay[n}o'z7._IDs~gP >6^| ګהi> S }H 4@n"ƥ5cٷ- I &mf\P<#=b1ԉrV=k[=[QI4?x5xC;]Q`$7)ƥiU7X?ÖK ϓЎ N$AP@ajVcjsz.Q .FXwĢjC&qG%j^zX[}78_QΔ_$jnA Xcx/Ko@f@!.w˼Ɓ(i\x%s! 7ie& _+sO`cʅoD)d@ g4+>_H,_&ap9ECDgmDhr.1-殣qz/D}a'-+|zXŕVX)?Јa'Xb)xmѶ\h$/n h@zc$'N$31g>>( Ϣ; rT : )y}x- y~H 4N\?!:DO䊈NC2C21R#%\\=5~_r0Ykјkz Kr\12 ])%c|9Mar!QwVDJaNYrr bie59?*iȁfO(,hBaּc|>_ +,ДhdYӼJ(l:Džw7L:seMXߗ* `h ~KE!w警;߯}>Ħ@J䡩`!%웶 ?=/엞hy44+[%+uQ)O9 ,o'x5^͑U)74RZ #1_ /π7Kr|PT\U{BGy{iL'tFXLna\Q.*/JX#'ڽ ͱQp&`֖[}L|v"< oLOCp F~CS MJ14̀@ +,|ͯc(Kmϫаg@;!Lvhc2V%GL 4_Hć7Y @ wQpHo"bYVPFF7PsGK[dHsC0wGj?!Tʼ_t@wNY!J|=$|&e@QNхG)9_%Csr'߽}@֝Zะ/h|G9+L/9V0On*@ٚz[OXpTxk0ckH|, bz!>4ov-7=kn+>!KjH-ByQ;4.}h !Ca<>,а 4h|:;U~X1h=S'M7u-Nfg4(gQ\fbc5\S;ʙQơ;n'aHJ܍MKg``![Ci+WYLǕ7pC%iο9xJ9 ؎tEGxSPih:n+ΞCǥex:Ɯ o@9h"r@M* aB8ܬ1Y1/Ě{waDz^W+7"w삥^R4b̰Y6wR2*hQ΄ <{aADߺ|fk%c|]#qth4wW+W$jähn!( 3QQ8|W&2#/&}7:_@AWx^VVq[JہkMQ 7cd6B->q5"rn;Mt}b^ fZXX-;Jssۂc8c5a'+h4v?2ދ:ϭ뇙nh`D"WF|GaRvwǡ=fl?ӇV`,&gƐ0 +GbCS{ $a-dUME ++LFqqRX׀ɃZ=|7!F!(CXaO` 1`f,nhn,;ac6+NM 塡q~.S:ӗwGT&\!.#?\͹05|pޤco_a5tېIm Ss:mst nbӈnNt82@c ˑf.G;#}€Fq9ç,|{#a2+G5jKIH)֨bFY@S|7Мz3Y1wh(39kmT |jpk:7Mv{$wsb4kJ%Meeok L_EX#'Cc- 4APxm$ GB jscT_ /7WnڎIeޕ EGS6Jeޞ_p0c.A=1C>4LƧ +@q@X hXa/uAۯ(E7zSqKm Y[{žkK Ecvh(\X/H3%_CVXa71UDFs.G 53aVX¤gVN_1Ip:. }Pד #8}gcv${+#@ +,|@#C޳q[62^~@TVX)Ѥ=D<1h6g@&q:T |g`VXaGaVXaVXaVXaVXaVXaVXaVXaVXaVXa(TwkF/4񰆀o z1 Vf no* yiM(ប}RʆmD; A6>zkq7B: Cb6+~6ČZ81iVm"y=>_RPQmVn51a F1~ 5+StK7)"hb|^yd9!|2֑sh:Ě_M@YRf _>Lu"3;BD Q;wBX+CԺJ^$}D$LC໵/ɕ ?Zqaj]pʄ6礳RBЇ ފwW ތ ^UޤR_3#Q[_Ku֝OoSW5 >]Exyi' : ǟ' A!Z5 4p9c؀]6cP||Nb✧̸E*qXTDʣ8w"RoP'+d¯H4s;Sls/}G~4ah䥨~i'MK6XQG%Y~0Ue*#7bػ# 3s/"ZysiwU/bb~߅on qfI.C.HhU,]oJhggļ*êק;3%h@wlۆEBīy15e@D?Q*%,8Z@cNu#q1{؛ (l;bcw7IR%}fV8s:cJ!ln2]S\Z4x_=q[r`8 l8 'A%>Hp6"8ivمMgcxz/>À'H/Eќ%|5@~/ IK)o  _,@#Y HԙtVkʅv ?Dwkp~CJ! L)*!׿Pˍ]5 3/uWr M|fjq =~J:B}I4\Ft\T{}oImf2_T/N*JRKn#itupǺ7I2BX14ݞq4l⮽6p k꣓iLzO~~8tc D].5!r Ddjge ILd%ړv|+&t[> :FGbwE4J!3k ^bp}#&h12>17A,8|8Bs 4ƀ8R8Y$+h S=x?v^K1s S \lG).=N23!Vh̪i0foʎ je[`=r8Ea$e{9rO> 3M}}5soQn{1ȃ sbwm>Bbh@RN'l<-ϗ;1ҋmZ7z{g֔8PgTүHzWՔ{ l{+hc+i_@CO r J Ebp, [\SZ$ofm6^N)E'{79Ch$70LJ ^%ȐjCШ<=w9kpAFaA30?& RRrɼ?IX }GoQm@];3mI8owl\k@NAXw` xr`f݅pHLQļzHwwq:>4 5Fw,ôo pkғȣ ܚoW,|  3>Gh;\:DQ2@4t,b4ܚ D V?U8rGGgLLL@A>}z?.T}B)WbD@SX@$d<Ce4[uC|FVYdxR(S^e:~ WωU&gzZ%i} ﱣ&Xtیl6;[dqNz$ 0;Jx1{`^='>U4ri> S }3 4@dٸf :ր$IPLD?bwa9̸bqSvD9+ŵHOխ$R(j|ܑ0y<@cZ1>^(Vq Ηn3[!)kg)w .Ѕb!.w˼Ɓ(i\x%s! 7\m~S~P"> qiiPM&ˀhW|X|LT1@capQgmD2 !e媫@ ?h~Gg~@SH3&Z.ɀh>yFk 8ϔhnfUe 񑽻[bȁhhji%ar-RܨIYaЈa'RZ4OR-b0kUs $>G鍑[Tt2=y,H۟ WHeϰ#ڧjАZ@coMCS14*3$3.<Z…8vZZk( / |xMRz}@C-f1V8^3Jib eGRJ r.5jaCA㞟`Q4sr;~7NQk q?S4u O.4j>3㣖loNG,79\0oq?Hhh, zWIP"[cBp# QGoRA c@!aoi(մ_zYOP>Ħ@J䡩`!%웶 ?=/엞hy44+[%+uQ)O9 ,o'x5^͑U)74RZ #1_ /π7Kr|PT\U{BGy{iL'tFXLna,*b[+a@֞h74FhoZ[n 3ى$1=UEG0‘G4*Iҷ&+Y2aVWE63]b ʸ. 3_OP A+!(5euǖ! Ɓ:Ba&a_Q8}(}Wa vBrаdJ<~s!h 1o^;.\;I ,[VXx#kj+HaOlտ$ySB\r?H 9;Jh)6 ;Dၼ^lOnAͷ){]-`Rf1rSta*QJzn*hМ,Ccpqwo=>4lu|8.lK}7<_Q ScU9̓ msf}@2L%ؚ[}ǯ# bz!>4ov-7={;!>!KjH-ByQ_4&Uy¥_1ԼmuqH-q]Lk~3](˪l\wߤ݌DK!>UBf##{KeLn8\y=2 \Ǿ2c@#ݩ̬|S:ـ?G@:5?hDkq2=+ohG9[r4[þ(gQΌ7p8 +wERnlZ:;ߪ Nc\7gB<ܸ*IKv-ySiv+"<›&HЄ@q[tR?.D,A06nO}3ߨO .AzlR)±fɊ~i'ܻ @-80RZc,E/D01fȲ#Db)P@r& bh\$7[,/`t 69F 5_ɿ&Q D=&F;w 94EYx)2rFx5 x1Lh/*3BXOU_h0}LX{&0hiA蕛u;Omz,CZ_0%И Œ$q'q7_8] $$Á1oltS?YqG^=|n%M>^?TDRD#q2\ɤ+ C{~?XrX5^~Uؼ3]ޟHAæ-XؿD;8S1|hhk>{kކhă{e3MY@#_w}Ш,\ݻb@x;:R΅Ef'v\߃`UOe,а@chM~V s8n&s%d4T0-9Jai^V$`V&hr0e}5l lް=͉̌e'}Fq2hj( sҝP?§4 wQj΅VN +C&{0 ۆLJ1a/(;A@4lĦ-PݜaqhYt63,GD OQDO pҕa2+G5jKIH)֨bFY@S|7 0Y1wh(39kmT |jpk:7Mv{$wsb4k +w|{vAjuok L_EX#'c /J Oueop>z`NP{cm4 eJzdxy<ݽ']uvL*T("?ҶWR.Û+NB[b%r!aR~Uؼ3] I^5 o*hqaj]p Ζ(g? LyBlJ7a姷 ѿ]Tf3~-<[Ǽ#bRU@ +C*o~~}F)…߽Aԛ E_jvkXS]{)ah 0>H3%_ǰt]켳 4U4RB|~hn:f&,а +_+& _DžojzaG|}b̎ރvv"w?`/.VXa= Q޳q[62^~@TɕVX)Ѥ=D<1h6g@&q:T |g`+VXaVXaVXaKb@ h@.hXaVXaVXahXaVXaVXaVX<v&-\5D }(M2 `;} eU V}>}U@qE;J%TM\ %ܵ?ϥRhdxl:c}eV&B$hhB~wS Vh#r }9SXĚ0{K٤|)_q4+ՀDIghn ?7]n*($1ȿ?%=3 ~v jK2*-|o|DzVX@, N>hN k麦>:iLΤD Xh gMW,? ?@DZ$hO-)0(&l4q'K@T=9܂ vO¡4:q{Ղi遀!H+tD6mx$d}jO9qyk"59c4;X:*-jJDu?%v1~,mASp@z,[,r9I}.uN)(GCƜ{:.?Y؅,\-Ys`<##82/ 6nX("͒a?<_pk3F)@DdX]G8:deMa2TVx)yNa꓁(ť@w泜2 JY57 ػ~"Zq48AlKG[.c_1 <|/[\zǢ1aQعof-Pb/ypap "cP|͇SH S ܩq$cRYq6ܖKR՝EzBd=Dƽ3kJ||(F3tlW DpWOj=xJD6ɽA`O/Z'al9nҌTrk%NƢ H8-)@_T76/!ꁎG 4dH!zhc;O`5 _#Ӱ؅K)x~spd^ޟƤz,c徣طb6yt@c. v6c$۷S;Ax6.5k ;<90s 8KF&(ۓ!Ł_(ݱT&^= S(hK0\̹!a4R ^sw'5f03φ[+ÌxEwL  ڂX\8e-c͸",Pi0|N4#qXߦeV`١Tܾ}aۭႴF5Smaow4s!{7ž4FʑF@Wp[c҆Dq1dbȬ.y/xXh e3y2hI*8h4R8&~.i?\iT@y9)G]Y`kdc(tmrV')1 jw wcə=ު>7o0'~<}3SG ڟ O oH)Vl{%S/iYY2И#dWbc&oC"{5AB4 J)Ÿֈ*6>('Ơ?J&^a{o;X~O L!ezc{`Ci9TYޙ)h 2d ۠hܥSKЈޓMw|U c,3}((cY[b_MhZ-&ތo9WBS48xp0HH\g<{PSw)SD_/$5Pzg-NJF} CV>La@ 4\ͽ1 9 HJWZ/;£ԭ^L9Ј`B-7[ajzT|eRuLcYyFgaIT{CpHb{Oxmq(P^mL>'V9`aj!WQO6ǎBԚxb#,oK@m3uDo9;h.pð *A{8W|2|B{JaOc_zfh~ܭeٸf :ր$ID#v͌ˑo1iˌNY\;ߊtTݚ8J !Ńڑ%tj3.ƥiU7X?ÖK?OC;6;AYuMMDc!v  g4_sCzabo|F9S&pohb}g p,])Ha?qjhFW2^1}զ5E  \l )瘖VOd 9f|'D3 4)J"Ҵ8k#tah D-+W]4۬ P?:'N%9jTvݱ g?+^B@A!' [GySn1V~_^\K٩<|ol951AU,а@U&yr *')1mk FUр-I:מgS!ztSXY#(Z3<9[= S3<:bz2 =Vh5G74Ɓ`W&F/\S՚3r,8߼IX}3 чRp-JHOTշf9I S"'R 2ƝDȻR3-?vރP&gǐ~]* h|hI_6XPls3V"UYE39X hdYӼJ(l:Džw7L:seMXߗ* `h ~KE!w警;߯}?!6pwR>&M8 ,aߴ%n)y `H<(@GDˣ^a|܊,YۍMyʑf`y; mJW2<Z~yy_*ДFu><[,Oʋ18YT^ŶW= nh33,{/&gIxczV`#h}U4[joMFW1dvCìm2a'}i@Cr;/=A6tg@m~GX\:}^m.8yaʵC*>ds@iL|h|dqp@: ORxgyGZFBCaOl/ylu%C0wGj?!Tʼ_t@wNY! ʞ`e{vjMslj2@c(Tԣ/ܒU9YևFGz|h> Nb-p\ ٗ 4nx蕯”)#hjftۜYGШLSkI0dW!PHz:rb-bCfz"x3r+'pXQ걺ܼCCRگj6`ͺ8Qø.5?yޫ6lQ= M&H>}mr5~ V#c҆mDK!>aYڀF#S5YৈuN돀3uk~*~Sd{W,|@#rN%h&>}QQ<oqV>شtvUa?xO2zUooɝ%hm!τx\q7T\[L$ʙӀHWDy7M i"9\\ʉX al9ܐfQ \&"ؤR R/ccNw6/P_[p,a|2r#|.Xz5 _ eixY`Jc* ˑecOG(.SRFL³ѸHo&Y^2l8rG7FsW+xjEMo{z`NP{cm4 eJzdxy<ݽ']uvL*T("?ҶWR.Û+NB[b%r!aR~Uؼ3h`t9r 1=3~P 8pC AA^Qp}qx1fGAr \;߻Ba0_+(ٿr ?j dHB? +T"%;ԲU>ۆ[lYh$@'3wO u +,а + +V  %8B 4 + + 4 + + 4_`PR@uyfBkp"Ojm&GJH!~b{xZE'e_誔a4f@⻏ĚbMaHo\Y%K&f$,ǙIH_h1*"l* K6Wh_OY;_ML9Eʋ6%9 ዐ,D%9]%XJ2cXyet7<'-zN\Ƭ@Yh.$lӀ=Uc cvڌCM:5s"3'hcQW+ŋHBhRp "xuK ) E#}ss04FRTDkŦccp[`傏,B\?w\2@EÑo~A9l`-;|XR̗J5Ę #BQoz%E>\6$]':Ѫ XTԙn־C󲪀n _<rT<^$_Sv4ШPm9ă$x&d/$ YqqàW: $MRCvSWPb8{{>|@#ë`k*o_d MT@ChbJDj@#mDN/Gs KX}F0Z`oi>/$q4+ՀDIgh9n ?^:BKHZADĒ i)ѭB i0XaJlleT\`t@n8tq^8M54Lcr&'ZB g ?chbe"m&aNF{ SaP@M iN<{= /+s-@m%Ci8{{1/\-H="IGds܆']鍒W1=%9Lmf4&g Fr T'zE\rpbwac.f/:-h .Uϔe^eZ0'ԥNމ;h3rh֘S@zO%@! 4%kN̔gdyG5WKEDY ]2 nmƨ pU#Q,K@؋𭫣I98Xk Vׁn}]jC*āA60)3՞C[1CIX錈7:Pnp賚M̬1@N{(hL&X>;/wjxB[Ton?EwLKIn`[ϻCAʊh[B0H]S6;xŧ_2*9 XLCԺ(W/C:f;fV % }C]~yk. dgVt"gVo1B_.ho@ǐyBF֜ O.E; l:ӺAK4Ya J@'Vg )L]^> j0y/4)L}2p5;Ƞ|SXX19{OD+;'mb˅stl:x+ׂc@cˁK?X4& j6;E^ .,DdA޵p qJ;5dc̾V <_JH/]kd"q&2AXSC1rQedcKj #]}VS^)LsT"~HD :H{~ 5? `q/'f[+1$t2mE±$$l GpMjx9`Qt?Z.x- C <8xCMܹ~QD <D$.DH]J%4&#`7+žCGϣuQ; X'ؾu ƳqYY9ua݁5ɁwwXqX"62yFٞW.RևFF莅2%Dpo8/.g Pޖ`>sCh(eokOB$$ۋ7}Oj̆_af ÷#oKWFA7:)ĵ pZ'ǚq-`'EXjӺahl?GMac+I ׭6 C} Gö[%@i~k.15"š hBBϥo=h#{طƤ 8> l!cDY]FUQ󮂌F3(/; yM- 4NCkO؁= 1V}v" <#:B=hdc(tmrV')1 jw . -c_i3{U-Joo`NBybg4?G}v~J]u~CJx?`+zO lϒ![M߆DkhvRq-UN7l|QOA ~>Mv~4C:rX3S@P #(e4AѸK|359"'@"Y)&gQQƲ9 ľR%@j7f||?i2(8QħG4FX:cQesw–טR}LhE'}&Q;SmAvZW2[¶1e JoM_FR|5O]nn6ǵF|jh<Ǹ9Sӣ+АcqeD SRbe[SSՃi)oǔ珹it7JVه]kGB^yȞB@+5 'Sh!ۙre,('ϻQF cIY1ڍ (FACq(Hpk7Xa4U 4ZJB-\> #1t[F@;YC໵/>cYyFgIT{CpHb{Oxmq(P^mL>'V9`aj㒤!WQO6ǎBԚxb#,oK@m3uDo9;h.pð *A{8W|2|B{JaOc_zfh~ܭeٸf :ր$ID#v͌ˑz],3:QJgq?|+ҵSuk<*&OvhG߃~< )%yWWk` [.)l2w$L)X|@́酩ewLiDfdHʚy-=;ta"a -2q)J^xi\~ W e& _+sO`cZZU~;>( Ϣ; rT : )y}v- y~H 4N\?!:DO<劈NC2C21R#%\ֆY=5~_r0Ykјkz Kr\12 ])%c|9Mar7oVZFzR6HhHԝ91$E-'. Zymo593< rUQ@cC#?w *܌sUL 59c/hdYӼJ(l:Džw7L:seMXߗ* `h ~KE!w警;߯}?!6pwR>&M8 ,aߴ%n)y `H<(@GDˣ^a|܊,YۍMyʑf`y; mJW2<Z~yy_*ДƇ.u$l:sHk|f> 4+/br pdQyb\ kC096 D8~r PN'Z}(:Q o ֒`l-ɞBuPW!Z,W;Egzo''~IW(O<|@k"pcuy¥_1ԼmuqH-q] 罂Fz8;l3Oi$cta#RȃklfVX2F#S5YৈuN돀3uk~*~Sd{W,|@#rN%h&>}QQ<oqV>شtvUa?xO2zUooɝ%hm!τx\q7T\[L$ʙӀHWDy7M i"9\\ʉX al9ܐfQ \&"ؤR R/ccNw6/P_[p,a|2r#|.Xz5 _ eixY`Jc* ˑecOG(.SRFL³ѸHo&Y^2l8rG7FsW+xjEMo{?%И Œ䉱q'q7_iyyn3XP{\y[t vƼ=9LdšG{1r`\S4x0SK @hs 2rd381cq>`6c2cN̺Z\x] UQ5cw=jl850W1u8a{nb>-xxñlhQl7cj[$P~ZϕXаRh(y X"_Yhyh!OS԰'{037 4v ASCyhhKĔ.>(Ʉ>WȇˈWs.LMr_,_!7_X 6dR ~FToFܡBaÁ4 ,w>- h3rN{=0QdEDo?_z?Ù߾F |dhGr;'@z.r7gV^vD;IU5"Q{?4pJ|(z;0h<Nx8{S{%OT]QD~4m3\7=W/$̫حKbGyC@ä.&y/E9S)a8\2~qڠxfSv5 xjz+,|q@X hXa/uAۯ(E7zSqKm2Y=׾}LP #o/4c Z+q K;+@S%@c %7?Sf&,а +_+& _DžojzaG|}b̎ރvv"w?`/.VXa= Q޳q[62^~@TG~dVX)DJdw4e0}  پ/мIN>a+g؟)bVXaVXaVXaVXaVXaVXaVXaVXaVXaVXa  P*3`׌^ha Zc@Iܞ(CVIP#OlOkBV ]R6l&Y H|כXS}: Cb6+~6ČZ81iVm"y"B>_RPQmVI51a F1~ 5+StK7)"hb|^yѦd9!|2֑sh:Ě_K@Y)Rf _>I%yѓϮBvmcx_MnNX5ƀ?6`׮X:=4X8)23aQ{JF<y5(]/ YaF!k-\כĠȞb@_{ <87@c$/EEK;XlZ:?6Ǻ_.:*Ͳ,syǕx*S 4\4Q~}̛KH*|cc.E}sSJpڐtDG`QGRgF|v6ZA˪1~}bį~x]XaȐj7 `H$<4o7ui{ %̿3W 42 V6mAV)K47,4A 4KFAr4t5'at 3߭ IK)o  _,@#Y HԙtVkʅv ?y^ +,|^xMF'p4Ca wt]SL4W[,4}3Ɓ+[] "-fd8eԄ &Dzɂ/mg{nA 'x[ lNdk`^L W D#5GH\xWz}jO9qyk\ڬjJDu?%v1~,mASp@z,[,r9I}.uN)(GCƜ{:.?Y؅,\-Ys`<##82/ 6nX("͒a?<_pk3F)@DdX]G8 hS(ŎQXE20uz؃g*{ce<0vkd ;YNba Ƭܛcx]?8pV֣-΁ӱQį_ jIRf-.=cј0d7W3Gf({z)$)8x1Z)((ƃ|I*#vYuQǙȸwaMyF-hw[My0[QȦ!66"iE 4$ - PJnĐX! ǒ%5KffRtw9:D=QhFrs|\ 6dYz7q kDq4c!u)o.ӘTpwV &>h E0cf>caJ{'ef u`'fa]`ae{_=ֻ8KZ@];īἸ}78_t@C)[!` s=m ş|l/ ?16 -]fd>+e 4WYo,L)kkƵagOs-Ê6U'-4\ڨ7+85n 7h k~3, i >9>1R5c6$H\$4h!EfuWͻe`Cwpa_Hh`\GףUYlC6A}| ߎϋʚmҲ?ldSV 椾Qybg4?G}Ru~J]u~CJx?`+ZO lϒ![M߆Dkhvq-UN7l|QOA ~>v~4C:rX3S@P #(e4AѸK|359"'@"Y)&gQQƲ9 ľR%@j7f||?i2(8QjħRFӼcQ댑G} [^cJ.V1e8\:_H"ExD TL~i^ɨoǔ3̂( 7Utb|}78_*!:c͓wxG[1 sZϹO4=*2 :&)YNp=%o!VvqAͿ1u:_=(S?ݰ*AZ=fv]. z#{ :o3L Z? ngY>tr S:ˊ)V @KsxBԿ-ET hlaOƷre?'10 ICve|O/6) 4@@SX@$d<CepnW)[93h@~.S˓ B,P(ژ|N29sE=WQO6ǎBԚxb#,oK@m3u v}uߝH4awcczЫh>P}M@=0ާ1/@3A4?Vml\Z3}kނI &mf\P<#=b1ԉrV=k[94&ΣhH`ik?`v$=gɣ(R^qi7x) ϰ%ohRB?1cS . IPUdڜ޴K<>(j|ܑ0y<@cZ1>^(Vq Ηn3 [!)kg)w .Ѕb!.w˼Ɓ(i\x%s! 7ie& _+sO`cʅoD)d!PsO7eh S8 q'(9}4%IɸL>c䙏 ó mF\!=êH Dj] CC#ˣȁIߒ'Dh\ciUfH&f\Jy$ 3ֿ0 pzBfKn6:^c^>+Pqm6sM`Y3~59V+FP}+z[x /)LR#; {#1Д z e3qZ^Y4ʯ4fx卟`D(+I Sp|k%Sz|h֗ \$wň?s7%M?Q|)a{<`7ZPX3y@c wUf>S!ztSXY#(Z3<9[= S3<:bz2 =Vh5G74Ɓ`W&-rH7Y8#3͛7}(o­8$J:P};mTА;U+r""cI4[N1\NA,>b#,܃P&gǐ~]* h Y]:XulwEtL+h|ht|t Wߺl4'QhOu@T`}hXaӁFm=ͫ$(rƭ1!y\xwÄ#7W} 1QАY뷴_rj/{},'HbSG}g %cT0ЈM[[膟➗٠ KOPɃtD<χyϭjsFy'ʫJX#'ڽ ͱQp&`֖[}L|v"< oLOC ?-ޫh&Jߚdd[cc솆Y]4ڬflF@ 4uLcqyh!) {Lƪȓ7bk Ҙ5B|. uMY;;֪0(F {b{|clǔ5܏=R!tRsQJXlOnAͷ){]-`Rh ]zE[=>4'(\b\[~>d)8_ 0Ry }”)#hjftۜYGШLSkI0dW!PHz:rb-bCfz"x3r+'pXQ걺ܼCCRگj6`ͺ8¸.@N z7>4h}hh>4<؇Ʃd/7#ؒa N`f僟"ag9?ZϤx;8 Y:Fl"ʙKLl9| +yjG93 48wí$}Ii 8(8reߒ;KB rn$-8"bMI3ۑo J CMmEsH OWA ؘs!?|(<MDI"_Ǟ5&+Xs.l^>X6K?`(*|=e%)63,G=!LJe3!^X{G"ѷ.|ٚ(gy_ci0] hJ5Z&r0i6ڹ[@ȩ)cyT$U3{<ߕIċIߍ=|fbE{!U!²l~v`5@S{`{4 QeƸ}^[Lc,CZ_0%И ŒXjIIWs^ $$Á1oltS?YqG^=|n%M>^?TDRD#q2j\rd381cq>`6c2cN̺Z\x] Ua.Xץ8ߥpQY5=~^]*ʙ-%`ä֊(g}KE9t!(gԸDQEp{2e2Ww5 d^[ 6+,T (6ě1ܭ@p?-LKJ$J&@8G),kAPYhyh!OS԰'{037 4v ASCyhhKĔ.>(Ʉ>WȇˈWs.LMr_,_!7_X 6dR ~FToFܡBaÁ4 ,w>- h3rN{=0QdEDo?_z?Ù߾F |dhGr;'@z.r7gV^vD;IU5"Q{?4pJ|(z;R6-kiX,;U#M<vcRwFєͼrޞ_p0c.A=c  dKߺ׍]H 8yw7\ /uzx$l<[ce|2(u#P{>GҜピ硙pqDo VXa<@X hXa/uAۯ(E7zSqKm#|l { }/5ڡp`G0_ik#VKͧ5Gdh"߄_7ζ6=D 4&8r:I…q_[Gڿd;+_8 9݃]!0˯_ۅ?X\+mrKY!:Cʎ+,ۊ.M>*#+JH!R"I-{x\cиmM t[i KQN'NǏmn >Jh, q`q%T  GnľwG&gc_Ea%ҫJ)/3_*5Ę #BQoz%E>\6$]':Ѫ XTԙn־C󲪀n _>_9į~x`b/? YqqàW: $MRCvSWPb8{{>|@#ë`k*o_d MT@ChbJDj@#mDN/Gs KX}F0Z`oi>/Ěq4+ՀDIgh\h3<_9T0VX4ݞq4l⮽6d19-b\314]2i6_'=)0(&l4q'K@T=9܂ vO¡4Hώ$HK FjX#nF+՞s &6S?33@#Mʕ,'y9 ~Jp7*6VmbfYڂXLY?X6 sN]䝸SP63)f9? t\0 4 NYZ\jcyG5WKEDY ]2 nmƨ pU#Q,K@؋𭫣I98Xk Vׁn}]jC*āA60)3ٓhOڡСl$tFD(F}78_t@4r0:|HJn1`Qbܩ mQQ Fl΁VMhkg/% "l?j? F)+m;w" wMEho@r~Yʜ0` 3 ]8P^5֒CuX5<$ weʌDI ,FM.bOpQi/1~ x*nޕ&WGgwGj;)#<4H4i>5kj!dA2^h!c45_;'[S%\|_6^~ ^i_vN 1,b$.ķܒ>ә,jZmPӊ]gƓ|OЌ!y;ˌ%<ܐ=]a[-Fef3%2~."Bg4E,`@%Mq q HV.C/{Lpo5켌b>َR\z`͝ dPg>)B,TИU{`'Nʶzt9p:6<kC1Irǟؿ},f5jޢ e/b "2 G|8Ѐ8O1f_+xp[/I%Wwb.n2 8 )q@9Ϩ22ұ_5Ñr_>})/&z 9*2ybA`O/Z'al9nҌTrk%NƢ H8-)@_T76/!ꁎG 4dH!zhc;O`5 _#Ӱ؅K)x~spd^ޟƤz,c徣طb6yt@c. v6c$۷S;Ax6.5k ;<90s 8KF&(ۓ!Ł_(ݱT&^= JA !snH%+NBc7l8ff0|K8t{n)\dx0B\[ E|~vB_9<ωƶ#8~$+6V➴ pj,;۷p=K VUũͳGơ~ߙZ.5èbx0v.NV⁴pB_ >]2:3(GdtX90f8@ Δ.cA>yދ!vq"e;Pv"qXݘd^R]4@N_e:hLG:+53ވܒ\DYR&g=@i&Ȕjm?ne?'~,|A@SX@$d<Ce4[hf߭}4D V?IT{CpHb{Oxmq(P^mL>'V9`aj㒤!WQO6ǎBԚxb#,oK@m3uw}uߝH4awcczЫh& )|!7fzh&(ݪJKkƠo [PID#v͌ˑz],3:QJgq?|yT)Ńڑ%tJ(ƥiU7X?ÖK ϓЎ N$AP@ajVcjsz.QJc!v  g4_sCzabo|F9S&pohb}g p,36 C\ l'y_MQ(JK3Co8T+L@xVbI8ǔ ߈4-UM&ˀhW|X|kh S8  Hoܒĉd\{&f1Yt?#AʞaUG$"oOծ!QU@coMb+"Bͯ ČK)pafBZfNT( }MVkl i^\Xo o_zM('awmJ)i Ȏ ވe 4)=?=Hi@wn֨~XskYWi6fn K6$ׅ h8>ڵk=>4uQͅh.»bğTӒ(Q=CYq0GwEPh wEtLOh|ht| Wߺ@YFm=ͫ$(rƭ1!y\xwÄ#7W} 1QАY뷴_rj/{},'#31yh*hile --tOqem KOPɃtD<χyϭȒ(Дiq@ Ph=qC.ey83R}78_4>4w58G Qen"{ 9X5>3QmWc1 8cpm15Y{ g fYjm^(L7jh}U4[joMFW1dvCì#mي``zlIhnhrwDeLY%qbY_ 1dRTcxCSf-?t>Dv,Ya|C 4_E1}ť6KUh悳\;41#O\h$HcCc h׬ u(a8N;;֪0(F {b{|clǔ5܏=R!tRsQJTlOnAͷ){]-`Rf5rSta*QJzn*hМ,Ccpqwo=>4lu|8.lK}7<_Q S# Pa Tn5k`j- Rߑ**I_GA uC |h@o[ozvB|BZzģ 4J!W=Vwh(\JCͻ~YR^4λ|1Ҙ3E;3-L,k+Ѓ.ףKMnU zN* hLB} ?u —zG@G>4,а@MGtj0O3fg\~<~Sd{W,|@#rN%h&>}QQ<oqV>شtvU Nc\wYLǕ7pC%iο9xJ9 ؎yEu|}<޻"RĂ+D" nQccXbEĆhT,XT y[{QDBp)]<˕D![:i/xZ41IwЩ89C !R]xQGe8u#w{ec'C]L@cRc V#<\M"~œf0v"*4݀EerI ;>NDjN!RbL4x8MK h_d)05 f9b̹f`LP-ܛEnn Š^Һ4DMX˙7A%x]}']^0]PцA>Cl =cNe?殕/S8~o(L'HR> cTSzy{SUMGS8)ZHr5Bx2 y{9optNi-r_ 4,|@#w?<-@Rε~\W/Xаy o1.Q w5X<*EIa% FB5+>xk879HS&ژw¦t? CCXL hTRc|ȾAp4H-Ku®g}^`u)-.=L YWxHLzQ{%O[L)5Vhi+.ÛX9BU[b®gG=ehC@$/&*~Wġ9='U0uBAҖ&͙0+l<-Pe?LzMPƨ^IWJucF,53 {'fw/[oi4 v l$6ue1GsY ?^„jC84LRxM |jQڮfkxthXfTаŠ/c^_P p7ugW\M]0;|Ѯ_4fj9} G@K9glC~/U1v 4XAJ&c֦ 51bVX$ʰ\ILĕc+ѿe;+<C".6n]<ΎzYXa QqW.R_TCM+FʳlXVXa+|@rwN.[wVwmltjTxhs6" XahXaVXaVXahXaVXaVXaVXaVXaVXaVXahHsgFSKR5Us,MdԴ$neynY)k1-mD pUitsil7  2ۮvY^*ql#ur%e}[Q("$a5e fP##pl&k߾9E4ݙs!6×mJy[!*aG1V<(b(,P~)Ն_Ow5#E;ifh!ZUT[ۃcC܊w`լh=K#fQ32B0ncSt*TEfo5H4^?R΍vu+~ 5҂f Q/j4Dz_^fi:"w+. G"#qho0vp_E3yU)/%09,cK@35HL$W IN$x* H6^# +^j{ {`hXao)# P0iZU\w@ !}5s MiYް-Ϥo_d M@C1>"@#y mDv$Su KX3'㪙 /[/&.f ):,Af!]PHCf$Hs4L"NAN^{?&Sqx&319c4{Xť\\I3;5"bE[[Ĭ^t@#3K[.ߖvEv0%yݦý2wh֘tk͇tlJS.n9E70G}I\f Vnq-)9W*|ޝfU<"xϨNjCyIk[eU4B6ܵ/×k5S0[8: F}@cr&}> مIkO²Vƽ8bTwE4 !;K =QUv%O˙/UaL蝒hC`iD\=bdE%0[įl >RۋH?۸JB`-aWZ&NŇ+VߎZQm-NF$jߌŜ߶QZ3uQ\g4wd[WGOTQj ߱]ހҷ!S@CyW;5]ſ39SFo6;ARX^v"E}=<ǩ=PFg11Y5XRUN^O9 p\a]gxJ@7\c@قg,ssu*I'7I͠v⏍RJ<R@cR ^=1a2l8UlKmAWk.BS8vxp|/kF hL@l*YΕLsb3h>!9T w*wed7jFUu𳲂Z-P5 '0#YbpDA.@_cY GK8AvhHCm,h J!u]NƽXlYWdkDQ4E#:|)զ<^/91.3Xw L|ɋa8p"lt{J)녪5Sk6݈!590툅cFs3TML(ʓ1_kѾAz`4~v U= XwE4'FXp[hu1;}gUfù8-/De ޝ"iF `?o5&@[KÌ@)p8:'KҜ`8s2kE{} )4\'Wp ^w 6^T lK)Ͱ/$/\ʎ%uHPGpl[c(Bqt6drk,/*~L<  @X0~ &]`n^(,asA?!"dMA=>5{ǎ8jY%s qgSI"| Dw-UYaMQ 23:69D&;6Ѐ=)ܶ ㈶Yaed &XVwF;dJ4Ҕh+cXdfqyzm!Hi<DO pI*zZ-M߅X;`MJ/­y tǶ*!7v+Ovat+}ϥMLA۪>Dӣsрcnhϊ -SGSRN 럫b<0U"JC~7ҐPu|B[Ja|Hc^:fhPn \8]ܫL$@pM`$e(3E.cF]n3jC /g޳6KCykRel  j Ud{yPJsto8W~5 }^ H7~g $  cWXbNVw5 7¾"c¦qO$MY4"`ƕ"o]oiz9S>p'RťM<Ö.fVYt])Ya˿qx5 41c+n/UQHR - ZD|$c.L1wx&@@IT[x:ha)]Fw G$>N߆dkC^ʔWy 2owŪۺ5d~=|CԠU|T@>ڇx/p"Z `yksB6[[ 440&~ȩ`{݁#ж\zh/o#.63I73Fwlln=/dHNxpD(l )y~vk*c hl-NB!7""(T!p)P.LtFmkʕ[z}L؆V΄/4|ܚ\#Xܡ1z49V#*>ڍRb]= qד&w A >g 4eIh@8GQ$a:Sk?&Xqg3B Ŋy ~qmVΌs,dZ%y)EB Zn"{RLxʗVf+=?#P1VrŚI2^(CWs<Ν9q^4D" i,mI@Y/J)L[ɓ hf~L 02WcmA1LjL]47M"x<NR~Ih:PΝ6kD hHԞ9$/#N^8>b?M! y0.!5#d3`$zS)P>*5~xsb=L5HX~ %+@S^@#M^@Hgα5Գ!ly\XuǤ7K}RN C@#!ao 悔=cД3&!9lZM#^ڠKSdN|"&}-0 RۍMY#IŚv"TrXh;hhcd}]y)-UF#Zop}@S/74Լc4ّ>__Yy#4F˛ 8[PVŶ75:  nhNE)fIZ[r‹Qpì:Ęn-򆩝OyBX>0d_m#YҧXCf1ܔnf0*4z\\Bd4:М-JC*?t 4=qi3&_+0r?u8^ه23PPջ{ h»zRkIOҚG'$o$'G!Z,Wb^F:O ce^/_xjFE|7Op~b Ucظ9 Z^h> hdfЍ T,2ۘI"8tFg歖#9_U5H)bqVXm)T &cf ۊgFs4k~*dA36lZ+oh Hm{9s0;OƑr/g5սo;;BL#F9<~)SFot-h40nܾJIJyQ(O3!{"oM)iszD,ų  x`B%ܖ-/@SC a^y QɊz<;@wkp̛aa1nz_+V]{_:"Ә.3H3pppe(.M˙DX~"п6|*/gq6^y:ގ4TD ޙ?&3w/[/z)sk}Sx+wBJiOu^_h b0Sq8sp%Bzei.<ը2;wS콴Lms~{˙hLj ĊpIYUs^_ f7xNDŜѽh?S?dG H)DVAL)&oɽ{ɽx,H_*`38|-xnƤ 5;N}̽YTp^ Un.EKE^ /gT9)=B!ȜdҺ4DMX˙7A%x]}']^0]P2oJ}eVXaӀF!&c x8[$La?.+ hXh(Ż,H0U@Csz<5`Ȝp$nm;ac(Ošy\,t&q}4D)MFB>d_G O8ral% a3T>/a<}kܽz)Fބ]-4735: ̝1Y hw$ikNTy@Qn@#q }<UA^sq챦ҕ ;TeօA5~kR/b(/i&{![z>VdMišsޡ`fP $3r8p*caosn``JS{0 FǾK  g43Tܠ5rjۀob#x$E71! IT3 V{7吱s)UvW X}]WRcFј̼2鑾a/$aZ%&Z~f|ړ]6d4LbRrw.B%Qġ9='U0uBAҖ&͙0+l<-Pe?LzMF*0Gj"ƿk}ai.`u VXa,4(-p懭\ Dz"}?l)6_-(le$uZ?cj;+@S!@c, %Dď!FJP \#hXaLpa, D\9k Yٺ1? nŃg^_^ 4lMrw:mZ7R(׏ +GMkBM;L܍;lYѳѩQUX x:QوL+bVXaVXaVXaVXaVXaVXaVXaVXaVXaVXarp T#M=M],!JtVmw7W r ~Ó}PӒi^d"MĸNc#~3ݧ (D.à l,gWf#0 ,)#߲}2@,!Y)c6+]0c.=4\Ew`)Ș ]mg_|>oS Q <UhAILC5f1H6z}zӹdD||L7"}m,`kMϭc\sK]=w0/$q&8b_|ر埸PM5`Kw{p,cȟ[5Mgi,|[XCTM@U^u \w ^EݗH@#s u/ѿ<ΡYx>C\Z ^1<X`8BW€VXyg(4`T  ~ކ#87S;8gb/Y"jXRKhx^%p Cb$~&OVǫцD' مIkO²Vƽ8bTwE4 ECkgq"*ƤfEr'FՆ~z$Z~XDyW%YQ# lKJ)cFkGm-uǬ"1R6npؠfaX~Ka sp&շE!lƆ{b7cp1'mk#[}Dq ,Fߑn]Ś=QEDӪ-0~JvݖN{J߆L e^J;QƢ 5U5j'R 4qmK;֮m1f -WiFu-a"J$ɾS<*B q v[1oԮb>!]*OTX> [غx*.K@#}M=T Јp/12T/ۭLЌ jvx^sιQՒQP#~vKw0 uB=nĚyfŏO[[g4@@SO)vk,hVw#[pn5W40I͠v⏍RJ<R@cR ^=1a2l8UImAWk.BS8vxp|/[9p{&1aQwd:W2EϝPpa`(Žxbqþ_ S ܹI6[ZPPGwers~C|0ϋ8T w*wed7jFUu𳲂Z-P5 '0#YbpDA.@_cY Gk8AvhHCm,h J!u]NƽXlYWdkDQ4E#:|)զ<^/91.3Xw L|ɋa8p"lt{Bȩ5 nĐvC1*F&i}Z诵hj=\^?`*՞˅ejBn#,-f4WՋڸ bw5Ϊ̆s_qZ*^;E>S5ݍ2:8J?hqkIs7}GGbc^B~I3c>|gNF`/^h$zCx޽]iA?%S$|K1.1mkLA["نLLe^ k~SP$v G9m{QXo 6"Ql { i&VvyU3+J7-LێqC~4 iBOGl sj=a16ET z迯*)]/9ڭL0}OoK:n3j1O…y1$/z? k;8Fj{TlaG}3]'oDt$LCa|91<8w ޓq܅Saڡw "NFa-l&rfeqgt(tmr8 Lwl{pEAiSm]Am@%ooM w.i ) Wư̒M jMC|x?`kibؓ.U. ?Wjh.җAnR}nkH};=U-Q˴O ;oS+Y!ǒ28(_ Q_P?GQhkXw}:KWtM?:GdS6^y ?Lwm-DCqD4hZ-L2QքR+ R]'RSx~"\Ns2[56&: ~>{ց5:Ohtݝ$r (L[\¶6eSp0 'RlzK 4Dl|$aF7Bч\9^/O4=*1 <&_ȧ=]4}gŅx̩X^#_)SsͅՔ 1ybaR·JC~7Ґ1Y/@3I4(7{im.`kFm$k#/CG_ƌj6rV=kѻ4&Ul6iA+E2r0"Q}NK鿡y-]6:fmF:@oܗ|(3ČTm.;D I( jV)q1IjJbM&K.ڷ,~u"|R^DIj} ] :׆ ސ)}eV(G`IL֫;)020-T |ií( cO8B\sx\$<> V}r keXeHmWxQ]1~O/tiɉh>Z0Wxq \%2X/&@# '?];6J|FU0^D=Awlx&־?Q3on嶘4NDlk^+u:?ŒhU&i:ǹAʁ%qUR5 bT/&@#[OW /e%ՋЄ:!{\WƯ~a/4*޿"aj.7>DS@3<d{VSEfα5Գ!ly\XuǤ7K}RN Cm-HE.䝪7{7=^!t쏉CS@SVj 7~(mǫ^:%s 74kl̇i]HjnhI*ִ@)@Y|ݧ2G DшVSBφk2]oѼ.TG++ϱz&Ш+C/ocj +plAY"ܘא'|М*DS>/ tpì:^@#5}kH[Cm솆Y^4@iUohxnq9[$D7⬇]<|C4׿_oE4r~$Xh2M7&4y1Wnh*a4r8^!2>wV+74Mm~WXm$'\6]\0ڠTylns!h=ld@m^s냬8[ kVXz#kV6'K7*H vw<9H a~L¼^t@}IY>XR|H،8 FFO+3PRZ㖬 74OtQ'jM_K1E0ӍP"uSBB3(4|w-#j=xfz44-T}:YQ4&Q{/ؙv~eznݩ?2X74b=AWu74ee{Drr(T q hH& bFl=*hlҥ S%X4/l+9[ϡx>6flٴW,|@#rY̡`g>|`݁S>U1w$+;kʔћ:]@k3M:oRR^e>{)rf?dRvm "4%5qb.^B|ZfR<&]m٩oے TdPByBTCeb^5ǎ51fXx-Wur~Xu _"~?X`Lc* #!64ɇ 4 /gB5{cIIB|=櫼e9A @Sd^}^q«OqdF&^Ln$ k}Sx^VVq;Nڋ1MA fc8t*gB(@jcNHƝ)x^2 F7IXp58 /ډ8wMGy'=h8!9J9^v0s?4w/709/?Tx|Pb|GWk1\u30&mٖqc͢R7bPrw&Jk3kx GOGarfKy9ӗ&Mu,h"{ n(o7 ذbN t/s~']0LN~fh9qPJ+uCcj=~ •0E)vfFm?Fl<.zj&A `}1ȋQTol>w wK7Kܵ8e~2'yDND4c}qhh?1 {\_;*QJ}<\tɽB հKOa%t*~gP/%՛0fbw֦1-PՔaq|?R@ #I[v|rSA c5ܤmܙژeXa]T*"fARʽ%ChE?]Z:[oV p©!͹ +ON^ð&t*G|&û,) ,ѤRqJimļ$\'Cc-g^.>1吱s)! ܋WRcF=ɘ% oz.c@w IVm Vd  ԫҚĭUz84̻66 1Է1WR&gƹdޘIEcoMXPkȾ>͊4oh`̎p$.RZQWSspr&Nz~,/R1Mم[R:a"/Oې$NJl +P@#yvA}gkxhKE +h+ by !:aWpQw|e"}?l)6_-(le[$+ВfP;/ ~3:a,"Õ!>w^$ѣ@D֛2,7=H $ Ҷ)A- RcVX$ʰ\ILĕc+ѿe;+<C".6n]<Ύz4Rdzi [x\cq';+@6z6:5 kV*BJmD{KA4?:k*>(]ۍBt2< B+Z@˱^%n`dBܾZ|9@d=̺"w۬tjd r݁5?h;s#c.Dvfr}MI3/ck2D2#(FTՊ%1] P"ڰN31t9uU]4a22ރ^$}x-y3XⳍRM1-Շm*px-h!n;j@4X(RoaQ!@S7Uy1p)\z w_+do5H4^3~vu+~ 5҂f Q/j4Dz_G^fi:"w+. G"#qho0vp_E3yU)/%09,cK@35HL$W IN$x* 6^# +^@#N :&k1'uxb744qhHJ' ;>N&Ušy X3!.r4)^ k.L65mAV(K 4~ )/ 4FdaG2Ut5sb0 ȎMRRknW<$jM|@SBۆ_`}r/M6N _,а@e&{zSg0:xyp":Z[o vMSH4 h!ԿȰi>~VM79?z:@DDjD8~55+>:MއbE۵>ca KGYal&b3T0fr G !SS-h(yǏT\*, /a"=,F.QXc]RO1ʢ-V-bV/:-oKcI ; Z]Q(9;K =QUv%O˙/UaL蝒hC`iTz~1^KFAW_-׎FZ6YGEb쟁mh%!A͖ð+-ÀLtoGB 'b~#obNo\WF1Wۺ(3Ac;2ӭX'yZXTڮio@ېy ׫] 4ށ6-\y,Q;R Om[vm1nhN 4Ҭli TG I: QmT^3ot=߆VUʹQՒڃP#~vK-2]Zf06B;x؍񞰥ֺcYw)Si3ۭL)L);D}54 ѻ-x8?]ǫBtrST jG).x/i3K +4&wơ-ʆQ%ʶt梊,;kG݌1ĺ߈3 Mž#й)zTlҗ0̅ Cv +h@RMDM1҂ <+s]d#4>y^͇"d>*@CX}Ns&@ͱȠ!~~VV]B _cf;0rT,1kr~3+hm0i(@#\T:d`W./¡ɸ- 6l(J’f"5hD/Eڔ׋%<%`1뎜‘#Aϣ=yQ0^N͘ca^Z9aэRێXxh?f47CQ$<S}9@]Kg_pu_t@Cm;{BḿR&v@} qa_?l85yS05^(SlzhqkIs7}GGby %iN BI9xʢ=>+y {N/;@iA?%- IK>c lI]@c;78<֘5 '#з5D@ (2`ʭ@õq@t(w#ݶ(7k y(Ln[={Y4Z@{ +;tĪ)E ƳEiq<.Â1{ȯ؞&53MZ ~Վ%IvTݚapD>}&Ӡux$aVf9p-nf&<u§0U(bsRW#AF ԝxe}2{ȴMƞ>60O%g5?BK|Mβ/LG}A E)a!/]4ΓMKuZ Jws4JMp61'Uc#nsSgk^cJ.*c:pFw^H+@r j5NZJͅ?=!l+kS&i9P  Kګp")_Iꮷ@CtƧ>+Ovat+}ϥMLA۪>Dӣsрcnhϊ (X^#D>/k7>|?W1yba D6هoG!Cyߑ>]?ש d-nC3eːSOw5iWl}Ql{˼ XR6 @^:<_!V!M0ͽ``<дTxHQ?g64~ʧ;HJw#fhHAp AhFVǤ w,v)`LN>Yy8  q1IjJbM&K.ڷ,~u"|RޟDIj} ] :׆ ސ)}eV X}d)C974L pCq4apE+L0T.#ɨ5K³lnw{wXZcKi3(=+Kfڶ†(V3JS@#-.9pH5Ay s.B5.%bi3^oh`v~C𡋸*.ahdD'l~jɣhEXcxT 4@/\6b&ib?M! y/3S|D]q0<4_@ô#;aW#{{1{$NfZoijA!p; ŸMAzQ hx<6\fžl:,l(nu03IS@#ūMUo4Gf\,} D05߆|k_} )H1"QW?,b_2сJjWБK9,i:v2;`RφqaO,)s3K;4Loh Mf ~[xG\;kcΛu/yPF|ġ)g)LBP+sz ?F(A뭗)ɜ"D M[:akW5{FY,ߑbM;*9u#74R8Z FRt}6x_+Дz 5/7wDg?d^_Yy#4F˛ 8[PVŶ75:  nhNE)fIZ[rR~KaVZ NOiF|@ݚTҾ5؎n6dvC,Cef4Cs 3.bxD^QÕ'o \M(YL{C,$ hrH…q^.py Mʣioh#@NBtv~d, >V3r <+ ;0r&afINvmλ'ڹa̵AXR=%XFڼY\e!pu)vGT;C"3_܄ tr"o a'Ua3 zM%fa`CQS!a3jnJ_`[73=e.w @]J j[ohΖ~Ccpn:@֞Ejิh]{9ˏ:StXlwdݽ`4JS]=DaNQ'$JR1(DC м݋>V\Da]7r8_-(޵f Z j?<7G A+F 㼘~g4oM0xCD|^DSt 3-j- a +7ԸCA,V2]q@Cr`;0:CjzӿM@z7=D`, [>ۺli@# )T &cf ۊgFshNDjN!RbL4x8MK h_d)*&ߑƁU=gpZ 9W Ijw{ͭԫДxoptNi-ֿ3}ih_ǂ&vT~ !6Bgž1'߫' dy]+c_V3pp ߠLwh~S3)=ӽBTAn!]xk879HS&ژw¦$CCXL hTRc|ȾAp4H-Ku®g}^W8y ÚЩh^}pF>K *Q^# &F0RGRtpN7ymػ-.=L Y WxHLzQ{%O[L)5Vh^i+.ÛX9BU[b®gG=ehC@$/&*~g4 O[O-* 1zRqh wm"x/jo mDqT=jijq.7Yd8lvLw'J'#`_Rs4 v~+)sKJ dM>" 2β=b ,򘓥 !`Z!N݇2ezCKvG˪ Ѩ_8CS6a,4(-p懭\ DRQ]0;|Ѯ_4fj9ktm@K9glC~7E(zZZg苏r',Okլwr9|Th@c, %DDvmkSZ@D@ +|e faeX $&ʱ_K2֝o\_X!p.D`gG=zbO `?s so-ac!&@#EqW.R_TcM+Fʳ +I>zi [x\cq';+@6z6:5 kiI43RRm&b[ 1~XSDn tAd]rZ*ql#ur%e}[Q("$a5e fO##pl&k߾9E4ݙs!6×mJy[!*aG1V<(b(,P~)Ն_Ow:͟Sϱz*&[ԁ ߔ<Ǚ}Ug{*}%-ՇmI[ۃcC܊w`լh=K#fQ32B0ncSt*,?@w xAGE&E\9> }'xK 4RGk GY X|=# e#bL} p$2cjgL1 %XDm3L^?CJE)K 4"@#y mDv$Su KX3'㪙 /[/T֔{ǩ?}y)IԚrQm… ~_l[%#H[hX|@=3W}<м?8F-Aĭ7zFaKo_d4+&X79?z:@DDjD8~55+>:MއEX%>):,Af!]PHCf$Hs4L"NAN^{?&Sqx&319c4{Xť\\I3;5"bE[[Ĭ^t@#3K[.ߖvEv0%yݦý2wh֘tk͇tlJS.nimrsN~t4)BvKnN!' hüRؖ.0#9FuRkK'_#؊-i8Hm FP}]B臠);D}54 ѻ-x8?]ǫBtrST jG).x/i3K +4&wơ-ʆQ%ʶt梊,;kG݌12oDƄ DͦbߑE\=w*6CC…Y ;aǕ~a4 N)p&&oiAAQݕKR}[n2_R\{^9LvhdHe kSh^@CO0XskŒT|gFe[u:Q;г5~Qofe69ٙ}# hķ+*Q jECE8t9ceF\EIXLXWR<zqǔ}!l< Uk 0l>Cjr`b njf<*ZQ'cj֢}C#ZsixW{.zh(ugO඘9H_aW/+ bw5ΪLfr_qZ*^;E>S5ݍ2:8jL&4~7pt$6NlA)z_ ęX,cI):>woD"S 4\fn*\`[XR{ds);–4#}Cm)[p2"}[C4:ې" ֫]hsmo*6Į1Gm/JapZ{FD:-[c^!v0o2jf{E ƳEiq<.Â1{ȯ؞&53MZ ~-d(/9p-nf&<u§P`IX0~ &]βu5ϩ~MM^I6^~&Pwqܗ{j{_0Ḡ{s nݻ!Sos$x5SOsI}fߞ*[79SqlRj3[,feqgt(tmr8 Lwl{pEAiSm]A@%ooM w.i ) Wư̒M jMS.b$/~--Q3{ҥJ1ErVDw!B4wZpk^C;ݱjύjX}(}=}l`y3J_j ae>)@e_9RF;XúC)_h 9"'ybW)㺾hm!#ZW@j=d֗Ɉ&||^:hu˜٪7չU)Eݳ 51x1~zpt@;/]v|w$k@9f 5dx-Ÿ)4̜( %UpW8blu_J!`x' 0>́& xmUQэh@1X7 4}gŅx̩X^#_)Ssͅꧾc$V;l(iߌKC #}~گSn3 Z݆ ngʘ!ʛ Ӯ4>yg3llRuxB!BBa5+){9xizs'~$miROwt=:@#AhFVǤ w,v)`Xw%X,uIU;)>3}Q4FG9(05Y7Ppp'N/TW|TZ~{4c?XkAy^6o@ch+hԔ;8fz6tOG1h}G{w:nzL64Ҳ /O}@ڎq=YC\1R? q܅ ~J!{{ QcJ`M[;C)Gh>[Q'U3NG Fv?!Lgt$9 8<q)$ (MbB\a9Yݙר q! ЈWe\wLa:BH6C [[3fm>u>fff!j-R0ČTm.;D I( jVIspLRS:sn2Y DTtAվgRDIj} ] :׆ ސ)}eV(ڄG`IL֫;D020-T |ií\3qS4/NFM9m󛰾n%99h"1 b}CdK?m2FC@#ۼY\e!pu)vGTl6,ݞ&TÔ#yN' hd!!*Ģ~ ܌}a[hzF`Ocs0h&Mapͷ42/g^:q$xYMu/gFv|8N}fcHlW%wה)7u[f4t7nm$(YH2˽{9)rO;O6Oif 1/!>?-3)m.7m]h*R!KU^β{m,c8u- h Չ39x3 |)H2?J/g8q_82#/&u7_@A>Bp)]NDjN!RbL4x8M I h^d)&ߑƁU=gpZ 9W IjwZ[y1W;Ek5ۄuJk׬KC&:4@ 'g|lw q':\g9^m?M.w&t y1Fug/rF{Ju#|up5`[Hs^jy94ʠ<@Y`=Se;m>VaB_M|CLpIε~\W/X|a4[K] $JuqRO;CQġ9y}P͊ |0dN8T6杰?h<~.c:vU&#X!#x'M06R?{s݅ao0J5RLK 4G&Ljy؝y81-PՔaq|?¯ #I[v|rSA c5ܤmX,ð.d [c{CyI3qu x )[D@"hJyVCu7_:F4r8p*caosn``JS{0 FǾK  g43Tܠ5rjۀob#x$E71! IX h)tJrXÔpW X}]WRcFј̼2鑾a/$aZ%&Z~f|ړ]6d4LbRrw7H |jQHXlCc( ]`ͼk{mJq?cocT$+@1V#JΌs"A`{933aRw& i S ?„qh W͇]_b/6%T]^{ Сb pjS"hhKE +h+ by !:aE"_ DR𵖑Rv̖  Ecv'8 cYFgI 䫙#~6΋w_%z( hhh06mmJP \#hXaLpa, D\9k Yٺ1? nŃg^_^ 4:ܫ],xVgVXa+|@rwN.[wVwmltjTxhs6" XahXaVXaVXahXaVXaVXaVXaVXaVXaVXahHsgFSKR5Us,MdԴ$.xnY)Fk1-mD pUit=il7  2ۮr-Yn*ql#ur%e}[Q("$a5e fN##pl&k߾9E4ݙs!6×mJy[!*aG1V<(b(,P~)Ն_Ow:wŸSϱz QA"y3Xⳍo܉հe9z@i@CWtǢ1Y{F`͢gHKe>DMaTUupU$}h(;jh Qg3WJ>j?ĥ@q)ʣ^5#t, hle ,y|2K1XMpm8C{13x&u,ɫzuH(T)a<[1/Fgd%ymHOt"`ViD|vW4tmX~ypG~uL8!8`$|bӀ>Qa_k(4A*.ͻn ᐾIq?xæ4,HzOoX[tgϷi B^J!^_H @|I<\6"{ ;: qL@v܄-EXSv3Z偦'QkE 6hqjlUΗ,а@4 :3p iDzgpihDY$F EMha" .m R#=1yuX i>,z-|A S8uX ?Bf30;H.h>2 :`E oFGF+=~L\Ray S]MfBcrhċKDf"vbkEtI=Ÿ+XyYFf \+-}V&5`JRԡ!M݇{ye(3Ь16 ?֕\,xEhR`B`_O8 Ly"ف-]`F Qs(7 N,F.[VEӾ pq(DnCѡ)]"8|9V3A y Ⱦì`T4&gҧC`]Ծ$,kuA`[(Fu_t@PL,1hFyFW)hLjXԎR\^*RӞg!V*hL*٫'8C[& #Jmɣ-jEY=v ׎ce՚g&5}Gs%Sܩ /a f "(-FW>р8dc̿ExtW/I)7:nQGiH}p󼈏E|N}#5;Uʱ{Y0McAC`6iE 4TD 5 *HwaX5Qc3= PfVfژ3`)?PhF| qkuf]4_Cq/1[lQ%D jaш_~)cKyLKc49#kGƒ*G4z`wqaz#1qPrj 1&&~hnʣIEyr_?ֻ8k-74r 5Z,=Ϯ!ؿ xra뮷耆ڨw nv@} qa_?l85yS05^(SlzhqkIs(iGGbc^B~I3c>|gNF`/^h$zCx޽N1pAaƫsmaoT}!~)Rv - h |G:cSFdDַht!rfyWB8Tl:];Ñcn^֛ĵ)@e_9RF;XúCih 9"'ybW)&ghm!#Z@j=d֗Ɉ&||^:hu˜٪7չU)Eݳ 51x1~zpt@;/]v|w$k@9f 5dx-Ÿ)4̜( %UpW8blu_J!`x' 0>́& xmUQэh@1X7 4}gŅx̩X^#_)Ssͅ5Nesǘ牅It7 wPf] |Gt=_:0f@ Δ1/CN>ߕ]Ei},&`=PTWF2 mG\ž^ڬx!W@yzPyjNP8 B?ʐ1 %O-Aůx߇>"S|0)N N׻`d:| ;z?~f#Bm)!zIrp@K3pmxtq[3j# \@~;2f%6j6rV=kѻ4B&U8Ѫ ^uOv1ȜGQ L7s7XaM祀q'p6Iؤ*&՝y` 7¾ȣ*b3IS1j:qH[u_^f@$܉Tqi874ϰU;cc ]CfmF:@o/5^ MAX8KS I( jVIspLRS:sn2Y DTtAվgh zxLRmJA6dLy+B&<KOv`/^؁LX?1y?熆in(3LS\n5hƞʥq05qIx-֭nK+|)wDw=әqy0T~0Z 83}z=|C)Ohr keXeĨ^e9J o>t^7 L$h M%LɁ_&V=h[ME=Lb4◷XJ~#;66i xR<iz8 .' Eڭyh' ^d,|)"BM ȄK)pabDӖ7j D^SKv<*u&Ĕ|96[јk;tpP8.m k4賜]S۠,K]w+y04 W)^5cQqмۇVյ4.*y£W hq-BmxVnbp gѩmش% q5jŴg;@CkA S14D|D)Š,aRڒf^YQ|̌ƣxPgmڕOoqN o^RW*rN 3c䄢DtrCӼzT(!q۲ N=2(k;V(4҃*Ģ>~؂!AhbZa4Yfc8oHme9sh7N‘,gT10 réd;^5 CEZ⏹k52zK'--?17Ĥ%ŒTY&,g"Ii)j -B# v#%\& xb|%$H_}Sޕ0Hd 07sseмT k>kfa58捱zN2 ~Xu-^i!113lGC*BD ]<˙D^XzaWIee# #yrI;7888v4_v0窺1YC*Բlߙ9g/qT$Mn!O+˙oh| !_q |p&g=N~P'!cOgL"8n)ZHR!13OqҡV-n{xt>scWwLj].Bcz%Fz?XZJADOU`,E\c]Xxbs  {h Xn`0D=;+g]W<2,)#@#wozx:[[S4%TaMf/KL̊qRX|*ÂAPO Qϯs>ިlO` 纾<;wrDL:44dL7G dD_+c  )F*5]rbv݃sKX]I 4zvѤ PȽQMbJ0wW8H-@g AkQE :^EYLF4z{R'=u+'q;F6q?֭X/b/IO{![J:d+SQCCi`bhK(#b(*q*bpooǀzd?OA}=I=S ,Ѱ?)TBT2\LaAѹ)D~e<QиI/iAkvcb擰 ]~"ggb!G3R-JXzEq)~9SZåF-1F5(3rcHڑhUB]1cYT1; 6Ͽp*VnVC3Х )fHF69 m][sY%Xغ˜xq}7vao HňTE{ExW%%E$Kg܆ F% jj}2$3y4-hj>119*+y)/e:qx0Ξ65  KKMeJ@'TI~ @ۂg,sa} .N꓌[)ť6OF2sJjbJ9 py;qx$4~Xd ?ފ\Tc_;f"#UjO®@,G⽲s.@QHQpvm--''|FFZtweBy*{l !~L&豚G h0>f+,VMPqD|#OΛ'{?WѕayqA=*Wc*rzP rc~Bs@#y=9A8[pV6OR\|GTĠ=Iso, BN򱔀&4~6#<*&4sJ91+F_='qd֎E}(4\'7pMZ=wJH3w t Ϩ=ЊR(c}^^\%uH"|#8-0y[$NOk8:5dȬ/*}M=#9e z'|oBDQl{hX ጊ^aLlr=Cɰ 3viLz_yLą|}9yh3eE±=K1(bKsMQ[qi ]Y=E&;6{qe+ ሦYA6ާ#wwNsz{dHo }S@c\%Bʴ OBBO,Ǟ7撸<7M4{ GV'h=I^aS;!νE)=NWld9gơ2 i&J`oow܂b&3@XKl]β.LCAUI)an=)_+pD:_6?#sLڑQV sz1i>2Dm [>CZ/6hu¨Yʳ;US|׀R KxyZMptFw_=XXřGPk {AJLa@h\xd 'RlnzKhN>dink#Ñ*\ĪOPgޜT.Ѿ4kŅ)SOS9G j/һcBvKc3m3xA;':僁ԚaoLk:Sʾ %}WxsvƶŮ̇H9pF?+'/]VH*~hH-=`ZwTTxHQ_`R6Ƹ)YxW5IW7uf12E O %ֶ$ |&a~5z薫XAd33yr98<X^g\W<ϗo_dwPi6KM^y%!.um#Mn iLr"~kdFR@Cacy/H8.S38d ( S.(\ Jp%bAϩ1dc_O!NSiE@u'՘~_zdQR |Nq^%<8r4RW3/BhK)-f:L^ơGeؚQB$@pM`$ꏃy3v"W0T\ZC,gٳ6[-Da54:&WO=f9< %QBg Zš%/cďmA c-(q'% aPR|BSh114+Ț~PwԳ݀HT E.p-4/.1s1\{3 36 l'?njxk.}D{,@S"``srO)TstOeR 2r} g'M?R<G*{ :o Đ4,4g@ILUȐhC7\ pCp47VF8attM"I5Mċ"݊󎮰]$I(qO<S沴#MZaSǺ!ico~%Y%G|1eEo;J=Ъ\ژJ@38CcQtObd?9۩7@6 R׷i= ) ^U\Uȓr@ck/;X)DO)uy(ܐLH&F:l}"0sqj2ﶞ >jz}G nC, g^:](㈱giwnB) 7e.wqmAʘA 4vz,y3_ţ.^ǣ4k3^g3L`3dXG-%SuE;K#}r_;cf(V`}\a/")L) J1wU)f8s`XoXXzR4),5lI@3^j)L[Ӎhof(%Nn(ş5ڼC`r RUVF!d򇱼'e\+m {~S<c#GWOS,FL|@|D0x oFŦ(7ϧi }M0/-JӠ8&"$y!}1 W806G ^on{$ Ü Swµ;<ǖ>6*ɘpR1Gu GE=fr֧ԡ)c@Snw~{%KGR?Ib4 vônI4aХiG5E88\ O Q'E,4'Z *DPxcy_+)M u/te2r7tuZ2~p v:ˎW~#,SS_>Dv4űKDo 3^ ީ—p<RU$/- 4_2 Jo4|^ǽ\ w$: rUV4|oC564msUc 1%.oH4R5ڿjz/kH5mamK?rP{3ug'P+Gn/򁩝4'qs ^ϋd]m c/s%a3nJ^b{3i1h=c.E;Wv@,14Vj W#F7WdiR6as׿_Y.OCMO_YR7PLW==ah»S;vk# $qM 1y=8Uu4.*zy£W hq-BmxVnbp gѩmش% q5jŴg;@CA S14D|D)Š,aRhĈ|a՞148[1&Ɣ>B]U(h??H(h@wް3mjA_e%/e14'zI&.Rah$ezFz钰CX[?d1MZV+&l gSY@mi-,gfc׉S84R嬚j3FA|8uufaHQ{V*t.-?17Ĥ%̦0#U8˙Heyw.HЈ4݈x i Hbc;r Wߔw%/w7棑= anz QNˊy<|;kpce$![U=PBcW1cf؎$Uj)_ȳ AT%'~5{Sf9ˊů5xm'#zX8Z@+ +T!bЮ;(Ɠyhl! 4L: v0s')lIl`D\y$Ϟ2S0iGUk1\U70&k[Z[}1W;@S>lS6,Y?,gCw Y|Ɓ:Ù\g:AE|W=W_3zG``h"Im j^O wA^'NdnN}V l3E}x +OB%O[:”tǰM'ץ˸7w##uݡUVRhXEmnD8ƷY4 {h$ ;7<-@Rn?,k?UXaK(KS$ ~b2;C@#Cssx<5bPUZm;`r_g}uhhɘn(ɈVǬGS.Tr\!ͅnKhdA&LIs xTS ̝o1A/ta;5h-A|(3@#ɈF@oOj%+&x ꫎OZaጆi *Q^#¯ &F0RGRx spNwy-VW֏=L i7xwz$x}zS'M6%x/&k24̏ƴc.yfh鑼<`/$a w@_3>z*24Lb22w&F+~Vᑰ#7ЪCcšƒR}$P- C6@ "TdXW.ғb8c6h7K|Z4֡huhN!`+oZbʶJ2=ǔ`Ar}t-ibhg) F~!:)>ȳ@1V *+y߸q,Ֆ :.dMT^%4?[~yt\Z(A0Fh[/7?Qʴ:+ЌP/v ~RB_<0<沞Vv 7!CS*@c, %Dk!)%X(ʐ\c+ѯne;Kp}ub9?ظܾx! ЛL,1t‘՟)4F@#AV߸'pqo>i!ߥ'~d%X2ˁШ-D<݄=Ν/y5 ZBDJ7 hX@I pI%k%Xb%Xb%Xb hXb%Xb%Xb%а%Xb%Xb%XbMhU&>FQV <7WF9%(zIfI3Tjk"_Q <%"娱DÈ@,~U#hΫ$mLHDl_b/-DH*͊ԭFF0!X~ /~}]XK~372BdW-.ٗ_.۔$ -Xd}dŰJB4_񰤦š_3*@EHk ^ti>^M'IRz)^ڋ$} t;HYM bkW{p,`pN9 }f,xXK )^ XK׮!+BF,s*u//L^`.yR.o B/1P,ZXP(WDVX6Yc!lLۮEr@EݟHD ”vأ+6 <_RʵKhxޘ0M!n1P&+hI#1nh q$4硅p./@C?)J ' Ɵa`i)~Ĥ:f4uh$H  'QS0>*:44 k<a6' kNBV Kh;"A䷾@FhZ$C KWX3;c+lY3KIEWXSjS]+MM̩C*4NkBh.{v˞X@_4 q ܧ&È%VRwQ4LøďDS~&~LXh`ͩ" -'#B=/*ڹäH*65-Ln B7w !t%{x3{zьi&#.CX)JBN#ASPϏ\*(0D;*M},V.Q$83&F#dEx+VXyټ-m76ۖ GwFêv0%{P]RI;4<ʴ gzGcw&3 58/@ P+qыh9 Uy>Nn 3RJ^C'T!5οOqbPw'* xl)[wA3Fo^FLn:4geMS~ã[5ה%C(sW7j?;b*x;UGebIe>@SxR8 Uc_ŭF |~ h$V`kJqMLXRƤcp: m8YloEgk.*Dh3+K/5=Dh@@x YL}\J^+fu 0,Fo7>qJ;7w[=i$ڏjUŒg)H~xsO4 J]+Yˏg{e{0]jNͣ:YY$Z`O;/Z@CO?9N܍: 0˶"T "w-@*T9Fqp;9 ڙMc5%`~}.xV Y 2xV z,+wp? ߄RQ%E }!Q ]5(s>nKyLEs$ƑIϣ4z~z'#[0p@9& Ɓm{,<|ӛ(72F>7O(~GNC#ţ+ws)x:zTT\)(rc~Bs@#y=9A8[pV6OR\|GTĠ=Iso, BN04y xQ4)4y`n\^7'ft'$N 1ްhZڞxݻAn14sMs(1W8L%[R1Ў-‡8cEdX Ա\C&.282w98l>:‘c._pZg&DDIa˱GJɹ`pΨ(q3γE˩;p< %Â0kؑ"u3M\~q8CLIuDŽ~Z @kks^@ 5<-q]\; eeNFm>zΣQ8jY)'c[7;jcPD:&ux,f2µDqpv P{d0"+bFyxR3|g414,A$ Pkq<<{W:'1ʑ. d,b"vc侘z u 12E~#1v}}4GoeDZu9{0%*Lwl! |mT3HA8rVH!ǽYCߔWDF2SqP<獤DO\؛&Q\fS=#Sh$uޢBܞ[j+?W23P4_%o ;ns~ OĥH P.gY*~vְn/]h U8"/{r[9.gڑQV b@|}dH;&||^2(m(5'Q'g#v&]<$m?Zq> ֵc4Ƌe9G j/һcD: m,YYό;AyHo@6Rk1A ht!L)2]a^>2C#Y [T>Pt}[!o"f #tiq8RS͖ E}qIAS§d];"L,z#$]9KS@ԙ6<(l[Z~@+T @`ꑣΎ MWgIa| PVyx!A U0B>@ 3TIb4"1lA:j4&<֟CPY@c7Q9(wqlDtkghdѺo~ HJh?l,Ծ<i;e ~&rZLaʥ?QQ"xC6 (?ŚV]w"]Go)L%G'>e*ơ&u"\Q|B[Ja|Do19/f ?`t\4<*֌0$k#Q+Ř#eW0״P-Yq, FVw QXM*I!U-~}ra9FIP-s&-4}A?c:p$APc Jj͸N ĎwO(rq>)l|S@cAy*b>51jo]~g9s2`][h^`k'3p]:bc0MgBfm&";@O<:M~h8KG$*.?% 6G-+$H sHTQ:w2DTxAg&i)vF牀D=Nێз bHJWY}c3dPNdz4FUjG!8p+isWL0::&$Tsr&EVnwGWXZW$Nr?)sޑhx)c݇Jv\1pTeGP٣gDJAG` e`E3vVXkoAG}Sހc /:|_j%X%:`DsC#Y@c\jB}~{Ue11*)z3gp{Ǣ鎟v~>s&S o |I$H]PDSNnhK{WsQW#G^EwS6/RED(iU!p)P!.LtVdm=LR!.|#sJݞ\#Xtߩ#^ϼtQJ+c>օRb]uAbo$\ۂ {#1)M;h<L}XL,g9G]Gi:O9hOg3Lh 8>3NNuR2eZG }_>"!.G[C=1fbKVg=?(~(?+BbRs׻_YΚb8w֏%ڭW*ELch’!-PÖ Dm13J;}*Vt#ڛ٢w4M[J1LN)̽$,.&jB;-X!QcJD s&8A)vrC)Sm3k@^4L a ?D?!/{ZlmkؓW=zg15e'Rwx6h0x34-6R{C>*|:4 T< chBh,B҇#p5<cn#,.qʸi[vC߽w*e".?2|m M} -4"Qi8w@CA*wFgQ!}dŚiYe9h*1u{LGȒ,oH̔Sdp5W5q]h XXSuFzL6Swf. }ur"Ix7 J}M%Yfa y`9vLy7%/1QRVJVFG Y+5~sCϫ4\)TK0Z /,gy&Gꧯ,]w+y04 W)^"w'Q $JI1(D8C bhCo+ktNi(8#KAJ^(y\~uG8hƵ\CYtj6m CF}1-vQ<}7",'c c;"+yip7KX+[cm5"كW{nh4n%hJXT$kDxPwhF.a[6a۩Gc5D@^[~eWۻl)l @#tIXߡL,㇀- &-fӘ?d7lJ67 h @#"rn6v8#A#eYΪf9cp%ȧSXw01Qjk52zK'*-?17Ĥ%ŒTY&,g"Ii)j -B# v#%\& xb|%$H_}SޕޘF";V(q%DŞ;.+ZX\3 <1os/iWU"?.ꁚ"Ӹ3v$84"Db"E<˙D^XzaW矿Ǜ}e *=0qNC+1"J12?-C;{/ />Hn+:ܶ/BJf"4&U`EH(BCU(,9o,l 3J Z 1ptF,*OZQo| t`~@ORdٽd&Hme\bҎ /f=b̹n`LP}-ǩ9 ,b02w$5|~ٌ"mr Y~ZY}CS&7@ W;t6?3'<-u< {:[f4>p#LbE4Լޟ O? P;bY[:WcV8a:z ݨL ɳQ/"SkdKc `l9wwWڱO {hXn`0D=;+g]W<24F|芀'w.:8ra ,1hdMOg űsk* аe Y1.Q OeX<*B!9\fy# \gNҚhc@3W&\ >_Rk|̺^p4HKU®{}n\x +J1a0/՛0&}g`O|@j S-=腞13lGE1{ehd1IcOԕZ,X~*[`j$z <텔ro*M#pehdCCi`bhK(#b(*q*bpooǀzd?OA}=I=S ,Ѱ@#~qDgkx|,)O jHil7Q0" _HZ*Il#5Ѭl$f~b,ۗGK 1󺢆,m"Ls8_˴ot_̍@ˡq6%ɸm !2aG1W<,bL P~Z;]/OħtITlbid$=Y@4Dq푲`8<֮X4߷X5sT+Y)ɷ̗(@S;.*.]CܽW% Ybrᗪ$̏[ X0y]C<{JG41@]jaC^5Xco~RiYv0mOm uڎ#8/S9gb"*Ϊn~K)/ycRH"`k65ňBOV%IWx*ǁJ6)8-<#uy5,y};MQb;:Lڏb *kc AQN tp® IW1Hh2|=2t$42 4%OMby SL354EěK[Dd̄WyA,ZaBf4R%~ؐ*o[/ C=tsK1f&+jtiޙ*971[Z}I\^f VzqE4xɜaժ<{w'F7s)D%!P_8p(VDoF}B(D.Cn}+B\HQ+˙:6f7&k> N+rv&r4Om<Î+Ѣh@X3_<5\aTݒhyaiDS[beF|;\^;@@`W+f}"t`:t՚cnYŏ+סRǎB셍.Ǽ$jۂ #՜߶.RU;(3AŨ5 D=uiq;WmiP5dh/*}WDn=V]HW ;·-|X¨75\^  h$WVMRF QkT:ZouݥnGWK+Ze5M-Qł]s{d/츱 |kF@Ծ.F*+‹ظ2,),rD%x] Xxe*P3}yuG 0%qfaԮ x؍HXU9?^Jq[ơCwanS :!,h /S ȁO&/n5zշXx]@'[SKld - Ăr4&vIhnÁe[x+:[sQo&E#|x6.F^^z9p'"GS"t`P0]0;!p7}7w ʼn{0CuLMY̫x69mlS8g)FYe0ԁ %, hcOP,/ALRc Y^km |hd}z:)zww|'hqd?GV74Q"DLT\.T/{y#)t <3{֦{ GV'h=I^aS;!νE)=NWld9gơ2 i&J`oow܂b&3@XK|W.gY*~vְn/]h U8"/{r[9.gڑQV b@|}dH;&||^2(m(5'rNf)FxTVOgk^J.,i5}s{`Ab g&CAv؂7.a+2YR9sᝒ?3HJ[\/!:aq1j G#s@Sph0?AǟzTxsR}Ly I~}eܩ'XFÏ)M~qTt1yaa"UD6ǬgG Cg霗N@3QhT{I:oNakF i5?b̌ۑ>\Zg\ZC,gٳ6[-Da54:&WO=f9< %Q§g Zš%b/cďmBA c-(q'5:% ;>ȥb/bMi9OeCn;!;U:oʕ!8p+isWL0::&$Tsr&EV]ai^I8Q&߰ M%LƁo(>=Ъ\ژJ@38CcQtObd?9۩7oz(")'7%@R@˫'^EwS6/RED QpC22R#B\_ɔz^c.lC\9>F4= FSG0yt9V#ƞ} ĺHAF(c@Sv(xؙ"豘fY<~=sx5hΟ"Μ[4nxE1a ]`3dXG-%S&xtE;K#}r_;cf(V`}\a/")L) J1wU)f8s`XoXXz4),5lI@3^j)L[Ӎhof >x"{gQވg7#!G{C>*|:4`F*Ox!&\3K%x2.r@{\ `.`ޗ1?!+D,ʬlM)Rj~ДaOOrI {l &v[V]11$Δ0w9cc_9)@eYhH݊*/2㗼݇>6nY,\|e h .ta/yH 4)@[fC֎|]b/nДq2ִp5?)GFKh4Q*,V@S/^nd (De2o@[x嫬l&jʫ[ q8_ZŶ76SQhYh𖻸L2{Z@뾗#ZM*hZMw i51,4*+@ch b[hN21JG$xǢG8x]cxj@=Mڡۋc7߲ZgS/qy$kXhw̴lL(-4e42аI6,X3m8;L6^]AS!$݅X@-i`#S^sꀬ&8_ͱ4! XJz|]@pE>0d#nb 1yK6Ax,u$lSMKlb#-g̥h'tԢ߮谒CsV;JM*u4ꃬ1 W U LV@|>Yiɑ+0K*@םJ^'8Uxww]WrdIG\G1(D8C bhCo+ktNi(8#KAJ^(y\~uG8hƵ\CYtj6m CF}1-Q<}7",'c c;"+yip7KX+[cm5"كW{n2n%hJ)E_z,v@XWNt7W)ychBOC3L\TCS& h H/]w!` lß3Ij5?d7lJ67 h @#Eġl:q GFʲTS2KR0ș`4b"x, i;;bsjReEW'fBif2gIL;O.Wif1/r3 7 ^llC.!A.|4١GB!̍\/!*ܩtY14/š`Ya yc,S$x_3V]WjZ`L*{ ۑРQ]4,gBzaIID_ >Yβbk ,a6>JhU2 $fZ;A&? RYY_qgedF.^LnpTX+"ųL¼<oa%Rv;q8:Đ:B(Q @DŽ 7$ Qls۾y+ИT! Ux#w缱1(7h.DƜ}h|t?iahGH.@f!L)M>Iee# #yreI;7888v4_v0窺1YC*Բl fe3Ķ-die9 MP$+,w}FŊ$5 y?+3z84:YwT});Kla,^fYf^%vF:Wa|U C^CF&`tI];ai,^Kš K_TɃB-YR׉G07*[Xù/ŝ\5Ƽ6?/f Ms1ӹ@|Q4 uAhʅJM!]`5ܸV@m)b`^ @# 7!`jWM ǁ;.s'x[{ ]cf؎8e Z*b:( b2ۓ/)YFJY#c1eh鑼<`/$a w@_3>z*24Lb22w&F2~Vᑰ#7ЪCcšƒ>K/UC6@ "TdXW.ғb8f6h7K|Z4Q\ լ/l; Y1݆RZf.⨓*}?/հkǢ]m9_pj2o@04 K,i* cyS!<&aR>t\Z(A0wh[/7?Qʴ:+ЌP/v 8 FwKKt~KE1N/']H,)ɔex~R`S\#аK_ºXzl%U헳 38sgN,Ǽ!#^z3@~} hoѿn"9 6>Y̞ QV߸'qo>i!ߥ'~d%X2ˁШ-D<5݄=Ν/y5 ZBDJ7 hF8}kт.a+:Xb%Xb%Xb4,a%Xb%Xb%X@Xb%Xb%Xb4@#7q`V/4roJZ`pYE6))@SOE5KBV _8BԇO{)AMiF *_Fb@p^%i`dBܾ&Oec|i!B6f^WPmV42 azkp|š_K=m1"h9t9ξr٦$Wm2D&3#(U%5] P/BZkX}Kn:I],`s7M,ahf#e6%px]hoÁ;j4VX0Roc/Q. v<\xU0`]4.]{Trᗪ$̏YD0y]C<{JG41 @]jaC^5Xco~RiYv0mOm uڎ#8/S9gb"*Ϊn~K)/ycRH"`k65ňBOV%IWx*ǁJ6)8-<#uy5,y};MQbiaP7j FQVW}pfqX_a͜Gx/{ & ѣ] ^W h>Фco/3pjNUF/ph># [=9J4\O4g27΄倦 ֜Z "r2"*Sj7+>;:Lڏb *kc AQN tp® IW1Hh2|=2t$42 4%OMby SL3q9cc7*vr% 56Q%,ƒ ?XY{EhniK%!U޶_X=3V)ISz2e113i\VL\/|L8uV1)ҊO䢾r4)B֋KE/ NS4~Vܻ;1+H!*y AІP8?ʼnCW"|K43ǟ@!vv.0w냠\"G?2FV[xh\$51MuXIXVwjPw\3Đyjv\%,@R8l R@ˋ K#ت5(3rUHڑhUB]1cYT1; 6Ͽp*~ X@:v_¶f/lOuQ<'Qcl$uo dAϙqbԎuJ"Ꞻ4Ÿ+я4Z (2u4ԗyݾ+_Dn=V]HW ;·-|X¨75\^  h$WVMRF QkT:ZouݥnGWK+Ze5M-Qł]s{d/츱 |kF@Ծ.F*+‹ظ2,),rD%x-.<%mZ{ʄ A9PwՍڇގ Eo.hY@ C: h˔bǁO&/n5zշXx]4[)ť6OF2sJjbJ9 py;qx$4~Xd-~7Ǣv |,DF*Frv g.?Re$wBDZ8lvm--''|FFZtweBy*{l ~L&豚G h0>f+,VMPqD|#OΛ'{?WѕayqA=*Wc*rzP rc~Bs@#y=9A8[pV6OR\|GTĠ=Iso, BN04y xQ4)lW͉]1rz ?'ðv7,`C:`>{nD"[ h 1p5<\@+Jl{!z%sI;h #y!ضm8>u!4:א" Ϋ]rmPo 6y1G/Kp8q3~"bأWFvv0o8 gT¸p٢8{aA5gHӺ&.8ɡycp?-9Z~_eMӸ}.^2c'6j=a(Z5 ,fRN13@cx})3bCEhL`d&gHL2]}~@Db>@V&p{ZBW.gx~yDe M0d^\{ 3PሦYA6ާ#wwNsz{dHo }S@c\% ʴ OBBO,Ǟ7E?qxcoDL@ @ON{(¦vBԝ{R q{n=\prΌCe~,|M60Mg6b?")@ٺe]:)RFYúz2Dm [>CZ/6hu¨Yʳ;US|׀R KxyZMptFw_=XXřGPk {AJLa@h\xd 'RlnzKhN>dink#Ñ*\ĪOPgޜT.huÀF}pv9%w ֵcru:_\h!U]zwy^XHga~%k1y6<Ϡ f@jͰ7&h5d`)e_|+9L;cbXCzh8K^`doK)-V!E@GlӺp›-@٧0ƅO»wDXFHr37 5)mx P(ٶ&W3 #x&`Omf/t9FИ8cL2CTbLt 4y hT8f"׵tƏG34C2#'7Fo$463j_ =\!S@ynr@aÏ'(UB=Ɛ}=: OAם*i)ߏ"S S,J #N|˜OCM+@/'@#5_Q|B[Ja|Do19/f ?t\4<*֌$k#Q+Ř#eW0״P-Yq, FVw!PXM*Zb<^<ا.(`D)><_p@Ղ5/9H'~l[Δ0$ P`|lA;Y)aV E.5'8~oJh1( c.<UN᩺LjU&^PoYDGZ~@y" QeӶ3A2!RUVFߘ/P}(~m'2dg=*PgM5B#cM|Ѵ+x&NCaq9|9Bc"H⼣+,z`+ #{{ܿwi^+yJX!<3z m>U T/)xYh =e^sLtb-o&~ k gO0ԁX@\j"M0 *QMѫĞ93;uHw+F3Z~cOO A6 "2_rrC[$u ߫ݞy2_l_t =h^)UDpp 7$#.<*ą[ߪ\LIjG12W(yh5E:Kr1caibvJ称dH ԰%aldk[̌z3QlO7-G0a 1jEä$\ N¢h?~wnb~Fh:PܝkT А1]%s"D9hF;Tha˙5d KWYcfDD?!/{ZlmkؓW=zg15e'Rwx6h0x34r{C>*|:4 T< chBh҇#p5<cn#,.qʸi<249&KI اbތ2ӁX@HҰi$oZ:[Dž{WL :3%]ؗrN 0b }"J"@}cc?ApzOCSƀ a B'w^:$!M $o#=w#Ma( )M;di-BjVR: m/b՗<Qi$TZM)whbh{%8.Yȼm9>QP4+nbJS+pl~iBܜ[DE+ XhNF%f[W2RKcfO^i^Fj5i5I߁.20뫬13P~BsW򐟰>"|<e>™zu3FXtHS }i @ۋc7߲ZgS/qy$reh DΕR9E/w<+-ưi߆kmggi܋\1b!K]4621(5ڿjz/kH5mamK?rP{3uƎwyW<^S;iO6zAX/3ɺ$K,l2_XKf1ݔ.f0zz\vNG-J Z+YY14gch\]G n@?>pP8.m k4賜]b.tݙ{zŒ (\wwxIwָG'H::2GG!.[bCnz[Y{pNDi\UG9Zݬ?A3*S۰iK4241iaw/m|S14OuzC(}2:f +wNK"kK19ڳpC3F`u+~؂!AhbZa4Yfc8oH}EȲ9]'NHHYjY0Ij9v2FLA!mcGoyZMҙ 0pLH@^ 3Rexދ$Yx邴H3xO؍p9/6@! }MyWr{c>#Xa{Tjas, Ǽ1^)QF<E~+\^5-D0q=fHqhPE(.Ey3!j$$ѯ|y,gYyDo G x4~*DU ux3 |@g),s,g8@2#/&s7_F[[Y( a|?70|U@=0qNC+1"Ji12?-C;{/ />H?:ܶ/BJf"4&U`EH(BCU(,9o,l 3J Z 1ptF,*OZQo| t`~@ORdٽd&Hme<^I;7888v4_v0窺1YC*Բlߙ3Y8z*&e0맕L74uhn`~CD>Kx8Cac8{3žQ'?ȓѐEpi= ǣq0SXz 5|Fq2|7B>+TbT&00ܘ1pUw61bwXe/OiG'_@ΕaV+D޹ȅ =Lt 42xHڹ5KcZOdhXm٫%Ja AZh?1D=; ~sx<5bPUZm;`3h?1 X+PJ}Y74 \tɹ9BuVύ /atݖB1bRYP Shwg?Ap1%@;b_݃^3v)kZT@QfFޞxy*~98D]I܎Ma*uG2VƋKk^H)t89YTT%PZƬh(ʈJ.1^)Y5SP_uW# ͝<lj/{1Y묔eO23]+X9B.0~ 5ެR!@ä/&*}gf!~Vᑰ#7ЪCcšƒR}$ _ R>Jx\*jjlqz+ I1^2% M-tu h4:4np@f}1euq: ;Ê^5pix} 0鋁+U Mw,9\LA +~?p'@,ahSyXTB8xLnaR>t\Z(A0wh[/7?Qʴ:+ЌP/v ~B_cRk<_!}H h51eOx~R`S\#аK_ºXzl%U헳 38sgN,Ǽ!#^z3@~}4,a^F7ɲ%COZw)%m$IYb% r`74j +s}l7asg hEB.3u@Rа4,K,K,ҿqR hXb%Xb%XbO4,K,K, h@վɾz%|sTϪm.½ōQNI"|/Y|,)OiH9jLWWe #`UTe8F02!an_FHb'Ʋ}1D!Y3+j6+R0cN58LIwa/IȘ ] g_~lS+ض`"q* |Ò. k~d!5,y}ӥD|zM7$I.깛Lƿ+6HJy!h~ǵGʂmJ[ڃc߆vbh3Sfa $2_\MAx`h\v q^+d42=_h0?^gv «Z)u u)b^5"xLo`eS,¥,,IC@;]'6倆?mǑ)3GWlbygU7x|I奔k1)$5`jCbLV'ђDGb<f@I%o\ >(1*6_4 }  o4Eʯ. ⰾ9p_x~|F7{{ڢ|9ῦr44RBiux/$?Z"{P̎& o+J~֔Zo y@Spsꐨ>Mh=%?,)k@Z?hұ85*O4M@KvtuWJ4KO4g27΄倦 ֜Z "r2"*Sj7+>;:Lڏb *kc AQN tp® IW1Hh2|=2t$42 4%OMby SL3q9chc7*vr% 56Q%,ƒ ?XY{EhniK%!U޶_X=3V)ISz2e?bLڡ1W> >4Ӱ3N9Us ob"8/@ P+qыh9 Uy>Nn 3RJ^C'T!5οOqbPw'*!]6CE~1Y粚Bi*oxjLKU#aƃ۸y{eǟ; O#б) Cɫw¬Ƈ} N)p&nkt<'[SM֝X2,/`7ic!2R6k`> p⬾xl/& Pmtҩy=\?++]D iE h5 ?]`ٶPDA^E?(71nGC0@;S z̯ $UAvj^E8|ǟpU# D8$ QKѷyǍ}>ɵyĺ#8v8<1ytFO_]V18ud C`n(y ?݄80m`z3TEF&Ǔ ichdxtnXz.o^\GPJ՘+40Bn}O(bh$5σ1=u;~ *݆sIJ2]'IvS Eۙ_(ީ&&4~6#<*&4sJ91+F_='qd֎E}(4\'7pMZ=w ;ng hE)Ur/Ydr.iؒv$o>-'ѧ5DF2qQd֗yپ u`st`  >7!"(Nj[=Uo4MmlgpFE, w-ZN݁g(YƎ1iB/+ÙgJO;& 2\Z[jU28?o9e ..3v2jsv¡UPm>(u%7&\ZMc'qpy xIBJJ/Dǜ@H-~:ܳOb#]`XD}1{%3$/@2@cd&38Fb)+t.gwMQ[qi ]Y=E&;6{qe6* t9+tSN~NO oJh+?"D\VD\_ FR'.{M(.)ȑI4Z|EWNsoQ̬֣ϕL)8T72Dm[\ߤyf+@q)Yօi#")e5ۭ:K׼t~EH˦x|˙vkDCpD54_v_ rnkؚz9Ƞ~ 8GWFR­s<8ּ]X2jå4"(L>"Zo$] V5e r@Å;%g8bts׻_ @Ct¦!3 Ovcd]+TG怦&V%`~r?ԥtA4kŅ)SOS9G j/һcD: m,YYό;AyHo@6Rk1A ht!L)2]a^>2C#Y [T>Pt}[!o"f #tiq8RS͖ E}qIAS§d];"L,z#$]9KS@ԙ 6;99Î7QFsf9-)KP˗@P%ojQ&qy'xidmX5 V) ?@Q0grvcߝJ܈h.f+~.ҕ:\մÂ/h)[ iIۃ*{»{~\IC P`xDKt=bc+رb(B4]8z5qO `9m-[ SNmV"wߪix3/8&fXѣ{qH!P G 5hߊH UT:E;HjXz=Op>)j ¯v;/]΄JgY ͘vB%<^|vJt;U[h]rqg=Bh\ [c6A,gu5}pOL-~I!Z2j>h ;Qɴk;chlp}9>~kl}Dž}Ou5r+#xݸʣp0\[*֮<ƍ@0@[Jz:TxkAf%a^4 EOy\*-+!ᡲ:՞(/2?qcsY Xy|T%o|&>W7ėL7 dK|8 =ǰ[UN}wYL(J酐RPҍBY럗ԁ2tJExNEhZ޹ |'~kZ1|v$N']rƱ/OxRgofK Żc'_,~;&V_6t* }1؛<@xk9>IN})N s: Vw֓~߶F7d 'x`7ؼGciZ-hJDxh y5и14rE4@h+nV|"D=(ǯ\?óipbkq52,p&zJkc̎Vז8uK&*if~Fl5)ajr{1:h[Mk-4֣ 4ζم@#?-4Ш1T@coo4ݖGSY*j/w?MǤ&5ukTҾEV!.,Z<3Psx%`w\,v#ΤZvZhVt{nE4h6 uT=4vo6ٍ}wo[8eڗ5PW>/ 4֘xϘNOAC?lf K6e`)NDz!!CNbnY$,@8х14N‡'І¾8=ixmߤoۢ_3L7ƚogP+̷ he+G*Nj888.ctVIcYfv4mzoaQA`XaHT*i%{9gpa`;chcւfT)ȫ}w|lrwy}c$v‹?κV/ O{F,(\K:b|m.$;:⍲z4sȅ147WQt\rnDZ8.1RKo/ 4Y/msL?@<Ј')iW~k^|n>6ۍ56$mWG]hfF2Ygbhl=2Ye,g.Wr:߭BL:,1bkJU+GNm}x 8xI©kƻW-3ȳz}NYfڹ)]& [_`KV̸2YxyU{/~{f7w)>C}tZ"USb\]=Jv1ˊRX51Y(<}aH0J!:j~(dmvq=XZIx 4<@1˙/crx$~UuЅ}5Y. _02Q qY?x 4.*j*ᵥq7>.|V|| p ΋er gg٥.^e;ЈYPHS<[* z6q௄Tt@c֝0S.X?C*9tZޫ \?^q)\g};Uh<*ĴUWXg3s>gkbKL46Itϭx5@l¹iH<5@a1d}ev/l`1 ^K̨T_XZixƘ;m^ J ̕2^uS?%,aV݀[*"ኙ'g:)M24y| {% 0X@^yh/Nێ+iqi;MeC 4{f&3Wř'OYZ¥G3A㩂w`O,nCecS;1g}""VAѐ%IEw638W;t-><=U@o`yC?# 4ƣWC-UtkNLB=\7 r`I& ˙ ooO$:9bt!Јcp6aP5 @1aز~3'_py:bzĿ10=@c~[L87b~+Yi_8?j?`!""""Ȕfĉk'<'ݍȐS+ǻ+p.\<ˌ(tT\t.ٹQ\^#bB6rK,3""""|h8mJ +z `'>'䙜L>͓@eUA/;`ȼ@@CDDDDB+FxR`fNY\Ŀ){~̗חC_ Ͻ3?oĺՋ0ud_r1k$hF1 -ݹM^smPsmGvYGźRx7 6_/ Q@3Gqnxto_gp6U7vOǫW֯ B_mR:}۽2c!""""G@6ȡ^ k]QX/ h¨{VoD~SC2֓ ޭF~! ?n8[NES?fl܍ȅ1ؓ@CDDDDoJlohBsJ 3דr~Uh0^"4G 3zLqN| :֘y>{GZc EYM;b]/)ѥWˌ(Wɹ#IaL:Ԉ7ܔד|v: ᗧ-e4ѷ#IC.7'bQL半`*>.'6T 42' ,kS]% Q 4&3RΝ\O pv씬uی׋yM[ѧ!!I񸤃PC 4Sߙp=~3~9To1iĉ)OCiI{NhB8w;ݥW45uhMP9O1:w'!69~FDlO}C{!:hR 0tMT1&^v֔c}*_X;gI\sFבԇ 4ul@CDDDDF'ܾ&XKѿ|kQamظa M}G4#}R *f4q-mTvYXkf@_5*ڎ+aX6u!ï{y{Tac>, oN_Mѱ>WEb/ˌ(iIo]3ǻ!<']ߏytE%W{C-M~n=l"~0Z 2uqFHV kR:9\4Hf j% C)HiTXtCreation Timeпонедељак, 01. април 2024. 09:26:06 CESTgzIDATx\[U]BD0;0 v"}k] ;nQ@`@, wA_~^ww윇sL\r C# & f  3a`(P. 2a8pIp lKz}W03);Ōw #AļtT2c(И= GGsG脄RIoY.8|= #ygUe$*H( k\8DGG9@DFFǏAf}u ^|u 7U!-2*ITєC3MIUeCAuի0@Vfa:yI95j|||7jp !u=_S˪h:*QI|ZRKllӧOPGďOJhJK34pvv>Os=y=^zϟpfc?-yǔFUI!|0x'G mf޵k}-yhQU FS5FS찬<ú/^DGLPPdlJwLQUAuT+})v:BE ٳgv_]Ⴢq>1Uÿ$z4FSDFF>TXnmTU@TOsSYjCDĭ3G{6ޏ9rVSQ窊 &?a_ihʊDxw[8c7CeE}Wj׬&RZeeT:`TU:/ͰCkU펡cշ"ĦL9!F8}Y<!- >k׮MYZ.]S!/iϒU")oNý5B#86n ߍʇ_PT;0I#O֨#}O DuwezNUϖDGS#q{cg6;v٣1G'mNNж(,z /||U#ѻSk4sj&-:K+uR[2:U3'4nL+2>՘ܿZ0e8jÖӈdQ98eVpvrFn`G8 .[ù {sx!F8l s%C 圄bER,l:6OJRD}v$l,kз1;j+G3̈IvhY5r섅'^'IԒhѶv낶Q^R C릪2Zbĺk #m*vE ^?[f61;vļ㯒Fhֲ9sn!~N(*g={Dٻ8)[?+ߝ&+m`fT4?Lua*IT)6o`F_dvǗCs¡I ;=5pF7DaIWU0 ߍH]FsIš\{HJbl, ">|@xc?6aa(w 7c'{377Vlf`Ct'xS%JH/%?UDygwbhhw5$}ŕ=јٮɔ`B89]99ªFZSo޼UsM1r<Ķq-T%'8:C+pCӹ]'|^:+4g &Qe[n٣ѷS+87vSs9 Wͷia&8 ûFSMТ]w   4C^ѦĘe{q㝪g1_'l]b(x ܨBgbHh–n` Ç{976mM2l5yAtd[hqOsz QiHW_C"nJU?I*ETUITy˼!ZDUDEdzi$*}sV?k)b R|** Aƙ2&$* _#$* rҺϏDEKT#QEeK"(*[Aj?f*44AYI*11AY A  A  A$*A$* .*߫078mA8l_DJj"7# A*י>e?OEm(Puϳ}?Lj / ~#3}9JTO?w$* HT/Q} mk4x_~scľ91Yx,ImC QDQ}~aVt_AabVSO,:\m%()ijˣ}8x},mPF Q;K`hs'$_IhH^hX(L LPzG9BC"2ziT`?FAabqm1̚CP燡Ս[Tacػ, % |vnVu?XF&XqO ,o"3{Q/qu\vs凨DwlF8JJ#Uv7}<'çE!C[< hj^ǪS$"*9^IvXV}v{#!)?d`9'I`hd$~q|wq80 5#,#- [OE%9:_۷71|+ sIPrq|~b! iQV*xJ"?-^iA\T|R`O]2q6aCxo,Dm#N܋|R ZTnbIQ~wзhp|&=2Y &[WrKTh; Qe,B-IQ ܗ2)Txo:ۗ@>&i^)=Xʤt , \ǒڎ QPQI/̀4ƄƎ9a${#ńv*'I'NDv!rښcs'RbNgA+e~Eеo9~cs~ɓ'{nر`9sO>*I[͛;dnqFnv___j5wF}Gk- HTYRF,۷oĔ]ƅl?mݺ+EiŋQ fc?cm}}Ͼ7 Jو5wt2Av'N$Iȑ#x>}Tf_߻wnˆb?~zYGRjIGK`ɓ$Y|+A~Iׯ_9Ib=u\egPW͛7I H"HTHTvŅn7oL+BBB8Y9/_/;@8W{=M]6MQ$;HʦWw|$U+&u˗6IMJ )Bnڒkm/z wnЏ QBKaUY鬬ɜiJ0uʕo~x0LGƂ~s3 QBEIޔ&d!Aˍc3rZGEG@!/zvtĆrd2/LNe QeCN>͍儅إ僳-? UÇ0a}/a ;U`h)bv۬1~lY'UHJj ;rbDi{YV>܁ HTYԏH A 5,A$* HT$* HTA$* HT$* HTA$* HTA$* HT$* HT*ا{DE?C?~~HTY-o߾A"DۊJz 2:D=%-Oa߉{ QDQ}E%K/6Bvh>|-nQ% o>HD:Y Uׯ_9?Fz0yC{ #gפ+?C+FT@9RaDD9VTcPJ0j徜6uP9Bet[ ?]< C_b5aq{$r+h08ٖE!f&2B^$"JW%"/PJ+٠!$gWGW@8ABTsbà|J^: U67Qz܊JLcD#F8Bl5evʗ8s>sq \'UD'Cȱ`9-HPu\(mdg0%-sWqalEGCq|J2JQ][R_n[ a\s..'J\gNܸ7oPS/**u:EBQ˱z8dʈk뗤}wAti"+2|VT%yka-H3\EFYZWPC=6U&m#<"3ty\獗 AK"9XTמ>)ȰO\{ć`#!A=^5_>sDmKhM$d$kc#c~nx#G|*OUhw *ṋYGl|,+`Ì n2G~nIM=Я4x߅Cǎh]bQyqKƢP|_-^mQYRTyc^v>]QL% ̄+NcςVSRD6,.Bt ^U`T}QoSE796wҴ륓 Qe#QEQق [랇eGW:BvG|balf:,ITBvpnX D0,Tnĭ~~CC=3Dro|PV?˗;[0!_u.CY&Q߰ *wiK'5AR('qHz ЄDE"UVJ. frX/A8QDuA ~3rrMzKo  A$-i/7%S_~ç˟ / HT؟16DE$l**;BHrϊ2܋+=`|ga4N+vkvR0M];$%'C$LJv? eV=3"mtGDb&w#CrL)C?\$pfX̻#N DQG$,+Ks+Q W$>n"Lx} =[Zbb{2!_"^d,N HTY"*v^' ='Ã8F:x8.+#5D`޻oH`¾|y13B~4n!DEDE Af Q~ڣ; jR{$WTVQg/ ͇PC=+: UU_@puV7PNpibM"U6]L'Qgʪ^_>~E1TSoc}'`7Kg@TAzDSkMalϬ\Wm+fk4@fߙT$hg\=aҀ-,ۮ1| ah5kΨN'8A!#*nf VprU dŃm[J@X z{4+cX:g[ka0%ɮ#aƤ[:Eaj Q VL^G! vnިceڽH4V֙ e9sޘZ'@xl Θ˖0"K0ٖ+îXx0zA f4WDf_6l=xb}tdFKɢ X:S2kZ74 Q(Q:- FMV  a>hYZ&sT6h6҃0 Ö! p r c?Q[AhiÌV<$g{ k8 _II6 _RhkG'5AYj =gEΝmB(7a{ *aO*QcsthxFsø `Uif$Sl:Lr=IڶVg5;`W gvgo ެ|1{mXqaӦ9F`b$Ű|xطou*⠒Up ׁΨ缬n ձw5bDڪ#'uQ&u2ݹpӈߞ HTHTl Dа.zú?g6,YJPs;7_3°_)DGPƮ7}0CyHbɸTGzEJdaE|=òt8[u^좞]KpI1):IT K&^'{QӷDqQo{ Ĉ@ErXZGI@|M Tu Ʊ9՘ΜtW̴i,4Q I^K A<(?Logzg\gʫ~ *ח:= B~1 V@q2wN(d?Q&Qyp4| *a^oymPJ\֩]: 30ѨcBv&,mW0ι4ۀDEh4SM`KfIKUb9iGrʴBC[ƞ`5^ma@"Qyp^ Vٸ,yńa iW)9t+jBc[*6'QhJ|NPT$*Z8y*~?;%&៫<-,(;"ITp-ɅtU?oaFbWӘM:8n!DE"DEDE   Z8˦ ecEqynyc iR[_^)飚u#HTp-'X8/1j10v /&&Ĩ0t^sIw\7pΣg r M)-eh8ֹ-G 祹p^uj&ot71G;xzĩ| gC_}J^ Qyp,cDn3V)%1`nv?J# Um+T-%Ecx%NhX8/Ǩ=zt a,gS砤wpxyg[-G e~3Ux~,D(?lGbsǼZ{4"Qyp^:5eDUL MCQ1a`%$*-G }yթyO[ܰd ={1M9Xc9Uw<6"Idq|cXL~$*Z8΅23U]* C?,>M)lY /1EqfpY/>hHTt A$*A$* HT$* HTAHTAHTAyp^,uî) $yQ\Lh;eĿWeL 1)NIB^]AV(f"8oTm+`,#! Vt0Kd-{,#f(csv ۡ<$ze1d\]]N`X]6a\]3i8<%uŨ}4Gv@kcS?PIR3v߰8eŅ~4ے Qyy$~OeZ6;Zoh;E)6Gϝޓ́5#cBQV>c/Ӈa7m#QyyBtg[h2XNva**Kbt ~]F~Z`a"(2J 2!dR[lEh_<5_aS;1HH{h0>wAGFD/x{LE>AO6C\!*ދOҒ:00CT"cc }îGDE & Xڴ(jNEHRK"vJqCrȓGzyF%p}hR n\©`LiVXo;X? sCO_yDQTzdur-[,< HI"vx||O^Gn0Wթ̨]@j&~'+p˖"HTp/p6wIi8Q,EcTU L౮˲DA߂"Xθ%TŭQP\cCh_<&|;3ťA7r/E씈zƄ'ab84qL.XJpO+`_r$ e!1|/{ܿrv0A%әEh_h<{48WWtYNCUup/qO ;Ƿ]sCbZMb7ImxF(X}gbdBCDE O%A$* HT9]Tк 4s/F HT/*5kjB;TƱG~Ӱ7AAjV HTuM8uz z fMA]MfVN~=/:4wD HTUVp '(gXc{wd@cL+{:QD3U ][4kЪ;/Xf}ujc& h֪mOFS>0o>Js!&lZ|Vu;aX _Iܮ*V2 cVs=3 % P1`д4]U>~Ř9'[ Lrf1-mUq*M Z,c XNM-;2xqBY4 6Vh4hY#U>k_߈ rgVQ 1(p%uˈ&gj's!j3`iyrrwxQўu=?ob:.ԖN`DEef<َ7],Ҧ=&D4c5XY%l˕cj,I@KW UQY;`BUhb&tjS9ha >Xj(ArLwC '[$,bFT|NyYD74D8K8QEV\XOxjb/ tc5YvV#.ׯ+:u鞁T D4쎩+Ӹ發foc[> n~QO[CMQXIi5΍bZ_!p~([ @.?yEKQ+@__ --P\nT~+ ^ETpєuΘ%ֻ.M>%HT9fUhB/W-i1_{8BfVcs$}y:u#]VU%0Smnd:p_kn<ұ^IS%<ǴLZh}apqbZ~01pdtI'0Aʑ3S%ӵN}aR/" n F(Vp_F$ұaRI \K<>^1mHijM@Up>zez̝>X7@wt$*/{Rb++>$3Xem9* QJT1+WLT-D3EU#&3#;ѐ"GV;$ZDEDE U/@(d,Yi슃/d)lL. ccXvƼc^(3#& Ap/N1ȟĠJ2|i֛J(`h|jy|ƊAS#OHOT}TsN"%QeQń`e4-bꑨcx?7+fj9 ФR,! 4|p4A1= H~8օP*+M1 yq[A)qA[{:ۡ}rxl¸f0sڟ`u7.Kv>_3_tS󏼛]o ڍ6`nؓqש:\ƴø~[xUKp.pMurU )~nrE냽(["(巉=?ʋPbq'!Av},#E >G ߦ؜鞅&ě<)?bgB[E~gjsdas`-.cS)= 1ro͇8?lutfV;ydZ6;*gX'Hw*XOHwOal)#tF{ag|(<0ԩIT?GDaHlp]Ξ0")FN8o1 2☎Č JE|26_8f ,7eg?D6&KWL>]*w^13j&uyu[tcTAq$P'+*3dQi˳HFBɊ ,ؿED\zlrvO*cx<+bpSp4 n : Vǥ'G3&ź`NW(; )E%G\'DFFr|b:R+O|b UG` $MFØNyG>ȼkhe*ҚI83eE0@lp'Aԡ/װܩ̝q3pJD>3|k*tdðZ°5Z<>x'#fk7!0l{t(Us)[f$UPfN΅#f!Bg>;慸bܣQ*;Y:}%} Bd9գ01>;aV ˯}ђpǓwp玚[32$Fb׭爔kOpZȠ!V$h?2Lzʧ#p)'Fq\e:`V"u\8Ǝg4S{^ajP= P F4$ѭNͫ~3P^\_|av buS 6a=8zbfr00s/fylD8yoxo zܡЏD D%=a[$OeaPԦ#\J:e~ey!AB=zUބ1N`n IZ_+'\RF-߇{UX^H rT:S^SGsnWbpvYԫT"6.* ~4ĻóѶf90ԇŭeN[h Q QA"QA"DE"DE"DEDEDE  A$*A$*A$* HT$* HT$* HTA^TAQA Q QA QA {..^:ս{]_Vb;ӭ[@?yf_6+7ۉo߈m;jWW<ء }ivԮįxHTA"QDE!_AF6"rEAj%@q!.#:65qI3},#R'"HT)X`=h; F9} z/;uU\yPHT* E%`Bh$NGg050i>0^!xR3Ԩh"TX ÚWC|HB݁A)QBQ3Ї97#G@Fl \s QZ v2OgK (h̼_.8ğ+*M380D%COL[TQװnLsT-lQaTm6^̵J8H zmxӮ-^=Z¶.&8zㅒ:Hxx8ٓ&翏RLnCd:8*t<, L`; `ȧ͚/S8y0쌑[Tm'oMXJPc-(8+v 5LKη|'Uщmw,{ׇ2q%ߏ{B š=gOGFA `(#.MG?.*I?9eR@MThY1s!ڀY-JBlk(U~nb| Ɩ^"|8^UƖn>ߖ/ +}Qe9[,B!Ok;+77aw<ߗg#5 $aIm ,\A;L%Toh'Q-Al?Z%S(QI"y o'#7"ֶ6QPXi,9QR~Pؤ.}OVTl+==eE%0cX)Je"g&dts^^~$0\T{b_gEYzF.{u|IcHa1fqD,6x@U: NBIU̸, f$QsUO=Blm@4)"@( ⻜XJȬPC"$! ܖlQb|}Jr)*aET XJ*aʅdQsD-4D|#/Z#"{[qv5:d(AQnܺsw}.'yO(FV2D+1V{!nɢJrC, P^=Dü |𣈥NYsqԥ4rm/lÆ+P,+ad)NTLx[g#L&Es?O8e )V:@\k!n˾ Qq?^zɡ1(-*a> "q&11Ga3#^,iԤFQ&~Q1*ȓg`8r`'ֹOЅħ,1Po"x0؛Qa|L#ߤ\[݁C#hꛣc&eFW>MWRWWv-2Q1o0ʈQ?Tpy{Kj@̼W~'%𢒩#ec4, #5 P?ߓZh^AWAC|̋\wsЭvoh=pGS{d$|:^T}Я>)"/# *4ذ *: ŏPK"89==^"غ]LeEEn9JHT$*A"QDEU6Յ P(m;jWW<'Q\~=/MۉmS-v*֮3`J/ڕ/=) zR25*A$* HT$* HTA$* HTY,wŋt;`ۍ@ߵoppLVars-ܼy3Esږ7"3mIYbjm;|e!2v9d ?NF7xR;eCį߈k_YT?~IJeЮ]$3e=YKpQ\*S7폋zt.j5AU8O=6w>< QtQ kq% %Qex6m.VZha3qR۪DL3qr "r0]X&{f aW3msܰ]{3zƍדY<8MAirː)ķ8C|nBe jLI%T0۴ԃGc9 rt}ttBB:uꄗOos٣mɊYm>Z~ !{NB~"na-Xm]DOYRj#r ̭.AqUe;Brphnj9:`۷oѵKNR,@={_\ؽ{=ơeCܶ$ %04-AX!b3u'CP H oi#OC2G*.J~ĤJUfN)T6| >=K**~΂t+%Vs,})hT %L;VkIs%t,J YR66eDXL>ūgwr4 ٜܹs)0 =i;Уˆנ_#3\ D%i+7˷BLbjQEn; `Oʣ;S:boꆽNġ0]i&DrCWכ01QCqEيgʟ"ekiAeX.-hp)]!2jbeu;S{ѥmNml|V!*愉{q<0s7~ -ja]a?qr,4)"BiEUtY$! p\.f;c'uٶj &{;M;wkXl~m53-/{o޼9sеkWNF %Is0ݻw̴xb1{]RC O8T@]Q#B)Oð;г ` G+M@lkąb{F*UԢ*_'͟m.BGv(أ>$E4QaNQNTC~(K );'߻$lUJȂGxRyEUaoo2;w2"֑#.u9qOWƵGlzuFF"TrQdﰮ9Ķn"M{ߘIȒYUxx8MAP_SJj&϶e# ۡ{uҟ!*/).b'&S/]@{|;F`(J[CӾOԡmxF5Z󈘑$r3#wʟ"*6fWvE}ұXT"}>*gw= +cԲK`b+ʇ.["u*|`pJG6g EF q-zQS wzB,orY8Ruv9FH7$ jj>RvX{M!l5D&-"Y~sQ{*Dt8Y>=ju}4*0\cM.+ 1m\/D@Tq;՜]g6 ﰾYƅ5XFTI@yڈ1Q߉=yz,ϺutuY҆=SKt[ľk0%院F.ņ8}9z[C\yBC~sCǰ+o\єBƢvC5`o*FGQKgT݉@xo?sWB:¸^*^T,Ϧ/ϙS}^y۠,ȁX>CGtI)Ӱ%"®ڙQ1eTLݍc'Ou8@΄оC=y {ׯs|k@Rm4v܊)؎1 NUΗW1!WC~ؼs{?:D<˙pֵ&*˒8x;:m|ts/SR_66q>pƍ\"ٳcrb d1pX|swC``F6%Qymf"6@3q|rYHՊC$2FXPڗ39O}IaRgq<_Ï"^]4ƕa;5$(eՊ@'3B(Aw?;G+LBsfeÙ񔮨W0g-k++ 33!L ey8+եm㍸_ZNbҵ1X4YM%M /RMܾ ysX ؇|ZT_2&2Nƞ>ʊyLH9[4+TſőeP32FaV638OJ2sJ,O/QjVJ4UF[saMrث|? eQQeYi)½btƢ4%+'UDdl<ͅtlM ꛒmmu-7Y@T%U)*6dӧ<<<SOFU2-5e^9V,쿟^~ǐg$*6a:_f.&]+ _+g-/*MTE =CɕbbChEUwZT*lr~?[TL'2f?(*̊ C̊… \Gl;R;vܱoAx9`ۊm3CTy* [;ʬ'|\~=餠ຣn3߿OoXx+G dW~ShjSwQqMբ*!NB2.Yrm$Es֏;:gV\01yTUMQc(P6L BGQoSwQ1 !*OA?KTɞDU@-Zf Y^Ӝ^X-*s4WQ H1ٳ0(?) „:OE"gJ&҅S8Qi\Ӗ"QD-?%g:OULWQ S)NT5O="QDM >a"uT.S<:S_cMw ˼cWJ fSrHTA,Q72':*6nDJO%AnJh*ZT&J}OsTf/^c+|>: 75E/f} m)Q4FU!PV *X FWvVm~>Z`jh(RoT`e;2r|)#4GU@V%gs #Ak6%Z`j#RmAy{5*3*$UR "Os4ʼnP0EV }yJ-,+(K--h^ 0MjmgNm'+* BCtz4:*cAMV{ A(zVU qG\6/-Am}F0b@NZPP qMRϘw\FJ*- ҪP^UbIDG teA(:+-pI%)#Mr#+sJ}EB0*!AXșry FNj9,Wԣ(t$eȻI,YsV*(V iZ^Ӥ,Am}WطKiUP 9)ԣ)ɾYIENDB`backintime-1.5.4/doc/manual/src/_images/list-add.svg000066400000000000000000000024541477034762000223050ustar00rootroot00000000000000 backintime-1.5.4/doc/manual/src/_images/list-add_btn.svg000066400000000000000000000067721477034762000231570ustar00rootroot00000000000000 image/svg+xml backintime-1.5.4/doc/manual/src/_images/logo48.png000066400000000000000000000050451477034762000217040ustar00rootroot00000000000000PNG  IHDR00W IDATxY[L\^6 n]79#Yn$UUF۪Tr/R>WRq>UjcT[GN0ہa`aΜfOΜ9Ais{ooΌ:#ͷ%72Vݖb֗& ΓNں $O_Me; $K'?Z׸2{@D:e1V)`3&_6 F_ohTlN6R,\GA_!_R>2 {XT@"p|gffvrVeҔַc ^zOg(=l }uip.2ihiE&s|.>73::?}ر$@*---455E-qRLlJ@:.i9Mv[^u _ݑHYU^^NH$5;z.,+5fox*wX^}%YnS8>!HhII +S_㻿E=^evs#-t^:ku8FgUPkƢZ}2z޼9(`Q ƿ޻u=]|C&''k&HdY,d2)b[laH$ Ώ=C/'ELFtZېD{c1:|*E$I {Vs%H$ҡ(J)xEQ؄6tJv)LzTzSe`UU t1QҖϖ)\Nt ]"!M[FkPo=}$(Jt:8.SSSݜ208R)V.Rzv}H&{(?3ohzI ٺX0/,, -?RZZ@JX`zzc xjC?[) M,n/Y }\3\-C_"|ϋe4OI:y0 fV}UUs@͠ZS|z~J.$=k@ZL 'ЫT>1 !(@ӴyDN^@Lxrd;OЉ}0C5;.3M.+O?ڷk4 ÌNCDAU&Ivp  7ZT}OБb) B)kp/Qs 6X]SSSylp?(fc`8qv5MiwWh. Ay}Qnfإ2D=T_~@権)Bp"+G"j" &&& " ;\v8;00Hl.{o.6Ϫ a<fhIj'&&XtZ[[Ag) >rzyxīUps0 Casnjj` 6ͯ17ڊ|W ݨ0.g9 k_>VƭvFs'wu=qƇR^ #(,+kEWEG%I\P&͢KLF7/0rV贴n{Gi\z  P)<~ΓGl%Z4ƦAUh۶m\[I3 đGd5x\A!煞a/ arΝJ|ZMpsдK3~ƛܺQ͛tΝ!(Mɖ;8͌ @PBQQg˨4HBV)@!\2zTɧO'ڼ_xaD"q~n%K/ekz.DVrLMpХK {{{? N]וoE!hT*z$ /^._l׃)m}G#qTOO.+8~]TUZkF}ޞsWOrlpIENDB`backintime-1.5.4/doc/manual/src/_images/main_window_sections.svg000066400000000000000000000175621477034762000250340ustar00rootroot00000000000000 image/svg+xml Main Toolbar Timeline Files View Files Toolbar Statusbar backintime-1.5.4/doc/manual/src/_images/rule_keep_all_for_n_days.png000066400000000000000000001247271477034762000256070ustar00rootroot00000000000000PNG  IHDR3[,sBITOIDATxXW_ED-FM}MQ&1FDQcዊ&& AM,ĚX1Q%, `vPh*H/.Y.]X 3ܹ9{; BP( U3  BP( BP( BP( BP( dBP( dBP( B2CP( B2CP( B!P( B!P( BP( BP( BPF2 s0/GiZBqWK`P(T%O?chѢm۶o~!K_'NV^NoF,*7M65y#G_>du6mS+cUJ $%%egghyĉxAP5 իWqq1=:X/b"38Cca̖>w'O޽ZhQQϟctݻo߾hV}?h$ґ#Gܹc:"ce]Uѕһwocu] dֺuk///~+3pa͛d2KNNnҤ lRSS)}$Y#K>Ѷ4hÇSGT}dVyewڣG.]t p Bf2srr"[ryF8t:}oھ};SwӦMd͛7 3Dy1cƀk8QžvoO8a;wqȐ!*F}_nhTX,hiڴizVZ@}]f/ƊVٌw_`x;vhРܹ3kƐ\]]a) 0p}] B,##F0cfdKՒD"ԩ١G-rvvf2l!'hтCN*_۷oaa!|-hRGv6f #.ų̀J;2 >JcII X+6ӣ/įH$d`B!G&q)9eJ/].\C !7.W\\V :O>iժ޽{NZZo~5Tk*vZpd8LhTw܁F~ae7K(Gtay} B̓Rfffbb+ :ujuٯJJw*j ~VaZMf1ҐN.-\C|JIy9tҤI 6\*#> n2wZ`RrDgϞe|G|L~6mR6RCFJO? fiuV}Z-df*V􌵑(>8Nf]t8`+//}3ud2,uUU^P($3wenZ2srr"^^^Fؓlׯ;sL.pz֝;wڵ \zc-_N:饆b0FsUV͝;Ѱ;nnn$ׯrihX9::_r%~|SBf|Z5Vz%OcEXɌfl;yzz6kÇ3Eff(,, ; 'O u0P(wÇ{9qٜiYzcZPȬ= ТEIck7I&f Sau5Cڵ=~Im K~WmXf Bf|Ze2g-d'cq̶mXdQ-ֱcGSdfju--[R0P(Ñ|~Ւy@QQQF<ȝ6YYcbua&9uz96Cٶm[>۷|ua?Z+2b>>͖F_Sk) oAA'I~m!3>L=V#Sy'cqqHԨQGZZf̥F@z!3>G4k,Q~}˷ /x,z B2$3PتU+w!O3'#جY3w^#EP))} KrSTu7x}WnmZlꫯXg }-sN"!UV^c۷~1fk)cɒ%F_~XXa[zෝL=g"ŌŌŌ}2 ɬ~ҵk׎z>}Æ #gM 1?h hs=ܹ˫AÇ}+W]t)((1au?+abbbb"!=L;w\vN:d;ggg/|?}ݻޡ822rٲewaݻbccW>ݻa n:jԨ~M4 ? 'N`̞=$''lfwd cȑ#Yc5?^3OVsTARM33333 )~͐`˗_~i˗_}UΨr-N<g/9%mڴ)jڴ)N8= ֭[XcN@ptdˢEȖ2"kNR2M33333 )hΝeƍ;࿥Cdo0|lٲeZZ'¿[oܭ[7_G>{޽;#E}رGFLk솱8}4i<7ߌ?~СӧON^ U.j %+E4Jabbbb"![ONڴiCVח<?zI6.Y>d>oLOOgl߾=3 'Mԯ_?X4h-syby֭[AÇ7lpҥd;cw6hΉ5H7g}.׉tHfHfց8y'ۿk3(555!!}P5@cçMfddd0$ёlp9s֭[Yc5'|sϑ-/"֐4Qp_bowur33333 aNi&MHX{v=42l=k/lذ!mᙙfsε9]ppwww!&8 ޸q6N>!>֌yԩSkf?g];ef,f,f,f,f,Y;kɂy/"VfZ4$mQQQ}e^ئMK.mLK>syY#ܹ| c\@UO+T\~$fj1c1c1c1c1c̐jY#88)5jԩS.__ 0_$%%EDDуH^xJNN dvuu`ӺCuG}4I1~ӦMxoooC"k˖-gի-d^~ݨQԚѥ+҉>);@&QddVC%#rTNPÎ3I-@M~)[ֵ/ 81{o;ԭ["kyyy7X۵kW N-Z[;T*JddV /IZj?3c?9s\r^+VYڵk׮]/2͛7g~eZd-77LJ<|Ğrϕ]꘱HfHf5TgϞݷo޽{/\`8/ڳgOppΝc)*''رc eحT=|00c1c1c1c1c̐P(Pk"!Pϡ0c1cQHf( f7mxlQ߬<0颊=1\#*}Q)fTfzno6f]_y%Oe~خ8޺PWcuK* AR}Dk^%s*#2U]]c|MHE%?kNI%+o}dQr#i6VDRZiR:HhFsW˳.lRjkpdWd/3 ? ;,ҭː'd?$-{2U4+f܋g4(s1!fJ[,7-k %'>N('RKfnY̸(Yx6⇄FХ~rHy1t!\*Jd/N|2ҏGlqxKA)};ȉ?L-IRc*H{YR Hh΃uaˊ3sHijaX'XzQ B Ɍ{~m{$ƊO-4Ҫ)i* =}(#C)*k!$=Ki}kŸ:q1mzBrJ<+K2c0^7s%d%ڕq~S"G-JSQ<ԟCfE\f\.J=fcUV~14襵/c XVy9y%G#31z?SVXtZY 2,g}ϐ fC2ˇf$eI*+9dnlhK MX}k*Z =ƻ*Fdk%(W 1/=6~ !mL8B]cBhB&3zS3M-|ܩ8v];2Tm(Fإ)%4ig .\GJ>-%H!Ck +fQaŷ`]_ʫ$|J!= =Z?uD%sc5svGLԵ1a\k.)d,F{>3J"ɧ(^@/ =ZRrM!>s~%"?/|Bf|N9l_ƅ 0KfX^%S T~4z4v"ʣ?+~K L'"3Е>)mRs>J啗r:CUZp$*nk9d쥯 LF_@d\.S_+2sc.|<rWM>k(G\ RT)c> Su +C?Ucj2%Yx-4}S*$RU )'PhKk}?޺=sEU_so wJ .!3ϸ~A 6HGl/ͺXrXqt2Kg|Q%Yz: )'PhKk}kKL1o:Ju w%82T)Kf, щ=`dU ÉzJ"ɳʭ\8RNѠډd*x3,w9q #}[ڊЗײoSc=ޣb0L2!3胉;uF4mV6YGjR2`~T'?ݡ>ƊVQ7]<[ZJ=KIV"`HNҧAl]BfB޾ bUre/O@J,T ~ci&QA/\r2&z>l!1mĀYK%dYIf5:SëFjX^TdZ$H,'Gxؠs3FG+*ڬed= )R *Ɗ@//V\GsHX1|~vwLun<;uɊB]Yr$|nCYb26s)?/Z5k' OADQU4VzȌI_#xFaHfGau.j0W<EI#*/k)>/"dFo3d|N4N.]$h+n5?(R2Zs@ #[*E 9w⛪k̾W>u/yp|MLLRY+u+ hKkk?--p!(,g;|vj`fŭ܉oF^1|C;LQ1X.%ZtԦLӴ?k˫0|J,{6 t*2hKkkE\8w!g;|+ s'yiݯӆb:)2hu#}W\S d9k?R;mH_r?J2R!;W0wC;~3ڛ$3]x ^o"3}\?xkeߔG:.sE6f&ӏs.?UЏ-b'UmHA]\ odUiDcx.AY\h ֣ՉBr0lLyIVa$NJ-ƛO~*qYL=V,'xUIe zi~_eXD0dH}(q*O\j`ﭑ|D+J f*|HX0Sd^J*ҲgbZNdVƺK0@\OCěfY #y9AØg0Mp^~]LyD͸&.Qڬ?~@9=kU%h6yRd˫jYCxo)Y*m _߷ h`N^\~)F4N:mNL0/Pr>] `/~Bub9FlTÏ4(\sI[1K'KN|$Hj׳bJtƆDLɣɗ;)M_nwun:>3JǗޅ8idCӓU4g"aEѠ־\9s qwz9 $-TT?~)G%fK媜"ɒ]1< x6◣bgfVwbeaʓFK%fL1:X JLߑ['* ~ O=Af}7{I){busy&0Ef#qjM2Q\V+Ûn]`K[Y*JS3 LrvEKt#dp5ϺdJ26I^L.2raedF^Y6ꢦj#i6ζDRZ9fVu{XIuf^[\`c(p(~9xnEd ͌=hxϱGUIq%ڗ̬>eb=I?d+];@.2ůduİxۃoMkoY5٫ɂtFQx2V,SeJME9>o--#/][,?(T*YJϞ=[}g wwwI޽ݻD ::::8p.]paٹs'~-\ɊWޏ?~ nnاO0ؠAFnl4Lg?gГ̴̺{OJQ|A8]Fsfܙqwdoe&tf5y^@|"c]4lXAj3`A`FGnl4L} b/O2p4%"{Np֜f.:ʙ)hTφQ2#8~ڪp+ncu'O-!7/&dn97vˠR3@nl4LE2{6lظqcu5\]]{]ZZ ,խ[7Ҿ}H$}7xօ-3f̸φQ-Z,]C ;v48KOC'NrII++P˗EEEY _sh oDE Rqcu'@B(ó.lqmmQ&@X~+2Vlqtd?36xG-(sqQhN򔝆bQFe?#'v3@$U&K]|=kΎ U*g]زb\!@l/R@ `yԂC!^`vDnY(U  +lೝIbFY!3W\ ' ZMV!fGf˫nݺ&MS%ڵkWsrr,޸qEdpdHh˗mܩƌӧO>LGGGmAk~ή Tʬ{p?̪UȌxn@ISOd,oEf#/,c%ٍ[Lx>[pq(vAYgʌ;8n ڗRZ,S1O^`~ Ȍl kO;%d9%:{ցBe^d}ϐ fC#[Oʽ|hFRF] +xK' CnO _$gȟEDDl^fM:u~knʔ)-[S2Gƍxqq1Y1Kf{ˡJ6lبQe֫Wvl4(~626@@xn5s_vGLԵ1a\k2VY٘%3hgUМ(NBi "猊 qf6>c/&WdJϙ ~twGk ;~QVJ*,4Kf“ՖIe2[x?γt*4 hP"=Cdgk֭[777|``6lwl]Bf~~~ ,رcX, ~hŋa=,,,00ЊYZZIJ\.׀&ϟ?ۼy7ӧOÑr[xd2޺=sE}SoPK3n_zЂ;Cj\KF.3Yp8DTeFZq2aC,ؼ+p@"=qL"a}!wH?}A(UKlվ+ŇDJy_4뗌f_XN|t&K'1NUbYҌdܝ<,Ry'+rH9- !,l3f l!C5mڴY.==l]BfnnncǎuttJ2@ j y>mڴWR-'om۶jڊHoQ@L5jtU =KP մ9>\fK%d=61>**~+*`8 Y`+2ʲ +3j?}s׶Gu+UpA ~P؅+ڃFxkzӨbep~_L,iddfﳆgf>|XoڹsgX^d l߾edd7̝;2| rС|)3yYii /. ŸqzvZ8Mf-52[,42V^C?%IJ&Ȑ<2[<71COA0_0"ccdF̓JUʌ5*.yzrlQ;{:oY#U W\98Lȍmw;\3Bٺ\.7; >9{>~T/O3yH8$"idL]5e}{\^d[@2C2YpA_Z*,,lݺ5vZnu4u 5lذ^zuDdL>~}||7nF 4zhXQTf-$_~aÆEEE2|cnS*|I-BYk6 ;:ѺF26rNS*2V-KqǨA{#Yd2cjpPdYP=@s׹WȽk_ap7UP~?q>\wpTXuDFsxZ<3nwkw*Ł,g; E~ HfHfv=k5jQ#o$khҤ =j:ubR T*۶mƧIt%''1c"DCjhyo6{ݻK\\%-- &E³Ff~A=}H政I@2zi;bR NejUmp敱TPQ,Ng+f<*$禿>8^J*_7&" eѷYpdj^2,"ka2z>]x J]8֎ɧItbT`ioK 3EfH.B2ϗN/3[ 1,̐*(( VXqq^g @:u,^6paEѠ} hsmG1 Us~;;jAHZv\^8SzqJ̖U9E%bzy'l/G=*X)WL;LYy}iX>yYO{~*ͥ '0p\g,/3Dfk׮]f yy 9ss=GwКQQr4p@_6l63v݆ ;v̊`-oٲ>JAk~~xu{XIuf^[\`c(SCkƿ#~{nEd ͌=hxϱGd,@f@b} %U ڗ̜?eb=/Iּ@d+];`ajhͨ(~m$3#f ~u0f[pj%"ED"bd&H$P1##Cӯ-6:A(0jhJ,l.o_-G2=ڔjz&Ji$AH-O4ٌ/?l.m"B :Z'J'cuYl$KS;kÌEaƢPHfx³ 9f,f, dÌEabƢg s(XX}(Tu 3B!c!C 33cf(!!~Y 6[̘16KpB0_"N-.]j!;ȥ'աC'nlq(KA)O?g׌1!fJ[,7D._?qB=Z $ĞKl]2ڊۢLfpᛱVdFХ~gly1t!?\*Jd/N|2ҏ[6+f+0hPJk_3ra7S DRebz!sH{Y si [V콜+d %R4~w,ZbO@ ӎh-3Z`i4(Hf )J5DU8kb@|k#t[I%dcE~vU~,7nxѢE2GЌ˗/nlʯu:::>]3V-ĕ|p?tFȌxn@ISOd,oEf#/,c%ٍ[Lx>?[pq(vfcUV~14襵/c XV9+@>B1{ig46ݰUtDǢz:P(Yd9@CT4^>4#)vfcUV~sؾ-Ѡ"=+dQZZ5ou58k'5kԩS EAAAvLҲeK>um!3>~{1n8+3-̒k޽òa@@Ճ휠ѣA/}*S5cs/A7[kn]) %펏reIˣk #b¸dRXW5ګia0V 9AG^Z3RJt?)>s~%"?/|Bf|N9l_ƅ{͒?#=VWeX2/wrF%___Xlڵk֭K>zxx0}6lw%%%f2[`;(Yd4ŋh Np8rFcEti8RNѠ>~ή{go݀X]e77lpС1P2[ a}fѬ ,':05yE4qUnh*26 )'PhKk}kb KL1o:Ju w%82T)Kf, щ=`U Éz-ѕ[p@ѣA/E2{LVoڴ) Yr`)wwwf˘1c` iӦ@ wf2k޼رccaaزR5^fwyO6mSe7ߴm_df4VѣA/?g׌(c~U|Bc.POdKȬy1ގ!PQZWZp gaˬ_0N{e؅K̟k#:kV[6+ZRA/Ti|]4 [` L~vl]BfCzoa!sc*J., x 'e.^9xF̟6;XcճtFcEF^d,ى'~Phgf>|XoڹsgX^d l߾edd̝;2| rС|)3ySii /rJ"I'3 z9flf!y>77-IڦFz0Gfr3V2:fp)ȡf zTdl7ySJBЀvYT23+nRA/jߕ!+9tƶcB.{Gbu9"u!ç g?/Avc2O~Id]$df6V\2F^d̑YLL 1:k׮mРٳg=<Rjj)ťCIIIRt޼y췘t=44T$A'OóaUrrr|ON;sȐ!VbluJJEѠڧkƦ9⤭%U\%'>II5yo1 xx?cCsDjiˋz}&/7cMggf>waN~m9Y"cOOr~5kڲ8Wdu0ݢhPJk_.ф;y~=ΎZ]*WcŔ^tǣrUNdɮ^ i<Fь_O33GK`NZ2Yg0eIbl6\9A)E2{VlϞ= DQg fV$C~~>3󏿿?Ϻd3g|;R E-"_~ٰxݻw6lx1+Il6ζDRj~ήxVu{XIuf^[\`c(pȴ_nƞa|#f3mwEsQ5kڲ8 JiXfVu{HΞ$kz].}lt F2s:blfAW#ofYLeq%R$g̞MͥMD"Oï-6ΛTDҧvdɹi߾Z3$te:{)c2m( lHK"B :Z'Jĉ0Zddg<0cQ(=70Kg s(XX (0cQ(~B2CU7BU0cQ(2 9@0c1cQ8f³ 9Xf, d !!A$Ug6[̘16KD<FKiѢҥK-=䐐ܱcGC2:t0qD9;;;**R˔Rsvh oDE RqcMu'@ٲօ-3-d@"߾i߾FХ~gly1t!\*Jd/N|2ҏvks,?0R˔ڗsT^,5vqDs~;;'^VT`ϖm.lYrfYx6H|]K|Cu $nMRV|: -XIv#%)(!3n\f\.JO!!`d-Kk_JjL|~c'OtJf2[JpdA!QRޗ2%Y֣{`,@ q=|V.n^dlYqqu5(7@TYK3[ƌ[`L6m`KOO7[YƎ +FJe1 ;d}ڴiǏg-'om۶j53-m2ԞSXX=XEχ-d00 ztIٺ̚ q  yUqbD|^_Y6>vaeR-'onڝJXgA- ƌTYg%d6t^^27>+Vp~P؅+ڃFxkx?GiKmL/E2{ йCGyfʽUul֬Ç+]];w +K,۷ u9" s2COA:_0a!;)n' +W=[lez=q+8?U*ګshܴ$i>gHXi!ç ^/r Qx)n'D/ XykkCmL/jߕ!+9tƶc[C.{Gbu9" u!ç g?/AvcS2O2I?zR$gاUVߪڵk4hp'Jxxjժud ~b^4ZPÆ իs!@}t>>>7NKK#a =z4T*y/Ұaâ"ͶX>v씱w6}6Gdžauw^4ZHFuzJEƪeI4Β~}~o|_8 :7ctҪZIfH"ͶXqWo7}#bAdiߩ[W352nU'ɺLN.,9E>~71ן`Eњ̓@@[lez)3Jf-[߿۶m l'wϞ=!Yfqj7UP#Gڵ+<贲.]MZn߾-f{Ҝ6mz)O՞iAVAYqsWF2ܮS>?pT KEe 2S4O|2EfnO=-f{f;=×Sr["=+dGQ*{.,,~~~5:z54iBFZmNo%>mۺiݯ@ (di̘10:8p'&Zk洴4kV-K;cӃ{4o M#N)tMq*Bj{|[7oW*J1a=at2; ' R-Xۜ&"h2Vflpdj^2,"oda2z>]x&J]8֎ɧItbT`io7EfH.Țm*\o^dLN۾}Cȥ|%rJʕ5[VuYxyRS+O...:tHJJJcŔ^7 {"(33s111<F0=[rSN>wٳ!Cm)))YڡwƦ9⤭%U\9u$ Ҥ췘<<9Q"4Sh=c fퟛ-} KL9rDƞ<,k26{ \-L)} hsmG1 Us~;;jAHZv\^8SzqJ̖U9E%bzy'l/G3~=-P#݇%SswuF"˔R$ge,''gk۶mYYYU2bo(fVVX-`fufΜsϑ;v45fT 8"2{ ͌]ݽ{aÆǎ"feJ}F 욱ga/+Xw+Yl浕!;25f;2ퟛa|#f3cWwEsQ5[mm[־efa/XwNf [rv@SCkFEk#x1l63v O7fnRdL&;\fTpJNN656E*fddPT~m=Ti3ݲR{޵S2V,096Wˠb䑮LgO6eZak3ݲg6cKLΥM; *>*[uޯ-O:?V6Z6Zdl00cQ(rAx@a?ŒŌE!~3B!9(P($3T5~(Tu 3B!c!C 33cf(#;qݾ}6k bǯ=9;elх7KUآ`n&rJ g6[̸(Y~VdF 4>;2JfFknN=,(xN,ZbN]yJs1K6 a^A[#aB |34p+>;{{_vB Ok" dlt?suf1mWݺu'Mħ.!3+ZEKk׮Xd9==qƋ-z9dRqO^m ;w*1cӇm_c}ʕ+ϑ#Gg?gUKJNYm(1 9O|2Iݚo"c3tʑZG-J2SiՀ8ӯ-6e;='2V%v qX֬Wa#Yg}+UŲ1W2?0|>2c0h>u maE~EuP`٭_3&׀98dhqV\m>w!V2HO A0 ep\O(}^/ٳEf۶m ݎEkټf͚:u*((h׮ݔ)SZlɧ-do=ƍgajC2pO944,'$TBaFŶY^=؍xܹs|ڳ{:{ ܊kn] %펏reIˣk #b¸d1$ }͡9Q`9asFE}D A/ ˿oK)9&WdJϙ ~twGk ;~QVJ*F |8@*osTb6XUƳĀ(PSaz>ԣص;y|"=Cdve˖=xg{笱vںu撏L?|__ 6u yzz-X`ǎ|~ /^_ yzȐ~O>#G?NW{?yȐwwjQ'/|~&4jL[3v_ĭ^3Q_bwH?}@(UKlվ+ŇDJy_4==B_XN|t&kHf{Szyy YUfJ3c@qwtKCvUWnB-JruaUc_$g>uVp@':k=K3[ƌ[`L6m`KOO7[رccaa8R5^fwyO6mSe:5k쭷6m4i8|gUo6l4jի};y+Pٙ}ݯ%{ш[`L*1`lu xv qP+*`8€Y`+2ʲ +3jNfdB 67;8O\Xsmz;|3fϗIdZ620_4+Zw}/ٳBfBחy 9kxzz<|յsΰdXپ};0[ ͝;2bС|)dFL'38 9 wZƭ.y(ͫ:~MK飑 ~ٺ܌ ͽ< S=`c2(`瀇+36v!6/KmBɱE k=:o Sywg{Ԥn+j!F.7n^Ql]dHhݡ8fp&,ןLg ȏMftt2OF2S6+~QSVLL/q ᫷s;SrG}|"=+dlrJ믿<+РA+xxxjժudiݺuW35԰azE%I233iܸqZZ4hѣaERL'G? PMT~'-Zo^7oN 7<:Qadiݝ}W35szRjY d>>_&"a=jd6FDƦybKm38cnqSjUDkqtP%8cŰ_o-X>pXK.)+"NN2ixvꪓd]Per" nPV\{ hZ%][, PM~JxH8q|"=+d/3&Som6@ Erwٳ5kN|Su 5rȮ]iN+{%ڐ̀ׯV9dVPP`c}]θݩS7? Et_oO?26-*(c]>;n5C0Vq7UH^12wb\*J,c 8~ZY6{j"gTeeO:"3>nx7|֌ hu:|+ s'yiݯӆbBȐ̀z:afYHac'-].`YNAelW3m0`oݰ?iii1{WnH$z+>~;cӃkVwF&U:mQWPꖕI2cGxX_J\(e3SDχ;擏=3vGIosDfMgz"c5rvDjAZ:hVwFAH}(eoүevwH>MTbL[>K$h,ephi؏s5|Y({i?YbV=J5Rj7_Y!3 { ԩx,VޏҡC$8m͛7Sz݀ݻIdffN3Cڵ+lРn{_ҥKryDDD֭ '02d11*z $IbbÁ)ٯF}*VoƦ9⤭%U\9u$ ҀůgŔ^7 ͉Ȕ<|yC@ϘB٤fg =.,ӯ-'{avƀ/{AD޿;d{ii\Ƚ0 n6a#A@Z=OOS,Q:<`J(~k_Zф;y~ΎZ] |p-/> $S$Y+BZφQrþ̬ >,rŞd)Ozޱ'/_w<I\J>?pס9Vꦬ< d ujv7S_Fd_U}g fVVX쐟ϳ.̙3{9cǎ@A-"_~ٰx裏ƍK0-[0>3>IAׯ_߿?@0rR>~z3>eŭ]P+03?8ɳ.k+ Cw  t܌=7"2{GfG",gO2>sT% }Du[ڗ̬>eWXEr?'Y3wd;7PHf.^G ͌߯;K6S6^ǸxZ"LNZƹnKdPljn$ T7UF3_sIlVMKKKJJ?'DʜF>~Fd,?Y`rnZƪeP1C?T_[3VQ~%ųZ6M$H?ge*TʜF>_"Mdrnd 5T|T(k_~%ųZ.@]*D]J_$3$v@=9ŒE蹁Y Ҿ} !lf–3ff|GDr(gҥrHHXر)2tˇݼyL&:qq(KA)''c>뫹tI'h\.n+뤣G_IJܼɳ.l3G{.Gx6̴_&erVZ2c0^^^u֝4ir|||h/Ѯ]ׯOGҨ7nh"(YfeӧS,@0ׯ_?R{}2V'`~~4iٗ_K(Gdpw.7"LQV eG[%3lƲJ$5 E+7?R$3Y'3"""Zxx8f͚:u*((h׮ݔ)SZlɧ-o=ƍgbRdF| (^zhKkqG}Ξn^}µba ~ ݻfuȧ-ǯ__)hI YZ2[DE5.V=7Wi=R$3ى'Μ9suRi~nڵu}ÃϟapWNK(o;vIŬHxEX `Mum[_>}9ѣnH9NѠړ̞J*7m6m#eg1}W+ +-5[P|ݻK[BYh=0"\b"3L7KMu $CHǪCCsphKPHfKfЗ.ך5k#Uu.%̖1c2ӦM@%Ӽys77c:::ŠRk Y6m+{e>dfͶYfz-h-|&MÁc z= i\"A:ql!1B@fuxU6iI࣮I,`8>+gyʦMeA223f Lj{S/hrٗ_Z=R$3[Bpʕ'~['Ç-;woo%K]FFٺAܹs!9./rpp`(MftfɌf[ | ZG^TޚaAU>+W篿frE+~`8@" `J+cS͒6owWM U#cѠ"P2۷oǎϭ]AgϞeohժUaaa֭ɰӺu fkaÆՋK$$e>`iܸqZZ4hѣa< Hlql ͟??#c]J3%z4O}fvX.7ꯔu+*_2}Lud J))>~KZfd0Ɉ믢g,ݲEdiMdp,OODfѣA/E2C!dymhN.={6f܉oFٵkW>-2Uh:v].nys9w⛪krNJ=tҏGo;zF~tzkX 2c_W#?m>w4Hf($3T %3[4>\M_FސNФI;WU:ubR}um۶nnn|D+rrr3f YMfVn͛pDΝcL:]v쫙iii1G^j72goKj 6u9YV֛WP꒯F)U6i"&B]QHK'N fa'3kLIL?Y9)ލ}5SAЊ4Hf($3TM$?޽{@[l9ZթSgYJMMevpqqСCRRT*7o-ݻw D'Ovpp)6(~90`>3JNN/0zb4tЮ]QdfόգU+/^d-[LxC?L*aŔ^W,~=uxN,>x 1CRS<FˑdO-MB,9_*i3ŲF}"~*0PؼrVEOF'Y$R$3&to'NX|9fƍwܱn$ìY}ZbC~~>3󏿿?Ϻ73g|;Z3*_hˆ&Ce6bG}D66nxҥ|n J}̞^+(V'0Ϻ7oh^1ћoZ3&_. ft6l6*GGԪ~K ddVkX*(((5|sϗMBRS2d6- Y3+~mTE={6̴_FeK%΃9jTh%ͫ|-#P5̒}}}\VRݻwiյGѥ%ݺuj...۷OHHD@Bٲօ-3f̸Y(~ry-.]j!;"jj#"^QQQUhndfN\ү%@rD޻eϖzwMRN,bϖm.l3G{.🕈IYQ'- ,~ SdVMm6D^*dB2CD2ٰaǫd$.X,`-:xȌxyyխ[wҤI|UtDv_~NNE7nh"L%h3#`:::nׯ*!3{fN" GUa/fǙ6}%rK[* w{ 9rs-&L&(UGSԾ{UYF2C!j"ݿٲeܪsYDDX '׬YSN_ڵ2eJ˖-ԵrѣǸq0^\\LVmsD@Ճr`eSX3ͫϜ&6HKWX(M6sSG>um>~%ʦNFKJJՒ|(SĐ[,#P5̢}}}% PΝ;ܹc~nڵu}Ãϟڰa+yUP[`;b1f /^aaaV)26ӧa;ǩ-CfO1c6 6呏ٳ>^㏊իltЕK(G>[݊KT}!۬_Mt~|.&FO᪐+UGyFR}l82 U _~e˖-G|rPPвe⪻%̖1c2ӦM@%Ӽys77c:::ŠNQ5)fwyO6m-223fmɪl2{Z i\"A:ql!1B@fuxU6iI࣮I,`8S>+gyʦMe"223fm Uj ddv RRR-{l֬Ç-;woo%K]FFٺAܹs!YY/rpp ;EɌn,QL#YCfO+cs^U>+W篿frE@B~`8@" `JRS 2bݲY2 ?Q?Uk ddvԩuֱ\zz>S Vɹlڵ 48{,{GV [nMa5԰azEX 8ݯOƍxؠAF +*ʬeȌfm*l2{*ټFΝtEEKo2gpu DuR6%Vn>~(11Q۷Yf'HvvvTTQ23I8k̙Ν;$3{ftzJtI'h\.{E?[5II:x=[ٺEݻ̢0~0:vPZi!O70IfVYGCcOe:65UPѫaO1BMlQ23I8(?cPHfHfݿٲe˅bukOC[I%u O(,Ut6sZdY)jJỬL&(Ygl4سpj*+*j+7nHf")6U^5QdsF2C!5dv!E*dÆ qWAKxo;vpDo߾dVtJe2 2BӦM?~|eCl(m$ѽ{^y8ggRc`JH!4l0##|v`̞ M 8+QtB!63l]&M}1IԾ|1Ezby% a!,Oٴ,&Y6Kf46DH&o8ȏ o2I8a2 Y޸X;#P2~ժUdgf>|lquuܹ3x{{/YVoΝ 2tP>~xOtt2[%xҩSv{u-?? H/={޽S!3;g|WkYo!N\[~T\ǞcBIV!Æz^ `JRS` ~^a2mdhYiYվ}ォ+(8'^=lt}>x_2hPHfEGGXB&١[vm Ξ=ѪU֭[au^4ZPÆ իYH$I|<@Ӹq㴴426hРѣGÊJ2kNft˶D^xa޼y}YHC޶m닋v:a„BfXշ.<14{s']Qa' fk(d J))>~KZfd0Ɉ2m$+/˭mIr]Քו!@2C!j:i 6?~Ҭ_0| ̚5s'9r$@ٹiӦN:cǎٟ왱ЯLf%߉/nC0{T]#<>O{~0vEGmHf[ S/1eOtǢmZIuxق0$3YRRҲe\\רQO>OD^ѤI{DԩsZ](m۶u{,S,9993V#3-S!JoD/W_}'-- `um޼a_$3eV-աE6u \V֛WP@(Eݺ&M$_P+*b` ,XC22%: X,j` ERs动ëRWײX U{-2:u,^n ˞={!H$Ç2e5dȐF>p,ѣGܴ''c0EŊEz$E78$}|o|UO}@6c𥦚˗y6#0޺IHпUKٜɺij%!/&'Knj.>9GYۤOHJI Q_~e=dB2CP2+**Zba]3[!??X%ߟg]3g>sd{ǎM /G^~ef2=ׯ_߿?Bj6PZnaÆ:b欬 V[喍ڙ얱:P?ңG&wxH?eXkSL-+jYd-mֿ;22L4"P5wܹlٲ˗X"""vu[eyyy޽{{rj!!A$g7[̘16KtQ2QjѢҥK-=䐐ܱcGSdfeJ!>~mnfΜ  gΎ4R=3V:sIKt`){Gt3]W3 [޽,( 3 cŪ ,~ dfeJ!>roo]^,._jj8#MlѠ"P5nݺlٲ"ּr6r.bjWݺu'Mħ.!3+ZEKk׮[:ezzzƍ-Z$ɞydfezǏꫯ2WHaM6ӧOg[`:::L/3cuN(d> _|0"7oǙ6}%K[* w{ 9Z:63SԪwYL&zQ22ͲiSů^yTu}M6' PԾQnez) U޽{1[gr^"""Zxx8f͚:u*((h׮ݔ)SZlɧ-do=ƍgbb̬Lo31b{wwwyX^zCN!gW9M>*6l6yPܽlLQ|Bf|JMb Sdfez͍l>hXn%!'htR$3&Z߷mۖ ~vW}ڵk֭Ƿϟ?wÆ qWAKo;v}jqEL/=ŌUn(lDؗl,bjtf2V{bx_|7Wч+"\b%3-,pd0ysErs'PtR$3&YY-[lYlp+VxD}erXݝ2fBcڴi#]zzٺ̚7o6vXGGGXXXX)*bˬ_0 8M6m-ղY2Xfp԰aÌ k 8[ vR_0'2#N(̂^_[D^M(b};c.*䎫'e/dd_ 2>dT2V-y3 O ͞%IWT$zdI&ëF! WWAd]'jSR˃|*,j aå_E-+e:-e6V0]ͿJJyxjHf($3TM$3<e˖ŋ*9G@ vrwٳ5kN|Su 5rH>dfbR=w˿'7U_# G7]jQ-Īr`/<\DXXٓ)+m-KPHfHfw޲e {K||h%''Ǘ rdJ,m3|=蓪^^^C III2>dfόգU+/^d-[LxC?L*aŔ^W,~=uxN,>x 1CRS<Fˑd r&!`JٜzX6fmr2xƞT/Z$d~%K,SJPHfHfe]vY~gwr.cfakŊ ?<͜9#;vxԒ](~98pE/6記mhԭ[wذa'Ok[Le,3{Qk0RAB?y ӿEs]&֌OÇYO. mtTR6ѴU}_2 dd?yt%%%*J[TMMD"YS6߽{yiHu| FK9yX<ܷnY9o?'hUZ)T:ּU Hf($3T%3AaaƢjSƢPHf(PHf(  B2CaƢPHf(PHf($3 sPf,X BP( BP( dBP( B2CP( B2CP( B!P( BL?]9hPBIENDB`backintime-1.5.4/doc/manual/src/_images/rule_keep_last_each_day_for_n_days.png000066400000000000000000001455141477034762000276140ustar00rootroot00000000000000PNG  IHDR @q,sBITOIDATx} | WO} TR򖄖J^K"bJB͒$/w91s=w3{Μ9gΙ3_9@ M@ < @ y@ $@ I@ ȓ@ '!@ OB @@ < @ y@ $ܹsXnhZBv`h, A<ٙ ƄrV)))YYY)--}f7 yqcՍxy`̙LRYY!믿LXʓ޽ GڤI(ÃW+3[x8k^2HMMZj5j9r$G><^ɩu oJJ5Rz1!H^jUf@{Æ ׯ_;5Ɨ^z v8'zΝux뭷^}-Zq"H&8|0Z^gȬ^Y嗡駟2g5(zHNNK$k*NΧV6 4Yի!0Cy[nQM:WJ8pig:Svmپ}{8o&=z4Q jg,}ÎiӦ r5u`Os<;q}P_@`+F+@A/Fxxx|Y!Oڵkׂ @X,YqcՍxx𕬬ĕ+W2~g tBjZ aoΓ>cɅ9H'f.\ئM>t%&wҤIygIC S+wloa!!!(-2QAlh L5u#K֭[!M^ɾX(cIDh8fǎ"㜅Bu̙3 ;1|`Q&Zd2 ?# Nֆ 峀 Csww;v %,ۯn3ē ѵkWf}yR=HG>}>piQϰ{޽{YUVQpԮ]͛`Ŋ5j dk8j(33.;Sgw̙3W;w.ap?"kƍwtklY}}UxkuO pQg?7s +~K/DΚ5vI5k?ӀʟcK-kxWS~G-qկ_鸦?> P2:?GA/[c S.Buupi vIӶm[Sά?ƍ/[LRڵ.p瓡pIWC9<<rM0K%w%vԲeKu[ծ]۰V| ȠZ6zݵkW/<҇#4kl|Zd)ؒ֠s_/sAz-ahI"4ZY^G? vIχj;D;>.BkϾ}*;ߙR@:Y|pXx1B 6< Dؑ#G?ZL3[+@dd$hwuuOTY:w ́R`ɓ'Ó<ϲ@<|بQ> `TpwcOD%w3ftM>5~G$ؐgי9,570b{@Jٳ7nLFt)"Onݺ}a7gQ$ӭA3٢~cTʨ5xZҊMս{﻽,y^}WIVZ-v?ׯ~-Dq&ڙaP8^<ɡg yzz2CGڶm{)mqioAA鞀'7(O"]I%3=$''3UFyg$@9>#``&0M -2ܕR)Z\HsVu6 65,c8͙̅S(Bx{=SZG)3sd^<U)kبZ9J{Ny^x@,p j͚5m,o0H$733 rm/9C$NӋ|r*;m4S@ OB}>@ OB`#>>ٳ!!!Ê\URRb4III''!O"//s +s{I>CN3#G[z]v 5c$$$sȓ'5k?t~i&}ſd2ԪUܹs5k3L}C|vGDDD||y$JZ"^۫W/&}С$񇤂@U_zov޽>>>k&#=z1$}/_^jۡCB &믿>G1IWCDDDDD<8~Ə/])nݪQI9|0u}'|< yqS> R+7nx78}7>=::ٹurepSUV*aGQ 1 6H6_>>>>oIIṛ̑.W-Z ;}e #)MnH%K#o߾#/{_FF[f֭~Z4iR>}`g4D5k͛Dưa^~K{"i&'֮]n-Бg}.׉t*D<9c|Io =zS`x{{3]SN!L8y饗HJz8g2rM8Tj"Kr}}}}_ȓ'Ň~\nnn,h?xUV̑pGL4qqqFxχ{Z%۫W/3YfHV``;<$''oٲ$H~'N`Znݺg7 ٪ʗ*IIIO"OB; (([fMʪ 6$߳{V۵kױcG׿;w1W^w_l)S qʕ$qI3 .9mڴg]Wnr?U)>^sOOOO|y$8z(s矜\!cԨQ ?z_& 6,++ 7{ϝ;Fftc<<YA 3m:uҞ(t:'sjfD<ɦ뿔55j !Le CDOcXW?1pgaܼyNNNv m߾};fV[TuM>>>>/IIȓl4믳ݽiӦ˗/gcWٳccc|Mroݺ>xcr5jaOǤ z>>>>/IIȓˆC1I' sdaB-H2rJ5lFs_T9eeRS@Vf@ZQPd V{|n mE\@|lg_T6vK-֠>>Y"a&Q}@H1kE;hn@hl"YvZ:ϊQ2dաV֖=a_MT ~lY[b Jxp)_hdVHi|AO˕ XT%Wr&ҥJ?ȓ4'QLW7հ< +"4%Iz6@I׿pGN$jوٝ4oOe4N^B@˳,V+kͰd0tF.cW H0I$i L[eIb >)UŲ{جg@NBLĖ=ŧ,Iۂt{emI|v 0.fKBc'yq],'8_̀1'BЍI%80 "?\?f|“蝸܂]׬.T|^ItA_Tp+ drx0!}q rҕ<^gk%BN%3"V+-7I-QsY>_qXd+"bJqDo.vM|V VS)Ot3㵤Һt\%UkbIh)Ptks_AnybwM?&λ/eKP JY“VZmOFXwYj}.7*0tq640XgXh)Ptks_<v:qs6=BlY“V=kP|4)nfZX:O.CsnmK̍-n z}xlCe{t6rM?wD( zwUŵØn!}xײ7QQ$[$D:N#[ɓuVgQp~6 KI7Dw}e:D,eͭ5]|O^J=.0b }GNң?9:e Oÿ(_]ݞ zAxRɖ+?R%I?@˭IƬ7װ[j z%01Q tT83L!1[Fܣ珍 eEdV/|/s?5vU'*?O- W4v$\CЭA}}RyCe{$29be O8G;ĕ7Z ,14Ȭ^8//=f%dOY[XCKO*b<|U͖l8t~Y6kE>zATw/``alD̓'?d0k+ksmߓwX'Y*eF޻=I^_2H&I B|jHO!DJ4RF>ֿwֹrX , |F]f&@GK3e$wt'VzR- 0}'JRCѲЛzkҵMW?ʉ!`caKɓ􌹟; V=I3&OSCeO%]22|f!F~aJeItΖ~&RDtq6+piƨaGU̓'w޸QV=Caw{:r^獏'ĊaH̡݌5k%+}:=KWoeI_p߮Z5+'O:5= tk@ϵObZ6>֩ɘ9 C歜ƞ8y7;CV]}Cc'kc{UvCx8Iߕh\@IVaF#?PIު#tTN9M5“W>5F|2iZjt^.~>fxF{rVXn z.. \֠ڇ'?[$wxWr++r0 &&y\Y8lO"\ntk9NuJ֠>1iWFPO\1"ߜ?ٟhuv!#SQuFgGS%^J\(c5v,Kd'y in znyqB=9ɓi}>z%>0|s>`qҳ>]x}>,!U7vwD]X*+my#aұDxRhGi9en znyqB=><5BHOʼ8OCpzjIFw03 ]) ]yQMPÞ>RA5-&_A̠S׿~oO)0Hm UΖNԷ (%{CzYEh\Iu\tR?,/%7샤yxDNɁs[A(0kgV&Ӄ%yIkpqҎq̖&ztOR;~#{CzـG:96$H-͒<|cs@"SQrC˥If,Ȉ/{V}.Lty$b v&T3,%yI<<w?SE1rApzN\x<=!셸\K̑UŒ%{'E/3~gO2ǂJaֲ >`ʪF3bIv&pTg ,%n' E=hlKmNY;b J@D ,II@wBDOO"? o"t'I$$yDG`LBOO"'M$$$y"rrrLY))) Š H4ͳvWgdoL ڔ&xX{^1k-k (zRi瓎r*(((DILSVX&5ude lY[@[N&:dlV@d]u.3 *׏r J-;Gȓ^(R–/_a???ٙٳgjjS^UX8x`re;t`޽|"z,\GVȊO͚5Gvٳg uKVCLO d@XU$\OPT$ n _V޻$TiUzR@kT*_Hb;]}RgT9'hH]K7$ɰO(>x%@[6;lG/'Z BZ&;vIbX 0l̓"[O899M4OY“|}}0]/}jժk䌌u.ZH&+Add$TƍSg0 ٸq#\$N" UUDž^S玾IA}W_)Kxbb+@[AaC]^EYYM~e2M9<[(}nݪ:1E[_K:'J%sbbeˀ0j|lև3!!_bK?SmAYa^Q=g),S(ͱ߂ 7'5Z +ܰ{/~U]GN[Tgs8p]prf1q!ȓ^$dǎ10(Zk׮Q!CZ2eJ&M'ۥKqY!7˓Fݳgj35k 9FK:?|RqWi~=BtEEΝdvm'+[+J+k$} j3'k`C9-==xRzz}}zJ.ݘ?Χtz'.?`5+ %=1<hZbHN.c%_/%Qn|>z'8 $iʕ߷c38F,o9.艂Vt)ZWhvwD]X*+my#aGc܆<)5]|޻<ϗ=u垉J3Ff >RT+ 9&ȓ^TXXH]̙3dN5/^|ynnnmڴIJJJ9 e:w"&O]e Pr/~$''W>nݺ 4Ȋsg{}||@uJJE)II=ѩ_OrUfӲ>a[IdR/{CzYɓWbÇ35; E/nwj`' JOFXql|"P_~ɔ\$e˖]t)SSr nwJligo 8= q9 e/=X|Zbbɒ}ݽ yV IfXQ)lVAY/ttްuX}|~r]g(U)N&%6T 3j>=SV"d uZNٜ-ᱧbE/3{k+f 6 1@fY葧K/D۶mk((z9߿E<_76ӯ_~4W6YgdJy#|Y)~9@WXjM<=;GظIn'craC-I h҄Mϝ9tɔ\ LaO2]}.kbgA/ hաg!cOk#Or9aXm/ ~9$0>uʨ*`U>L_ #E/'U6MJD"::Hי.h 66'G{nv֏{WU>i^[_\t\钍>YP*xlrmW d 5|\$%k#^V.I--(r(Ջ< y }>> xA;O"''ȓ&@wBDOO"'M$$$yҋ;}>@Xȓa >@DD`DNII$@DD OWD EAAH$/rrrLY)))Fg84[PWLhWVZ(z󓓓e2bBabbbvvEz!8'U$Azd{e) ViEY|Ҵ^OeCS45^|yI CxJJ(H˶UO%c_T9eeRS@Vf͖Xj Q:sѭa4y “kj"d,[Ϟ=5~'tH-K8 js7T'˕} u0u qwyuOb˗ܹs'\>dPjw/Ŵ5+ffZlыNq9u-g(zz2p4>%v/:6֙.p6:BM%y “;Gryvv֭[mfj1ѣ!FEEԩ{77֭['$$]^^clYH1c= E/ҥK-ppp0Hn۶Qvd?Ξ=_2Υ͚5sww0QHH+V ]]iC {nذ!؜^$Gdݨ;e*QLq0NkY-g?N(K_yVe1״J(,MeO\mCFIۖv\Q8>iΥJanaL{ Ҋ}B׊>8@t#5 vPu ]\[n>9ȉI+IE.>e#|Of^^clYHYyFVBKTis:`/?#IVי.9)_Pi\M1'Vh5(ȓ^T*ٯT jӒ0xV]@z_qrr4i'Za^֪Uhu]hРW^yÓT*ӧ۽AAA{~UX3fL^...pƍ9#669qIITWw =- ;M'&bӵ{ʋ,IIN}%4蕠ҪpLuʎ|2j^ӞI%0'Y>Y ǜȎࣷ:ݻwmIB-Uj/k, 2[nwiosl #J9e3v+ow}(Otj7hjhAE$_ lhh nڵ5j dUVSLiҤ $>zt2n8+3 yҕ+W @D^琐P:rH|5kքFc.]Gou$Gduy{?jBEi3ç.ir#>emI|v 0.f5>Icȓކ&{Cr䄲wC#gS>)/-syyyYYY)tc+80!C"?\?f|9蝸܂]׬.T*/OKYL)GKLN֠"Oz1yRttX,~z'''ӦMc"y@M@xiiٲ'yyyڵk{1U[C ^տ8w\``5I֭svv.((z5bĈSN٥r7nweNwFݹý\pJQ ?p@~:c|Any[紛~Lĝwg_M!H*fjWFЂm{2żYAhr/ZЊƚIՙ.@hJw/|ikB|%Ht֠"Ozyٳg׭[Gպ X£G.ѣ۷o;_d ޽gff-d/;w.qb8sQ }Itt$0<ԍZgB1nܸnݺĬ_lРADDT/<<|~NHUz'9'VKx$ͯsOOuIN}{3NB Δ<6[|%stp>mY|(n }Itt]ɘ@>ÃL$ r\̂n&'lpr@D^xOE 9!>>۶m3u5Y}(by~IUۼ"GU'yZn=>?.-+{p,8|V۬Qݽ͓$JmI`Vh ks'h<)::zŊLwڵ9{ڴiM6-**j޼9钁4nFbСݻwgē #[nzz:+0`Q`GRLI_A3(b R*|IƍNbW_}ۛIkDi7R(k~z(p{7edTZ$HlYO]o/uOIgfvTZYt4O>I3(b RjU\n|jP%'UWyo䣷:aZz5{Ф>y(nYGnqDX1l^9~Ѳ%ɾLN)l>zcمbW>+hJ'ql OxN ZT"F=y œ |Ν@tdY>1sLxjSe 1bĈ;].dxuZmȓժUKVsxRaauڵ+O+<<=k;WWWSE; 6jI :A\Mϊ[q9M5Wvs /xӰʼnOVT+ZBEu>ӧ=k;^@ ˌO9jJ{OEѹtkN=D5c9M5/:ç>t^.q>Rgd`E=gѰf$Rb T*[lΧJt=z3vIwp/UV|޻ܯ_w}}xa)JDutLrOf9eyO:m)e+fIy$U@%.R1[_;lu;OJإ ލ^~:)< dzgLgD)}}{-Iҩ̾^ܹsȴ>_5:|s>`qDQ^ݧ Oϧ-{j'S%^LU&V0աG޹$LoѭU|I 8PL֠"OzAxe˖Ab :5jXxeҪ͹i&)) 7{CzـΝ;@\N<9::g(z[~If_`xӧO'L;v@ѣGk׮/^gxtR`3r<,,y憓 4(%j8-nݺQ$11qذaԄס1Q>Tv\.c4qՃ[7m~$Hh=!l { zE񝂏듗'IAF|؀MWY@чa{z:O`3Kwkayכj8ϝ̓.LV}ۅ@AD-K  =E|'v}1UVG[|N7;O%g6ڳ7G\S&W7caH/{!3srUndɾ^ <+F"R؀:p}%%evyHP(|{[yw_U{%51YU/"mCFƞ듗fXē^?=İL_rkXD`6|:y{z g1|^}^߈]'r0R:'sssxΝ;)K" {w.9D$gq&,PUnuC 7d6$7&H6֙"$7vI}6c J.'U6^ljmW $ 6FWYYgV8LHܨxmlYAڮ4Tˠ`1a_eg:m8;I͸*T iǍwd`v6dA4XiV"UILGHeVMD\IȓNII_O@ }>>@7$}}< o"x#0&!''ȓ^@I"D[t'I$$&@wBDOO"'M$$$yҿ&P( .2o/rrrLY)))FN4[PWLbhVSSS3Fs!8'U$Az5d)Bs'-kO[^1F}|RI?\tk}~yXJ)+,39!'delY[@[^1!Vs^%ӭ!r Jb+H}zrLI/O˗/#Sf{xx8;;l={(XXȬOre;t+w^Wi .\hDY&g\L 7nLľ;g[p(xDЍzTOWQʬOza(΍,7r:U>ivpm۶d2`6gϞ5't5KAuhLrOFt UtL%)NOw--g?N(Kƪٲ2{,fEoOj9&'s.!#M$L|Qpmie0Vo5(Μ9SĂJ' 1NZHL(x>>NNN&MSp___+@KQVZ Ȩ[E+FyuuK;5PӧS$1]\\7no znuOU\T>e'|lv 6O|5>I[铙kwfs$9uOYWIՙ.YU~k'Ub`Wh[[ <… vtlT˪جgK5L_Ζ=ŧ,ۂt{)/Tn zȓ8 q:&!)<_*R|ɥc|ȧ-<މ-u BIe/)dd5xHOog'3QhKBmzI/,OH$񇿿JV_ׯwrrGN6۴i/--5[p//]v-X`Ϟ=ff`Vodd$zUܹsV4Ot֭svv.((z5bĈS 1;n zn$NŕָDywyRh,^qve-Hض'#X{8Yj6}.7*05c'YWgu8t+P|i#=sňOBK9J֠VO:{l\\ŋo߾T*Γ_,J:Ns6=BlYW=kP|4)nfZ_{hEc$H6j*/{me-%nPKom،9:7y ȓJJJ6lOL <<<1c@ hѢ@ 322̖%QFcǎuqqEEp3Cٟ:ut|x:“5lwށ}|ҤIhitks'9'5J` ?TY#jg Tb 3$9f(x{]]os*`TAf>ecV$U2dζ$G ] ݚztҍ9(^>I=x<ڵkT*O*UǾ;r )Sg LhDNlY{Î2qW*ao 22]&~Y.,OHŒ DC}!37\IR, MEw1$8y ȓ AXm6SC ?zFn߾=̟?ɒ%{ni,=0w\p ͓$JmI`F@@uZc婋j zn5$d*古U|ڇ|oKvۛqbpٲ+0 L 2_G/rƐ 4lDl'Ql O@5U:ѕI5.X(ZvՇbyTqyE+[O~0\U=_a2,dñ8l6^DuDf3ttDl%+ϚTy#%LT+LHnp%D[z- vl){,><Izj` ׮];""iӚ6mZTTԼys%anFbСݻw'M m[nzz:+0`Q`|BlO4oe~MO )R5?=tlѲFoTZ$HlYO]o/uOIgfvTZY$NmIl]FkV2'%bIDRe6Iؖ$MLt8Pt̏{'8pх _n#tjժV9_mE0@hӅS+ɚZrH>UTebM]:o{$h,Aې'(b R 9^B1e@ $ށsD0'< ݻ;F.SUHhSFŋ_f!--9ͭM6IIIRۛ=!l@@@ΝCBBD"QVVɓyV{d7}to:S$ܱcGhѣk>>> JII\$dFP.Nq Unߴ9I ]{odaH/B?dž^YǓo,v]w<^O^dse`7 o:S$}ʬV@> c\y) Au(Ok_MMM^VVvI???S&B{7;O%g6Dҳ7G\S~8|z,>s-18Andɾ^ <+F-EXQ)liVAmL)&괜9[.Kcfd%3sD>oW_!OzArssĿsl;.Xr%s?̚<|饗Hz۶mMu;E/'&H6֙"hȐ!$nݺK.35(I']wUWQYyejxZR`/6dn'g^O^aOzjn$LLZ4$>Kw\$УgϮX-[߿oO2k}璘JDr!YBP_uFYGH:SNFAk#Or9aXm=FI[ҀHI+g֒9=lI~l'=<@&AP4;ljV $  Xg: A8P[hn5|RV,0+eP0S?'^|Ҷ:IE) kͭTTpUOJ3\v)Pqغ[zM$2Kg6kɇBfI/2ON!t'I$_xA;O"''ȓ&@wBDOO"'M$$$yҋ;}>@Xȓa >@DD`DNII$@DD ODT*-ARRRNN +%% f !5ͳvu]rGN(Ԧ?6y{ʍYlY[@ѫϕJ˟=4Sgj%WOjڒHdGT9eeRS@Vf͖S/jT"W:E qXkմtkE/ٳ^1)??ٙeٳgjjS^UXȬOre;t+w^nZ/ Ú+\"Y:3]r$@6 k ^M2UEEґ\QVeKMuߊ@lu5C*/Z$tyM܏bVg>-j,]}vRiO;v'kbL[^ P*R ebE8xγb ~=?uuF%v/:EقW!Qw]$"dzb>AK%y œj5\/_WL=zt.]bbb%tԉඛ[֭ x {Ue!eƌX^E/\.oܸҥK-ppp0Hn۶):mv%WCLOJ'|.[sN KߵWQIJ҉K[hYRsfk<`6}ϊ8mUZX},H):oQE&&Ǝ~~~R" I+IEl.>혽9b2\ٲ.pיK-|9H ؐ^IfsDZN4aky@l Bb 6l^I -%y œ -_܎ki(je(/?4i$>e tUVnnE322֭h"L+I31]\\఍7Kr5$N" z!!;TO`ԗ}s(,t6tY$Y%jTᷬ\&(OrD)j Sn^iӦ3gإ)b{>6%Z!_bK?SmAYa^Q=gtBqo|G}ׇ̰B,9.yk3o agnڗ'̧E. 9EC}^lVzJ.ݘʇ?Χtz'.?`5+ %CFy)ȭK~;w ~!|=*^brF=yҋÓ-C=mOMMMII~z'''ӦMc"yY -K8׮],Xg] ꍌW^sӆ0œQgps"<|RuA}]~]X6k&q?XF6:cs!r~%?~jV&*Jwga`+k'9<-t 9JmPK@"޽{߿ow<vLx{D %An '%_}\TYIF=y “B!<'1<'$// >z=}3%KݻAxffٲ܋#%se:N g+M:>zA*ypOK6˓(u6fuoIJvO={_|3F\}(vw@~IPyE[O~tU} f=,añ8)l6^Du6@It|x)gҿXgJDryЗqKς}U=mF=y “ ZT\ѣ̖k׎iڴiQQQĬ  -kCvޝK$$d=y[nzz:+0`Q`GRlOԙzyZf\iNW\,z?KFV÷EFGK :T>WdiSmf&+ &|}_O%[ē8u^gddxx8?;͛~jEM5{y7>nߟ(+ "]2w3ZsD||2Ζ[,w[_}9](&}E}~;j֬d>ڠAKCcC}RoӜt2FX7's9M59<ƊvS^ {Õn޴ռxǒZP_d$˗:IRc3)XZ@t.1k2QXxjSe e |CaS; 㗅r. :И8giDbE9h#-jwfN)KN0KRԩlD>U bfNEdOIYK23 c/|`EM6Y$(NFx#s $qEZӅSŚ,[rH>UTebM]:o{$h,ېȕjm\7-=t|nw-مbB=y “8ؿ]ƂѩQŋ/֦M$9 e:w"5ydgg芯{d7}t_ u"A~5f\^>':)VP_lZրwo_D&0U<)}uhN,>|(1CZ͍<+FˁdSA{&!6`xߐj3-~2B$;'8m6".+V@tyy*!~>՞9b2DZ0ck96r%KEwOH/Y1^fd od0)E2:-lΖKx gT2 ߮oKY/f ,%yҋɓ~w$f 6V\PPPYߟgY/Io۶n'_ݰڤɡu";JNd/dֻ`ofBZ#8ϲ@56nDoe(z)H.[uzk EZN3}|!3-#΂\IȓNII_O@ }>>@7$}}< o"x#0&!''ȓ^@I"D[t'IscM >@@ O@wBD OB 'M! )))''btCemEoyńzLP(LLL4L՞_$P9!+Hf(J+䓦=G-2ݟՒ$l fJkuIy$#غu+gavSK{xx8;;l={LMMePXXȬOre;t+w^ep=zXG|||j֬iՒ@v%..p%O>ݾ}{ެY'NTqOK<p?ũOtY$%Pe;Emo&ߥi(z<'\3I%ӭ+/,4:U%lB\] |jӏ#ۇ|Jқv;< < Q<̙3E,hbbb wԉ'ֺu넄H쁽ƪٲ2cƌ{,AY1^\޸qKZj`ܶm[S<:tkl߾}Ȑ!:{nذ!iv5<ɔ%Ao6ƓQ>D1 ;pُREj)YRfZyOl@PiQ6>5xi.}22Hn2ON2\:Q+==1a+iv((O2eIۿɋa < < ptp U,^ er|||&Mħ,V`߾}j͵HrFFFݺu-Z$^y<:f^-.66r?\\\ }ƍ<ɔ%Ǐo0o aEӧO6dTK*q%@)ۤ?)Ko/$Uod#W^dOJr(7FJP_<:f 'K!S^%7>8lȓLYr|7Ύ`N3æZ< < $ lhhe0Xvm5H/,,lժՔ)S4i§-<.]7 %%%dOZ2lCK؉j֬ FXj;|pv{$%CͫdkQ$*J[>%vIS)k O⣷K؄q1 I'M$%ӭO=KIyQ̀nh4%ïy'x/sIIg]xJ1iNNNyyyiv2oyS@iNodm{Pv\nT`Ek|Od֨Iy˞#  -54Œ#4)[ɁȓȓI֭;^k_Tjǘ$!{xx0)cƌҩӢE @gdd-K{Fǎ*_@@3CLԩSǏ(K6˓(m$Ajjjf͠!(X/gffnWOrOj=ɨyB:uZ&P!TȐ-K{AFw vEԪx zA e25vU>Il'Q$bJ?lv zpp'M[^Ǖ>Y$ F@p,ObC(ZvI^^^ 6|2z,Y;wLT̝;819~|(ggg`N``l6CLItɶXZxxN:X16ǒ@"~mP_v֭sÓq>WdOOqg뒤z8 aʔ\KJkq Wf sl6CLItɶX'3O>ӟk|iK|;3Pō`var?"OB OBTO:thϞ=Iׯ]vDS8MִiӢ͛. 6w3ZC޽;ٗH$I׷nݺ餯hF]2'%bI^}Uooo뜄mI;wsڸqcIIIǎ'LP<>y`7ɛ~MO )R5?=tlѲF,9)fT˒- M>lW4ҌQQÎJ6+Γm$'UWyo'Y$Mޙi%Ja?LyyZym Bh ⤓Գfb̙39M5Ĉ# ].dxuZmȓlΰa)\]]4hn%CBB§OGx=}2=B{P6nԳ0|bfjxjSeX\|weO#خ'Z&==2 Y2&&QFCet9'9'3}*ߨ>JZ]HzKꪦYWjU- w'z*qz\rL.b ݺuMH$Æ gРApى|, 2-`QFs(OrOf8 -M\%-6g?ICȞ^6х ɽ Kxݢi\Ϲ4ݢQDɂ~kٷ]2] Qi"Kcf;]"| >Ҩ_!OB OB8$&A(:{+[l1V܉AXr%s@AADnfe!{zzK$m۶[ē^uj1H2o۷/)޵kWZrj8ڡdm*P@fxgYꞷV؋ iɸOK3,IbXm=FI[v齾_"]'g֒mhyюIy$PTf?)(;;;99zH$(~T zM'&&Z:ӷYK>x&:y?쓲dhiTˠ`1S5}F}R)HY:ӷYK>=d @@>TBN蓈g'Ix;y}@@@D '!0&!'!'In">x|@[Ć$$< 1 < >@ OB`LB OBOȓhڒHd;@ HJJ1udlY[@[^1FRPLh8I8I#+0i YA|f䓦WLi*I -1-ZM\IIƤ,}vRicLpvv&+{왚>Yȑ#vЁ3~s޽<+F`…=z@|||j֬Y777>t'''ۥK8H>}}E͚5;qtkPr''%?8t#kb85U*J9\]< _ùQul)iQn'#,I5(ȓȓI~~~jZ*>xgѣG*++fөS'vo[֭D"zfBʌ34g(z ryƍ.]jAr۶m !C$&&t:0o޽6lhvE>>@(ۼ xzz_rrr]f5(I(`QEwT`6tgvE~ e"x {=Ze!eƭDY4O[eS&'s.!# !WNuD{GLk ]2ϓyk5\7GVp(RkPr'!'!lڴ̙3w!BP'!_iҤI|kz WV-KJȨ[Ed2+b^= ?Tg]x -!hbc...qƍAu(OrOʯ@Plo}Omҍ%<7k|'3O aZi',JMQװׇzZlI2Tg]o%gM)T]]A[< < ᐘ/[0 DaaaP64v5j2TXXتU)S4i҄OY[x]t7nKJJȎQF||<ҥKK>{SլY4rF=ס<|2:мJ5HPՙSb49$>zMT +=Oz'@.ܲ]2v9Od}OʋjtѭAE@pHLH$@Do~z''!'yŭڕ a۞`Z', xˍ ̾hORyRdeWZ1Pri/x'Vvr 'cCѭAE@pHLPnݺ۷:uƍAAA(ojuw"\ÃI3f -Z = <##lY“5j>vX[TTJBTAf@3fԩǏg%I͚5u'%ߗ_~933u$0itksʓ'5J`6?TY#jg Tb =3$9f(x{]]o+*2R14Ȭ^tL]6>faOR%IN:^'%ߗOʔ<ɒ I`^>I=yy!1ٳRRR@@cWÆ =zĤ=}3%KݻA8)e9,`se:N W3S}{l]SތxO)Ii>m`:N86,>zAs@7`>=͓$ U7g~?|R? %$/o~&bh{t0cy$\II$6l`ܼy/Ȭ_vO6mZӦM7oNd݌5СCwNI׷nݺ餯hFJeV2ĠW_'ܹ"0;N045Ik(5n5=5HQP%!nF/L;~I=yy!1 "ceHLJ$@t8dY?sLxjSe 1b |C;p@k^~v6;3l0$6BBB§Of'suumР֠:'9'Ӄ|Eϊ[Dq9M5W9T/{v8v6q"؅'=哹נ§G>Ze'o z.$$CbR~~>D vHppM,bvSΩSFf#ߜׯ_X?"bvSj5T*[lΧJt=z3vc3Dz}I1115:t([ ==> :Au(OrOf9T#QyO:m)e>]U<3=z>/E2fq1Q`:6#zA־<)8Q𠡑ٺ>)&ks'!'!ضmybŊXc5j,^2 iiinnnmڴu!st9$$ɓ';;;GGGE/cO2 Û>}:' [n@@D"ILL6l07\<%3m5jѯ||| \G3qI;.1[j[7m~$H=!l { FE%Iz>yi:{|ydė= [+>a.L$jY mX`)zL`4yy±1ڄ Н'ϦO"ȓ&w"$$< 1 < >@ OB`LB OBOȓ6D;}$<  IIycy}@@@D# '!$rrrLY)))Fg84[PWLbhT(&&&fgg;Ύ'BmJc<~wܘ5̖\>Zk2zh cȓȓ 'xl 3mUZX},H!OR#SmrrNMK|4XFkhu֛M&~-g'\II$oxv7H, X\(2>>>NNN&MS$___+@Ko߾ZjY [FFFݺu-Z$^yOG:tP'Nث "##7n...qF^>HtB!Wp\XU =/[}'Г }LS$ŒVR†.<$kDM*dכrxqʪjoIi>u:8*Jo[,Zt_K"OB OBTGL:vw0(J]F jjʔ)M4SGo.]ƍgc'-t钽ٳ''8_͚5A#htIIuE_ŦM;wyzڵSGOoٗS+-%;y$$[i:?Ս7ȕ[<+zrFLE@pxL*--KJJ{LZ~SޓiӦ1w޼ytӦM mR$//]v-X`Ϟ=bg5%1W^sZX:O8p#om3t0ѣG \pJq ELϭ68Tn"lP_Ofd"k(\g(,I*W,]fVDGYX*8؊y@pr~>VL0ut Jq ELE@pxL?7nH݉r90&e̘1B:*Zh! e OjԨرc]\\oQQQeS* P zA{GN:~Ḣ'6k ԹVsiٲZdzn$$80/=&NQ!N(1Xe,I6o&M}1IԺ3=qzAWell,Ḟ'iE#>`po[uX'ȓȓIHV^MR6l#&e۷/Yvv 333͖̝;81k|(ggg``alḊ' ߿ߩS>i+ ^U KVOrO~+z5GtwgbJ= w} oe#;x¦#?D _kl'c$d>< HR!I߾ y~%jbz.< < ؘrJLfߘ~ڵkGDDMִiӢ͛. 6K2ZC޽;ٗH$IzK[ntW4`QFJ2+Opooo>iuֽL͒Óf\a'o+.%e$eѣ%TT>WdiSmf&+ &|}_O%IN#7쏯6o6i{2nv\II$ViӦ3g8عs'/Yf1|b̙ɦbĈ;vSށ]\,O;Æ Ε ju֭OnT=-udE|"8@%)ȓȓI+W߉.-51yzK/m۞79Y"VEݾ}o߾@Hb׮]-zG^~<^Y*hdֻ`oS),]&Fqeɿ#l܈~d1PryҰ$Q&}Q;!@*Ǣwy:k҄Mϝ+)ȓȓ|vWTC$NNNbmWD333TێzmDKgSg٘jO|R{׊]3w꿽'k t%%dKgSg-6$Fs'!'!S }l$< o"x'B OBO"ȓȓ$$$$< aM#'/O"ȓa ؟@D '!0&!'!'IIII4y7DRXXH_;@ HJJ1udlY[@KLhԡ-ONNdVCq:P&xXѹ͕dFc[TP *ȓȓI{]lي+V\fjdw"d|eϞ=S^: >ˑ#GСg&ԟg(z,\G5kr5"%{bk׮]N8Rc;;'9'!l&!|AJ\OPTĬO_#0Y{rQXά^eK%#E.q5"%ɒ56mYJzLbgII$\aÆǏ""##mIGҥKTTTYYYLL DN:psskݺuBBH$8^clYH1c=FE/cƍ/]R m-Zriiifa[3hv5S`;;'9'>魹~]'hbc!^[C;ktb1ifB|l̦Y1zڶQ^egςdo-ZLIaCC-)֭3?ĔSyy!1ݻ^\\̤;vT ;X,_(2}9>>>NNN&MSo___+@Ko߾ZjY [FFFݺu-Z$^y1"%(zcƌիPmܸP>;;'9'uN(d jxҗ)iP_W|ʒX #V;xPUشYYM~e2Ml\:}DiY=҉$=](n)b(^'!'!abR~~>r!olAPwڵ5j ԡUVSLiҤ $>zt2n8+C6cEVK Q LСCG>8P͚50FIꈋ/M+*w$k˧-<^I޲/X!\WZJv ٌY-Y߁+)'-S.aFFi/$$Du$Z/ܹ3++ B]n;DN~z'''ӦMcɼy6mK|)eIڵkׂ #yVìH{U?w\``5˓ [dd\o׹|N;x`Fpڔ_pZjh(z{)vv(OTn"lP_DlLQfm/̕%[>[KT"ج^MTvDG- fya,?:j+NuDYt Zjh(z{)vF@pHL*#}vxhrǦ?~N"2fH!:-ZAxFFٲ$~pww;v -**+y`hY #SN?~|U Jϓw߅VMԩsM)X޻_TyL)SGMPX˒ l@6iI֭௎yoTnOhY PҫgL//Y&dE00]Ag6o6܎/^'!'!4M``ݻnݺf͚L;$// >zI=ztagK,7kX0w\p5 9y]2dE$B1nܸnݺĬ_ZנA>١<|R>[Uiܸ5D١<>Ԩ!'ro+.%e{7e !=Z2p@eTMInѫXXԴ63I~>^v%I<[ğ'_ F&pJgmt"Yi< < ᐘsOOl2 ;ZI'g͚D3grS*k#FtؑO}zhtqׯf,m]viC/]Ĥquu:Y#-m/II}@ TOs#txjwLԗ{匧6UH+څO}z71߱*'oɒ}8}ZKAT*鈏Lzfl;#OB OB8$&߿xIF?Nk׮:u:u0|_~}Vm׮|JqU7ze˖|D+Xѣǘ1c`>4ODoՒrN(1.jDHzz:!@@ Gm/IIПM!!Y|Q:9Պy}>,1KRԩlD>U bfNcOIfZd5O&ԴC\'j2mf&!@@ Goi;#OB OB8$&%&&B|L&1uÆ {HQTFŋ_f!--9ͭM6IIIRۛ=#l@@@ΝCBBD"QVVɓ+^P"999ONyZjɇtR`~r<,,y憓k 4(%%^ʓzZPb ի̦e}:xȤr__|' Չڇe3f_kqg(z9 Bcݻ؀fCyZjɪ^g~r:N-_HR-i/ȓȓI[n_~Y/_Rjb*aw"fm6V\PPPY?ߟgY۞/Io۶E4"VtɘՒ۷oggZ! MU 8γ,mstoYIC ÆZēDVtɘՒ$lϞ\^M{EഗngIIG$ H+--T*bMGKJ$P033Բ_lBզ'%%x a'99[- wߩYV}v23SI{z3< < TBN蓈g'Ix;y}@@@D '!0&!'!'In">x|@[Ć$$< 1 < >@ OB`LB OBOȓ²2މARRRNN +%%|f5ݕ:E2)#|R''?|0f emEoyIǶ@?sU>I$$DoݺaÆpkNaٙٳgjj*Bf5#G/ۡCͽ{E/ .@|||j֬Yl\^Z^@lڵԩ'ytkPh-d WmzS1y _V޻EemI|J}9 Rcf̶j$\IIUiܸ5DxvvI;F 9[Ƨ};]q./[ ߻-k$ޏ-8sE*զpU,Y,jTI$ÇI?;VtpK؜dYzLٹ:ҶO*Z:}ۉU1X7s9M5=ƊvS^ {Õx]$-/YҷOK})B?H<2M#>3],3$$cRvvu:dc`#صkW:uN:eEH_>Gնk׎E:VWʖ-[]@ (bGcƌ:yEVKׯ߻Nٿ?1.jDHzz:!|@,: ;WOO4m 1"_Z4ב9V/)eXjNe&]N(3ut }(O2"yP7qϧiU:vUSsi33 dYyy1̙3˗/?z(DDcЂ5j,^2 iiinnnmڴIJJJe:w"&O]5Pr=>,+|hd5|a8)K.#š7on8ϠARRR[njIvI=-_OrUfӲ>p[ux6}@7!'!'IIIIwAUU{^v!/Rr쎨LɄSWCFAWNa?2Ǧ &DM374!#}^s8,l9Ӧ~[ : '$D'$I: [bOIrNIrNItN;FS]]믿wjkkeYorE{zsNE$&EVzKp钴7* z_I~wEsG17YteNX,z=jw`سgnoNbŃ3QsssRRRpp0_9}~Iy%r(111..իl&L툏5jӧA ]\eYڳjժ Hl^d2dȦMᢢ"T 5kȠ?З_~nop>IICcftVUMɓltޣV`Y]-tK+,K{Lvխ¯WJ!zLǿO?%Ϻɓ*!6S4_/67GZ-,R uVV+tNI[nTdZن0J?t._}^^G}Hi4}lei-}'-[,I999t^ݻo~-.\4hPnnh[MG-ߊtprRPP3[zQ?QRu/ OH,!'PS餎<~ת{]pG DFvm2avJoƕ&NK)ԓ} V5_}Eg: @']Sf9rb0"ŞU=>Qneee PKKȑ#WX1tP5eIjꍋ{G=p~T Z;|IIISLQ!7p@CN{[}>=BIz0ڱc66&V]cF06ZMYotz0>b{;pVL5,^<޸yyyy{ωS]v=oN./'hXrW'=2eP1feW>kxr'9s愆̷R'6&)б9¦4|:IIKHi^GJ|֯NRW^eeҜҮAiX0"QV$3۶mcXXX3Į]nbgcϜulcǎU>)+ye61bqk_FiUp/Z6^'+ʈה#3HØD83Bp=h|>S0aqR5M+jb[ϙmX"|r3&}\U'O cFƤ >:=I: ,'[K[lOضlݻw/|eRVV;H 0`Æ ?^> >>~̘1aݺuw߿?66D˗48*'ݐKOOg*^~ …NΞ;wnmm[9VĤ$tBn/Ǧxt@zI$F)'GC~YZV&tViB;Ze8ڡO33g:O)eIeddtMlttt;"pc̙naÆ96[[i3FPPPBBg}nT=s>IIy 姣4xBwM,KHz_7yRNkJpK' b-E޴YCbpQ̱B'$೜V.illoV8`}}=&{Ν_Vo=sؐfU9#={QLz\u6Ο}-V$ @'$3NIrNIrNItN^D!INjIUGIENDB`backintime-1.5.4/doc/manual/src/_images/rule_keep_last_each_month_for_n_months.png000066400000000000000000002004421477034762000305240ustar00rootroot00000000000000PNG  IHDR7nsBITOIDATx}XW5X+)ݨX0CclhlA01FJ HUDtPY.\eݥygs}޹32@  O@ @ P" @@ %@ @ P" @@ %@ :3g899@[?ڵkx@B߾}_yrCwܡ_^*??_^ ӹZZZ-Z@F5>U9rssG1|om۶_x\'9DP= M>K,iԨk]v;//oٲeΝ;kF"(>vL9uٳFQ_[*9DZ"377n۶m %cǔS?ЦMz:[9DN"XXX@m޼Ynϟ?CHHHU)--LKKLMM슋:vlmm%Kx~f|sڵTǥDDO>rʟ !_effH&ۢK9bXÇϞ= \a+̜9}('=zD6+8 B1rt۷TͪX,͍8}4,]TMYp}_hUk$Bxxxll,?!!aȐ!pm^gذa]vYJ&ɫm/P@V{\ ?.GGGh#Pl!þP )8C>ߟϐ|ݝ;w{.lJL8τ0ք߾z 6yC@"P:/VDPs丸;7Ο?ulmmu-[9O9sXU_(|fy}ڸqS֊DPl|F Ϻ|8VE.LZ@J ;t0p@nijjR ?\ FEEQ%DRPg٬!m9dr\ ]%$&&B[bUdz= Bg73* $5j$dm5#C([TΟzı:Q"F"@޽>Ux%Q?77ׯ5t;!YٳgP69є)SZnmccq y&˘q1JU$@ D?WҰzj}}}SSӰ0n-_!C(⼼<<Q%?*0~8-EDD;vD@ D-Z!ѣ2ӧD@ KX9fٳ5 D"Qpp۷޽S唔bW@ jH"P )믿}ׯI HI6m8K[[۾}g/ƍW{!fϞM~{MU@ +`@OR277 5 IM";wNCCCv%D˖-oGpQNV语V?*3gz @ jS"&^߬Y3Rgݺu111ƍK~e۶mt% ҪW ,;믿:tsaϞ=۷oCt$n@N|>) zW¨k/X@gJyyy˖-;wvnܸzj̙ رcaaacG@ uN"H }:$¨QH0&n=ȝ⅑BaG!7nzjj(--ӑo#HK%`uH:K!=ZgJDDO>rʟigg!$lww z4-YϏమb]vUX MFFF9sѣGP #[ÇgϞ=wR0E4ʳg(TNUar2!jS?7PAHVD5kYJٱcG ZN```Ϟ=㫯j۷/;q6k +Wy<^ƍ 9^#7n/mСC0yTlLm۶ZZZd)+wHjϜ9ɣ.S;jժ烝aJar2"!!D#c;W, Roɗ `ܩ_f(cccp I4a@@ǓMU&o4w]È<$$sٺu+JJHgQQ$N:EGG.]^ v 8(ǥR;Ȃד9&`u~γgd0<PD۷S%'OjT/gݧN@"Pa'ufH^!6)TVG.{&߂k K)_Ç酭Z:thU^"\v ,4m//7o.`ddD6۵kG= 9xܹϟC5CCC ߵkWAI?3f p<#Ber3 ,HM'''?pB˛e۷r'N@?C^jҢ{gϞfggtRGFF* BH( {89c`᫯UVVV=9KSaĈs!9s9;;ӿ |(U.3 A"HzHax2 5a0o<*@L_~M=HaRqN|6բDIne%BAA֭[a ڴiWjDU wޥ@ U+v՞={F.yǏYvUI@ C ʩx9TE~*ZYY NaŊRuAu455ϟ-k۷006-=zjfĉcֲ~k|իWUUs΍7rss|dGu)̫S% $???xbK`nnN/ܲe V"?,wٲejQ"T{ V"B㧟~ҢI #OY oٳijjRȂ)SP%"믿VZDP __<+>vvgY2ҪUd8@D8j@^ Դ]vPw^|ƍ?~ |OOOHP… m֭[@[nnn7od뭅߼ystt4?7yKu^^^}]FOO+8v&vXgꮙ12@ P"pP($@*Q۷/ F Y<|bR`D:tڕ),)FT͙3gD`m۶S!rRD{zO+ؙauA2D@YYYaaa 9EDDUHՁl )!!ڶ/P Hѯ^ROc+ǃ3Aؙͨg&M@@ %@ @ P" @@ %@ @ P" @@ %@ @ P" @@ %v!A @ j0(DxhPSA %JF| A A P"DPrrrjf}9"H$ %Jꑒbdd4t-Zhjjvq…^^^r+'%%j6o|vvv\nݒ*p9O@``ʕ+v 5 gϞobG a0 0(P"To߾}e6jTr|||~d+p vUkq9 /dk0 66#> iAA6klĉ)CBB,X@vnzժUarI];V#b'͛7P*e0H$ %J)LKKKJJ6(ZY*?p)6luLzzz:[글yiR|FF)}MرcA_/ԅ4eZdd*/b姳_M=1EE͈E! A D@F$''7 ܤ* <ݽ{> .)&M"_ԤV$1N]QQQ7o"K0 X\\&.b)}_!N%H$  %Z BiӦ +Wlٲ%\_!B]Eڔ CCCf@@)LKKV5<==99fRBW^jʆ$^/E%U|BJJ%& '"a0H$ Jjz)YݬY3eA2y9 B///6BOO?pMlƍ333ַnZ獿+z"a0H$ JGJJ ۵kG Dx  ۷o'%9;v֖LLLҥ ug0yT!*۷G|M  A D@̙3k~UƼyΚ5̌3fm?MM˗Ջ]8s?[l@ccc3l0j4ӚEoŢ7"JJfV$B$  AA]9rE:ÇWvqq$SNq6-ZTU5,nϐWm=M8eO a0H$ JvRuFUytdn6sssO AD> ; A D(yZZ|QS/T9p? 6tSK__KbXnb>хe݊v_>S^eŦ?|q'Vp踠Y)7;%OiQULTRtRP@]ZT&秤 KoE0H$L}#LmJ#U}J*zNBO8O(,:*HOu+e}PhTJ/ş_S>(%|T*ש X(-.Ӟs1 ^pTa\@Vvx??%~Z LfA/O|eɪ!&U'-*]L>?oZчIB0H$L}$LJpTCɅT([rI="8݅KIIR"@셕^X_`ibMRNM$*Z_S\+go!۪ U[Z,zSqD⼙Eys*ϳtS]򴂔 $i)k;GyS ?j)lNS"bDbŹ0H$L}$L]"gV:QvŤo'W^RtH %J$$@4%0YRXOԀWҥ:[pf+sic%1PZV ITLP+ BijN\T4ՕeYQQX"/Vҕ.-Ӏ7HMV5yc$  SS%Bib aZQc/yVZQ[$W"HŠy>z/ Jו8C @diQį~F t+~jlC upLTg.`)Uk)9Ut~i|Pie"vTu3G>S-,l{FfG a00u]"fQ֪ ꟊKNIN(MuC \$ˈE*.!flC[ /OPj+HyUi,M[R>A a>aD(>_"K/R&Yt*+JEdyAT+Iے6!>4Y^7NAr8"5IɭʓTutntϕO|Ы45+ E}\Lab!o^ʕ[El3G\ .'sTzż8.lfp\0]1D@j A y`Q"^HKQ򧙆גBY1]?>'IJQ<Œ[S*Ɗ/nԩ .' (JkC\X#@(a&|%ARBWTtąb<\lI+7 /AQq;' {$&Apӣ3gd?fҧ:bVߚuBgiݹ{&7pZ=zY&vbޜ"Vğ3Ow*hpYdEw?7A aaD?([L?)iPZ`>}oqQ} 9,WY(+KVW>Kՠd AAݹ%7+ yDE&jpoiqE^3#Yg:XP*ƃ.:;ibGT? @s@.Y0 nn<4MƊ6% o~C|Y A҅Eo:~@L;t70eq('? @JeX_\%B8IYZ._UZJx9z=RfhGR^r#1 )+_\/yijQi嫳8O 5K10H$L}$L}-NQi)xxQ!J4 7DIQ@VntdQJ~4N$ceo"a0H:Bz5w\$  PG`aP #> A D0F|$  @}0v. ADрA aE8n@B$  AA/`H$ /`\$  @}0v. AD@pRSS?|7nʕ+6mڶm77;>>>2 pPXXx%}}[ٕ( 6))C[ULRuAة&b,ҋswHp%iSȱmzgq aG҉ŗv.ūD\ar_IjHK=ޜ >jhq?*'O+f%O^ 2 zγ hOL;Z$}})`RRs|ަph %Jrcc㸸8-GEE_SSsȑGjӦl5jTFttt  9YvFʀ#b{٩Sϛ7oڴiP|5+AACnnnm" eG{e7lhCܗ߆a9YtPwu' S?NΌL{QoY|.04'0յ`a^1,WtYumVS6f܂bC.c,7޷- `7Xnw#W"0i %.JKKlmmy<^DD.͝;wBO~RZZZ0>&"h73g+;LIHH֍_1bСCM6 [dIjj͛7J&m|W#aJ+3HOsꠒB-q0> hƶc<ʎ$ Ru:cP#sgjQ7.r%aJPC!>ϦJ %/oVJ"0'5;Z?7\;jKX"ܿY\&ȕLB9@j/`)0BٳgɦQfϞݬY3HJ"0'33l۶ž}N>;UI&mʠ}k$QW~񐞙QD`O&?l R':ϛWքW L H[%&AoVrb3a5gvT%+:>ίXKآ֪$P"D^VЀG>},xxx!͛011J"?p3k,hGD4oϏsU%UK6BA1=ҟ!Ƿ6ĂTv(#q6B?C[o\KuH'eGp'LI[ 0FWGoGXze5d|0CI;Dfr8Q 7E+ALV,TD`J5qgdd@n;w.p޽`!0PrfĈbxϞ=PNZZZ=zhӦ XX` l2(ܹIzL)նP#~Fq.䶹+:_s#%|rqxOyaȻW}\e7ǽmt‚'}Ѐ?y‚eӌI>zޛ.Z)T-m&7r¿!5F&Hi|fU^*)j5gÔ6`}Ѐ?|?n?~I ڶP"D 6Xz;HLI}m1Ljr[`T{)\4$ǽ}܎,@%LbӳN|a)dh |W8}i2/,Y{G 8|I[L$P"DP|Ev1]/_]ÇXzj(|s;r1rnݺ:QLٶmlTzUH&m51߱WtPOM 4w.;?RB5Hx6ua;ǩo2Yω sY!Qy In=n0E VOraF{i=ͱI:?%]3[Y&]|s{E6"! aGoXo#p TwF@|ꇰENb٠!_ LH8g- Tb2r%~MJV~tһ3CClۂ4\ߎdSX"bJeAj~_p{gϜ9ӺukwRcqv_޻woj .xd?=1uTHդNVlRyQ۪„iOs$tZvLp] 5ghzs П'>ЃTM괲%F)QϼC? ~Hkh}wJqˑڻ @?eOOl< ԙosV& O3~󙷅%B[.**++f 0Ԗz 8AA[o!'Q 9 RoUR?9c^" Su['aRə<0ԖzPMy'(0 B.ZFb a0HJcs0H$ %1^عH$ 0v.AD@TLj $  - Dqj|"a0lC4PD; A@A#>v. ; h`!''kD@D@D@D##ChBSScǎ .[9))I__gϞPy'OSuTsq>(&~Z[[/Qu 0c"a0uW"Wv}FLMM*O gZn+~ ++ %BAŋ*\\\ `ƍNJOO[_reӦM۶mf\aaaNW /]#[ȭkƱc~CI0υ  =z4!!AIQQQ9rZZZmڴ͂yyyF宣3d0hhhڵk544W sU?e忾ةSϛ7oڴiP|-7n܀Ù9s */=0#ڴ.0@G'C{^nYPL׶M1Z,޽6n8)pg{GRTo^˖0GRyxqv:$G=p@FRgǏGJuTܳgU388YTR)&]"ܹS%G <ak?>{,j{'OD"e,>|tztt4ٌСC׮]B! 6Mj-ZP\UX,_S'<|Qm 5nxDEZZZ"0(6"~݋׿_Y.޲gf}Ȕ&s; x;)>HAy!y?F\y֭E'%%Q Itf+)6l%O)R~޻w%&雞ƠU@߄ ?}*χ1+H29sXQD`#FFF/1bС*o 0{lCRg.hPa*&>HAAmAa,qx.ߐ /beGU?7ou Ə;FmIn-Z$C5N^fJIzچ X,_>3C6$Odd2+w}G@'51+0Є{PCRimm=j(H͚5S0$*ğLm6;}t@4safg$d=P"8bFή`Hy:UMY;LgeISI Z8շx׮'L Kl *>|8)444͈@R~U6sM4!è'.\@@WZ)*9}4G͛011J"^~NCf͚mYXXҼys???sش ӛ3g֭[cbbDPa6lkJL[!8k.I^ߖܻW};ۡ$8-Mhe)YȲXS`%UVN,NJTVl JÊl.\xNQ\\piii4wݛݻ6!,V6mJTD|0%%`Հa~oBn,Jrȑ#VVVytܹBڔ 5%?'{[hQT*d)'L&*'z}}} MBBPYJh۶-OƢpqVo4 Μ9ӤIɓ'*lͻw !&C2ank#]~$# %ORO+#1LRFgod?SSV޾ e0y,5#aTՖeWJjnIIDHMM65/ӦM#V\ٲeK%ETvvvfkS.eH@="qjgϞQ< 5aD ɓ'|Ev1]/_]ÇW&9rdnX(&5MR  -X E(nmԢDPa׮I}u$;9Nho_^PT&v107?ğ={$r͊&mzɓZ"@.͚5#cnY9yB///RctHlm$i*Df{8$1A[Q?<<Ƶ~_7ˠ`Yް00fmmmj?^z#ݻwhRL,@qX,&S1jw+7:&2HMl֨3iiʔO &Z_&HʐC$Ύ8Y$o;[dL2HMHK3նE^T8[vZ9sP _~*c޼yrAtt4%Ǡ KeT07o`X/f\>.)S0] Jڪ)¼cѿoܸ˒[ސ/]322jOP*]G(eD-v S%%#>%%%#>%%%#>%%%%%%%%%%%DAaP"4ZHD >i'!$ J(P" 0#a0((P"U5kP" a>O D@@P%RRRڢE MM͎;.\Kn夤$}}={B͛Ofdj*g6>RwNb% - mC%"?mCLn^wSh%=%J#((H[[{qqqСCT۳gU388XCCC :::,sNs?333Sd0x`RE@|Q7## ի7n8zÇ_x儴 :`˪#nF6 WrgF]o)Cן`݁y<֟\^ޒ{KcPl{8qZAC魣o3~{_$M3(P"iiiIIIfBB׬YC8p6dEtlm#S 0fB`/4jggfaa *@˗]^,wMzL}o`7w{:ӫdрLê>tW@4$<>*)@r5<~X cz[*)R;=y 4*uEOP"D!l۶ TI!lFDD4nxڴi5"W^ek;wܤIСC߿~RN^p%3! Z7GA#{ %>1d#C.[|&l܎$%C廉H, (j~~~ZZZ$}]{&{͵k%6mJT@B_)ŃUZy?7R[n^`$yߛ߼yS喍`4n ӗiԐAXIgP`힬J"h?':46É_I^do]4B&קO:t ޞ={]틎|8 ԩS76!,Zj:::$c'Y?߬Y3E}HG{-,,=뛞p1SSӢ"e,&`}G8'uT5|oħ~Z-;y beLȻnsv:LbWr[?U /9wϔ6W]#AĦrPW&C1l KD(P"Dw֍5K.MNNf377ɓD1A۶mwؑq1][V^ݩS'sHϐ0 pvv6111.mllU4Eumޅ+wqJ]LUG層2W 8j8HCc,{NZ+Q"D5`7nPݷL7K.e԰x<==3} $LC" pp|V9T2zr&O,VNjv~t;*꽇J?HHXEQwHDCZX,#P" 0cG P" P" 0cG P" P" 0#P" P" P" 0#P" P" P" P" P" P"D@>F4` aHDm%B×s0HvBpvKF|H$ J(0(`LjA D@D; _ufL~m%#>%%»##ChBSScǎ .[9))I__gϞPy'OSuTsq>(~믽zʍ7O<J}ʮoԨT~V611lCU9I۾}{:uz JڃH$z򥇇ǽ{ TrTTT#G=zV6md3n^^ިQ@ 2 B` \UOfff {fPDD!4i ͘1DӦMdkBB‡[Ku&/M#=Yn\ٌ',uE#:>뇸/Ϳ!er6蠆ͷ?.iOX:2-'J}n}l?M쾃fS0\|_qYiOKKJ]{&{M ?HMr3336<_/-LII9X5`q)ED@P$<w F͛ϝ;^X mllF rϞ=PNpѣM6dOII I@ށQUVׯϯZ%LqnVZ_s#%|rH{ C޽bnrE-q=n})D_~JSLEFF*HE߿?}DTT 'f̘AFDDD@D9 sAЇڈXz;HL Phll,@\dZ]eFUx#g<<<`˗ʙEիao˖-:T$z wHqd_ĐkoHn6G]j؎0=3ɴ<(]`tN,)/mr4a0QWVޖYIoFp Uadݻ(/\֦\L4DD`'^zQ_www̚D@ܼ1ǐA2yR,Lcgg)̱svd*m۶ pq̜9R)%ÇCCU'K, Pf)̱Cs;r#.m0eOXʇ -9}?3ÝR)%0Q!DHMM65/EӦM#V\ r?yIPڔ CCCf@@ĵc~B"P_Us(5D|&/Bcǎ" ncS $0##G֭g˗/AݻWUݔzz.K&r۱WtP=?$߯@#(|'cnG>aL58ynd@v)^!^}W"9R2Ç+{)L:>ghE {.2:ZhF|ΐqA<%-oU0TMȎ[&{  wڹ~:&L C0zNNݸqc˖-IC7^paJJTe˖=|j_A] RH#[;L&{.ʻ \Ot]>@>aSAϟZayMZO" 5o{Y[g7T?Jշ֭UK.MNNf.Փ'ORw@ر?) |M (*PZZ Y|>_dت^ RoUR?PATTTDD.g)CFOAL S.ZJjzR " a19]]]ϟ? %_LrʥK~EThC~~~ u2K$ .KJF|JJJF|JJJF|JJJJJJJJJJJD  $  - Dq q A aP"`P #> AD> ; A P"`A a(.\UY...600ظqSVW\ٴiӶmۼ1AXXӥ؟BsyPy[tA+IIIu*⫖0B;]n32:k›7 )yGFDqE eۢ4$Z$$&&ʠܲ@XMQ@Q9ykTP"1 SېW<ΰ$p =c_Ľ}ϡRWpҟ!&7L)JXollX߿ȑ#GզM,7jԨF 2 rvZ \UOfff {Vy[>| M@77#TKQttymZL_ס={79+8!mYcFjY{7;Emk݊7pS\U8+׹*oZ^hh*xޯ qrrXe,'}Xi]VqՔ6X= '/5z Ht ϓ=Z\&'ЄݝahW,(aPl{8qZAC魣o3~{`"[P"DÇa`jРA|СC׮]B!$?wмaIm2RZd:ںuV.]Zj[$j ?~<߈> ׼޽xU-!xyVln֗$DT9)<+ K]hKx6׼] .SAW|}wߤWDjr&{YЙ^ А#摛Mv@"L-U^&ճ4_*Elzo}>'cgP yŬA|I 011qttTJ\ܹs')Uu޼y\$xƍ̙ʎ$C`dd>>>^mAoɒ%7oެSA) ɕ}J\ -8c x^*)1dr2(1Qm #Y&eݰ%BY }(TI!g+Db n5{ʎ$CFJy8=y 4?(P"H`ll HM'OB}=BٳgɦQfϞݬY3HJ"pwTS[>| 5P$9=P"8blgW0qBEy:UMY;\y}LMm*FßDQ^BO z $ !2*ğb!$6*&"X%Bp67p?&&۷*WZI>},xxxa6J7o UdP2X?~DqҥKGm5P)ڰ!u+q֧&8k.I{^ߖܻW};dr*CIhRPϏÉuW=Rw[uP"x;Ko`4d RӗiAXIgPX=v(?':46ÉbO`T:lz'J5S6IyJ_ti($7aDW/eSpFFFΝK/ܻw/X،1B,ٳ CBB)\QKKGmڴ ,()a?C>|8NaV5@qf&S¥K*2 Ǖƒ0v>.W> ^n`p2O1)l۪ks!PGoݺ`yepopv 97@0s;e+jN)m? 0i!񴭶RHL&޹Oַ9|#_(,,,?N%'N3Wus6Lv(v;{Hf/.}.@@|I28kF`iBHgpxAw<>jUH+wo]r~D%BNN\_Ç6jZZZJ8p}}} M˧Hv9s;rbqII۶mǎiXTV qg̙:tZMDCJmmˏdD#ɲF(2}ս`J&ُԔ?z*!:ڪSAZDǎx,C惬&D{l)̱.MUّ[lט|z/, -?baqx;wچ@aFn!dqErtOXsDCrʷo]D9|v>Ʀ"^,s;r1rnݺ:Qy򥆆޽{u DP7a׮Anf>qC }'HzzP(~(07?ѫWy[)ڪ9uJ,;AJ&';z>!8{>{C aH yvbA?a30*]j& )M,O+0%.p5O]V-{&  cƌ֦nLBի+;rѽ{w3b`ݺu_|%ڪSAZZi #fCH{StGK-㇔ʎ\`:#H8-[jKHʐC$i;;zz Qv`L_y9KiH-l{?99y;)mACa qvvV2 !+C֛dA7(HavԻ*&sQ@}X?Pg^'nA[9+NH@/y m(񭬬444&Mt2*?]###}}}خ];`?Ç,--{ѶmDoaYIieI[Є]9{%CelZ*kOi,yQRoFz|%0ShR__QtF\WEcAJgϔ2h ::‡<?xlaRRRzqppx hϟ>}{yG[vLbqO,jOhi[lw2<>4~!1wtV V-@R3%r\͇a)7k$dؔw] AJ$RI%oP9sL֭H]v_޻woj .c=SkmkٲerBm"L6CHiR5uJ)wZYѦ^?&PANwMmY-BpSSS㏸|{M8X*r umޅ"!gxȯ޵xpij@F'ut;P|+[X=ɽU(jrQQdXXPGI[T](ryS.nJ{X^y}zzzAAA{BFO)ǗwRoUR?ћyd;;;el[nI8wb'ALL̯ګW/ܸqcpɓ0H$2~oذ믿jԨQΝ/^Q?.}ʮ6JUׯle6ڮj-#GC? |}}۷o/USNo޼A a&77w޽ e8s JD]srr DX۬Y'*x_/XjݺUtuu7٤.`P+ёq1ŋTСkvŋ8oA a8&==}ϼWM@&M?Q5~PP6p7..:t={3fÃ8ؤ_;wT1tRR޽{(R0H$III1cUr9O x0---))LHHHfpذaԅJ3Q{ mfgxx8u+sWsA a){*(?Q" zc@hh(EbE5o|8)444͈ƍO6QFիlm/Ν;7i҄?ts󟹟 Ea(0H$ g?9nݺ-[e'N %Jv*kiiQQwޤ|޽vZյiӦ̌wU7W?X599n86_hF|$  Ù0r̐!CD JDC~}oϞ=ɮ}EGG6a(.ӧO ;vMMMmll~Z2e U-22RAt/bg/g̘A#> F ?Z۶m;Q.o0䰛Twׇnp[r1i$_0s?'{E}ݽ눏A a~zo@pjj*ajMk¦MF*\e˖pe+xggg6А@ ҮU OOO~؂L}իWTcG a0#\jC[[%\pQYfD˂eZYYA)  [rG]l.5kP pҧZ?uF|$  OYP]v(uNIISV[NNN7koNJƌ&رcfbbb.];~7oޤjR>\p0H$ s?~dSVD@ xΜ972͛Gդt֬Yfff͛7&1͍zE}w׮]dںk׮dĈ~#a0HzJgϞ;w600믿ߣGuccc~9R"Ç+5)L:.^hQUtttC?wޥEOa„Ӡ(P"(uRuFɲKgX=y$5G=c)s\Lԯ}75dG a0bbbV\I= IЦMCC(P"@?ƍJʔrʥK~Gh~~~5v&0H$?߾}tpMIiQ/`F|%#> A D@A a(P" 0#a0HJH$ 0^HQh@ 0" J eD-v A0! xcG a0HƈA a(E a0U"111PJZ...600ظqS2\iӦm۶y{{sc.0Z;믿:t vvvzzzǛ7o8S+_])X'ylr*"8G  $8m 9-O nv|2H}p!LuT0ثk=q\#*K2 ;|Wq <&WbaGЛ6G--GɯV"1 SېW<ΰ$pTm/r 젗9mz|;ł;OX?;e 햊(P"TʈUrTTT555G9zh--6mfQF5jHGGgȐ!`R&;k׮^...lUܸq<&fΜ9`;j(""_~M4f̘ѺuMZYYV$ZeG{e7lhCܗߐ29YtPwu' S?y@3w낎w/,-fG\7pSkMoJrgO 8pYe,'}Xi]VqՔ6X= '/5z Ht ϓlUĦj~[Gf&kDn]_$-G G6> oOjgxᯧ18x|(*E|hUkà }llv C z5@Cwwt6l&s; Zh@PPPƍW^]RRBJ6tҷoߒaÆJ`OmI& EѼwwu CJ'$tdAj-'0#!LƶcVK+S͚0oz[YAa@%d.hp!ˊ./&=l&g7= `  ? =r3}IX|޼ydS$ <9sXQD`ٳAHy<._ ʟ#oT3HoOs>MGX|A -;VvT%3f(R^0 Np\o}XS$ƒ8;%- MsPH?ɯB~_`|񄈗7VrVvT%#}=y <MfՖD?>M+Rz.ˌQ"DP{ėɓ'>+P֣FܬY3HJ"0A600Py7V4$ 7!A81 Hnt܎$x% N0Iv8+j]"8qȬr7GA£#{ %>KL<ެ <<<Y[[qP%RSS_nnnc'?ikk[(G`3g"jQ"05lH?c )#)"k-q|`s (L,HenEYlgr! <3a63+#0v*,a R.21+j]"+9[6?z=/Ө!ϠP@Y;DOthl&(_UKZ 7r HRy4[P"D=t䤣GnR0pgdd4o|ܹ½{1𿍍͈# Aٳ !3SqV=ڴi,X@`&\v 6 6m }_~%CnsqƵjjl%LqnV/v|rH{ !3Sqݸfq N`J\Ka}ߎ/KB8q^~gK S>w-Cn38R[#$x>{ $ڿ _%2Sq_t,#;.:?m((A $BAp_mNw%B×YYY|>V KW yTj;H7t۷oC!4-@@dd$?|2صkFU!ymSSSꫯ^xA=%0gիWޖ-[Be{~j%ay46h{G u_z;Er8Rv$B&e+(S'B`il~uWŇgt Y0QWVޖԮDx5P%44T!aCjO n xw>]jNYt2u}$L e?-s5?X[_w1iDHL[m }(cǎ]xQU!AMKKK@@2Ng# P m۶;v,URTTV?ʟ6޽Ko %Ç7o.>S=a^^f&M7;. R c']#0ҶSzDR>dh=lM}T0a00y[ru|ʟ% { -C&d{)Փ=s;0uOee?7_rಋ+Hb"2Njej%@"6| L#/S%a!{uMN/гOMhy'nwg#  [ægFLV0%6ҟV`O-&++XȸYvwMNv$ |Bp|V, ͡0P܎\8袻ݞՉbϧ9~ zP$m'eTvȍ ({%_lBp5MMM ƌMɆtثW/Vv{fuL:/nٲ SRR&@иq3fH&h 1xv[B-чt']n?1$c) „”L#63&V"a޽{ABlѹܽ1 ۭ6q[繻Yّ `Չb0g۟ޜ;*_XPiR-  >y%Brr*655ľa y]_,PO@(HavԻƍY(&@O2*_"0AfffTTڿ?+j%⫋0 Ne>s! Z'yГ#ڑWuA/`va`ʃ #}#}-#s*?-PXXxaFUaPy]w y'6w+L;G-YF'}Ah2)B0 8t)HFAӛ7o?~i߿WƲƤI.VT50~H__߁k׎z C;!~B޵ѣG۶m>Xټy3蒐~ 6ܹêYfi~xx3g޽{Kej.$k|;gxG/;BG~躰Է8;9!~0+e[{:LQ#!W9蒐w~z6e̬GmtL@s&<7G?%)u))c=0q;?H5Hxoħ~Z-Ի y beLnsv:LbGgfbSY{GCCsw9~(m ҼWp|s;MaI SFd-;=IʏNzwv( ;%BßEejjj0jz˿ۿA;[nM0 ׯC~N0O+UU2:ӽ{w#77wƍ-[$F7npB*S+_- rHeka2;uA@ v':.p_RPu :R|m 6ii?il;fv*S[… .]R? ~HȲ:6dݥǬ8CCCPO^E"Yn?(]!ӌ('=A]mN z@0 LOO/((PjQTT=66VABCC+%ѯ^b)#QQQyyy[˵IR>d$ 5][@$yKd)#Qy cEdaѓ3ya-V%u) 5#>cS% JDl%"eD-v AD> ; A P"`A a(xc"aHJD}h@ 0" J7A! @D% @D; A P"`PpA` P" >}J@^y*H4x`ȾsaeGU?g":[d d&”U> ɕ}Xpҏ3o ٷp"VvT%ShD(GFm #Y&el\<#Br T>+={lZ[[5 pfͨ);Lx j 䟺#j03$GGPrJW &NשcYՄ*q~>$]j P" P" /_LKKw !DÇC9r͛7*͛7;w.p޽`!001bX,޳gBfnrE--=zi,,XL8]M69sŋKpڪf#uTt Ap$W&K Ø)\1CxݻX?BK ɺ]:v(?\*Uy[((*aPK aRać y4"2;vqСo߆BpFvb;HߓiyPv#pT7B@[6/^,%*onJ! $lȣׯWcwHrRv$(WL˗KϚe?-X#/4Pel%Uy[((*=<<0}M%#CT$$K($]# P m۶;vQcQZy8~8+ؼ{.9CCC(LNNVm[uS"a!.?zT&Or4P}ս`2:c~$Gp$UV:wKꤤ-G/_BpBbn.^Վ;&˰~66q|P;vbȑݺucu6==+=ifbbmnJuFx6>mӮ7$)ɩ`wB{ۑ y:QL.I>>ɓSm %%B?'';)NRJ׮]Ԅܽaaa`a̘12~HzbeG.w>x`V'?0z:/nٲ SAڪAܹoFrFD@+#x e0#7Q\\TEرC2VmD@D@8 Sb̙3Z2u~hO>`ښ8)zAPPٸq#ӿ)S>HC믵J{#d y]_,:D2'NG Vy9F`g2X?PgٺEÇ"-Gϟ n߾ RIe+++ I&] OA50~H__߁k-mtĎ?hÇQQQ=zh۶''ټy3~ 6/Sy[v Cݻl Z 6u^FHW_QTT7x=ShR__QtF\W<9mHܒپtIixX$ogguU>yHdLAD@4d@R Ӎq)j>g˿ۿȑ#R5aںukwSC;ׯ_ݻ7w„ ZI?T Nݩl2]A)f)M?qB߼n]Q#!)r#M-=VRϧ:_u'uxP3*ohj/ _2(-A!o6fZAF% 9#!!!44*a+!V/="aAF<ʨaDoޔKUI]XQLLrQQ" P" j((`iA (0(`E a0`"a0عHv%h@ j0-!($"a(0H%JF|$ @S5kP" a>C P" P"(BJJСC[hٱcDž zyyɭ߳gOټyɓ')csݺuKs8C?zÖHDJJ*طo_مӍ5255߯_?&&&mB2j#GC?zÖHFJJ*T D\f&N8*}!!! , Znj*]]]r&f0tX܎kK$L# %%B ?~|\\)9tC  PGG@`swܩ#b:ZoHFJJEHKKKJJ6fpذaTd'-2JOOgkS1(09a((X 4488o}Ty HNJJضmÇBCCC،hܸi5jDʯ^&=vܹI&C޿Ty럡D@k P" P"0 |=}W޽I޽{asڵ𿫫kӦMI[ W+`vjX[[sa(0 0קO:t ޞ={]틎8a(ӧ;v馦666 vLBUT65ed:J$LC% %%BHNNoH񓛛TwׇZ ~6bҤI+6ն P @@P RSSaDM}ܴiH+WlBwPaٙM044lP+ޯU OOO~2i%pO5kFP ,6kee^^^\Uڔ ===*>S Ӑ@@P%RRR[vWɉ C ͅ۷1cp 8v옭-إKV4a:Zo @@P%̙C~MyQ5/ʝ5kYe2I&i555/_nnnnddԫW/껻vpDTG ^" aa((ȑ#>|8 ԩS'6-ZTU5,nOް%cw֍#K&''s{Ijm۶;vT渘?[A@h8`8z7n0PrʥKrFFFM HCJJD]g"((((((((((((((((((((((T" 00% %~KzgQ]A (0(`E a0`"a0عHv%#>v.]@@.@D@`GD@` P" P" P" P" P" P" P" P" P" P" P" aP" P" P" P" aP" P" P g9rdHꫯT.] O>EA (>PRR$~~~9͛EVW /_EA (>P7-#j 0H% 7عH$ \$ ; .@D@`E ((JJJJJJJJJJJ$ JJD]  $ v @BMO,@ A P"D@`G aڊ999Xv%3$ %%" :E;v\pIII={͛7 P" P"T}.nԨT~V611lAU9IښCHχ0U D"]f&N8*}!!! , Znj*]]]r&f0tX܎tL>oF" %%B ?~|\\)9tC  PGG@`wܩ#blgϢD@|VAD@DP$j3!!k֬8@ FEv2"Ct6Y _ɮmۂ(0a((X 44(}LMM@O! Hύ0,m6*8z{{SÇ'ѸqiӦ5jԈ_zMzܹs&MC>7YyRٳi?>J$@JJ"A￧ݻ7)߻w/l]wuumڴ))733ckSu }V kkkn~6/Q" a> P" P"0B\\\>}HСË/{{Iv۷O'LT4?}4[]]ݱcN>_~)Sj ~ۆׯCɥKP" a>+ P" P"To;?Hݻw?PNp[r1i$MMMj E]feeA /Q" a>+ P" P"TT9Qr+7m4Raʕ-[$OSaٙM044lP+ޯU OOO~Rw5jԼ_|U 6Q" a6a(( 8Yfd% 2"oVVVPEނ֦\QalROD@4< P" P"Tj֮];1prrB!CȫoNJƌ&رcfbbb.][~Sd@\l/^Di؄AD@Ds̡c~"yΚ5̬y$SĚ˗/777722ի]vq8"~ǵHϊ0Ubȑ &NNBJaԩC/YaOYPcGHτ0#?(U޾[nT-]499ܓ'OR{mwؑq1S.J$gEJJUsϟq㆒ᆬfz\r%Q7DixAD@D@C@ (P" P" 0JH$ %#> @D@`LjAD@D@`LjAD@D@ $ v @YFb a0J ns0H% 7عH$ v%#>v.]@A` P" 0#P" ((HH9yprrpGR!աK.CӧOkQ" a0JE"8ɃF|θy*hѢak˗/kQ" a0JE"MˈZ$ @A v. @D; .@D@`E (s0JF|Jv%#>% Q ] P" DxhPDA P"D@`G a(0H%"~NNN-֬/G `@@)))FFFCmѢfǎ.\%rRR~Ϟ=f'Olggu-Ν|P ްa_ըQΝ;/^%3! %%B ۷iR'[ĄMHU->rbgnn޽{7n,[ ę3gP" a> P" P"T9S:h 5k6qDQ/ _`պuUVBp$!חM*Эce8::r;.&~?T0`|4i(0 0U"((H[[]\\)9tCb PGG@`wܩ#bgJJʌ3,,,sQ~ʎ_Q" aa((!---))LHHޚ5kaÆQ ȐYlm#STP~D@4x P" P"@hh(Qx޼ypŊd;>dkS*(ӧUoD@4H P" P"mۨM>fDDDƍM֨Q#R~U6sM4!:য়ߑ#G֭[ײeKJĉ\ 9) iiiwݛݻ6׮] 6mڔ`:|Z)FnIOHC I(0 0קO:t ޞ={]틎oZe̛7IQY̚7o.{M2E|rsss##^zQݵk#bg:Ν;_ѣպ1J$L' %%B9rU]ÇWvqq!R:u*}fvvE۩SZAw} @@1RuFKҧ^Y=y$5QL=BcǎLe111+Wm#hӦ Uk 7HA@h8`0z7n([jʕ+.]5۷o.\)i>'0 0D" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" P" D@4` aKJD2 A P"`PpA (0(`E a (s0JRAA(ϕ\\\lmmm``qSN˭\iӦm۶y{{sc.0Zo޼Qۤ${ /]uVhv% S*N0;1TEzq $8m 9-O nv|2H}p!LuE%v)^a4e M*A_Jz|k)hD\1.Ξ=娨kjj9rZZZmڴ͸yyyFjԨΐ!C ^v֮]ѽ2\\\؞jׯ_&MŒ3ZnݴiS+++n]"ptАlN:o~޼yӦMݿ/)Բ-nl;f-J"0G0 N[v _3(! ʍ"W"KQ" P" TKKKO8ammr'O{PBMPCF={vf =3*"uG)A*$0,޸kGoOˎ@@PA\ϝ;rΝK/ܻw/X mllFvϞ=PNZZZ=zhӦ XX`jʟ7UVׯWHe˖Ν;O4gϞ9wn}"Lq.䶹+:_s#%|rH{ C޽bnrE-q=n<]jay_+I/)T0UKzޛ.Z݄AD@|0"JB* R{ll,pǎ$B&:t۷]jNYOOO2u`׮]`Oky<ymիW-[:tI[ %«Wƌ`:tj/uD"0O~_AgHL<}&K )+_HA0#c,?ubI!|h nD]YhZO:R%0hDxK Ljvh%%c\\uqo!BMKKK@d2WO܇쫲# 8mێ;*)**Z+p!8|0TSǪ-&!%%} ]@p̙&MLr.ExG^]A S{d| X,va'”j|jSD'*M2Q" P" Gwk׮ijj\ް00fmmmHϽzbeG.w>x`V'?tq3fPD?>VomaaW\u$Ӵ s>UnKG =+; sWwbvaO%ˆmxIamP^XZ!a7Px% %%cćph'' [x&WxnRWRK?}#t0U\Y4Z\}}W|⦨ҟKl/Z5`$0s?O&p¿hcڵj-1kA~Ku]W<lm{L>NHY D:95oPk|-'''}RuڵkmTkc $3C aҜرciz&;fgg2e n4E'iֽ9III5 1ˀA'YYYcƌ),,d,aaal[bŋ2F///BIOՌl2lQ+c $>޽[TT.޾}z~)k eÇg3&3bteeelJD@eH`.]bja1c9sSNS-㗔={677ט8!0f0@"%Kجc`` -taĉVVV}Ϟ=T/s=|6l؉' 1ˀ+OfR[o=$$̙CSRR:u### uN1a5mqB" `2`$DDaax5յ}eV\2??',yfC}ޯoMǏgm{Zi  ZxȑLʣӱc0k/_O_:DvnPZ7n/a3~ ZfN [8q"O>ҥ ?9æݣGS+sαwG&--,K D-{vfccL4a&X[bȘiEYPZcիW ݜ63+00@"褤u֍}u&fСC>>]sN=K<~) 1ˀA''Of󣓓-U_@;iҤǏGFFj^9Elii9s̨UV׏`[D@kHwww=wu6NNNfNƪ1aGӦM˫Fv3 xf_}bbb^41cFqq1?<شi{!((ܘ28!00@"̥رc߾}F=ӛ{~<߻w'$@"H'$@ HHA0 2>2>@"H0<  `0@" ) "`0@" ) "`08 "`D&H RҥK)))Ǐrkkkcccϟߖim&w޽`%Kddds( ._cwd<7,\0$$̙3ODh=+MH b$*Rq&+N_خ;Əd}ˋ$["jׄΟD_QQAEhÆ T}jc< 4}ԨQUP xxxXYYyyy :3g INN6t_j<&鋈ԩ?ٳgOj_DhGÇW?jܶm?`g0,[ڟ={D"4&8Ņɓ c*`񘤯`zD(>s~;J ;VJ*o*W4$E,N3ȏ$ cīRzV\/<_ $iJ?55Uոe˖{?TeӦM^|JJ Yn,zxx666zmk1D0xLөX,VGj֣Gvm0-9d,JzVO&x{T1I_5gQC̈́N@"H3/߿ڵW^U(xZ,..6mƟ={Eyy9kټy3y` EWWפEΝ; UTTԿo;ʄ1I_f͢GIQ"Y̛'모x\\F)kFz4zkuVt)EEAq@Fӧy($}̝K @L8C"H3/<5!!|ݻ;wsO7ݳ}T!!!|Mqqq#Fb 2fggsStu>}Ô)S Q&Iںu+-:tnݺuر}%B\37wMDŋitbb՘+J7ݮ(p|A2Dػyxfc/ɎJq_|awDg^ܹs'cǎmܸR||D"1aƧM- "Ru6lH빴LI0Wi6 #A1U_ݻwO<ۗW"APR*ySX+B!z}_3<\ϥ}~3/ w]sfkHDeXC1U_G4U8OuFE\\hQؿ$D|@ ذax椱L&;w\XX؞={LQ=33T&0իhB*_Mݺ7'))vq'C||<Ϊ@" `A'YYYcƌ),,d,aaal[bU ƞ %Y>U3eLEǹn:vTLID@޽[TT.޾}}~)k eÇg3;(iJWVVfy {{{2Ҵ5--=u yv@"HtUc̙3UO:uPjٳƌߠqFEEQg0`$D0wlr`nnn100srr:t0qD+++ƾgC}f^zc,ĉ{g0`$Dӧ[o߿?c 9sN:1HC}AEN1/MllD@< $' ٻ]o߾̪+WS~TM7o6'믿qqq?ؤ?~xYnn߶Q8!0fH2#GdR͟;ŅY|rr!w㏆ʸq؛[ظg|D@< $B ̉=ar'Nd|']tTg;gش{QC}j%00y9hݤ'$Y ZH<ƆBiL1==1Ҕ>fW9 D:)))anݺuc_ÇDNH @"HL<͏NNNöT}QI?ikkyO̙3VZկ_?ylq2׽2Hy D:qwwsWjdd&LPqYYY9m4]ͼ8TyϮiȌ%@"HWkثW/7Ϙ1lڴ=QT^^nvq'$ $)\JJʎ;go3w駟{qB" `/`$DB"  `DD  ##`$D A1о -:Ϡ$ .$ .C 2>.H`ѣӧO'''gddsmmmlll@@۲2bݻ,Xdꝟ'OFipedeeQ/EEE ǾaaaW^}$Bk iiBBmpp%Q{t5?ԮXQw??udv,'Qla6ʄ%B\3kB .^TĪ1W(ġ+o]Qew/Pz#%ٯ18Xݱjfo|Yf&$D|D"ظq#~9s؀ 3>lmM711a|Ȝ(coڴiݦaaa2&&FN==333!!$K22]~4!?5цja3t<$ھ};-9rDy`` K"A7lP0S[gHL74=ߏֈܻjfGq#yD}IvROIi/Wizw$D|\.g̗P?i;wfׯ\k.Zט}}}#G+z2hG4z.4p-5{-<<.]jGЪ#&V9xվ}ʒp_KX^ȨxTy:2hG4z.4pԃɓtҦM @"H?3d2^4_g7stt._LFO%_~J޽]\\ QcD׍7MTT?.^%9)lǀQ^MrrUR9oiT2E*W^ъpW QcDҗᩇ")"$DFe**{4#prP]3W( '#LT{̯E?n%,3|vD"p 4hW^y}EhQN+aC©_~hO6E!bC"D"pڸ~[Tm8E_^^NJ9Ic<8pbܸq;seԌ̝;777733sݺuiϙ3gHC̚5ԩSyyy111}qpp䤞aqܹgCBBEDbOm#@i׆[W"<` U-VΝSoFuyy3gD#=}^VGv:JŴ!ôݻK 7L0Ki~|RaZ ~bDC]ٵU $hvlپ8@" ` $0gPRRjժaÆuҲ{SNMOOڸ߿o߾7HHH0'm>k֬j.^;h 1A'ϟ8pVVVjoݺ8<5=oݺ-ZnStM '$@"H}ܽ{]}6>SfL6ږ?gV988?97nܰ'o4KKKcOkf|C 1.]fe˖v33gsIXO=RI6!**SEE}ןc $Pfd^FFkwsscӡC'ZYY1={زe cpB~~>lA_8!0f0@"pl|뭷TWߟ9s{JJJN{dd>Ç3hرc?c $' ]o߾̪+WԍjJݼy>?NK~Ik6 1׀eGɤqB" `5`$Dɓ<䤖}||ؖ/4i###mmm5+sɗ_~ҲAPr ]=d,111Ə3  t紭jdK,&LPa\|2[~vZJ D<3￯>11W^ﴟ1cFqq1>U zB2qB" `#`$D0%)));vطo_nn{c6 $D  $@0  2>$@GGH0@"2>0c0}@"["}%=xPgSJƣ~djF$D:L& 999Z3D" mL1 ֭[׬Y=7HW]\l?{,kD4?izr Uɓ'䇁J;US;6i饥?V}<-ϻKAe[J )j%]YVzU͏?4^{*b M$ҮFDh[Ywj%bZS=mR7mH`>gb1EW' ٳRϵk׶oN&yR{s)))dr,RhccCr-[=GUЮG"phL) 5DnQ]su'R"ٱqP5֓FO}}ј}G"pDLm0D`ѕi"˞%_~%>|;̞=¢l޼<0I&%%-ZwQ#G?ޘ]"h4h7y/ƍm,+`juUTT<.[E1#¨~vR2ʵX1"*/F"hV.p4ԝI0r/VϘ|ƚP弿K*8tx2w?jz\YM4^ !PAx >{͏4f`Aw>?¾},3@"d|~ˣ/TXRR/O2jAAA e0lذzsi_bҤI5^zIM"ژ3g1Ax K/|5RQQѧOWW'J"FTܹs!;ܸqjdPIkN 1`Wi]+Q^3MCrAr克Wǟ*ϻ ZC"<;|c{ Hp$Df|*8STh%ڵ꟞y6zF4=ע9XLNZvECc4hW^yE0U(OP3V(DÆ*O$$$Z1J'v1f~[E5Enq/D\3{ci̢L&cPUG(**,U2P=8pbܸq;sifdܹ֭M3~%ܹs 0^0x?a`󳳳 鵙Dh& V4:Z#k~HٌʹdgΈFz(-5ԏZ IIa ex?q(eRyAR= Oo6Tu1(㫖m.f…ڵkZnٲΎYviYR*->#ݱ/u1w6m0Ki~|^з ՓY+pW4ݏj5j}3^ͬvfϸ@"HrN]]]yyLY=\z@e|=/uR"<C#U>1m0<=v< H H78 H H78 D8C @I1о -fJ+IX  #`0@"oǖ $DOP/))Yjհa:wliiٽ{Skm\TT߷o_jikko$$$铩 Ç5kVrrLi/^@ttIZB" `)`$Dy㴕UDDZ[n999i6!66mv)㷫,((ښud#[B" `/`$D92dlllƎK86u1;;[)SUvvvg -L~>|Mȑ#߮x懪UњǹD@eH,WW1c206XB̪cOMMe^^^nj[)H8s  qݢ"vlOY{hh(c>|8Dikk[VVfO?Y@hܸqޞd4--=!ǹD@kH`.]beXc̙3UO$'QZZJYE$E[B" `2`$D0wlv`nnn100srr:t0qD+++ƾgC}[la.\ϟ|`!0`HӧOﭷR]տBs̡))):ub쑑$άcǎ1?j5EG `DDh- ٻ]o߾̪+Wԍ򣧧jܼy>?NK~Ik6A" `0@"@"#G2)y49Sk¬]|?}9t{GC}N6Y۳gO.0H_ZZJ3<&Q'2 >.]0ϣߺuMG5s=Ǿ$Ƕ;iqѺIKKCG `DD0}7nf 3dfC8@t1KKh>0 @[dv֭[77>|MCe^tR2zh>'jFuw܉A@"HlwrrR˿>>>lKN4㑑ו/zi (e2-!0f0@"]i[777ɪ~Y&LTeٷjeڵ @g|TVVرc߾}g D `DD$$@G `DD  $@GGH A nyx0 npp0 npp0qp0@"I=O7oʴ6Żw^`%K222xaؾ}{AA;-+++**6KvDh퀡#-MH b$*Rq^sm`@uNӀd.͛4YEɎb#ۘ/] @ Irrrrhhի uUI7yyy tww5jVVV^^^C%<0PX~1s1mL՗j#Uy8 KS(ª*Iѣ]._Oc7v]ś7SvwS $Зrss7m~]ٜK믿2dH~~>[{)JUQ<~88o<.rߩSJ_~ѣG׮]um.mLWmFqՑ3%T 97?еQKOk\\,M4_ ;*罯 ^Q=uͥjq $Йd2Yddd||P(њ͹njkkU-[FϞ=ZD"Oc6]\\:t0yd0hQi饥?ֲͥ]-2`hW+ʲϡ/T4i,C M$r[WoDĈF̞{WKͥ]K b'sichY&WFB[2 ~lB,J`Et=eKSvY Ie!TFPw",;g Uc=Mؽ^whioA)/A`tm.mLW ?<Ϟ=¢l޼<2\]]-ZD;wp̞ Q#G?ޘƥ)iqv6yv](eiHo<0굺~]r7{jaý˫Q|.#%'?-m$DO\ƿw{ァj !L͋1bU+V1;;"99k޽"ŋDhqU"(˅/X=czskB㆚'MLWJ(kgq/fjmPH @"'.O2Jc{AAA e0lذz?ĤIٻ^z%R* GhcΜ9&&2WPL*jծF5@sGKUõjǏ>e?+JB$" Y}]}s^eL"Hc i]+Qּ^Q0\GgV2.\xz%Dv] b$66VU4G}.%]2'/+JK gyKK<{)^,֫D.mLW OEh6 j?,\/XvZ-[1k. pHH%G};՗sicZܮ6m0Ki~|^ ՓY+pW4ݏ-j>ڝˏ1U_-n$DmL幦իC }Sc55\壌'HtAtAtAtAC h߀D$ H@"OKGIENDB`backintime-1.5.4/doc/manual/src/_images/rule_keep_last_each_week_for_n_weeks.png000066400000000000000000002147061477034762000301500ustar00rootroot00000000000000PNG  IHDR.psBITO~IDATx] xMEcjxLhUUDb9$AA"BZs2Ij׮ݨQO>䫯:yWFێ;wԨQ~ =6m4ŋQ%  C Pw 6UVjXxx8T *Ʌ#G_~|B/ʕ+.]ڿ?b۟BiC_  ?sӧO[=#lU o߾ *2iW J3fƈA@\֫WfooOQYJŢM֩S'$$0m۸8Et݁w5111kӦM˕+7l0,RҴ[?#;;&MaլYE$UsQZ5%===ׯ׬YzgՍ&PbJaA}DYܹJ*`mڴ6l܈̂3ѣGAj z>#RB`` XA*{ fA)xΝ 9sFR+05j/_~ժU V`<f)buf->-5Bx0̙ӨQ#rhÐ?p[n= qpp4hˋVR[Ctaر+[Db_|7* "H$͛7'Xx3?b }׵k֣J*_W=z'೹edt)iZlH#GT m:鍁IUzl쿂HJv\˗/(,D)DسgmJh͛7)u?#rM=P>} WMiEe(Pnݺ ݻwk5`C֭[\ x'..lf...*v=<8fKL5hHMJa RpppN_'OKЮlie%zǏ=<<8bB BW[ItnnnBžK^ 'sXKfXiv'0atf?n4̅yYjecDpՃEYqGf[(9j zrO)C_(`Ѥu_,7qvA,^^`fKBZZg϶BPCM4hf8?~#l|9 '@> 3VEGn߾=9*|VR%...%@pBpKЮllejԩS*U"3g3Bb˗i@bp~q8_d ']x1T_rRæ Bc]I-&tWN8) sk^ggdi?ρveц)MZYje[);w~[W_}5}+V=:>>\`BBƷH{.t -.[>glQʺQƨYr oKȿ+y1ׯ_HrrR! vKIƯ?k_oXXmMzX@zi;v.N_Q~/,?g6uK6Dп6mX CMZYje[)ddds▢"[j33OOO35k@n_^} *|7v?#lU<9r$PcWڀO8SNr*& ֭KBڷo(H`͚5Iț7ob1ABB'|5AxW%4OOQ1tٳgz ^](zܹܟRҴA%>>={zX, ,wD=g6u?#[CjҤ Rdd$7n7 MZRT`=s'^nu矡Yt)H!]7mb~~~pc$5pQtѣdPi~FتPлwoƵb%hW 6 Y;Brrw1Fn7c.ڈ7n!r!T?o߾%QFA[ 'vmF6*,*HLLUVΝ:Jh Vф&EJiӦADFNjΖ,YM,8~8Yfq ;gծ]3npJ* ڠיl)7'om۶%iA@//&pZ7"X)WW>mܸ1S$!٭.O4MH MB3]}FتB>}ةXI6RSS t,;T vqlaիbd-zFCg}E8qb( ^ǏZeT5mRV_ cn-Ea,Pad0W(պ;bLՙRnNЀRagJ6kcM[NN~ccc eAŀ{Fتi2 2:睢bzVC%|ʔ)&Bs>94hЀׯn:a˗/E,(C3B DbvΝ;D__SNݺulZ!JgϞy>#@T AGxx1@ H@ !@ C @ C @*@ @*@ T @ T @ @ @ R1@ R1@ b@ b@ H?v@E Jn^*(zKC"nR16 h[ˑ} ___4[[[[bldN:%RTh_~. RFZZZڵkҥKz'OQ-JS֪U<>>hqŊ[ [lAvvvvvT XqLz|Ewޮ]m\xT=Q^zͥiҵe'3YvRǒ%K۲<pҫW/҉ƂvM:^͚5#!|?ܻwog, 'GGDKo$<<<-- N(MÄ HxnݠԩSJׯ?}t+J,MV6<'2%6(!&Ӽ֢ݢݢݢݢ"C*Vؾ};y[,X@zlśYf-^ennnz`ѥKc4B iMkԨ׉N^6 T-X,+VEEEEEE*T$Kލ~?Ç#u GAΝ;KëNHc4~s盛wDi7oΉwi&rʑ+Wх,;!뼚x\@EEEEE*TF^ɓ'n.""._EF@tI&Mt76޸qc!c4~зo_rޱcG4ԭ[;33~g$k׮Fgތ| R˗/ɋ1vتU֫Wޙ *4lpذa'$f)YEMwii?IpH` @+]0<ē B+=sG.AEEEEE*TdPZ53'SNҨQ#ٓw_>w_ MCJJ#Q('9A p-z`ٚ2MRFV(zfo-aFIN^6mڐ!t3{4eܞ:/_4 3 \WڋYoWI~PlMsR3.͜9Bʅ̞=D s΁z_1Ճ "!UT! W-¯:5d`ĉpB'::2Qܹs'7wi0mV44w>[[[[[bHJ_vZ.otEBr.\`Q4æ*U"}wѺukS &4iE[~8C yS`gMnRl[[[[[bHJ {e4Yt)r11z_u뺻[8;'zزeK͚59)G7MMM}]Z. +GEEEEE*T,!---00ȑ#qㆩUJ\xgϞMHH(–Mnnnnn!C Х!nnHHnhR1b4--4@*T @@EE CX4 [-QvTRPĻdih[[ VQaCM]---XI@M%B8z6 tih[ĻLŴmԑ8Wfxߑƫr^4A2?\fH+t}UZYP.z dpyihV^ ETV͎hҴ"H1ͦr=hJ׫H׆kèd]ZQۭ@%%RMV@)WhVr,[[ uE׆Qmb*.)+-Kj*^ jim\LhnڰQWtmR1CӲJا PNC&GTyꨊD:ѹycyF}+5%rJ\ hxv}eOOO@iPձO</RR̬,Q1n֬x-<\r ]YGYt#I Fi ofܼ>w4\in'еaVW9ӗĘkڠKmV TYKS+Kpɍ{Ϋ˄;%T+C/`_¹ ^-9^TLŏ˲U{Q1=݃jgjì3o>ʮ ][B-$ӎW euc aIKVV^.n3 d圔&5v߇ UvOQ1'&jеaVWd/?Ů eϣb<3V7ABTEHk|naXl`+ԄxqԷ3ߤ@o^f2W.Aǥ<|*F3B~!#Oݬn6<'P "T!nɀ 4_~۶mk׮]z54z ǎco >anR!@p#ed,imb,'鞯5¼ga醲rE6J u]0淕F]Z\Z1SB'˝7i7Mز:g?cIk c)cCYyRHNR!]l#6ԆY)^]!\OitmХގ|~=4>v pTi6-bn~{3V<;i\2^p8D+L\uP,ҰS=EѵA/f!uWwuЕ)Hɛ7tn恆Ԍ/ʏ7%S [RnhtYq@G  H`'YZwr\MRG(QneL+ClZBńeUz`pnޘLlxBܕ%r9S10-ZXČiUj88G]Z\ZQۭ<[ i̭\ȐB[,PW$MKX-n-}k3\+򦟔cZf˅ _O[1.Nf/Zk ר6k.}V3`X !-_,T'ͦ%Tl v-\fZDDr!n.N֝>VCӨ6FڠK ]њT1*FKG;UbJ) svXw *9- Xp6IOS1cuV]e("V" Z4LENq^E6 5JoͥJyV|ʳn>Yk6 kU*J~T3R SS1zΌTLJ?SaVWmХdMڭ]Ϛ/3t-.N<}YN8n>Al6@gܘR.de TO93R,ޞQ{tmՕ<)Et`:Sʟ?s9݂<`ONMY.7c_ř Yuu9DǧbH~=_6p &(O&rdF&(CxB,Aܤdk$o)bW W &(u["_Nr 08@KE DШȈt 承.,MnʬTw`PYRy1Ѵ=)#ɎWZru0гnOm>gF*뽥;OM؟]λuOW<-0/g?OWd587 ,zphZC olX- \G['~IF^6}^a]nۭwP k^腓%kqe0b~=Ϣz.{!,LQlvǡ;ViiixH?/XcT[BdeyCȷ٢%`adtrⷾ!NVY<#8:kÌKVɮ 44vWw3=&0!CaM%(i )xjU_E?r*q";~;2d>X;?ZXڠKsr(@8%p)vmХčF6-#%}ir%-4Z;XC/W,Se1y?u]NIY>V6Ҝ? N \]tiPj-Ao)7($'6sI?%MQ1 vy|F6)Ϩ#Juvp,?] PmRzGz H4P(^r%cӠ[M U}/;>@2I!.^oJO-+WdkZ+tR@1+En8Jy x4s )r`V06@ &;k"-.~PԿ︞z;b߁A94\'͖}}(=׋+/H-}&ItgW[;[RLצ׊E AV4@#t2V06`MPt0"mP?2γ>}8lo\R\p.Pz+w,=qTz!YVWcUD)W~ 3dA7p18t#|y2< z&uNx%HiQ18&AM z{-ؒ.V Z-Y7u-LQ1p~:4^n]vQ꜓/\4CoW.U. āׯ_pcqhCz7ڼHQ5cZ``J2I ᲦտQ1qiU3u6mP٥bsoz"QcgIa!CPCk,b}nXmnD-ZgKҵaV϶h"}W`[)?sQzZ``GyW RTl3F_ {p"6kìmEj13+tI}7[Z$]ؒ,:X4X \ ?ktk6hhèd?\vR!0!jV aJõ\[uhKҵaTmi|QS S!arX-rm+Zm)[6J 3)Ժ49 i("%KCEݢ",}h HŰi@KCEݢ"!i@KCE"!!nhhbb-(AE*bKCKCEv(z C*. T vTJdffFGG߸qT tibhhHŊdN: bvCv@*VVv횹t钞ɓ'DԢEBŞ?>uZjEiPb2L<^@ OJJ2D ŠRnNಳ[j:&&ƺ*:s6*-[TR Hmrɚ'OrilZ8ruR4h WgM]lL>!ɓP"j۶mb;vn 66֐EӦMqT QTl˖-gΜ1WXSK?p7^~=f{{{bݺu ~Gzo޽{oR._~ b͛W|%KtLIڵD%^gziR[mjlD5>C([ӥÆIci/wx4C;LAbĹ5F*/^,tPf(U=*rlF;uՊ%^gzL>S.߿?**k}Xq$ŋׯ_O7o n,""sF><<<իWy.T\\\vv6KT-4U(˼yཚ0aKZBB?r WB >>J*/UjU=*RL:D tppL6l3]ZTV+h‚uJXUS~U"ue4L[LT h&'RCvID@H;w4mTo {zXR?>ܢXvڶm R1DbSm7n܀ׯCLjܶmxM6Adp޽{+W\jزe K5k֔+W𭴴ƍ7𢲤ۡCcZ9hR1P;B+g/_*4ztiRcWͦm(^-mzu+,imb,Jz}5oW*}M޽["u&t*4ztLŠQ"dy.W^ 3"ڽ{7j֬ O~޽{st 7xK4C*6qD蘘h@ Z$8abg7n܀3|-bb111222RRRV^ Kx{{Fl߾}܉8$$$|||8D||u.mݺuvvv))SpN}n7nH5i sqqٵkעE#f^bܠ s??ӧO[ tw>dȐgg\Eϙ.-R*VzVfaׯɥl Ω˗,Q^ܶ6w6orO˗2Ϫ-7;$DǙnQ*__+!Sn$6-Mhd@ k 9ӥ3. & , #dśYf-^]s+ɟ ҥc4=*vrYB@[QbC!C+\Nݝ0/% N5ͦ%TVZF=z\r뇔Je8b\Ȱ}|З*pKԜT X͚5۵ky&LBɳ0 [lKtiRRb`|@d&rүCnX+7ylZBD͚&|-8AԤ1\j328ҦBg&ST iSWS gy6ن:?|pra1b1"zܹ3p.9P+DB_F r $U\yCT VEoHE4 t\޽{5mV"4d58+W&Nl͛73Υy/-g x\'!!lZ=tÞЀXʅ9TOk9өD*' ~WzζL)+%v+˗$`WOD.Qxzx΁:7ٴzP…ޟ+R.d[YϐtTGk9bs~ҭ)-ζLT 4Ղ[֭"""K.dZ2WzuI&E6nܘdOK;vhѩ\z\9s - R1DQUW^=u*@ ^6MLL|Ȉ^+\ںu*V75Vn NPMkAu5oDngqzdTR?VcpRLbχ!۶mr_f(VٖҢWV7X:w[Sc-k32D ,)n8Ai4J1b__rJ5G͚-Wln]MB|1X8h s6CŖ,ߺ]t妦2MPZ[g[rKg*KBDƎ mTz233+T}aÆA8di)@آh|*ƝC"b#4nHJ>}H 7Fqww75(qtaΝ w$KgΜQ3f-E7C iٲ%~hrm!M]9b@/@˜kԨAfsK*.:wN/, o.GYs-E73Zܱ~JpK 믿,z F֊ó<*ưH!YRԨZ {t{jժAɾ\:uFBCKկ_{z2h|*DGGGn`,##8XZHoX؅ ٳr܎;^H <0Z?`wiv\dd䮕h4͛7o@Ig=o%ZQF^@ Hiȑp/:*C(ڵk\7fqqq.Ş3]ZTVnF ߲][ py(EZ&|͢zZP~үVYhFAOAA#R..֭X&(m&!3R9ӥ9kժԙ0aÆqth@HѦM2e!33;glbt*wާOr~~~U.R1.-44-7{yy9ozp6lQ(9bX*34Rʕ[tus͚5 Ν>nuE"ѳg&M[b\=ݛ} ""A.DN:slʂr1X-[߿?abϙ"-j*VRvRի)>ΝZX(6Ma;wUD)WA]JTTGp8;lc( U>-USsGYxt,ə"}ϩ3GGfΜ !Co@+c͝;w8 >c4, DBTB(`~ש 'N 8U^W͚5,ChHҠ[F\v .MrԩSVbϞ=5>Spp%oooF}0.Bjj*:liM>;#rЧOXz ͍NA_KZ|9ːXQי3EZT`PA:^4[XVڶa^><"*&a)]O^uvgۢ3=g=b\ !@_.f|N2t-fHŠG5}w]qS Ԛ4i^~ML3ݾ}p3 DqS1Fckt. iii2 |2""ԇ)H$0!!J64 xL٨|VʱYGEgZ]ЦCi*:s6*}ϩ؂ 8R~Yt)~dOOOeݺu-fG .}e RRR\n n?xE^*V EKv(vtf9r7nZe4C:u.R1tib!!Х!"!!C*. T vT T 4 [-QvT Gpt- vv(T 4[--4[-Q$S@itsQimܜcM}j–:ӵaTn4PlNrɺӘٴRnN9enmmݒMryqڭXKJ2/^ jim\Lh^DMJ}cѵa0*E*VXtt 8qD6 _3f=Yrح[ .-~GzK_'4./d7o^>nc9Rg6("ui%hT٤kH;kފ}HQ^i?!Va\%Cŋ}:stmP@>|abnnnL.T^nLugpWcv)_ޢ" W/giG,>KDqfcm)r`*+Tn='cmtl`:]wS_E=d̓ E)RMGɓ%Н"mFѡCP "Zh 4i#H4ii!dڴiOx`\֮]{rvtt4EŬ3=g:'%%ݼyRmPEJn㿒}V  ""1g{OMuvxV,Դٴ"&:;?%D)3c37"-?!gq6uRgmrrvhڠH^ğfwa//bx&*ǧyq7qy%My1-x,EkK)@wd?x9[kHN߈)06) n"5cɖ FĦY X٦b|\|SS*)))*gfz5j?+Bb@ .;B[Upɍ̛7n„ ,i quuB?r WBS7k UTYxL&ZQ*f]lΠLq謳k.-b[D K)aWKaQxOgIKhbR+C/7Ç5))yLo92^]T̺:lA&ƕ[k.-j=}u_ ,n4'󩱱[3qU]Z,+RسO; \\GKne׽ӏ7%-b[[zB8.YsR׬}*TٽUfu;} b]TbϞ=>˗/۶mswwߴi {!(5kʕ+GVZZZƍ:u갤ְۡCcZ9芜.3:)_]ܑ%-\Io"s훼wR193P4ÇC еAZGvK?2ֻvիWT[ zhD^'.ӏFr|%-TܯiEBI(Q*P 50+Z;46Rb5h4"۷O;%琐+h\feʔ)S?ƍfZk׮Eٳh(̖p}\+)*f]R+WJ]ZX!ڭյ38._DzrV ڷ䌦%F>'Tjg͖uKG/|}x uu63K׮J]Zv߻wp> ۺu+|rrW;wv{rT2ymΩo>}oϟ]y\AhlN/-bn~{3V<;i1p p8D+e .rp`E) {MŞzM,mM"2f.dȑB[6l(@>fZSVQF=.zr!ۓɓ'7Rsfbl#ԙ6L n&M_2"jV(n^ٴֈ5MZ6qIcfdpMgZf˅ %ݻpMG i9P1uL]ti1mrr2X#Xɓ'm KHH{=|vTeyr̅#Bp 2*pIibi 0A wY "zǴ̖ w@Wew=g*"U4h77cƅb,` {MV\CPP4lRf/^#FhN,Xl28ٽ{7oL^2gn `)A"mzf ζP1zk.-TV>'Q&^)_?iDkйͦ.tPr!+5pM{lPzuYcJPٻ)55j~ tF 'Y]gz,u# 6ҒbEjEu/\0D hZ5qM%(iQZME?rB6#;$_׭nS1kLϙΚπKk.-jҾ<޽{`dnmb>A=8qけ9qQB٧/V_7թJbςA,+ ApmTLTT3Ԛc=6R41صA"{ǩD"qssG+ W\`6lQ( =BK+Wnҥy8p`fåRܹsۇzyyn… "I& ({DDD<ȩSB3%g:ϛ7i"-Y*VtvRի)MݧdR+PzZs'V,$&ʦM~X#FQWΠt~TTGp8J)93Yxt,EZv ]~mϞ=GJKK}6XݻY*;>5w7qSEqIY@S6>1K|Udپ[]]=KcT\=L-V,/rNH7AA2:6)kk@מyEfL W^ ,ETb`h )0 |&O:E"1\AoP9|xxxpRSSpJO lf*U"ᎎόRcWa蔍ulcڠHKr~+IKrPQSi-]۶19xf riAQ1G- MFl3%gLEZvxO@[[/)?sQzZ``GyW RTl3&#jO3 NX>I׆Y=ۢ ػC(8Bo^VXnDDD5п Zv\[`ctmρj4QQ9ۏn}T|Vـ\tkèx^LSkmQ,y7d@PCtu&`u@ Q&eY1 Rb+"%KCEݢ",}h HŰi@KCEݢ"!i@KCE"!!nhhbb-(AE*VzQ. U@E ,[bH4"nbl,Gffftt7|}}Qnnnn!i(V:u6Хݢݢݾv{=bbƑVv횹t钞ɓ'DԢE4<|ԩj"5׋P)))nnnn n N:mܸI^ѓ'OfffCCCm۶eiرcw;Q4mGnnnn n ƌC" <|%ٿTTREGGC47 ЊQQ\]yضm4[[[B[ZŊIӧO#C 3覐d֭/_^*訝8qw\k:s\lYLLafm</0]xxxΟ?}vihhhn/&͛gff"C 3x{o޽{jժ{С;w$;w6m]޺hMCrrLn]k׮m۶/^Dvvvv[v 16lH"C*VXd yONzVƂvM:^͚5#!|?ܻwog, 'GGDKo$<<<-- N]ٳǍ7`S޺u ]---m-PL"TTscbbؾ};yU,X@zlśYfqAL777n0VFFF.]zr *rG.+B. _}\BGD*@*V___n9>|~G=zbvܙ\B8^uDBȿF;bqi+WG_ i۶q㐊!ZjPgOLN QF9ٳ'tڕD_>w_ MCJJ#Q(NVV-oEvvvvkr,MD*@*CVΤeٛk׆ߑ#GhWM6dhzH=ul_@wi{})wWXKCEEE%HNNnn *p2=T 4 ܻ4sL:t($-H@@;w8лwoQh4h R Yj~ש 'N 8+V@G^Aό[2. n ѢE \+@*f&L%`nʕ+w6 gYz[65ޤIk!4 hhhh%kFG!C 3 po!dҥ\ȱcG^^=Wn]wwttdmRRR\ܾ2ܥݢݢݖfE*@*VHKK |aÆpss;x`rrrQ1cۓ%ݺuy @ǏgO}M޽{Y_r_Ppy/_~ɒ%W^p;;;(Cwe̓ Ei1[y[ Tg8]#N|K'7n$R_i?NDܱ7,2]n>t[kV-pSyKon upܛpy7QvKՆY]٢ H6::z 8q"<{ έo!S(wؿcj4" W/giG,>KDqfcm)r`*K@9] [3X麛/y&ctmՕ-ڠHy*FZ?3==B\\Çڥ1GHHHVVVhh(VZi4LM4yH$4i!dڴiOx[c-\\^v˗[___ѐǏZ-<=zԬY%[6߼yRmPEMJnCIf<( oi`Ь&~(+FrSƴ2o'gnMgg,e&]/ 3bĝm(GpwLvKՆY]q#[7X H 5:'O.TTl cDRt Oh ~8'eT4iƴqγ!wjR%P?]YJΧo7ZݚzݱdK׆Y]q#[b,ETSӧO[N/}S*)))*gfrHDVŌMc pr .QyM0%-bV^.}*T+rRŋe2YժU@{] gΜa*jìrr/ |Æ ڠKݪUAcq3pY\rC5noSKZ[K:t;vCINR1>͒*R~v, _XO_[q 0+Z;4zRbe%%%yxx3\Ҷn 8'wsh)qΔ)S8>|777ͦ%Te׮]-ڳg10[nPP\B[ ~~~O)Щׯ7diDjEzS=EѵAK+-vWyFr"wo>\M>%TxEY-7(\~W!_^nTliӘ1c#GBniذ@ ^f*-bj5jѣ2==?ȯi-2l߾=9d\pr@/ l"U4h7Xq6י.E*.PAffpp0tmr KKҦťf͚/^(xGhѢ,X`ٲep{nȇHJ3g7cɈ Y =g*- `:ujժUjkì@]Zl.$gM_҂y!Z\N'_Sxp diVϜ?W1Lr!+{.@8>Bŀ?\ .JUdZlTmՕRAbF-ت#az,J=hxt |un>9]l6h'ן  Yuu9DǧbLN!qW^| q0+}*F3]TݡbgddK[n]ŊZ;eʔu릧7hЀ ,_phZC 4k׮\"n\WW*Uő}>[HKϙqΝkUb ti1TvpSzKc=y"Ad`i#F۠^&nղpA,u}ʙqdīiC~Fm6g*V`*޽>`R+@T3% noLX1x7X:e8g4!fov%r.S㒲Wrz541.`pؘDReOn8uעK؟]T]bXxᣢܹ^8Y>sL̘1Co2dH˖-YC/_~FzmY*h׮k.*\FvmХſUfm7o %3(ˌϛJkn紼8n>p -[sTLgcͶnڠKJ:_w7vmХ6~p8YhIazM5-GzE?r]_12C9b܊ 7[7)6R3_ө;L"+T,++Kr{ OΟ?IwQX.m׮]+W>{&dիAFӼys9pJQFFb\@΃ȑ#_uTL*H$V?!]t) ..pJRڠKڥ{W>l #QBu>JK5ZM JPV[ Fn-`[j8]NW2NYGŤrf"wa[6R݊_N \]tiibt6[OPlNx`d2QB٧EN,JZ@6o+|Z;XC/W,Se1y?$a}zrxH>O9:J] x&&{RbeM <#--@޽DH$nnn~~~hBʕ+ ť?(WҥKE8p`fÁ̝;}(=W֭/\j8i${{[n1Rz_+frhԩ䜐.]@?#Ro6(LVM/AGw}tkoa|㒲l8u}(=핻c8 ͫ ɲ}{ƨ"Jz[9:)ԱIY7_)BFFцY=l7sՄWA"+b7|<+!88H/P\>t.Bjj*:+UD)B>}XDիgXm2v޽^zg";vdkìmEZ.69#j_N@KĘ=+N/ yRշk,b}nXm2v͓^g"fkìmEZݪr¹"9:xաyNI8pʀ!(H(9?I̜2p&"ҏeғEfl6(Rbe(4Ssmr] =2 h"""L}AB„UX]-x0*-VzV!0!jݪe0A̟+rm[ }n0*-ρURhi|QS S!arتrmY Q&eY1 Rb{ EKv@EEXaӀv@EE C`Ӏ@v@E C C"nnH![-QvT GŰvx Q@*T ]]-XYCffftt7|}}QHŰA@*vvTXJV;թSY;wEDD C#nHJ3j׮]3.]ғ>yZhQVϧNZV-Rx˗P._ޱcNj/"Cy*vAoooBAxxxRR 4imܜܯ*eggE@$$$h42TgҲE,[P&'y$ǘ̦S.W'JszΚ$9VmI٨}xɓ'333硡DԶm2AvءGbcc9ibbb˖-RJe!+Tl˖-gΜ1WXSK?pi_~=f{{{t-&&ziܧ?Ξ>{x r9/NNN*sI7\J[)"b%hT٤k}&.aCTԤ{ZqO;T)7I;LAbĹńOI}:\S 뜔tMKsHJ%#m@Iܩ#4H:|_õb1Ç25ܡb\D<-U%g ` _!i6\ji١LTl;|2GbO8Aο;.>4k׮:thΝ)Xlt 5( pA 2EuLMM.-Z!]xq|""";GnZ_ze'aBegg4X,KHB[Upɍ̛7ޫ &%T ^o+C/`߾}*T0 s7n\ӦM D8iذԩSΠLdÆ 9ӥEJJnV(.U^>F> e史/֨.{)-B?r;|XXAR9&+׿ &E-?8x 5i (naϙ.},E9AWNV ڹs'"ܹM֙D3b1 >|Ew=vڵm6  3᜜!{nL 77۷߸q¯_#'33s۶m6mBd.{\rժUb˖-.MO.׬YS\9·7n7ʒ*RnƎ[9C_|?1cڷo_gNm' yx36LTח0~?Ç#ѣG fΝ%sɁZM1FS1ȿF:H6 kժP\^zAbbb:.w޽v횏UVAڵkkpZ+WL!((YtС͛73ΥԬYŋ\-Z 'q!PDUV7c Yǧ5 'Q&/ HğӉ~]tn>PDzu r?zC:l(K@8h P=%g1]FdSbo_qNLɆ:ے3]>S1ҐV :lEDD%EdZ2WzuI&E6nܘdOmePGB?WVĄN&R1DRUW^=u* eD?(s>jnݺ+Mխ[7==Ad`iFbРA]v[}"Y~G^.4UTOF>|8T*s&w qÆ -[?~<u%g+qM/֪]Xڌ $K-NPMkR!7o]T?roleKEujȈү&FsmIr}@[h߼w 2u:ے3]>S/_.2vX֫W *4lpذa'$&YZj Х(q688sT QT۷oKpcd wwwS[BZG|2], 9s%KSzKM5Đ!Cٰ^n~)o߶1g=\p=w\hs5ctiQS[ T, oݭ`KM5Bƌfâz/0-/sփ_G?bJ%QC@GddթS'iԨ}Ϟ=!:$YNknTh|*DGGGn`ƹBأGR1DR1{Yrejj*\ر:e4>>s j]ڮ]*W|؞dիg䮕h4͛7o@Is )JhMF?/S+yprr9r$.g>BCCkժ5h _):ő{tiQS[Ңu.F d&Uܮ-JZbbV-ef\Ps?u 5k*1"nm&!3R9ӥ9# aÆqj׮͟㖺iӆLYr4\Olb*֭[!"Co X8~\mذ!&&FP <\BǏbTҀK+Wnҥy΁6k,<<r;w.PzZ֭[DϞ=4inrлwouW,9?~xԩM> ߿?abϙ"-j*VRvRի)>ΝZX(6Ma;wUD)WA]䬉8 us,:/~%9S9svv̙3!dС\ٳI4xe@`lзs΁ygftDIH*U,¯:5d^`ĉpBEH'/x___"Zj8!=}tŊ|͵k?$O:kE._#իWC8Dt钷7K>\T Gu>}zJiZ1JzӧET3 PL5+)>?EЦ9()ƴt׮Emۘ<3Jf =g]kT`c-:S90aE/\ڵkѕInE >.+njZ&M |`b@p>#5:TVd2Yy숈S@"@„i*ꜣbO֙"-%/)};**g[D7UvkuV笉-qxuecF9[`GJ!K.BY^=>[;cE3ᣅ rɾHw:t ڵk!J/+s"%KCEQ}N:3G9|7LgVxٹst>}eA C*. T v>R1R14R1[R1R1bHХ!!n!!Х!"!!C*. T vT T ai@ h[Z-QbM6 hih[[R16 tih[R1R1III"(22'w̦rsr]9~:""5Qtu6*}]V(}L:9dd7ilZ[@)7'J9ڀSSu*-:«zj4Jb*.)+-Kj*^ jim\\ƚrm, SRbeEGG0'Ni{c̘1danbbb24ǏgOG-iܻw/k`\򋓓/5ǏwD+V\y,bN I,Yb4BQԙ"-RVv C6icҒΚ"s}j{ZqO>:tv.brs? 5gMDd@VMa:ŋ-bN CEQgdٳgpBLugpWcv)_ވ37\%sÞ,qٛq.-rt]_E=d̖^GIzc9ՕڠKm*;:'O.K1bDBBBBCC>J*/dUV5Jue:88@6l^g&znV(.U^>^E.놲GYt=5˾%-beKܼtЦbΪs@IK/П%gͳgun+rd2QFΠLQP-uKKn9*Vccc mEVm Pe /=%xtFY6{:د{CX*DHȀȁVC tsf)"GصA"{ǩa/@}mm7m11C#^(tO.׬YS\9·7n7ԩS%-T:;psp£G 6lh|f޸)*F3pCF3]ZJ\ZQۭ:*u+Rqz5·֭dӧ;+C7n dxx1B:kMQ1z > )^g4mpp>׮]z|&j֪ov+y"L?J8˅>~iP1ʍ~"?f۰z]SV[9 dN3zJk.E*^S1Fž}(d{ iXnL2swss۸q#ٺlZB\\\vڵhѢ={{t-7((.s??ӧOJr?tuV{Zj=ԛ`bQ*R+W@}E3]ZX!ڭյ38._DzrV Z ôܿ_|A-rCBt--rqO0ZՉfM?b,uV_Stii-[@߆ AvܹBbG.Gu~,C7 9=>>v p@:X)${B+s\7ca9L_ϭ{Ĕ)ҰS=EѵA"{ؓ'O@@W^ݴiM OcƌBF !daÆxo6-b@eF5zhLOOcZf˅ ۷oO'OE6[%)gmjn{ºuݵb:SA3]Z6!!`A.S< .#Bp 2*pIibi 0A wY "zǴX}*4g_(Fl z'bOGϙ.528G]T콦b+WL!((lRf/^#FhN,Xl28ٽ{7oL̙31dĀXʅp@Ɩ رct `YF@۩tLf*VXv+i ğӉ~]5fD@P r?zC:l(K@8h P=%g0\ٷH Sb5T߸a; ֙.-mv{(KV ?uf?Bo?s92 `ONMw*p\`Ww"_3Er ܮϏ'[|0+}*F]T콦bϟZ]4X2eJݺu4h@֯_o8Ai4! ԵkWru 7.>\WW*Uő}>[HkK{qKJСCk׮-򶎊LtiibbZ5hnEsmF% '(5B)F7$j"#Dr˖$$/_MڀM9|J;FL+Y| tLT3$EojlgĊґ(ÉBi 1{s෫.= :.)Kx!\>mp.KΌu>ŠKϙQWO.E*^S1@fsNRzdI̙39b1c bȐ!-[d~۷m̹cǎ7r9_vF*RgeP:ӥn}K%刅|bcF;v`\_{a1Lsɍ叱d#cJ%nZ {wy?vO, _s4߼-7s\yǸfoI9[qO3]XODb]Tb/^9ozeǎX ݵkWʕϞ=k("%T^=#wFi޼9S JZ T*5j4j(<8999N |giν{O޵l!cs\\gLK+R--[G}႑=wQZ2ш۵o*AIK WRԪl, !q'zns (־#Gte3b,u$$~\tiibt6[OPlNx`dNlw)2>jYZ;8\R_/>"Zz;M&eYX9-eLb]TbP(^r%ưaÆB-Tr.]z~ځ6k,<<\*Ν;}(=W֭/\ i4iaR?|Qˁrx 4`?""A.N:[Ty?22"mP%Ҋnu\z5Jup0whx&mڦF2Օ}(=Gܹ_+keӦ ?}N)W_9:uR*OՁWE}s|MTTGp=8[TgҡCt/DiibfR(.ӏ<M%ep.Pz+w,=qPWenuu9(.QEL4{?|´f kləܜ]WFm"{ǩ 88h @ (p)gF >Ç!55Q~O^R%hj((O>Q1zGz8_vp 0:VWuHK֥r~+IKrPQSi-]۶19xf riAQ1z={DȻeLҦ3\w+:SjJs>rLQK\p!m۶7nR1[[bR1bōjժAF:uFBvJկ_Ⱥh| 0dddK㜷YwT T XUVPZjaøu3k׆ߑ#GhHߦM2Ác4^P/1ҒB $&~L3!CEE*@*@*f90sL:t(2{lLJ pΝݛҙ1 "!UT! -¯:5d~`ĉpBSZhknnn!HŐ$&L7znʕ+wWT~gE֭M4iT>]--R1RĂ tR.رcȞ;u뺻[d.\'sKC*vv@ C.R9r7n0Z1--T T T T @*T @*@E !Х!!HbHb[]T @*VVQ<@Ev@ CwiIwnb`@*@E !Х!"#Hޓ&))i[D pJ T(Vr$;;s ?~ҵa0*-Y*Vv d&+ K+4J+d٭ZzB UwD׆kèXtt 8qDx[GׯnjcooOv-&&!--mDpqW8ݻr9/NNNꁒW/_:t{.ctmՕ-ڠH3Zh:q[:Qpc&::OgOp"⎽ gYr 6Zls~%Ookyv7oX햪 E)R1R1DqS1D'Ozxxp‹ԥ1GHHHVVVhh(VZi4]6iѣG"Д3iӦ=r ryڵ/_n(9ǏZ-(G5kքcɖ ↑n޼i6("b%i!p?RB3yjuq740hV?|#RKM)cZ3ee;`y.tĝm(GpwLvKՆY]q#[7X /_ \ZN#9RLIIQT\Hff!0Z(#cǎA4 <:\r,ͳ0aKZB\]]\}UPիW30<,, "9s%g6*'w7l^g&(nR cq3p|777-ͦ%Te׮]-ڳgD%x8;}ta2d4" "r GOQ:ӥ>=l%E8>fWxMK]]ދm+VKY\Ai28M7}*˫s3]>$xƪjEzuGOQ:ӥHH%$$p!<|p4\i̘1\ȑ#! 4lP |ͦ%TVZF=z\ː)=p|laɓǍjc΀C3B1m0J A3]ZXmӘ[ 42BpK*1*p$i ԭo-putE(5* "zLJ̖ U݆Kږnʼn @. X(5b:ӥHH֡\KsqqY/#FhN,Xl28ٽ{7wDUV3g7c Y -9o ؿNZjj0+=LbEkw=k:.Xȼߗ$|$lZ}kޟ+pc&KW yv{kْs*O8)`BR-Ufuo:ӥHH#[n]ŊZ;eʔu릧7hЀ ,_p:hZC 4k׮\"n\WW*Uő}>[nKzΝkåkQWO.}غ+[˭Y "K13ֈ7yv g|^-U$#^}M34jsַ[sln`SK!!;*sNzdI̙3,YBBf̘TZC 2e˖,ۯ_?}9]vftmХ@%kԨ^gݦb;㼁xU, ywtrw"wSimG2-~ק{q;㱍9[`TmХ@%{Rbb2F^xϟs;v]vU\Y#XW[h7oVsR٨QQF^@ Hiȑp/κR)3 HTZ~ҵA.^g4S1[6޻gnyʹ%T铡T40%npPjT1&+PYtۑ!_u9K,Dji5?[jTmХ:${Rbb2F$aPrJF\rK.Cll,a͚5 2w\^^^[pIoݺŨ"Jzݻ79t.A?}(0gy?22"mPdN{iw#V\n`Ьf M`PzZWZ_}M 4$ɓ,r+u.WnM:g 1]LV vp޽3069nn}F0"mPHHeAH >K>Ç!55Q~O^R%H2\="*F޽{zD;vddцY=ۢ 4S169#j_N@KĘ=+N/ yRշk,by+{LD1kIOmճ-ڠH!!JY \߻ oaCH$H+rm9##ǖ_ kèd?^v+K5n2H IOC䜡<Zq-UFHHeB"#HŰ T v@ CKC CECG aC@*A hnb]@-:nhihl!bbhhnⅭZ-[H8~sR@ OJJ2DF75P?6;;sJΦeYjZPMN6!9YI1Mk4]N*XkEwG%RgSRbbb[l9sQb o qȼ~z̘1dlnbbbҸ888?~=G}w޽@)/drlRXgHX ڭ65U6ij!﬉{+BztP"5i:ŞV"cMfhr9(V,8pGt)R1R1DqSGr%44ܹsYYYp piɄݥ1C!!!P" UV0p&Mۍ7B>o޼1P1]v-ZhϞ=bQ?f `8;}taL+W 9ӥEJJ*,Q]5͜9u%ի۶WΟ*&r~e̳f эWݺ#LU3k 9ӥHHM'K ߽{wXX'O<|NpM6s. }\i̘1\ȑ#! 4lP @ f*VVQF=.CJ2k1[.dؾ}{r>yq!rٖ"bnQyMH!dEcP ܼ3i 5k*lQp (Z̖ Jw;"-@ٔ3(6L"C C7h4nnnw޽v횏UVAڵkkpZ+WL!((СC7oghKsqqY/#FhN,Xl28 $$$MUZuΜ9N R.deooO>ؒEw[lKtiRRb9?6Ѽ|Y@%N8sϟMՕ/\ 鰡,BVkȣ5@xƖ-#}dCmə.E*@*(n*իN_%]obb"Hϟ?k @Fr>jnݺ+LRn NMkAuڕC ,#N/յJ*ɈW߾}'*Ɯ-#v]lKtiQ+VvUSFnEsmF% 5B)FKεR&2RȽY*-խIH #^/KF̵[ruE-9ӥHH%@>}H 7F'pww75(qtaΝ< w$KgΜd2c bȐ!-[d~~۷m;*:-svvQc̙.-j*Vvܷ9p$\ wsJk-؁E?r_~a8[_6lrU*/EL"C Cpž={V\ ;vؿ?xY"k47nnnk?ݥڵrgϞ5WVF4oޜA%-_9R٨QQF^@ Hiȑp/κQ9..3R9ӥEMJnuKQ_`("%6ff*Eܮ-JZbbV-ef\Ps?u;*:k?.Ş3]T T QT,44-7{yy9ozp6lQ(9bX*34`ʕ[tus͚5 Ν>nuE"ѳg&Mdoo+X,޽{厊߿?abϙ"-j*VRvcի)>ΝZX(6Ma;wUD)WA]rGPgҡCt/$gӧOWX\v .c3rԩSVbϞ=>\z5CK.y{{349|xxxpRSSpgKO l*U"ᎎ 5QC>},bVQ3]ZT`PA:^4[X mcP\}Z3xET;*uK!!J1]t괴4LV^|aCH$Hj0gR9[MR&**g[D7UvkuaFHHB"#HŰ T v@ CKC CECG aC@*A hnb]@-:nhihl!btibh|bbIII"(22fJ9ǚԴ9F6 $'1Mk (c s.:]J!!ۻDGG0'NK{1cRnݺ#qrpp8~8{ڏ>Ho).tP/899Y9[7o^,YbӢ-:SEJJnI ͑wŽ!=:ӊ!աCt+KYLh lIxCL(L"C C7'Ozxxp@wԥ1C!!!YYY@ZjhlҤɣGD"ͦiӦ=r ryڵ/_n9 *f6:'%%ݼy:SEJJn㿒}V  $1g{OMuvxV,Դٴ"&:;tcBlȱbzO۶OkPKL"C C7˞MRLIIQT\Hff&ZC^b/T, رc-4U(˼y&LP1WWW+C/`߾}*T0u_JŋdUZDX tppmذtiMPj%P]N }\G e史{jT}=KZB˖Zzy>,MI)Ĝ5ϞUȑDZDX 5i Sn^gQgϞX˗\ȁ=ܶm7m11jBC4rf͚rָqoN:,imb,vaر3hXJX \|C=L,+6U^z\*6nVF6=]ܺltQsGP1r%={Ⱦs־yCN,b,iu&tt4zRbb2F4 }IsQRRR=X֭[ggg2e ϟqFM~MIKˮ]-ZgX̨epp0>}r`e+W>zי.-TVfaYQS/YXZm+prF*&r~e̳f эݺU3+=-K׮A}E3]T T Qƨؓ'O@@W^ݴi.M.y3f 2rH!- 6 xi U֨QFy/wJ2[.dؾ}{r>yqxVr.:*F3:ӥ݂yMH!dEcP ܼ3i 5k*lQp Hχ̖ Jw;"-ڔsQ1Zי.E*@*(cT, `ʕ<A|M̶n...5k|2bĈ-Zɂ -['w|̦̙31ɀXʅp@ƖLtiibe9?6JJI;% O9p@?7V "_s%aCYʅ‘Gkh-9 ֙.E*@*(cT ]k+[uUX1008eʔu릧7hЀ ,_p:hZC 4k׮ng]|zUT##^}>|8<ܖLtiibbZ57n53sEsmF% 5B)FKεR&2RHLd)Wln]MB|1X8h ؒsQ1zי.E*@*(cT 8ٍC)ܹ^8Y>sLX̘1Co2dH˖-YC/_~F|ms.:*Rge5j`3]Zvܷ9p$\ϝ|TZ#Tlhq,+ q/21碣bLuVC5j^gQ/^K{ΛرcAk]v\ٳg Edիg䮕h4͛7o*AI NT6jhԨQ,+yprr9r$Ί;*"*R縸8πKי.-Y*Vv[ZTC(A԰UkT.UKلYC/W+j32COx*45{GEDXIH {RbbRG$8ZPrJ߰aCLLBo \\rK.?5k.JΝ>˫u.\DϞ=4iaRz;lrsԩ1gÇ!55Q~O^R%hj((O>Q1z3)6n)ҒbEgs sҀ|TcZ``f k"mL\}Z3xET7fi )R1R1DIR1 oQzCʦﲥu{eDDϖH$0!!Ag%sс^g9[MR&*ʊgGEgZ]n \t٨RX(]4[>t64غ!!nbtibh|R1lhuC C"H74D-T aܥA NP2gR14R1XYCffftt7|}}QHnnbti WWWjN:Mܹ/""]--R1RAZZZڵkҥKz'OQ-ʊK{ԩSkժEjϗ|ʅ+;vxEtihhHbHJ\~IvCCCm۶e¥رC]rĖ-[?WJʢW{Gnnbwĥ}駤Y߿TTGGG_t44=z0U|Xd o~֭nnn+W&1T T XqcMV˜3 .<<ܢHOOo׮]۶m.^Hqi|R1[[bR1b 2X 8իZ ޽ 4k֌|'?s޽9Ǎ+D3ti'N$!HxxxZZ Ν_>D+Wɓ'ݢ"C !+nl߾ , # śYf-^`777rٴiӔt7Mϥ8p\VP!00Ж;bqiÇlٲ,ݢ"HK%-?ÇwĈՈѣGs¹&J]_F riVZʕիƍ"CEE*@ C*V #ɓ[nmgg]t!3/dz$f&M:烛iܸ1ɐ1ߥۗ*;bqiGݽ{?\Z5sȑHnn!HŐ7^|IcVZ^z*Thذa NH4j֬iQ4K!mppp14"_v --R1Ra:u!5ٳ'tڕD#+| m5RRR\,ri="Hnn!HŐ7Zjaøu3kπpK۴iC~8dff,G[eKۺu+?СC\Ç#CEE*@ C*Vpvv3gBw&pQUm+%fjLS4+VҋKi.(nfXƦ!;0>0^g9sf|~>}=s=>_=sψ#/;|0ԩS/_޵kנA+ӓ4jԈ,6K~rSDǏsB7o ׻}#G899وb跈b(XMkܸq| <@SV^͗ 4~HvZ HkUtBWWW(pĉ&M|3-- ((V;3gp ){^|y˖-eҥf3ܹsU@W\1b=z9rsooQ(D1?$+H/ٳܹsV+3yegg;v ]ވooQ(D1 Pb( (((BCPPb( Q (~BCPPb( Q U(BՌoQ/ߢPb(!iO4[t Q 4tC!oQ(D14- o: (zhճܞ={^r,Ǐ_>z&ѠV+զߪ /ε  L-̘=vnu:n{.'F,溺wxT k[tϓc<>a1[69V=Q (iiBBBS|||e/=:;z&NJFpYAϭVM ˿D_F+q=~R⛤@XR/4~k-$NזiӤwDOv>}`.j!RAc/-޲ɱg._7k4蹈b(D1TMP'O\|N"juzz:0L&ssrrJJJB}41(޽{9,KPPqX7oCo'$$@CX6gΟ?/_2KP ׭[>{AY~VK{sM`1y7,A76؆w[%nor~[&(|~4w3~+ .p:~e z. Q UGQ,66vڵ7o^zʕ+!<] س7*lEEU<WZeccCB$knĉ-Z`k סݘ DW-ts=zT^=H4hsՄ\Sn9 C Z}5(fVןA1yĻ3$ j`#U~𾐮3hѠ"Pu6nL'YرcU-,'Oٳg_|rd]b۷oCCC3"t;dooo},3 "k2%p:E zn]@ۿ؆QT_|P}+<.KP,_'n <"S+X\UᐳӼcgc.>?[}~k2%tn\@G(BCQSv޽gϞ i* ߟO2ҦMX \v233M%(֬Y3??QF999i~~>"/tēKonժ$ j-3/m۶jڂKL}4uŪoK/}:bq!LK\"0)`.AfG]3#p_T`Ś?Xڽ-$ .[6~{֖ZT\~K z. Q UGQL~.WՆgg{)>>>;w9s,ZvvX]AVƍg͚OVqذa]:u*,,wnnnyyy, lפI(h+G[G֊U^Y|"u?,JƍIaY&"qY?Uvn{@Wr/e}j~yE, l$b;-[h+]=Q (zQl͚5׏~fɓ]\\[nM&֮]`]}yzzۗd=ծY,3y/rAA7nq=bkS`輿]/z'XZ// 5?{zbw JblWMױXf[?|譂b%~K8Vw(BCp(m6t$|ƌ T0~:՗w׮]YƇ]z>>jWW)SXpg%%%Nb z?ŶeDD, qe傤+ Y]e[vۨawQ֖YTlr/=Q (zP޽{{>w֭!m 6ܺbmfDC>8g?p2?j:E~ .a~)i{~0-]EJ1 Za1hUE3w$q~Kl }:X}4蹈b(D1sbr<88ĉ%IDDIJeC… iѡCd@Cuûu 0aŋXp}Sp&//ƍߌD^:tFnYWT0[Q*͌9&o=wK=]~q?Hg^_'|(nR \Od[#j9=7n6J&_4#-ѯnQ,[VU0h:U8&sPb @ՠ ԅ s M6A$cǎ !}QڽzlHn^.]hEl]G[Q*0G"XWTpouoyoP& )^}|k`g@6$ש Xg^M^oˇ:~Kl]G(BC&Y,J%.F!ۈ"\݂GUHB-JYu~ vʼэi>VB,C+*iX$NʯzU+-JY-.EC!KI~›B!n(D1- (BCEMGAO7 BCAjF跨oQ(D1.pV 7(Bçz- (4?O74[>!Q(D1TMzhճܞ={^rѬ>k޼9)УGTj}y}73-Srjoyy %M%MO>F\kueoNfM&nNrSSJ_c5kϠ_v@ dWђr!fC2%Q (i_yF?vؓ'O޽{#=A4pWWD V&BԩSo A(nٲeIIIZ6--mdLd7M6)J@Ǐ;D* oŔy .k[(V~ 2.i҄'Y^e9Rn@$@7n0օk?nNMvCC~II)j5wIۻB̚sɡCj۷)8?dvJy+Z2UoeJ. Q U(]Ry]Vuҥ<(yܹs'99Ƌo޼QZZd2X |BDS~%((vܸq,u ͛7ς[좢(lpz-))2eJusΗ^zؾ1'''0n:vjEZ[\HH}`r ʪeQ͟/qtP~K]bEZ0>vX<-| WQ%zKJiZ 8;isr M"#ś6["P5b/_0.Wpp?x9H?{MH͛7C۰a y W^]lي+~(ƍCN< ŢUlllDvM8E,uA1ڽ~:cAC:}aAT>>2fH^zA[V+UG>s_/q'ϗusSN&ԑ5(fV\[АNK/\Ȍ5}=@Dýuo3ht\D1Q rrrV\92ۡh ܹSQA#ա"Çy˗[֬YckkSɓ'A}nׯ_v?~l.A۷ס2+2[]:}^z]^^W_}[o٣l,}><'A1v iW pyMvɺŤ+ǍU'umڂ޽t*ݏ]MF.~bT>IۻUN(޺Eg°0{j0WOPN[鹈b(D1TMF rJLLÇ!XLҐ-[PC#E矿{ABZ@@Ƚ{Ν;9s-ZqNVVɺ:ƍϚ5dذa]-//2ϐß tD3bggS);-sߪf} |D1=o-8g..߹c KE5w.?J>.Е:&_zҊD,}nOg&} |S>C+ܯ*SvZ"P5be嫞Ϝ9sUb•H$޽{rw8^'2WgƂf͚GGG 'O⒟ߺuk2vZӳo߾z3Kɓ&MXyТ0en1}RtcuݵkWaiW=zxyy>xKuDSyȐ!|xҥ! f…gN:$''@CuuP);;{„ vvv"cj8NryRRWƍnz ֵkW0߿~7n4hbAAAC%3L)Սb8,S:χvmT{SԺ%쭎Tܽ:UԱe!2ڮF#<8Nw)) __iKfF9~W*J4s.޶>Iapj|on"s,SrPbZ@1 %KkbbbT8sR8kIBCCoܸrJHgDDcH7*$$/po#4K 6mڴ ;իWDEr{%|G>7jh,Sb&wy}پI˔F[~_w=sn~./$͛U ZwC-q]1bo?NK,p_g[JuQ˓}پI˔\D1PQ @ZDJݿ?%%Fr4$%%rvٷiҲ:xm͛e nM|-]ma&%ؗ뭔6?eߦJJsPbb]ߢPb Q ~B!0oQxQ(D1| (BEPf?hP-[ Q (CEMG!醞~'$ (BCEMG!ŞJ,'''?xXJMM5qQu]Dt} ̚\.72e4QL+p<|hÇn<?j5+jRR4bz[k,SFX. Q U e֭K,7h4!!!Q!-77Ύ,߿g7DfANNNcۥK 颴ѣѣG׫Wr{yF&L72 -X`,SF[(V[~SN/iXPwͳ-j͂MuוC%?̊vsr'HJvPzYS}&*ZX>2R͟}+Zle)AEC!jž˗o NJ+ ]!P&..ɓ'OnnnPR0Bմɺ2u[o%Diw˖-ÇOJJjiii pvv>5]z7oxbsGȑ#;C1_pѠV7Ֆ*|¡̥KZ4!IֻW>r[M[irV&n5m.\o%Di84Tᇚ2V.w+ɬ>v>iǏCeu7b,k>,7k4蹈b(D1T-իٳfrz%8vULIIIFFFrrrnnnqqqNvj:==fnPR,{bOUpϲڎ7.AyY0>vG`g(|!& ڹsK/d5?RlܸA[999A֭[>F[\H6~@bBD禲*gYGg%(VhCo8Wp[ӦLKܳGdln%eJA[I]A7md z. Q U (t .@ +((sA"O YYYBBB NCC#YِqPlʕ9zMɓ'XTT9]j aHԮ]'hт5(fVׯ_vcbb,hHϠ={~GX+,,$Pn^zA=Q: uhz=am~r4i,uA1-ML=ނ =@D i?&Pn{jDgAEC!jJJJ &k׮% nAZbٳgTP@Xff& i&eoc,immmp8yd>Ϟ=;88x`q峛RX@@ۿPsnnn!Cu^22JϟbccĉAc|iR=ZQmKnZh͛b%(eqXXE%wkߪSTE~Ҹ8nENF9bY(bYW3PѠ"P5bz!&:tѣb"Ĺ?/_B  O{17A,xS|}}!Li:\v KPYf~~~FrrrXRrJG{VZApݲ>CWx rǧsp0gΜE;0|#@5k?ɰaۅԩ޽{Xe)@dU5AϭV#~F`G1=o-8g..߹c E5w.?J>.Е:&_zҖL3K:T@d5AEC!jdpH)Tݿwj”X,mRU.nE ..,2&KK3VŬL z. Q U(ɿٰaCpppZZ޽D'N\RXܹsPEQ{CڶmۀK"""tɒ3f`1}tۻk׮,ҮP=zbc}2dfYb, 0=ZQxNedI@,TtkGzdvec}V믿D1&%% mۨcG(BC4 ͛~mǎe?$ ?c+C6lxЏɇ4MN-+H(R\ܶm[??? %T*9s&S,ׯ//2cA X}4Պb"H,iZVF5G%(u )uU2>vJcZLں_r>k%mA'w;[feMV3`)Ѡ"P5bM!&i&UZ~PHR.]i%666 .<+Pzz:_ãCq ֭[dd$p„ vvv"cj8NryRRajРAfKII^.@)Sc, :T@ϭVE(d:6~}>{wn B5o3Z-9|XfouT]ԩ/3v51pʽLIQh m` %0kD.-eY5b7hEC!j D-]T؟,''\R+VJjMH7*$$/pow^ƺ@`ӦMkРIرQYlի"zbhzzwB-[78fehsjo sE}t:G$8xNƺ@`/4oFeu7:yfHvKo\{ ؼh/M^3iIt7npF\˔Ѡ"P5bzˬALII15Er*fee _)VIIII~.̭#ہזj<ܼYfrW7oro)j 5))~.EC!.=wI~›B!n(D1- (BCEMGAO7 BCAjF跨oQ(D1~U9ᐢ;EPPb( Q (0--ܹsG@CEEPjT#FZhQ_~㑑IIIooP(D1DڑH$j޼sO[nΝ;?/!Ν;SLi֬yffN}u]W^QQQooP(D1DZDd +$^{.B֭[!JOOXhsK'N@CEECjZc=,,͛S>--?$Ǟuɂ %isrr{>}@0 ivW"GGG[sE!ٳvvvʕ+ooP(D1D֑#G3}̙Ç={}|| D(oSHׯIa,& i`ё._+b iYYY]t!zIf&ooP(D1DUBByO4[n)))pڧOM뛕k׎d,& ibSI_KH{[ow9`拌b(߿O}Qƍ[lYXXK/i>t8 %ի٬bCi.)h}b跈b(D1岷>m߆}bZ&vDOd]{1aHر#?PPPP}!-//s=~no|~~B!!! ܬY3|i޼9חE"AuVnjt?߂~ %A$YmڴtY/8ߢߢPbHHswwc3 eĈ|_|A>|Owԩ˗/ڵkРA•Ό? FfoR.~h2w\RLJ>|g!-- ((V7n |ի}4666fi׮]kРI|wͽnݺ[Jʼ+@DCEECjZsaaapB>e޽˗/oٲ0,]4??߬b7;w._|&C?D1[[D1 Q QK$EGG/{9wʌPb( Q (~BCP(D1- (BCP(D1D1 Q ~B!0P(D1 QyA1f~zBCi/HߢPb Q ~B!0oQxQ(DA+WQXLYEEEԵFv%IRR-0kZcʱ`nXuV"Ѥj>4ZCͭ[eFd]kDkW*դh,kVWsPbF%F~( ǖa閛oggG"hذa$i߾}ut颳~b-G=^z۳g+W0zl]G[(V~SN/i(og +>ArJו:J~;(('N858:p=5VV\5MkhsPbF1\V~-$$?^!P&..ɓ'Onnn/Ꚙ(Jk׮1օSvl2|$V C4`gggYk&姑.\`hsjoc>P%X\$ݫL0#eVɊ,*q.\i R- U|&%Lդ&m }`2kZcdVi|YAEC!jń:yuVӁid2[\\SRR§꣉FX +ᔟe 7nK]bͳ`|r~?NHH‡blZcXtrruֱ=^PְjrDŸ7V ѹYGg%(VhCo8Wpe^zlr__J]AzAEC!(Ʈ]vͫW^r%1Ǘߵk{FC(rj*"]v'NlѢK]kP̬v_XА5keGիWu+zn]@[u3i{|Y77iNYZbf[ȵ{ YsfYfpo] W\D1ƍ!֒5k;vCɓ>{דOKP, `_uhhpF.vsss E\YsO> - Wܺb5?|/qtЖ)gL烺j+7oVzSj֗aaEޭe~ޮ6/O{ Qe5ke\uL 3P^sPb:bYYY|ݻS!MR<)B[ڴi#NffɺŚ5k7j('''8ϯxO<,޾}UV.|E\UkH+zn]@[P'|bH!-Үj%*lu I;W?NN{UK +] Q3 ŨzI3rD=Q ((& Z?jCZ@@{Ν;9s-Z;v;j qƳf:6l{@WN ݻ[^^媺^sGҬW:VZV5Ki{Wb'{pY.(Zqή]\sd]Aj\~GǕT}0]+uLt/-/4iܑ4ktQ+z. Q "ؚ5kׯ-Lc+z?ŸWf͜ _;i B&7`]H#2 Mjݻf[aJ,j\H\%K}4NJW\D1Cm۶DDD褓%3fX`I>}2vcuݵkWaiW=zxyy5keܒwwwGGSNF;J*"KU_- X](?J֫'+__dZfiJJK۶QD(BC=g(v=Ƚ#xuV} 5z2SN;Pjӧyqq۶mXƇޮB~B*Ϝ9q^-eddשR콢eoE.-ԑYC 6e"qKݺ*ǍezZB1 L&mJ߯XiɊز鱂ֲT`)^sPb rypp' K$e˖14 (==/ѡCd@Cuûu 0aŋXp}S$//ƍߌdZcdDAAACMMMe uŬ[Bcc?CwQ*T=UjݒÇeoVGE*iUN*iXz2mW;Nw)) __iK ۦ \5M[15b7hEC!3BT2Pb<cH7*$$/po#4K 6mڴ ;ev^:p@ ۫WK.1zl]G[Q7}9':BҼI֝2!/J7=Tl"4ҿb%<+&۵x4蹈b(D1TmRT"H*liJJcr%|X%$%%=z:n[`nn^~y@s%c+P5E~KiW[XIIzU^EC!KI~›B!n(D1- (BCEMGAO7 BCAjF跨oQ(D1.pV 7(Bçz- (4?O74[>!Q(D1TM4ZCn7Z5U*+jRR4 ;w,[Jʿy[fߚl(Q (i۸qC %K0(Ԯ]7#KeMD"iӾ}vEg)O?x v=z4zzBnϞ=\b d;vsΤVZ/7|ӯ_?so(2%ZQV0^Աbg p g+{u~J5J99ʉ$NM%\o(~ͬR͟dOޣWϼ,1¨)b(D1TMد3J||<'O޽{/A4p6511Q*F6YRNzK Ҍ@iw˖-ÇOJJjiii pvv&#Ƣ#G;\_~SiӦ);RPLR7oxbʼׅ ̵LɭVEUCKbqiBw/l&'ke2V&B5ii7'&Jš?Ԥitä]ǏekQ R5g67=4:2n4N3ҎV,{Ǜk(BC4k׮%=x^Ap]t)7@wINN6"7ofdd4L&+ᔟe 7nK]bͳ`|=(!! 3N_eff6jhJq:(oߞmڴ2eJsΗ^zؾ0NNN`dݺuՊbZ\+%$MH*n܍TV, 73Ŋ-`|풱xZ0&;[RLtA1OeҮ*?Oh}3a0H鹈b(D1TM˗!?;wϞ=i&Rp6l!BaիW-[bŊʵqFƐ'OB(rj*["]v'NlѢK]kP̬v_0$(ֳg{OoTUG}dJzZtn[(VwV}irZ~6?_M9mSG֠Y&&r?h\qꡘ ?glx[`_D޺74ez. Q U(vmR999+W?ODDh4vܩ(Q őPBÇ{lׯ;+.A۷ס2q|2dKQl0eM6>?Ncccĉ7ri3PtjE?|/qtVȌ|PW-XPreM ZCouS8,hݻo)O?ʂ%Par/Oa*p]*si\7kx"'J111PKg鹈b(D1TM$i;vHHH|tSN[rΜ9ar e ayR<)B[ڴi#c`ɺŚ5k7j('''8艧vZj…bttӗ_~9++K`& OM4?feznX[p>'|bH!-Үj%*lu I;W?NN{XUK +] Q3 Ũ(͹Nxv8 .垚3 ?)-sPbF1F|ʕÇCl[b^lٲ?Y?Bgg{)>>>;w9s,Z V(uuY>f:6l{@W0,aaa{vsscLG1^{ .dЇ_}֭=.Ύ ՊbuoUw>k\ַ pk+aRWG裚;q%U`oJ]/e{iE"t2}S>xLD3\#@R2=Q (i++_|̙@ p%wޅW(@c!m͚5׏&N<%??udbiڵ/ ՗g߾}1]g)avѣw  v1 mZK~-z&@.q\A3RqcYƇޮV~B+I[RE҄i 265gD[P݇(ƎV HE X2=Q (\.Xmzp֭}vQQ(>)޷oL&L9|ҥKC… $:tHNNˁχ%t B5Rvv .Eӧp $///*\/@)Sȱ؄thqȑ dpXPPСC eJnuXm-RE!ԱFݻs[)y*nò7{4w*N4u,|qS]dJC7KO`P~rLHw̿׊W/22%Q (Xd &&&NM*+44TFƍ+Wt(FDD04~BBByyy:B@`ӦMkРIرQs6c{Ձ^z _T˖-NAmmm===aͽ>wa_o2%Q0GWwOD"` }y3.{3C[zc8P`ņK~5ɰ.Nq}vtPO2Rb^MZ"PbqT H$R*UhY)))6H.CŬ,|$%%rJKK`Ǟ*++-̭#ہזrc߼Yf&n~gRjRR}+MOō++-EC!.=wI~›B!n(D1- (BCEMGAO7 BCAjF跨oQ(D1.pV 7(Bçz- ( C Q 7(B{*Xc +55EMֵFv%IRRܔwG-\.7=5a,bZ6C>v1USu]T_yyRo E~K cb(D1TMG%Fj ivvvdlo?)H$78rrrڷo{.],NHG=^z۳g+WCAAA`A;pz ֯_aÆP,rX&og=ZQC9ac&BC57869^W: 3+vPQN qj*qt}{@kj|8|PfP,rX&*ZX>l3>\D1Q wZ~pZCL\\ܓ'O4 _511Q*F6YRNzK 9.Ŕvl2|p`&V C4`ggg#G;Ǐ[jp!d˖-2Jj޼ŋ)^.\0k4Պb跊1p(sV,.MHxU&=nu+MNd­Mօk?nNMvCC~Tjw>0ZV?eu&'W(ǍuTY[WڱCъyxF(BC4 uuy999%%%|Jaa|ܹs'99ضdbA0ػw/|BDS~%((vܸq,u ͛7ςK.?NHH‡b٨Q+ƍSDD__߷zzD;w|饗 L'''uG[c/(korV"OKHWSTV, 73Ŋ-`|풫}Z`t4R%eJ0;49i1aC\a}3a0ś6=Q (s(dẨ]v#͛.]a( YV7*lEEEUVDڵ8qb-XZbf{uh7&&89H0ȧxzz~[&ٳG}d:Hz:F znX: uhz=-m~r4i,uA1-ML=ѸcrL4drSQ|4zӟoP~:h}A=Q (zPL@<۹s5JNN縸8 Bښ5klmms*;yd>Ϟ=;88x`q峛RX@@ۿPL8>2[bQR^}Ugj={4kŖAϟK'NܺbU?|/qtVUΘuՂE+Wo5[.A1լ/Š/*ٽ[V]m^[RzI ޥՖ'о4) ,2qw"|'J111p:E z. Q ح[ W@gΜٰa! @ߟO2ҦMX \v233M%((7j('''8ϯ寮tēKonժ$ y-&`_B6l_Yp ZAx7I>cFkѠe*@ו?;RtZ{m.A1@帱㤮T[P@_Ȑ?Pj$0ֿwh/qiQzנe[+('}h>\D19CSN-[@ϟ:?3t pvvwӹsg83g΢E`ǎ`'++d]AʬYN .\xXXX޽X,Ӂ裏>ӧO||5k֣\@9wz˗4uH@1Sv=Q (zPz"Q~}c ,O|X]}y{{wڕe|XG^^^]KgԩSf&!CҥK|2www`Ah}4uŬ;JI'KU_` |X](?J֫'+__sWo̟cM1ˊӟ㖎 _ܗ(bG(BC9w;[nCZff&䦧[6lxЏɇ h4N: ?*Aኋ۶m2>v cR~̙֣ؠA^uaJXXO[CA X}4蹵b"H,iZ2z&.q\A3RqcYƇޮV~B+I[R*@1OYg\/0 Y}ZD[P݇(ƎV HE X}4蹈b(D1TC1\| $""bٲe1[EEE࣢#Flll.\xV a]:$'' ?Jޭ[H@ &], #ЧO8aIJJ~ 2e 9&Y+ŋkT*܋֭[bYG|׊ :455q4L.Ur,`_Li>ڽ;R7OR>,{:* PIsrTIS˗h|`8E(|}}4nPAD.-Woܷ$V,FRG )uob#GT. Q UP  Qmɒ% # i  @+ 6o#THH_ //TG(.شi4h@;vxk&۽zIn^Le˖gl=zrazwؗG[(V}~o#+9"Mu0S}y3.{3C[zc8P`ņK.5.N>-T9qVZ~ż<ٗG(BC&Qq  @T6.knOII15Er*fee _)VIIII>n4MFFFrrU-]0[EhBCߢPb( i(D1[t Q 4tC!oQ(D1f~zBCP( BCP( B!P( B [1BIENDB`backintime-1.5.4/doc/manual/src/_images/rule_keep_last_each_year_for_all_years.png000066400000000000000000001464731477034762000305020ustar00rootroot00000000000000PNG  IHDRSsBITOIDATx}XTG'Dc"E#/hԨB4J"-OAb؍bAG"UK][hهg﹇39̝;@ _X@ g @@ <@  @ 3@ g @@ yF 9s`#{g϶ܷo_DDj ܸq_ ۷/V=@ _U 5_ѱcG_r8QЦڀX,vuu?WXqСdlcש3ZlG1F׮]y<ʉg;vLIaa!<gϞ--,,j #Ft.EӦMakmq7jԨ~m۶m?@Qu1n:矕^ ݑghgQܹs".upsQg@QFCZjm6Ӻukg GGGtRQQQǎ Z:%%%7nx%|vھ}TIMM;@ SLQf0PȏCFFRH$><} Rvkoo_M٣h{U]Ֆ}WNmz݃S'3}UTgr2?`Ti Y*iwwwPeګ @|M97o6)5^.siwmZWat}~K:+>o_ U- 3L!?KH=vgYuM5s $S<ؘ(ff9RSS[7nx1`yC ׯ|Q:mG.*-6I;LGxƴ31f H=S5^СCûw2[P,QmZJF:dS.Z~4** tP t[={g_le[?>Ϥ/I2 .gC5WC+uڋ% BeFFt0ZF4Ruٗ]MϨkm-π+ŵ3:t*m۶w521eHѣ p̙3L-V6:JׅBigȥ:bN8D .i333:ѥ%QmZJ:Af)vW-?rm~йz*S uȲ-ԏ7LʩS 4Uׯ!*qGڋ%Hedd˥zkξ53ZjygQ僼:ϰa{tO}zag}ƌlt;ҽ{jgɳyt(`e rC~~n遛)͉FxFiՖek$?WA:dݕU[,Bx>ϤtwwW9,}6%cE x)ڰa9r$Q.Ms]kwe1QT#{5@={F ̕*~jA7A)WqUT,yy/Mս{<ř@5(w&jgɳxyә:J"??ŋ&M0FigT:dS.Nf~Y25*iBBBTjBSMIz{{9[^ϳiS腪ݳA011!iNNNƍl٢riZsjl_klS5%'w連rBp$ *x5ޭ[7!}89T9- ekk 8wy|A܀lt;ӦMS=>>fff3[~=U1cs2$$$xJ|W:dyV?ްy :+Ž/_!/4AW5^u?I~),iݺy`N]L8ZB$[?d$J<=r{x:.~hY<Z74שM ]ѣg:uiZ̙z-Pls mڴquu=<>MM6A~ܹÜt9 FG$֭:/.X޽{DoܸǏs*;IM)vT~@ʊwt]}uȩ-Ԍ7,@vvvLrRϳiSTZ-8߿8 lR<]+|еBW.MsjweSڔ޷o_ҡب3JJJ &':r4?W+;rvv&+J(ݛ}ҤIJ7,xB___)e, DZ FiiiTxxJuHo7oΊW'pZ{H#\qlbh>͏\ \L_(X<'MVQv6`:\l]D_P߽{۩9MYCr9ZM :BhYq9 I+; S#`=שvg٦cuQrzށ^Яg_jϟu;޾}{U(p."##/_ 'P~͍,P|J_MUwRSS5Ǫd_.xUDDDvvf:Cnnbf={sJjREطCY_Uԡ.wo߾=Ǐ_O~zzƍײeK;ݼySrjjen@EÇwssS&)3g5<y7̙3.6>x ?L人aaa /WS7nx߾}rvvv*$pqqjwmStttt38 66iӦSGSyDDj"5kVݻ7yͿ{(}?pɓɭ6m@IǍG TI?oLààà @ -}e" #bbb۷o={9442999;cǜ8 Y@_t\Kbhh8dȐ$"e\v-3F?1HPea\MJ$RttttZ֭Z":vXG% .?sLݙ3{&&&>ijj ]nΝ;LMCWW7..˗'NbnnBHjj*|58g*ߴi~iì-Z0(IFnmVzwiERyVX,d=P ABBSsϞ=D3Ѳeˠ 9x*&EwO<VRzR4ӧɴiӘWֳ2 (feh %*Ow"ttttZ@۵kGs׮]˗}fȭ3gB] 5dL5k֘޽ٳǏ_E"##߫W/rk"_>#dmmMSuߟYR xFC"W(W^oT)&M^@|D|XGUR1?$rààà @lܸQnXYlձcG:wM/UIO*/,)y'}}}Z++@^@ZNZS(TfDWaaaag jg$&&Q~F^$VROxDta%000033N6MQcdd d};" 4^@S]a7d 2 '_ggg`s@濪V@|y%KPkkk"ٳg1Av8r j߾}o=xmR] } \8qV†ȵyP|I__Ν&Mjٲe`` Qvv5vX*"11(:ԩRCT)M grĉTy/ޞnxc:eoSߞJ^H%%?ʾƔEbtttt:3vRzؘ9RQpuu%rT_y߿?SLJvifN6@/5 ^TAqy IxHHIHHЍj0XxqƍahBy|//{xxН8iiidbʕ F!|W<Q<9\<ɠ _!''رcΝSUz3y Daaa3 0l a3g @`@ ag @`/@^a@<y(P$G\EèS!Pz!eR9J1T?K\_~M"S@oL)J:lVz1߼H\BOp_iỊ3>e}=, oT%W>fZd p$4G 000-`^QYX% ʦ7ʝikCHgگ8Ctɉ2a*!B^[_kKwedFɻ%e*~;Qݚլe~RNZx4;ڔߋ 9)V 'JZ- U|h$|+h<gc$e ߕ7DqhIp\R!k!QtX/2X+)Y2!ɔ?(_y2C|_GU\-Eѥb`roF$YR ~ f/PIrB@0ԘZ$[RGVRv& %jv{DZ!2,)@ o 8làà4He=B^Q G#ieko/FBrŏ$ >làà4T<@9ϰd3 aS4>%3%͗Pn'PΓZEׇ$Jx?>u(X%Vx;"mc$J!y\/ -B/)*RPM% 'ҝfq oj@AAiSx*H |{g23J7%{Dŏ%O.@[f_ WaA(w@H*J>%ު\GFNv JN/ <-XE'K;>o@/Q*:$̏Il4B`ŏX^h*-IyP: : :Lv3eo7wgTwÒ sDSd/~ ʔ.*ͥ&oԝ^Gtǹȫ,(n1W̰C: |䓏l"Y*򣩴sC*ȅb6A ttt0gHs*Kڢ<`v k3DuM .Q_liK!'; K?ds {IVz󣩴d(}= ttt0g Ts ߬'3Nb`!?9\vUU.ST"E.}GL0}VۑdsJs~TN sw u;: : :̇0gNL1%玗ni弡"EAI3dYI%J/ {]*:GaJ_{ډĘ~*dҎzol~+:"&XUjZɂ! %񒂿dZvߠààà PЧcolI,3x?fK2ʼMVJ[zޕ̓M+<,r컒: R43$]ZUHOdoQ#J' Uz_?ۈ?ґY 000]ti ?_!y&ֹYMFLQwj7;2E*a7: : :Lu3@ԩ&@AAA @`/@A @<ay: ظ000Uр@A#AG8P0噕ð.׹>pSqcYwr?54j`KE.oBz1-]]Ϩ6l\),lNH~%m!g 4 _xGFFjxW^yj*{^/H}ĉR"ª)';U(Hd``0eʔ+,l5~x r60%~sU=ㇹ `>1>~jzo';eS\B#L*>Jy|g3+dQe|i"@h~!sr 3_ "k!~C~SWqe” vdNwɍeOp^ZS P-Ϫύ`0{1F'a[M-#bO?qM;O9xaK:1p'"mK(_泷Sü3kֲ1" ZeaORagkXjy^YYY-Z0aSn:@Ѕkׂ"+{;gϒK˖-P!*׏j֬٘1c~?޽FVQ^ *嬋:q״FӀ.-BdeoG0/MZ0=ڭ BUo0k1,ʏ=GW axE/`uSx1QBn>¡R!DVvd W%p´3Tȳ f Yb֪Fqg _/0ydr;NW\I3~2tEvcǎС]йsg9aܹx-s Mi @8wD3m Uq(/w'+7?rϬr%S!{[Ef7HL8鄷f i!dζ6e7ݬ{jONv\n>Y&,}̚ߣxZOe<}٠rf -L!aQٯq>QzCtNT_fY9B0u,lgϞ?ѣGC]CU)}'.(.Z;#-egVâ~zL#π?*N0=qe!ϙQ\n'gv *-eg6`S?]}0Ik/ {/^Ė*n"%%%*[vvvnԨѰaNTăȼybbbvA~ک D*󌠠 R֭#`}ـe!-L|||xxԩS˵60~\v'=9rjnyY;ϑ/ ک0<#(7-&|VuQ%dgVî\}!-L&`}ـe҂<=I[{<.F#@h8j jyR[i߿M6n^tU2:l~ڶmK~tÆV&|DDָSprd7wI<5J;˼>ɓ'WNj7lԾÔ&% R05gDBw$śl~`j4bL^J& DCu aaa3 0l a3g @`@AAAA6.: : : yBGA4` aag !Oaa|h@<<<y  t3gh"kk[nlѣTW`Z!!!-X C˗[XXرughaEWLt^UY ϟ/ZnUvmݻ))ӧjJQ&:vTNxzYSl%iug˜BSyDDE"5kVzKһwo͛P.?pɓɭ6m@IǍG ڄ^qȐ!84i$** yxFNNM j?~v۶mϞ=Sr\\\Ϟ=0` )zzza71bD߾} T@oԨUjo߾BCk׮ݍѣGCԬY3ggZrI|`OM!#F:bؖ7V0Є׺T)?}kZwuUm~4,9 *q]DG  )8>c:34^|O <111gϞ 442;cǜ8M2tpz%!$"qڵT r"ǜH%`3==z GGG*9rTPA&yyy;wܽ{D"Q-[ӨܡC}}}n1ՠ[( #cr9|I/!H,Pm~4օ tҺuk(/^믿DZrΝ#)9 t7o].EKv?!Kˢ͏ z)ٳe$7W Yug@lժcǎ v*Yp3gw|#455F.Ν;LMˡ 㙗/_N8 A]v-\BH`$5?Iϰ={6XhժmZrӀ-ZWYJ/_T;;/#O9]\ ?q͏F3v. .;veرc ;v|⅜BA 6ׁV3ttt"##RSoXn֬GEf̘ .WrLtyy!f0j'@M9dUG]]˂ IAvXaMr_jgha3AV5\ã,F[XP {; Ξ|2"y TZ َ6_ HJJuڴi p*##te;YUڤIw!`РA MaÆѓ," +NզRPvҮ];Z?*O3TXVz7"",M7t@9ٷoߏ 9v/h*-xH$=zt -9ɑFmһ% ɷtCx!';Ç &c: %&?JK5#g[U%Kö?'w>lEuΏ*3[iYׯXҹV3K*z33o@&Pz~  Hƍ[lIm_~ENÃAcnn|&}ƌtF|ru @hf-FEE%&&2OEԩD8+yA.Ϩ %11ݪuaV~D"I||Itϯ1E#Gܘ% 0|+0=vعs7Nxʕ+Ǐ?}kbXg TàYa @`E@@<yy:  س`EAA@@@@<yy:   gA4` aag4LG09 N  03g @Q<; 93gp@ff3brs)`~q@zzƍײeK;ݼySrjjen@EÇwssSfXX{Ѵiƍw~< 3aΜ9t~g֣_*|߾}rvvv*[nԘ&D ta0!@<bcc #""#YfկI޽{7oᅦrѾ> gO_|5+-6%v|f^jyfl8\|jtҋ7356-˗‚H (1to>{shhhesrrݻwcǎ999q2tϹ($$뤤$"e\v-3F9tD8b"N_Gvtt#GPMq[!;LwgΜ9wܶm۶lg/N^we|}fm6dK]Cr~x@ ov#pv߀`d߷FXYZu @ EL`LByfy [qr-F/w+#@D؀~UVS;v,H C'ҽ{wÇl€On*Ν;LM'ˡˉ'177WP`$55^>{3goڴk踼E%,m* M|#N T#Wĵ<c1uەj,'6%wHr|`ŊS 7 ̈́={x-[1:+=rm۶T̻'Od UԟR4ӧɴiӘ߽{ME IzuNPd'Oބyy*)H}eo)!aE\tlfᦣ=W͘7]O?1ouܹsI4:s4Wih<uo޼9p5ny@y2n<0%%U,T#_,R'W3T˳j fo>Iͳ;=aY< :ubA`zrDEEщC1^ =/6oܭ[76a„*ԩSA,SMJJ/:DGG3,_`С !a޽\m*۷oo0<t6jɓ'켼D"fyFVxp1јgFi|*Bdeoը7u˹a:VP!*׏w`26d ЦUG"'d#@\رq0}⅜B 6+.6lDFF PDiii| #k׮)Ӈ]f%|ti T'BӁ QDd {@U ˔a|k:6,YBN~Ԏ5ٳf0f7MSRĕ+W+`ܴf\\ߴ4*yI֭i*@ixIdΝS߲w`N'MH{ !sݵ)f V{rqdoig3T],z;)}! ٯq>QFhh(]羚sNoooI&l200S;]vuss;v,v=11Q6N:/=EQҴ 'RMАC???{{{CM"TsVVVڰa ݇3aTq7???'b L;wiD0=qe!ϙQ\n'gvE^V8+Σ4sJy<Tf˸>Q`׮]J]S#G**##DSإ` zRߟCE`B7Kr0 #@ixS]GGm۶A YYYAAA۷o߷o_aa:SL;y3 |JN sAo#^kԲdOv,a]nŏ\vqjϷBu,fX*|VÞɥX>l~҂<=I[{<.F#@ԹA:z:M-$$$$$F.^q0g͇_~ENÃ@cnnΜd>c :gK,_\g40.Wٔby}ڵktmcC0ðY% 5k ⒤oҲꜬ%.<{61M~m}ўgR2yWNg n@0;@4 ^߅x 6a33g g g @<yV,:      333g @рр@A#AGzàB{`3gayyyyy 03>40?.k"@`@ @4(9cƌ)>}ݾ}{J9?^EzzƍײeK;ݼySrjjen@EÇwssS&ԑg 0l g |Ɯ9sv2oDVHFpp_~_qSNNN600PTS&ԑg jgH$F,XYY-X`Ϟ=0jQ& O>h"kk[nfG,P`;vxrpg6`Y?.\hkkU/xHrM-T-Ϭ] salcOFM<=<""D>k֬w$͛7\4GLɓ'[mڴ7p5u YYYΜ9sܹm۶mٲ%::ZMqqq={gf&&&Ч)dgll {Ĉ}ډA&Mѣm֬jQy]PmـeQ~:f̘^zuرyd&ܘmޥ!'7>E/Wj'MϤ&n߁w4`T?F,)Bfe>P0噕ð>\&&&vA___,3ՠ[XWϟ?lKv_xA.믁j@DZW.\ҥK֭axQϨ6l~՝={vqq1|v30qz/Jv1bIq /3CBئ,$0\0aoFVQgIr?=gYϨ6Ϭ]^8;xcar|aVH;v,H S… vޝFÇlHC݁ѝ;w?1dM8 t)* gϞQs̡M6!T%Љ-Z0׬Iy#'Oބyj*Ї~JZ٦}gz Nvq)ЁA D")Sddd`H)`gM-|i{m9LBDC<~=F*_*s7qa]K/nssgҔU?Q3X{j5R rugVXA CCCmBBSsϞ=t-[QW!tIãMÈBM~bޢ/֭[s%)R:eooզʚ356矓'OyyyD"͆,(L0)gڵkA͛7H`$g3״*+׾}g}Fwszk׮ugha 2QPa,2r? 1bR;&[y =Ya @`giUV}`3qo9uWצYرc ;v|⅜BA 6ׁV3ttt"##RSoXAt#r }!w׬YciiI2'ʪ& DLݻ:MY&˻d5+7775իA(wJDvedNU;wrl5uQ{yy1˗/!] QghabOBtJU ȉpK 1XyrDTmGĝM Da^3,'&\Ӫ\Gz+[iYugT3[(733s=zh CݹJ5jQ1c h^&WM "p'@m튷jM-={6Q@ {@U u 9>z ;L'O8LjM[]/ |-ⱷa ~jy3H%=|~3tΝ;O4e˖D->>ڵرc{Jvi)a*ԔeTEL8Q!C???{{{8M353mo߾}XvvvnԨѰaNT Gȼybbb _}0qz'K;A1tm۶>fuw+٪n:rOQmـe@@ZCçNJiE-Ik;<ȉS =/tK䀜|y'{3KK#NC&aKK?t:!WF߄٪.IaՏs_H 2ԇk oP*ڵK9]ccc6rHEz(U9]3p(E>>>䥉̟tgoS356 <\zM)6o "Sŋ֭[40N^^ނ hokffF,p49|yfNOϬKm"w?GQ5 ̀D`Bu]t+ldd$<a<y: 6aaaag EA gEG Ӕ墢"++ ٳ'33SP(<}EoݺX|r ;v<\J 9p@jjjyf 6v N?z ZNIt?``D'nU.)R߸DMF jsFS~g 46D"t\TTWZ>|ϣMHH飫kjjɎ>)йt@%L2Eu),\gϞA6nG##~:Іü !a^$ok׶_9QBΝl/w=F`ԿpL˗ .Jy`eg\sFaټZ)n$u u!7Ȅ#yopGY.Si HΝˉg3Xɓ't:~ .Ϩ)> Sh_eaU* (|YX~{wl~;*䊟ŋ8 6yf˲K h ~n'epwm޽t.:A?ӲL#B)^nsVlWTaSP$=P~Zg|clNK.<Q <#77z7ޯZaf|trroڴ nnnkkիW0**E@@UxMYƎ ݀X&29rX}ww0aaa0 L?y[t#)l<-In up#I/ްFG(.092TZ|d ]7oބݵrѣG˫_iw'Nە}jMٳgfoGQF\\3Ž5\uʝ;wj+lhaM{*UZS|Je17oQl7G\\}v֮ю 1J{0!L!0lVvv' HpMI%+oMtFhk܃W boKT34V,d^<ˀ.ݕލ 444, ~(rG8`ΤI@G GGG>}†VFkcwwK"#!d0B`-dqW`hɎR-fA>UiSeÈ]/J^mMH?