pax_global_header00006660000000000000000000000064140301213000014472gustar00rootroot0000000000000052 comment=ad8be708251c55da3a87077ef0f7de496916b9b4 CPU-X-4.2.0/000077500000000000000000000000001403012130000123315ustar00rootroot00000000000000CPU-X-4.2.0/.cirrus.yml000066400000000000000000000012421403012130000144400ustar00rootroot00000000000000task: name: FreeBSD freebsd_instance: matrix: image_family: freebsd-11-3-snap image_family: freebsd-12-1-snap image_family: freebsd-13-0-snap env: IGNORE_OSVERSION: yes # supress package installation error on FreeBSD-13 install_script: - pkg update -f - pkg install -y cmake ninja pkgconf gettext nasm ncurses libcpuid pciutils glfw libstatgrab build_script: - cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr -DWITH_GTK=0 - cmake --build build - cmake --install build run_script: - sudo CPUX_BCLK=100 cpu-x --issue-fmt - cat /tmp/cpu-x.log - cat /tmp/cpu-x-daemon.log CPU-X-4.2.0/.github/000077500000000000000000000000001403012130000136715ustar00rootroot00000000000000CPU-X-4.2.0/.github/ISSUE_TEMPLATE.md000066400000000000000000000001411403012130000163720ustar00rootroot00000000000000 CPU-X-4.2.0/.github/ISSUE_TEMPLATE/000077500000000000000000000000001403012130000160545ustar00rootroot00000000000000CPU-X-4.2.0/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000015311403012130000205460ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us to improve CPU-X --- **Describe the bug/Expected behavior** **Additional information** * Operating system name and version: * CPU-X installation type: **CPU-X dump** CPU-X-4.2.0/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000007351403012130000216060ustar00rootroot00000000000000--- name: Feature request about: Suggest an idea for CPU-X --- **Is your feature request related to a problem? Please describe.** **Describe the solution you'd like** CPU-X-4.2.0/.github/ISSUE_TEMPLATE/libcpuid.md000066400000000000000000000004631403012130000201740ustar00rootroot00000000000000--- name: Wrong CPU Code Name about: Create a report to help us to improve libcpuid --- **libcpuid dump** CPU-X-4.2.0/.github/main.workflow000066400000000000000000000003161403012130000164110ustar00rootroot00000000000000action "Cirrus CI Email" { uses = "docker://cirrusactions/email:latest" env = { APP_NAME = "Cirrus CI" } secrets = ["GITHUB_TOKEN", "MAIL_FROM", "MAIL_HOST", "MAIL_USERNAME", "MAIL_PASSWORD"] } CPU-X-4.2.0/.github/workflows/000077500000000000000000000000001403012130000157265ustar00rootroot00000000000000CPU-X-4.2.0/.github/workflows/appimage_continuous.yml000066400000000000000000000031251403012130000225230ustar00rootroot00000000000000name: AppImage Continuous on: push: branches: - master workflow_dispatch: jobs: linux-appimage-continuous: name: Linux x64_64 (Continuous) runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Build CPU-X run: bash -x ./scripts/build_ubuntu.sh "RelWithDebInfo" "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/AppDir" - name: Package CPU-X as an AppImage run: bash -x ./scripts/build_appimage.sh "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/AppDir" - name: Upload artifacts uses: actions/upload-artifact@v2 with: name: AppImage path: AppImage/* - name: Delete old continuous release uses: dev-drprasad/delete-tag-and-release@v0.1.2 with: delete_release: true tag_name: continuous env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create continuous release uses: ncipollo/release-action@v1 with: token: "${{ secrets.GITHUB_TOKEN }}" tag: continuous name: Continuous build commit: ${{ github.sha }} draft: false prerelease: true body: | :heavy_check_mark:CPU-X AppImage built from latest commit ([${{ github.sha }}](https://github.com/${{ github.repository }}/commit/${{ github.sha }})). See [known issues](https://github.com/X0rg/CPU-X/wiki/appimage). :scroll: Build log: https://github.com/${{ github.repository }}/commit/${{ github.sha }}/checks?check_suite_id=${{ github.run_id }} artifacts: "AppImage/CPU-X-*.AppImage*" allowUpdates: true replacesArtifacts: true CPU-X-4.2.0/.github/workflows/appimage_release.yml000066400000000000000000000023051403012130000217340ustar00rootroot00000000000000name: AppImage Release on: push: tags: - v* jobs: linux-appimage-release: name: Linux x64_64 (Release) runs-on: ubuntu-16.04 steps: - uses: actions/checkout@v2 - name: Get Git tag run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV - name: Build CPU-X run: bash -x ./scripts/build_ubuntu.sh "Release" "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/AppDir" - name: Package CPU-X as an AppImage run: bash -x ./scripts/build_appimage.sh "$GITHUB_WORKSPACE" "$GITHUB_WORKSPACE/AppDir" - name: Create versioned release uses: ncipollo/release-action@v1 with: token: "${{ secrets.GITHUB_TOKEN }}" tag: ${{ env.VERSION }} name: ${{ env.VERSION }} commit: ${{ github.sha }} draft: true prerelease: false body: | **Version ${{ env.VERSION }}.** Portable binary and distro packages are available in following tarballs. *Note: Some extra packages may be included (like libcpuid-devel, cpuidtool or debug symbols), but they are not required to run CPU-X.* artifacts: "AppImage/CPU-X-*.AppImage*" allowUpdates: false replacesArtifacts: true CPU-X-4.2.0/.github/workflows/linux.yml000066400000000000000000000016011403012130000176060ustar00rootroot00000000000000name: Linux build on: push: branches: - '*' pull_request: branches: - '*' workflow_dispatch: jobs: linux-build: name: Linux x64_64 (Build) runs-on: ${{ matrix.os.label }} strategy: matrix: os: - { label: ubuntu-16.04 } - { label: ubuntu-18.04 } - { label: ubuntu-20.04 } steps: - uses: actions/checkout@v2 - name: Build CPU-X run: bash ./scripts/build_ubuntu.sh "Debug" "$GITHUB_WORKSPACE" - name: Run tests run: ninja -C build test - name: Run CPU-X run: | sudo CPUX_BCLK=100 cpu-x --issue-fmt cat /tmp/cpu-x.log cat /tmp/cpu-x-daemon.log - name: Test CPU database with LibCPUID tests run: | git clone https://github.com/anrieff/libcpuid.git "/tmp/libcpuid" bash ./scripts/run_libcpuid_tests.sh "/tmp/libcpuid/tests" CPU-X-4.2.0/.github/workflows/update_pot_file.yml000066400000000000000000000023401403012130000216130ustar00rootroot00000000000000name: Update POT file on: push: branches: - master workflow_dispatch: jobs: check_new_string: name: Linux x64_64 (check) runs-on: ubuntu-latest outputs: output1: ${{ steps.step1.outputs.check_ret }} steps: - uses: actions/checkout@v2 with: fetch-depth: '0' - id: step1 name: Check if POT file needs to be regenerated run: echo "::set-output name=check_ret::$(bash ./scripts/check_new_strings.sh)" update_pot_file: name: Linux x64_64 (L10n) runs-on: ubuntu-latest needs: check_new_string if: ${{ needs.check_new_string.outputs.output1 == 'REGEN' }} steps: - uses: actions/checkout@v2 - name: Install packages run: sudo apt-get install -y -qq cmake ninja-build gettext - name: Disable all options in CMakeLists.txt run: sed -i 's/ ON)$/ OFF)/g' "$GITHUB_WORKSPACE/CMakeLists.txt" - name: Generate files for build system run: cmake -S "$GITHUB_WORKSPACE" -B build -GNinja -DWITH_GETTEXT=1 - name: Generate new POT file run: ninja -C build genpot - uses: EndBug/add-and-commit@v7 with: add: 'po' message: 'Regen POT file' pull_strategy: '--ff-only' push: true CPU-X-4.2.0/.gitignore000066400000000000000000000000521403012130000143160ustar00rootroot00000000000000*~ *.log build* packages .vscode .vagrant CPU-X-4.2.0/CMakeLists.txt000066400000000000000000000136461403012130000151030ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0048 NEW) if(POLICY CMP0075) cmake_policy(SET CMP0075 NEW) endif() project(cpu-x VERSION "4.2.0" LANGUAGES C ) ### DEFAULT CONFIG # Global variables set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(GNUInstallDirs) if(NOT EXISTS ${CMAKE_INSTALL_FULL_LIBEXECDIR}) set(CMAKE_INSTALL_LIBEXECDIR lib/${CMAKE_PROJECT_NAME}) set(CMAKE_INSTALL_FULL_LIBEXECDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}) endif(NOT EXISTS ${CMAKE_INSTALL_FULL_LIBEXECDIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/bin/) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/lib/) set(CMAKE_DATA_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/output/data/) set(CPU_X_DATA_DIRECTORY ${CMAKE_INSTALL_FULL_DATADIR}/${CMAKE_PROJECT_NAME}/) set(APP_EXEC ${CMAKE_PROJECT_NAME}) set(DAEMON_EXEC ${CMAKE_PROJECT_NAME}-daemon) set(DAEMON_PATH ${CMAKE_INSTALL_FULL_LIBEXECDIR}/${DAEMON_EXEC}) if(CMAKE_SIZEOF_VOID_P EQUAL 4) set(BITNESS "32") else(CMAKE_SIZEOF_VOID_P EQUAL 4) set(BITNESS "64") endif(CMAKE_SIZEOF_VOID_P EQUAL 4) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations -Wno-unused-result") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -Wextra -Wuninitialized -Wstrict-prototypes -Wformat -Wformat-security") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now") include(CheckCCompilerFlag) check_c_compiler_flag("-no-pie" HAS_NO_PIE) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND HAS_NO_PIE) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND HAS_NO_PIE) # Options option(WITH_GTK "Build support for GUI in GTK3+" ON) option(WITH_NCURSES "Build support for TUI in NCurses" ON) option(WITH_GETTEXT "Build support for internationalization" ON) option(WITH_LIBCPUID "Use Libcpuid library" ON) option(WITH_LIBPCI "Use Libpci library" ON) option(WITH_LIBGLFW "Use Libglfw library" ON) option(WITH_LIBPROCPS "Use Libprocps library" ON) option(WITH_LIBSTATGRAB "Use Libstatgrab library" ON) option(WITH_DMIDECODE "Built-in Dmidecode" ON) option(WITH_BANDWIDTH "Built-in Bandwidth" ON) option(FORCE_LIBSTATGRAB "Force use of Libstatgrab instead of Libprocps (GNU/Linux system)" OFF) option(APPIMAGE "Enable workarounds for AppImage" OFF) # Colours string(ASCII 27 Esc) set(ColourReset "${Esc}[m") set(ColourBold "${Esc}[1m") set(Red "${Esc}[31m") set(Green "${Esc}[32m") set(Yellow "${Esc}[33m") set(Blue "${Esc}[34m") set(Magenta "${Esc}[35m") set(Cyan "${Esc}[36m") set(White "${Esc}[37m") set(BoldRed "${Esc}[1;31m") set(BoldGreen "${Esc}[1;32m") set(BoldYellow "${Esc}[1;33m") set(BoldBlue "${Esc}[1;34m") set(BoldMagenta "${Esc}[1;35m") set(BoldCyan "${Esc}[1;36m") set(BoldWhite "${Esc}[1;37m") ### MACROS # Macro: print_config(libname foundstate withstate) # Print the state of CPU-X features: in bold green if enabled, else bold red. # @libname: library name (e.g. GTK) # @libver: library version (e.g. XXXXX_VERSION) # @foundstate: the result of pkg_check_modules(...) (e.g. XXXXX_FOUND) # @withstate: the CMake option which allows to disable this feature (e.g. WITH_XXXXX) macro(print_config libname libver foundstate withstate) if(${foundstate} AND ${withstate}) message("${BoldCyan}** ${libname}${ColourReset}\tsupport is ${BoldGreen}enabled${ColourReset}") add_definitions(-DHAS_${libname}=1 -D${libname}_VERSION="${libver}") else(${foundstate} AND ${withstate}) if(NOT ${withstate}) message("${BoldCyan}** ${libname}${ColourReset}\tsupport is ${BoldRed}disabled${ColourReset} (explicitly disabled)") elseif(NOT ${foundstate}) message("${BoldCyan}** ${libname}${ColourReset}\tsupport is ${BoldRed}disabled${ColourReset} (not found by pkg-config)") endif() add_definitions(-DHAS_${libname}=0 -D${libname}_VERSION=NULL) endif(${foundstate} AND ${withstate}) endmacro(print_config) ### HELPERS / SUBDIRECTORIES set(GIT_REVISION "") if(EXISTS ${CMAKE_SOURCE_DIR}/.git) find_package(Git) if(GIT_FOUND) execute_process(COMMAND sh -c "${GIT_EXECUTABLE} describe --long --tags --exclude continuous --abbrev=40 --dirty | cut --delimiter=- --fields=2-" WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_VARIABLE GIT_DESCRIBE_REVISION ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) if(NOT ${GIT_DESCRIBE_REVISION} STREQUAL "") set(GIT_REVISION "+git-r${GIT_DESCRIBE_REVISION}") endif(NOT ${GIT_DESCRIBE_REVISION} STREQUAL "") endif(GIT_FOUND) endif(EXISTS ${CMAKE_SOURCE_DIR}/.git) enable_testing() find_package(PkgConfig REQUIRED) find_package(Threads REQUIRED) find_package(Backtrace REQUIRED) if(WITH_GETTEXT) find_package(Gettext) if(${CMAKE_VERSION} VERSION_GREATER "3.1") find_package(Intl) endif(${CMAKE_VERSION} VERSION_GREATER "3.1") endif(WITH_GETTEXT) include(CheckSymbolExists) include(CheckStructHasMember) include(CheckIncludeFile) add_subdirectory(data) add_subdirectory(po) add_subdirectory(src) add_subdirectory(tests) ### UNINSTALL TARGET configure_file("${CMAKE_MODULE_PATH}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY ) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake ) CPU-X-4.2.0/CONTRIBUTING.md000066400000000000000000000115461403012130000145710ustar00rootroot00000000000000# How to contribute to CPU-X CPU-X is mainly developed by @X0rg, but contributors are welcome! Here is some things to be involved. ## Translate If you want to translate CPU-X in your native tongue, please visit the [Weblate page](https://hosted.weblate.org/engage/cpu-x/?utm_source=widget). ## Update databases When new CPUs are out, we need to add them in databases. You can find databases [here](src/databases.h). Also, please note CPU codenames are defined in [libcpuid](https://github.com/anrieff/libcpuid). ## Develop CPU-X is written in C and uses the CMake build system. First of all, if you are interested to modify CPU-X source code, take a look at [how to manually build CPU-X](https://github.com/X0rg/CPU-X/wiki/manual-build). ### Source files The file structure in the `src` directory is the following: 1. CPU-X core, where data are gathered: - core.c - core.h - cpu-x.h - daemon.c - daemon.h - databases.h - ipc.h - main.c - util.c 2. External projects, modified to be integrated within CPU-X (optional): - bandwidth - dmidecode 3. User interfaces (optional): - gui_gtk.c - gui_gtk.h - gui_gtk_id.h - tui_ncurses.c - tui_ncurses.h ### Add new labels Adding new labels to CPU-X is a little bit complex, but don't worry: this sub-section explains how to achieve that. This text is based on [this](https://github.com/X0rg/CPU-X/commit/ba60cbfc18952fc52b16a4c34a33f565493fb125#diff-8e11e336b0bbcfe85860ec612c712da5e03aebc0a755e6fcea1efa867c72b2f1) commit. :warning: Note: this guide does not explain how to add a new tab. **1. In core** - First of all, you need to add a new constant value in the appropriate enumerated type in `cpu-x.h` file; look for something starting with `enum EnTabTAB`. **Keep the `LASTTAB` value add the end.** In this example, `TAB` is the tab name and `NEWLABEL` is the constant value for the new label. - Set the label name in `main.c`, inside the `labels_setname()` function: ```c asprintf(&data->tab_TAB[NAME][NEWLABEL], _("Label name")); ``` - Set the label value in `core.c`, in the appropriate function: ```c casprintf(&data->tab_TAB[VALUE][NEWLABEL], true or false, "%s", XXX); ``` :bulb: `fill_labels()` and `do_refresh()` are the calling functions. **2. In NCurses TUI** You may need to adapt `tui_ncurses.c`. To print text on screen, `mvwprintwc()` and `mvwprintw2c()` functions are used. If your label has a dynamic value (e.g. which change over time), also you need to adapt `nrefresh()` function. **3. In GTK+ 3 GUI** You need to use [Glade](https://glade.gnome.org/) to edit UI. The UI file in under `data/` (e.g. `cpu-x-gtk-3.12.ui`). Two labels must be created at least: - one label to display the label name, with an ID like `TAB_labNEWLABEL` ; - a second label to display the label value, with an ID like `TAB_valNEWLABEL`. On top of that, you need to declare these ID inside `gui_gtk_id.h`, in the appropriate array. :warning: Please respect the same order as the corresponding enumerated type in `cpu-x.h`. Then labels are filled from `gui_gtk.c` file, by using `gtk_label_set_text()` function. You may need to adapt `get_widgets()`, `set_labels()` and `grefresh()` functions. **4. Verify** Build and run CPU-X. The software must not crash or freeze after these changes. Please check all modes to avoid potential regressions: ```shell $ cpu-x -Dv $ cpu-x -Nv $ cpu-x -Gv ``` If nothing is broken, congratulations! :tada: You can open a new [pull request](https://github.com/X0rg/CPU-X/compare). ### Add new options This section describe how to add a new option. You can take a look on [this commit](https://github.com/X0rg/CPU-X/commit/6a469c04ba6cba16df31fe60b6c57f56eb217c54). 1. `src/cpu-x.h`: add new option in `struct Options` 2. `src/main.c`: * in `main()`: initialize default value in `opts = &(Options)` * in `struct cpux_options[]`: add a new line entry * in `parse_arguments()`: retrieve value for option 4. `data/org.cpu-x.gschema.xml`: add a new key 5. `data/cpu-x-gtk-3.12.ui`: open UI file in Glade and change Settings window 6. `src/gui_gtk.h`: add a new `GtkWidget` in `struct GtkLabels` 7. `src/gui_gtk.c:` * `get_widgets()`: map widget * `load_settings()`: map setting to option * `start_gui_gtk()`: bind setting to widget 8. Do something with your new option! ### Things to do - A good starting point if you want to do stuff is to fix [issues](https://github.com/X0rg/CPU-X/issues). One example: add proper CPU logos (as requested in #144). - Another point, if you have a lot of time to spare, is to create new user interfaces: - Qt5 GUI can be appreciated by users using Qt-based desktop environnement (like KDE); - Cocoa GUI to port CPU-X on macOS (read #147, #56, #55 #35 and #33 for more details). - Also, feel free to improve existing stuff. For instance, databases are defined in a C header, but maybe there are better ways to store data. CPU-X-4.2.0/COPYING000066400000000000000000001045131403012130000133700ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . CPU-X-4.2.0/ChangeLog.md000066400000000000000000000422501403012130000145050ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - [Changelog](#changelog) - [[v4.2.0] - 2021-03-28](#v420---2021-03-28) - [Added](#added) - [Changed](#changed) - [Removed](#removed) - [Fixed](#fixed) - [[v4.1.0] - 2021-01-10](#v410---2021-01-10) - [Added](#added-1) - [Changed](#changed-1) - [Fixed](#fixed-1) - [[v4.0.1] - 2020-06-13](#v401---2020-06-13) - [Changed](#changed-2) - [Fixed](#fixed-2) - [[v4.0.0] - 2020-05-17](#v400---2020-05-17) - [Added](#added-2) - [Changed](#changed-3) - [Removed](#removed-1) - [Fixed](#fixed-3) - [[v3.2.4] - 2019-01-13](#v324---2019-01-13) - [Changed](#changed-4) - [Deprecated](#deprecated) - [Fixed](#fixed-4) - [[v3.2.3] - 2018-07-01](#v323---2018-07-01) - [Added](#added-3) - [Changed](#changed-5) - [Removed](#removed-2) - [[v3.2.2] - 2018-05-03](#v322---2018-05-03) - [Changed](#changed-6) - [Fixed](#fixed-5) - [[v3.2.1] - 2018-03-24](#v321---2018-03-24) - [Changed](#changed-7) - [Removed](#removed-3) - [Fixed](#fixed-6) - [[v3.2.0] - 2018-01-31](#v320---2018-01-31) - [Added](#added-4) - [Changed](#changed-8) - [Removed](#removed-4) - [Fixed](#fixed-7) - [[v3.1.3] - 2016-10-25](#v313---2016-10-25) - [Added](#added-5) - [Changed](#changed-9) - [Fixed](#fixed-8) - [[v3.1.2] - 2016-10-23](#v312---2016-10-23) - [Added](#added-6) - [Changed](#changed-10) - [Fixed](#fixed-9) - [[v3.1.1] - 2016-10-16](#v311---2016-10-16) - [Fixed](#fixed-10) - [[v3.1.0] - 2016-09-24](#v310---2016-09-24) - [Added](#added-7) - [Changed](#changed-11) - [Removed](#removed-5) - [Fixed](#fixed-11) - [[v3.0.1] - 2016-08-23](#v301---2016-08-23) - [Changed](#changed-12) - [Fixed](#fixed-12) - [[v3.0.0] - 2016-06-15](#v300---2016-06-15) - [Added](#added-8) - [Changed](#changed-13) - [Removed](#removed-6) - [[v2.2.2] - 2015-12-02](#v222---2015-12-02) - [Changed](#changed-14) - [Fixed](#fixed-13) - [[v2.2.1] - 2015-11-27](#v221---2015-11-27) - [Changed](#changed-15) - [Fixed](#fixed-14) - [[v2.2.0] - 2015-11-21](#v220---2015-11-21) - [Added](#added-9) - [Changed](#changed-16) - [Fixed](#fixed-15) - [[v2.1.1] - 2015-08-26](#v211---2015-08-26) - [Added](#added-10) - [Changed](#changed-17) - [Fixed](#fixed-16) - [[v2.1.0] - 2015-08-08](#v210---2015-08-08) - [Added](#added-11) - [Changed](#changed-18) - [Fixed](#fixed-17) - [[v2.0.3] - 2015-03-15](#v203---2015-03-15) - [Added](#added-12) - [Changed](#changed-19) - [Removed](#removed-7) - [Fixed](#fixed-18) - [[v2.0.2] - 2015-02-08](#v202---2015-02-08) - [Added](#added-13) - [Changed](#changed-20) - [Fixed](#fixed-19) - [[v2.0.1] - 2014-11-23](#v201---2014-11-23) - [Added](#added-14) - [Changed](#changed-21) - [Fixed](#fixed-20) - [[v2.0.0] - 2014-11-16](#v200---2014-11-16) - [Added](#added-15) - [Changed](#changed-22) - [Fixed](#fixed-21) - [[v1.2.2] - 2014-11-05](#v122---2014-11-05) - [Added](#added-16) - [Changed](#changed-23) - [Fixed](#fixed-22) - [[v1.2.1] - 2014-10-24](#v121---2014-10-24) - [Added](#added-17) - [Changed](#changed-24) - [Fixed](#fixed-23) - [[v1.2.0] - 2014-10-12](#v120---2014-10-12) - [Added](#added-18) - [Changed](#changed-25) - [Fixed](#fixed-24) - [[v1.1.0] - 2014-09-28](#v110---2014-09-28) - [Added](#added-19) - [Changed](#changed-26) - [[v1.0.0] - 2014-09-21](#v100---2014-09-21) --- ## [v4.2.0] - 2021-03-28 ### Added - Add new option `--cpuid-decimal` to display CPUID values in decimal - Add User Mode Driver (UMD) to Graphics Tab (require GLFW) - Add GPU DeviceID:RevisonID in Graphics tab - Add PCIe link speed/width in Graphics tab ### Changed - Reduce the GPU clock precision in Graphics tab - Reserve 'HT' keyword for Intel CPUs only, and use 'SMT' for other vendors instead - Update CPU databases - Support more GPU in Graphics tab - Use unit prefixes in System tab - Add a dropdown list in Graphics tab to choose graphic card to monitor ### Removed - Remove support for libcpuid before v0.5.0 ### Fixed - Apply dmidecode upstream patch to fix warnings - Fix for `--issue-fmt` - Fix overflow caused by some translations - Fix socket path on FreeBSD --- ## [v4.1.0] - 2021-01-10 ### Added - Add `CPUX_ARGS` environment variable to set default command line - Add alternative key mapping for NCurses mode (option `--keymap`) - Add debug mode (option `--debug`) - Add screen reader accessibility on GUI - Add Core Voltage, Power Avg and Memory Used in Graphics tab (AMDGPU only) ### Changed - Prefix all hexadecimal values with `0x` - Reword nonsensical messages - Update databases - Request `Tdie` temperature for `k10temp` if available - Change bars color in System tab in GTK GUI when Dark theme is used - Patch dmidecode to version 3.3.3c111e4 - Use binary prefixes for System tab ### Fixed - Fix build on FreeBSD when GTK is enabled - Fix build on musl libc - Fix list of influenceable environment variables in help - Fix override of refresh value when GTK is enabled - Fix screen flickering in NCurses TUI - Ignore batteries voltage when searching CPU voltage - Fix build when gettext support is disabled - Allow to run CPU-X daemon from AppImage --- ## [v4.0.1] - 2020-06-13 ### Changed - Optimize images - Prioritize rootless GPU load percentage retrievement for AMDGPU GPU ### Fixed - Fix double MHz and % symbols on Graphics page with NVIDIA GPU - Fix reopening of settings window in GTK GUI - Fix `optirun: command not found` error with NVIDIA GPU - Mount debugfs if not mounted before reading GPU load percentage for AMDGPU GPU --- ## [v4.0.0] - 2020-05-17 ### Added - Add a daemon to handle privileged access - Add basic completions for Bash/Fish/Zsh - Add settings window in GUI - Add "Driver" label in Graphics tab - Retrieve CPU temperature on FreeBSD - Add support for zenpower module - Add continuous build of AppImage ### Changed - Patch dmidecode to version 3.2.5b3c8e9 - Move translations from Transifex to Weblate - Uniform all units (byte and octet) - Rewrite all CLI options - Write output to `/tmp/cpu-x.log` and `/tmp/cpu-x-daemon.log` files when `--issue-fmt` is used - Update databases - Replace `nvidia-settings` command calls by `nvidia-smi` - Support for L1 Instruction Cache information ### Removed - Remove portable binary - Remove libcurl dependency - Remove libjson-c dependency - Remove all privileged access in `cpu-x` binary (moved to `cpu-x-daemon`) - Remove "CPU-X (Root)" desktop launcher ### Fixed - Fix some awk regex - Fix `load_module()` function - Fix options parsing - Fix build on FreeBSD - Various C fixes (unsafe functions and warnings) - Fix Bumblebee support for NVIDIA/Nouveau - Fix with VFIO GPU driver - Fix GUI switches appearance in Bench tab - Fix issues with AppImage - Various fixes in NCurses TUI --- ## [v3.2.4] - 2019-01-13 ### Changed - Build portable binary without PIE - Improve AppImage experience - Use GitHub API to check new version (libjson-c) ### Deprecated - Deprecate the portable version ### Fixed - Wrong GPU clocks with AMDGPU driver - Empty memory bank label - Build without gettext --- ## [v3.2.3] - 2018-07-01 ### Added - `TEXTDOMAINDIR`/`TERMINFO` support - Add AppData metainfo file - NVIDIA Bumblebee support ### Changed - Patch Dmidecode to v3.1.20180620 ### Removed - Support for CMake < 3.0 --- ## [v3.2.2] - 2018-05-03 ### Changed - Update CPU database ### Fixed - Segfault when retrieving AMD GPU temperature --- ## [v3.2.1] - 2018-03-24 ### Changed - Switch Cache and Swap colors in System tab ### Removed - Drop 32-bit portable version for future releases ### Fixed - Swap bar in NCurses TUI - Bug in Bandwidth related to AVX instructions --- ## [v3.2.0] - 2018-01-31 ### Added - Add ability to read CPUID raw file (CPUX_CPUID_RAW environment variable) - Add `--issue-fmt` argument - Allow to enforce BCLK (CPUX_BCLK environment variable) - New GTK theme for Dark themes - Retrive CPU frequency in fallback mode - Add GPU usage and GPU clocks in Graphics tab - Add Polish translation (thanks to eloaders) - Add Russian translation (thanks to TotalCaesar659) - Add Czech translation (thanks to pavelb) - Add Chinese translation (thanks to 高垚鑫) ### Changed - Update CPU database - Display influenceable environment variables in help - Display CPU family/model in hex only - Add a second line for Instructions label - Improve CPU temperature and voltage retrieval in fallback mode - Improve GPU temperature retrieval - Rework GPU detection and improve multi-GPU support - Patch Dmidecode to v3.1.20180131 - Patch Bandwidth to v1.5.1 ### Removed - Support for libcpuid < 0.4.0 ### Fixed - SSE3 feature detection - Cache labels format - `--nocolor` option - Set window icon in GTK GUI - cpu-x_polkit command on Wayland (used by cpu-x-root.desktop) - Buffer overflow in some cases when Dmidecode is called --- ## [v3.1.3] - 2016-10-25 ### Added - Add Russian translation to shortcuts (thanks to TotalCaesar659) ### Changed - Add more AMD Kaveri CPUs in database - Print CPUID raw dumps when using `--dump --verbose` ### Fixed - Segfault in `call_libcpuid_static()` - GTK GUI theme --- ## [v3.1.2] - 2016-10-23 ### Added - Allow to set Bclk through CPUX_BCLK environment variable ### Changed - Avoid to refresh Bclk and minimum/maximum CPU multipliers - Rework CPU multipliers calculation - Add AMD Tyler CPUs in database - Reorganize databases ### Fixed - Segfault caused by `free_multi()` - Socket detection in fallback mode - Kernel module load in fallback mode --- ## [v3.1.1] - 2016-10-16 ### Fixed - Bandwidth build on system without stropts.h - Segfault in `cpu_multipliers_fallback()` - Asking for update when already up-to-date in portable version - Dynamic allocation checking - Memory leaks --- ## [v3.1.0] - 2016-09-24 ### Added - Libcurl support - Libarchive support in portable version - Add support for L4 cache in Caches tab - Add `--tab` option ### Changed - Patch Dmidecode to 3.0.20160907 - Rebase Bandwidth on v1.3.1 - Decrease Dmidecode verbosity with `--verbose` - Merge Descriptor label in Size label in Caches tab - Hide absent cache levels in Caches tab in GTK GUI - Hide empty pages in GTK GUI - Refactor Memory tab - Various minor core enhancements ### Removed - Support for libcpuid < 0.3.0 - Support for GTK 3.8 & 3.10 ### Fixed - Broken redirection with `--dump` - Memory leaks - Bandwidth build with -DWITH_LIBCPUID=0 - Set speed to 0 for unavailable Bandwidth tests --- ## [v3.0.1] - 2016-08-23 ### Changed - Add more CPU and sockets in database - Decrease verbosity in Dmidecode and Bandwidth - Improve fallback mode ### Fixed - Refresh in fallback mode - Detection of GPU temperature with NVIDIA proprietary driver - Check for a new version when network is unreachable - Various minor fixes --- ## [v3.0.0] - 2016-06-15 ### Added - Report total CPU usage - Add a signal handler to provide backtrace on crash - Add `--nocolor` option - Add `--cachetest` option - Add `--bandwidth` option - Add `--core` option - Add a Bench tab ### Changed - More CMake improvements, allow to build with CMake 2.8 - Full core rewrite - Improve options parsing - Rewrite update module for portable version + add `--update` option - Rewrite NCurses UI + add color support + add help - CPU-X logo redesign - Patch dmidecode with latest source code (commit cff11af) - Rebase bandwidth on v1.1 - Recognize more CPUs for the "Technology" label in CPU tab - Print some values > 9 in hexadecimal in CPU tab - More fallback support - More strings in `--verbose` mode - A lot of GTK UI tweaks - Run bandwith in a separate thread to avoid UI slowdown ### Removed - Drop support for Darwin/Mac OS X - Report CPU BogoMIPS value --- ## [v2.2.2] - 2015-12-02 ### Changed - Add technology report for some Clarksfield & Richland CPUs ### Fixed - Avoid to free dynamic labels in Caches tab - Free memory when possible in `pcidev()` function - Fix a buffer overflow on HT detection, causing bug in bandwidth --- ## [v2.2.1] - 2015-11-27 ### Changed - Add debugs symbols in bandwidth source code when using CMAKE_BUILD_TYPE=Debug ### Fixed - Segfault on NULL pointer in `bandwidth()` - Buffer overflow when setting label name in Caches tab --- ## [v2.2.0] - 2015-11-21 ### Added - Add support for libcpuid 0.2.2 - Add new tab Caches - Add labels Technology, Voltage and Temp in CPU tab - Add lebel Temperature in Graphics tab ### Changed - Some changes in options parsing - Update to dmidecode 3.0 - In NCurses TUI, add tab names - Merge Architecture label in Instructions label in CPU tab - Merge GPU driver with GPU vendor in Graphics tab - Update GUI for GTK >= 3.8 and < 3.14 ### Fixed - Typo - L3 cache value - Some problems with `libdmi_fallback()` - .desktop files - Build with Clang - Stop update if curl is missing --- ## [v2.1.1] - 2015-08-26 ### Added - Add translations support in portable version - Add HyperThreading detection - Option `--version` informs if a new version is available - Add an auto-update module for portable version - Add pt_BR translation (thanks to ShyPixie) ### Changed - Some text changes in `--verbose` mode - Improve translations support (rewrite target updatepo, add target newpo...) ### Fixed - Segfault with `strdup()` on NULL pointer - Avoid multipliers "(0 ## 0)" in CPU tab and "-nan" values in System tab - Fixes garbages after freeing - Some problems with build - Do changes to enable compilation with libpci.a in portable version --- ## [v2.1.0] - 2015-08-08 ### Added - Add libsystem - Add a button to change GTK GUI color - Add new chipset section in Motherboard tab - Add new tab Graphics - GTK 3.14 support / partial GTK 3.16 support ### Changed - Improve drawing bars in System tab in GTK GUI - Use dynamic arrays instead of static arrays - Use GResource instead of GdkPixbuf in GTK embedded GUI ### Fixed - Build - Options - Deprecated functions in GTK GUI code --- ## [v2.0.3] - 2015-03-15 ### Added - Add verbose mode (for CPU-X, previously Dmidecode only) - Colorized messages - Add a "Run as root" button in GTK GUI - Add `make uninstall` target to allow to properly uninstall CPU-X - Add `make genpot` target to generate a pot file - Add `make updatepo` target to update a po file from a newer pot file ### Changed - Better support for non-Linux OS - Improve displaying of memory usage in System tab ### Removed - Remove RPATH ### Fixed - Stop spam errors (in Dmidecode) - Options when built without GTK - Incomplete possibility for translation - Output messages (verbose and error) --- ## [v2.0.2] - 2015-02-08 ### Added - Add argument `--dmidecode` to run (internal) Dmidecode alone ### Changed - Rebase dmidecode code on 2.12 - Improve options parsing - Less (useless) function recalls on refresh loop - Display dashes for empty banks in RAM tab ### Fixed - Empty RAM tab on certain machines --- ## [v2.0.1] - 2014-11-23 ### Added - Add possibility to resize terminal with NCurses TUI ### Changed - Better CPU multiplier calculation - Hide non-existent banks in tab RAM - Better compiler detection - Improve option `--help` - Better translation support ### Fixed - NCurses TUI: correct refresh (when left key/button 3 on mouse are spammed) - NCurses TUI: segfault when spamming right key - GTK GUI/NCurses TUI: use timeout instead of new thread to refresh - Segfault when file `/etc/os-release` could not be open - Add more static libraries in portable binary --- ## [v2.0.0] - 2014-11-16 ### Added - Add argument `--dump` (no start GUI) - Add fallback mode for Libdmi (but it not replaces Libdmi) - Add new tab System - Add new tab RAM - Add support for translations (only French available) - Add CPU-X launchers (depends of GTK); cpu-x.desktop and cpu-x-root.desktop - Add possibility to run CPU-X as root with pkexec - Add more CPU vendor logos ### Changed - Big changes in core - Full rewrite GTK GUI - Minor changes in NCurses TUI ### Fixed - Segfault when compiling with target Release - Memory leak (with function get_path) --- ## [v1.2.2] - 2014-11-05 ### Added - Add argument `--verbose` (set Dmidecode verbose) ### Changed - Print nothing on impossible values (Caches section) ### Fixed - Stop distort GTK GUI when label length is large - Stop spam errors (about CPU frequencies) - Typos (BogoMIPS, CPU Vendor, label Manufacturer) --- ## [v1.2.1] - 2014-10-24 ### Added - Add arguments support (`--no-gui`, `--version`, `--help`) - Add support for custom refresh time (`--refresh`) ### Changed - Rewrite error messages - Restructuration of files and functions in files ### Fixed - Segfault when compiling without GTK & embeded - Unwanted characters in NCurses - Compilation with CMake --- ## [v1.2.0] - 2014-10-12 ### Added - Add NCurses mode ### Changed - Add possibility to disable GTK/NCurses/Libcpuid/Libdmi before compiling ### Fixed - CPU multipliers calculation - Relative path of file on error - Segfault on unknown multiplier - Unwanted characters --- ## [v1.1.0] - 2014-09-28 ### Added - Add possibility to change install prefix ### Changed - Change build system from Makefile to CMake - Remove calls to external command `dmidecode`, use provided library instead of - Remove calls to external command `lscpu` --- ## [v1.0.0] - 2014-09-21 - Initial release CPU-X-4.2.0/README.md000066400000000000000000000150241403012130000136120ustar00rootroot00000000000000 [![Logo](https://github.com/X0rg/CPU-X/blob/master/data/icons/CPU-X_22x22.png?raw=true)](https://x0rg.github.io/CPU-X/) [![GitHub release](https://img.shields.io/github/release/X0rg/CPU-X.svg)](https://github.com/X0rg/CPU-X/tags) [![GitHub commits](https://img.shields.io/github/commits-since/X0rg/CPU-X/latest.svg)](https://github.com/X0rg/CPU-X/commits/master) [![GitHub downloads](https://img.shields.io/github/downloads/X0rg/CPU-X/latest/total.svg)](https://github.com/X0rg/CPU-X/releases/latest) [![GitHub total downloads](https://img.shields.io/github/downloads/X0rg/CPU-X/total.svg)](https://github.com/X0rg/CPU-X/releases) [![GitHub issues](https://img.shields.io/github/issues/X0rg/CPU-X.svg)](https://github.com/X0rg/CPU-X/issues) [![GitHub pull-requests](https://img.shields.io/github/issues-pr/X0rg/CPU-X.svg)](https://GitHub.com/X0rg/CPU-X/pull) [![Translation status](https://hosted.weblate.org/widgets/cpu-x/-/svg-badge.svg)](https://hosted.weblate.org/engage/cpu-x/?utm_source=widget) | Linux | FreeBSD | AppImage | | :---: | :---: | :---: | | [![Build Status (Linux)](https://github.com/X0rg/CPU-X/workflows/Linux%20build/badge.svg?branch=master)](https://github.com/X0rg/CPU-X/actions?query=workflow%3A%22Linux+build%22) | [![Build Status (FreeBSD)](https://api.cirrus-ci.com/github/X0rg/CPU-X.svg)](https://cirrus-ci.com/github/X0rg/CPU-X) | [![AppImage Continuous](https://github.com/X0rg/CPU-X/workflows/AppImage%20Continuous/badge.svg?branch=master)](https://github.com/X0rg/CPU-X/actions?query=workflow%3A%22AppImage+Continuous%22) | **CPU-X** is a Free software that gathers information on CPU, motherboard and more. CPU-X is a system profiling and monitoring application (similar to [CPU-Z for Windows](https://www.cpuid.com/softwares/cpu-z.html)), but CPU-X is a Free and Open Source software designed for GNU/Linux and FreeBSD. This software is written in C and built with [CMake](https://www.cmake.org/) tool. It can be used in graphical mode by using GTK or in text-based mode by using NCurses. A dump mode is present from command line. **:warning: There is no major plans for the future, see [this announcement](https://github.com/X0rg/CPU-X/wiki/future-of-project).** *** # Table of contents - [Table of contents](#table-of-contents) - [Dependencies](#dependencies) - [Build-only dependencies](#build-only-dependencies) - [Build and run dependencies](#build-and-run-dependencies) - [Download and install](#download-and-install) - [From official repositories](#from-official-repositories) - [From third-party repositories](#from-third-party-repositories) - [From GitHub releases](#from-github-releases) - [Manual build](#manual-build) - [Usage](#usage) - [Wiki](#wiki) - [Bugs/Improvements/Request features](#bugsimprovementsrequest-features) - [Translate CPU-X](#translate-cpu-x) *** ## Dependencies ### Build-only dependencies These dependencies are needed to **build** CPU-X: * A C compiler ([GCC](https://gcc.gnu.org/) or [Clang](https://clang.llvm.org/)) * [CMake](https://www.cmake.org/) * [Pkg-Config](https://www.freedesktop.org/wiki/Software/pkg-config/) / [Pkgconf](https://github.com/pkgconf/pkgconf) * [NASM](http://www.nasm.us/) ### Build and run dependencies These dependencies are needed to **build¹** and **run** CPU-X: * [GTK3+](https://www.gtk.org/) (version 3.12 or newer is needed) * [NCurses](https://www.gnu.org/software/ncurses/) * [Libcpuid](http://libcpuid.sourceforge.net/) (version 0.5.0 or newer is needed) * [Pciutils](https://mj.ucw.cz/sw/pciutils/) * [GLFW](https://www.glfw.org/) (version 3.3 or newer is needed) * [Procps-ng](https://sourceforge.net/projects/procps-ng/) (Linux) / [Libstatgrab](https://www.i-scream.org/libstatgrab/) (*BSD) **¹**On some GNU/Linux distributions, the appropriate **-dev** or **-devel** package is needed. ## Download and install ### From official repositories In alphabetical order: - [Debian (since version 11 "Bullseye")](https://packages.debian.org/search?searchon=names&keywords=cpu-x): `apt install cpu-x` - [Fedora (since version 30)](https://src.fedoraproject.org/rpms/cpu-x): `dnf install cpu-x` - [FreeBSD (since version 11)](https://www.freshports.org/sysutils/cpu-x): `pkg install cpu-x` - [OpenMandriva Lx (since version 4.0 "Nitrogen")](https://github.com/OpenMandrivaAssociation/cpu-x): `dnf install cpu-x` - [Solus](https://packages.getsol.us/shannon/c/cpu-x/): `eopkg install cpu-x` - [Ubuntu (since version 20.04 "Focal Fossa")](https://packages.ubuntu.com/search?suite=default§ion=all&arch=any&keywords=cpu-x&searchon=names) : `apt install cpu-x` ### From third-party repositories - Arch Linux/Debian/openSUSE/Ubuntu (OBS): [cpu-x](https://software.opensuse.org//download.html?project=home%3AXorg&package=cpu-x) / [cpu-x-git](https://software.opensuse.org//download.html?project=home%3AXorg&package=cpu-x-git) - Arch Linux (AUR): [cpu-x](https://aur.archlinux.org/packages/cpu-x/) / [cpu-x-git](https://aur.archlinux.org/packages/cpu-x-git/) - Slackware: on [SlackOnly](https://slackonly.com/) ### From GitHub releases Look for **Assets** [here ![GitHub release](https://img.shields.io/github/release/X0rg/CPU-X.svg)](https://github.com/X0rg/CPU-X/releases/latest) for packages and AppImage. ### Manual build For step-by-step guide, please read [this page](https://github.com/X0rg/CPU-X/wiki/manual-build) on the Wiki. ## Usage Application is available in menu (**System Tools** category). If you start the daemon, it will allow CPU-X to access some special devices, which provides more information and avoid empty labels. The CPU-X daemon requires root privileges, and it uses Polkit for privileges escalation. You can use `cpu-x` from command line, some options are available, like: - `--gtk`: to start the graphical user interface (default) - `--ncurses`: to start the text-based user interface - `--dump`: to get a summary of data Use `--help` to see all arguments. ## Wiki More informations are available on Wiki, like screenshots, troubleshooting and tips. You can access to the Wiki with [this link](https://github.com/X0rg/CPU-X/wiki). ## Bugs/Improvements/Request features Please [open a new issue](https://github.com/X0rg/CPU-X/issues/new/choose) and fill the appropriate template. Note that text between `` is not displayed. ## Translate CPU-X If you want to translate CPU-X in your native tongue, please visit the [Weblate page](https://hosted.weblate.org/engage/cpu-x/?utm_source=widget). POT file is updated on each changes thanks to [Update POT file workflow](https://github.com/X0rg/CPU-X/actions?query=workflow%3A%22Update+POT+file%22). CPU-X-4.2.0/cmake/000077500000000000000000000000001403012130000134115ustar00rootroot00000000000000CPU-X-4.2.0/cmake/GSettings.cmake000066400000000000000000000037011403012130000163230ustar00rootroot00000000000000# See: https://raw.githubusercontent.com/ammonkey/marlin/master/cmake/GSettings.cmake # GSettings.cmake, CMake macros written for Marlin, feel free to re-use them. option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" ON) option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" ${GSETTINGS_LOCALINSTALL}) if(GSETTINGS_LOCALINSTALL) message(STATUS "GSettings schemas will be installed locally.") endif() if(GSETTINGS_COMPILE) message(STATUS "GSettings shemas will be compiled.") endif() macro(add_schema SCHEMA_NAME) set(PKG_CONFIG_EXECUTABLE pkg-config) # Have an option to not install the schema into where GLib is if (GSETTINGS_LOCALINSTALL) SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/") else (GSETTINGS_LOCALINSTALL) execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE) SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/") endif (GSETTINGS_LOCALINSTALL) # Run the validator and error if it fails execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE) if (_schemas_invalid) message (SEND_ERROR "Schema validation error: ${_schemas_invalid}") endif (_schemas_invalid) # Actually install and recomple schemas message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL) if (GSETTINGS_COMPILE) install (CODE "message (STATUS \"Compiling GSettings schemas\")") install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})") endif () endmacro() CPU-X-4.2.0/cmake/cmake_uninstall.cmake.in000066400000000000000000000021571403012130000201760ustar00rootroot00000000000000# See: http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) string(REGEX REPLACE "\n" ";" files "${files}") foreach(file ${files}) message(STATUS "Uninstalling $ENV{DESTDIR}${file}") if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") exec_program("@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" OUTPUT_VARIABLE rm_out RETURN_VALUE rm_retval ) if(NOT "${rm_retval}" STREQUAL 0) message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") endif(NOT "${rm_retval}" STREQUAL 0) else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") message(STATUS "File $ENV{DESTDIR}${file} does not exist.") endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") endforeach(file) file(REMOVE_RECURSE @CPU_X_DATA_DIRECTORY@) CPU-X-4.2.0/cmake/gettext_create_translations.cmake000066400000000000000000000027571403012130000222360ustar00rootroot00000000000000# See: /usr/share/cmake-*.*/Modules/FindGettext.cmake # This is the GETTEXT_CREATE_TRANSLATIONS macro without GETTEXT_MSGMERGE_EXECUTABLE command macro(GETTEXT_CONVERT_TRANSLATIONS _potFile _firstPoFileArg) # make it a real variable, so we can modify it here set(_firstPoFile "${_firstPoFileArg}") set(_gmoFiles) get_filename_component(_potName ${_potFile} NAME) string(REGEX REPLACE "^(.+)(\\.[^.]+)$" "\\1" _potBasename ${_potName}) get_filename_component(_absPotFile ${_potFile} ABSOLUTE) set(_addToAll) if(${_firstPoFile} STREQUAL "ALL") set(_addToAll "ALL") set(_firstPoFile) endif() foreach (_currentPoFile ${_firstPoFile} ${ARGN}) get_filename_component(_absFile ${_currentPoFile} ABSOLUTE) get_filename_component(_abs_PATH ${_absFile} PATH) get_filename_component(_lang ${_absFile} NAME_WE) set(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) add_custom_command( OUTPUT ${_gmoFile} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} DEPENDS ${_absPotFile} ${_absFile} ) install(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) set(_gmoFiles ${_gmoFiles} ${_gmoFile}) endforeach () if(NOT TARGET translations) add_custom_target(translations) endif() _GETTEXT_GET_UNIQUE_TARGET_NAME(translations uniqueTargetName) add_custom_target(${uniqueTargetName} ${_addToAll} DEPENDS ${_gmoFiles}) add_dependencies(translations ${uniqueTargetName}) endmacro() CPU-X-4.2.0/data/000077500000000000000000000000001403012130000132425ustar00rootroot00000000000000CPU-X-4.2.0/data/CMakeLists.txt000066400000000000000000000021271403012130000160040ustar00rootroot00000000000000project(data LANGUAGES NONE ) add_subdirectory(completions) # Files needed by GTK GUI if(WITH_GTK) include(GSettings) # Set config file(MAKE_DIRECTORY ${CMAKE_DATA_OUTPUT_DIRECTORY}) configure_file(cpu-x.desktop.in ${CMAKE_DATA_OUTPUT_DIRECTORY}/cpu-x.desktop) configure_file(org.cpu-x-daemon.policy.in ${CMAKE_DATA_OUTPUT_DIRECTORY}/org.cpu-x-daemon.policy) # Install UIs install(FILES cpu-x-gtk-3.12.ui cpu-x-gtk-3.12.css cpu-x-gtk-3.12-dark.css cpu-x-gtk-3.20.css cpu-x-gtk-3.20-dark.css DESTINATION ${CPU_X_DATA_DIRECTORY}/ ) # AppData metainfo file install(FILES org.cpu-x.appdata.xml DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/metainfo/ ) # Install launcher install(FILES ${CMAKE_DATA_OUTPUT_DIRECTORY}/cpu-x.desktop DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications/ ) # Install policy rule install(FILES ${CMAKE_DATA_OUTPUT_DIRECTORY}/org.cpu-x-daemon.policy DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/polkit-1/actions/ ) # Install schema file add_schema("org.cpu-x.gschema.xml") add_subdirectory(icons) add_subdirectory(logos) endif(WITH_GTK) CPU-X-4.2.0/data/completions/000077500000000000000000000000001403012130000155765ustar00rootroot00000000000000CPU-X-4.2.0/data/completions/CMakeLists.txt000066400000000000000000000006271403012130000203430ustar00rootroot00000000000000project(completions LANGUAGES NONE ) install(FILES bash DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/bash-completion/completions/ RENAME ${CMAKE_PROJECT_NAME} ) install(FILES fish DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/fish/vendor_completions.d/ RENAME ${CMAKE_PROJECT_NAME}.fish ) install(FILES zsh DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/zsh/site-functions/ RENAME _${CMAKE_PROJECT_NAME} ) CPU-X-4.2.0/data/completions/bash000066400000000000000000000014321403012130000164360ustar00rootroot00000000000000_cpu_x() { local cur prev display opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" display=(-G --gtk -N --ncurses -D --dump -M --dmidecode -B --bandwidth -h --help -V --version) opts=(-r --refresh -t --tab -c --core -b --cachetest -d --daemon -v --verbose --nocolor --issue-fmt --keymap) case $prev in -G|--gtk|-N|--ncurses|-D|dump|-M|--dmidecode|-B|--bandwidth) COMPREPLY=($(compgen -W "${opts[*]}" -- "$cur")) ;; -h|--help|-V|--version) return 0 ;; -r|--refresh|-t|--tab|-c|--core|-b|--cachetest|-d|--daemon|-v|--verbose|--nocolor|--debug|--issue-fmt|--keymap) COMPREPLY=($(compgen -W "${opts[*]}" -- "$cur")) ;; *) COMPREPLY=($(compgen -W "${display[*]} ${opts[*]}" -- "$cur")) ;; esac } complete -F _cpu_x cpu-x CPU-X-4.2.0/data/completions/fish000066400000000000000000000030251403012130000164520ustar00rootroot00000000000000set -l progname cpu-x complete -c $progname -f set -l noopt 'not __fish_contains_opt -s G -s N -s D -s M -s B V gtk ncurses dump dmidecode bandwidth' complete -c $progname -s G -l gtk -n $noopt -d 'Start graphical user interface (GUI)' complete -c $progname -s N -l ncurses -n $noopt -d 'Start text-based user interface (TUI)' complete -c $progname -s D -l dump -n $noopt -d 'Dump all data on standard output and exit' complete -c $progname -s M -l dmidecode -n $noopt -d 'Run embedded command dmidecode and exit' complete -c $progname -s B -l bandwidth -n $noopt -d 'Run embedded command bandwidth and exit' complete -c $progname -s h -l help -n $noopt -d 'Print help and exit' complete -c $progname -s V -l version -n $noopt -d 'Print version and exit' complete -c $progname -s r -l refresh -x -d 'Set custom time between two refreshes (in seconds)' complete -c $progname -s t -l tab -x -d 'Set default tab (integer)' complete -c $progname -s c -l core -x -d 'Select CPU core to monitor (integer)' complete -c $progname -s b -l cachetest -x -d 'Set custom bandwidth test for CPU caches speed (integer)' complete -c $progname -s d -l daemon -d 'Start and connect to daemon' complete -c $progname -s v -l verbose -d 'Verbose output' complete -c $progname -l nocolor -d 'Disable colored output' complete -c $progname -l debug -d 'Print information for debugging' complete -c $progname -l issue-fmt -d 'Print required informations to paste in an issue' complete -c $progname -l keymap -x -d 'Set key mapping for NCurses mode (arrows|emacs|inverted-T|vim)' CPU-X-4.2.0/data/completions/zsh000066400000000000000000000017721403012130000163340ustar00rootroot00000000000000#compdef cpu-x _cpu_x() { _arguments -C \ {-G,--gtk}'[Start graphical user interface (GUI)]' \ {-N,--ncurses}'[Start text-based user interface (TUI)]' \ {-D,--dump}'[Dump all data on standard output and exit]' \ {-M,--dmidecode}'[Run embedded command dmidecode and exit]' \ {-B,--bandwidth}'[Run embedded command bandwidth and exi]' \ {-r,--refresh}'[Set custom time between two refreshes (in seconds)]' \ {-t,--tab}'[Set default tab (integer)]' \ {-c,--core}'[Select CPU core to monitor (integer)]' \ {-b,--cachetest}'[Set custom bandwidth test for CPU caches speed (integer)]' \ {-d,--daemon}'[Start and connect to daemon]' \ {-v,--verbose}'[Verbose output]' \ {-h,--help}'[Print help and exit]' \ {-V,--version}'[Print version and exit]' \ '--nocolor[Disable colored output]' \ '--debug[Print information for debugging]' \ '--issue-fmt[Print required informations to paste in an issue]' \ '--keymap[Set key mapping for NCurses mode (arrows|emacs|inverted-T|vim)]' } _cpu_x "$@" CPU-X-4.2.0/data/cpu-x-gtk-3.12-dark.css000066400000000000000000000002261403012130000170730ustar00rootroot00000000000000GtkBox#footer_box { color: rgb (46, 52, 54); background-color: rgb (76, 153, 230); } GtkLabel#value, GtkProgressBar { color: rgb (128, 128, 0); } CPU-X-4.2.0/data/cpu-x-gtk-3.12.css000066400000000000000000000002241403012130000161520ustar00rootroot00000000000000GtkBox#footer_box { color: rgb (46, 52, 54); background-color: rgb (76, 153, 230); } GtkLabel#value, GtkProgressBar { color: rgb (0, 0, 128); } CPU-X-4.2.0/data/cpu-x-gtk-3.12.ui000066400000000000000000013114141403012130000160060ustar00rootroot00000000000000 True False CPU-X False center True False vertical True True True True True False vertical True False 6 6 4 6 0 out True False 6 6 6 True False end True False vertical 2 True False end 4 1 1 proc_valvendor True 1 False True 0 True False end 4 1 1 proc_valcdename True 1 False True 1 True False end 4 1 1 proc_valpkg True 1 False True 2 True False end 4 1 1 proc_valtech True 1 False True 3 True False end 4 1 1 proc_valspec True 1 False True 4 True False end 4 1 1 proc_valfam True 1 False True 5 True False end 4 1 1 proc_valextfam True 1 False True 6 True False end 4 1 1 proc_valinstr True 1 False True 7 False True 0 True False vertical True False True False vertical True False 1 1 0 in True False center True end 30 True 30 1 False False 0 True False 1 1 0 in True False center True end 30 True 30 0 False False 1 True False 1 1 0 in True False center True end 30 True 30 1 False False 2 True False True False 1 1 0 in True False center True end 9 True 9 1 False False 0 True False 1 1 0 in True False center True end 9 True 9 1 False True end 1 True False 1 1 proc_valvolt True 1 False True 2 end 3 False True 3 False False 0 True False 4 2 0 True True 1 False False 0 True False 1 1 0 in True True True center True end 43 True 43 1 False False 1 True False True False 1 1 0 in True False center True end 7 True 7 1 0 0 True False 1 1 0 in True False center True end 7 True 7 1 0 1 True False 1 1 0 in True False center True end 7 True 7 1 2 0 True False 1 1 0 in True False center True end 7 True 7 1 2 1 True False end 6 4 1 1 True proc_valmod True 1 1 0 True False end 6 4 1 1 True proc_valextmod True 1 1 1 True False end 6 4 1 1 True proc_valtemp True 1 3 0 True False 1 1 0 in True False center True end 7 True 7 1 4 0 True False 1 1 0 in True False center True end 7 True 7 1 4 1 True False end 6 4 1 1 True proc_valstep True 1 3 1 False False 2 True False 1 0 in True True True True end 43 43 2 False False 3 False False 1 True False Processor False True 0 True False True False 6 6 6 True 0 out True False 6 6 6 True False end True False end 4 1 1 clock_valcore True 1 0 0 True False end 4 1 1 clock_valmult True 1 0 1 True False end 4 1 1 clock_valbus True 1 0 2 True False end 4 1 1 clock_valusage True 1 0 3 True False 1 1 0 in True False center True end 11 True 0.009999999776482582 11 1 1 0 True False 1 1 0 in True False center True end 11 True 11 1 1 1 True False 1 1 0 in True False center True end 11 True 11 1 1 2 True False 1 1 0 in True False center True end 11 True 11 1 1 3 True False Clocks False True 0 True False 6 6 True 0 out True False 6 6 6 True False end True False end 4 1 1 cache_vall1d True 1 0 0 True False end 4 1 1 cache_vall1i True 1 0 1 True False end 4 1 1 cache_vall2 True 1 0 2 True False end 4 1 1 cache_vall3 True 1 0 3 True False 1 1 0 in True False center True end 18 True 18 1 1 0 True False 1 1 0 in True False center True end 18 True 18 1 1 1 True False 1 1 0 in True False center True end 18 True 18 1 1 2 True False 1 1 0 in True False center True end 18 True 18 1 1 3 True False Cache False True 1 False True 1 True False 6 6 8 0 out True False 6 6 6 True False True False end 6 4 1 1 Socket(s) trg_valsock True 1 1 0 True False end 6 4 1 1 True Core(s) trg_valcore True 1 3 0 True False end 6 4 1 1 True Thread(s) trg_valthrd True 1 5 0 True False 1 1 0 in True False center True end 3 True 3 1 2 0 True False 1 1 0 in True False center True end 5 True 5 1 4 0 True False 1 1 0 in True False center True end 5 True 5 1 6 0 True False 4 1 1 0 0 True False 1 False True 2 True False CPU 1 False True True False True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False end 4 4 1 1 l1cache_valsize True 1 0 0 True False end 4 4 1 1 l1cache_valspeed True 1 0 1 True False L1 Cache 0 0 True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False end 4 4 1 1 l2cache_valsize True 1 0 0 True False end 4 4 1 1 l2cache_valspeed True 1 0 1 True False L2 Cache 0 1 True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False end 4 4 1 1 l3cache_valsize True 1 0 0 True False end 4 4 1 1 l3cache_valspeed True 1 0 1 True False L3 Cache 0 2 True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False end 4 4 1 1 l4cache_valsize True 1 0 0 True False end 4 4 1 1 l4cache_valsize True 1 0 1 True False L4 Cache 0 3 True False 6 6 4 6 0 out True False 6 6 6 6 6 True False True False Test 0 4 1 True False Caches 1 False True False vertical True False 6 6 4 6 0 out True False 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False 1 1 0 in True False True center True end 40 True 40 1 1 2 True False end 4 1 1 motherboard_valmanu True 1 0 0 True False end 4 1 1 motherboard_valmod True 1 0 1 True False end 4 1 1 motherboard_valrev True 1 0 2 True False Motherboard False True 0 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False 1 1 0 in True False True center True end 40 True 40 1 1 2 True False 1 1 0 in True False True center True end 40 True 40 1 1 3 True False end 4 1 1 bios_valbrand True 1 0 0 True False end 4 1 1 bios_valvers True 1 0 1 True False end 4 1 1 bios_valdate True 1 0 2 True False end 4 1 1 bios_valrom True 1 0 3 True False BIOS False True 1 True False 6 6 4 6 0 out True False 6 6 6 True False end True False end 4 1 1 chip_valvend True 1 0 0 True False end 4 1 1 chip_valname True 1 0 1 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False Chipset False True 2 2 True False Motherboard 1 2 False True True in True False True False True False 6 6 4 6 0 out True False 6 6 6 True False end True False 1 1 0 in True False True center True end 40 40 2 1 0 True False end 4 4 1 1 bank0_valref True 1 0 0 True False Bank 0 0 0 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank1_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 1 0 1 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank2_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 2 0 2 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank3_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 3 0 3 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank4_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 4 0 4 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank5_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 5 0 5 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank6_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 6 0 6 True False 6 6 4 6 0 out True False 6 6 6 True False end True False 4 1 1 bank7_valref True 0 0 True False 1 1 0 in True False True center True end 40 40 2 1 0 True False Bank 7 0 7 3 True False Memory 1 3 False True False vertical True False 6 6 4 6 0 out True False 6 6 6 True False end True False 1 1 0 in True False True center True end 40 True 40 1 1 0 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False 1 1 0 in True False True center True end 40 True 40 1 1 2 True False 1 1 0 in True False True center True end 40 True 40 1 1 4 True False end 4 1 1 os_valkern True 1 0 0 True False end 4 1 1 os_valdistro True 1 0 1 True False end 4 1 1 os_valhost True 1 0 2 True False end 4 1 1 os_valcomp True 1 0 4 True False 1 1 0 in True False True center True end 40 True 40 1 1 3 True False end 4 1 1 os_valuptime True 1 0 3 True False Operating System False True 0 True False 6 6 4 6 0 out True False 6 6 6 True False end True False end 4 1 1 mem_valused True 1 0 0 True False end 4 1 1 mem_valbuff True 1 0 1 True False end 4 1 1 mem_valcache True 1 0 2 True False end 4 1 1 mem_valfree True 1 0 3 True False 4 1 1 0 in True False True right True end 18 True 18 1 1 0 True False 4 1 1 0 in True False True right True end 18 True 18 1 1 1 True False 4 1 1 0 in True False True right True end 18 True 18 1 1 2 True False 4 1 1 0 in True False True right True end 18 True 18 1 1 3 True False end 4 1 1 mem_valswap True 1 0 4 True False 4 1 1 0 in True False True right True end 18 True 18 1 1 4 True False 1 1 0 in 172 21 True False 2 0 True False 1 1 0 in 172 21 True False 2 1 True False 1 1 0 in 172 21 True False 2 2 True False 1 1 0 in 172 21 True False 2 3 True False 1 1 0 in 172 21 True False 2 4 True False Memory False True 1 4 True False System 1 4 False True True in True False True False True False 6 6 4 6 0 out True False 6 6 6 True False end True False 1 1 0 in True True True center True True end 40 80 2 1 2 True False end 4 1 1 card0_valmod True 1 0 2 True False end 4 1 1 card0_valtemp True 1 0 5 True False True False 1 1 0 in True False center True end 13 True 13 1 False False 0 True False 1 1 0 in True False center True end 13 True 13 1 False True end 1 True False end 4 1 1 card0_valusage middle True 18 1 False True 2 end 3 1 5 True False True False 1 1 0 in True False center True end 13 True 13 1 False False 0 True False 1 1 0 in True False center True end 13 True 13 1 False True end 1 True False end 4 1 1 card0_valmclk middle True 18 1 False True 2 end 3 1 7 True False True False 1 1 0 in True False center True end 13 True 13 1 False False 0 True False 1 1 0 in True False center True end 13 True 13 1 False True end 1 True False end 4 1 1 card0_valdriver middle True 18 1 False True 2 end 3 1 0 True False end 4 1 1 card0_valvend True 1 0 0 True False True False 1 1 0 in True False center True end 13 True 13 1 False False 0 True False 1 1 0 in True False center True end 13 True 13 1 False True end 1 True False end 4 1 1 card0_valgpwr middle True 18 1 False True 2 end 3 1 6 True False end 4 1 1 card0_valgvolt True 1 0 6 True False end 4 1 1 card0_valgclk True 1 0 7 True False end 4 1 1 True card0_valvram_used True False 1 0 8 True False 1 1 0 in True False True center True end 40 True 40 1 1 8 True False 1 1 0 in True False True center True end 40 True 40 1 1 1 True False end 4 1 1 card0_valumd True 1 0 1 True False True False 1 1 0 in True False center True end 13 True 13 1 False False end 0 True False end 4 4 1 1 card0_valdid_rid middle True 18 1 False True 2 end 2 1 3 True False end 4 4 1 1 card0_valpcie True 1 0 4 True False 1 1 0 in True False center True end 40 True 40 1 1 4 True False Card 0 0 0 True False 6 6 6 6 4 6 0 out True False 6 6 6 6 6 True False True False Cards 0 1 5 True False Graphics 5 False True False vertical True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False end 4 4 1 1 primeslow_valscore True 1 0 0 True False end 4 4 1 1 primeslow_valrun True 1 0 1 350 True True 1 1 0.009999999776482582 True end 1 0 True True center 1 1 1 1 True False Prime numbers (slow) False True 0 True False 6 6 4 6 0 out True False 6 6 6 6 6 True False end True False end 4 4 1 1 primefast_valscore True 1 0 0 True False end 4 4 1 1 primefast_valrun True 1 0 1 350 True True 1 1 0.009999999776482582 True end 1 0 True True center 1 1 1 1 True False Prime numbers (fast) False True 1 True False 6 6 4 6 0 out True False 6 6 6 True False True True 1 1 True 0 number 3 0 True True 1 1 True False 0 number 1 0 True False end 4 1 1 True param_valduration 0 0 True False end 4 1 1 True param_valthreads 2 0 True False Parameters False True 2 6 True False Bench 6 False True False vertical True False 6 6 4 6 0 out True False 6 6 6 True False vertical True False 10 10 False True 0 True False 4 center True False True 1 False True 0 True False 6 6 6 0 out True False 6 6 6 True False vertical True False center True 1 False True 1 True False center True 1 False True 2 True False True False True 2 True False About False True 1 True False 6 6 6 0 out True False 6 6 6 True False vertical True False 10 False True 0 True False center False True 1 True False False True 2 GPL v3 True True True none https://www.gnu.org/licenses/gpl.txt False True 3 True False License False True 2 7 True False About 1 7 False True True True none True True False gtk-preferences False False True 0 True False True True False 4 CPU-X 1 False True 0 True False 4 Version x.x.x 1 False True 1 Start daemon True True True 8 False True 2 False True 1 False 6 False True preferences-desktop dialog False vertical 2 False end gtk-cancel True True True True True True 0 gtk-ok True True True True True True 1 False False 0 True True True True True False 4 4 12 6 12 True False start Refresh time refreshtime_val 0 0 True True True 1 0 True False start Theme theme_val 0 1 True False True 0 Automatic Light Dark 1 1 True False Interface False True False 12 6 12 True False start Default tab defaulttab_val 0 0 True False start Default CPU core defaultcore_val 0 1 True False start Default caches test defaultcachetest_val 0 2 True False True 1 0 True False True 1 1 True False True 1 2 Print CPUID values in decimal True True False start True 0 4 2 Start and connect to daemon True True False start True 0 5 2 True False start Default graphic card defaultcachetest_val 0 3 True False True 1 3 1 True False Startup 1 False False True 1 CPU-X-4.2.0/data/cpu-x-gtk-3.20-dark.css000066400000000000000000000002151403012130000170700ustar00rootroot00000000000000box#footer_box { color: rgb (46, 52, 54); background-color: rgb (76, 153, 230); } label#value, progressbar { color: rgb (128, 128, 0); } CPU-X-4.2.0/data/cpu-x-gtk-3.20.css000066400000000000000000000002131403012130000161470ustar00rootroot00000000000000box#footer_box { color: rgb (46, 52, 54); background-color: rgb (76, 153, 230); } label#value, progressbar { color: rgb (0, 0, 128); } CPU-X-4.2.0/data/cpu-x.desktop.in000066400000000000000000000011541403012130000162770ustar00rootroot00000000000000[Desktop Entry] Name=CPU-X Comment=Gathers information on CPU, motherboard and more Comment[cs_CZ]=Shromažďuje informace o procesoru, základní desce a další Comment[fr]=Récolte des informations sur le CPU, la carte-mère et plus Comment[pt_BR]=Coleta informações sobre sua CPU, placa-mãe and mais Comment[ru]=Сбор информации о процессоре, материнской плате и др. Comment[zh]=收集有关 CPU 和主板等的信息 Exec=@APP_EXEC@ Icon=@APP_EXEC@ Type=Application Categories=GTK;System; Terminal=false Keywords=CPU;system;core;speed;clock;rate;Intel;AMD;motherboard; CPU-X-4.2.0/data/icons/000077500000000000000000000000001403012130000143555ustar00rootroot00000000000000CPU-X-4.2.0/data/icons/CMakeLists.txt000066400000000000000000000006551403012130000171230ustar00rootroot00000000000000project(icons LANGUAGES NONE ) # Icons file(GLOB icons CPU-X_*x*.png ) foreach(icon ${icons}) get_filename_component(filename ${icon} NAME_WE) string(REGEX REPLACE "CPU-X_" "" size "${filename}") install(FILES ${icon} DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${size}/apps/ RENAME cpu-x.png ) endforeach() install(FILES CPU-X_original.png DESTINATION ${CPU_X_DATA_DIRECTORY}/ RENAME CPU-X.png ) CPU-X-4.2.0/data/icons/CPU-X_128x128.png000066400000000000000000000540031403012130000167360ustar00rootroot00000000000000PNG  IHDR>agAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>WIDATxڭgeu}/׍΍nnH 0 )MIiQe-c:̨ʞga45]u߻霽 ַ/+|?J=wPs,y'b @U*F#q,I4RJ|_[Yoo/_M7n-b}s7o^GۄL{sH)A y~쩑a_8۽S*y^95e9b`9u fk| 3o;! LMOQna^oSK,đc#NkB-Bbnl۶/^k$|-2u)s|{8\r|tsVXKy DPKs/ ʝy}/۴Bpu^|&}|^ /k`Q9aq*.Pgp~/ӿ01H⌝lYnUYj?sœe&[!͢7AϜSU|R޾Jg ,IJG*DU "W_| 7zKς$ϯZ {-AAƶH#,s@WmvjT˒1֔qM%1{J H ^8&=#{$$A$H|yH߫a6'd$E(!W]-s )] ҅7^'I VY$0%׾{;W_~ 騯oN<՛HmE. lBB=Bn"?mvJ99C-9H_L$'mye^F6B 5 c̀(8=q5L1Rp'ѱpRx)/zwߜ10mveڇ ꈚEIo'` 1 m͑Rm rgAB xM:e@YX.Br}kO?1`a Ά!mUcp8ZYRhJj- `(RU-,&mD*P>_*,tZ29Y{옝A5`F\7n2VC#0A0$8Ws˓.nN.36BX/P,TJH!f1 2B(~/8DRB?Tj-յJ~.8b `ucWnƵװѿ7(sbGlIqAN'?L^CF{ F|7@(.!\_y.c8Ewf!Ǯ} C($"y)8 >яQJ°5"fIҀ] @@ Jl$;?9p f {rEB?.|E:?HhMvYHo[Hr/w]1"yJH0"@RރN/s&\Dy %TثNlH8K/bbr 𙿂$Z$8Z!"e5b}b0sUnM1ܿo%b?q)Hu07B`u)(FW2 z~a\q }B//B޲` q Pz{1|{w߇Nc3AM,g~rM!sV|3=:wa1}NBZ !45 \xG>֥Qi,K*cPk4v 1هۋp+.>yY  6c`8QcjzFs4C S#e#S7(TE`XA8׵Sq7 PG4~r^C  !Cr۵jDJ,M!yP cq ĮQ 9(`N,lRlU "KS5pf 7W0"DZ|ծDMDAg`^Nb ]B@pD1,Pc^oT9T.H 8a j#\x9j֒1R*L~Vc??Eu;d#Sb"0!\0 M5Q `n Aa/kyWjFۢ1J]L!Wzg"xB+ca*whFHly9QXX .VA7{t6t~NvqLD>^)wMkkkuVWWt0 eW]ŋp}x}ϻ?R)֛0R<րKH) t]F@˃OC 2HԀ9J֗L%$4B2980??7OMUs 57@-kA]/NR5PGNjKݑqB6y<1 ep4[vR7k.XC)=aI#ҪO(Ncyeػw/cxp9\xKKKX[[C\a"ct:z= C`rr2't@{=Q2XHn~R" q 2kI *%yK8s Q9 >iP((yߖdM ` QkZ61NDQILOOZ$ .Z!vCu]СC\*kWad pK@`, w )ҳAsP_7'{~kVvά ,8@D '>h_'c a9&-@.i9Y! Cah cjDHfkkkHSgYhV69-o{oMnA{ yȒld֥b :t8pf7ѣG՛Wf1#HRw[saIP53ڼ棚ik U3ۘ;ܔN[a`O销D:5PȲ|smTk5'~A!PTPռ 8Fá10b(v,hk)B. v kɱD| &%;/~ʉ=3q>[SH(=GYp#c&'sg~F!.ǧTx*@$ wڅ(ӧ7S`O=4?=hu:8~_|60t'I:M`Q|n%,X` bTIzc1y;8TvXT\ud FFz~񡣇y8v/!%Ni\Ò>l_5N(A(*@T l*x׻GA;.lln;wދClEm޽x?Ξ^~% " ScD%K?40 I `BjzhlǞ{7w$Ox,C>{Wë_6A>\b3pޘU4b%Ev@2՗_B5 +{~G/4.^yh^ݻ?pd3t&]9p eN޴'WȒf6Ky@s5i4JJu@|Byi{}h.FHxwrW(^_eѳ?—먮k|5R}!%.&LO1un Y )sqos+D?>ዒ\ڄS'In)T ݓ_)YR>5G^^kM+ YZ2B[<%,ÕWo/rD0ʐ.J. 9GvԇOVK 8s~on{H)z`Zхq]J`ͤ6v)n)^y`C qDm]_S(Q`qGycH TvPSDn[E-/1c#z4MjoV)P@MDnb4f}gx0O&s?V!lm"ITU'muJuiq/(QRXs4Th&:LGek_*-\x*7{q\;PDRrEC su{?j~#HאK9H{`3Yp!C*M/9X]]Cj.;#Mڣ{kVt:BNs D里[Zdi;c-[fM0y ) !a2  ,ׁV YU} [De3˰sK#d&*!Tluܼy  `^>to!徝j1وFwKUuů[J3S{˽WP>%J$X;4F?^̞^ :db2!! <8$Řh6l6mM`03xֳKܣjn%f ?ZLzM /2i-mΡUK`S^&X,܍mڟ fvF@UT#*'W\Džݷ&]_cavM$R *!Bge%&LYacjj ۷oc Bؓv% Mކ[{( ,~+!H$ᩋ- ָs}f< nOzGJa8!u8Z}r&Pt3[nK : WX:CKdnLX[v Oֱ؃}كzϣjxW|26 I26ȋ^ËKp(b\ɂx!*N;=&2FJ.OF.d&(&UVmE#"t\vi;`ϰ~Bg)(c `Y,U 976pAm۶СChZ B_={vR2X5 ``Hq3TYfIYqđO9v.3 }\\KiR*[BN<~Q# 㿃DZt+-EE%`}Lf=t}<#GshN8cu xwsE&~QdiLVoPr1U @$JMic2S2T/emqV'26w v,lbvf|恿b`}TA2a\z˵chnۇ}bǎh68z(0Dq%TU7ٳg-- SYyg/%|\ټ,"$,(&&!/q#9LWc€,PmG0n-.Khzx055h;vb`P oo&d4Rm64 DQ#G`ݸr nݺ(0;;kyNam̡Yu59ĉݘCE$i:c`e3Nf@ps>gyrva)WN9!ܑ`)IO4ɓ'vhcǎVAz !4`G:&''133FZji|ĩS 9n߾ YGʕxSOJ&b貆dV^ބ-U*궂I*nmJ'"K]rȎ9A71zCjcxrq-%ߺg6j{10JFa{:64բ Fzz |Wlnn"2t]/B`8Z 9GX__O^)oWnʺz R@F' ļcuc $I6;V+.16YY_G;I˗/3sO~h4JcO[j5|_!0Jn/| 7M;`Vq&~O~qkOw@Ypsz h;T*T*8u4v؁G}s64]؀O15"sɋ^,2}oWDL(s FfJȝ0bJ(SBgx:z9;wޞ$I˿XXX亓J"~?2ql1ck~?jVq㥗^wa׮]މl̹,ܩm\J Wu?hEBOw$'a5L I8) [Bb}cmn8t~jFg9# !\!@%1'q{ ڵA|qaz>w GQgOSZ-El !.b-xY߿}{$f}RäiQH%b|`֟ \<8_pp7^ߟyEK8qox'|.Ylw0iaRAZEZۜjwOGŧ?iTU4uZ"dY`Nc/ V474fMrVں3S1tPXw H^G-kE<0E(',|dPcU>ᮻYĄ-$A߷RKKxWf٘.2}M@fCdrhvFT*\m[LN-AD5No% > -UrFaCRpUSoqU__ã>j{s]+P|27ܴ߿&011>)m<`N:.ZQ ?~ GD*[nw)^V~O,eD!בRl()o˸r2aft _n?co&o>fFpbg66QAFعs'>:fff0==mib0XE%:yC$/2E4+x=A.=VU-QrW݉We}%d[J.|uQQք6[m;wkkkO<~w _|+ mۆ0 133YLNNZW0&8} Vn c bg0OgN0Gtt7AH[HUjx¥KMF#,,,<*JEHl37$I9<裐Rbvv۷oV1,01 0nqԙQ^O14 [)Dӂ ˸2]\C?TE1jE4܎ɓF!` =H˷&/IN; KCy@c2"p#Ȳ6orb|jkv> Ox yV|Q!˲3ךr5OTE)0Ļ.Bd fGX=Rv?Jaʦ9 sD,W/CeExnCȲ.BQ,;GѬMo Vxz~)N:BV+ptJfH~-93zo~9+ \,-NԾe(\ $l:1fueUBwڧ|I^w+ hEDp52;/C*̞x_oc~VUw;0\,&`lu@w8R[DQ@A8HԂFV sss "v`Pn;yn٩O{A`YIPl6 3 ' 0j]`.#JYBL{76p`\&,iPRS= R5vNJ(¢璧: a~:OP_:(e \TG("j>Z:9ܒEXoVBVGȗ *+T|樫5$w w F+`{FvfxhM`8Nl[ggpRvfff011zY}:@13jͰ wi 5>,MqU$I PV199{:tZz-N3gY` vL3RS<y1"eH C2??đ#-wږ*z8@=f~&R,ar;a.9qJVJ j5K*pz+n| LEkh4GHx;bK7Ѳ!#juLOOcǎ޽fggLcj()ײ؂.I4Op93 lʴ^' d݄?BHv")DɷtT[FF?ށn0 [#w;!{7*7ĮWЌ[2׎pb"\YʰO8XQqLM"LW*Jx~Ead ܞbrN4x4a)!;ZH N%}2-xvEޡTM T:_ja,/FD`6c.~acۯaB,"d|m!wFC`RA#*Xuy#6I5+R0yԉ[(q ! 5)K.#Ч~^0,*qtPpdLZ >J5YHL09*H^PI@x6~}FC|߆O.h)tnn8Htڜ|dj1 #l]vg]˥\J J p y50 tXlpiFl^H@7w}x<b0 J5m4,xBwh5h~LX̦p] tjjP#dE34ҋ/8&zZI2-5 s@H:?K-Qz]Vea+ AJ5GtTU.WԻfQ< RRhcdHDM }X|u޼G$g?k+n;2=?jt$G#x=3Yhp6@u tb!Sdtd~:Ԝ$MK%rS'Ʒ)| 1e6^@^Fa૘9SEqm j@<)15h7؆]qkͿ7 `YŖ7oJt: O0 X:IzgTf]ls$SDAl9窉IcycL2OF;IB5m+NЅ GRcj*ʼn1bhXg%]:`D dMx a$`Zwvi]Aqߝ3l:|Mx:" N,ak20a*= UܘiҙIqS'bns-μ>וa#ٖA ySaeHBjH!Y@q•VB* `ܑ/1]J0i\A7x\/ڛ9Ɔpۿ]ᇲ\6=-͛X|t[-QX&(^YHۘ< _C̓\ͼR⓾fpT H#!AN8fnƄ׹+H? aGr s&(nyD;=xkj?8!VVV 糀3FU[ZZ~|GT.B Hِ(@XöяO?$މ\=HLaBI~0"L*h(pv. KDy\%1SۍU Bg6,􏪬=/=XY{{كuO47[Hҷƍx簹J4 F"g[oŷa{++ދF7xed^"[`w|M'dEFS;|>|X ֟-g4@LmWPhhO8 1FSG1^[ _lrcoC!z- !Hu :=`>tEo= HpGPAK+ )|\cjzQ#u +g΀9cEZ4r_kٰ<0N;pHg*P"a;S7_v= 뿋ݾEE n_ޠ1Ͱ׵/~'[fcdyJv u;byyWJcjFE0^X^ZpSLqu'Sj)RMM`( OoLuݻ{E2 ^W\3g5TvT@b\0:Vܕ(DTz4&gqa(| AiܞfiV']wwjҏU)j@ >>/n_8}41??iW`FȻ-..ZzIMWq@ uzbj7 nkilyg@9ZY4|%٘S6C"$E o'Ұ:ږRi]?eƝvg!? N(4E h+%Dx6~wxk .]… ,7&HV݅7 ܽ]SRfúLWf@6$@ͰD`/DT,̫zrw<-0@)5'&{.?yPpk$Rh^2d$cr(YL|e&UA %*)Wo^g܏KG6+Rͦ55b!޵hC[hVrU0.VއO!j, !B*R^-^%'J{3gRlsogcW\p0@Hz99^!}40SbӾ*.a-b׮NRӲG4t!!&6ٻ0CP(X7T$p7kza!q L"0לGg fӵS-J>Ae#˻xGhGxq}/^ˎA614SZɘ G͘xL$6)#H n`d>[lt <)`ہ c>&9 n&K,T VP*(\2w# `@HD #l!Ih6dLhQIԔ$A۵`& zHdEN}Si:o%Q #đ(De} .V:{6As wȑp%l d9%t~`Buc`,TiOm6Ma/bcj]@y{jieP eHHIhu2HQ((B(h4D&M4xB-'[t{fʾ.ʘ;R(\pp+_,TX0 yS0ƶ'ps Z96/MIݑ ^Î]1;3Z3VW87\h/@tY$#°t A vm{h6h4hN411jW <c4´z8sdQ} Εqf?82!*_B:@ :A:-WZR$i(!D ,uBg+ut!Bt;'0%Pw AAxim;jAAFl)t|) T8G8su.!ZBcdM\OF2mQtfF}l6AAlװqJ$҈Fy%|$2 K-ޏ|7._Ve70z`V1g$H*dzHHϘB؆HԘ,\\`&Z\wmkb܅.!8a$!dGCP_@GCHOSo ea{13.`$3-$iU1[kiEMP%Tu1Xmԛ0^$͏BS)%ߊçT ڡZ͍+^31Ҩ,d*3ǫq{z j1JiAŒX8cpYWPbM pHSP! <|ac4ZAxGqֺ)VbܸQh;K 0`y3cYD@ Br^_pGS i2: *!XH7B=i̠i<6sˆ鴖kJ8 "q~%eHs@*iqB2.4.QBf"dQTL!`HFC?Y&VJ,],@44JX,!pBqtaG?i b lm@dC,-0uXl Ȍ!:6ubtׄ*9Bi4dT+3 @FLcA Bg.ŀNnW$]7qr|(PAl1J#  Tuq"NƕKXa\`}E YܸpοD 8{ =rD&a8bvn;0BF: b@a i) o< Џ^eސP>^]nN5ol7Q`8V7 eq( -yXZPeR"c,Wci8~ s4]3@6 p) P!WWJ*F}7 kw48ͫx7T -@ʕ+hxA%pc_R#3"qT64'FXhTP#`udY8oGBV.Os?fNP2U2V>BȈU+ 4h<ͱ{=yLo_3X+%!T=+D*~X)LELUZϟ;_:@ ;3XߍWob[ B@3qra+)|< Л, "D,r2U`Lҷ 3э'8* l#R*l gqLƍ * %as#>kE'wj j< &s$iE:jVS`m Fqo]ǛO5 p ::z/.+0BhK᳟Eo'-& LU,:Cd )I+KuּRN [v3RDȊ9tb̜a2a`Mh%]ɰR'͆ r+ +5qnaOpUa՟]=8v(_ (CwVp\|&~ nsO G߇VB:%PAOB ү::1b)6WWU*2=[HVBO HSI3Lo5Չa%8%c!tj *F AePDž S}oE,z 2n3&z.[Ï~*@(}*N 헃 jHɴK5#\\W^ `[]_l$y ~K 4K'QB:|$Si θRdU{ "|sQpZp{ev֭سw?\8sgq#x A|?6v:i%*i|cxM[Yn#ⓛ" Zk?v:gϡ93mK-G DrYBS34Ʃ0Dy * ^&5Z#K JfYǁ[u H`Q 5jD t#T&f0}!tnO4>ſ< Da\'PT6ӘQ}yOı°˫+`([%~o7v|5oɂ,*bҹ?ݏ|q,r3 īSbffn{?7qCv*(.\Źsoo"YC?zYWUUHaS;gQ&=Q&Pw⿾˼\jr~DDF Ĵ`ov~溸YR:]ZNvvuϷ|öӥhmljĹ^lsz֟q{QQQĹ\krxެjjjTTS[jqw͢AAAƷYiowٽ>==xywvս[@ƲxRø\lruTmH* ɵ`owta u;86///w_oum|ķǹɤhaaGzVhn4K\@GJ>BD?BD=?D(IDAT !"#$$%&'()*+,-./0123456789::;<=>?@ABCDEFGHIJKLM@NOPQRSTHUVWXYZ[O\ ]^_T`abcdefghi jklmnopqrsNtuv wlxyz{|}~u { {t!DFY%tEXtdate:create2016-01-04T17:28:07+00:00e;%tEXtdate:modify2016-01-04T17:28:07+00:00fQIENDB`CPU-X-4.2.0/data/icons/CPU-X_192x192.png000066400000000000000000001324411403012130000167430ustar00rootroot00000000000000PNG  IHDRRlgAMA a cHRMz&u0`:pQ<bKGDIDATxymWuƜk洷ҕPC#@F q $-;IvJ%Izq*)'Ncvbcz0 B +ZkQn̵9WWosOk9h~ a[ fN?pS/15w‡l"53Ce1 _W{,.SxXǭ_ ſ'Ք⳰s)=boN;].eǓ]ɧPZ0@U^5i @ D 8_io ^Y݈8>)[gqH`j9![%@_ >ذ l'(͝V{~}`s4Zvy ,H]cr_7&]kw~7oU׾KKK\9W^u-I\0HwpN}f uhk6nlm&ϭQ:~<a=\V$ mAv^g70UZ s8L^QZ-x;-B޳юJ 5/cG?jav6xHׁuz~ 0&]PS0)rE&I,V@7ZMD)7WRV%:usX~e6R?OE5c,:+N  F,Dyх_ޑog J䯏O _+x_>30 +ujPbs}qu 7W1W܆`S6{ J 0li zA>jM ?A`wÔN [7otZl[kG|TiX02Z4]dҟgUkcHb!6~!6-ȩx!kylyM|ZIi ߚ7\j,y  U⥯\w]?.4 6)#nXֿ"fa{i-,+L\v5yxp?8L`iқg:LjpJhuEL鍵WfC "M ڋQ.t*}}d\ڄS97&{,-Jӕߒ'/hM|T ,:V*]k^PE}gqϜõ?Zگ=כ`xlqǧ pR ѪAԨݏ*.M7V>ﮛfRjM&( ~׊Si&[3!"i9XiSsdIL6[L~_t X|rA&0s&[kKIC?_"W܌9C6! H%XUgֿGR/{+hB旁 q3]F~rQHb$S;jynO1@ 5)R*O]`ZEaSS5zoQ#I$/3qR>nP2"" #: ʽ=ڦpQV"u>dj\ bqks]tqNe,Nmҝ}c4S$_6c :GcʤHXDnvɌn+\q2p|wtN\=U/+hOkQdMB1JH9TkO e=_# Cntq3Qg\DE{iEݒ죧Abprc53,MD)`X}l~[ZKS;xwHLnR!&kR@뎭5AW褄.N?߄Ì()d6~ܗw,B*uvYM"|}Egn3`#Fu ), ;DƄ6enL\Ȕڈq#u^<#TEʔu)bf> B7C~*4&_`S*̉Zf u}!0Db(mJDng]% PYіE;<dGiq65)Bpf}. L17uv6t2M9SR@2L$-aٝ4PlJB;^$C8l_0h|*`|qG PcE )qy҄0 ,Z:.Zr 8aӱs(|  *0dgůn-~kv{eDsdžHn|zX3wpLzŦ@';"{ȑGD Щ$GJCŁΡ B(T3QʥJZ(5L ECcPFA25J* dۂb6t]إ>=af(X(R`& $Fh"(FUUpN{l`غkBA X4tQƻ"AX ]hܦ+|hm"k-Hn3JqEGTQw^(+7(,Fc uI\b-:45J4jcb~GQtrֱ:qֈ?rB:\*BTH)*RK;%i=7@$->as~W_x3 7?/|>,,31&u\lJ#|,g|-jE/_L- X K9|Ͻ>R/5n!Mm:NihV(T󺿭HӪ,bQx-r'"12m`w)"ԍ"[ ڔ[ZFNaTU82߉;{w46WS̍) 'OC֝Z:EʦJ9Edk#v}{Q*ћ+~[q01nccc  @)#@3H AJ~}vEʿdœ2u^ǯpzMhՐ(L?PNfY89!uNuESͯ-7݈'>O~l,/3EJȺ&TY1[c[<يd9LzApHB_3?믺ۃ!Μ= cW< -~v<O\CHgZ3hbjM`E0[ .)U r _z^rq7.0])dEB3"ȝxs>}zjFg*֏2j/REl O EhUq 11Z nDƺS"}XxNo}J}y8;Ur'IZ|T Y6\JG~coL(|c`C JQ!sm;@J)c Q> W3B_izr|nW;JQ/9O7m&1kcB1dJt7]\(ORn |ٞz| y7>wa}kx+EV"E#iXHEg֢(k@9\d iMiqBxCʷc B0 3؄IMS>e5(bhGSucPJEQzfsOpo{;=z)ß}N@E j87W:Fץ/~`YV"ŠCd"]'˿7޷+ >/x# 2ccE6*"[@)yHEDzz$,d':o-gjEkc.hǮ{׌S&(zkM`E~hrs &7:ɫ'E<&n 4 H+ q/O$VG)` .m:7<@'!Y춸B}[^u ~?5Ͱto6l (SeEx5FE81Øvc!V4%^ IKᓲZY͂_/eI@Q`^ӂJJݷ8Pc,JESԮV&^oϹj߆yŶ^/:ųȞw \EL Oa{DK|e\sg-js]vPY`qaPc p+bCJ9-W`h#2 8lT!)|~.6GwPbpFQo{4}ō.F@<ڣR٩q])NvK5ǷkR- vi1u]cskK9,Jjތk x!yHYv0 ዷ߅ JĠ/BӉ϶. Rh K %4'TD*rph tWEQd+m:uG^?{L2`K0ƢƆ 504w0 c8qrwSi9K|n]G$}/|=<_k4kjS玄+tK(Uh# B[֣8J؀?'n|%&T 6BZ[9lHO~N4(Y ./t~=p~*S;8ڛ^Jb< F]B"XWP Et7܄`"R7ݘDAYsG7׳+ q,H8Kѱ1N9OwUֺ)њ)%\tŌhDFgYٔ&ɣ(ʭAE!E. l-cV c LcPc\ t07?S=؆R^JrR]h{ =R|3I)+0 pn9h>Cr.{<lMZ:F^ٹx̺(jM@4>.OJ+#Fn)9HcيAyZ"}Xy}q9,J 0RlMMXZ|,&alMNT[J[@Y-^kܩb'@];R( ~BTк@Wu|*"2E\w:[N \$"ZR ؏K0z{~:.,"ٙVN0A>;$jg B A ha@8.L҅IQ 3#?C˞RX/"3m) 6RPGd5*D©d%?Rq5z/~M1Ɵ&Av+u:.:[ TʲӖS037ˎ5uq僔>abߘ ̮OaL57C@Q7TFhtJ\l @$+(@DH6z]ob)AS!Aے\OB.A8!HPrܴ #w֡MWVFq#HNsy.? OC΁[iN࿨ԁb6c0geL| twZw C9JA(P@+/jAY,V΢Ĝ+!#?PMJҲt8A^:=prXhq֙T"Dwg)y jXV\+&N=4M|TU`Mlnnb0`<*4MAbZkesen s!ʊHHj!fF͕q8F?`GFakȱV$)U#z&.hF\T\܄dp b Qu(XEA-McY}h EFVێ(H >rB{8N(9JV<*H5(( /gϝJ)XYY:1QUpeYcmm O=4nzx^z?1ML`_'X !P2#eo.z*k$dBKs2TVU&upB5镂(|,.4n v-##SuWL_9/Je$PWB%9I\TQ<,:5m)n/+ۀJܓOh>0 3gٳ1Bv133v<c{wmЅа$(qU Aޕ; ڍ_И&v U֩MN$71MV-E*, ]&ߘ1HH߫me]*DG`sL8PATs:6>R=2y#Mzj='͔"D8-Xa}cEQ`aaǎC]8wΝ;'N̙3X^^/kxzS`4a4ōbLo~ss҉”`HҨƻ)-$a>(V``ў:ђEt'ar'("O8f5 eXv nj[3äk"@TvRY7f @!JE"jcB>=n4vj`MBnZUU8y4Rc#ɓxꩧpi?kkkv,C4D69fƷK_zO4:[Z$kZ0Nʲ`?O 'OdA^B2cOڬK&SVk ʲt$y LrwC[@XPEw?, (19yQ0MV8 t a:LJZ'e(v6ɍb>uYdW,uR!pH_XX3㡇c=~N¹s簶/%*O 3,AફĞ={", Вк'HdlxD rx7CKw_%jL@P ˓sczNPurUW+l i-FCdyMf#20\{X%7H&'+z*HAl2 JP6WPO-jP3ϠӟFm=3xGSOſF1Ouvz߆w1-͖]N,w&!*YSga&>3`ZxCDJyxKT' a8rJv,zDGZFBCVN5 N4.SvrxH8Q"3 4t@7B"As2=yt$x03qY8q"=X__;o//~& ᮻƫ^u31J%hq%x*¢ `{+R K&IOʳj0̘YFwX^ZA ݶ%,--ey;w1ꇜ_.v;=a<01 pRfz@Zk=1L6^sN >1 ϸ=^*ʣO28G؝&OP$5*ODrha,z<͂(R,Lr"Ou_2%qK@փ"( Z%lfF,C,^sΖ%+1PrCSFHHi2F;)`4:/ܹ8|P[&L~ dvE' I*1f nd4&bVtS4߳*ULckXdI5L_^` MI8=YVrhB&rbfLcQ_2f\UUass39B_:NL BF$`<c4'pA!55w}bQ,;mrQP“ @qhY` RA(P}!"ZB5AlаA1w9lM=Vqצn0֋ߕڈugX nq!HxHd"`mq"Ỵ̈-TB?s)0◢rx>Nl,fffvc*4 FN{)^%LKT!LR\@LFJ!Z"BA4ΐCN| *Pi-ԹHubYZze8]@EsAeƊw_?}3dAO<95fF(/5Z]iV/Go!& ahԚ^˂3oK'IHM.uLmBw&_F):=D#yb'(F 0 x3W/15:S&c-x"e k FOlj !u'{x5k p~,o/M"ۈ %_ƎLi9šQ#YO"hJa9h$fmNd'|ʿ/k(>g<c~a\s ,.ÇpӍ/;]"¯?^[O/077yQ+ Y`a¼1k ÚLe5Bl]ZH&)ļ&'ҴX!#0l2;XG;EEW=] {x;jm 7S FОQ.xMa@.I&i0&wQ0͢8CU J)S_=(8:O N%Moy w/{+7Nu]Gx{ރt\[,8늝siD!Ǎ 2:Nq-V<]R-łؤ(Ddk lrcmt8LF*h~T\`bҽ#`jΙwj˚* P\p qI#!~ɣM`mv s0m/?x,o  l-;HZBTKR,; yIAT2&  ^xÎCG>4M|[߂1wy't"N;5@7a!9cxoS$#&'XHDjt2l]@TUB4;ID3K575ShVn#/N0`1jL5)F<"S!2IɣXƁHb<,YPvy'O'ELTz6kkkp}3;O㲣GwJ{n uٿU]klp IJ">Kim(~Sg'AM$f ڠ(KDQH:x90mnQ#C+M;6M [m{ )ˆL0 JZ,е|1S-܊ub%av+Aۂ PT8޽{[qݻwvz|8\jOa+F:|܎ݟ*n|)W ֋MϸYh&0h ތ\sUdP%:#sӤT:=`h*G|l9p|fObU!D Z.m*3jŤCig Oj \H ]ө_~L 9E{i_Z-܂[7\vHGXYYV%{>Z CVac2-oz.kAk01 YtLB ݦYfEniY*da ,#ZiJGx-NGhh4 ' Gb{'@Еqф4Tvj |YA $j)/i)'H׋m|>o7+5س0N]6>csc}DžDU5F5j fHJ9h۩< Tbˡփ _h:yw֞H4]T ȵ^= ẅO7uf{># h:`sVaK4iTS>nOe(J7X,%6FP70N-ƴB j)?xKt0 _1`@ơK)ݿd =]4w| V ix\V+s{,݉[RLbF"EIipj,ុ+ `fquc.4ņ`@3$6ǟbB.05y^@Aǎ[ $t7<7cSh*DP{p4&wѥ7g4|3U,cn {lKV;M BX&KRGI%9l16,ķΡ1GLO=t*ʠO,<1P$y8FsZaj4EzqOe83 W]ux >}:^,o>\s5 q` zW}{ ] 9-0ScQ:7L L$uQ1jDݢJ"mK']eg ˜'H' 3>_;#H6$-XAYИ"k򖕖<`eW^%}] z@v`+E~Xij.Q`0wTǠzp!=z\r ^k_ZNZsss8rN8h |鯿_u3b%FK zL чĉY`~*SDv )niatSS^Ϣ .\ ` ¯uRU\epOakk+=_XXFWarG]*Fc]9Nl}X\ae{ggK.z IipK_z#)M mM)}$vtnFVPi1«{ƛlKKulŶAC]4bY(Phi*fN !-PYdz6 QZ9GUUx3꺮qرt:X\\+~{;aϡ( b48EƵ7w^,..F-в,t׽hM'Fuu6P bب N6B`s:O adni lce/{YT+t]4MŸgff;GGNר>Ob FA6]{eYg?e6&JJb [Tʼul[PɴXR ƛ`h\4X$I})/ka4ADxs -_gBՂ2glD 9)&>`2< a LWpwqwM]WUmt:(!*NYx]qL ( t:+]?q)[)Pۯ"F|‘E$rNQVyKfuag֫yh)"";BF}5@a N۔6m&a7IV- 2$2M$o;! Dr^HN}sq7f[C3ZL䶽>zDOO#AF`6]8eʲ׸#Xܳ;4',̀tH?؊7PaϵF.evBpiuT1S9` 0Rʽ9r(OT ho- R-(<*T&{OYGvs ѼKO߾;XYYnau|69g  LaH2Bȑ#xއ|#!6`r>ٿ]qNhK5bǏ#.wQGyy Z,Bp "'ئ?\;{+9I:EtHw@My1ŀ.L$(\Ȝd6MSp4a Lj.--0 sssx׻ޕQFe ù#@!9D?hDµRo P8~)|o7"j]KZ@ Ʉ$daʌ ki;h`+ֱ$dmԙ5J\$Y#R0s:.~g/:*\I8 IcǺ'=j}̌o|e?o߾̲pM { mrw'2 eRo+#x bbHN֥[!5S``b4v%aBWQyY- :A(ꂈ uk-%hT2rBZ!4$L] `oNcFOC2A^)G M!N!6͹E7+dn Q:43Ao&u]C߿7ٻ&N^W]u>SmݖL N:o|1TDY2JRZZ:F} b3/E }zj߿?S{r#ȏetnwd HwzH{QUU"/!$U m_Ͻj\rɡIsK39u!q'o&_7LLEB FD.Am(ŽDPd›Q"1%)q>MrT: Ux?STopSdT#pC&^wRI.6:3#79r?#?!Kc ೟<~'~tZjˬCjrn &T2mdZjeӁ82@vϿ] X+ڠV* aB2fb-! t5GKmB?qD[U}{$~MwR0m Cʳ} MĆB(~^)BJ)㉔ĉַM78W&H8sg4Z{}30p;ivk 0&nРꂣ ``OnJ҈O+tԾdwgz!Rj/<ĶڜVJ t C(Vd2Qb3??h/h:;mi{mD;w_߻wo<&,˘J+l0&:C_Wq\4ɢXshBT( I14;ZTqM#ր$\sȋ^M[j /%cHCAcI3LiJ9ذ"+ .EIKp 1M][ߺsjS5~'/yK*2o=6!ӏi~IDB->b޽q0T+"Kp(1/}{x"h9JYqnɤ&;8xC]7YkSƸ41)/bw @9%OabD@;b/ű6Z1/Nك( o@e *n9 &MO<$N<S9S|{r1i=6Ψi`?t]MtFSNM6@]xcOj ߖY:IL3+}S)Pc-,G'je*$y qANpdI9u-HNLy 3t9UyrL##S(s\S= ]lnnN>Zʯ fff&5Nn)NE촺@H-R ~O|1 fFUU~(lЦuX/ң,Pcm'4l`R.he$JҍR  S7A;it:>"@ˆrFXAN%d7׷K*D=>`7fҜ| >ERaR:yj =-ܒE"};u6vrh[HvwAt:\S0i;-0S_>BN*qpNQUE`{KU{HSaR;ǻ: yP+j!˜Aijjq)MI't 0VB۔Z1ccc>X\2/..~.@wZ;=N_oD2 jozӛpСMzqDe*)bw݃rhiNP_Λs 6 <5y0 o|"M2w oH~G0 \%E+],&0-u8Idm"6BrOpph/߿PcbmH{󞸈\[z ü uTRǐX] ;OAغ(w韶Yړÿ~qAXkQ%fggl O2Vl$MHi 8C4JoQ㇄:y.qpAV*`wm Z˧C Tɛhl D')wҸZ蜼$6S8"O :QE1xSA1NN Lmi`ZZF "g~~{`ff&)75sT ɦ8D/ ˜fByH.u2&995qK+T8x t +EZrLUM\)`eez'StN Oh}kXZz)'`ir ?Bw]7n`V4P U FYؿ?ߏX S@acGy]߮!&R*Y~hڪ6rG\@SZ \m"7}? g;3͋!S Ƿ.%)xAi|mwl3IL / { X4 :tL}FQ\hԎNQBmϝ:];MwT 7A]q#KÇwެ#$k&`{.F!F|Fڛ˟:qئ55XF4M4j&e82EяWbBLv#2Y *CxhS}>*EK1Tr-NRuwxɘI}_G8/vG$w mt[PUaqL{h4(ǣ1?y<Ay˩0eD 1.&n.k zK[ 'N*JGLEb'@N}0^G`OºTt/ZPc* 2Թ#07k47ۈ"iV`ө_ C;w>v|Btx<1 ۠~|;-Ҥi`aaW^y%pQ۷/ by1?Wr0%**$P.0`Kj ,JGqH^R,ӳ$$m$Lrv^ /4lt/4V. ,C~b]0>MQ."A6cA+W_-g[>vK.4\kE)pM7a8bmm {Ç"`'A xDcT4h|ݽ+ $EFׯ881PŮ8;]t(HĔJlu3ழwQΌ,# =x /D)/rD:f|'1̑pug++%/8TF&)4DGQziuHMtE s lra,1  ).2ot\_kQw4f}Xd^,9nou]Ck[8pEF Q񾗓a)c (~ܹڧ@B? ZS938M[+a/ȜZ sYGheMSH9ڀbBdl zn+q@9T#~R1L3,{꺎ZbEQſ{Yfح 6ѣG11qylnnNu5Tڴ yymU7Ʀx-ظw*~E;(BG³r9ero6 vv1 2W06 )=7+cOk_$m3Щj6O!4؉{1$eU,N^K7Ay8jH8=fdtSfzk18p h۝w;2Mnw+n)O; ^\a8x+EQyHQ떺¥ g8ӠU{ 8%DҼ/nmma4i 8 %+乻r `*_Y D䢊,ZE[(VmPbR2P:Y|_śS(.LKq텆Z;2KExR/ Zu}kPCk:?1+O,QvJ߿/\ua u41@PkY&S `v;2[BH*˳:rf^ق,lo'@}aI=},O5B%huTJbԊ~sf*:؎5Akix  pc8pg>w+'6@Hh4Fd\hȴCsw L4}T5]cy`iaH U(:]9؏{1]Sp@IV.ݚ0njOr6&k RoR+`rn/y-83HEMY"bUԘ*9LQ!2grL>(W9Co®| e>¬.ް!Nr虙|cûn\} MO_ DXb:bĭTZ!)a&V,"qk4mυUJ&6.X"*9s T 78?5\3`t];>koڔUbo h mpZ\̵؆gѓ\{>1 vP13`X>Wf"4 En+B*S׃$"ɢ5C(VP`Kspt&mrn%* i4ڑ &kc,@!ET0$Q # ^(*"VHzihp ldD"_;[xM^uu?)\a#i*tP5ӑ-2(_>ۃݏhbdQ hq'$MI2 .7 ϥ8AnS#ďb p^d}m J'{xi&i(hdd g1 gs}[^,L|55Jar310>^<d1l z*EЙx>#G/?xK_:ThZ-0D;SН2o/~mj=cvץeh s4M)U18=_D!ճJHHBMi@,*Px ԕ)0!wa8{ ,^y<Zt$Aj.GFORKS2+*keМMTTvsC=tQN0U_6{ߌAk/~7|s٥NaɊ-ѝڝ!i9#yw'8@vK8țsnFDV6 D ܍6l">NנeFDaŤsT}Fg ~}\Iud]?{or 9~Xi{{{OڸJS R^, nĿ&[ƇtB6X9µ5xpPӧVzJ;V(Z)̼'gY8n|?A- k4s`JY@VTuXd]84a [̠(ܱ5:4F!imQڄXb _}d[7ȫlmm7~7 ~>,MX FNf"7 5E[•/g\TQ[V?!4qQV ZhHt8پyy)#ؚ k^9ĄasH&ї&@1)z r6-$>8Bo|7ܰ}TΝN3iCSi`-a8·][vM+MA+ E ū+GDI`KjB@&ILWJCqsdzD7?XSXn]I1b5HMbw,GSd@R2Pn:uKe]diʤ,B _;ꪫ4MUÍZX siQ8-}ۼ.,0gk#"ԍS `(k}s-YMJ_W4PJ4vK#}.{/Noh[,ɞN6S\4 >O̙3m`<[O]),-c\o\>D(&y e*QS(P>)!ـ#K Zan홗JB3H. H2|օ0A.7`ݗC .<|2FvJwf ;[72[Ȅ$&6*$3PG f{gpӃxlB$ 0VSN8 O,~ ;r+TeMAb ]x ?$:ҭ:BgX"UKX[gQ)⫟/8QwڅLJ#{VM@k%#A*3FEE:N@n?汭 4ec(_w E5/o= 7ફ*kUU(/amNoc$O`XZZoԎb%r6ƦE)ZZ l( pl%vJ~D|M7%#=ȝ&9.eN|۞)>/)p(4L-" Y3\C3J쭚-)M0)a }5a~zAlx-ߟ)ʅXmi'@E+e ?u>a0d_;ASZ[*OOOus#2Fu\`>s> ?ErtP}Cks_GŔ #  zEi'AkM%Ӏb*Q=*Wp nW_n~&N:B)/ ?<-Ur5n'n)lcB=pPQlUqIcmLcl{\D{rƏVf7ַK_M UB ({T"hm$xS)gS Nax<4%mF nMú6P;C~6[](\֜/1?:z!%/#G nX򿺮q{IDZᚣj0!aSrjxsżFaMRK:. ,=|lQ .  TL.;y miWVM1eRr w .4,IDATx:m'47C(;p7/nGr~O<݋kW^yetM|'qux#̍?K 64lfƲ7ѳ`KxxBHfi^-D_}“ܷttW4:@i8 ͱxr @*Nps8ډ̗yM;c0J;aZ*89Y0rRNpK1Ϋ66(-a{һ/i{A[u>ǡ{6έs0\ {DTċЅR@u~B\}8g\s ~H؜pP#'L^Xin%p=pQ`vpMmr0`!c}7~Ψ,}x%+l<?cC )X5M?|ҫJ$}8OLeiqu{ÁfÉoֱQrVb( h&r,8q>UҝѾ?ǘK<}1"w%^[h\U%0 #mx DcH!ZY{ vUNMmJ ::E( 8nz\~,dQbxQ'cL # ;ߓ L!`Ъ&nMoG@[C(v@!0#D-qm d@1}>VhM#>~c ;q;` iI0%7cC֨=xbu:X,)e@[5Ÿ"DLӀ^פJ`c@^t0V_|#< 9RCOZDfl'B$ByAe4%=S1vz^4;L PB16Vqn7ҵN`7K"9Qncd$}% \D>t '7o#Gk ֌m\F+eϑlwEr¯qWr|U! "\Zy9S{7N2M\~;lV@qV8>&DvR?hs ڛ-JGZNg減뤌T.?t[]]E mb5mY&ScGjDPkpr}כH9)OV0 C3ЅZq`FnR뜈`0ֵbfn@vw .vFu[ Mh%އ Q_")%qJw5V_0?(; a4Py-@ mfȡAbh"1.2D;i;ሬ*VVV93?4cN?CJ= mR_jH zţC zQ ]* (Ph }NYKh-Ci1N39jZRN*,4cqP&;᥯{^xU0M?/ JrQd<T> |޻iv , ږft}a`p;KtJm v6[$R . ePxD(7 W,qY;w XXX,nl wNUU Z67/Eӊb@]N!w:@3B)UUbH dȰ!C 6"͢`jvt"],6Mu1N MMl IQ=  =}"~VhHT%>s>{.QvQȵvy]E *שX&`jU{pD(;'f0uW>pI3[ذ411Dj`F'H'[\pտ^<,^?i`A܏b^tVCqx;:-~hWІtؑ4bjv- X@%vqffPenfrAC509RK((hoӠ,A|d3̶@kwt0i'Ee!#}MR(=Ai5E8@mDl+v(TqTσV('Y(0m֮UU!7͸/^|}] nOE<"rEeN`G:'xRI$ˣPV M txvƗkRЬ<ҽ-߅b֬V&$>vW  ļ:vj3{0E{077^``SZJe4Iv^`uhHՔ8lZq"׷6Cp`87 yM 'xטNىVRPx 4l2Tawpvr;,(?iƀ nR$(d\P|*{7UMfndEu%,:p=bpx ކ˷cnx֝Goxַ# ՀPZc+ b?03;n룣D (8e? /zr2Fo9XOO1z#`8Pêw6{GNNn^uv:(Kw:e ]h]1[%!60v'50hO2*US%hL R vsr̮a$mfF8p/jĩP 5ڄA/\aS cctJrrAG8|,/>^y~W>of'A8TրS싯:u8׽W^ tP}hR)+t1f\ E!mh (\b{Ch*á`04%>v:/nnn٧}z==:ݰQ P>U}Gp/ FupfnEUP&H|;u_w7 {olan[Em vGdf s l`L4̮v ]n,&Q-PKt!ކ"rU*jOjtP>N-^|/ݎQR~lȡ +R3?݄Qp~\v ?[J$ _X=PU݀MM-ZTD(w! o@==] `t0G6WZCb/ke.߅wba)\'ֆ5\o̼z3} y48B}ݣZW!e: #zUtK%k`T+aS`L`݁/:0 WOydSyl #i| lԌwbIɑ9EѺ)l/:٥Xa㷄=r;h]4ԥm\)t-mZ2 qi0>ߗPM%lb?ω8d( R[3JA*"]pַq% 6@m5ƬQQEO|gu͢Ⱦ.]޸M"~|uEOob@DYҮ!c'h44)ZeO$ G3mc^0=^o-}-.2|?l@RB%vq\䲖pfy n41/ (BcSv 1yU`J!Ե3SpScQAY ut\|S%2LӠ,5ƀW0Ơi=46E[c1OE[|:!mхN)\!f,3:` $ 366(^Wuԃ x V02bl 0(f4.[( "/BmN<)$uЈJcoaKinByVUMgfs^x}g_\>JwaٱE.+`G!51j k& 9ژN@k4( Uc=9_8ָ.c*Ttѱe\24}V9la"Eu3„3tz:uPP*=d 7 =tg07F1FBB1Ū)X-6IU: nP5{<L z6mҮSh_ݷAY Ș,Saye[ZLG88Sg `ʍaj1v]"C=uXr6`k0Lr'U]a\WGwVTg,LEl(}a<$#IY@*/mvў`=H+ɴr^) IaYYQQ[=7(*91/~ٗ`ĆVvK0(;QWp>gw@Ai9zq8p6+T/"0RzKSkGl38$!' OcoDYLC&3u?7[^{= ၮ4gUPyl~W\u-n,B 밦&p<߀f$ L-:mYs9,TiN:x,(b:B/뽏]QHvSCIIP;  \:1]nj*Z0Z60ލ1&Kk}߆|/CF=l? Rֈ&R]JMݸ`(nL9viULkj8qԳ5 "MQlkPxzm7b^9`. -Thɣ}>ݬ %#xf+:.~ @a_<3%^86.Wئl' \^cߧBJG+ p80^FPxw2e8ChXDWz '?6E:Vxd"1֓(4 _EbQox;܈[oیs1gW_nyܱ1BN Q'˲yS?wx fR~8hA=;0E"/M|:QpĀ;j֎TMp|,A:'B)#?)^Ok֥KL " kk(ݍSꦩQ`8ObˎZYO m#lZGF&@Kz68:eOuSb<F4f蠮s<sc`0WJ( :]\WWr1476p7nsGQι{ЍKϠj׶] 43G34cë^s#2Ь sa~3>W4 msjұY?*^;( % tz4Z{ʦk+ 60G|8ÑX4 ffg1 NGSU4P Oܴ>anhPz { N׽&:T1FNUUcvvuUij/V}\vvY;P8CF?Bӕ,p4$\,DnmZc7Y :n!Ъ8N}*~\M[&F٧? aBZ6JW.k_[z4tz>C6 MVSƚ/;XϠ[ _qY=|$ k6`r3\|o7zgwLEa-o>|^/|/C"0 Ϣ?4]q^]D)/6TZPv{>L.#1`AJ9*y n3q4Ą1ou /Ni?_ B>;E m"u]XC(ƽ['K`kQ_QO+|{ &Bwf(S\وMk;Z06i'V.Efo{5|۱|fKX)I ܀t%j`T Sj,фNF3&eV~}z4Kgq^nRH Dg UYp:<*9P)J_L@YFDBSx X /՗TnJ}R)/zZ葐p6,<@P%ۨbI^(]ǣX0Dk؂CjE'Z|_kv..:ȂV ,E>x0C؎%u;(cq߁6Ib&yMgdp' 6xI|kJ/ BIq HÂ{?:s;=틽oSg^}ωMo'C+ĉX:H  'ǎ\}8 0.%Ж:l(2pӔ y.~ç@4VqԵk2!I]8''y[0P셛Nh`$"9uv=4:8#ruGmjY(rJu8x0J]S8ZRu҃B%P(P>+pW!2=oHNmjc 1WZЙT 7GyO>fs3|o=җoő#Gp{"ŏpMe,c@&6t~M8D\Wr-^߃t$)RuEJ'~x2 JhÊ_]qA4|(Arq YM 7ol] @ZH)`DoQv:&_[c~M]FBoҏ4 п '>ȉxހu 8))"!uhMNQ|kSa4q7u8M30j{Qqq" nW (GTdF|Ql"j0S@Ol.0" ,gNW_S<@aH;=?PHur?g'0muь;_.h6>BAD\EiÙ5yI`.{?WGq=w?y౧Ncԓm`%ߟUzMm'QJJv&("2.Q3>0A Gsaܐ{WQm i|اpD#d@Q&l1' x 1Kdc#)I|SvAJ9s?7jB|@@*׃_Y:_JNlL>W!U}!e7)!X@H %A} s?"t ~ꋸ 5|Ǐ =OGqQ)`x[AWm\q٥892lm )b/+xɏ_]u5Jۻ/I]LqʜRT2H :3;d;~]Ѭ @]L1ٵU_k<3̘)T,6NZTU M0J&U!U]#r[|[%3&G5Pq<;1wv)Yfo"T}ʑS:頻nR i7AmFf]VQ e/No-8+ne/d^Kʚ1>>񡃰 3u;Vzb,AT.mER6ȮcPB] 160?;˷b$ǐ);CMP(D0Zӵ69%+ IaFdR tdѶM*+V6g?rߤ|'ٜBvv0g@4Z[(|g< Ʀ90݋L)^k(+SӸb?IiD"3r)2spmW}zL. +3kJ*IFfI%Leea"Z*>Xn8X\zȗ"=G*/7CT\)WW)>?׏&w\k__غ)ʰ,yY"cES@l)MA[e dʪ<39fTt9*Dl`:>.2CLC#X[z,8#b [mf(phӚײ- ܰ?5q ۢ^ձLNa8AdW 홡67G_U%ui fvo`5GC){^[[SD-JWPyRI&PH y:tą{ސr(#?EjijXߑT v ߶M6bLM;5'VCa[B/b.\iD8ꁫ>rRi"C)AmHd:2\U2=L*U7r3]jj @d?6!6Y|K ycp6(8^?sv3v2HO}w#Y +rq4sfA`OE#%k0*p\GY4z0RP#ߍ}%$:?-aҦL&z"3 ~>uˁk}$keUiadf)lQ/mxJ)jYUlJdKk k9*Un]khq2BZJ&N$D[kWHD6dRlCvW]tˈ׻BIMˀ59%2skwnhM#Z"iM@stQ`kA*f[FVd oﭲtp"qs:7B˳ j10> ("i[o"(`pvV5A%!# )4XA @^(6OP@1JLY~e 3b2GFB#X2dzl+#yU!'(gԁdg-f8vm7i#oAEXp .%&W>8!8XWfS$2yd1 Z,b:ZfHNt|ӕ.zMGdžMYajh"9E>kF"ˬӅk.ԪAp?m+54rBb9M 5\;HWpP0jԴq5 9t>wx{ ɩF$UP})+ףڥsu Vv^`@|qHx2a1mfdvX(pJigI#OR׍px_]Q(½KpQ/*\b>ON+~T3_NH5#stTdfer}s5H_Ri8t/{Md`7BE->vSpP' #!i1Y$3{Ïn޸cǎ3o_ƒ~/3."3An8Sc OsF<, mQ)؇crш=ftQEv& ꒨"6D>}s17$dbL8|tgóocpnC 7汲Ǘ.v\K KÏbnxsos3ԧo-87xSr $}6Kjw܀ |\%St2",7GC,l\?Ȓ!T;yaԲ"c5G@2p ogDߧJ<]#sCt6piM?v^y&ZMx웘/pЍ>f&GqOn*vn8{,gujއݗaNZ5"{oWav~[k>t=-0Yaɣs/iq JAnxIc8Jp Pq} ~2ćc}ab$n,i ƻkAD^|SNkhKqBf->E}rcI@E$- h= tgBig0pqa? ; $+pb)b 㿳xynطBh9n5@{uofg{%"I\.GY 3}xCR2 NDf,w`MY f!lfod1Ie /p(Nt Re('©3讯anx)YHÉ֯v]POIv"l , y< 5)KIi 7or-*CES;j "q˲lqTɧaЩgnΩ:9=LoE]k,vF{~5R+.*ͨ(-a& zh1,pRd8#0ރޙ|W=$4'pNj+·CQYIFKHq-}/Nm\l;nMƀR9f|3c.s'Z9Ǜ8@ <.oB}ݠE喈͏-aqJ%R P(""ɬVUUJdRO'[;>(s\6bP25 Qރ]B$7ID0` \l %^]#|{Wtj"c%CgsݸNS? eo-A={Μ9CGRٰa+Wd۶m455Z\Z`,MJ!&|رFijj۷3==W_  fR r)9Jmmm3x$i B$5D1S<"BLMMQTCjGިRx:wh÷ׇhVt>W7VDY6jрJhÍC)o<+;QGWWccc|=0@X&_Ƀ">QJYwÀB%[P<Ƨ9zvUs 4l"j`PQADft(ܹ(qGK [Z?H '[ ܽY9IGTIUL-9@r} snT/=ͭXk/|ȹ˖sf5+u%!NƵܶnSJe9.~o&(QN{YÃa%NR$*pn|6.~㏬bfU" fB-" N  !Xغl_22t4K4!oԞY0w$.?dOCIENDB`CPU-X-4.2.0/data/icons/CPU-X_24x24.png000066400000000000000000000033021403012130000165600ustar00rootroot00000000000000PNG  IHDRw=gAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>IDATHUoWr.vAFiԤB%TJ/ Oy7@ !HҒ ZqDQqvl'Ƿs3vґhf׷~7f5mjQPc@FUK5 t/S[\HJ3UߠZ'48aQlhb$AUQHwyXPU,ɣ q"|q.n\A_l'q/~g_.<$ ދ V~w|}ņV³G3\{5,9Y&KK(9ޑ9$jі7@DRBP@ uTf8&o1$D:s!in\{Ћ$FUQ :GuY 5>_7Wfiy 1c n!#!L B "1`y$I?'< pߤz`k׮q1* dØ')YkRU:;ۯ׿COO |gWe̥dFGSW#E%#.]Ǐ:Papcǎ?ɡCOp3X8>$[E(twwIWWO\.sYiYc-HAGLM'eevMfgILHoCmt U$!I[Pj>.0o[ӳJ"6j*QJ`!"MC W](n~ wFtجEwYFF!@ȜlCDj4\`qOa".,cVq|=c[8K LF7RE k5.]aq*pwnqꧨ(FӥAIz+b*8CDskק(^[ז#_y$V색,l~j Ftj,2롣xɊSYI%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_256x256.png000066400000000000000000002213301403012130000167410ustar00rootroot00000000000000PNG  IHDR\rfgAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>IDATxygu~[rZQ(;A$ )DJDJ)ղȚ%=qha;KXӚ"[;emr_@} W[޽g9_V@Eπm{9:{]PUK=m0-08|@@ɀpY f'3<(< G?|9ޭů΅Z>w=:?YYY<';0nN}OQ}^A\/g]>fN8j[؁L 0_{k#w\I}ֽ8!s'OO>2`nrv afڇ7qIot:6;IWټ]f>ϵ{3tz3Sn2sx%}"li㹸Vq~%;}j! ܗxL֦3L@dAZ|| ^{}|ʞ3Xp;7tLvs\d*yl7{xM baspy*Hܬ&=ߣ:z]AgǸ޿33@Zpq:煥4~)ɘg?;7N +d)xƉC8 TaO]rV|#?clzKg_yS"T=U109WW}j̮lۄ]{q-ƟqX3bSO=$f7sXEV}P{PZ,x\#QŽLεR_)3C\}SLzVE{Lg>Y);q[J̄Txwo5F[8}5Я*מ Fq1<Q'wyJgZ/ `Cv".6nc9<>tW)˛ u4M0S4NKcFG_+Z2(-ޣX8`\`g*bNQ9],G".E)]pi}JY44fWL /HſY~9n2~A\> 쯉\,\@UX]xzk'XYw*Q:L u>cd& Ejl-5ŠShͮ"囙n)7\1 q%O48,S+^)Op8F;8ӵ\&l]Z`_8gi2Met|ւYK7> |AxX RߧLz`SL19}f|!EK:yMx):ǭ&"c! Pq[2ou6z!~wLҷ{\;Ӊ3쯍UolUl;#Fr)pz|6\.x|pG X=E0*>pC'~Ө 3XG`!YU87k".z4\I,[lzAt\o?5{/z4@MpCE8'XL,7UcQ,VaiGf׮28+Ri4L:SQ:qȟ,3LR `|3rFlRebwUStD\|&D,g,["ӶE#Uyӭmҙ^Ζ WJ!P1\*b@h} @ĸ[qvx0pM7*ر?9^t"66|].難T(H}|?~cߋac<5.z6|TycEYэpU,Nh] uN>-Hif>L)-LN|,f:eHEd t͘Uf l ЊAl}|ܗ#c6Ne!AE 'GN {}&Ġ0 F sof f+BǴ|GQ:LUS Nx3꺇o~ϱoKvB-JrYhc_p Cd\/>};01p7ˡGP!?g.DtM_e@CmHV/o"=%ӥQ&d:Dd@~e9er"2xrFedJ `VQцbLf.^AI6.&}D苘@\9HI0a[+E;ȅGIK0saw6L]'&r>2aӧ4&M`*D\fSVE d.,y z.SXě!!C ab B2*v׆cH3ϚJkaܞjId6PtP1b$z 8I.(-BXv6!AH)mxMMc\ 3`E*S"%|O0N\wMc'׿E4N4s p)RنLge-Z'P4M9.4J(hD\"cxxYf *q^(&nܸ]|DF|T8l|* MAi@~SGq<21H)uPes{΀rP`(+nyZ.lh(>-Y(2&Ld 0Hyɲ ,M&9M8"9UT?M[̎H$LƬ.@ |"u)Kg_[xg &wGsHqE79ތ@- .uK D062iYbbTⲓO"do!ELZ!1.~4"1%ؑG5Pj@!Ӭ(0&z^d=0szAC<&wXRq}2q󅿺46 ) f*BCʛHR2mו-on$6k@ %vU׬z4l )+a`8Gpr? μ+N=Vި Ȳ^-uLOGzuQR! "!}*-pSC[``0D5\l?f7q7+S͉(ph.w!BLkq|^S,NdZڒ . tE1NN|5U=0& G)Ir X L1KrcXoegJfoL2NY1CL$u%Rs]8c!n8pF終uNb*=/,j\+Ǧir/e}Sb8eS7-I8ɁR]'6MJBm=EUpCƎBR2ÆM.,>AA;UBT?G0`A3mPtJHjXVv)WJC@ħ?ӫ&@ rQ"b8lv߀}z466)gGJɰW j1~FW*MbOkPRم8Q[{b\-5g9B@o8nʘǓޘ0<߫1>ʀ\ 2!_ qcA>82 Pb4SO)1j,LG@G*Tuϟ΁آWX Ǣ7N]Mp0xM@EԀ] 'ո\>4>$Q0P9FE6脦 \Ä`ww6lp hh,YhuR4z΅"Ɍ]MRixKlDa}QE\ 5qr*ŦUE­Ǘow܀[NCG0^  !3RlD1D0=?9FP4/Se=> Q9׸FJt8KP(){ 'sЊOUe`;GTC $BMd ^`T qkCjd$fHPa6 c*=bP,C9 ׻"?p.q|=d1Y6V d|&Xedu_KgvqKxs8{i ؊9TJ69}Xr>(* =tjQʜ9Į=1iM̐kW}RATQF#vb߉VX9`8L(ڏ>$Cz` UE~zS8.uŖrٓH$5I&Pƺɷ3[H|I@o*k T`e<]5W0+A&MC "?uyv†x5 +鷔=Ft(_OLA8260l _9wfa.e\X9VnLfpqy|^ѝpk_ǥK;i.gj 5,Ep~Der[DA'ʇ̇܀n~CS~~ VW70j&CuajB4y#14S.8hӉGV8io˒H$"gY_"]]#C :8^5sqkԉ/).7 1i!f/:P&1ZޅkB5DhlH$<'}ss<.Rmz_c{o4GƉoǮ[o=/~5|KObjXarJ< %P&ȥLDz0DzȊ/MyV5@)A5e"%x'?wu/ i$Axr%̣$("Nb^&qCԫy!0ǿU&`sw$>GŬDQB#C $T*ĽA E PpTu-QT2 ίĔq6 yJ's u SUʸ5'G(X;&NMRDLexଧ:t+Oǟ:~5LƑ3Uu B2YAN f^+u3/L|hUCI~ P2!~<77i3 O94Ɉt( zӫ۝)~]r\1C(OgrM>&pq|"(&~o>; u T`TOk,!$k{l*먪*wl Ȑ럲 ZljNCQUT-(A {qH<}Ƞr0=ĭϾ+1H i\H[Ri(51tSr"ԃ:G{,?G>4r 1QЄSn|;.@}SESYnK[ɅGͪR}$&q~\^ؤX>`I$u.`,xb66DI(HNY@*7a(tϪT~`ܒ';=z^dLP -^fR' *MAQ:+5Ηu[o ?G?5tr5hV]\Ģx*ۀ| 9TrAͩ_z{F?W[67Lj> nbM$H8sAXefP+<=qε^Cm*c&|"BUUF.KLK7AwÖt/Qj?ׇ&n ⵓ's}'\d% =(ٝ}hnz^3UKI h`'*@*1Utq9t?xu%2OFD  Hƻpf @[a>31)u!1 na{k cYvm|2+,Mbp"\hdhfrE6!iS>݀ uWzY{&|fDžߵ]x._֤ Ul<#܁pG]Oq-Xp{ì,lV-=8,Z'fvε ]H|kln]9LY_D)8=_٘*N{2[pLdv3 MkĬD/;ANk||0wtԭ]!4(n~H5M :c-C)Gx0=O$ŠE- wik Iib\hޠ#}/67gK!򀊬-񨾣R^'nPE&g6)J*wFceĖ:60g9HkMZfL)7c9 1ǐHLoxՔPd0؜h2ʎD-^{!(2 8b^ddTVlt n|߇o?͑H.#L`Zo`1̣P(zQ'I W6=>C7a:ePY}FUU:QJRF%=fmtrS?L$ "=^68ҠPdwzCj)e ъ HQJȉ'uYޥ{5p2ZQ2uC`L1c:SԽ!غzu*0^Eji e}A|E6ݢ,RZ5X)Ve߆jy<˯~SCp%L'9'! زass:$9eRH01IjT؀]E-7/l6SENF; &iѹx2rZ) ACv4),zO)NhS W$6E? HqB&>+g/V'U\I'J߿I5rR61"s# Q" lY\,9 [Uf , VٳѣG`NW c@0p...xϽ􇰍UV99\W Q PA'T2M4 DxsEp!<8NMBp!,j>̇aCZ7NI qg%.Tv03ŕg2-5FgE݀XPɼtJCʫQb_F-qQ⢴|yFD8UEQ?+ݒzai@%錈1,GJZݔ8FƠc8anǹ3~z;OYu:(xu{xS -8E*oӇWbd[n#?CAPdVv~nᜊ̾ t$1"evlڤN}#/@1ƅ2ˌ#'>]!ΊU#H͂f+${EyԨM(s+~2RѶѭ[v7yhG d.XE 6z a5U^]c~nkXY>v Ӻ$^6Mrc8nF<)<0 Wp\ˆZ4p.p3-ntk-lӄ ^G09A)6gRRp̒"І(!&p'Gӆۍ n ޢRvcb ~sC.tbP1I&ƹ~NBϢNPսCdZK]ר}8~,w!ƴMf(h-$+dKauGaz=nms|m4 ‰º&gʗe!**$GNЁ9M.YZNt $&*{pi/g"4KO/[0e'cޔ:TX1!? šrqy uD6&C+362ۥK D`QLibwl%8~/D1vi`jt >0 xe ;^0ڂz%x `A?-"hx71ӱbkleBon)DY'8n 9e&9HR 6ZtqNPNr$l8ۨ9+9+!5- &(1{I"=ڏ07D\YL*Oqa 4Jf]"$4bZƚ:*B#>?9BGBPl 2uIR/IL*w0Iu8y`YRTYñyֆV}=DTv)][$y`jQ9ettva},vXئ)jjxnфeHGJ&yhC0ڠiM R_8bW*r4r|uFH.dLUi1Lwwm-lں`0H8 ٣*LӴUi#t/G,K.w`TC38ga*p"vqr;:ht٘ A *S&k'X9kqY2uZ붱v ' ۏ6^#PcOU깦 ("Ѥ0-me.u=tidDZ<9m4rTDU)(BNB4P^2) Bbϗ`K:!Ta4v ihgAiak{;h)qb\6M`2& 51X\\<`cbA5ΙNh4; cBVi $#ud7-Rj9QԞ}JK N1󀠧G.s֧v5!wp68@b#.ٟe"zu`eH"$K:*Y2ܚ`aF#@MX)٪r"vpg;.3o/o nh -^1,fpU^Wc2H@=ܳw$]YX&.L[_\PbM%,yXb 9uۺ ˒U吡0i( )M$6UE6$3)#q;SqXCk֠dZ.3d6j*srK\R33hYS0#M2-*\B H yL⊾) IGYn6mȲ6CK][ {" #/]s@B' Ν;'Oi_r d/ٕ1K8y{?xRKJҊSIStOPRt4V+?*ZlzP!@tMSvEI6gQܓԪ mxu†[K:UvSi*,[=p56`O'1`J%eªX{.J6)H`G"jWW]D ZS3r6XFAg' sεN~Sxh]ZWP z)-dz*D:;;!!qG9: -+,%KQvH!:WĔ ]HHgVkp֢\;WC{L-跊hT$hҪ֕M8'hOEDxIc;S! -5ىTk\I4 E?0QbqFc\|%qѭcmm ϟm/S%ڿG~R5 \t O|I9z$2ԉgKS>IgfHYh).O@]Sjю1N~ѫϷ}`VhKբ%0k0OLy̍ u/ah`W+ QIRW٘ Jjh(Na/HΓH hQA,L<Ĭ>C-޴Z1 j5+/R*Ɓ˦x \|9n]h6m/#X`{>;Fk4Z5$$31֙Zxh4d[, 82PHFa',?Ckw FBEP`@TĤi>Ro{I~?SRudM xj)JY8&!bQ!j.|GL!Ju{X2Kq۪HG@[XL3ybm`JjO4 \FN#:bccW\I looԟet:M3(._W^~;RLēZҌU=,5E099 3HtuO`9^%&ՙY/1 [~ܯpʦ/CS `I05c s FM蹏̐e[rC2,K A$+fx+e" c~Wd/T3VQW1iRqr-MUq`csbX~X]]U}.ϛ{u&zŸ^z>z ¹M(TeYjYv[^h>GZ;J27E<2iW?jm,tcTdH>8IU/44v'!\S\,9Oj GE(z9|lfLP;2ܴ| DRY y CgQڛ]vglAVHVb$kum@plAQȴr:X}`͐S0(b\ ip15D@4" Xr]d *L^M`ccCvg?}1ƘgIh &.^_*Sx2~GK{Yu "OT2Ed$h2JARhPXg6cv(LK[(–nj] SgNƷdzgYIf:Cki8/":ٚ4bC>nE!Ii_:bK஀DZ D !uR^"4 )Nt'a4%?k]GC]iT#e+x<ٳ,J<88MefASԩA=i9q٥$4b9KF1;F#fߢ}l˲2T1&jDT.Z< ӟORo8CQ5T-`wA˦!JιJ9ix<mjA/NhQm4+Qע=NvX23 $j)VaJ i@u:\1Тb [[L-ܔq_mw>!!z^gjBP+@4 .iЋ@X1M(3֤"7:Tw ɴ50TDb.aZU0DheTN d̾oM QF5eJTe~@5ޡAy@*Ao$[z/n}؅gn2Z<G7MRJBI*;Sovr5h^l* Q#2ބvRkH2 o E,:\jfYr D xkk+}x2G.@LF'JZd.,,`8׹i!TU]L&UVHR [h)^֩rؗ wbTT_ŀ,KXL Jۜn8BUh/f . {K2R#Ƙ0jZ U"A!`j/^oO#ow}_wߨ !zH@*!&Cb4T|)<|d@6IJ֩ިdyhֱD8n*N TWS"d>KǍ2m䩸j2ik~;XXX‚W ەH`{{ [ۺ/,7B6MR#ob(VHņsL󉜌c\4$|2%*UwQj;ƀTߕd z,U'nix?>op5ow˿ }O43b<9ahWnƎ./ȴGeU>tJ_Febh$iR>zrD H@VtybCRm i23-oĈoLԐB ךS\wawwH\P)F9Gj!kIP^\$=tH'$Xr/EN^N.cdIHT(!{t" H1fx2PqCѷOw/a||TO~;o~N;~y~qُIoSZiAfYA.^oZt:X J![䠄2wI˯{s1qR@kOΰ' H?2ϢߟL&pϣ* t7~SO R{3~YO'/VYJV.SurXpta-iODL'cG$5vvv0LZ{m|k-FQw{._W^yxx'pJ@CyEm^D` f ЖriGX9tˇ3V{1bz[ pc{N8},N8;wu7~w>Е{+\| ?%cí0K&)Iɺe rf%vAlK:ALя16RZM!b@{ ߎoog=W˗$?%!Psy!%W Yg-| -@ ߋ|;Ci.ceeo4g~גXs+ ,f]'9-Pw9۲3էII:\{(>I_֞f7D;$u>;k2;$o@_Vh'9zߚDkq˛c/{Wc~пˍoM @K@b}FRؐ:s, :PiJ.jhMR\jw Cw}MZd.b2z vwG8KKX: k->5w]w_xCaa~>Q<`<`k{w}7;?Ӡwogl@~ x%&~ޤz P @1i=M8ݫI0P:M>N!qƁ#'7hvwv6.+OYӛ:}z*?Q81kq=wD~p^8qӍJ_ઋ(rFܦOBA8Xgߣ͘?T2Rnq]d͙[|BD e[`;7={}ǏO"\sViiSSqVf5'݄C y !`h?dʘ{mR)*Nl^CT+8w_<{O_w |}_;ճ7V v7Q]k^u9(j G2%Pj(w` ꡝPAi|VuQ=UgUՁEW *ULA_۠?'-_򗱹6VVV1{Y\wrqc8y$~~?0w^KFO=)`XCC/Ⱦ~]*?5Wt}ʘCx w,:}Xn~C) u2 s+5yjc_*a*lSQ Pb敳);ĉpRmDu4Pj3oF(]. LLA tBpI\tWi\~=]fbuu5M lmm#μǎp3g//p73 yF#=L{4 6761b3ZU(vaX*hfEf,A"*LEo.Q DCc fd(mN}8!4Vn".x 6oB& fCr$ BwLNCee`(~{,X8 Z+ǹtRͲ3R>I ?!hҫ&U'&ꠢ9V&Oԝ=wwq>֖B\U,.-?`/fz);wc{{[]pYc:d:ڕˉE@1-Ek*ah1,ՖY2f깕+*e[# ZԖ3ƐC]p b + 06n12i,]и|Ɠ6oJwLrWiE/ $YHhorp\CB@ NKCw<Hj/ TNx_z {{q&=@qA} پ tx l:m+`gg /e zYF :믿7˗.L({0j5W&-y έf?N B t FJc\"/#cM,ȹ}z.,) TL|Eɤ85%UJz0# rM8Oe!Kf@46Zo J;8d=B+2:?8>|?,|1 pXƇJf`yzi͍5\Ys籵 X^Jɟ/w7;c'clnl⹳{ +ƿgYHSi+cDeȎys qՠ<աB <& RFMƲA?;Y TI֋a.! i/7אD~b"( +~!ԋuc)< `J 3 .El#zP7iR\;I蒧ޛ3ݏy^?}O<8>?ɟb~l=?Ыq=< S8DX6W; >ޙ0L>^#?b0bty5)\re/uu-#ܚ}eFI@PHd{~# 8hQS"ۄPeQgfSea.01B"9Z9Gp -)1+7SՉHijV:޾bhD!R-3({ n8 `www]AO~"p` m`a=k:f|y`kfo,~!n/2.>sw=O&X_[ÓNc$*MC&zDqXYc]Sԑ.5DIZt(r钔u֨H8PDm+NkNR;r)MĀޛt.o@Sd D_ZsҁW@.XNjdgP6ef. E]6)2 HcZ9Ks4@&dOlJZiQ 2A֋f.N8u@)0ppf2Z?,itR1Y칶 Ƅ."[F (0\pֻ6}S0,,zZW~[n{.0aC*̌ng Q:Z~Mu‡f6p`X;DZ;׾U|רiX Y؃!EHEm**l ؐ}2[Al;7@TU[7h08)I<yL]7~m.VLɡA^ m"LH5 5/{AO=dxK([~TO Ji-\Q!5t੿cT081cn (n-M00ߓZh:^ֱzVQLB҉ ,\tV7%@,-sad@C! PX8.H1v2X_ Y@@ H^^ IrE@+Iki]wL{&%{ED(̎;VO)XlMQw~ekFcMc4O_yF=7ُAE`j4[E+"I+ߢ*obyMw4~ /?۴8]@VWW4MAG>Aށ̸(s6^f"m,3[FlKy؅z FiI:s 7DA(JG2n#NBM 0t)b>A6ߌT:yٗOzRǽSQMƥXg^69) kX=HOބ<|U4lq7]@suX:Q0 ?E? q6A@R/_i2ai YҲn;HX\^/*9?@i.AI]I&[)U:'3Bqy2MC!WƔ{1&S)wȻ.$A(MEJpcckt F'B^J1> O lvKrXp2f] %]ʞ B;pj- Œ(az$ZZ=}1)%K=$w &[e飍 ܹoh5|#w3{3z1L;o=woyy X9K5w Dp9fC1IrnB0%1a ]q8wK V c#9\t.^b9 >A ҩ]` IB形en' /%.zY ږq`"BL(~@g@NGeMND_.(ybc ֮/Mfͨu>M0VfR^2rKcNk͠t2?]v,61?9la>0.;_Mn<-ڎ#ʁ.awppU_o`M7X?Y\fR9-:y zkUc(_h~FiӒ<xxV ϗ.bN Tv=Q32+6YpAϒ١+F; y3 N|bE^E5GʃM^Ey K`b"*ZTg4bhS:ܝ#PH]K*&a;0 Q`p"@ny }F:nLhFyW~qe 8zqdJؚ'-LaOdWNjS Jm^ʢtaշ/E弔1yp(qY,s2galFw%oRҽHJ;gLFyt"6@ ]ל+Ո>'Cn3JF*F"q'ϬM%ΊB0fQ "4=%iJ ,g60a{{McqRg=~hn4< ԇ|6P- F Uw8b%<8@~85(ص\H ٷ)@ΣCo`n╥8v;H%y1t)l ΫewQr볻2$-Ieq4 ; g'x߻-0`ifr4Xˡ$zpr<]8O}P vMy/1^8˘N,4ZCxՑ  ZuKy .駟#|wkRIcOdqֱ\R5DfZ&[E2M>)6u50ԡW䭂z/.H8(K_9(vkCJiMO2,LaڼW˞f$ RYu4 8@+W.91_`x`hpj&[S߸]aNe<&3 KsXg뗧 ɡx8&a" ̘N7w띘y$$[eQq7omݜt ) S8e!N"Gpԙ`ASuXD* R⧪wI9'cśuj'Qnv|Pt u\4eǒ%;̀ylRœ`փ$& \='F ;;Sfv]ﰸҠz*ѹMߋR^r@Cl6׀3W:\Z*&z,= sWS!JUS/l#P x6LAJqΈ.UlQTkJ1됅fg#qeai3/tYJ*,0(HJ9GN&2[I?qY^fBҋ*RG/z݃){*{6VrfjBT|e+gצ2) 几?>.kٛeڌ7[.Xj9ip#W] " z&PEDXFFrKВ`==6[.P,OΝ4᳍kCWM8vПc>Rt lokckB` ?@8!s=8n:qΝ;\zp,--… 8$rFy'{~7ZFQ, Xu|14ktBf@a5mV0KΣ6b1V!|Թq[qڋ -PQ2u %zgϞ-w č [_0gaQU~l#x @ 0orh^\0NMb29뮻Gދ??Ԫ KKK8vΜ9 o~ЇZ,Q=CKAgq~-@k]BcEt q:[0U5J]Rk0t i$> >ׅu>;f $.55HdD/Pv],D/A^|HJ, cl `z`9tRV{YD8u60LRN 8z(zw~ۼgbX"LL:z'QՖ  Gafqq\B_K8t9b~~vVVVNh4JxK0H M_>\wuyy:63˳O)FZh05O<=[2'l۠i!щؠM'gL?Zd`Mo(eI`ru>LZ?Q`]t,ݼM B#Z\h fnPw%N3@(z\gpkD "lWNb< : ,.l־kLG#X&L- q/ڎBa0YZ¥u8;=)0bii+++8x ~cǎn˗Sz?L5\|Yb6pE|_DzW(Ie~_2G; SohJ!i>D)#|pYbx cY8|:[hqXMlT=PEdd:fgCf]eE 9#p-g]e`Y0 ]>V"DL  (˝ $HeyRDhVs^ )m4C24VPN>/0L {A8pD^!;o+ַg0moD}k{5  3<v>cyy+++8pwߍo~}F#loocuuΝCUU 8*O{߂ﺫ06`=HTHuLDH$~QG0$f D`e -@TQE#STu6n 5e>@@:ixIECR3Xd yTNAp$<(Z3|CQ ZŒH=MSIdY;v sss`p1L?—09,&[Bg׫1XCiaj@ᰇAy,..X\\L8uzۿBcF#lmmauuUU?㌀Q'`sscǎIAL>f-`ph|t9!h ?2v8\N%- zМsz?W re BS { ` JR&B5 u[ %y[;1 H2h!ZͷB(NevFpyb+-ir &IjEN4p.z`/]dw fWplTKhyLچ>x~K.lłSC (KRH m rE:gPn9d։1T͂bUcvf\$|3mscss) koU#A :TU3\Sr Ue0:N "7n~e#G駟N%bkk b:&0^){喛q뭷D0ŊS$68S:aXw$mAIϷ V'K$Y4!/M#>k¾"g<6Jԝ%5fe %`H,f`\+#- BCR+aXBII8啇8/@HL3̧L-#'Ο=SNa4awwWawܑ]UU\t4{up˗}<`0`00o <~J,I젪*XkQ(9N/~K8z0 =Åed rL2HY40yx~$%me ^QU TL-ni ۻ[GyJBji=CňdvKY='-q;9,Z9EnoP19E"uc*iגK.i RwJ}q"_ix簾N{q 7n 10S8Y} 4{/o{weCo<j=c:r0'Pi,aHA@nX8p>(>)_&I %+O| p=n$[NU(HCJt-8T:R@a} 6j:/۔6]̦p9f5./3O6SCL|OoZZG`Sa%R$[ U%' DIb)RJ%T|OE~i駟zaUfYA@c/e) =J/"|;s=@`QWUd{Ɨe>xQDuQx(g @V"ZcʔKQ"ۥD."؝|š'C ׫HLx-_2`0g2nA.1.Wq)xJրNN3pw$H?-S6**, Փo|WtPWq)td=;-7/yF\=Jn|?=oD71pk?_}!-6@lk@: ʢ]!;&="e p(aJY"P~=<>W~W/k@4-߀L&__'(;ʐsy]!b! +|%X4]tN5l[o[~Ne5 $^fDM;p~_@])0UPݔB#Oed&9}٩E 0gZ V6]5Bi(f\UK—^zvu?q}VY~# DT,. ,7?3n?qO2cZIv$|<8K-OB”U}j;sj} ˆ9%2C*YffP3g P*;0P%L ORyej6s,th8Q&3H2^h"u `/>̳R@9|}96*sߑxѻTnů,gYrNf 2 翄G#WIT sOQv>1L0TOus'@roׁ|q\$vOmw`fҤ5wuIӄ%"oVyÄTJVzj(DW#U"ĸY<О 6UxfL E /ܹ ǏG>V)UbHFN]3ep{>1ZXfe0]S^7M4 UOm79إ?T;:X]XSĺ;DZeL0/p.']=P6+1`:MT3(9z#oj 7$;rD^LHuu\G>]U(躸]H{&d|,[~2-?ioΟ?2Y@dP'Np=IgGSyCs+ݫG*)Z;Q΄kbX.i#ӈ?ר*#nw$ Zܑp -Aw\xda-PPJM pF 0ii -Z`6u;τsE>銠ep駟ŋNرctjwee܀Y?]LK jMEYgriZuj\ sRC^8&9LU-v#~#@:Yb;R+>|m-Pfp+[H\&18Q[#FJr7~3^T6'#5zilW(fxOOq̙VAc&Ь,c#|.R,?`/sGĉ/&| AKZKx^eT %׵,T ????k"X,`V >%;zKKK@`gcY67 &|Iq!"3WBuK;rL><%k  ȉv *|f`ލ-1<3F2YYέX(3\69|~q5v f 缦sC *;/.rpD4Wf .yԷNO&~)zn2ՌҘs_O;ħ>kS: RO368}u|od,iFg'OS>^D19JR嘂A~%wP^ON4~e\VdTDm&E)(!jA[1A8Y}%x&KDG)Iqf tr^xE;~&7OTv]nBMޕ,yY-SElᓟ$NJ("nVvۭah2}ma!.N]疠/̨?[3 l$ Yߞ4UrrEcTBida>}PEsN D@QRsYJ=;4KxDXtSLQ +m>.h "\|=ⓟd'ow]J<6~^52Ok-n&|?4m; eV/}+07|Lsj,&q~qjjx K]p[`ۡ0hR5i\R*~=n߭8q¬t5@BNcP.Ps 3ː9v[T so|5M,{= )h[ &H,iuACjk-{yΤNS8p?s?X6^YA Y}פ^גf#>1|+%8 I:.j.ФQpߚ4VLDd1Lhj}2'AϞ=^ݓgŧ?i<#]$0 T+kj$7O|Bq "XM-B&IKi:_.^FiY3uH4*"0p (6% KE6l|_Enʬ\caB-f#$.5{~Dl Seb 48QԊ5-֝A,~$R'Q)%w8%纋NHc <͙d2[VL b Jݯ_-;(pg?_|1Ƀ, `R%|2?y!a .۰tP3~=ĿB=Dr ~L/H>KsSf[k:XS J'X0][:3&PtPT!U/O;MH-v(u5 !/s Y8_k`m: MY/dSpܹ=O9|?C?ځq(ʏI 2 9gy/tbԅQ˲0J]$*BD BTZ:R;UBTtP2 Ys̛2:(έkft[9M"V"wh eMFZO@ Vixϵ^x)m~v_'|dl:na봗YyfPŇ~O?O=R.|2v_p뱸'MVY\fQn4L[FeڄR^Kl  'aR|iiЊ>D]`&@@쓨/w 4iN@^=S[-#rFc %]9j-ԗ $IAV 7*Zj3#b$/?ӎuފٟp8lx:Z7Va笍? +Ȕ~yyG/d++KyNٳO=}: Z.W "1iZPy 8TBS> #dz'ͤC$'سė_UC36|JB ]!A 4Ԣmg_jQbJP&\p&P[BEmy $ydpK %TJ5HT WԫaggwOUUiu],^䠮`r5@q/&̤Jq4x{ރ{7)UUJb_-Z|.\A%̢o`*1+~LzX|Xuk!P!2 bLF&?/.e *gс⸦3$Ş絀pЈA n "r@T8h˲*Y@3 W?IwY0DZYHʴDL2+벯j7u{G\6,绫wK裏_TZr4ᨆ񄪪T>[[[7?=n cIP{Fdȃw&t g P6,ڿ^('D},'Kt~aCphOQxANL+=b)jdnd!R&_,Q[?Mopu 9sc4?8p@Z o4֯щ6 W0+ 5>/IG4$@l΢ ˯X.|$Nr2]L'8}sZM8J!̔ S[ô3v X*K2bvl |Kyƅ KqZjGTUvI>DAs72+ +UVHY/jxh<>OxG+]oo~"u:⮻菦n/bNܮ}/~2~uK,`:[D G8??, nRq%< !S'Jc S.Ao~k-l0 7+y1k^V ;TbĆ-ۀ8/L簨g|PU~l&x\6  MqGY gwSܣ)Du>}:䏟g"LAbT14WUߙ \xZpӁ.yUK:?9hR18,QZI&&DrKQ8K dfߔȶQVqSY{~~KKK3E8JJ9q,hqTjp8?W^y%":W+\;y?~姁S}_lmP̀cyBq̀#8vag! n,8<탞BVI")jQKMɋ+R a`cr[/dK!B3Xet:_W2]j̿߉R`/,J^ߏG18tPʎ@Y 2`2^t2Ii/:=/y*b1$=pޅҏ3aOѠaXȂG<' 74Rt&v*#l+چ 7yШ0Cd ID1("G^T9pk7ҩ'M7>caaa&_{eWc] #^ "}eeo{0S8x >E ֌,00[;{WzPi9+̞$) l/@AB*d#b[Y38d wثY&|@knĄf &D5A`BSem"RQ0(+fC9HyfZRLD8&IpM7o}_ {#;{e!sSbaaG á2&1t0Opԯ2UcY-{RuÌ$nDuj݁ {I(.m7x s0د(tXt?1mv1MVR%O3)(M4pIQKZU/D*OLZoB 81κ^+6a։0B8ND|R:www1LR0cD|W= ow3@ҬaWV"'NĉFI)9r @ 09{k! KgGcjAӥlyZTi°wBXw,A45Y6!}E0$;4_+{jE:}̤MA<֭˪/Z]6 ĜL#~U,"Ҵf:Ŵi4SKXumomҥ8߿';f]X@y_ l3 R-y zWr P xo pcQ-4q!;p07Cu| `77N3Sߗm2?%LKlC`őViS{ąfw:+ϿH ,XY[]SOpXn7pÞ_ƦN}qĉt777f| ]XYMp%S.}Xk +uqp5ĵFefK(dفNAK@}x0;IXzm@޸B^0gsF,#oYVufK eFvKԅˋ@r^)mNkyG>|+++-;VI'NH@;;;X]]M4:zY@;6h;n)"#Hs޷`qn SLٕպ!:a#S RZ\CN_u8̞[N|;x.XQL\bۙ$ݟph&?mlni:OԻV\J,b]+KY9`u]J:SIϝQR@Ӧ6׈ Z\ChE9pIb)j|(i3ŗd! (UrXZu!+ا(h}U^z6=P#, IBJ_tċZЃA]W APp,uta [[[X[[CWC@{m-(@ww<:_)sy\BBS D 1J61Hn071Ŀz#+k6Jˍ+"ʊvww4MSuIw2L&k37?R4*#ՃNl2NMj#tM*Z$]CyTFBP k"i.{p`Z܈ԙSB & 8 U.0NM2R|,#_׉3*73]5fN|T3by@خRf`w rٓ)7!p+ e9h5y1*dMd堥vAJ_a=.}%G$fA9O,Wҵڃg[2DvC9p@u0mc[OƽnƏ  Qb2 ~0)rV CgN?m1Jˬ ejQu8%j, D0~Q/O)NU~v$R@vqB;g9]Bfz ?v^0!C7٨ cn1!kzg<0`w ߸ iHUD6T9ŕܪ71؟e;NC.xq ˛uJenTi1kRf('@|dXF z{ /j*(daHJTB^ "T 0|2 ĈC)e1@y;Q lk^Q>!q,XUUUKpC^n{ҡ/$ M1$46 @$LE;m.3]W ]Z6kW M_nRY_E䉏4k97bVWkbQ2 63_3)(ȓLU$K*U% ]##L3i+FJly1H(eWbXA(o?N)0Di&6 E?֯AR]HQ# F_֢Om0) Z_֜^AkwmRD z87@=)ɝX uYqB0pQ;heZm0 6 gQD-[C菷g]X .; \og(7dLoXouZ';%߬)2"GXhDs;.b[9~fV)lY6r}3;Pe' %dxM0S1>ϾTSWZ.m0dgh6Y>y,S&NC=%oP' 2^ N1@lY$ B &ރ"! Hjd'r@(Yuc*2Rt fOŽZpz񿪪18w֒e 'N3 -%٤QcY:{#ucS@$˗/o;TUxUuk=`<˸x R<ヿ+}"1䦔.d=}ݢ稒$炙'S*ل NDp.Ůp趛<.Y*7M@I'sld_q`!Q2K;=LpI&-,{2݋Ds0BN,1[_KW)%!˥ͩLM!Z{pIͿM mc<??娵Xksssp7bkk $eD!MS݉a .XBi?eY9:n9gIllkZ_qdG7@*P% Cx%8p)YU^5.TR͜ BA~]4 t df$4^ݥ "(o0q]Y'~Ou> >o]f;I$PN]+a*05R [y#7pнS_ &h` ΃Xxu7r8wΟn "׀ͬVd͒N,XgX0;CƻX[[vvw0  i%@K#ї!f ̌+QU99N ȃh[)"Qt:Db: s\R-zIB_ ?$6xH&2v Onɒ>qؚ19K6s Wr !{|bxi/}f"(:[2^Ž+W/dqvwwc RaGvϢʀ}~@YdYwuLS^nz-o"cnV7NW-?\Yo`ڰRl@7hxz>P}5VVS%+Z)^ʩ+E%ظNƥW]U4qGAE\X!=lJoY( nI"$ݴɕi914M("ݤXlWR?//`* d#DvΣq/^B3`eex">㻿q 7U?_WrN\kث/?x96@\7VxCA\XS\cuڶcbõ|{a04s[:|si"-IZߣK#/=JH^j:آH~x᩸``Pt+q ZC~ kʞZ` K7(''rS&!tM3݁JB˓Zړ|27e5L048: p , $gY7!!73x !ʀjSEzTL;ϣ Էc:w^L>R^rLLjo" %<o ="Xt\(eۋ![3O<pR&e n{yk/'()h1ä(Zb1+bJޞa R$!Y#&|"DdyE755 by v Tfư?`1dz9/xceٳg?|#[gڃ뱗0b: #7}P x c7AնxXe BRHUjԗ1~37vd•AjLlΚ+/Oe6c, An vcS8_FD 0 {^u.Kl) ! 3I 7adVC00Ҩsbb:$x.+(LR;\zӴjPU=io8 X6؝84Lٖ}3i')#b),I_>mhUU%썡ܚO$yJD1$ɇŸd#(>xzL3 H2=F<`pC13w/ p_w9=-J7^~MS4)zORq~ 8?>O}Lr,#nt `A ;)U虗AadI ޼'9sKT"l bJ! 6mLmC(pS 26 (3sm|^=sm\x$xmi^0PP 6qEy0EMq6m-1L_iJKqi$z'aۧЛ_&pP97ZLv.C7}{k">N>>O{A kVЏ ,e2jvڼ@/9rW£@pUkw1^@>NQ'@h2% v t.e(Qa„`LS$^Qر y@S߂w} ?暽QHڮX-(96H r iFI)VLCk;)栧ƘSi$ͷ[_%.#$(b`@59F՛{K!7դio3ϴ6짗]r[WK$ʮ6ͯ7~0|=7Sm:1JCPꅯ{:|U+d&U[{(<>{k 3y)D"%"ɲ۲ȑ㴻[?__Wgv;d˚lKd("A 3 (Tjus?[ZPBս眽70dHdQ Y[y7w _GRhƆ:xZ7ΡdGژL dzcy~C7[wXX݉!ʮkvF;9f 0-sLk?d8t8TBa8Z '@s)-.MM@l16]~ZRMz=(pY^ybPm'_y;!;y.Gm&-UUXאsrxBI566$|fHChY1f֡YqHǎؑ)%NHc!(OPA $Ga[1_-TJcz'r3㻓+M}w:28 qvuXN0G{fA ۘj=z } o"(7T\.L&1bo77 BჰU5&bΩus;ld 쁻ɟޜpR'DaTdZywc(:^KлXkDwp%,t_#\xϞSJ}Vg",#`Kb}Rx~jm-U\O,.2^tt{N^#HQ .3)Z)2 D{٠3d@GnS_›OA*|9>>8߉;p9јUx)$i|?ZM -P8DJtyT p=J+.1}[$aDr4,#EimM=U$`Ua hC~m}z"rMXZZii mHBl9 J aT%k1ۜ`vH\Ζp9J@9$rB AZou7[8;mމ1٠J80+` n1tő|#QQj=~ %xx55xǿӿBlaL }lcO^9HȠ0}[U7r'F0Il)‘O_DXӬ9|֞ QBy*; d)s(Аip`EޅG߃v8yfM&cӏ(*Ae")7bJnc m jQVfKO^Νy#~?~R%"TO:yNj?>MUQ B`eRmٟ> IHȃZhLWho4ˍ]4`r&yHI_뮧̵qjO0$ܲɌ]=p u j):GT, B9$ʍlNid2W[‘Id=sB1w*Z (C0[ f, ]x*L`!k,.=s+1? fC=|MlTN2t7>Mr?VRt &}f|(s )+Wk{dcKŸ^#: '-%9RZI:@-'Ù&OdYnfan= ެQZRVCt[ :{QL8 #C6dX}v"vR\# Y\U|q*T({ }$B̙3]qmV6w:';yc?s3?@d%cQ Or_ة/& o 5{8{ !f]9uv4adFmC;{s0\Hi6 7.'aJvb/㑇6|8ťwdD΢ߟ鰱JNU]J wՖN)D_ @Drp|^bT9Xy>;2)W96ķt5@L53 5!+U[gzUIn&;v _;;hۨzM`oҸO}mSum+CֱnwZz4 tt@`GZőIL{7YgE֌1Ch-'jUɖz$[9KL Emy&QŵWqg>H+ ~`9WUH2)Pم};AF)]Mu_!GjHtfC2a^'|I)A@ F[x~=\LX/"qȑ^J"ʮkD;wj?}N|im'{o w>xě \jkUaS =&s8-s ;aRXH:<%؏&` {!BL^̀ukGFFTaIGI)[x~[=:uDŵV uRS9D{ƒ L =b=$'[G4P|UZSʤ&ڌʴ-KTiK%2t vPh <}t Gz4,KIWR5["fv>)yci'l|Ӏȣp6Pރ>%1& >##<_XMvui7G WFjz~wk֠U ;ud0i] neCcږ:F/d]PƩj@A PP 9^.i8 b3=}b ("rZGvRQˍY=܃('^l/o|W4O6!^UU'ǎa#׃v626SD0U f?É1_[dYVű֐BvyHܫȜW j6Yk7(3ʁFٙǣ?/?. _k؃Rɲ3'Ex ی">3T$qЎ *o fya5?Bb84b0\a l5"."1=5iet:Hvh'Im( t«&ڦ8Rec 5GyJ춞sځ)}3ߏU15 V2(,MRaڃ paaŤ9|cԔ??N-NwMM۱,3ॗ^F097priB+m4qJW:wZan|g܇<57H 7鄣bo‰yd‰\E*GXU(5O'{ ͏c1?ҍ@ Wr0tcGnknB=([ϸHI pDNxȱC7 3ɆO=? ۴wAٳ3c&;qvN2??apygϼ{nw`n1g Ƨ9+5}_k7x?=AwNIXLcƏ sT5Lc Pj0PB,CAUTJIJclŌyv_!Y(%y%P j7@yk8}mn1 h(r)t7$ K[+c' a7A !Z:bxQUx|<`LxO1&7SdS @kA~ ϯ^» N'YCw/- 8z(*lNjieԏC@X Q7"TC`4 pF6 @d^tshS]8c7cs&dۖE\Qhe`Z_E9NZnHωw9Yg讙'F& =(+_83e^`BeVo2,hJM0@ 8pc%VKm<އII\ g<rb~qHkXZZٳgpc@RJ;@UCʗ,G@9F0AGYG<.,RqhS\.P?VJA;'[!(UVEN6?#@p2_HL{f\)h)xL;8xC׃ Zum07\l5 7] ʼn1;Ht MH{ӄ 1˖;hv}N7*7D@Z</nYॷV_^^ŋeO3k03B`0K w; !g چl:^L6ڦeǠrhA!a4$ nq۷,G T]FQ, 6}(v}.)ؑNoZUuJKӸu-YWefH㦛oA{{>t]xn=L>  Cu ~Ⱦ7ސ b<(u ! _iT @KoA]_1tW WD\FT!2DULr <{wܷw*:L1T|PfuJ)̵oxȎU7?1J`FO-!Ti92'hDr'P~5 YWPȐ;n ǾKh%Zy+/Lk\ C:79l..&ٴ2rv=Օe\ZY : &?0l}'27v"YMK'iZw"l݁H|Y% 1ZN !XD6UP^w|gmbU0/F4M8$r܀Pflcc=Ɖ5-I1aW/G8jҘ}cR\6pͯ"f/d YJrHW:wcOAߌ%dUAdQU ΓQOΞw`YCZ3g Tں24)H/'M[x~ ݑBw}k&61H"f4v0eR9!9qU\L~Zz v H9`gO&uzln 0B nYWZMb%q leDpe-?vV'4Tk+Jl~UДkz'fC򲴾ƺKf$MPLvEtر[uµKҰ,ZЪDxFIvl4$'E9sۿkl* wFM*`^fsV$$9pc#Ykʇ CU[ ԰Abg1 Mp;hI/@?̜) rͳgq[k~Z!\ \M+8 -z2_~I{ke}PUiX~*oN}Q(`H4#C9t[3LD <%7%D) m{8($K^G L@Vqs( w:>{j8ː1Ȧ릑/Nr<4a $IE߽bOumnm!wWDy v IʰU Rb[Ł6I'MZwr! \O`wJ)c2%ǨMl{dsO.~xI݅G{85 | L۔KV't0j,Q&@xеfԶ2S:coPo;n+6T+ר$ ?κ0 k0Kgv1Q!S7O/WBȦ5 ſG[ 9*,FN _ `5.#M|4P)詬.f[myn_5 8jŘm32.M흹n$LPi|q4vdO.0*%ӣwc`B q!- lUFe# ,P~n:mwE83dH q'kڸٙl x9*#|++`mcI0OuYPlO|h'޴X}W5t s]4^Mw^{ iO> X0d\}c06x`K (v(8*oZ9XUz..>J6,1]3scI%!!Ikў禍P~U ?\ߍo^L QAWdƁ Wsj^0P. +c~YZT/ݏ76f!3,hw޶st) cv|V C C 3sb'sfuA3RJ(Xk1U7JJBA)h)k?G(Ξ;} TצEi~L̀Y`\KW0Y{,U$)t* dy)Ƣ>n67b'dm/r׬S  kP*r( &LIVͅ)oN~:Ï6g{qq8ˏD&$*6"v1& HojIZs"dio 8z(D14,o|-[vs LpT"A! q[sTDBJESQz!NBnCg8Z3h֐4w2Z2HSGAWz~ti76@kٙiLu:hZY&9m5c.I 9g4ShK6L o>?v _ x)U/W-y4dKHa*$!d^f+dye&!YZҩPW[z,d/B@)Fm+D]x~U@;ˁ ;H Ʉ3@t@+xQkL,Zkh(SG.EgS.(dr!#+ (;掠9:肺Y{ sk/b6:-"YDC;L6zkUM8:WÚ؏0;;N>'đ"ʠCSmMRzmAeA'i^RC6 yl[$Aw PWvr4"*B2Sxccq&ɝf9,Gj(rdyVvWȲ>AKCFt#do >sp4ˤ7ܑy| ڑb_6@WR6"-WS\j翦";e3)PY7HV~n m3;5w+> u^1;<iOcՀDT0qnEf%oEx_߸^eԔ-30RԣR2517HBc_ºX-qu&CLs|Z& >$J°$*3NaiBa<ϑ,0}Qv00@f7 YT2˼G$ Մ[SuPFe^*lq8L$!u N3b >qwmtq'O k LO`3{U'VXҼYV-z4ydAnIyىS"Ȣ>) =ߛ퍀2)TX>11vo rv#Pųf;hٍYزߔ2A%g1{r9b-$0s)|-۶x8K8k"p޿CJT 5PV4'RI 㙵iilZ[9,V(* "/ -9QS߶Q+ l% ,ǟ, XXQZ:!=D])퐄ֵa2`YyjHAusJfHN&`Ta8Z_U *4ь-B6ɺ,jl5ԑYkegŸ$H桶\r 6וuXj;X¥A+A!=H3j]bu:ő@a*KaO(M֍5̵`h2ei͔PP*MEGg2# u/yi_ƭ|h YKcrFSxuc 6:q {޾BaV@hyP/' 0ߙud I K5T e#$"p T7}-bo,GƊR(KZWߔwΦwO}}}'6pk\Q#(X"X Jc$ѰfoUAնgMS1II*M8H&A"g;נ(}ZDSuLƁr  ȭ._ElJI5 P9ԻCP/-mOLdZEI9ZT 2]RA┕_ -J29׍R}Ri{w`=:ioٍ8u`su3a:Z.2jc,cfAbw >CQ?f)m^pB@Z~k 0QXgk J2F ̔O9G`MP#FTJLj&A+{=TQ (]6jVV T_ܱ840+*CUצ̯+(0;^}Pμ%r?]9ppp_cdN5^9r(y2S )[Y3KS%A-?0 GǛSB- \l,3Y!c쪵o\d/=JXR5$’e&Sbc0rYKڎψ ) )@1-P,7 ݸȈw–'S[WQWM4XUpF'Sr532)!ƁmFZ Z`D 󰇀.W+/^Ο>O1$|O (+1 0&)致 (ZS6ζPTr݀/H]Y s<2 /`GS?d%fFp%@(3$^N 6V8n'mzrMht Fjb.cj:KwnZG4̐BQjw07[,}kٻO-dic9:vaEߟA{¸4EU BuslW:vl0UUcPVa@HوzPQCN 1 tb~n[x+R/ iܪRQ(H&!3gw,cN֙ǫ iP e9>$Bk{1NIP#RD>KHKqo[&F?.3+˻`";90MLN`$sL2kdcR8p2M@PA DL. =Vڧt6G> J$@*$UUAĬ M|(q50ϖ&uXH)ɷ.d7=ZH+? # YKc yBbr(fj"[>4: 5+۩3<ӿs76ӿ.?ߪXY=&ߴɡ2.,s+(Y aU؄TupJ(tDkL7!ҀBа-8cc هǗ;+3IMN_?N+'ly/" bf d*ż~G[ ?߇@#hx0kT[/N]Ɛ9`ks&#"W!0 APg$L<ۉ\NPMD*Akhkmu+ #j`@*H{FBP)8fo8@@paiXɈlTzE몜2\ !vq`;$!^|uHif0u]+lv BUWrX @1j=U–ʆP[[m,9:*~n&guH,}bOzÆXۓJ |{/J [ڃi Jޮ6V9"sA)-l 20ȤJYv#/lb蓂,@ ތ2SٞΙlq"7i3﷛l7aʫYkK6cJ W=ƹZB $[f#llm5 SQR6 .467q1l]dY+ ;nc@F'S4~ ! FCY՚}5غ*m?02:B9kԪ6Ȫzȫ݄98! nB䦠 Z( ۗc3%L17* P$CB'.kQ9IE?!]۟g$kf̀N >S][P5Vi,NEn HBB]k[m'RXY۟eubL[l9rR5@j)2c l/`衬?;*83H+UAX֮@$P\6:t{aYEr3ѡV P8gFB2紑bkmAdk5B`fjuOvxG`y@╣{߇Q9 MA !!Fؾᰏ* 4H)je^2|m wM̬@җ2,$*"YpmN̦EN gY(oge,--K0 p]OZ/NX OBBdXo} }2r`Ojw-`\VCTu)$Ќ 8oU.Zʜ *.3LBr($iPK6, H=+1Eeo;Y#҃NdHf`mj5$cPU/I6 FV uUAf9:z>DޫـcZH]Ъ24Di7kWg@$Rw}n+qZ Sa .8ȟlMjܘjVo,pfgq`~up@+ː V2˓ѭz8ɓgp Һ@O\[nqpLXz߅{ 9y V KP-j+&f-< 'M7{-l ڄvw ~ϔueBHZB gV|aNJ:=jQ0qE%(=SKJp"A&> d]aAUXܵ5CqcK+KxɼT+! 'qO0' ҚOH+wm}ʜDx#Q~jjd%YpsF~ZC9RkƑR*Ȥb 27U+"3cIz"3C.2SI mem욛Zo;SΡ֌vvN #G vS6U =Mz BImmcVAsgOchg?K=ŗ^G!D1oV@5AB̎P5 3PIs~vݙ$)gYr?2gt,VVz1Tm/fk7fhҡehdbd"Vƺ!0 a<kt:T!0tPKFˈ0D"3\d5̔r,Gdar@@ն=CFSSӐҗR% ƛ3Նi6 XwE$RL,䠽ȍl٪ŐujUt{ ¨zVkdO%gl+0B)&kI8T6Vcu} j)3Ls"/,F$8uҼO)2cE.KxP !ޑ)(̅9y5z~꓿}1羋V‘ө645l=wAsjA,Vc,gJNniDBF x?_qnL j81 =Ge_ id>JG#}pT2{S 3XUɠ"쁣6a:(?Iel#DٷH:NkOusgAu'>Q{F=fd zG#=3d6=hb0P0RoMb%kJj6& =V啵?}0o[Ƨ9XZ2'8uem*{m #(2$Y,/ǵݲ5~W~/|kh F0ZӟxeU㉧é1;u-^@k-%:V&D<=K[/~ {æ$#?ND+.)?Ͱ#@|)bƞ~lCCY3XQ;ɬWZqb*9@_yo_` T'9q4ٙދյw0q׻ꗿ\ t1id?z/cu%A͉V~.dfw<*}#z"W[ h9Jl H3B|  ̞ 5N8ozAVS: ZGϖSPs:u2X,pd!mm[`#ե!06VKYbX6vk:!Js4ol_[\wM2MEƒȁXFJOvDU>^vnDكRFS0`6Ցym~,,JX#hyz`ƙV&"Ka'IIQO>-(Q`c}N u =@I./sXѱXIWGBJAL"h*PDž&daPPo%67Oacg hD9bq }v|\XE\8 B6*g0$> ̢K&OtY2E7шYxn*eyŢ# Z}=lR#072m\8\kPQ"1 +`|~qZ 9zCGx:_{FZ CbeMMMBxVdV~or %\}&Ix|PyBz$QV{“/8 :"9.t}Ÿ"YPP݁` ␖79L1X[(7&C R!TX!Z]U( ׿co<"Kb#E_£}._+lu{d0%}?QY㙧qa"v`yyAus(~/} g~ _ xÏoTgʔjP(W͒gruwz!(8$ڂ_O$DCG@$ph,? ,y^g)InHDoN!mUO9p"yI|䱟 i<: }˚ԌLFG3q7+w q"Hڮo(ɘ;D1;UJkH{j ok=t׷ Xdn(l7aD-<4Zn;‡~#.+_*zbaԠ8Xט^8MX6a?WQ?t!"I:ВSغӗ^ÛO㎛oĻnp?s(Ȑifq|@3rel 9r0Xk(76r#Y! JۀL6h2~%3.k$`gm $#{ꫤMKKdv<#S ZMa8l0eY7 k"3g 4W8ť Ro7{^dE9s'gl!BJv\_6s SDu5B]W !O"(ؙ38v"=u{veUAյq*.Aܯchr6(jg1ΖAI.3Ds6F]hKxx8qvjTL;$|tT䯐ZMcB ϡ3u?^+/.^ݽxsvzI8_ -IܑxCDBI20AXV\a*/0;;3m13;Nev4r 0 h)\1d*̂R>0IN+ 3il G "fMw:账1kQV Gn~u< ):魝Ab#ۏ{aPb%FάՆx11<6› U)K \MWJ{lAZ54ڸp]w}u1߈}&DeU)G\f hHatU= hu dH.Q LrPVehAVַx~60j@֑R[\R^dD;C5rY@t1z\3S!;x ZvGj$IkJ7q^Z/rRLu  u;;atmx15C]4@UC JF{24V]By/yhMϠ5;5(jqG"ʺ:CMA Qnl? 4ϢF0aU5@:#vzXeݨB](ۚޖUBv#va $PWVzvxګGQ.RjۆhOfwrӋjhC2h#ҌG Q +Fۂ+k.K)Q3CU_Ȼ9 pbb(Kˢފ߆74zf_׌Ŀ,2% Esձ07"N 7^)RFf.g6sS@+7tK( ŨFai6RژD9p(=7 97.|+LoC= ,P FW둋'"?듌 YK5//Uo']R #tAl@=Q*֩mS ?<[ydHCSqsk0gЬ0UE@CqVm6ᨄ@Yh+vX( L*0*`@&@̢wsRyD@KN]'u$F im٢z=Б k7Iyq5>1D h^ŵNH83+Dws̏NJp=hTb4XTؤ9my /!D+38CXanDqwBko+48yXX@]@4cZ ngX}$,\GnQv4-~@*T@!wFmϜ jqlKg?PlBLCҿW P㤬شiE@X(EIhR&J!"^.QbLdgd’aו|+=-6ٸ WcΧK3 ׇQUU.v <ŀ>t5jFjH 0JTJ@df l8揠rzToEN!0EG@𱧶,̴"c'hD5Qa4Bx|1 }I-F 186kǜԙ[!mz23/׆kv ZeG$ lp@ dTm*S#Fp*7(@$GΤ#v@ _X؎'ÑP}jh:MI5O~'F ݗJ!N[舭ߤ1/--8IA$(JY\4ژ8 2U[lAJȠG`1w^P0g?zK vR_[v+0 n~jTߥKx|)ӢQ_>A1Mj۬}6<:;SgCu~K`H~V{ b@!U[Ab^ t;dυ{i C1En{Qu7(fݏ7AL4U&+NiM\~>< &,zmp$?0Fֈ600IWrF硕eGB$1"2ߍ6yЭo[]wgęA֐#)R,ngqPp| 7p{0{/}+gm  ^J*8ޑD J8TyEɘy(kW#}"xiٿ\sH4ųBu HlzuN{ 灷*$.U:1Iڋ 5Z3c=m DFdQL!oϠm(k#GT Q\!oϢn˞  ;4Ea ڷo/ƿh)x&&3w}株pꮀU6Xd'waAڿnc3> ٽX_~a=co U|R?B)?S]]c(9}`JX %v%vB~,y:ޔ"ԗ#80r)BLFY xQE(]c Ŝu&?$rI!((mq#3ozo>aV?xOcP۽JG~WO"Dg+/⁏}쯠WV}aMXa||{nKNl֡1>l> x߽ (k^x^[/o/1G)<.2dW'2ރڹMƹ F+ƱCA+8ryۗ,4ʖ_ 57JvÄH1R̙%SBK^ D܎1O:9F8x1V K1֥#^DcpGWըZk$.{V)Uʫ,<ُ i?2-yz+(Μ]!OGyw}nKIT@.>ANc~cXx|C8|pۃ KKx-7CpY[n_'gt|ċ5c-7cXN9]鿫 ȝ4lN4kd+3 :y5>#ūO}\R>'F&jKWK@u 9-y9#. dGA(<^a%;:x¦ S$,@GUPc cFdt{x-5'ޢQlm5S3Zjù7Ż>46Ν9_b} '/o[x_үᶛo'NoEwq_WGxџ^,_Zp׻?1llm+Ab7a|k~+v<( 3ȩy9 4|SIow :677{wau׺`embwf5N 4>H<>)h<@dߞH2D*EY:5gaf^ИӘUd#*}3E @RoL=4-4A}&ӋaUӄ$Kjf 2¾GQ){bffߏCصk7$~ cϞv-]Xط{B+ؽk o75ϏO OO/ɄZ(s=Y&w.A?W1{Ξ|&+{bIտ::O@3ΎW$x)83}5a^OdM~4~HJ鷽ܨ'Wg4q|jW4&Pc`l ab\#&@l bG_ ^|%l^Z“{oϾÇs㖛ns?m߁'?߃ x ^xy0Ib9T Ȧvx ¾4ŌX5ikW&c]d?&L8E[{5fcŸ':5z:Ah_ 8įOz bq7anUa iGW48wc?w'^ {3OiOdH̫/.!$T]{,DU]|6gK@2oAוG}Y>nLlDEσGV%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_32x32.png000066400000000000000000000050641403012130000165650ustar00rootroot00000000000000PNG  IHDR szzgAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk> 6IDATXUm\Uyݵwح7&fhd4@*!;j J@jLQ'[&qqqz_gv^9|wf#sg{sy~7מl/c0U0Dr1Xf9?D(6&gpsvעVs7|qw #I7o=\_a.f 04eeqOZGiQ ;\!m29>Ʒ_<Ư=J)h33ɲ4MًH* W\a}?~;P5А9Y!'3:-JD;3AO0 " ʵqw?I^}UnܸA$?|=y7*fJehYaY6|bmH)(yG/r ^8A'fuu@K@ CY"D8ٱv\RԪ:`v)3>>A0 瞣ltCR:s8o1Om" PUD, A۷?c._:GWU5%hؖxAX/=wDY[Xu 0 Cȳ5.W戻X^[n7f}"wHF vkiUqmv{}S뿟M!^@LYV]-[IqqA[Fdf]_^|K3i ]ڵ tJ:+TUh ~2Z-8vLO}{g=Ο?;-s頁ՠ0xy 1s.z8ٱALNNrWyWx78p_8|qsdmZa«/4 BdY /ӧ9<Y'pzmp"m ү=SѣGVTU$!I(b||9>CΞ{,jð4p||ĶܧnXرc j5(bnn)}67 R0Є GbK`n޼E$ Y"%2s,--9!1ՒS-Křb~) wi;e` ޭ4nF;TJmVԣTP: +f #7?Oerr<nYm^<ģ<3Qoc6QΑeo)[{22Jdh3OO?n!Inf/xv<"ݶa;L5Z;]#z`7%b ̄$2Ҁ kkk\t[gm*̐fW)_ "Co?RTs\1RZb\#SW>⭷wK~r<&oB.rL6fb/nC',"ĐЃPu7ϯ~DyZ,shhNa9ӤjV*Ua8P tY[Ow# <C)߳A=Z%dvܵqNYC@+&-JR@{tFfom ] L~jR~N_'k8' yВ 8"Aea W;ѝϐ&Ly|'8'EpBαqo'v1Fԡ7x84%DQ;G\qs5wΐuS f{(ʳ#;'ix"geℨA"2'U+qY~x?15(lFG1`0&EMN/_'-Ί>!GKou&c-<)!R[-4Ar4(jL2@%|DPIӌVF6}-rq4x˿Ovgx[V9:Up±a8V,(Sαrc>O~ Z˕%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_36x36.png000066400000000000000000000060311403012130000165700ustar00rootroot00000000000000PNG  IHDR$$gAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk> IDATX][l\y3].%ry%dvŖ Kv/,E> /m})y("@RC m]QbIzGŢDI${=g9 ݳ3oY}oɣ34 ĴkAR  hL t/RA!^9 74pR!055'4XA/BcL|vworZF:2؄ޡQBFT6ָddh_9*34(eрMBX$-T(B# kBeQ}zF,(,&nbE+XЬUp?sy:Ŧ6y$<_|j c,1 ˯}c_9HOO/QaE)Ab/Z5HXN kZzyZm:<̅nk&C{6@EUk5j5E>D\aiEc֒8nRl?= !-(1n5JAZm| )NljwriJ{ b-$c$&!E(Bhܹ˭[%VF[.JDPZ5[v?{܎*ݠ '6$Z:O&@+`W:Қ Z;9 ?X ݉m:bDmC{aqq=c=tvQuAtxL"RvZO4aF)m^ytbaبmM1Y`QJ-Tskxo?ZfXy<h86Z5Ṗm'JV@q$U]vh1(?dre{Y\ZZg:0Vޘo#ã}!]X7n3K)) |15>?Fۜ{O'N1η29sZ(:dߦgi2-/z u*… GCw|r|KKۿ_:x{6!8s3~ۊ^%EΝ;ǻ'O20O@Aɓ'9}4 w3Ş ((e:a&N1#6XI XZq3gϲkn~m<}}}1<<֚i{=(JQ7:PZ}CJ(j m ^a~wԩS   |k-otuu?TyS3q DDF:FX4M^x3J \.GEE>4KKK\vz;][iФo8).ˬ9tȅt (uNk tHDiOnߥe%c*[OI 0^\Wè3z Xu(Lk`>}]ίQ 8+V̐);#(on6s8P ivf#lMPuw z&$"q2o慠5 YXam!BhҚaw9yiPQaLwf5CKr9nJO<솸KTjQORuRm] ۺ cK{JsEb\A:NkoG'6!vc0*3E=؅Z32rwA:$`[`norS>BMlooD!l161-u\.pרKkg6ke}AOQVG'[ p)̧!Z aaw"RI ngEUVEϮ095No "Р,q/ ] sk+N/Lgglckwp Q~&qI$`b\ 7Uv6WHH${((gW7{OmP9>TkW|P)>w_z{:wtwMs 10yG7>Hs%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_384x384.png000066400000000000000000005014051403012130000167510ustar00rootroot00000000000000PNG  IHDRǵgAMA a cHRMz&u0`:pQ<bKGDIDATxieq~9M9Ueͨ @aI8 BDIEJ4e%I\Kݽ۽lT˭ڦ-і-eI(I$fb Pj̗޻رVb%*3{{ןWx /p}*_uf3#P@ i93C `D`>Dfs(w_ä ~j=zx1y/Dz1-^&h֋n~X".}[~o!ݛ˵G^%S>VYj^9kg".9Yپ$yGqA>זo _Dmv 9?#u?-|Lɝg9iӞ04>SR=--Ǡ1/7߉^//>p3o{,v! 69~NKK=58quNOg._M{ˋ3A|n,!ԇt֛-7ͳ?Ͱ}_~zcAK"`U# pm4rn vN)Ś'p.~pyHQ0]`pNr8m9Inn&%uw6?32To,(sC M+>z;v?*7) B ()qT=ʍg?$]s}nsʃ\9뒚B(pv=:"ԟeWEn|y [~n2;.:U^;n79??{wCMVHvI|9e3G1*_5s2r)CxW zBABs1zX#A8D)85Iʒ3ϔO`)U"b~}!  3@*ݡTwNO|mqA,Pv@B,glwS>Q[4%.ql;Dp^8@\+d\(+! 3nsoMmCs=CMu7vG rx o9 a/%&e/hݯEj17ڵc-wM-8y>wI}GP.nmv)ITO Fvm ,gS*~=Wn~t&P}7"gu/ΞG/7-ގ_)ϣ$z5.Bvf`: ΃zNnH`2B_jWbhaU<+$Jא$q}L:Dhh rl.5UZ}?&6ҤMs 9rAؿpwr&Aw58A<ס;u T>gq<! v둛6mguj PϹn^R\c+{IJz緜ck_ EW Dxݜ[&M3vd:xJH`:H(+&r#bV^P7Exߙ[WH݊_<~+x\8D#^Ʒ]N\_'1(efY7fy0,A%g0lSdBD3(k@VvcZfXn.rǩB18Pk"nK/IPtL=w| ؝?fG< +\p7ȵӊN^C9/rA}]CϿoN~Ma9 9 tP. ]rǥ!/pgBm(]%L3(Fpbw7zU1|$Bc%U3}q­-:A AaY-1`oXo>'a8 !^J$tr m6'幫BsS6S+Y=߉3{K˛?KyQBFŧJU79Vj˫A8\(؝fE:\i8Bd8Ir4qd!DKM!y {jBVwjYRUV'.^P?5cp9:Ld#MgI,cddh``- tpc99`Vb 0XjIzϮjGmCsKݳ*׉%I{w %{#~pS`"%~ Yy Y+ʨ;+) ea@(֬ ;Q,Q :\} kbvxݠA= ZytYb gqEu9Z܁@<*Pbqh=_k|w~ېבhݼR=̚'aw{xbokS13ʢ^Ns9r GYA [(]Q>%ֆPބц2 ]g=@b$pn8BаA3r 得5pr.irɳ0J"89K91Fe^ Ƨ3qi.L$=ZHw\rı\w6d)$jDm rt_K R-y#dLTX>&=U e)nȮ_ւAA +@QVnM <(}_r#th=eTj R vv BZ1Hᕾȵ w ;t$6ι^ch;ɑsSeVu߆<З?Έ/^ě]rx_gzC>%𼮴OA5g4]+4Q߀U$<~*}/6X@~0[t,V9eq|:3ӷ9[Y_mY"-Y< R36\Q2mV'WB_Z*e0fUR&+4:3,j5nf Ca)PzNb> uy̛J. >N:r6p`n-DDM]-1Zu#aYJksvةvD,] ]q)bJujkg@) &}so<2j_7`Ub NǝCI%k #2aY2EW K2{(ϮilV#ϒ]/ "^#7㟼/%oBBDO_OjI A>64Zٳ*Yrdn6sQCs9'P!OVMg1g s>sknjuRZ`fpjk2Xf`,eʎ͂In5Yh-46 !:}BiA_6Z2~`.s-4-' Jw'{\ Z ata|'{}:\qS(p=9Yͣ ̨ IX)ez86C3}MT,$iGbA}߈!"}o}>;7m`HC7 ?as3.ayt|ıJegbo a363=n*ňxw/{+0z+ˏ},IrA+;r( mjͮݧ LCw 7ܷ~X 4|1G5KKZ pC2RP鐸*[\ W /K rE3S(\%RU<={/5yᵜ KS0ЦzRj!sDC1nrΛڱ)I ݐI:]X<]: +lyɝc;I%Θ[9h\z |Z˼tIFיgsYcp*Qɾ7[,Z鐡>9(]pTt3K.\ @sNlL23̌sKW%%:؊P3MRaN]P澺rʷbG?gtkox3|cPppAU^.x/acHä,V x>v-WY7lō=-'`j _7Ip +=~ey3$@^hϥxE. [B KחRP]bI&NBgYG`G,`3("URd3Sr-uֱ V{Ry|f#*\Yw!Jv ኤJm_9f~Grs8YK ?s-$.e))k)7cs.lIYz-x,9}@*|>9>sm">񓿏 /p)1>O˟v0(96}r9ELCSd)(/ zaC`yTFJø(_HϬ~C%3[E* BoX}vXy#^ōG*V~ƶAʭ_@4v~Zv$JGi,30\+jn*Vh2L.=.S[cY ]5s;K'=#l{)r~pp4ǝ~av% ~^hd cp;$5Z<m$gΓw, YJ\/6>’s#G1j!I0\b3~hd?᫂ C lbb">j1cVZwdWݺ58x޲bJ ZZ+\!@J|:a0:h^';zV}7"X)űs#Gn?J0c}.)֊K{g$KQ\͍r3,#a:CWMӦ&}6jc*~,ׅgvj!G1[ y vݢe4Ȧyne\_gX $@ l˼=,[L\eXof;QI>n~xpKkMfGL9 5 G^6mXsܒQ [S*\&a|uܳkrR[õ<2nD\}mcyA ?mO3:}=t F" |IýF[oi'A^iI*Ɔp#jҨIS MWv^->fj8q- kb'CbfϿL1츪'lʳBT tçMH4Oz'0:x|WF(vpWJ`rG4Qq!+ro6Qp*Dۙ@+# t6oO k|wTy> Zdgw}P Djd>{ɭTp"w>biVFKVձPg z}7P#䚔 Q`CA5۹c.9&̌*$j!B "̳/%O$fA'&ZW)Kd9k03!Syݶ%-}DTJ̑Ƹq#Br-Df-R*o_4I_v2=376Hm݇`2q .DV6ul9/ tS݌A r^:q'᷻ j SMI/#TɉMv3ԅx\9y"F73(|xc_?_|y}(i;l.O <9,r0-xG3(AΙx J PQv>BNf@"C'nQ"B^ڨ*^6+k6r_1J0b𽚧JZ )jub .3#LN*U0RN% ZKU!lbR} ׆>s(!:|U]@EW_jn;bv$*4UX(T", +,J,|m +ؼ'3"YPYslxw.֑T9!ʌdBeV Y88EP[*tCxUu^K5tĂ1R(}AmnhyB). oh%aBucB'a' Vj{$s͚d~~V _U3>3x~rVU" t{釲7cI()ՄR ,˩2ȋKW c]t"$ 4 9J!,rΪcpg)LwvBu#:4е.*^4gޔÿ 6{@@83∀6X (p##Lj1 1"`$fD TB\0(/AJL=RY̘5@z LI*I"L"ȜKu;;D jA) eF i(L@6'b@pfyW+$0fJ2pP`MrI`dSYڪ;c#\XK敫TO Blq khs CA,FY_b(A!V`"6rBЮ0aH\YΟ10R Àa(vfǡ^U]愙8 cg.IdK1MX 0#;Sb쎫MsyTAvV+$,@!)9 P̘A6lg@,S:bf4#̛ r L 1qz<%Pʆ{({- 3yGӀGaJKJ9% ̽F4!h[A~:8PoRP, 9)Y7k%h !zk(SIiTvDvq`m{x}o˯œO>/| 'zGFv@ CFMca`R\8#.s'j-6o3VԿcc&nnѓNWmNNYX?ad|k޷/y1417'N@fl,Aҭcd!)UyNe/3hÓdQK mS{4^f@Y`R]0t]<%0f弧Dh69c- TLY:dK0hS9? ,,9YN^K9c 3"qH$̓@9 +"&gۤrߤLpf&dˑTy#Y % ǀ9϶mϊ>Q>'s-+%T,O|i1׀l LTmTmR1Ě КP=W]Ͽw~'n60g8::fFΩںX )T*`i X%y* P$0asTuvfP %AECmRW) V%l:Hˬ0Q&+ rL&L+j+ㆨM /Vu$t];4۟0H"ܔq0X%\~>% `Zy+TET|9[((d& g-̛ bl>(4ġ8'Ga%=Cj2=6s8Pss 3Icu+PTwC!nE-:\ 4;UGoС؟dE3UA4VHCę#x qm#y0m1Mic7e} +A$W55 Ԡ[`*hl+_a !XsNޒYV+4 RdC K:|?[y&wmzt9_#v/[wBBVf(ts8I0Sec^+q%`mm SJ\,zEa@횚~S2c*G.MmbϿRN&Đsd)oYw9{}㯏~jj1Ά)_`Bx /ԙAߞ۫d fVAnGU寫/ *BXV*ql[~5QɌ,UTC"d@swvve\X]pcuS{O=eLiiͤԽud㓁OD4 u6,̅bwݍWq>8|"R3/Fs`oK؉ G獰SQ(7L t1uCp{[oT 4bD/[q1K~ d {{;c\?f4OY%lL3}i ftk_V%Hz7T&m'۪ӶŮUO\>/YL:kzPmshM_ORl}fnuPXS<}"`_ ;h+&*߿^t'Q*&bU\dq Ycɺd V;VX hF\>CHEȹ d8]dT"`u0>O}Y2a(EZ2fO,֔RԚ#\-$}2D$ k/Ul7F0YhPpBϳݰn*wVJV2}/;7qi¼ٔMyM=nAcI!7?XZy:_+lL=[6S4RV:XMVHi*JYmJ =4?wj$hDeX8o+@XP`F l4;  ;>h- IJ7QhR%"XEς^b5!`q_je,rܚb< :5Raߏ?Gދȵw(U„ Q[n?qBM0T\>ߐ|бDr^aa"fьea]W[P,+m_۾ۑãC\~ WLӭF]j~ :rт-3 yi}7LWP̡OSK{|E\p$yQ{|=-Iۿ@c %695rO5ᤲĖ,4!O4JD$A}O]gBX,iqMD'l{o}Ǥq?76|֯*d+i㸪>/}E]C3e]M^ҋHyq.K CڢFF~Q rGU+AnA\=қ!FyʓR0gS?F%j򳊾P]3q>4rJV;}7^z wi%!4>W&ow:/cSAF, 'uan89ɰDƁ<+P x;gpu_?BӢ2mpP"& oOc[xA;hnFڂgŕ.K:Rm[8onOZ*gXap]۶ojmaPWm5HVvG)#.AKU -RжKxSIcw?FΗ?4w^%6'n}ytӥBq$ST.vJQUe/nQJO\}QOeX#9)s |efȹNi^TOY78rw"@* g/o_Agf`iرI KVbWc!VETƢ :^H*/ꖪ⏛6{)׺3a`mmۺ ٶaJo!nguڱ_S>-47f%ל<#ɾ'49< u v}[`hl9?JcX| b0w}/xs.^Mfc :Bn;vn₦f$E@PŠJ ʰ)PJ)v}훰N3puG }ϊ6U ܳnŷUqm[UXv=L j _Fǧ~mZ'g4zM-=M[ym\{~]m0MSTm=a^;C_۠sV#׎:։$Jfz\;#&֢H,O-٢ٸR9`Fi\ĥď!$GJ,3&/1ԢPԊMMFc ūTP,˔izeV&P?FP݊#LJ8::*v`juS~V_V y>"yFs(\t> `n۪DK (Ft 2$m?$.F6-uh0V ?U2}{,2ϩU VݶdJSU%mZEY3UZ$"lKh7[aN2_ͤt6&'QN`nԮ>^|$`n׉3@B:3x.KUםF$1#DBnѵWߎ7E~E1ݤߩsfh[äfnTak"Hpf9ȈlKZ&v~߆o GGX17 d1pAA5.'2v[t?5oJs5 2mGT7nIL\x+ X"`ǚ<64SPqT}5´-9MSKfQTm3 ;z,J- lXIxS֒?Zƚ\V-P \08|nm(@$"7ǂ~F b^|/Wv,d-`DQ DP*g65ft9<8:׾u  #vƕ ߞc^!Wb/?(O@ݾiS0X9Vdt @Ϙ2^hxA~ Q?[W5wS l6ev{m™ocRfd.^J2Cyx2 p͸p˭v7\2;\n,JXћ#Y0iAAx͂¼ p]GҴmb)Tsv%HʹWgFnn@0] /9n蚜H P C @+&jALdCWc{5Qn)f΀BMJzmB -Z L)hJRs[IUB]*猜%htAPoR(+ 2TȉН- UJ}s.ɧ$ !Њ"8l:U/J%LO38 X;@wp.!#{4af"!وF.ġ/hv}W&Sg0 U4y9Jj,u|#! V 5o-By0)9Gr^}oy'rb7klM;eJϸ8s.|q9m;G b~`͹ަhU C@CӤ2hWT:/Y7 ' wXLs0iH!F.vIZ94\I̩RjBu(TB9@ F,7c v-uvÜZ3cem.3kʸL|^[6n :"nb3cUvdBl)Pjbz;H;ONLW1HO)!,"U|0`iA#xp0+'(≣3]+`ut?SO V"ZXi޺Z-9Z[wVՆJ)wSv$~h9p.M8ip۫ j!*:!j[gTFMS:VFtɠVr_) 87TR(Z\(jam}h U \BչڦeJG8b kG%3cVhja 7(9WF)5*>'HyH ҷf09f6_t}͝C3 jEσSBL22s A<Y"8zA= TAX*),XSO,ɹY7:,NRZ)Ao7B] vɎr5>`XO膳VPPJ?_Qw|; c&1V|k pdB9ʺN̮ݔ]ڒ6N8n[CtYBK>Y]9GaVUvGD jЊپz πRg.b4{gk*JA\ϳƈz0px{+loT oʆYUSBeK7PCKbÉ&LݧY2YXU|l!Yl0[*vfvzR8$ϒF'=5Xyx='b]CI0=vuSaFZDhbٷ!E<}\,@FgC)0I|A~]MSTd? 0p(UƜƁ07¸7"Skc#_s#RJYYPOwg}qĵ+x]QWmRTOqklD&[U7󞿡cYry7!sA*:ymNyv JT4[2 MtIXprE|7PٝV`lW gQJƄWnL s" V0)H\d1O QsO9Avq2b YeikPH ЀEX!FTT87-TKhݛ!-t=7$[,eq:w>УHT%D)r.T7\$6k fada,'PsqA,! )׷$3)U4ulbm8gPyN&T<}o(vPM8K¤H*iʸf.F 44Z4)G6Rϥܑ2Z<7(`ce<^t2pCF=(L5r 8U:\zQ xU;'-|b,Cqѵ*ܘ.Y} jwX-﹞ha~n[vݓ:2"FciSbpbds]q㤃g6?庬PΚV>Ռ6<+/ ޚpJt oa#.UC\7R޺ةƅP@R$"OO]L+$U~y7ʼn+xA>I4=ŗ67L8:>?8 X7)CJE7Ml9g5p l |4lIPA.Ŧ1O-h(r,UE*/|cu٥-0!ݎ\5眪A`u$( ܑ"nG0*!1եP%UW6M4Y#NOaa C??M~Dþš'|O_/?0nV<p뭷~=L V2҈M2#g8s;5لj$H1Zl9o;["Tv<%KHn8W:_.RnoozYv a03cLICĜ7 ˌ^:mj*̛Y(Vp Lg@SJUΜ M8 S@@ Np3'W< ÀUAu!z )beB+c荂-WesP7:SJ2u\KU DSՄ$oq$+=X6{V!f5)hy͉(s%xް񩥵+VX*!ٰF5eÉM+SfgINę0 OnCqY$V>xb8\@ܧizffD '1| Vha#裏[n^JqUEkB3ɨk"Ҥ0oq%{Pe*2/fA`8RUۥBO儐M京 . 6X (c BEIK:KUdovE\|vl9@NuaO.v{ <ĸ1~&Tu}W{hVX`!xHe'Q-SSkv,*fh^ 1FN+_i$zXhҞ0gѣlM*~'h/s:sůuZNf{X{L΁ fivE`|w) [Uw<#|A1b|err$>O!KPCxߏ׽XVU 6V?̹YW,=lgc:#P3Fe2p GmUe/qG!vU:(n[7M޺&{M)D@1mp5k(<יD=t !Jx"p Q`a(hn_ Mӱ`PXNV]β`*9CƿfhUVP!!T"lFߥ% ҄9|N @yyD>NKقG#jEE)]+H-ĦB{9g|S0 d!<ůc\~GGG8::ĒO.`ggl6..=s p ftC$HM2U.PyYVU[!:+),BjD;K%G B d} ΔݭV;T )@=H= 8$DU1vϥlBDE `v'kb}rj#*GVcu8sfB;SrК\(NA 90pCBk@`Uh."Oau lPIΒəe)^^"CB*z+DDM2/1q9w۪3Ot U1*\WȴÉQ }$ա<P7 )jVIdQ,d|泟 -<Ħr)%l6 [@_ @Bu=HA@:ͦxx顇/on&êm{>0mz&2sz\CX'!7Z#iE:SAB#Ft[@U@}ج>a42 C-'A:Et˽:URxKz},W!d`ZOlKrD ZlJҢ˜Lf `Kym5Q,"Q[nz3%mPUىTyDG6Y8 1H%؃Pa[h-3FjSEH^圉WM;\jwoT%3h2&U=3)yiɗMgT,Ֆ!ݥ#:^ylf8A+` ^kUNa33UY/~&IW +A{&vz(x6 VU~~~9R-b$sFtآoPnT}ɬ;% SNb@?"pfLjRŇB/.~ !K+I9j1icU61bƒ̇Iҙ*AYb(CKdvRw{7v*A3lRm,"f%NJy I'8H%,Ӱ*SiH.6gN[UE1dZI|]]V!gTЁs^ʢ( V9j|$a¬r>aF& bqL2lxԫyq5䏏q5{dzz y=gil{P5wos1a!u<9s s5݈%\ mjT9OJ7?k$0:XBmCQUP;KCu""A%@NsՒ$>"\u hBq& s"G;n&0b}|T0oz} ކ):id(3Xy.Jt`  . d,Wi OUڙP=4:PW89`N ׾*^x66ێrv|^[UU{j!9*VҖ%Ri}U]$sCS\ﱇuPO[u_Fe<~!f!!9^=O=aΝ; .`gg/_իW^quի8<<$p||MuS|hP3u]8請V/J*J5n}/Y [JJ`)G JS~>$2ʢ 4 3`p؊_Q4? !Re_ٗ2ՎDYn'SZ#tCכBB1"AWlÌ"% b3RA/WP$J`HfE?@KUN^8[%>YGcxƌf6&9Ft,{:.P^=ٳg9u޿XL!T)._cDi穚Ë"F_ ocW)#/\˕.Km6y;>?[By衇++xމX6+%Xez1-*AQl(a"dVI,?Kl"-u.TM]b0XY6ɾƶ}RQ MɢҚ- ZLu}9A5j 9Dn!eIvYveg3țа7ޛ1Ђէ _Cu=CE7Z S֍Ka11Q8di9 ?~p7M|@F!P#ۻi4ExZ/۰:J31gy5S]H&wwNR蟨A6-jt@Qϗz`8 .\-܂}LӄK.駟\r*~loog!)=~]~ _VujV^`] Vf B & ߕ1{*p &4(qt'i0t UDVxUx Mٝت̶WPv^P%%YT:CHk ٺ2bj|2Q>et1%*! ;y1&@iR/ *ٖq6|9m*Io*DW3,Ǻ(V:ۢԝe5~Ɇ#zm4QBqٳ?ݭZ.~PmЖ T.m Iqӱ6/D'}S h߉) fdnSgh=t%^T8ϟ7fSO={ .]jV=`>h^3zqt>O{ŋO"b##‡'GA{=!WͰTo8EyɶCYN `GxvIBr6w<\!.Rv{XϿ9ypVIDAT dS24dr4^؍H.rΘ1` qBRjo3JɩhU2<`X91xs=|䠛3x>q$`6~!V{O!:/  ~!!U4[nHAXT%l}'spZ^.euMZ@M$o`@E7]0R~?v^e<d3qoLW|8*w S$x>W0S|XV8880 X8<w~ᬑ>vzEfXkVdlT|4 HOUuBz63jVט%UM]nC-@}+ qMy^'˗qU=ܶ4ϕ@cC0[50vT&( ynXB*l$g/K +R#bb|T6k7\-QY,,hʞI* M;~E$.qb$IL\Sp}uøt:&/*C8Dd.Scbnr9yh}Πe1% "A@J (yK5rsf &E6,v!q6cֽ= 1_Jqk dZ~$ִ:srKaЖԳ pP*yAmz3*'ZZ!Q 6-@iO>!VuׯgSO=||uO`5{iAGG>78{ɐfpx^.9D VXa͡rb[(ķPh†vrfەl>9TI4'DӪ &PailOuilGa>J>TДz!eX -iRұMW̹jT[L: r9^h]AՐՋԋ˫VfV+R?j0j*5PT|7pN3kf;q׭#"3~?kWDr8!pG'{$D%o8*w]$ V_0 MJ|駍-ޏjlgsmD=-{I;vze_4DP19d۽f@mEΉB˶B gaGf[B?,03ry.3̢V*1M+!eurrR4awZ9ƊA׮$j(B/$#09RDe0[w\3@|r4-oP4KbFȈu͙;ňlmc*8o+f=8ð.臌mP!h;tSG4uʼnKnB]6 ;D,FԹ**eX;͒ռ77[Թ[e$cO>W{ƵQ=5k7}O}l ~{6>~w@aq;(߄ݽݖ .&ˍ{4MVc5VDorC"ydP[b/ W1tI(>P}&)0 B9:u^%fdt@C1z*}6M̌8@ͦi*i<(*pw΀ ;"7SaƤ|Rn57k7\ 8Xdk.31M}Э-3bMQE$&/iÛ`_UI4EUiu%Brڹ [qqvh-BonwC jX;`*̀\jWŽa\~f! lnbK`C-x TyO=t3iZH/lnA<A8q[fPN?%_Av7j\@y>EYMpaC`zZ+n_蛭Ѫa&*4'EA+ t"Xb ֋yDh\)I@Z r'l =6q+|)k&LbUSBh: 4feu+yT[rۥ2%]xɆ}46IӂUA?__H>l3@4t[3|egˑ%eWE\)KیESoպjmd-!!]QQE|є>+֍ٶ !Ո̈́`ۯZȒ Ñ[Yc13+:QPnD1)!Xt {x;߁|ZٴldW5:yܽy4EJ8s)F_Ap8UWJ e'A"C#n͟ڟ{g9ybFy~0F'̹>)e N˾0<#b5vW~E?;HsVCO|zcf5ݸ,NU;b rqpU B2T/"HabQ*ZAѹZ]*=ʱb-XA+AF3x1 _+UۍBTBTHΘ&JC%| 4,Tg0m+-ci~6d^>& =gyc>%/7^}ĸnaVP@sP?MŕN~3 z"tn 6QB\+ջg!@Ւ59_s,$FfՈ)Yn)^lR;gP#*GbViF#'pC3ؔAu"`IE07WF5,rFp i.2W>q VEq6zkm* Bq;(Á |mTߚjʎh qClm-IRUk7鰔m0@z 0/NSzn<_HШ}mc1zv?^ D{7͎fW4I,O5孈b-N@,гkF5 SiNzsqШ^<TӦ;CPœ+T0rN#S*LV@B Q^V$ I3pc:Z(."2IZn=[իƳUU 3aU\ZOzv_(Xp|,)qLPuhMx .;8J`ED5/ ;sƵױfu Wžֹ->-Yj蓀xO@'m._"?ѱ$pڂ_ط$6ӈ Pw_0ՅghkR$z R@_^G_atY˶ ޿ eYIsRA CJR fl9j*hZ.|ISnO}=.QX^u!'AcNK1{ju;Nm%Z=7V+X!cW1rC?uЪ+TuzT+,K,%@!"'B$4+9eຨ6RaՀqP)M+73K*,I3 h+e90+dCXl aGfa&7 wM,Bmi<#)LBqD9%t"{3T:#m뜒 iu xXtrN轷0G+%*!e[f &`?T']SFL~/!.Z4K}'J7Dm]oK{'*y>ϳ1vjN-jl6KDiPi?f+WysfKW5]y)eqGgcll[*aTӳ'+`W,Q$'䜥Kh9P #NxrUQ(*ĺ+nQ&Hl]@ӄf0(˯:Ǫ`"2] nт?B, qXݘ0>O~;/KvLIɒ|F *Ta0Һ½c@Hmki nꟽ3VUW`N͜]a1=Y>(vƲ괐v&x'P,ɷף>!27&qxC0Ϧ\No澳cW~G.mhJL &nhڙF,˔"'si@&`g[vv>qʹh̪7ECx L(e0w {E=A|T>\xtsK7$ާ?Q|Sڃ]9 ;AXw! b5;uRV}j Z32-T- âŦ@cט3;ZU %Vsj[r?45^;N|u*WߔNbhc εuCUr~fBDL-R]g~-hտ{km[ὼs3=\L>(׷vys.6i; rUoW(-uܾ[S9odS nta6N|sLZ<XeLӄam&h VWY93bfbus^9l & ߇vϖb90`,/}K~~~-ɯf7~׾o~˟OrZ a x:S#1qae л ]3 D8ii\e  4PKL/.j?m}_밌wequqpP1n-sJ\aؚ=8s܀puA/}ΌqjnO Zjv? x'Vn3|7ن/UXBO}uF!,s}ԯ–ܽD E>(]_=54ƈiވHJʹ˩Ug Lh9a>v#v>Vu#hALcFE0 P84}Z f!0"dBp9-/?Ѓ_ ]oy̰'B cqˇ#·pf NEP.k3MZro0Uҧ - ]amܼD6aif[hM:g%9r'F;I >Qpg2AMd7gZgn_fV^2qӯs Oʕvc,,V*eC)zW|Dk;elN&GH~ͲW@5PJ и˯?)ON?+?7?)[bql#Mun+Z< @!}/5̧>ϴQ#>-{72k$-;yXpb}~ڬU;fVse&Yynje@_.[|?mg@ ?ޖwι &-(̧ґϊ-<<' Ha;3U=7,FX8ʑ9vESR F?:3!EZ!RUSuY}|! 7c?\1\X:0Aq Ѷ90w@ n?33kZ~Gy?mK pRr7897LeDen2ۋ6&j4h1_p!R3:̺;t6z@X떴l bej$x)4ba̼ tϻՉb`iǘS.o6kM7{H_eZ{Kx).^4駟ƓO<zGGG=Day%ˢƩնuSWs% T~`czJ;zp;.v:9RnwPi.˞~ l]C F2)b SfiYm'LFo_ Qu dٛJP)kXx9Dg A._ok5%㣣W/ѝRC9sƅ:#v-1dgˮРn΂JtqY7TU* |5U[Cpf.6p yLfQS/sg%#BT}e|t5WEУ#[ q7/zы|'E/ΝC\9FI"yXm  7q,ܴٸ=3!JqlPO)cvr-%Tʶ7;< 84w?"^i t' s.:ٵe>B!.`jZ(% ^R mUEO MzW2j/!kϙxsڷ_t~N a]phQ75xm1b}ӗ?Q| ֗//$^- oOx^[.ތsgڂQΌicmp?ٟţ(g ]b7.kq!6]O1ĀfX`Qo諝;0"Ss"J`T{F.gL/;kF}䷷i_ w w^oNJ)aglekto 7|31_X/NK]gGvm:hmaXRS+k7-N45]/_ ڌuc޺7`}Z"O|UUvi7v+-I&ŪC(P:Ӝ0NX7jq𒗽/^dsnKJ vKU["jXaqEq T547&`oz;bk_oc?rpRy>Yx\(M*ezv-+)Wʤ۩o衫u^B,ՊD1>q1Y|e`+-;dCmȳ ؔD>X圑LKF1V9a8y8D+0Bc*l悢q'nV;{efg.qt~. \C wltlJ`pG>ƈ1T :PM3pV'4N~5޹/` L뮻clM%K{{8{ .;x˷}TV+1z-8w\pFKܹIIv^Tmt'E""DYjmu8%0.6fc麗Wf{]`Yt~fmMo" 3kO ,o$A7is\%ȯC L_t*.:F *g.=㋯S//nۼS򽜦򌼾^cU_8vٙ&4s$:;/-)xޣZf"~mfxEr*%5Ǽ VVB-xon b3quɓZ{` n.KAyn6D?LJ1bZawg=;{ΟǛ-x/_U"x;ށ׾p/|/wum1b"VX]{>я,F/84a6[F {e3Á۰8ZȩTiKG 1ʠd* rso1w|L ^@0tD$ϱP dA<'fJh 'S 0M q3QNɻ#I68ϔ>/woOnx~w>u|O'@ s:A^_+l`n ,ZAd{9s5^hsr44rQa uk$bXI&o^- DkJkAFsoӎRD+{5^Fy….TG~={77|׻#?#?~~YŹsgqtuW3?3xG̕OORA~{ӛ?*+j]Bͳ*?%yscjDKF%SY{])lk_hRT)5ҝ ZAYͳ7%yJM*Q,vV;܉j+]`;:qM9#Rr5l$rnfАeFtЌ]?+x)M Kox\8~5ZśQq813Py\}NAa)U{K"gcl V2Z>T3DJ0$TLۭ.{BZ[1eU_L} ~7i /@gfےo-?S <888>|鿏gq7]׾G?+{yko}C/ )|c!oe|_h00Ie5֯MfgBMܦuz^ѷ(5>U*5muM >~aauϧ _0vQlDK5O^Ym!9spX>)% ®q%װɟĥK?uΜ^J Ànj>pϽ +?Ƈ?aſ񶷽 ?s?to⻿{0On:SZY MZJOԙļ`'yxB-iТat !'fxmDyڭYEKdF/:SjS`C9J SNa1.gu@IA7iW2#(wEAJ/K!LDHOホmeuO) N)8 'veqrU<4ee['fzJeppH+D4Z 'V^~""D!"݋9{#g#EM22{N&@AVB9 /{>Ow y{S?Sr~÷88}݇[o< NcwwǮ__U񖷼?3?}t c=_}zWS*%3[b~2ۥ[c,:J:*3y!&gOHaI9uH P+\T(!٤=8]~7vq-7ŋ/}Y.O?;N|~/~~ ~GGGK_~]R*"+52YFϷTv<4苛a֘-")d(dh͎6_3]D Lbe^953/U:"g}gQm6Bp[s4)>BO`/g݈;ab|pj)>iY3%5/2&`|a>mQL8A7pB̝yւ].5AŧkTh&ק .>ً[/4CeEm1F (>9wԆ*V TLrpMo?ӥ(RkRJXhYձY[E`Ÿz/`^wNw72\.q|r"~x'prrR=??e/\ޚ}/z/zD~ .\F/O~?0fU6](!u WNm%;r|q.,>ֲִA)IzYϞPi!)&cbl-~%W'ʎpyRv*t ];\Rdlm dà5Pǒ}1s] *|lb8,11?dAHM.Q-Ï)'^qI!K/@wӝPY 1u2>-I9kM%>"u*bMB%OqUإ[+u͍UF9W<-`T΍UragmS0MuA QZհ>,n]''xqxxX(>?+^Jlmm;8-ܪ>-M~/=_>ٖ*Z PUܮ?l2FmʨriӺ2K>5^`rA[@f*;DMdi\ sXS qBZɈ`tǰ LsX}^>{DR&Aj ʽY7"}c#mE+>E6RM%op sӢ~0P+H -cbm^޴-ga9(7f\SxgO &zQKN'X Μ/+=a sxʧ8&)C4=e۵5qbn`'2Dɻҗ}o_"Ӷ/7eDžu`kkK1~888]w݅?0^MEYA ck^B6@A ; z0G%:* %Y+?!pkg0PRY BW,cϰt0Tڄ}U]X.WN$Oe?S5&M~ zQ :jEq+j҅RiDqcj\)r@/UVy_I.>!A+H|^P9Jhz&o,]b*rDm+EW:2EK"T)[mx0 :B _S}yXFRzrIKYd0Y}O@?}g׌!p#븾p{{|DSÛ7_v(=ddaLj{#h.=Oj!bWU)#d˓s @O]xOsg!fM"&(ž&04&{@Ƈfa Yy{ͲcCCOSW  賿ZJH |wPJ"XVn B;5!8LF7r "8'=VAiJf Z9nSWw99!VY\s:%+2%ope 0t- Wa928ijh1 .K럁0Zw_2j ,czsnlmm}/OL0;ʥ-/v,F0F,'xGv _f<41uzGGG8<:·-ׯ=q8b:7ٷqo}q7…=\?H8b c:}a? ` _K"~BZEL W-?w *1(=;F5xE DFl#E.5C$7k='%p> ] I[)[`V-k*8" ZhwnN6CE}b7L~~hMEx<%FZÃX<02|dV#e Vbgh,~EB&%Nyf^ .˾c Cި\_#fMLVADuFlݲZ _c5-Fsm&޻;bV?b5y >O`XK;+?G /qBx7{9eG !W`|[e|S88Ne_+Źtє^ڎ ,^`9qq!ZNU\o`Df7fR1xɂ*:yy/jF., jV]-J3~01^ ǜ5B]=eFcнd(u|N0w+:t0%dot*R#9PS' ! 6IXk1VKɥCI DHƐk;e9/2qMX;m]xB򗾄|{.]¿'>w[x1\;Kt[`ʢ ܼ |3Wwcçp?+{.9#.W.{~7ay./݆溜8bFCb_|pmo-7u)ߌ~,g8!c{Lϐ?YhIl1ڹ:ģ^ZB'ۣY܅HH]UѓQy{AJ߻2TjRQVVV1VÐ 1էM ,蒪ZJ{&d*VE a6^%H J'x܈_P7>Wg;ԸF%UK4t)B?sP  h0!B 7SNhX7kSm&e/B)\8fU;{Q|ןy ܟ/_+l3v}[?(ŋ LYs{/p|Znpb@| ?x*=vWWʿWpe  C3B\p|| /4 Orif S\=8VS)¦֙KW P֝7R{9'c(.*較^>]^5Fctha2!T ,JЋݱ}2ƤnaS B4 LC2n(Tadm?l1+Zj#/[h~_q`_LC[y1 @mlc%m\zCOo07 { ˓8WIca13!(d!*$6g9l{`h(3pr+a: I:,UZ;=@C+N.tN<&lșpȶ(@\μql .g#T1#Fw]UY,T|F]*?fZ80~H4F lm*!EX 1er n~/͏.x) B~ 4?+eo=ŸNt&{==8=_b|Knb}G'G㣿۪=o?w À0c6V u>eL'ij17k璅8&( JTOr)>*dډpFplTɇļuϨ<"?uVJC[ވ合 fռ4KJn^=|xNq0j8q!|J>+7`zT" /qy>=rP<,uXxS1Kc<!.{ wމLJdy6fxyXڛjJԤm*3vi2Hdg|F ̢aD!Ktꓚ62|&&Re"Jtxy'(g Dgf/b e~c$VIF%獡&'#Ӥ NNNsn~ΦUa^svꛣ[{t{֖|H%p:sVe%NIὧt 1FuQ1bqr"{2KB_ 3+( I<~NK X)`8dFe>AZ{CҹsuC,dN ۧz(nƛl*LfЈCHvSVWc|sa"g撧Č0jF§dђz2,˫dדKR3jjgicMQ4 A<:W:dh SGx  X )v3A y\{/~ .S1oⷿj_o?#}ΏZmH''_[YHBgm:, #XJK/t=kߴȶTnԙ (#SΥչ#1԰֕g5C1'kp0wi2qcf a{g# ׼^U٥:Ea0 :P0ga0OĆW/sFJ۩,^A4ollrW ^"dlbi942Wԅ0?Ig,X_n dνnB'uI4T^C2Dk j>|N-c$`?=o.v#=;tģ$ av"@@K13l=Vl dWĬȷ՜fGų)xM@rZĒeHf9( +PiB6GWKK<ϓ|I> KL7C8!>14\I;MT#PW丱䢠Av' i_At#ȌHbRDcVaYO@ÅD"0o r%,݉жtC幌tQE R\Ҍ}2#Z*Rsxml˾Z3N>i[S[Y=z~k_/Xl6l9ZG L[Dg_Xo:>֎)"p8.sw޲_cmHm!g5-y/F V96QZl?q2ҷSE &̹x$rLQiaP0B߷ bFw>(3 9;TK% NSy\'(꜀8 [PF,t͒ /vPyhˁ dX5~$& VQ){ d"g(\k֙xƝx9 آ &$YhlEa vx_z o_ܢ9ֵvVHs`"X9ilƈ*$`5_~I/sdrtx \ '^1aTxZ?1M<<*H=W!ugfT&4%Zjձd=iXYK61*I3+l-7s^z9`@T՟EL!ghn9~OՊE92 NBA*f>(&nIgV`Gr3\RVco\YdX$Z%*jsnjhM_Sqj]ti>vdu5 @\ݼF5)]@mQQa89f^{?: =|@xgOn뛢un!'vmky(CEu@,PocV( !O[n;#`0!`9}t!ۍ'儰N*ƨI)ܾD2!sOPRu\A7ZvyR|Dž*.Y <\LyYJlɷB-âiSZV./wV[.]~s9$MOM Pl[EpDnJDeLu+BX1p|\C[;{ G eohD9 O[o כ2x͡`5Fx%c [1,Mv9*rZvgbVNTݨ2W $8$)CǐCbK<8)J[;(Q{1>Fʋ@`ĉ͇U n<0cpSűx+ P m| q4LX~m`_qQ3/전1`.&⎪o) [lyLSݹ0լ#kD{@Lv ݫo||`  (CBfBj5D ic} *P?:p*㉧Q@"O״Ro)`G|䧐l SsWUWZCc`1CA-+re,;6Cd(# 'tj !4b+q$X"!etLuz@")9 qMO1c~[ۻ1.i==kbIii2"c^ s]ZEU(t .P:Vɺ)N{"U#13{ || ` #`%_V?f21Tdg)}K1<4Gz*``-#mr!_>,,B?J~aMt~-P? Srn-i.&\b$`8cBI &aG % "Q°N rIknW|)Ew,}L OϓX\y0{ȼCZ5>e+ʋ ݱK$YP*X uab$CˡN@]"vKG(Il`/sM>cJ$TVq id@}*d3K$y o-LY$es$ͨF9{*4qyidrB'7a[cigL$ib)\uymijܷiBjPCi -m:D*&{(8NC̳׵=[n]Ǡ!}Pw1~e?Jpă'tȅc.+B\㒰̝cO<|[NJ֝aw]|?X.G S@ -ZVPGGGxܳO 4u9E_ ֲ9]=ǙkH<Hz%hI )A:<477%>SAؙFU$1 8Q&!u[T$+b q8Q2 %t$Z*)\EYau$ !yy;tMl#c&@t5b_&e2b44\}^:兯98?!Xc6fݔ]az2fm P>NN-CRszu $?{Lo{=Ux;t'phq/ {ɻ,8$kKϹ%a\&}{epS@GւpaN' }Oo>G?g߄Eϔ9GVDB|k^0$5_a}3ѿhuai,D_`&̪%ІI3"ÀBEc#<rvڔJ IP)*2d[4T1/ea\\A8squ\ vu[q%Lܟo,ulXtNT"˲0TWdpFA@F0H7<}CM w *a2YT~I(#LT_w]%*HmZ|ظPd @𙯹̣7͈/zQޥ~`3K|xRU{’0#`3=c\",尳cwG@}YLa;t]b[7y~/r̿<|-7Ć4$Րu&WN2p#JM1\NXpxd%x$*gXuzva .qX;;ۈ㐧RpHٛ0w0, '9v}Iu۩I&a>n:W0dxT̿CR9ĘIL\<G-ܢ&. _W0Rhۻy#pj %&^*b$Svd=]PM>!u[xѨgɄ]&*3>0Z؞8[7ҽ G;`]X1u8#[ r[`>q(KRЁK`<&#>_~8}`:Bwv~g >X_i'b]4^r K kO|Sx^S-H{" q}OBZ` cf,Zhb iK1j"=4Yt.]|X%7_\*jʁ*7肸qsc8\/2d>fH'U1CnC1Eڻm`T{W8CoaoN988|Lɚl%|]K:cc&6_|D,_S hyu˅ݙfp=Pm@&jt#ꮏ4Fj@s.zB3O<͒^zF 3.^XtaWdD/>qj*Rj[t̝\p੫3|Hi =wu_FϿ|nj GmlmmaHq0`\H1ƈ?/ᩧVyyʘڐ02,a邿 ȳdb `{{;;;`NܲO}_s(UTE^tWKDHjIamBCOiKb _Ig ޙXpMӌðB ̔RN8,#1e??*-XvM6ư¥d=0do~n@vF⧦aLE7h8;g9>p~y)sxjƩS ԒhadqLuDIA`W~szX`KJ #yaflD{=LYZ؞< h4M߽fu#ǟy2nw_̳ twet$FqT`(@̂1 2`xYƣO^MbOSy᷷]c ܌K.a#S;;;݅s.qM`O}o~ŭڸ6/VF=Me‚5#Z$ _F6 9tff6rorx Y[mB(ca _/4- PhAʶ}I{SL#ie[L-67hPcY5dϊKQB I/#2êiaL|o͇J^)b]?w``ߣ9`Wzj;B:.9P)+_Ghg~$*Yp\.3hjd.׬p zx g {.{-F/D^`C#! 'pxj{ ¿E HɁp.+G7۰w nyxGLQO]akk ;;;x"%cPR̮]|D4y: Sk95E,(S8+)}|?Ic]:؈)\̅q@{QoNa,HIX3i:?:`d _x9 :63 kd:}tk$4'Y(xCi}Ke5r5R,**sSkׯkk wx; | .<; g} a{<\271150'>;mQ"au]~w=|pu /^M7݄o/x &Zf˗/… X.)6N/| RnI܈jbdS[Ms% Y&*fDɄ>J㶾?,{܁(/WYclL+!$&P>0"ƈy0"pUx3\GZ.#0 8^!Ns7o=Gʆg#a!~{K;_{._˗/oM7݄;"L.]­ފj'''qb]nj·;h9xo:!Imk6{)kRl2'.#{n*;$+Z]s%LPŢ7GTB"?TTw"vvwfU:)eXV.ad"g; .AhF wTR*B9,R\_R4rt D5k""[;iv"0@̘U6 :6[\7#- ܐjc_]w/@N?wq7>ndmt[ =p=J2`Υ{BH"ʠUH8 0ƀԐ \*Po`ar9b{'{FU;h ee/tUGethN(2Cb tbVRFTVSJO,f tCK"QJ64Po9% D*\QeOM@Rjhjw=sMS3{ tnǃWoS"v… ZA ^W`ww'''s !`V+(]Ķp|| 98^aׯ_G>Q{\k3So^Mtk fccap3Qy%v}6tK|%F>t(LZw]eHWX!P}C@FUaI.Hiȅ=6&ׁ%x u!MVy*һ1KrWq^fڥvVDm*rm7YE^/@\նU24ܹfV.)=3eZnE/0z(v6; oEɢ}VsegA69Ph-?997v#\/r3zOa\܉'8!‡5 V,t"u[; l]Ƶŭx6,6w賁֖DՈWݬ^"\rַ_rp5looŋ^gRBC>7஻j`zc覥ͫP6n>([(e;00+@A̺6/x +\ϸ %xw99f蜸fhɰȥփBca(YTSiCEuquu![auZUv\S]*#i!ڤ0R'Qحx]BM0Ƣ1,kAf2xF'kb i95.B΋rshGuٛLfMW7a}ܜ?'zJ=e]wUk*rA/{p {NN2L1wɿ[XluY`V;Փq^Ţ@?޵^>_ƔeéX( hbb8>>ƿ_љȳo ܇lX=zݙ`#I.Q<ׄ|}POts?|4FGcȌ8^ rEjV҈r~NkQgwE |t㘞SdF/f}"˰rMKr7dkuӜR6VJ`ˤ Jd & 0k:סzvVlf% :ާ&0.L]r\By8GVGpKpvMڒ:O3%6e*VRMsu3>M1>Oe/{)ㅧLv_NfI/bm WE"*)zQ=T e-)% $!9!8" *O14,Bov1m{p7A #((9= tX@Āum!WVl"b[p*t}o݂?D.!9A}8B n;BĴ7qPF2sQZRWA&-}sB.'CM^9q^4C7A¨j3 _WF؇ȁ2IDATǕD&{\bwG/jBa-¢{إ-ې6}kk ?C?__ BC0L`h|ϿbQ٢L:+PvQ "zd\P{UhcT1g)Dζ2P藴8%Jh@1+]#:1F\J)zA>+| pb-*P# U4b1Pv7h ,c*o9]qfcP.:,Hն N4 /N !}\qҁ%S5nDG‡X|;W`fHLc13=\ŭ]yz[:ȞP&8g@7|B@f{XI~rrPRt m`M9=Զ@[::КY,mlc%]~ }w7Nqo!vڳG99(.C-ӆ;;xߏF=@{G>-o}3PY|Or&_i^O0DV6ҙFB0NT XddDy` !dfpTN1!dn5Yx(#w_]ߥY% !,Ds\l9,܃ĵctMw` .*v@N&U8Rc@Y N]2n@dSܔY~ ܜChkwaˡs",%π^F[.gӐMҖFkL|h B&/,=U|v4}߇f-b1vjZo:nVO$~7~$c g0:oyO|⓸/.L#Y#q UnҰ؄-bzCմacM*ĸc/BTb9$Es/Gt]c(/ED0SHsCK,!\j[r]~";iP`dsα,Q0b*dB:LZQ 5a%+ w]`?aިCu2Sg5y}Nl!1AּJ"$Ye ܔhĜD(y=4d;{jG*E?GKn DUrC5A6ru5R@aQ.XD9!_#ZZ#H &qC0+*Iig&F1\}4O*8X(4 fnn@L=ob66<@>_1F=7߼vjp9p s=hsu@ D07X,++?>i>Zs7)Ls;(Y+6_s7|x_Y5ɔc3mfubT8 nTtnS~ʎ4ś3P7TSC)׹-.B`xGX>C0h"Ov{WWt7#|P0LJ'3_LvhdT&[*([D֮Ik5G9 ,pA6-{'ҝyT&ZưoU nD~bHpU\4-tٌʞ={km$ְw _[އ@]P5wc?.v'Q=!`gSKq5-/E.抿o׿_'a֟ BÎ}({?w7]q[ ,iO +1xyQLx-k-+],.Ĩzc>&`B'H$\#u}"ĴD? z8'#@` Cpr9 H^J5x]JF~`_ }%Kwuưם -`(+-d^c1/[,uP ر`Ӥ4)M I)ɧ%<%-r*L|He!CweN'zglvu ڂbۆLk9W _ NNN&v"W ?zn 序9v`;v t|wwoͿY9 쿷">."~>?C' Qc,Fm-@iGKmĕu*X^ߋ1f44ك4W^Ylm&a˔35ec@HN[^M=rx-0'd&cLNWj\QA" R*] ur[NiR2+eSaC*:&L:w2*K>yu%yVŐLd7 1/Љ3,)XRALiR k[i\w=ɧ6%l儹 vM'z5p[Ǐȏ=SumD?@Es^C;IxG,~ow+ڴpaGQ[!#:RD8Q,;XFF6ƃz00>T/ )~*iz#23zpIF?!jgCH_)iΰJ%La d0N7vd\Ɛh0eeڷL$.bPhٌy SǷT$t A|I’[  tU>5l2o`FL4-܆?ӌ B~spx/k9]O? +6 2 lo<~Z禛n//o=Kl{lq}/z!zKf>rzr6*C۪͎LW"5 +`L19SS"]J-Hq@Q7Hgȇi4,2k ENkl]iAv[8,).)iޞPLu,4&LaNd:t)")p@5@d iQM&9o|PYبESя'J#h ʽiqR1sWU 397\kS>yܗ ]g)1F]­޺_uM>z=`Y}{_OPsoG-^C੓|#;?5a9MkZb|VoGU,Ud֜ru8, ѓl1g=`uYR|'4D.vj-0iٞ]NrLLx8u fo`sURK%,Yzry@N鎲4 NDe͍̥.K"k*m͟NCY><} %u!]FzHDYֺ;j|흁j ºdɟʸz{v@5iEp4PRx¸i n]翮^wߎ|Odzúp[- =̳?&Lgb}z4Zb%Z,'7LZ^KgŔ #(>Wz^{n5lMj7yͯKusbC2 #Q˧XA%oP+PVVBqyRvD5깙A__?<[[n:-9 ӈ_W{kNvSMᨂ yNXYr:@n\Om鹧yWi :.N~ 27yEOb!\Kjhzwq,]uYą'%=8M7 a\{DD "I/)JcSJTRE*%8[ *Qyx' `s~P-K!PЊpiXa70gOo8Ɓ^1^lM6%zkFa`N !|> # ~ߎ7g1څ0m?nFssP:gŶ~~^_LÊ"G]>~~??tnx#1gŚo\/w)"D֤06b4+cl󲵨uRr>tW@tZo\-W-O@&,#1ׇjfÃa @r`FB hk}kVq]K0b4;Vf`#4 {B|2~D O̘|eI:],# "l1NiS nZUb wR좎MeК0{9=#xo}>kKKkM@[@pj-cÖ3w1u ;ww?wS$u&+x^kK4ηdP:'(rqs kXI{@ '54EC={R:dTջ+4U 9O `FxQ^YFkLQs8ԋM.bAՔ*>.tfL3+rj l\J׻ Qgifzy͐OS%\.G,VZ:[sHNh#B(M >p_շ?7͍?sӐUv1<?Od(ui]5UP6?'J-٨UDzP${*1өZB̯k EQyUpZC^/sz3~d/%+~-gǹ>4WEi[,&iw܁__{oVղZbw6,~lP&v:>?7Z<b@n+GZX;++7Nd`R7.y]66*Zԙ:fٞ%=v28rqY3Nwu pGXΧ9 EmEBaش-*TFwUyse"* g|tBԀznbNd*@dd% BCY՘lβUϾݎ04rn0Qߘqxx4Y%u\pLE<DX%3/s?=oo˿?*?uX0{'S0])rz5)RQV8C͸rʤz0ѯ\ ׇEFhEv ;9ˡ!]SS ff!*$?_l+ >a=/pR\@+a2Eη2 UUIA  dm *lyjv=UuRE?ZE [oo jvu\y&d_3ֱzZ7M-3hoohrimq]~/`:I_*^W_=SK#Uי&b 0/B@v UņV^DQS:`yl-9(~:rcGTaE"ְw39F@aT59?QV&qC@1s[]F:n0=ůJ|"9WX5 Z+T16_m!Ae"` @Ia(o" `y/CqGKkkKeGMda6ez %=o|><̳gZ/LW."jA= |mcOOo|_hVNubÿ?e/{i^͌jP-s_G쮸FF8/fϗc'k!r1rkcÞ+A5eK _%_U!߃Q"n8lu@:B؇aLc q] cEv|NI*@ uH!DS&ά7 Hg[Q8U8SIzAٝ g54hL~4iE27 ̥E𜗑L ׯc}20qYAJ{4s§9? >A,Vm-yUKa$*ևJ923Ǣ}Z:8) UHh*B:yћ?o'6d |@tѳ̳<8},(ėL^AɌ[ #2ʟ vh=x{{Ca+̛^C?\':gyϟw_[ yf)\2ZCBF!*:rݲ{GOBSO97+׫R+}r؊;̽'fD)yu -F ?b)S`7L2 !jB\&",ǀq\>8W蠶 ΡR#okSkI7 Kr$2BGK;9Tdemjcn1ddGSQY&U3\[=D7p(xc6J4/w?eJ9XU \DM%7rL U!=%{a${?sr ;vϛy9Ԝzxoܲ&6D&-xӛބ~uA<u o5=G/|o|>BŖY#=ʻT(G s{+OF kS@f,b]'ZaRŦXL0`-ĵ cJ3nz!^ǐEMdDtpslFw8 RD,!uSN-J#"&֐fID 1ʋX|bAj̸-*#27J%%{F LJL&j^b2#P8ӿ.u(za<ē?sv̌}C뮻6M ACsS:u;]ygY@[__Yt-gs+­UUV$^ڀL,URSڈG6?U ,;2V  Nժ.\J1H#=X aTpt¸.ץP?8~?sK3$^nfDN+L+lLN\^1$s(tjq5VlÕ]( 쩟{!Ytυ1J=4ο4dzzN@%t䲥:jyb!p(걼y!/\8 FdKx:z dW^Sy8[N,a/*.pk7ftQ2J y.BN.INH@ȿի>>/^__Tћh780 .>A??O}S-sAs:+>9}կ+^ 4eHȡbPZ o5E:sDCITkBf9v]{aWeקoZ঻5vxd6;)g9!.9 ?bloo9 ~RuY,y:QSqW8,Ҍl,}ĖbE#uB!z*BaXw;2>bIV q!;92۞ .s$d8u[2QܕwF|3!ۃS: @uNG'𖷼y2;NM@p .5S;2;bDu +?)?d`+jw'J.a(UVS8yp{s;L։qVa,Vifw=J~ ŋks=zރbnΦbe/{ww~w&@kW=p.a: Aœs羀쥸۪ `,nR02F"BVa&^X cre2JŬ}f*8`{{kJuXcDP_0 6|D.)QIU44{ƥ`7Aytu|8s,Oéw^59#aDcH%kLc=6ϻq:_F62RBjS^n-f}\2iʕErQ jaX~kjboL'{U p`Og]xi~_\Yu sݹ W>\p~lfqB?WCB  mgfƱͤ91fۗqQܤ{6ױl)by Uװ Xy_]ŔCŷˊDyW I^)4'OW}C^TQ˰01:.5HD,iTq1 7PUxAUh M#tro,dIU D:s>Yt}8&wX{uq&bk0ld*1èύa{X,C 㨜}c~Qn:P^m mtvU XU%!dt`[j7/ $#<2Ea0`cK{N) T,mIH*7(7hzϓ"Ј  E9*'nvo_BX[x _Xu*sV |s= N5[;o??8::kq&5trS^a{{{>&TS+VC CN~mD--CCg,Fm¼)R^tbus͖k:Ĩ IH1= Y5XQ%hh@0gVu[@SLϙ z%0PUQj|.w({@6RXR{N$! !,@ R|1s7QU}THυPۻz n Z xَ 0~8>>97c?cx{sfto>_ݿœӖ떵-w=y?G\ڃ@s a[ 4C<,_gg EΕPRb:K,'clcu}aq)zevP̊0"DEU0䩧d79xEP> 0dƜ rsdJh.g)uPDOKd w5p+EWtiD htwDϜzwp Uq^q\MVY)gYAJ]1tbnFekfY[IѤAe贉;88<1QyBW_9= Y9;0RzAp+&wwqppv!ܒ>kS-- $-/ ^ڻq妛&K[ V0.}5 (.)&kJϕ׋KeEr0Lϊ=W>3D1YFEG@=M*ԷJ?sb:blIctHpQ#`\Ga@ʾ"GRv**Y LF,[w D>^È|r&tȳy,g@rIɒbd"&gMFf*c:0^<9s 1pX/RV—&X(kT=NS'9y٣u<_Y[Om݆w :-iSϲ{h騟5Q2AZ{*:"JJCVabIJ#`($25zM- qxi9< \]ΘiI\ڟ(4t^Zň|&{ʰ=!&Mfpu\1r^ag.f T9,\B #;dclDd2-,D+s@C(볹ezVTXmǴZ2ğ?4,}",o5ϝe9}V w]tRl.6vvvf&BasNh1b5'v-W!zzjis8@C O{udce|yMX&=*dB-sgTǨ!C1x#.T\a4zы+9^U坊(@a94fCK10Zů.ŋ_ʉ]\>o洟w@}7MHsY o{۪N]-loocww۳p&q&) Ed ʦ|iZ;)V~` :30O{u} 898 Rqvur0F8) cAX9Ջ>-nָ 'ߧ̤Cx%PoQ}3nh PY*ێn(+8snq.'"@X#d,g#,#ԋ0a3p +X~y=%~/}K']\s?\=6ΣNh]fƻneK&t]K?Rޣ:}#)b}n[FaHXd^{PM.P~ջ"u*19{sMҷ@SʕO +1߳cb8lw>qb1J/ CQ @+:"˰7 N/f:R1W@ydBqӂe]rb~5TKc%Q+GD! >btSiS#[W!U\MJe~D )IrqaݟF֍]Ԅ7OcWmU{V,0ȿ um,Bݴ n ~m݆7 Y`ȭ-H7#8ΌQ^txk9sfh[([qENK%@;rcRD>}1daCU)$Brg OVԔFda'q7;$͗#$AT1)%5)[~ 8Hdg$M;QYvR|\X^1,c-{p7J< ;]O%_xS亩a؟ptG~E]&7À'ݼ8lh̺ep @}x;VbEI1B+6yc7'zr$K6R<4$FiR9V0Hu 5X=:8.3yr)0Āa1a؇rD&_\\A8}:ss Nc u1=w؟W wu{챪 $/c~ 82}Q\z._*>DUn !s2 4. Uϋ߆6rnsJ,J0}(vTq LJđ_abNЮ#!u$K.ɣFCL#ɂn[2SvQ X!ލT`\pu ,|1k$,(qs YI717HLn' q.CJK q ,,Kb+]e<_bW{8u=Afq0,.,y3 ӓ}q<b [?F`Xls,²9Xheiz׻/۸x".]]@~^:7X:j ղTϭ*=fVH,pz"r+ Q''B8Jd3;FcǠAR^59I%RU0#sy?3brL5tu@ YMSN+}7X'0n0ݗl^5^psFA썣'Mҹ^VUI#wD+p@I[꜇sbmQ[ ^dca('T}rVKX| C!d׆XP??>~|ΒN;$Σ#8)t0w|}v[vwwq%\t X,°9QiYF> 76~1_U@\4N UH=- e~nf۫_) M]ENS mXqp՛IP u.G2G1*1?x\&eV9- &=xɵ|yaH-e^~Kʹ=<:ia\C[)]Kwӱ@D\P&F4cbil\bH朽s1fĬLU?B&k@&"V+wXWm=u07bXMd x"' $()9Hh5iZZjw śG2)dBŞl W%xI^[uGE[vDR4 1&xz ٮw+ٿ%$ ;&A K`}{ӋuelF {f*X:jqA\O#VedkUr&gcpe3G.y&5C_uAS> ^:1N<̟?<<3<ؿ]Ι78x_%uϟ獦[ysJ]ag^W/Kc\… X,åKN|v I6J{%wu&=܈L8rR)΄54!F ! $64N1RųepԡØSu-PuV=6bU%t),^robDq@B k\>,ԜCF JɝhcAJ(5!RcrL'i8>& ":u'f눘L|M50Vvc^X+@$G0 rp\mo{s<(GgM .5c&agg/^76G`?:M{\.AS 4b)a~$BU17$~ê3sbגwaa(FpMh$eA`5y]6jS{E 5zIWc~H,/4 dq.2^*Hc-Fuèn0cuCj W9klFVNK 9!H(8"+o.:v"KqttPtۿ]P׼5*_sS@{XMF6/vQk;׼5'>Q-qtt Ya]Si%s|t~wBcW`+uęX&j7CōF!Y#2yǢFP#2]e" ǩ)GD {IaD9%:B%h`4dk+jOʔ҉̍Ugyl衢1n˝RG)@TORD%Ź"jhCn2vB* W9Ȝl"%o9I>[):U.m[Km|~pyxq||\ƂYz뭸tҙLNapu:u,&QcxK_ N 888KS3e R );^Xyq=^s'5\*pdzKV$Q^-R$J)=4XMഛc3tj",6]B aD +0#8֙E-:)BTb4nf2M.= eKE`MbxXȤ60!S!]Ή}WF.R; ך4ø@maK^ S@B,pӜ&5k^6nI^b.jL>G089Rèd>q1Nj .ĠSC )Eށ+sQ P_h(b-H>\ \xg:>TJT}[X̪"uZo(@B\C&ne ĶA0cʊpa7$ \B`nf^M7iQ RU,cfcGb7E9$rs kZ,ˁB*bl Y*_8;Nγ8Ϣ4{9M@[x_^d ]sNi!`[W^+^=͋3EkdDW|^΃[z?33:iD>OqLA[1ӫaԬ^E VM%;w)&Y) p|\<I!TpzdJojzȾސ 1V pua{9,BD=j'pNlVY,Tˬh߹8Z愤ﲒ{Wp mE`"!Wy栴Q֮+NRˎqtt4a({:._nL^?߮AqȳN033^Wāq qxxzij$nh{<ȣ`kȜ{ ;bG&N\Ds+®Ec., }-6lIPpGOQu[ǜihI#+e1RD-&1iuFyY͹j#gBVrPZ\ǐÖcA@ÐX= )`GwNU6U~XzPhh%4Q1v07..m/j_rb/y%=}ׅĴT#n*]`#cggGSr46 0磣cw_,CXKQV~u>r"2p{$ .HETԔ7g;IBEF)[C VÐ*{2Py>dTI\eKA`fp& '\2(Af*Jo8wqǩiϺ4bxtp8Ymzxꩧ)@^W۟<`u{=BR_Y|zyQ<,4č/d.Ys&IAw Ƙ ~IkC:S!Gt c9i2eLˬC7 E슽v~ /ȥI#|9xB%,L&z=ePM5Y*N#ƴy7<;Pak!{xYBU:@pPTG6O΃$ K0AUi <ۻê7@g$uBZ}g5P61L^Bb[n=t285A0W-y ϣ:<|RZ+&pOY[VO#̉bf9G&tҙyvеTж8{q]wiH >::֖^s `m"E֑@EUFpeb.H!Qs:%nl.3:,%>2h;a|Wbk,4ƈI7U0DqMse&:pNX`<ꮕnSKd**``1+f%z3YtS[ +o\~N3rR3v0z@M 5MvcΈ#p5ʫc>m9-wyBvr.W\lr ,K%;dP$örci`![[\MXF)6``&a#@&=aX a@adQrq2cDM b#FsCngѦ\j9"'Иx@yDT셑x2rAQ;m! D)هCmcd D-5o'{Pn1yW(X&V >=Τ/bdΤ hP7W^xa̘Kť>٩H㛭Vܜ:K$ I<;YEv2IX+C8i\UzH#aT+yEXAad'#Z;)# )#Z KX'dV:IPrylt>2s`1R_'jK}tA|(JCfėQm|5d2Jiqy RON[ۧv&MؾӅN[S3|ImR25 tS};D"85d r78D)Ӆlc@\v{#ƪiN #e>8}fF21)ޗN>EZ,%3s1JB A[,9]Ԛ ˞BU+X#sٺ P8x(\R/T044f[W}Y59Z]e]_-{8~w]ħ4@D+j(?6.R^aZk)K`f O3'7VwS]Wm-^ *v1\gvߦV3#kƇCSy:)0.A)3Oe"4vI j5Z!|Ih`52(\*gK vd+A(V{-z#! k&@krPXJQN(yT@V9_lĮ#78piNGD8t°>:1E.u@2}$M-2Yaǯ|QwBvgf= &\.7B@gCl|{PV˥X6VR :=¬K!%pͅ8Z<H)^ ާCV">s;{]et(W -4x%!Q%KXOϡ :`pJ \)/8 e;y2@ !jdԚ"?F\NLA}a\w^@w u[N\PŅJ|[q2"BEd%Y ׯ_7ߌ*ۿ\VzV+H|': _n=@KR@AsuuԦFU"XݻxkR .tKY!y @) T6/k@]*M3BǀK,Bz>CvQw_M)3e>*[%.h"Tj?C^ Y톦UΫǹEyL,u,[S _lL܈.AIxsc"<9èJ)cNmm(tHte>f)D\oP $TɄ|޴p@?+GO;Op!pg{Zy.kxFlDo (\m"dn[[ !g0xM h@BaTvkT%)9dnc4]eduS6pM83mzOPuDHKWH13\9YX49oW!mcLGG9&/dY!| 1p-HVQQ*5.MIMm'Ӟ %Y2-BYMWoZ9ӾϲzO '6Վ8eIx4`b, |O{=1w fuH<~dX8nlW4ps&mwLe̬/ L0~"sEАF N,5*d!GJtqi+ *>(1S?!CP'#T I=\gI;(N~qѴ0mX%YLYYJf n_'J< w}?X@&vgOdBx|N\ h=8w ^ Xq>Y,ǜܕ_Z|V= CI5I[?1C`S !`Z0u=oDuE$"☤PmsY]Kqu.}Y`brk+p-fao0_2y6vzDg/sՓP.s{2=es26LL NJY`O>okۛ{e! N,h7A*ig7uo䤂)7YA?KȽ=$ uk;gC('*Ɛb _ A5uȘAbˈU]wȁN};K1ݙƏmgנ4;!CWm8uFJC@﬇ W5цguy9 791(fGp8Xs+Uu/hz! Ê #wL=!i{Fhr"J;.mȷ>@DamqXW,F~|LYyמf0UoR[nZn |RdٰތbewemPd5X7![H6`fUy/?GPSM}!X"(zjU5NCWYCP=9ҡ(lIlO9ik}CA#Bᖂ':eO.{8ŤUp9yB> ڂ:x%,ĈJ Dֺ YPžu>Z6;\,Az3~ʟo$|<:mJ8O{{6o9a_ Y"COsFG)eW*:XVEF8J<y"-Bj0bj$7y]ri4$AK!g8PhPKL?aoaL^SPEJ EEtBSNr\wO HO \^5ء WpHs=0tp}'v~6=?w;G<gn_i v7t,cɟۃ` _}#6U{@e5yCL(*}Ve,6F(Sflu)۠P]eHJƊqFN"w6g=6o9ي[H"/0*S$onviﻮC P)a= -!IUbu}b(QuE+8}~C%W B~"jAz̵Wީ@ar 2W##CV.s[e_܈C =溥e|K̂JuMp\ᷴbowoG-U C/%bؾZĹ,źAcHj jw iHB BHz Z / \]*`Dž9)faH^b0,crJM2`70WVuI*)5K, .9U"!Dkvƹl,m3O$K1DIFߧov.Rr\Ԕ=R6^}.I:e Lfz %+ӝjKvL{+W`L&-}e|'h>gu< _gp8s <6󮗗, 01e)bh:k EfPMj7&9t|Ip}#>R֑x~բkD1[tڰ)MNK})#dc^ىt9hd~)T0*.D#n^, bsxHDpƲX2{ !W8M SX>8hC)B*?UQq46rtFn-#vTҩ! NNN +W駟7> B8+-Yi*M9Yn(.c^ڰQ.^oz+bX.z=<쳚)|~϶g=}26f#SW,#T-D_c(TS*S D0c OLC1DKuZE-h;af X{S|-_@kNFJd qș#m(YҸHw h;x܂й^疕p J نSxHG-Dh]jy2{ɺ:86kWxSs|_l TX$8 A 36>1&`f$7)pnыlޡa~gQ2EJLbPiM {ae8 ]1`#,SVEls, {>վg)g5\biw^\zGGG|w7^W5?$ڢX,]]x+^"O+2K"*cYnﹷwDOhGx WnwxO,ɮ@;^""W"V$I )$EQKRzh=֚iLjZFˌͰ6Q$l ")@(bG^YUY[fV垑̏s""HVYXDFFFxs-W|O~kWE1,s0ƈQ=c.]{C/8C`?*1,PFqb6Z4k׮_̍?̌5B. R&\2 .Cۏ=wgNHL\rJ^ c>RV*7x3K2ZWA>0EɝΞ=wxߟaO9,)(5hM`6q}}ounܸ1}WxTƬyxWG9|9ֵgRE϶ќPLdI ɲ8)M>ZI՟u Re !>g6FM[P j2Q*V[|Ÿ!X3Y3vkg}t]5ek3껏0jNjQƌYk74Z YNt$/dWN!wqsF8w*)NG>w37 n]X^xׁv,h 'pCf>g K/CMov=GC Loy~ fxXu8:}&fb\bkk av'úO|>χ|>mݖ#'m8q\'BLDRL>b"fAI>  `S$E:vz5LB:+QbubUE=(6OsrǠ|潩 Ȉ@UeR'4*m!BX@`X ©i="lEwAY̩+ǣ1&SɤobY: c@ ֺB@#FQٲ;jbZ{yD>2@</_}o /a讜Fzw@m|o$#kl6gyy{rzd2xt3 } vB8@٫ Ω *ժvw!V >ȧm!0)cmm-;=vs1uǯTP+%/Ù= ]TQe%U,I4AO y~&F'"|ИDr,vKb9I*LQZC-]FvӤDA]#E6JNQ剁td)E*ˬsVS ^#}*(8nhLjO\ Q,6˲c&J, Z;y>ׯ0h8m԰PA| o{=Gtn _w)!Ox` )TA>j/Ϫf/gӽb0}~>Z+-6M7nv~:Jw]סmA &0q瞻2\ @iιTeEN&*{z19R5%hB0Ԑ9{*=j']qiCJq-i u _+\lTD`kb=]GvG+0m/P%20:_Nb R>yO_u|+_?$P3@LPД4pP=wG;^nt%5ʲn,[v %<ŋ_S@I M5h-#XXq 2M,|w(-\@.(DBC^ ")ZKBXӲDd Õ\{X$U̹lG* Q1.E߮?YAJ; @zR/(35U`L}/iXmUϨ?_A}s0O`rZO ڔC_-.`d]RyDJ/TR >@\E=iwW}qY 3#jڹGQB0&Y2hW]:\|qꗯ"q!|CxG|`HX6 SŷQ*yޏo?~wK5*vmo:: -k2a;[KgxO>w=4G&ҿ$7<(q[y+X1qL)MDGn1 `D`3$waC郥}cNPcˤ5v{aƬi0ݐYع{ȴ.h܄lPP :SSA1/KPt l" b# YVE5ٱXN3)Ek^ s)O5: ya:뚕bKbAgz0諰Et{fIDAT<ˠF,1B42΄;9.lO\7yC`f|Y^KqKVԡsPﳗSk.B0X;x [+il>7Ao~`!c׷;|:>M>W^3/-pR?XNb:e%fL5JcNş1|/}N4;7.*$ܪC:|!;'LE51B "54bV`# 7jbMzЬsdmg3KFTQ7ӍΠ~#4et ёNVF<^iChL9ˍ0x2*Xg-/.IĒk^֭56[]昭뽴dRh^4K@FC, UXv5̂"w_š+W@$(^%K'D WSBw?qS^` "<㻾v@쀧DnEIe_A){a7[ E#/c@Mo+ f^DE HNIxB'vr#fąk׷u%(mPspuفs;}8ux_S񯲬2DrpMIzKbպ9JR\=sM}@}Ԙt}} j|qѴ-"nB(?^me _q ܸ,ku[yT 9թ>Q1PY>eQbA!fVa"UoޝR#"€2JƬT.PQ-nJA>T/]t9&?:}sQ%X] }'"^Ɠ0lLyctU9p89[X_Oe\>F=gyDZ KtPvS0 j`{3n} ?vE@ ꯁ5v`!o+@DP @0 {&M 4p S"%6I2FV.l l .\xf{p k"?Bl$ *AʸS+|_c@w!:|5&z` )@tE)4M{xD̛i8V巢j#bě1W?gl&2!(YA4^T/\f؁f`}1hW%[3 ,^o? 6XiFo!>T`=|w )_PfYx }] 1̰  ˆPƘAVumy%n?|M-l`Pn?]26{ª|=N*FH"U"zuM Ht8g㦱bh,=st~\n>wkĆ0UX;ppІ-]R#bWxR{2(=[P_i5S l82HD(U=L%X%ذk,$-( ǘY%hEF"ӃB8#FFA rzD)ԇ "{ k3@6Aӯ~Tb݇YCع:?'Zt$눧~я~teTAN^ަ`17>p3aƅ?-1o0A + [B"p )UI#WAP]ō6O,/kjT= hlc u9|gn| f1(Pa7z4n@T^z"B,jTkS *<ȬaSe'Ǥd5hR j' nZP0M es(#?!4'1⾻W^Bb֪yI\ T[~LE?Z=, |T~lV킋8uVY?>Lv{ vN}}P(ξ;J.5~wF|< RM! ']8 w Dmdp X/*h^n#l[5|],MD!|Ox8pЎ^%;0uW AE]L C 7E2t7L`/] \l}kʪ,ia ,7qXw(>RMij_;Eilb:3 TaPq%>ĈqŚ>ߥdQgEQ-/Grmß# o֬}JS gY6~g=&S5fF3nDFQw[aQB_*?AƂma GrE<ܔqHdUZb 1yks() )[HQU'b&9 sE) ~kx~ *{ڝ_/A<ܯuWg %!kkׯ1y. 8<biᲑ+cʴ. .)Qr п[A?9srQf5R l =:E'_>mC'@?#?cǎ[Ƙ}/k <ʝ@;$OijB]YB[T1@+:9WEڴV9yRUQeMvp & `Ђ ϿzMF]nQrKڧ\aTJZ0+ OU %N!ع7*# 8qME'M68nx#ױu~CU|7 g`5ˈ];ZmnQQRB.@"VY"o\%-nnI1|϶Oa.##S64SX&ЧM}z'is$VC.?ir$G4s^^o>,"& @uNt( ,6 Bl ;?=w.[(n{ ;;;9JxC`?J誈qbA :ʿXkT!XC(o17P( Y-b#,׆Gyxqн֞^0MXi:4|l[63=xq_{8q|=ʕ+9۪ԫTr*~-s̵_z~B>Gj8<[!!Cg(ڣ?#ȔhXu!AdJ>RdnToF K G&,6֗/H7o;k ֠mZ8.(TIY=L#^8}A4$iy":|ab484ہI#se@NRLc(yꊖ9volR4{W r!*:L^=s?)M:@)}ޚ2k'u9FTsCwU.r$O%JgZa.#7&w]cx!w_xz%X~:НxTHLX)U7.@ `<ÄX 8w:? YHg_&< ~~??'NdՅ|x%A!2Qѽ(OMhmw!'@%}aO(1P"O0rS)!3%~AQ~#:.V z qiƂrMcn`e(e"eY{JvbcDF\w- xx {@ܿvWѨkd ."De{>K[^ ׇO>ٟOOԩSEߩ_ cE5=_cg)`\W }B!(#fԀrJx iϪ5"?wLT5bDXYlck8z2NĮ>Ÿbh!߷yݞ1,Fo1֊MCub1hT9+`Df65NM\9X;/XcxC$/6p-=n}ᇾ`n3O~]oʨ,K! 1F!V]L @>jtΎ,KYŷ>[V V6D[KQܕ߷$Qkݐ6(#+X簱ޢWqǽd:^upwxX@FRp}^*ޜ%hCP G(P E//a}<}~}@b%w._+;Vbi1\sSSA)5~ ƹSZ668 F Y6h߳`.}ġ1^lƘ0 ;N-rJT_eIRD_K(C:ÌG%ଫئ2K0)!-Pk.|!?n.3T zI&7qq_տ)C'6_zZ:eP يEtZjpcbBZPѧb'#!uCwH$eétʖ9aGj% jMS3WŪ`gqf/z98\G [ /y; @>ñVBSb.0/+Ru L ; ۏ_}~P8Cmہ*/%u]+a))`SUTڃL/D/ɑ'{pcsp䴰JSRw 7^7^:H eDJtLʂ Jŋ HMNVk|I K0 8ƘjR+J֨vZOs=kx95U<0Kx} } }ҫ?(4` \|g~/zX\xxCα,y(5͈a#Ӭ(k |*Ԭ6΀W0cn.G<#\; @ @(^xK,4evw^7lY/g6MnDĞ@.".o ^y=O5~ekey^>,;{Ul `*]lW&AS>XU뭾A'L݆W߫ ^` AE_W:E\yU==TJƝ^"IڛMq})Mn8yNL^d qJ= )n@' MbL/ +pv[Coq?+.!Cᩚ$,mMl\M9RB X9*Q^HQ5}+O |Dq`@sPr!T8tA̲2b n˸}v3,y CK; x Px@']ɊDwӡqkpV k`%j\#<~yG׎/kRNbʺ)TP9L>iz!`6+$ɂ"za.2Ȋ8:M3A5icigϨ3iѻߌ>mo{ > o_t7Vr̓6?B8#mbxU%:}29q$tadWfH_tT4L(Lɍ-c<ڏ1fN?<wo^Ö6ZxXA`(^8;@IV7q+n}vv 7a=[F#rp;g2]srMi?xӛ4Ypb*q/%A{qRSfn]WS [̌τ3h WyB}vL+] !foU3¡_A8 2Zu\eid EhAH&6Yxi-!r&N3 9(w]n :JR N1dڌZtY zoJ855`\J"c,(%:0@cI1@v/:jWk R^|χ73ăx#Ӓ';qVn]c.:45֦omz1ǽ1W#_XetG> _05x/: o#^>ԃT ?<g_&>7u'>k >_}<>pxI 5_@!Dhd1C(mL NM(.ΤI6Wݒ '4ޠ4 ڂ6(^NLj ^jY[1G?,˗vgyi LB\HnPv7; ,~H 0[+~ g] Z.Rc /Fg$VmαrC "4QX,_Dt`g$Yu 'fE{u{(&'9xmńa{LA;c5Xݜ>L")Fb- g֖ovfO+ԫUg`z#M*"KSH6 c;?w׮/={1ve|,US1dem9 \f4鯸y uQ]h0Pu$~C 8D(_WN^DYfPs$ &TO(YԱQl5br=b-r8D$j;ktRB|uӓŶm44.&?r@ʸL߆>2{z>ф[8Ɩ$[w-QgЯ)^&9^Z8OT˸7EztrZ,fRR*"k^Ɨ/J^b#HYՁ_F ^{yM%w2z>`]?w#ȇw]JY?ÏTO;kz,圠ASC۠i^k; kT+}Goypc2@>f$;vy2_Jm¸*bc`mS-KjClDXN}\uji/֞PBA ,ڲĭTק`:$c@<`pEGZ4Wu1 jX+uއ|@]0}?#1`[ P馹0rls9@Cȃ{*Sv㜞=W8#/p|/ݛ a[{{B*~G=!;r~"=~~ \}EC YBW-}Z} H,vUE J0Op'({-UÓ J)FZ pGn} 1/dIQ'H|aԁ3v)at(y۶Fʟ ւB!US*g,Y[gbݢ49­r7YT[p5=2t_ :B%@3HT&z[O dGᜅ ^1p^(3>]/ӝCX=

H^0Ѫx)g9ŞC~e]'<1 yܿNH嚣PwX ~os;ǿdl6xcÜf IǨڒ5Vm8gA`|1I,82E9Er No=GP"OBc~?al=}7Οi@kSg"[9@ |,ZH,жh6s1ex8꩝꣛>V t9FLӫ+gv %V< \R:@߫rwTM7y ^G60j= \} ߃?evu|{=ƈrOo`*~| H,C`Ux xO}2b٬RڮW];i]>AO\Of7HL8'Xxe?b9[XɨL۬ a_'y~=eAՇYl!:)rZk6S16>&4z("]VPΞq ..c+Sd[ c"W`4,3\r 61q35Cd >ۯپc%RiM>^S ҁe$z 4a4g^ FaN=^ z:b#֋j_ǃɏ߉->Z@z@S\`yU>^p3>18s >O8ndw; {L4*-yWUvs!H؈Sx';OX.~.17 jXF}2hCH"EwdSB 8 (靌%,|;h0{*#dFh(O1|o?= nykiysA S7hK;k:À1I:T0F̄#taY84LZrn\%YQWhg9Q| pR;>|~+8bz9Ug>яfd8HljJ۪a|߯l-^~e|DuhacMb^S{ VAj S&Uc"C )f ﴿^Ν?J6X obIo!H^pԝc"&""Bs3 63HsDF&eWitPa+4E[d]Wu8a|ׇ%?w~q@$‘n~_Y4s`dbe_2e# d\0et{xY*2ے3{m؃=hTD? [ w='H\=#.o__S?w&M!{/e.<H>V-~թ%T~ Νoo`gP 7f@_J|e0V Iva1jԂ0xWYE/thg{?4joS;si9'?-w(b;5 AWdVA'> mrO0 '{4 >`/;Wv.!Z[)U_"/X Df >M+ 0:)ʅ'b}^xǟC<A H&Er HI Oau'|Xd̪a #}V}#3D z;)2lz=DZDtDgo6r (EI 8 n]766C?C8z~_U1%ZO}ʑtCD8}4>Oc{{{hTfaýgc!'H\F+KX$?ĹS f~"U;DusY dF]~dKNz0ȦV K2fB'0^l}(L^^]T8Hï|< fP3-eHA/I0݉ U `$2P ǣtyEB2;1*GB&p>0(JI2 mL9Ǩ;@W$IJn(@ќGxnBظb{F~q}|=9?B;1`*x/!=V}n3{&X5=J,0d("Y f{O 9R\ƤPM}1aIQNTfuX+M#iOUeAiG]hWAi#umEU`CC`bf*GNgvp<'Oww;qR[?Nz7k qį2fGygZqy8YNM?xBM3TPcU?$U!X1wWWyfu%GR9n1LX䃫U;f${P1 N!w/܀'ʩ' C2m?hW_ x ŧVv%d84`k`XQXKm0`ac |ԳiMS%9!Pd$Ӄci8km`a'))5K3ݮ̢.;OIwuY@3yl+2>xSG)GAR1 g.w=s!rV^G.p&DXx.cK%ĐCS|cX}u'S{<`%?{7L2oc׻ Y\y tKW?xWߊ;cP,c> M u?tЪ``mUO-,} Mw%1#أrlht ",W&5&$EC]Dlg{5ظc晘!t3FCa>JgG}c |t|rΑ١@U"J#+K)6G ȐfG fw~Ƒx_ËO>_7 'Sv\VRjMRt:noDg R?#L gIV!A*w.B!̞۶mka"F#eb-!Tw{n&\yxj 󳇌ܩ6`+hMBN` P :`|DmCcgSxx? [Z-?^ej.{c\U̗%/[On;6py>"WG28L'2>lQ|m .=Ç8zQi8CwN >VvO8!!\qX5uLn5ˏi5ިP4j!{CA!1Ki"e}ӂ"(F~_^5k;@[8Pqb_bPo %RsBa4mpAL^@.bc!0Z%kW:B~IRhZjX}@XrՓ*'c? _ݭ븂鳇@VQVL dFpoL_ݒ>ʽg!C977 ! tO)QZިY#BdX2lV|LQwuR O+%%[89G$&KA"F -:$ ~?3#x ~n 0<:xg c!K0@A5PȀB TQ%YSҁFmiqƬP>;ZY W^$4-MtV{:+ver}s4h /Ǻ_KD2L/922-^k=}'o}[U@Ó) *hknկSCr]W3}?#hrB8x&S 4~Чu3E0ƴn\Ӏ"Ne}R4D,2p"8tN <4huMYFb&a`+: XI0qC?_c눁qs/Ws;NK0L2hշQ~r62d͚X*yQ|5`LL[RQ ;kȄH}1$XP)c}2ъvO\ߏ&z1?^Lh)W̼OKl"(P,1,E n\coO%/ǻn}ݙV7埞"|j꽺cę3g#ҥKow?48cb݋69MeW5 `y01 Cy?@}Gw3`ۂu\8!#oZ9'(/NB"RaHL@ AJ$ !B˺"#ȺF4MpT}~pr&S](*)er 7u#pǩ8wrkvəZIͨ'-Ȁ\>t`&N[kp6<8)i//( )\@XAhZiL<ãYz\"pjAC Cz^jW_}uDzjR[b;O sU{ %*c~`[ǂGOߑC|a~YrA')tκ܁3mЫϪY\zƭ݀5r(<3GfPD 9a9P짃uRP1C,; nkWwp5,p+[5 =? KT k}9LBmZ-ƀLT I⼨1( XKe"OPN@9C<aJ `^++LCvͮ *:OLĻ4{Oy:=81yPaC痟… ?ɓx[ނ *7[x饗Cfيd?m$VS~Ed?xyoCmPC[.A;?, ?c9O7x5J evI҈GۺlȠ; V,%md`g56F 23IY *uTY&*hSmcLbq<~_fs<38ҳigj7dPG->xh=2LO& nF!-Sto,CKucN풔pQ~v$>8aJ2z w6S.|MG/9:/ᮻC=Tp @]:K.W_O?ׯVMv1xa/W7V|gLC{}VW~1c7H(FJׅoު{juV1T8f`N!xel+ ]e(ATG\\042ƨ-e+`NBTOs@$tb^,(O`ퟖ LNaT8tx_z1cmm`MY%;|Wyj[M )xJVIyk%u Ny`qd.5駄Xqp~$%pe#Ayl}i5 cq}ߵؓpML00 L35՛2]ǟ?;xu^x9smԩS{q]wĉ{5vqExrfdŋ¡Z:c(I!1c n1kCgH &4ؒXl mTé7'bW?x*u i%xwbmSeha9E gD#ö.e&8ȶ&T Ԇp)T+]Qeˁrؾbw+rM^"06d|x`"ցX>)"W?eca]'-Nu|%B{]A*bCb@ :Oݎl]Lj *d! Qʨ Eit. M8MӢaXJ TV+כ A8Yvq Ip> )U}qu{ oƖp|R/kdo{Vq6*X|b¿G rl-bۨ#Zq@Jb$+Cr@#R eL1%17 ZA ;uo>?^(wGMwh?𸂂\;,.]3g#n|鉋_8;IU=̽\rzI.?ChH`)zXh7\<{G?@x!KÃ⯅?u@?7כS?aQ8[MJΨET8/f}a!*9{,K|4q=Aơmd%ZlLPBbhL4^72*-U.q|5{&ahEАȤ/ h5$!0O@"͖tg `8i,YQXC* Sp,BuE3Fr8+@. ]'<(v@XŻL DO8xR-*90}0L-}W. d /I`;[<{g/>lƇ9F{ Pok j ^]y3-so{’gx7?q*~DA(>9֧3mfYa}j+ZI Kc}D󌮫A&5Ko9 Au* .zR-S 6%o@zEO~bcg OWo8i4dDZ&=D_U! ceFzxmP tx <24Lь*}Ϧc)jA{{ a4ڒA\\hwdg@2!vw|a*Mlji3MU.wS1jJd*4X/YU\yE?VxbWa3nUB^.N縋u0^P8aևƯ/ ?Wx?K"6% ]nO]Է/kvH0gN2gb3L}qVxj*q%6im|bbN,bB6ђH3PP19zH!);.Ey+0𛯃MP`b)lY'C(dc-)S@SfNr<D8Va.)] Dd)CAMx>c)~hq:b&C0Gyޛ5=|O5Ļ eL $Vy Kl.?{pyvn!tPրyrl #-bP!,﹉ETO75fh41ԐbO zpB,?Z?^|=,[)FV.12,abPvM"x-J񧁥M sBsfH=sm ?9uRlߨ+X6l)b@c ؏ax+/UM uz4D[-8~Y 80 cc T# wk3k7&9X'+W6SL5r/v1?K喰  0>/naAwc`3D aEa  -\?*n?yoG^/Eߧ 7Jqw{5,aY18V}s~m+5JDM|1!XgahxKiB4 ƀtr>5B$aD)Tj*]S-|Li=ua?_o~_%ؼj-N_C,:SUeDd4S\ƁCXVZ=jҖSjLJiQX0,4bpSOA/*r  %؎{,t]f~뢾w<)Ŏ* T[UƐL=׮+gᇏ7>b4 ]ԯ7SHO?S34F/ r[Ù`î7+Y,w|+x,θ7F²FC67!37"  l. 2jYDbz}/v1AB#USrcT͘۴0FfcvpDf5Jb-; }`X੯e7:H,^}b+8J*cEA@O{r3A7e,&y2lJ^R)UAtTMLvu1"B( G|e`%b#;f7\sZQ'I1Y¿ ˥}B^ ^h|!+ȸbA d/غ:nn?1Å+*k>!pW `AOlБ :4)gѠؕ"]ޤi <|ggj]  v )dZ 21:4gW|xs(LRIM%?@rШ]#GDY7yj;A[Kz;}!XuM%RKȺBaNG3 VE8}#~_. 9pX_}@`OшuA8YN9LGKYO!Uc|/OFR^h'gq+&5/ᦼܧCb@{Y.PV1@cyh3DI^.__ufA F2cQy&i#ԑJ#=7s.|6|Ks\eI g-<&U> C?.qQ\iH63Eׇ{፰x!h0 U CMCfPퟌT "v l[|*`l.mY_>b%<6^|G薺V&F7PBJ0|\er`@,'x҃Zc,5st[p K2|)^-cKorT aqq_-w%G9 ! J_Z SPL8JzZOql 3[bqu sg{늢?>Ao?hǿ_VAb* CHv( F5T]SPkhZOu7;3ܣCze$K8DֱuB*ֱlaU $#/s{/r%{w?{.0~buhT"Yd,<߹Ttwjnʽ0{ǰK̵Ր:f1*0"Q6K3im}|gفǸ?`/K_߫ŊS|8m:JoPF& pȆO99t"4 ~`,uvF3cEFhg\gqru)0lꀩ,rq?Dޫۣ Uek ʂF- 6#b]g?fϪ_{۸r ._oIB)r*yiQFM{U=H%xJ޹kotMjVsUo}kSkD5b@F Ȉ?8y&#d4M#yp }>kNjOoVHNQpkglNDĥ1"!x *Te1#o\_lj˿y`'ט"A?fBH,XZSC@zC.y4<08xl,e WUXyn>c׮]åKp? }3(W4\dס0:Zݓ;k <={-^ᥝV~TZN!xm B`)A +؀w'5FCrC&Gƒ겖ɾ_.R82bmt2K{1!H~ #ڶaEuR'0Jy)Qt$R6 Q-N<><|)4pp~sÐovFVohh:zH6 Ẁ`Zu/9SPƺ"ЩnVGz&\ S[857\:lSg?#,^Fce1 $TP&n\ Ǝ5S>TS^ٛՇأfDaؤR 1:;v GE۶`þ=Z&\k׮DdsjP0ƷʢpU$d'X{BF]pxt`m]^0@4Q/9H1FxhLb{1duؤHjW"JAQ1ʔ6FUr"fB )dfZ I$|֢q똭y8.p8 XcR(I-yN.N=Ԗ.xU7+ARNC2/kU#cdCM6Nlic1fY9哹MTUj7`6!lu h^$x 2Yz.giB*f)bb 2'pẐD@IyL/IObb7%i^݊b CX[[S^U[Zb\.nܸ12RA0+σo3iEPCy@7=41uT D [\-; X,EqۭPezW B<R@ldCyN.[A=LzIek!(4& mlkk'Oj􄥄ILAQ K%.ʦ RLk>:= OQ^BKCNy%/qđC8,_k^usZ  5GHr<x.>\8a)iH¨;~Nq.9R.u5;H*ӥ}c<|9EK] ! LĠx? rq|4lѶX{;8 zoHMиmM#omۊd3z#xb\.=CE/kk\h4M|i>:<>HiE(K&(I,f>J^/>9=[oNF$ԋA]=5X+E܊*XQ6J!Oًų âUVQȾdI,/`m!T;àYmn{D}! [LxБ 7m^(ZA䛕/=Q4$T4' ȧCP|4[Qͮ#LT}iڦ[^3g)YTGR7w. .m^B 羊O|yXd7H240T,t#N:Bua76:ܞr- jR %N+;dfaZ\:{g+ @y^L~_<|YA.^_H\ڜzwѴ-fuİkm M"&ŃTvyx\i51߈ ݹW,65J/"K6+̀!Kn1hrç^2q3(8bA bcUFy1Mj/ &U<c.LKֻR_]YŬ aAYH? s_/ֱjx a9b ׀n$yU,M ,G˒'ӟaEU)ʁDpbw 6BkM5KݡtuPAɄPp}Q?3H#v2>+.D;ա@NzK,0wBFP~ ؝KӜeHuPEÀI5!%_A` q_|2V= ;')qt7ϧO;{u5|zqzmeF { h\=X $qeaLNl#WV\1!)ܔE`Ac5܊,WNQX}D1jAeK}RjhNa1O݋< ZGx[ų ƾÚn93:(^\&el2k?3s"Q V+ B>N#2TSC~vX2'>馎1p.qOyld6a~B8ț7}%xyWwbWpjgpdB4 D;5eg.~z J'HgO^>s" 3Wqd6l6C p~S4F1-4K(6ҙmF_;2Jf訄B4G-M,%/)ch;'cېX1Èr7%u{wǷ/;׷RӡXH|xV.bƙK|~L$\A,@)iQ"+5"pLʽyf T g耘1k[ltjESsdj~x MPvBGأt3\WԀnPNdANv( /&UAcߌ5' t ' ݼDᒣyk!7b6ւC.%>ɓ$tf{4dM1f\9ig6):Vly6}5Wpr DG֕J&ϕiY&2IKDDHC20Oc3|10iMZ[ite =@9e:E'I?U{y6Ph5,ӓuf8m ҡC|ΦZ_- i[H1[pˇ𫧏a]vo%3y 5 w6xjGӸZSJ:!Zm-}hR/29 YdG3X.(q?CA#m=RpzQ^/C f2 ȸ+m5ƈϼo{}piU WFW$XJD 7lFX]/)>ֺ,0DQ-U;F)1QRQ( 9D,;$:C @/V!X%-M\1߻ f kkЅcC04Xtz3k1iӿX&/:PuIz ĸx S;hC ŋGY[}RB:7z8i[Td&ڬDh_16RǼJzM4Uk`ztiI ~dFCW~Aڦs`VFRf4BqO >B"@\=/'׿ / b9蝌cwyTBex)1"rtߵMb0B^Un/ DDCyuK-|pĨQ2"M촣q`c$t)F) DwqS?X#Zg{[cЃ`f0?&o"x\=㗿?#5s!`{sBs+Lݧb'j,(_bz7WNo|c X[[[B R7Q6ɦ$wWwQ=_%ء !`~]QyUQÑ ޕ?;+ؑVÙK)R!ZUiʵSy}-R{8\)^/&_ z(S+MIs3}nq^h'th4 N|Z5*=L^l b=@ 7 I :Yf TN(Ft1‡eFQ"(V:kx]~ 0 a7vHS@蓛8)J˘Qb`L=p!ؿ{ǾKncBH{D0FiO!{Y]|,vIjQg)|Iq ӌi8\[p/=㗾;.~+.1AB+iZ4I8A NWϿz/^^#Xߐ⿶6G۶o&wS)^c7>TK\ <ԤP/ie`:9A 3aCAGq:ױ^:iдB}Bb:nLf[<,:X/Y QmXA¤7V][a|%T?CTb};^| o *C-t źgzb 믺~=@Z-<9'F^;(5Y)xjFn V4FԨ9fQFr 2}WRgg[ @׸(DBH22Cb%C QZ F ȺJVU&N s~3fN~֝sOߧ@/-HD6~##,7C ZEY-OBpG%Q23J,YK/Z0&\"G]DʩM?VG0[!ń@g E7 4)L8x]bsTq۾#W;=Ësh}WhSE PGTZD^@,D׿ ]_:֤϶Nviwa\89u&}cDh*dz!Ю4 9ht"'1fzH xigۏ#W [Ċ[IQq\z }$xpN <~a2g?d &AtA?Wwijpւtw evq ͺJ k GXDZ3l_.ѴbHz%>vzcgg5ĉ 4U} Zft~U2f* rҤC͵_/_[=2gOcW`;R:Hyj0@>i@ۂAu0! !OC'MH{DsdIwA tлb THGafzJ{UԥQ KU9ni >EAz$yՎSgd^ `}J5N_Ө:`!ef1C}'| ;6L  ϳ {A~>x8Dr_y~/_kR>YjQoط(:}5 J(f3Fr2H~q׸{)̀?-DҤf`1r ^jw=f%;U8c=TC`߁}_T*$X I3~q/<ߏǏ_{^|4dUCGTA7^UZn2.1fwOS)(o=^X9kyP`^Ja`\swNJ5#@hcpVpNjQO*3{Duf$[>!,!U^Hxxmٍp#8v4tWTi5P`9GOI?kgծ? ֚AO¢ejvGTBcv$lGB5u׃ O )BdlNΪ}cX7 8F,6>迈 0A0rO|}#?)[9ǿ~f۾Zb,i ԓ.u)!MoU&1H~q2|M C>HC&1gmq'' ZP &f@I.E\E2w53zXvh޵ 5C7&D1`[Fn G6y3:9ę  -hKIDATv^'1X$f.scD՟Rœq" 7&In pD50@:ֈQ !,eJ"[F _`֔*QzI %*8B@h^Co{;..'#bV3H?ϵ3d6:@-}2sKmDagTAu_ 2Q)E1fм15FKCg,&q@ &&/di 0YԴcCJ=:Q:0C?o܎W&֮?#e`e`̰Nak^qᆻ Ƶ8ٔ.m"pܡgWb5m&t  >(Nh11(f%+)i_aҐAr##Ѣ(s!ަ;fagy)MY ڡBBɣ\fShŐQ}Wc=g'UF 2(k/N(ܕ gog%0 Bxz  |s跽^{~VC@X!&S W<'6CFo-އlԖX/]̭҅JC6Jރbjt+0bT-o}Y/I^%.ܡ&|WlD5 "ռ@1pdT y'XcA0C<\oup 7>1";0a{U-3" AK\rWTo0` z4sk!/U:Kb' Yƌ堶e0y$#):5HEhȊ=^+@v6 O[m];/oG9ɼS|ͮaV E?"9,k9^^lҢEnpLՙ}雊bPh ż-i X>1F4=9t6}L8fӹX֟QL`l |şG=RnEaɔ CqX8Ȏ\A^;K=xȡNBE*5\Ip>C`5r߇c`ul'ӋCIE$t.);{, QfXv[lL˫ P,`lI^/wQ {(e((ƀ ȡRq*mkM1µG"I'MJk\Y@^%6ZW!VkZPyA137ktV+C-8!%IKZID2Z2V $aZl"#VR['P,zY ѥ]%# &)pN:]`)KճtS 3Q> ĸrH-׋Mhv(񂈳_G&$U.;LFCGw$"we-dO"uУi{:k܀[r5!b7 F $ȉ\ '#Bi_]m6#E<ى[&F31{ y!@=q4xׇm ;|dwJxf'{z^^Mp98 ,!L[$Il/ _/KLa hKŲG B9ik0V*`s$A鲔/Fz}R.*g؊i 4"kAky3E4ߕ*4y$]̭E1 )*YyIŸ:]J۴yCD:H.X,c}mHpNNI%E@ 0#Dκ:,wvpusKO-TY~fB/o?xܳ, f]Y <*[|@B3`3"p ~Ѡaj%_k,NTQIЍ,} K #1]Lqx RsfAu La-FťNN^!3҄DC&R s$]`bdA^25"gQ)M!c*qVfDU(nDT$S5kJPQ]JU,VST" #'b@d8ܢ*3kpۚfl@h4l 4 Q=st}^ň1OdUL3&?6+o*[5m%03x]]Yl./qjxLڣŨPRX7N!UXi{IփY4ɕeGzNר\$:B%fr{Yd25BjBzFkHN* SKV!D(G/gSC~ ƶOV^`ԉ+ȧSuʢ5 byc^~ zf&ΒN{+z6rR}{=BvoNB} =^> qw4|Ł 8M ԈJG𢓈!dz"Ba.N_c3%emWcMbGOY;%*L4Z Ats9 EZﲸ ʒ|%;CH;*߹@=.3D yrxex8 \MeJ9j[3/a+W-~PRKS>z{¶rONg3(=>NJ"atV))]TS6UfC,k)He2.'( B' FmmJ0.~ gr`1\8$"sHУ) ip|hqc"%v2K9"rFy{QF8ja,'q\76 $똧Lg otlL$s^~U2e8r?rP4 &ubXXb8ط}/j^K`vX.;ǎ/ (t_Tqigz= 61M-[ç&`;r߻~82wpx?k/==jGKAKOHi`[Qܜfiv8*^x<V/&[;'dƪ `l-{|}/u #D ݲDm u™gFɸ>]bE tC "y `Hf P(>Ezq*a>$&bf:]؊ UaU|YD$]izCHIv Zq` . THU") Oы_&#YxJi&?WdzbNFo`/ÊjG驊tZ}:TAڌ:-gdXghw1(EQ]2) g&t@$v^ŤFY鞷ޙZLʵ(<=t)D|~㈮%lQ\1*n=(FU$L郆{ƍ uʽ=mf{0q4@u:< \sՋ{r5-\7IhwF#4c8Kxo/ogdkKMG+=BVOZƳzHd,ۜ6dN M`B^I+&ۛIi/CqJIAJIqN̬vn /HY":X^) Ӵf G0:53%FPJZ2_m~^*QDa}^)PD, S VUoR>XbF?kfCģM,$PRC]4^č+exVZHs)"G;W'ZA;LWŏCԫTĉW\KZ|?_i#4H1nغ[z>33']˾lyLYw5D%rq&P8+PG4acm,Xqjg{(c\z0u9]sIt{ulDKm}buBtb̖)A6sJ+3r),=kШ/De46S ]):Jyw+sS@DdiAZ}.X{\uZuF)eAWdk[p40FkA*« PfI.d/Vv޼m55Y<5)ɤL%4Y@@(~]k4TuK w|Aqk;YGG_"˵K<5˙B;< P&jr6|v3)(,w0w9}aJ{ekTh&*ٱ9\k_|G>9{yy:Jo-4y$ MuQKAv _Åq{j+Wazn\/VkW3~,|ˮE(,bG=|@-AڽA-7d"ᠪƀG۴:60Xvx͓KsH.\TwORyN"#fL2K"Ѯj0`6G\ =VCrgF}uOnR+98d8 2j7pb!D$DeeyCݏl{* $<9Q3Ӎj>E՝Ln2/ z)1uv֥h vcz^7灟U%X4i%u-RrZb޴JYb=;y!@)q3̪3F&EVtI4)edz^_>˾C䠨R4媀De/xP"9ȱp5,|`-,!i݉TdO(|64xFrqLƊ@@q;:νɃ `aAIIdZ-ɒ-Yْi:lcvkk\[rZ*+Z"-( 2A0 M^̀&T 3~ݷ=;_jaF0k@@6Ⱬ/{<CWOjxӫx#ATj%qլgqKi僆iќQ( &p枏[۱>G©Ç:H!cQܭ޵S u4HYSv;,p#8&[ ڮͪOndX1dJY j0qI, tx2 O2CkkGԵ'pEz\|iw 4)~4|w6gp8ZUjEiX(XK?" cl)0(\c`jض*@GPC)Td`˕_x 3cL  T@=hI9VuӨYI]B]jp#>y83c'KK0΄>h)= ¹0hFlQ' S6c0 0g'S2#m ;ţpK!'VJl%jB6t>9 M~YVsh*"1Kl"(i0L&u*85CRGi۵MSI1RY, شy>xk!TDXl$vv>xH7Mxkb6nߢ,]12 ;o0v5}\1rx(ka8PZ @lтPO9bSc2J1L&Զ-paW9`P/fd/*a< Lt0}4HBAW'JZClM,:y.mո$C* 儍A>&B)4 ڤ6Ĩ X7P A]w7*c4#9Q%44윰j+yqXCo%g,6̉_\\{''k.jvˁD>$ itm3h2\@5SJa8(SշK @LMs+B pmWE~Z"̦yx8 d!ziFT &LdGfD۶o;cce6ֹmJ@[DѲC3k_:T:yPhB&DMq5رy 3Ǩ-8{zm#Gr5PmT5R 4+"d 6"Lqqm{PW\pJ. J;"s%`=W_ǎ\:Z6Ǔt:!d:1 0]butnXQX[[WKպ1dWrwà 3,ͩ&!&!84@;C@׵QKB5ۢ>1Ìl8t] FfǪ֠nL'ፃ 0k}bA;:aD0rTBϯ+Lg3 ȇg ɷ,JIKe۶38h0 DH*=NvA̦StܮE׶p]l]V)CPȤࣀ΁B@;cN0C:0TZqF) U! \0j:3|p$ݏRkEC:Y#`/u ,T~Ow V1w;TE;yfX;ztrpa' fCиɕU~'x'Z+XE4 ;6ѥRl޴6nd:ù簲uCxZu*ew\p & F-;i%F)Zť% S;Ȁj6BVl6ha `2S1ce}HM!BxeM',,,`u<35sA-(<,5"Z.סjpm tj`׶5IU 覢4`=p ?{w]EL֥\P TQaڶ2sbT5S``(Bj2Pb`M+4Q SvReYdNa[oJ´L`z׮40UT 5fhY7A` B<\. 1c4a8CjFҝt)47bh B~*+^X\XKR݁1 a`lm;Wa}}=Ɲha#|6IoiySG °'T g0 saia[nŖMq |+yRTjHWWصՑh ,AN/jHI79>wD3%nl>Xf~r>{xɇ`iABֿs:¥/KO߃߃AEx),kgR )/#${a] z4|c 0d370 ;b&zA+LmbvΝ¹bwujB G""3_0  k$@7/!b F[uU8DGa">=bwPŖB9]I$.HJͳ$YRyu99nwY8u'ϝA\(H=N[۶o0kglPՍ`i瓧<*r8OXAƢi- @8A4ZsMHӌT,6X5SFc`űAfөyݵؾuVVqE0if,o :Bͺaaތ'S Kp cߍעYhyQVSt]d1svN:$欄 }d1;tj ds iNHvѳЂm!\𰵕D&MzHh", @Uh !`ax,4Эh*iEs8r(֦S99U%unPbZYˆ1{eN'X__}@!ͼPl izƗ2b5q߇ >|Q=!a Zz/okn@]8A pau&E~*y)Lzi׋vSVAkSkVCp#Nճj*V ^zG^q;P655`gZ\![7(a.bCMvc:T1eZlDer3R-4~=IR_J8vT*֤WĹ`5z!$쵂IwN1sy<'е^"RNdq(0bH ko @4PZRbBFN"K}EeRM Jˌ5?>U4RdVr{/R~(亞Ǡ7y&8AIe\m~DtNg4"Q:kSJ!X8B@\^lݙ:J-pNw!j6*kQY/@&),ʜTOgH4#Ϋ<׋ \d7jAdV?"1UiQW/#{*G("4kcL姞ĉӗ@m0S#S^J0u}rF0}~ +ɾ:`MDz!WCVҕ*#_}r(VqC9&Xƍ}9dcQy~I8`Dry𓍕JQ i}W Ì*D 񷜳m5Rw6ZY' yC_ *7x9hZUC6dQJʟÆ5{T]);ÐC70^Ÿ} 8wa]33$gFMɡԩ.>Dz& Y^gXK7D]FLXL+E|F. tdep{(qܸs#8u=@%NA@̰Uc?vo5o'=n\Xߓ+tG1]gUuݹL knIJLn&fr|)G)t@XԵUeJStjR՗T)0't DR!'Eb'z,Q^͠PcN|a$gƧ.!gn$Z!tlsh;!~qTF|XyF2F&@\- 6yS8YjM <—='ic1Zb: pFC,0Sm&q)l+,EgyEf\%m ~;=p&>I٨̤Ӝ}m`NJhJa|"Egwc'JbhleG~&)a,ST0"];WExATȄealUlrHI8ep>8;Pi{riYcUժ64jҺ7=q\4AҰZLZ9G2w$klX}7ҍ6yӣ\Un 7*)}utjf7_Z'/ʰ)]Me+9ʹ^@G1ߠ[Vv|VbJ'~)\>7N\Y/oUުI12Mp&VNx)idx'}'#!d/Q%zj 8V/]LYfK{Q|@nq܅;ǟ_Ğn@]7L?4lBl}5*H3_{cnFM^(z^PM[ umNfj,XM ^V5NIk __J wO楕  |lr<$.:{DqN;$} *BY K%z{e;ne@蚸v^)ĺYB76c6F@:5%L'J]E1Z<@CFADVJ \uzƉ|z&́*^P8Բry-W#5P΢RJQ,xJ# U#D茴_|ȸ3IDt‹$KXƂ0GbeEBX蚴R<׳fx33cO+m~{ Ĕ'X"l pwO ScFDɩWƩ8|1|#}GU/ V>0])b$ KF`\Ps4~q ܅LZ<ذq ڳ^,bCd$un:wJTk6㯆ihwsrVEB4UE,{JDZM])͔#>Y,'VvV^p F0} !Vw*L-[:tk&U%5);ՙSlC3VT5n42iL*. BjFz le A2Iԑ$ȉl7Q8Zy7CPŐhXb1nt::~'<*I 01dPg^/EliˠTj/#${d9KHV q^m3T6@[Rlkz@B;:CkM S&TX-] {hl3uEwaAem? d7E[uH llGKq˾:p1 tv /go{7czy`ٶo_~8<~B*Juݖ(&p"0WUK&SqBlc윸yi;[{PLM9D@z|Y1zO*'n IQ0(3ZX)$֢QPN?܂4)&畇@u:ae"N;>XwĘj%D-x]08'^ ROpd§NꝑPr 2c _]\\D=!/Q{^]YUN< 1l초4G)fzj'ذ;n Mg8wn.7E,I[q3;bEk{J@&deq m!usuT1VY5I乊|QUUwD ".16/,c|uQؘpCte4 ;s^~>{)LzV D?K`YP5@]7pA1yѢV6/Zs!vi,l:LWZg/|~1Sй)XH8Sh!7sͿ1\98SN‹W)akӌ nW[`sYBsyD?ceA51\*>gvՋT 8棥5-`l B@UK\#mQĠ׵U:+Brv.'W8k,h 64hD^Kq-[cD|7^ڪS;K.#302jZ)*um&m]Ű(,uJ|X_YŰ$k,4 24t#!XUU"?d1ed%L 2+, }+g^QySTbx\ ?zm&t弢̀Nůahv_iaMo?.m#p ]1Y ټ:\XJ~5[ K!ZO,ig/ov })Or 5C *aL,cB b:S">еcnlغC`Vw-o;Uj1~(׍Ց1s]CA} h" Q6 ^lţƧx91O|PuUՙj$Bܾ-le0-/T;#C]!A&oWvWN)ҍ9IQ*񗲹3CIڈsNA }e#}&ͮE Al@=A8 CuS7,c7^8 X1)*d!L5QT(@Z'p}k7*"|kҁ'[xc<N8LkCP/ FH%m2 `|6F\sd_yo7xv^{-e)u)i+%T[f[%MJs M{8 J OGp9FUBevRaV4֢=lT@HR#I+LB4mDxʂ(a%L8D˲Xu^h( @&+/xWb).]1u1:=I[d_DgEg$ڒ}n&R[[T`qMuL8u&m(̓kLDZHw5^ŎDTӮq }N,2m7C5%̪Ǧڧ(L%&1 Y3OZoV#_k+Kqj?0ͥ'SsO'PHyT s?G_8o"KxGJFp}c.I(qaص88uU?Pt&%j8 ;[jK1[K8㚓Xܲo`dDj\B_ԸX.'"StKa.2Ŋ`$o}J,2_2z{R_0KPJN9C<+X_t[CНrܵEzmz?W ^Yq&Y^XCV6 K !!q)3We mѓs6 LU#)`Ȣ(4C1A+dN5zdb9Z;wjlRC&m^>3gNn;P+*ꐻ̹'>l r͗>a8gJJ\yc?2hRɐ P(\x-ar31nt-vݻΝ{o+-uhdG5~E-5N7{[+Vt0<*/Ezo ⛷v-{?gx饃838x/`}m ?Tuv=.p( 9)1 3 Xj-n~MR. W̚SXϦ Ѐw չ#+秀[>(hIt=CŁąl5:j]cE肗*Z .] Ƴ|k@: MJmt Di:xl9 ZsoK\Y̠s/?C]Bv)֑ϒ撬@ F O&hg3u^ͦ  ︂6-F6gkS,t:Ŗ˸}p:a:/)E2cW:7L-V k lDzIa!5NhEa` N ךpLHCمfųxĨ՘&^b n)~xqo<7vrDM3H}(1M| @^y6JdP/mwwǦok^{] @읳_b.^s&_*c㦭):eT)k(psnH`ڄz8@+9]˸[qlo{1Z\D]5ʩ&2#DwX%Ȫ&HŧY{$ 62ك55(CCM-{V)7{)3ٳI)x2v*2B7_Dz O= 8r"EE8#ՑnTrtNMʺ#*O%m<{ ksbjTK5b휾eB`ݦ:u> u 'E@f羀^={oLSIQ!38=H< (gso.71*En(T%j-eν|H#Mv-&u/Uqst87,VRv W=>g^`|{HF wGgz^V%)yމw{xݾ<{s) E!tZMN+0 \`xk T&)OBJh P TFXj@uЭa 8߸}gkؼy vlݎmb0hmJU Ȁpe鳀BCgTǖ4:I Sa 08iK}Id57 DTQRs#:ջ]ۢLvuUǾߑ)Y(f>q[l?%UrO4H*aه6Z&="_]cG y݆dQrFjld7NzPsuMX''j2Q(; Š+`ݤiw0Uc%kq.:o*5_$I6I>qͲ*8iZYSc8x5KS(°2SI!$$#5AusEΥ5(Ỵq puqi"~w~_|>9CtdT I3s)P\9k kG ! o"X5Th} Vl4 aqa!wcvT(y9(4_g77ތ_zAp !$L2 /q *.!-m V/syUع};6-pؾe6,.ciqQpV%ou95$o &q)"$U TGK ֗&M@KjB2]tHM}xt| " UlxVoqoAbD$6"Q#?~BHF}B^Dm}G(H{>T9U&6Try` OwGi= jQMƅ1:m;- $wTSDgQM$B&+H&e %`pmQ~-ظy3JppУ+ ԜsB(p} r XYt]keCW@.H>]6'l1vb ^,H\"HhV ́=|+̕ؾUxC? } 0ϊ_Eb$sGG(;)tj,'_9:^=z p~uï<8oWM-/n_ ܥ5y ;lSdQfow.ސ(ae'5t'B@ء;36ߵA0`pն-}nظ# FC{˨^JF;RըSX8/!,mۡW^)z0qXZڠb4c0p؀CAMfxWq ,*P ģkjNToQLҹ;GT%~iAp:@b~^~ ;wµ{vb۶ X_0l`S=`rtЌXyZe/Z/˩wF @*4 q:f80h*j²b Pxqv氾.}qhY{A|tO pX7Ihn!TPi,TC l@=\`4BXkkg~$pnM#ޮV\M\' O;FA"5ƛg=qX V낚|'%lÞdik v3Pը&;VP,&<[uR-2jľMfHDs.չH/߬!\Eٙ埃ӟ] ʛ {RxC!#(/*\^Cy"u`3$̣*vƠ%(EWwpgԣIx@R,@}3)IhShXy NOX+{mu.hMհCaBH_lw׭!q @Ԉ,qԲsݓ찐*6Σ7/Ŭ1 Lڠ8+9m4l{5. ۙnFWӲ2IphR܁ / 0QE*$Z!c7Z gxGw-fE|q%3FmR]d nl9 &ŌؘZ*9 gʢITB}:Z Ű(U\+m>bG蹣irs>nĪ30\4$f.o9gmxȼs(^ۯ"18GpREj1sE]T9rTd!ǓDh2T#EV4T-lz |aB_6eE=Y=9<+wypfT5Wdfnj B=+adg.HBG* Jոb-Z%DUkrp}sXzQo_$ _X]ƎZY+JjcH";<8hUj Lr PU` iQD,:cP >E1TmTI?-,Ab:̰8QUM$Wy 'Vd.b5%FH*ppIˬMK6MfQI;X*cZ 1gXZT.o](ٺ Ѝ(${CFV[ Nr7eQd8L7Ć"v;N~R6/Z2 ӒRW+=(%-- 0J2`:V ai򰛍 [˧նd ʱ=/d4?%]C:VاÝ J>G>CA6[6 ``NMy j׃>RTb ;$lɐ#TlUΝNm4HU dXfM_AlՊ+EkL͇\5w?p; >@$ZiH4+g%7V0~z=8<^WVOdq=9SXڽw~O[ԣ|9@N32?c i".g喴F/ 2NDٳM611Ni&6C$ &{Jj3~AК|'hR!" oy(ziZcveh=LURLNb ;4Q8-V-rn"DW M?o*WZɦqà*'(V;LLA[ŗ Wš\)JtD\x,fKXĵ/$%B+SA2"pIVA7VW1UCP V>Hk֛l/ طš .Y@ by>Xo' 6J} Je d+IZYOP.4v3OS$W`EqµOf'Qd6yooLOEKD^ЊB\epݽ{?3زXc6|w6]O|giypwz8O57cī0SA]Lzu!U1)d"5>(RF@ă924l=gf 8a9P>3ddUz"釩2@FבlTJj+qBG(iC5-24(dC+bd)||z}Rf׌{Ʈ /cUUO&d$U!JN:b ֎Bo Mj0 ^,K˥vaD JRt]~6Y;25xUvO`qSbC0jq&t lk#C=WSp=7~-[| &nك#6,㙧s`c?3ظ}7]، 7݂#G?O ?\8{|~EF\wq{?n6|^;lw>-㙇>Oa6l9Ei2S|.' nݻCL$=Y`Hȭ}vǠa0~l!Բ9Ĥ(d!vAAU|ףپ=߂kuGV4ڂ=pF8>npгys3;&4A\2rK;'5/TB'{\C V.2iB 9E7E ]RIlt*䶓'Ib_\[oG:ب0r˒x05"փ|.úЯH{iL:L2 IlmAdb`Z5v]~nHPQ>c. Az0>2}(L"cSݛ\ ?hg\ -mh."uB #JɆۮFKXOw~رmƻn&#\:};]MܶZ9=?oyX.Ж~7;Kކ/<-C޾Ͼ?3رy;l _= G;l-K;ƙ1NR|߳A|TXOE?vD7V V4#}tHH?p}/+G;z.={gb`zc% a:ڱ\VSgVՉzMڄ.c1^C'BEwyiPk5(VE+8]C,=}jEIwBѪv*8ⳡ,=BwǢ/tJ\pASV \9O9,BcTy#T?۷bCCɸal6,mKg߿U3]Rp6Ɲ7Ũ&lqǍWÎ6}7Ԇ=pMزi&x&T0 [Gصjlu#F# K a wc,VMeqݡEe$86=w_`5޵ 9ZUˡU1hJւ)NJ郗@)U_SE} ^y^zO:yţ8v\*$!NihiLuʎZ &Y%-9އNm6)MqW9s0R)D722V(iJmaB﹩ ,ϸ6kϼPѮŋ+ : TǏµS9{%¥5%q zsV3p8q|-!sveVϝDy~x-AC*z=50.@HSyŃ$.[WaVz=pX,yZ`!SÙXe0c ,0Y?~g&ԲPs I$ $PTIuC0U齉lls6$v3~n;vڴ#Oċ}a#>\Ys8JMլB3TsoRb_FE'Jm3Z@`9yVo0dpx_<`j>Q,`o\{5f5s^A0 Kss &/O4បuEJ=6 fّ}r]l)=R=A&_[~AH4ܑzv~LRfY5c/iΛ=ש| FPDXPg fy) 4 mAP(ÛM)P`y8l:O)Hso/{o@u+y櫸?}> */|q?)hn|=x򳿂|DZ4w݆'n `^mlZl ڿ_|6vo]p{ў{C?ܽ3p1U6矴fOFZ׃f G2 EtSg Q`7šM 0]˛,ٙcT% jM$Gtqa% c336,-h+*>"X>QCI?hse-{TPpa^SlseB L@ya?Ρr(7$χ>{Tq˜LN(a/{TO~Λi>gb"aS (SA$pxSvuUzˎֺS01i6\({'9*ekMNt sRr u\ \"W Cr&pT<6!,~{ȥpA p⍗q-2 ,wgqF!"~x=waaPy/rN^,kL:+޵o *,/-k+3n\MߋמYw܊}"nχO0!3!fFqGÅ x9%ZSA-џGO͉m*R5 6Bh'E{W $$Щ/|o\!q+P ʉU۵xgBx4#*DCV=m~z@E\͇JN'Q -X=´+PK!sf1uJN!wQ{ԁ2*'Y3Ļ/c_1muo_UJ6}h*0O||}(~K @6e~Td A6/!J =<3 ˄Ƅ,8`^N"a0hz QB-*֦FVc{ Y a!´ċEX#Wɬ!aÒ0ƳN u̽ $_ B BZo %l XhvI|0[c+x3wP .H9^r;(iQo+/KV]Z\__?w܃ix3^}YVdgxqi+Oڸ2`.Ǡy'T e1{w}1oeF{Cw.yZ4Z]/WtQB\ԣ[Rb^8mfsP PSUYӼq@ߗa({++d|\EvÕ,t@I F=v}3oo)|q:h[@ Xt=yz@c±U|m߂{Qᡇ>K ƭ#< T<j-C: Mڳ}7bU˘9SDrG^|/ CƩÇB}3+8 }y|;g._Am8PT<17l ,(=;C;>컌Yd%9B2u.*l1ዒi.HT F}㷺V1z>CW꿽Ű^Ml71&>㲗?}|zW"a>73͑z9s +&O opo+vFL0N?\/]Oj"s8/SB Lo#竲Xek-02z7X,l|YJOkC4ty[^~+l uJUEgl I8g}p# 4m]s %~u<=c~sk~N.o5vdpW="b&1ÀoѭA3b0n7A: n hyKlY0åM3p̌z9`zf4 $S}rhژц珥^/lϠ.W{ě`wDp=k%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_48x48.png000066400000000000000000000112151403012130000165760ustar00rootroot00000000000000PNG  IHDR00WgAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>IDAThmiy{/rRKRL.Ji2ȉK9 É b(Nί\@b89l9QI$P%I"iZ.gϹʏ]itW~o0ȽWo~V#0F1@f?#{=a!!x.c0w 㶻zK&( W|ze"Cx0FE1$ n Bq絶 oV9Hh`a2S=UCnnV(22 Z 5X~|!y"` RnGL_zw\.SbXqN_*)8peQO!2(1`m\(^RZH6(1ڮhs2Ͽ&sua_t ( '>̟|a2]OX,bgx#Usܾ$DHnzUQ][bT ds@ydZ$ 'i1%nZi+KmŗS|;?ei^!?v>y>#a9 h %:\ {OJ@l R!ZE,24<ʞ۸m8/%2VR_uJf 7@Jiw(@ou)=<;fMwy:?@m FjLdK`!l * rB2_5>ÁG2ec?{f5B2W)Fc^B7M[mQזU&]VwO=isɨ Wؿ&caItu%Odj\/Rp4x0WDV{\5ʫ{U9tr&y(IMT["͹s癙fףiRZЦ?`xxNÑ#Gx&aV4zimj+ve]D b*UFFFعsfJl޼={vOpqyٟs-lt5 @zؤ&ՁI&>> cǭ;{aÆ lذ|3agϞg~F^Óu[yz1MȀ+ #SCFp<"RJٹ9~YoΡCRR(1>>NX?q:DP`ii78‘#q7ؙC)0|bFzNZ[TҩM/}דf188HT" yoN>gvv_|X-(kpՃk,} HL&C6%yn{rmۆRWȑct:]+6ؐiiAs7!/c̨r 9E!'O}z!|[b0%|箻" C*˜?;ϖ- 21~!(]}-)0"bD~ <:@WOup/:x+\p#6!y,ߔxi'V|ZXځQ$JnHim4v0&T]܂m5pspL=lݱ}}}g)j o~&R-K'&?{N`Bz4'ӚQT5|eW/XEW&//pӽx.>t[79RyۄZ۲jl'׷ZN&cq-UnMr\Az>`贛vӮw3F^?QabRrOLԵ], IDATxeq'<ˬ\j/(   efz֮ Le24֌l4=p'H$P}|s]#yYYhfU{5翅}{?7/{ @!"(~XƟq,H)R"C~W¿8ߒ~(տzjOQ ; Ծ}. ПzP4\ߵk 7K}ב26nsl/\걓L,Ȏ{|ӨtZ] Wu8^cR]tq$l}S8NMYs?7/xý%z[nksc Ns,ׁ mS>by0[|v=fϔfxG}MxnhOO/=|m#d>k' 7EoH{XDOfB@7^0rͳtHA)E׋;gϽhCY O仿;2}߿Yf`,nS njqV"7k H(CJn J|c![o2+&NJm[/2"m"+d*ֿ'dk"hy;]ɅHֵ#O0?ǿz1O<^x0/z1m,oUhDKxxqܺ' uFJmA^m*akYJCa>Î{ {솙zQUUR{B`į9vVEJ>PSKkQQض}Y=vLD`n?4{]8 h?Z[1nS(CLbdn8˪)_da97d7QV톺B_SSk(SųD]ZYfS8Nv޳G 3ų+xw.>^|W3PdE(_&F)H8!<'1__}r&pg(wXA֓)m6]V{UJVY.&B{k|]I7s{ N4->:H 2 $iPH_pB]6$qb_E6n)}#NHx=gm×// ǀ 8Tr;:MVt  l0G> Ұl08Y6F[߁r` m҄2enw.sӋES ':2FpGB)~vuB(."r c4cñ`@bP3>}lHpo NJc``/hSZr*CE{-*T 12ǻ"|q|.]&uTח{|>sjߊ^E蕇ރ_w){8'/S᪀;\Yp u @PS*Ŕf=ѡVg2 EсExa@VLBRG](nBb )eS9<#;RӲEC:\pDؾX5I.l`[l.(#RꃜRqzRisn)t:bEUvdBP9nC;F>ܺ";~bRVK[췮-m^o\@":G 3(gJ#bJ_ITx9o8&>S9QXn86|;O٠gHF>q4֍o$"ˮDlèGqY;/gc_~"4ou8Jޑm͐#z쪥!ҡCs`Zaozy.O`4,0 J)į0r7@wY_&x|ɟ _~2Ͼ|;߁y ﺶ2}_!Y{7xDѮ5Pqw=)L( 'o~+k`}d6ۍPw b ]6 {:x*:e yrܳreyꮂP_UJ6 0wΥ32B:IY@)MBO Kq.NȬ `#! ?)YY:rxkAUgX .#sPliEh%PHQRY a.me B^,hn(*jxLXևHJ:HC8 w6 nl1(ʻ!8?ȏ~Www_k"7 d|ɏ'x?CԿsͥ kR\FS= < <ɂD\W.j hN.X|ubյCAV)kG -@$Z vV#~l )zmT8vٵ)큢Ԋnpm80Gf`Yjn6Vґlڊ:LB+oؾ8r}sᤚz.l}J),zEI@ŚǼgqA"`Ń={2,vxKDPa,*P7wkk"@j@>_>䐼qƹwɉZbǐZAcPx$z/AO'' [,j(i9<{F$WjgG==6a>Cð^8 KT"9}d|d~48Vd X ҫP#A-RǝrWPHRzu'~O>a׿o~/)y{A vx7_K3d`A-Qmg_QWn/ѿƣ݇<|?'euΙ9Fybi'a_b 53$5+YB4Q:a4흧0j6jR< ЎP 洐w9 J}1.<vN \fp0 @hɋ0os[d.{FwX齡9%(G {Akr"\x.wt`'wNY\n[G9B}d>uiYA"c0×銓Y0Nt>g[(丢LTQ/zi㴆ٳER)94U4,5 .Z2>3+?kvH?Ͽ<>_Xn౏e`)?~QןS6սGĐf oU `R"~ГƵo| !)(_ G ,(Ai4A1ޏԓBGb\~Cn3Fk eQ9,m1t\6M1lK\FȊcLͱEd<MvW<Q4z{ *{EuH2MćRn:u3us+>7G[WLPNPsً{}Ƃq`q߈{),ɽKP"H/{BW0#ߥ{|r2֡Tr_J>o#xS?iw28JNO}W~iw;zpJI/NIS+3~iڻ[&0 ݚAHӵpG0%魛8}) !+e,IN"Y%lc3A"VwLHiw0̄c"`j3O X##zSsҾHc KRthm֋*!z;EIgIBP;g@k9Oڬr J#CfbAYw C*J`OK9q/osչ8Sm\xX(^`p^YӁPoX#Ύ8OF#i-}C<7YD{I ۉ^ &3>ԹT $=(FMuTӍAY,*!yhr!C j/ϥUM {#62 s^}3? ޫ7n=8=0R"3a.iO!|J%pGB`ܼQӦ+3Hȹ'NƹW{,A ^غKw>"as>?? u"3o ݠFEHM{X U(]0d8α?Eч:: 2hi؂[Q/kG xҘZa. :EC`_|g*tJx+&F^ RHx)$En{8m-nr문X/>wu.eR.81@+̘r?sv9PKR}1'yNN)pYXwMTqhsJ-һ2eƌ0^BA_DQ5Ij~Q2X,s~$: ?/Mg\1|7N|pEe˯݀nBb|{S/r% hE eD+y44RFD⊝]~J9GWw;@ñR[~2 }yWaz>G_wO_BnXieCE9Q_DY*1M-}&{ONB,"ػC sdnq7 E ocw[.ZQ dSc[`t8 ә;KqOt BRВ;3 [JV;,~A魓së!LC h}4;RW}X`S\\8m hcHaԈfCqLnD|}*o>`j&c/7(]‘bh#F>7ZYҊ|d<#YS\ )@~΁O%a$u7#9|#.HXq(b[4<F7__ǯp! )JAq2L@ksHIu;<KlE/0z ߭D,L8|gfYB!&t_6:,5#TR`UJb>9/ ]F6q.|F.q।inM:"s#B*T"&%pS NƑR{B8ݓiy Ka.VRw*S'!06kѯX>r; 璆[|)FHe*}=`v(SppٿM='PENe 0i}]E"^Խ &'xz2og Gd#oK uL~u/eqr%Q5M])Z#i`͗_k/cQL9| _էa|~7f|ⓟ;|]56'Ii2A(HA%4QEԱsO75,@ c:~SW0/ܮAD |<᳟$W7(|0XyetB=?4#0k.ư3+QLh:pcMaYg ]?Jߌչ yU$ѯ0ڝ;O<[tbwb],uD7._V8E->ŋM}H̻彧˄E#; ,et)\wT`qq\\R7H 1ϾQ(?SaU  .Oj~ H1}`hڦ50憬$] ƻ`7R/v}'~#7Eic(f@ͼȅhWڵEf_(fYܞ2S9[s|/ÍW9wW9en ;ۚtƮ,0Z]B9?t䐂W_Gbf{[8a|葫`nKa<=;=W ]s Es*9=ݺR%uBc5rō8B@B9c_L x<9a}Ⱥk`E[`lH5ɞU7B6H)ȬjNh`=n%!1o,?Z=DO}wDT` Sy8U``wn*V_14bx.+HX :ҟ\ТNݻQGv:8d&(H=4f1w:/l āmkdіqUsl|ŒW4l1Jԭc=|0fL=j|Aw/m.wy]0"'O6R0&!́sQN5^#cB`ޥ $%8⓰(S:Fli yupNi i׻р:zbspޘOX֏|s…}✸[j,AhimVV|4wUmCᅀh(5*`IBi )zЈahG%/)QgUwobB8 }~q]]zLU;$& /NWRf̂d/vMD8̂3Me|[hJ?l.jCG`3h:R` < ܰtvX(d5/Pw&MKg=IOo(moH#m P0"$I:bfnjGF"\f y]']F9oN6:4ڢi˵=[hu.&$)l~Ό\h\hZ7gRF|:5uFpJ5ڈ~T 1m+֕T?V}BPڛk4(4tOV+:_i133nJGEB(uȊGRS4p.R$흅ylLgsTX9ǀ{2H\]VTfQm<*J X10&գS|vJYR4p;|0fVSXd)wr C~t$9tB3^z /zvR,VIo<3v{y8DD#vmoI"XYR2$Bn0b;Ra_sX^P JʎD+u!^FS1vdA-+TCp$T1h u"䎝o֤C`{-NtDQE%6'UE Q5~]LJx#q A [6;enJ(AIevyYd.E/i7,:X!:5hs  YjV\ M&U 78$50r Sx|`&*#{"%'/O;]Bgƥ45l'QYT=vkDn4fp/5 pS n<*mݴ@Ӽ@~ξC(Q@s*H%W A]mB9kcqF+\^}aĨcBMs!5 Wn-wp0ϖZBc N_ R4ה"Ha׿ʠ0uZL~"C!QLFҐ*兏f$)"$zK+`Cb!j?87Pu+[۞FQ.C>A9)LJDŽk\]N}֝Ut@68#=O?H'O!7_FἊ^uM@( ف9d'h[S!լoHҺ 9|8fu1킷v-+\KƮ@ԏb|W >4)y) 0+ET:,aƎR%9U{y$K)77L8Pu.VI#U;vօD)=yѷHO .I]Nu2#Q@$ aSVH.-I-SAr& WE[  h~hHI*!3IlYV6ͬhSJH̵ ANEOdEK/S=fq"H.d0޳I*z"T4@%X7=Uj8/ 0fOMz6_R5fF]SJaoyhPe@UL JA ~R'툙iLDl6"gZy$ajE%Cjtr%CO9vȞ:gS$I6tz=g8ɂ/=/ʯ3{?_7|^T7 w$)t|w3 Xn=7FυY(:$B,BHѼC_޿.6-#%~.k*]ґѢc&v"5A8# #2.VP46@g B`p7zBr]mj6%5@H<]ӨUl|T,@BIۊ*ީLJd|L" p8xmSn)H VkaB^3PnD(dR>A;cE8u'EYRuI~m@1^%ߡX͓0R#NN-π|"4$5L3]WmHZE!f2^DmUԃ)D JK) A!g ]Y1 YC]r#CT=wC8rmLQ>ehmкaj\m<+\N:iO&z_=ԒI(!!.5Q~+ΒYZ"s $Vi5A ,FCINOA7~I<y:g8}z ͬMȊHRY$Z V2ʝ$U:q++TXx+W>w.zc˳.Ü'zaWʃ8.e/R0DM#ء́4@WQk-F47a#, 'D7 ^Z_ p"KW6rKZ*OeS$۱#ɢc tzZ02\()7/h[a^")YE Y+XF,̄^3msHC6|?.~/L1(EQ$H•6!H'ZPG!Ҷ C"]͞ё?uAa-6Rcw</P;~WRpl-by795܀%5i P96OTD̑"{91v*zS J0R9k72jj dFwHJ~KI7T ^4x~&dGKkă Ԋ`$?qBƗdXNZ?(V0y05,21K F2S>nk# k`&eO@rE fˀ*wt慛 F'Iڲ U2y} "걃 Us7 ZF-\NLK;^5vɥ%diXLK),pl3Y)FHo r$-t6u#MZsrA 3ԌrtL]n-p&Д=zRPE*\_I7z}* (GJui}>N<N-+";)NMY$\?GDQ q+Nz-0Aᵃ%&AF”3fM4}x՟JңT )>lTb#o+IӶ|J>ʮ!{&gv($VفF(H왰ԭ!XGsw(c]3jYLl:UpkqG@?ǐ0U,ZrOCaDJMmeg&Hf𚸄O@AQ ssBۊ] ca;X'6:w.5{C=$`+1zxʋ +:,3eF2DX1 Qy7neKH349(E:J I`䖫6ޣ^fvY9(+*e8ԔZnmv=(h0^QyBdގ*Cu# &zQ2(`QU&ٴ!2陏75lʰxtA|-\:9ļ;WPq4 u .xb>#Ӯ5 wƲ]m~J$6"&H IG|GK7Gb8H H  yiIWl^&%Ĭ]4CHwk:Qȍ(}:&&򗀎RO Yֳ]Bv$FA' ij$EJ-[06t܀ΧQas Om.@. "lyK ^f6uk^{uv AW]GX+Bzϭl5٤=q6@ss[2Ψ%ROq2VZ9#ucR)QSDQ-ҮʩTͯp<&@P)W?(`hM5QƄb0q']L\R+\RJ(n0.ؕH߄Zڅ%V.Q%-3JYptriSfƔ76MKϢhuչ+BQٜ LbrEJ)~!aHeDIGj^Ũjnv%y/#snnp^ɼ _JȻKE RH_6'ǏCm35Ii_2%vʹ ^29tfY|G&уL)j_,sclosjpaaeݴ.,tnVҐ0ŕE cפ #jHO@2sK; ϥ.wn޵KJLHHXʌ)'LSK37si{J)(Yj3Aqy/p~ e)uWS4MV&w)`&aPQtH@BRIa]TݸgkaQX5d)҄.f+%DUo$g͏眑P48$)X3PtQjP(#i`BPYhpQIbVEST?W5PsZLv#}_e@}tD+L L9|^d<Œ@DfmCL :DK\ȡj ),Re|=tr׎ h>PS01v9rF)=!hT=j~r[Azmʲ`:;4C&vz E*7wN8@8.ܲ?OG Dh΋uc[$6I0⥍i&hz!ObpYK!XLgnBWwQT!wH<DYYq"/E 7RRHϦ#?=# 3h<Ps sm} Pκ|cnSƼW1%AMi>'sF; rvZ#  pԥq!%Ɣv"6wRMy( @9uSB ,Uڤ2P¥,`a}.E4Q뜤e\n)AR`Q\sArpv@ij|'cTseJ\`{LR+# WXZi7dqT1>j`3reY0^X L d+JRߕ"K`7oު+̾`(~7aeeA y0jTgȉ %Vِr)"YwyʘsY4i AaƁ vH,\YZduYxA# B saTȤqYz=ieB{VtRd,eQv ÌjPspu I ~QYGE !4Mp>yNv$R"f5ZQЌrq&\|7nR Sn尀I gnavHSƴ[X J2-j4e0yAp1 n py^pn&Np^ KRRի];* VB8B.UĻo)vѽ ڈ$zh%|cod42TV!`da.*!xCb71i nL@2C%te?X wIqcVЍ 0( + >{#ߋ{?\ w_" M%*h 8U(tn]7!U &13~NW/QcS2g8i*Qv鵺/8\G\*Δ+.a,A6UlS&;`W1fVjTS7tVi͋rΨʌuν茻#m,.y(O;z rtO9DP=M)R<–qn(S /EY&y7L KY֤ YE;&(%$!,\)!\,)g-/uvMraei/zJI3)WR T](@e8',):#>,l,T*9Uh!0s:3YS~=RH~lܢ]Rʎ"**2k[e;)cY꽪 *k] "h_{)8,U3 yutVM8)ݼ7|o|O<=n/+Ocg0t]|.<@(!M:{C/R SKE"y!,(KA7 L;`{C`j3r3b ahnd$qqӵ_"*+[gC*q:s{vFXX9!~v>|/>''ޏ'/]GN?eTRPA;z/!&$#08F"ڌ7x0q cr-8X1ͶPӣ{ŀ4j_^[~Tj*dܶ&}THN^Sip,-.P9-H҃fv)䏳vE0 #q#\\~L8X=ê#r߾ϘVA-NjiE+%MrVGyXu ̈YtQLGxKyBRAT_gf.ӄݮ91c]'Ai.+isXw4!gAʌ# =ŤuU׵ ~O2lnrBZ 9p8pE A)x"-:3ͼ,!N>śo 307F憺h(ݬ#\u |]QܺE~) 8eVN(KE8Pj|e+,iJ8~.}2Ȍ38"/;O|y<o:\v<27`5,bN4jYZ|kXO9⢄5}?eN^ǂdRUETXjAIY7x) 3CM9cEnu,U:$17Q7*\=CmFI^r6ӄrp\:q-!_ u\LfƤ-uV;נk7SJXEZO#  gUz0rbR`׹h\49_w;>8,p0Jxd:Iuu‰zKdHK1ڬ ܹ^O Ipʂ}:~?=>2g0nα88,3yvy-.&DwbJJ'; l.>#H,޹@V˱C d$lf亩! sG,vf.IIM},QCm09O+dMI]TNA٣zեhSg!%,$xmFI(A˞73ɩY "AA=|/ ѤZ67j 2_kUvBPE(ZaU\~Y yYu?F:NJyP \χ̺*@ac{XUs|̔jHo'R0h!\,X緎8)QM y5zHpE'^‰}#GA$piyˇu e)8::2(7j#nC\rfU5rBuDCv$94hPjq.USB&%K*IxLe\^<=G ~_~~_|7!A5lF)eik~Ȉ LE%⬖)!eyjV%Yth V w(A0;XTB]ޏ_BmJ=:{( VF4Su~~2 gNSDBch&LFH kIda8zg6ӭʨl]vUa ю lRuqs#+hh)l/ˬBI1oHW,Gg"Cڣ 3/sfha4W2Dʺ, .M,50z%Y]̒l<TԸ !Rݙ\oS*BjcIbn)Uê+KA&;9_In ߐfR϶Hۚ$ɴ%XF&s541YyquǗ.cxCٕmR4ƴd ָgg&vm.eK<=QF]~]A'hug?;>/GL|n-'}4M*]SaY"%c:#?•Nq]<^xg 5Kia4/25"`w{s8KҮePstt"- $r;꿤%0!< ͉l| w̶!B ֌faOL62) 1s?{|ϳOp>/8; ʬ5H5(mVe< &+nl\b?nqY47XZ\_*xq _ɓ٧.G9tͺp^?ÎeYnS#{fHA0+Ȧo qcOa6;nܝr!|m|{jm`_II׮X&hG74++v,ZcK)U尹n+NXyř}Vq:g9} [KK lҟip*BmG2)#+;:[D%vQX@S[g[=g!p;SwFmҡAN(2.rxCo/|W3Val,lU:S&%dEqtI`έ\( ˹K)Yq:>ӣbk}vIԈdQZJ!,MjM6?F@a8Pa:TG'o7?˸~:K)[7p֭. ar l]:~S=t[G\rF7`bJ~SJ s.\Žg=Oxg59Wy8@i>>禋F~7(UxPHYgQ^ Ozq aށI\ `27 =6C4ȃtLѫ[ VH!F7C&~7~׮^%fz&3,e9 e2MEuܬ!j9x~#/UA#7۬:}Fa7Bmw@vTвRw߆"]Lx DZM@;:5D\yYu `"^@hGl; :RIΤ R Yin`ZA9 X Q.X'J[w7iwuDfn.f0gBЍ8M |+czջ2sPdF)OɄT;YqM'=/"ͮOe7v{'v Vv߬xť6KPmYو'{|9? m|OΐHvJ3ky^L]%I@BGρy ~D&} ۵p:X2al&S%*zT:]T :}rk˞+MT?f$CґbsߤҬm/.w=}g3nel"!6[_ފ^>r%ihVXdڌ/}#E#2^-D Fm[q1#Y/;{ߣrDZzҥ9J`ׂ0/ƻ?w[DyQ?ufn(BµN)JˆqxnDUh8'އ^z^?g߄,sa<dk73 n,`ɏZvyqbƮ#,>:|вK$5g<7>uy}/O~߇U:?oT(en֘a |[Dek|y͜fNdP8o/ #.Z\bGgXGa,R|FB9 q-jJSMa$AF2QG1c6޸Ы٘qLQ[!F;N7ivyq[+CF 9} 꿈moXPtϰCb"4s-"Vk$FalCF~C<Ǎq4j9-< Hqw ?G qеϊ]+^k;"xBHnIsG@ܭUnTD]G(\Cܿŗ]͐g[ӻ;7TYVx&5j;W ^4jhgj4FqDܗyc #Hy8[_/w=3ӛyzV5 KL~ n6qn(%Mjȫ9͔-nwkSB#?$sZ'vdn3\5v#9hƸoFB8.W]R`Ƣa#6[6uj0uun2CyH(Lckdx|ucBo$#?o$md>%Wcͭ.PuTc XLX Qii~VlF_h!!SڕcVHTqFq͋Xł؊Cu|YDud) L#H8 yr<>ePi lnj#@AÏ fAqf?rAE]$>l$3h7<2<>Bo&y> o_{魛8Pgyd8ÃRtwQ5 /ZUmu?Gq, C%L^f,d|qi=Ű~;,q^KsAPc}[_K Su,b\8P.ۤ?p㛸1If4ϤlYCct,)LRНMy}UtD[Ǝ>vK_нy$ucQ#fmu[$ۈnpH$zIقFc{Ds O3MSUs} 2?&,Zq,Ru7匙E ̲uaFtkZ:Ӆvڒ/Kܵ<2%,\cˡ(@?a򕌇QӿO]__Cf_҅QytLy)H@ 7̍,!yR4ˍhN s G% 5իw+K|xqEDk>2-0+So`Q>x7 W~GwߏRg7qNjiL0uIMS.qDMkt 2. i[(1k=E--׹qnR P?Kw/Z)]TlV 49{ <>1qeTh2Jc5AAYPߛ"i%c?B\{dl7xQSl▭nDboPOGvekX'cˁ2rm1tI=k)*=b |R@R.rnjLpW%td_OVcR$5NM੔]>V&\~H Sn:_|i55McpHؚawk>ܯ:֟"[vY_`0WE,ߒbx5,{^7iũDc]KYRWڅ6?'WLz }<}/2 g8?? 7+h;:M{MkQnK_؄ǹhd\۬nc0##Lq L9,FpxDy%ji umLMpEޠq45WHAEbD춤#e|bA iDdrɜ;A4à "ih({7г] 6*Fs?m=?6V.Cz# u*z1<ͯA?u$923s}i%'!V%^_/\628`oE H MvmW4G-}x?%b){JHygeq}g?qC3 f7z5tdSJhc:RiN%Z4Rq؀ڒ XQHڸ_vsu4Ќ+.Ԉs̏?)DJGƋ+ҭk !/kHt R[,n7)/<ƇFBcԵUPT[FEP{^V?nMS\\(lyD͏N[lHC :< pEVĶI vS{{(߶왷56U㧤:7F"nbb&BJWV< 5,n˝Í F@LgU ϥ}~ִöc.*N>#ZᶢV-(#$(5@ D;bRp]=*irZREq~9R}f̜ G%EJ,F3Aʌ4Mx_u_ou}z{XN\giFAt R:&m ~ =UsFNmAْ7 =/.鋀H!(k~쓿/88=2/.]6|r_-󌭴)+h/87Vj.{i/ GZmC ȸyXx'$[ɚuohۺh,-n'>X }aÛ2 b׮x9I=[iE6D [} 5l+9( h[fn#6xoэ46GJU"ܶ=V92f<+OfEuG!Mbrr ^{i9|ooX7⭂zM_zՀ<]RnNgR (-#추XG֣A =n,ɡzҸQSl$ @+4#_?k7YimS6NDgXc񋤲cqE*ܒ5&| m ls5k+1Ioi!iүY BX6F ]׀rűÜt;EKX }3LzkuQ&W20R\+"Yy49j 9t\NNNOӟ ~"uꔆ5BqЛֹ=82p (9&rx8BXPZP7S]xO킦jh҈O}nK8c9;)+83C fB.]:5D5_;~)gXя~tn %j|ľu !Xj{A9Bti\mէtA,IQ3.hjNe F$lr R, ݄ۜ.*:"dhpY9댜F8k]` - {7Lorn.1z鳞¬&@붔Ҟoi >Kx(e ˢ8EKxH2(*عS W)#ishsbж#2_KY anɣ9UTDs) KЪvÓ =gRh[ }ne[/,NNN:M(R̃ jhUJ.*.E"Bm3݅<] ~}쓡TlE  xQ:5p!y.5[v`. Xe1a-]ʔ.Rq&It%es=?OGC) ÂhRNoQZyc"A1ev؟^e5,C_+,˕6%C[b1v K؞#r|`Ŕ%tALu 4wvZcs ( uEIZF3ALjZ7%hS9>[onw3$ 'Cf`XDoYlѱP=;"5a)}q$JҺ !{{bOAc]?Z,zL^le8 ?-KqTc$zZ/gGl9?g%8A Z?`X)"YCy3$EYш*FT9Mi3x+(1D˗/oJyFʕ?/q~mggxvGGz.\| yCYȉQ9~EHuHdo4AR_wp㴺YjV烁h'oLh@Gf;"ʮA{#,}i?<f%9}^hM#)5GkfP-4"պ>?@^> coлhoqL ɀ۫;XKȵڔu?/ˌ`h ^{U|Kz?8v(e v"ԫ2\%\SJ'\7O~srւܷ:'^kn#ڤUirMt~J CwNsy_@l]b ,ݬzO(4JH&w.3̹OB$a^8?˂dr/,˲>M0L54+v:ݾEpZӗ r-)Fl]f<'lt(@-m2:H^xf4'RJZ w4źEYWE`܏dX䴍{ww]47 ؆Pjv֩kr]PT) 5A]ҚmXshlV?ݐ(`ʟ{^ 9r "ݳ=r=`ѱhDgSEX!6b YrYX×bmP2QA\˞!ʲtH]Gۘ7Lw6V)],CR*3a"}7w.Ů'6ө'L/ #8:kx_W^ƇSLIDAT?JFT2IENH!][Py$"d0pt|gm/?<)¦S؉AKm,NjPHbт06.&s`- y+rnl nR~ſz >Rr(8gK xH Ҙzb_v W_婑9-PFn1)54W;3?Mg"ш~p;P:Yyzq/vYVBzG5M 9G^DW^y W_ēO~ʬn\pv~n4G.:]`H5K'?~87D!UYz3)MGf]-^% WFuoXX7 ,2+;t ZX1Cc]FM erCN<w1a.Z% /Fe槔p8|Auo&\~7sO7nFUaa&>c$ Ak]uP<%N%Њ 0 ~T|XODǽh=!uwdy`u"tG Ƅ4<@i8FtwEKx* e2-_xL_g?Ei%N ,kѐ:P'#IO蔎7`* $/kɭNsa$qёounSjO>J>Ժ)On $f_L ^"I#+,Ʀq %Y.4K h%%JdxC%}[4@4gQG ,YI)tBd_سa2^ͯ+?IqyJ6zS3rdZCRyĖ oY:O% @[?vx0,RuV)MHзEs pvF|~XJ<Ϙ2eegVuUN}d)kv u\<ϢwcEÍhxTb-}ACmζE1vZ@͗zUİ!k8F~$ph_X+2{]v:R+ބ[Πn:NS*| (h/"S\g}Q䈾C qp#"LnTO \ pžp50nqD}L֙9w\7)(LyPqSWdPRZ^~O dXƃ`N{h|{Ku*GR,1Fyvq%2(kS BBGXA4UW0* J@2)uH9# '`f꫸vU\zyFYg Zʪl@`/2iIS-=^W^~?ēx/*5v9Fe" R(vAڝh#(0![sl^\yw(#Pfvq8Nh%u ) &~?.t祛eYǻ%71D'ɜ\Ƶ{vYöB+*Wמݮ3+[6g_`t`ұH^a5A6 9fKvK 9MLKBz-%E5 SĬrRsd )RGB#p%* ًn Sa_K[DTSjg,KUk RQ4Qxrkʂk0:8ɊWJsRch -B:َ1ޙ63@u9k6ј8D4K`L苍VꫪG|PJ5 * GG'Z ^~e|_g>3(e?2\CbI~%1//I|_@f-G`[FS|AuE<>V~}D+PB(lEĆ@3~ 2 k |Dd !iW"$]uکaC:Q Wn%b9ETw#B ilFo[Bp#G?rKRp$N#Qan|Э q Q!Eu BGiҐ,f,f;)[bt trbeΓlF_Y v ]j9X>XxJ$>"!fJ(V neaDp(Τ<898BI5iEMilV:wMais}sn*CrAw545;P?КbZ9OuaW&'(& _cS7YbjYUI1̯1ס^G v3r١AJ9^zE}8V̳n ` ۬ n`?ƭxcQ\W7n$z,ZGݔttݔR 2wrk*2om@ϒE- 6j|H2)Mt~=̥@m g /_5g0׍R˗qek23/bwܺYksQm.~2t";&  }C Z\Vmғ:Kg{Ej$-h r KĈd d+u85TJ=XLR }$u yS+&}mAOuQ]#o5a4NQQ"ȡa|ptG K=tQ_Q#〃%W= Z<;̊fC]u^: qe;anCp"#Q]3#hM,^_X`FɉQʅkiʎ~,ŋwP*5- 8?;ã?nT D%̌iVQIͧj1 c?²%@#YwpΪ5[sNCgLn:ke57MNrnnL~x5>6?N"}} 9Kʅ ³'>0%\r m7RB &]9^ 4UPJѬaeJ-l;hz߈0{o OԈx$Μ8߽u"42wK}3O:E.ɓ%0@\JYsb ҺIPɤKNUf=/6OS70rP1^}zirPnIk, rIcC#Q-PZp\7pvv'xW( ~7 5(52t׊< 8fBP$,ԑd3;O9Z˘$hFDEi J5rㄕ瓷&^I?K<=`r}m3'ꋧV,FY1!JMԤVd'=EGv*R# u#Uj TF#O셂dՑ3c7УƗh7(E ~DTsEy7\ /|-Ak!BUY 4e`YMC5p?8|<3 #8d> =oBؐ#n×AlJ@ M$Jzm@e3xϣ}(κ)wmql2˓s2Vߦ;LGOw%Ir`7EW ̔RY-Le}25v]]j–<Ű{ݮKnܸ{_,H\ D* k{I}R@uDr ^{u\{^\zo w{4T\1Sov#̠ir3 Z5Yw_YooQ*Kn< Y)MGzi:YY0Cp(n1AC*FdE[ $LR^Ξ<3-tWD)XZ|!X ʞZaI;0O3ҘeX{3z7 O$SVͽ\ZD*<ڷe+; f,F٦}֘A7rG F$l5Rm}GYufH 6Npn0ľ Z0*Ją]1HX;/ )3PI!/CV]k|8(VFD v:]kC`Ʌ&X!-f00WG =n4SO=N [Os fO)d/krV58 FTǜ$);>̇:{XŠT`&d_1+[Hƭ7W|AV>6Clu,=s*RqDp:HXiVT7ڸPdK)9˦eLKpq,_yP0)1 #hS+>QӐ_N^U!O>.ӬhNrKV#@>wK&Zț ȏZ/';>.JPx)M)xDɔR,sA&_\ q\ʬ~XTӎcHn#3&;0yQmkfwGR,HiXQOJ\uDt׾^"Gw>3$MBkDv dzyS%@V<Y,J%)){"ͨob]O|mKlq!Ym()dkws%qɁ VUQ h', %?1^,hD뮊&gyH-,&5 |"W Pp׆RJЂ􂪢3CKTFO 4آk sXb4,n׈: Db2΄ɦ"m稉ԍafHHu~cpŤKČw. l';v¤ԺqHph̕AM=+Q wK9 z3lFG)ѪszH5:>j#pe=mRL39K)(h {UBwXVtܤ~>券L3L)ĭ=Z3݄y^ȭ0K 9MU9&Nϑ?_HӮ nK-J!vs#JSpc$VX6Z8nuJ~\}%5z@ >+Eb,Dv1\=Ye:R3ػDoJ$;04ݚ/ʶW9`ޣ@%re<&$p*(ը*xQAWh:2U\M^ $kXEJGAi#.e $JLleLsYUO@O=e7|Tf]}]PHS-tsMV.J3r]~!b!yaKekACnK\Bnlt~B4vRŚ) UR4ehVU>ߊj {k7[[C HޗҼ#}_ /D.n,}( ,"he{5]R,X9S w%]H5sהri e᪷:s2/0/ D:~8Ty8R$"WfrB&a%$xyޱk1O $p} 5I!#w6.FM S bz9+zF᳊Mx`jF@]x:1tϕ+~.` \P#CVgP|4^P=مmiv}ͣI+ XUr4M)/I4mF! :-r4dO7d 5B3S8a뙻y B69#JL7v 5) 9{VCR?¼>$nЁL7 rG$OJ2ڥCdEOo'sQդi$v* #кD.&Ǒ?<}, dbт~_[QaV fB|n$Y7̋뙧y%# h?ņ 5/:=3"k6F0=F)[9PLlb/C-mm Q(>1~a>`Q^qTn;Q7HcSsvG{qk^knMHJ&z5,&*1SGq;Y8y GR7`` vX7OZe;g(.hZJGi.+Z۞jηou2hgfI bD#g>*m!L>im )#<'lڲm>Jvӛ6Q `}JcE"%WX~'*>Jj63- $VP)AijdIY,JGG{'!X -MpuboB#N*`j\Q3p&xbt?i ^3j1클Xp&YuaX(?Α<ʭϕNM >|ycb|;aY/R`s_<^u1r@9RYUq~^ haiȅr^V=yלE< +B3i.ek֍Sia<&܇u) 2QRhNTz0kNʒNe\-mQhgeg[=+;3[ղ,\`|BYJ^JWg>ͦc ef.iWIG 5~i C5盌nl 4Lb 2/ 8::[+|zWr$YPeIzhm"z9- ?_e9%s]/,B6ҹv\Q%>ČRՅym :h?kie:ʟ̨T^ˤVYP2tE$[a*7HE.4Mzw)^RͼrN_\@ENt<ʰgsTJ]Rϧ5|$^ 6F9^y tlZ Q.^E L Gs)傤 )KE9TِH&9cr5qI2+{\\GK9-|Kd9WaPJul?Ѫyށ,y%5[&BUIFp!bܝ܅iR9i&œ7/yƥK^ JO٦8T$4K뮻|z<s.g6w\⛖Ġ`2)"jC]-!)o&d,QפդTYQRSnJnMPx-z FODLۺscvb7`KEսy5u1 JEfGKkH6VB(j6rzюZFsp,yERj@Nׯd46d)3*ݛj8?.F;"\G!ЈwX+WRL''x8u+0ףMKhP抖N T(#cYoxBml]e抔w I.<5P-Fuv/"3ڵ[cEG GwPo{d6t[-Ϧ{Q)nasZc:>VLPKZOm\YfG4Fu&N; py`"8$'!6g/*ɔ m!|>5JEO^y1 k|zv7^K)xpe_4 fD~= 7np&+.ΰMxp]w+8::RsK]SJ$h.@mf;s΃!o JuP=#E|+dpTԗLhznӞvTMu3`(JKpiŷlS=LXtb"jSfchq])DhI¶\rP OE9]nr~499\_JnAgkqd^ip~v Ċhpv~e,TUPT7@I1o9O R2B(JS< 1(* 9h;,qL%ujc$n\ } m3(H-B3-Q-䝻Kdmim=wQXQ({F|YE`#QyN!i`±{4IퟛlpQ)juMz$$=]p3GwEv37^T2k fMmp\(7^+%2P*%i$@+ |x0f;U.47,zO\-yѦʼKN# JƳ'T "`Y*bfNp~\IeRr]g yp 'Ma0GX9 F#?ZYp] ʬFP=4CsJdMGjBUOӾv^DUmGdtu$Ə3K%Tx0\jW`$]'GOpXמd6M ǖYCQbr ʐ 71$zHkU 1QBYr7ֵ4W0=)%W"t,whWn&F}QgiMD iu8FY5;c,rTm]M֩>1M:Piy{Ve^{ 7ob3w݅R y^mo3 `5;Fzŗ "xW/>p?zA&56뜒rt\"UH5[P4XI{cʀT""SEZǯ'w8`Ѹntm jAёLXJ1Ez4$?+T\"4`:`-6Y,l0J\ WJt чת8l~M(6 9#уQ`uU>;-WP JZ|N=(Q34ř:9S6wa@K(D$bŹanUv&Թ%H&>,zlq"w3r+B;/3^ ՌS#rs5\D445 2ώ.w Y9fn;xm2@ ]JY=1ցM~5SMx[2%IԺ]@Κu51+@5]JsA^ $i_R`JLsô‰bL!R{T}ޗ.)>J?SvV#v$ԍO|΃5MFL((KVH)B,,aP&)!vBz;o}O wwuq. >47ɥgXy݆F.iL̦HHh8t@XؾE!Y-vb2#oJA'{aU}43 FnR@':5C`)2eM#e_5@D\xӺ CcB>5ٶuqR=%xϴIZD=<^}uB??#:eEi_|E+SG|&ϫҕ."Z%ҜP 7a'uH͇ $ic4e鿫HP-ݑ\>l= !wuhMDV]I j7xJլ!z]a2RwoVt]<;zf`' |Eap 5uS΁E<{aDE%ӈ/2y9 %\u#=Bp8p8"x#9p$qE[d+?VLӄ^x}(!ZɹtP4/0m[O l=<0*nW즩:yHQ5hϭRJ_mjE"-1ԏ3񈺰nDw6 ^%w PΈX%!<}!@h rskqA]6XUmFy,u{ U?17 BUo$*!ǽl JYFx2LYESFIgAiDA?Ⱐ1œuZTU6S#gR;G)I5WHT…FJ|[x 쏎ki?8??"`kp"vcH<nѮ_7/G><MZlyRI2/*P"o--'LR ܥ񰙥owE؍Ų/G\G3s@+vA!e\ ]v_1xB Ց㜬ެ<쾹q`B .O?5l[QۥZg||/H),PuL*wXeȩC93Z9ӄsuw5{+*kOSr82w1ssɍ 0V6AIC +ӛHDGsS&qMݸ<^ѶA!6t09pk>ֶ7.QALXҀ`% Y"1ACI&Lm^AD}-s Jg#fs+ԩ1" .̓gB]`J@dx) 3ɝ&#=ר6DTR&q7̳ '';.Bls'H( v;ۿ/ýS= ASOзs)wMCsIv /*"U؟{8,3 5H Sk (isP۠-Yh8ZE=PƩ%4G78]s Nq?yFis@uQ#5{V@j\NVٻ]֡WΜ5`͎>{WUA @ &E)Sd[{$+aG;v[3C y=-Ye[RH .ظjzݛy̓y2o -ros~:€dXF#16btdpփ*ZBR 24 91}aU^[0mUkl @UO8(3i"K}]ZL,}) ./ +ѱ.[P֥D$˗riMљ-xiCMxH_ss c@(M>p)@4ހJDiLT:xݥñsw*FWsħ_ONF'9=P g㇏Q&ls5eIu Iee_5N>Yc3,%.9eV \׼g x'arR'f¯~j]${5=[k, }\p}{p7'&w/ Z V)99FĺYŜ ݯsb&*:O]|'n{ի iJyLdAPC&qFBgB[(T"Dd<`(:R C+TWdCя§ݽZ1*Yr\rj1@!օ뜃%Z94F\-k:+\:fMF͑$}>}dlN@w}J^띝 <`/y 5yPB"ű :H)59ʓdN}"g> E./e {?eȊ]rEyT "fkݜLVY$fg}#Zz^Mwu)q/d4a'L~%--˃UnyRyYEbgTv$ՂD \َp)R;sR$eGLJvO()& 28,PHÙ/WJX5T&ZMչb#^rD_F_tX % PgOƣ?#G6 z,){{{W5ˇ4-E@r9#&@̐~peu]ߚ 2Q_6tʒ6pY.' ҄ D6e'dW1jj*锘LHx/R358REV %H>6vd9sGH֕ Dsk_J$wauT.N<*qj1: 2%×1^\ٳ'Dc\ἋX°^o QB@$9G @II1TY7@ae[Eq$粹y3 _Hàޡg>R4<F@\ĪX4TY"ř.wALTajyY!"m`.T@^YSLK۽d>O&CpIG1Mz/'.UҮBRbE9/!2:'/b/:v}#31:7j Ã6] b^u5N'Q.*Ikbʢ) &5ۘ=+^d(zu~&ʫeYi}e)/?s-}k&=\>zly*v WZ%Ӊ5( ""MN'k~QPTzv=Q\rsIuzK9UnzةUaPk[fB/B1a&ER mA*UE^ْQ V1*\q&d䣘ZJ$ӧuHzg2@ ww75Rпi0?@nsDZ?7G^}AwH `9U]X) aʵJqȕAqo 2狆9Ϗ,Hg~A"rA. TKI}bV ykcl۞->ឧ dC@@M/`+ 16XV5@י(/"d_!ǺAAW` ,bS8٪xxSaX/:"OH;]lMbD @^{~9HʝewpuU*QgNd/?ƮI.LHTtyĔ@D8 PH߫L-@|@S3_:+S`Кs#0uH%~QaڡrDLbu#Hc!B$z->)“cxPA b[yI9$g#@0!{IR?Dd˴X,XVN0wwwG]e?g<1Z(n [?o|o{[["dKuD^!\)@ VWC=%uTBaaT!L[]Pb3*$cPjԘSRqpyU%{b<ʍjq! E|l&nrGS&X CB^CB=qu(u952eJ_V1^b8D&YW 4f"cq= firTu#Gp1lnnqŐ wu ״&iWВM45s$ÃV {=7uW&*)?}QHVX,+h| PoJWs:ʔ /9D"E" _e)uZ"D,=5Dr ' 8%]VGsvim"97MՒ:@:ĝ;RP} 5NYC+Xlǰ lnnaZ𰂝=,׬U#hT(V& 8K)RL REkv*,T0yIQdEPOk0M^EN@s܅M +Oc1[k#k"T)^E&_*EIvȶ1tc = ,/MWWLfk"1+)?O<>M q8q[[[b۸|r*򱽽]_,[~6u4sVuq%g>~[nX%ݣ ɝ@^MR"ʸJ>'V!.VLƈs5  /y(bhI1ZL5.j:+e]XSx Zgچ9~@-QIdU-?|^e@%lfqD.E ZL jՠGנrD%])8 H|)VTNqsL&_/UW۝VD`4:Av@rN+SXY=IͣNTmD6tY\F{lmmѣ9\p!⯧޿.s 7R-d~O=4>NV"5DGΰxXʨbβԹ&Wp !gIY6 6h8>zE^:draӧOc\Nf/cʕ_G-_ko.oՌ!{hmW ||_-7ߌ^dCvuȡqQx?*AJ꾋!`@\o#n>#o@ *–ڣ℩x`|iDj2+^1ňb"Z6H oeQ~LxWTV*N q΁c `w c6Z,݃48TXdNi,d%_I|BlN< :v uK%W n#6 (RA"<s h KUo޵Ir*cXmkd{ FQkTء \h؛$7j`e´TJjAɊ$ZJ8Q*ds,(MP ^chC\t#G)_1:6ڠ%?|n&= y k 72">TvYC]i Ou>F5jڡGܜ]p% .ZRzd QdY@mj/1yF2T-NH2UdOdDD`r2 QMDL:ҶM \ڈ ]Q<*3aww_H9!P_r(2`]Zſ57!IcҫmZBG =>I#VsdTQ*):3S=g_Q rrK` !lfk+t(bN$vFgȲ/C8 _@ͬ9#Wy5^IB:!RMv)Lx>.֫5yU6DaM(JݕQEfdG>(}pS 9lc(dT@,*虄X6rbR`WU$c Kdzn¶Tb ݒM 7P!B;te DE§O$'3 ŝ&M'd&R ̢SÄ`KHmfuBe #;7vX)c)ɭnQBPM*NT+TWfFS6{5R]$9L4Ҝ]\xq~_w? X7 h~B cpuwމ'O&=q#{ @/Yg9Yx w(餬 u6g"0s))D@ 1A|JQh ;彷ɘ>nLUDhY#rЌ8"'a\Yl}$ ]"9Q25v`*Ҥ]M.1حhVJ6!U2Av#(?QѸe(8/ 0j>(Z\R 'f͈h/(ꘌ12_ ?"w|M~4|+_XS; DIr0%yHw a6)ey1_k]PN_鍕 &8(ς"LE( ~T,lƎi2I؄EQ"$ACx?RPB3q5(JO?s`AkA\2[6M-_$<ރ}/sfZs7Z:u2M٘)Ȧ  MigW]z *r*О GOsɎ6m4eIPe>}!>i)ő|8sp>bU{s.i&o(u>M@ φFók  xMq?8x;cȖ J:- h < B OڒtĢnܐ\myvP2Ij EX'/ x.Jn)\՛S ݨ}¤ Ov~!Hi,y^EInmR"*4IBeV辇>(ΉtCH\w#D?9VO;w%5e˺@$-%XiM#>ʑ =WP& ڔd•+WpElll uԖ{{{*?Wٯ~\?3Ê=Ð`bq<8yꝉDNBV|%ҵL4$!,_ҥ4 R%qNsq|K5g'Ǝ ⤌Ȯg> ? =bo%ƹ ;S j}(#@lT2ѡ` BQD6"93{Ik5A70OHٍCP, = 0PO@6zů i /W@m.gk g9A[ GTؙ̪P877?jB qJrR&)k2ӜIe2ɻSߓb"7TLr&>Є$}qUcV5R+wYSC*@Ʌ4ykF}%g &FR jTgHFAQ|~;]Pο5ASAjj$@TŴIIz]8vXѼ( { wjvdPA*Q ἤ:G\H2&R5 McaG| lv)+Ɣ(FK* AR҅f˚JGs[݈=e gX$Lr>5Sf>Jv'VqgҤ$/b{(?7MR$'GYc-j\ NO)|><KVAj\j*@ FnWkЪ?(TOa N[i4h} ~jaa;EfVP#ZBs8xwC~1Ă~^9"o"+Q6Y N%߳G!|Zf3!23H^Lh.b0Mr')ֵ x r^bfa,7h_mx<5X&x^ahŋ!2l̴a`";}bqHzLoCm~P{T:;qB$kLH*b R\"1w nW~tP[$:HyǷT'zhtȞ 0Yk;Omab8,\~vܒ)xI *bnZkfSHO=(Hrͧʟ( *dquxE͏mkW!*Iaz^SZhrfV?{{X. B\-A/V?-nFIĸK?KM>zͅa.j}|^z*iw4aӖyӱBr0D n292S_9_ihwdTa iUzmn\Q"U;6K9VǴ`'R8`֑h1fXD`2"9܋McN! XkPHOD8eaI`vr@fߌ]n}rL?1ôaxɝpn'ۇ_< Jz#psSW 唷Ó|8G~c.֚ 1ʨtLz(Q _CPZ\R"(|ƨEty/Ri&4n?kc뵇l Md&~W,{DDApҮvM>{ rpJLH=: ᛊ21ǒkκU#%eCBO? EZx7'poeS{_E(L.r&@r<5cs2;~[FP @ O{UI}*(*Xh2||_jWB^0(cˮs6jbd*к93DP&mE9?K{ʠ}:x|6IgJDgz_23`Oz[Xh.5 ǂpt?a' %Վ+؍ce|1!ȍ~Kx) FQӁC1EI؆ftH{!'1ӥr^;q34%au>E)f(jT(!Ω.j)8Lց꽏7*%.C- ~3oYrfԙJk$) Jo b u(S8#d.EX@5TZ|| *|u7]fB(\cE+x]ˇ.z~Wo{ǦWF6Lj|oz m",?NJąlfdlq{>9r#Vi6HPk%\ljZ,#`D6ZvK6=`'|ᳱHvw&BwX,1LPŚ7@N9$!B=ROΧ $˼.9ZHD K3Y}6t7#ct"*#^NB#r/Pf29KX54 w&Ya?%b"CAٲ%[[_m,5R^QdY N}Cd9)P;yţ yQeZHK&թl*`.!$"=s}9 :,$7e|Uu*QZHN]t*5ٯ3GXos߻ WF@>Ο3g⦛nJӯ$фy=:S,X!S+V) uM^KՂP?{MNt,ɼLlX]$Fy23wTrB&8?&OÙR)@ފalэdywI&veRVĢ>"Dz]4XK^2F՛LID&jDmaD8 J5pacZ57ЭXX ΡL(v,QB:J1>ף.GcD#@@y@4HI%SdP$@x:%|Jc P@4{^M7=7Ƒ*_4$ @'jIsIdӝ.Vy+skZFmkyi.&I#]*\R.%i@7{S[8C8w<Ν?ͭ\nun1 ?hEV\?58(2 djP._ǟxrKDrdhE%f΁<53*1$KC.pßY5\G{+AZfPoaclH.$K=QB EKqM>r2'L8yâz8IjC]If蔡Gyxc"a0NSu_M9/ĵp>g5i+ɀbA}}Z8i[k&V0\\uBsPZ`n }:Z0 "sAmCлW[VSU0;W<6OMB͋If|Do]wɚש3M?Q1 c"CG!BmI P"LۘhE^UPT&kd\_X=c1Y*2CB(W 47N=R8(W0]^5v/^8ཁ1<키a\'~y({_h`f} D.7bù 1i[_km8XfniI2U̺QIHRSe6֟b)5 6(TH({hPiXq.(b"'p\1d@RѾfhS9H(Xv(P, ٿ҈ <  PKZDVoMg.~Wk[@kj?HypcC@`tcX,Tpv*L5W·R%a^E)xRYNXB$Ԛ/9q}0 }>/W1:&ga6|r7jQJQ 月l*IuK0b,d96Rt v{{҉Mn.܊I'Px]뿯'n^U^yi~S3K$Ց\dbg? m)Yaa\_qH{PN!E3YM]L%YY:,G z +s;mx>ſnZ{ߺ(Xr+>=}Y董eSIspO"Ư8/y9>%G M_B20$MQl|!L0꒕hF__"3+O9~85E`WRp}+Fչf( | xjap.HHu&Bӥkä@B JH9 & ~['à]A/@~:3%FxQ*ި& VG .14EJg.y w%]F+:so}r!6J2Y.F>`: Ze jI~Fy"CTS,Kɳu TB\&6G˷ Lj2Ԛ+aę`D;QIVs&>/5Mu_~ 5 m|Ar됧@@>򼑣5-^ny/5DNxb\Gq/arj!I9*.LFH sʴ˅[b5BQ\{ƪ,+P-1^;u"뀮 r:ˈ*鮼 70#ȣ32H@:I(e4PdbeSE𳭞ޒ 1c~#)> %Ȇ'b GtX)6ep':fW o9l5t,[T9IRg]=MrcPTx.Pǡ&h{s犌} Ś,>;&%:"mD[ 3bww}Ȭ on*5WS&Y皨'5lZPq#_ v%M6" RcW.Ɇ<ѢbuLXݯibb8z$cv@Yql}.\\:mP . ]|e|Hd"wKT6 ը$N-Ι's RھsyoiB7xQKY:*jQ4aL*AWfAiߵD Ok)}%E&J9jdSHQ*W] >?(η&* R=ׅfIvw +D4"/.Km6S__4QuF|L+ 0@Yz&Ƶ"q+%F ) c(*T_^1g`=l3PZʌ,R9`Eu ,vuTO޻M{o>5{}l? |aC:L&jPa.)9RlAbNHL|Y18`\YcjaQ {P칉M:U{h:VT#/\DqE!4#S`}*$ko=Nj^r/xY@T=^=OEւ9eځ"an#7#D/`^&%G)0k]w%m~ ]{׿~-^&5`1 ^$ibέoIVP|I} 鎓m0uISwzTp%GMxROEK!a h -KkqfY˓Mo59}M>1QrՍX٬Ri2QO@-9i&nEȜȵvx/bsHqȎR9t1кnB[@7g}5!?5O~~ih2vל!nhTSGN(䍵N*>$@nqz֔)GT6 :X ),Ձx!4^S Y8UZΫgkA&8&2Nk(~B/׊,C*X.0bcc+/>(΅Ըm+^^^I," DBT~?#`6ƿ ,Mu;7oGK4 Oߴ|hW^_?5+a-a6 *N !n$h 4tEKW tݯX%]d $fY=RO-ŚZLÕ㝾xI1߲dM|yY SipGawgvbZ! 8APJ UTh+HaFkR>`v_?h07WZVZ<'סl_spͷd\dD,Hp;צ^sF 2Ծ8Q.(vW!i}Mt.gRTk3=(T/(ȄC31ۑ[y1{$S߫5af=;xH]DGb$@r(oxXk&4"!O`'[좝o}VTTK 2l<~F[xӛ޼_.~,ξ+;_=}oظwQpPYl P#'"vE.?[VН $xѱljM[4_ijI/\#.*  Bx"` % ?LDbj.T&zSrzNRT&d(F*IDATiyf2 bz7_*8 pK!Ԍsj}k%\ 5QAšen*z=vvwptM%?bbS@ :TjykXǔ> K&g8 Gxu}sv84sÓ8 Q `<Ұ`Xrbl|=Cxetԫs@ @~%LThrW()zJH7Pf$"Q>跮G>n-+?z}g/?}:_^د#+{_~w[g'cAH$AfPcvԃFI!>1?3!35ι(XHM< }Rbij#)=%nLlˉ7}QvH ɧ{x9ylh 4$""A6"& ,F .dۡx{v'-8蛎z~3w~㑿}cGa@-Av@T@C"fQҔƔ\߶@cMԭ.\$Z^r2\Յ=59K7?*Rmߠܕ3Q{NFcUL\R 'dƴ+BhZℕ䬪l}I#ZCʥw-yC#1{e A} d" !kPX< PJTj2'Nq:s5m1~d-3r?(wT2A X[;̡sw=˛8qj9cLL >w~Dx)@-k.</,'|8fՕ ` aYqXj2 KL>d`c(6X3cj"°C)UfF7&v ֧+ 6`_(rem%ؒAA# 5XK  MG4Lb8kֱo}߃־%mn="#H)ٛZ$")&i=>XP./|/ u|EEf  Rj2L);?rsKJ&\/0Bz[1$-H{Zq-OO/_ nB$X Pֵ%\s n&MoWbccCll.^go} w/.^V#-EA 1㪜S3% [S)d@=` F!ئ2.nD AS(5 "L] K3ߪwZFWV,|$)| Yw,Wk +"1>p~s#l JBntXWo=<ɒ,hgXNIzԏ!.h]Mrӑ ufʐF "#E߲V ?rhArv5KZMT9Y]rLDD >azIVP#(&UVjW^% $ _8QMa}T^/_ ,:0$4MZ]񖷾 '2Xa]o;w/s;{6#-A|LI4Ԯ.Cf@$~d 7SEn 4vhpu~!Ď:\Ӕo;ƘSdŚӤ{L|*T@T+X40D!UXB=V!TZ$0+$+~0pհn3v*L-:r#cڑc'eGO{{?OzZЍ͞1/%8D$rpPbSĈ Kbaꠓb;SJ7`8m{/OQ.r0!F**7abAHsY+^(ܲR7<~$L;W|Rv+ĉ+~TPP|V|xb ĦCԖ:7Av8`ow)a$u5=9~?G~#X.X.D^qÚo;~x{ǯW-c+z=`ED%QY0؛5" *d-1'9\ں: <:j. S+|v j8XL6R Oc0ARO< CUIZt-k)u1 (7svg" ȴo.dfI."Kl_SG3kF~y,5J,bd/nv'lw`L?]f A]p^7StR>D'PwiˀcRӸ>RNLq9g97pkn-Pg)$,U&L/5@NscUEuNKE ^wˬF܂k֫5Ο?g~ }[xG"CuL&19 uL}=n >ĩS'qrD%67U(L8_yObcs_XGޮʜMLSz6)PG=sg2Kdg<77''@ ~49~4bJ*k`%.Ȱ9\&>X I(aMAg`,0 >HcVN1*^Uv9UУCg$Sv}ƈ,wW ƀmۃW#R^}Ϸ)~'.7Po& ܘa~X0 KĪz7tx1$ex%0$ nM(jamk+oFPZ?LWk\#zzV2VT]4i7VRN Bqqk6O JEzitVxpE-WrSeyPz%HJKR4r8dN iɣ!fRnƈ+l㼇G11X3aQ`zxO>"m\Xx7h~sɢA?9^Z1%vt5I71;0+ M۶v'!8Wq`9+_\M'LB,)T2sK֔hُg& #t-NbjH-s/ޓ?ܙ%i=sRV7vߤB)Ʀ&+|pBB> xތ^};6674:K?q7r o;|+zo_o&GދǏLb9%*wbIÀG>?wO>xpDY:R t!}Ag!7A.RTE*F>G+/K QB"ꢩYҐA)Gv e M H@#}4NE" b"t-.ZtY4̦̕OGc;swcί+o0D>0yUYPD.:|فq}Oy4̌_nm< Bق1Ih"۰b<|T˞|F?L yc8j/yܭ.3T1Sdٺ]WSW:79h'MFfY>U ZF666fFN5wȟqk}@=ѣ3x{ރS'N(8(>wF=yz^X8yW^F8^_t} "[51+簦쵮ix'S3G B1$$D[aAsVE&{S\F^Oз=VusFj||`jSC1 kXakJͽ`㣸NA=H1`U }+O?PaɟAN>CvK.p=ּ_'ox0/v$ Ek2W1f@kT݀|tȄYbHEM,(*Dt ]S ̗"1Ji 8`0Im%j iN0ec AzרZF@s RM*'* ToѣGq,KX;8ףOA@awz7?ƗYrw~~ qvy]r+%$N qz/z}Պp+ox2 E:Ji5R7-|?/}xᯯ;TmY\l{_HSU`yRw0\6I$Q&ɲ`č7ވ|c'5oO뮻'OoML)f8qpK@]0֢{ַ>˗.%ׄ3s%;zȵ73M' nRifOU踉( I#MEB´8'rY3SYH)w}?VT 9P?+2y"Drڟ'gsa_cGEjM,sFd={`CMEt3ԋ^/dh{Ϧ˺ "\aG/"'΂݀|ͷ?PG/<߻E"@zOo#QInbBe dLaV#̾0H>ΨQ#hJ o +nY> ˤ ͮ< )1o )UQm;sUQ,h¡*S@<CrT0F88Ӑ`o~Q(%8, ( Tz\ XbXL: 4qca= _=݆_n|Iivm8~5ܜ&;_-;֢,:b}E?{7t3.?7.^ X ́TH{%YDm :bM,4brA Fc99XY7yB@ՎX 4X*$lי*qI}0c乕Q"`UZ k 5 _c`l‚^\nHYNpW%% <[.Q\8^8}¥+5Ȃp6g <b] -GS _%r&p$'DG,z1 L(3d%Hx $@ \$N @fd7@iɷC 3ytΏY2k6c^= Ujz9gP6R3Բ5ԇ*b}L5b]1;p)=zŢ(TS4N"7d#x;މ{|/?gB܁7)>?w8v(9R0{](k-: ~ u謅5Zo~=n' >#(. _ LYuQA ֊~ƁYjAfI5"p qah'\;kT3;zyv8muښP9竔<{"ct}ׁbtCO6G@b OB"HZP׃=u p@^'H/)SDLy- `X_ww} ^;_xVeݸ甍^#$B8(w)!8E(Lq jFhGI.C:Oüf/ lڤ9klM"+I(ށlyvr.j^dV\<:)i0Xڛ,k)nhT'1]pajmN: JP3jc\`cX&vpIߋdbN8[G\,4Utx XkqM7ầlb PӇI5'N5sh)N0/̺ k,JU.Z:/;Ūi[ &>e@UW%7ٲMfAovA 3pJ !6}N3΍4>1AԌԨ(^I5?S ^&{#45`XGbJ~)Uhdl ֵ#;65`ߥZc#>_> _}x =Yݷ.qݩK_{N#._Nvzoa [3VIײV;ܢ"xig ;bS抨&h]/RMι酘Jhbem,Ŀr'qj-}0C.T+bkw,)mGt]'O 'Cr y\t 'N+_Jl99,KlllWx^nя⦛oN>bc"ʪ@cǏ[^3>[f9 3w0_(XzA^3(qa?VوRpH8h&A5v&4rysNyvqf◪BOX[4clYnfmqb#`dm9z3uRQX!C}r")."UDdwMtbgL^CZAׯvdx ?;_[~=aFg*"~}~_z~SWĔ`UPlrlk.Ğㅬ~̑I zkΑݦhA1Rv͌߬nFCگUXÉ.L':FkYSsnܟXbsVG{{f;^z,ba5.?g񖷼7x#|A<#>~~ .\//o{["% Q9eThaM"9+tQB*31%Ra>KMC+\A]3ݲ6"ʧu`B4Aՠ3-2ߥw<R aޓL(T2B$=%G<1=uM{zYYei3y 90Y,Xo?IR -V0Y;p{C8=v.oo>o|M_n_<4+/YwyȭB <ݺ؋ɳ&%V!&H.8v$I5d"T_= ƍc:gCA0s853gÕ yM)peaΥдڧH`Wa$VWRJ[NiFH!/؋P O&jp/[[G&M5ܹsGŋ?wݸ.z)q)|8W~%vw_0׾p}`Bagg􋿈}ck}q|cc=VL_җ {]WpK&XN<~j*!TVEuDsWM#OЀiSSؿ"?7Ν2 )'iC*OAIPz = ٛ麉CF{T3ѻg < YJ2{fX29Lt J\ Oh Ζ#+Mwv\# uXn ={8{gԍ7c~%k+3\vI, 9< ?{ ;}}{ 3 rSzb2P5❙\$iV o.s38'OYT h}귄?tqa_G)޳"{O_/e\ܹs-oy zl, 7܀o/<:q$tKu/~q뭷~?>Gz7_wc~OVs==‹+G_˿4\:残[nu_O5*qSg%Ā2r]j21r`!P U&M޻jQ/Sr'KhP\-M%뻮iȫěVGeQ>F_wKk^G:6?(i8 פ;8-۽#; \˗7%˟mBw#x\_W!z;w}7vww{++UrǏy-Bxr}ƛnbr,O~Sĉ)|~XVܹsw;M)Z]L6+}i'r]y"iuPqmU!ʎe\΢JZt 4{_% *s>>]V[s1Cr$]he-#O6tN Ok~q(/[I炃 i:/hq_"q4c#6r-X ­`.b]nv0 R$Bz~ ;tE؅_Dß{$_ꠜjE&(2J4v&7]Tiį1eD~WPO%tʻ-L l#Q\hbuEHA%'=U(_!*2fEBA8BwRZ6WD+:'!I^{_;< >O駟za?q?p-7cqN:v&nftbxꩧ_V+|C»n|oo[Μ9\qHPd5s<=jXE-JlKLZJq~W0PX] 4'|q;+5T5ڧ8 HYv%zE ՚k]~ Ѧ=¹6ů@ByS _C!% FgH:rNK:SSϖ#F:Dwgd2upORg[)JpdCO6bv2c]xV+$eJCNԗfjHC40UI̩qȣBNl˨*h1dٮ. Ǐc\w\r0L7 | Ǐ?Ecsc3h kcc]}w{}wߍ[oo}[q77oOvqEݺ Hş}2Z +Žo XΤV&q.D VJȀBC3#Wk)g`L|{d n(^PA:$LgL?3_눮X~UL4BlB izI.t}eQ⟙gΜj`v~=˹O>58["}-6zJzܠ$"#$gࣺ`ydAe vo+2̲]FA)A.![[`AX)@3<%;)9gT%1pX$41>l?R;Oիa nu4,{Oąq1t8rHQ<+pQlmmc>}sڂ_WCg˗t";qGL=V{/Esj\jl}F GID[Mj9q'L~USs^:ސuԸP _0}]v!Vd>PFK݈lz~w΍>0(A_<.:ae$ _z"!OS H:bt&NH~0Fԃ} I藈USkn W[@tebؕ @q:WXC3$/},;r 4MFrS+L*aD0{SdjR"d{%DAsh`,Bf4? q'W-IZ^Ø>@ UǸ&5^jBT'zcz'Oıcǰ(Dx]r<4^w1@X'N7ngp9p `f<8}tB(-D i񏮜,e<(BZ=A *7p̠ϫEghLLMAuXF_^Y ՚@vKЏ"VT#hTiZ(wqB8#]ya[jV&0> }Ŭ*<6̀#l!tx A@,q.>"!d0*$廊Z_@)1Ljm.$\z!FH({["<Dt!L*d}w[3m%.]br|Q-NEV7✝EG :ٯs0 q(֪y]nRy LHCk? }Yؑ#X.|gϞMĿrU,kv+IGwȤx1 bX/`/:6就WUi cscl/]駟 j\0O-(OD*MZ>yH--P-J8o3_" 0L\WI؟iqs\J4"! lDJYM]HYG۔587`9ã I8;W{ :j3TJdxT! }U+ RE_&,}"|N˓\" 6} !G %|!ّ{gʌ}$9S|F|:8?Z,M MRxtBV$혂JUda-b ר 'ܘDnؚm$?aKH\G0Jsv4ټL2TijLyRDʀ۟(_t*gtQT?P2ȍ ΗgœO/g??bwahgΜ^z%6%W}: X>a= _qEx7bow@;~#FWj|k'?+{Mo 'NvYqLM}r kjZ|LU-W%d2R\T*3l3}2ڠI܀gB8Z xj} ʼngQecES/ ŀDs5 ɒ8d+!.$ SKQ읍+kL"w@9#Fg%u1":JAA$E~+P:8I0LN4sˢn O#il>W({1k=Dz)] AVCQC GoV_{ST+7@Ad U-iZF[afFP{`!^hZBʤf B ʜHn|;;9zO?u~G~/b;Z2/<4ΟG70w&4{7No xmwx+ &sca<~3ŋ.^ݽ=c0k]nzu@ {v{[tx{0cp=._gzyBtQ o%|03MM_MrA>SV.I=\+- h@nuPY{1Ro־R0 W@ ^/hLpJJ\b*9YJ%9Цu0SRHe%e~=0MўDJ/턫<h0]HEA+`& CvTA&[,~V-eMhˮJm5у8cWm(MG^jPOGdW㠥-{Lc(j<<&>]?rEa+ uCb 6S{g%zV@æ@", lnn };{_=ފ"}//ww"鰹d;2|txz~ \s:%,vƟ|-T רρ^|[Bե]gK8~~Õ+=,KnİGo #[r,zoӿޯ~.n;}R5M#Ks??E\ z&nWnV)EBb\eMB59*{1r\s6P Y?@9n> mʜBDm9.(,_CȖQ>frc@Q9/ d0SR#sSN?.7;:I ƆH%"y$PkY&8E]{xETv *&}j Wng 670 @eMRk7НQfCiK\k tԬeNT4+>CT3߫zY3"!777[ZVw X._\| [K-1b;w]neNyܸ¨QmA/'7Nח۱=\ހ3q{##&v/ݏ˿K+tf `ciC?!۱Zp^1{=vwCQ*CO&JOK7~ QTp]8 XQWAh=`nxS_i W%px q; cxml 0t]RÏ_T!=B/.#iQdz\;FM5nT7iLܤ(! gY3Hi/H&΂Q*ԑ`)_%$Tk1ҝ( /Bk*e)cӯÐPwy%Kr@s{jg6 1@3F4)?}۸{qסҢ|#ɟI_tcc l,x%Lo{ 'q],'^v8u*243g;9n. ǎG݆G/a_ ?ƻN|A:`K9!q;ԟq$K+w.d?o'a_>\эlWD"#K"[,&bЧ|HskgU]qx!R< iаi09("/J5)X(⎺uB*3@)X@B(J`(ŵ]X|X,/ySYRdg` >ӫFN/9ƷԭcsM0U$qD1-6.E@&\Ԗ.hGbϘg;_3%+ɔ{ ;az ǿ8zd72ΜV+wBAd/xiAǏ]76ޟ{};e—|aƃ0.3Vѩ~j c7gWvǐF_gƹ3/~\y]e#ж=C-rYȿTs}H5LY&OmHA\TqetTTxnf 32#۳@+!{UV8&1`^ l΅S`=1q'"XO\Kj3:"tc~a7+`" a?{(_NxwU @18 FS!$ #&ҚT1].ؚ=^LWn0< 0%]l W Ę{Mdhas'4Emj*QgNJYí\h*IYyIӟB%S7W!.$-ޯŏb[o?wO;lF|O knQ._~Z{E6FZ,6>׿xI`g8{^lm HrO0O| E·O3~g/2}6?a|G ara(aBZVΞ}]kZm*"7qvPPi՞ܑi) ,4 Ap=>jwJ}$2ptC e^/#r^1 7NNbY~uv]WːgexcVl:@b-fS܊&(Z6 0 $t}l~-BwC Ry2=kLx]*DdE=AW@%l<.#NM.JFA D!~/C{{I!K̀nQ؁  EFZ g@mk1'm9 )Š(bAF@SQZe{.FXbā S>-_Z SwIM\%&x0@o_7, 7<[Ň߳#[%[G'fw 4嵿&%=<w58j576^on}w|Qb]oz~7uZ0ca_~+/Jo5kZCJc4< svŭ0P9 i.:3ă6?!gwd2rEF t Q4t LOIT{t!B.H6E[wyl60gt0SkgZC9#XoEI> ]$ { 1r% dUPÍF5ܚ.0呀 XBpQ an|9tflҞCdNjMX((9I#Ha]l$KnR~ LW}mR l[ 5sV{+} ~ϭS 2ȝ+h6Lj |A"u(zU7F8Qp |c:[G{^[w.\%݀}]0x҈V~A?RLtS]'] dyoARВ_uDv+G9[&C`SUu6 6Fq' }7dWl`dPx3cP{Z <9>1q3 }[w~F:8G7l-º"Yτ?$>A%l1| = 1t0c"z}l8X3GV}M||ZN\{5J˩#ͅ6%B6IYL6avMǍ:x'Ix%h%ety[]0_pχfzu$DB"]cDu3ٙ?qy~7=moŌ<}lihA1b5_RSJNLfad10 /8R,D8D9t$HB9 ^G|C P= v&Fǟ̡'&}J$D^.s\[,[iB6>uF@٥hDB銘< u5R~!w'\T\% ^G=}c0.+b)$9SA㠜XwWWQrZ7$*Y>ތp!.zצy%-YPP>| F|RlMNu,`Λ*BE?'F6qƦ7xD5_@˯Z~?WzLӆ4Vmm}KaK8*݋WZ_ׯ;<~ΣV[aV `z8? q{0 <%͋R WZ=|>* yiϩ P#0 "+y9e4с;m`=\k DV@ۻ;Ѵi!_Fh)iÛ+s[솈t59 r*"ɒLwe_TkT|o~ +2|N2y8`Z|(?m=p'5qPO^,Y3ޭXnX3aI5ݜ&)O iqd?t?#8q/ce/vvg.aSHE1DzQ2 wo>y ?=o-luIs/_u_V!RY$aqSnr6vOj^5<|zXXFsyըm``'$pbhb0lӋ!Hq\K'%-" K2&9MŸ)5 lxnT!:lmnbۑOy6M@nďdL|VZK,I3c?J7 @:L: ]i_ *(VTlt!/b6}`5 !&ZO]M!_-8}֗ӾZ'#\ k-Mc>51ėAp&W>(Ăfʽ~R·촦ca (,Xy~\W}Ü놀5%9n6?X,U{%3ΆfW <=&}3 \ݰ-|-Gs]\a_29;h Ԯ=;FkgQ*ݰ悍_A]a Bi˚SqHz`\]d~,Ԯ`ufq*[ xp4ZTD8Ag;{:,5.-:#E_ɰV0 ݋45fín y.$[f-| &ɣF/'6e :4,d}PBB%%BxʉF`{W%sm(W)ZrkE6?6dr>rpUAܰå>jπ%wD*JjƊդ%usH$F+xz#q>7zx:WS'+Fllz#Qm`>e>qx] ?v?k,f[0Gqq…h59H5ٓ r^嚩9tu*@PM l 9-v9Qcdܓ ^q$2g$O/-©r>7}TD!Q㨮b|Z R/4xI]V &"y2-؂0W!^| /ZGɊ֋c K ֲ*$axS `Tؕd}}~LVX};|&dY_9٤p.d  Cúk/l}5ZgfT_TR>Q׶ȢjxzpqJhTA<-PgO܄o: PmlU ]G 7cSjrN5AB)٧y ё$l{AM@H~G\r>9LD|gΩ0{_nig3*A 3)wܔ',i2jL匴VDJSjyH+j`8{xC/ěH||*M ġDTp#=6}KOí#F35=h\ 8-1nFO]`X˙&*K6I*}4} &eS=Q-PuڟA|eu^_)SD何c." [ihRz}6˂`N(E<6;^@,l'xP _O˟++=V'pM'ZB&{49%ů;nl*isQ`"atapXpqןo?:(8=)2pbVTq7V 5WN=<v_Mdb2f@I@]&f.T#[A nzGG?a2`qP:crwŕxa",>ҎSa} n,}cR T풛<S]c_N*wqY#yt>IR`ae\ znt q$k«I/uv5[(7ԱEQQ%HGωTfEh #TcK_7DBiEfAn 4?ꔂC'҃ cᙆ`!ߴel.ne?H# |:Wˀ ??ƩŃ ZSԾ_1Ƒ1=V{8±kYM߳=2$Ƕ׿oV>.\.ɓ|HNy$W'UT!T skfRJ PLSdjH0IN<:UOnL>!r6yJ KQE{1hs.:t`l$qXxsd1`Đ;uxafUE^G /76(]|& URF{ u[[D]z&e긐NX| \ZyPbjc&WVvy׌7P6s6/z20ozAೢ6Bxf_~+ q}Tfx~eZI^rPeǝ7㭯^n'"[.f%-vd争!7up5/ |$`OԹ>ZiG?X3wۻvmdXr_OfŻDggq)8ɛ *B:: M$Nݪ&5P핻JOLL$DG9z"~fXwf8.hduXR98a*;h#JFWP.M5S͈/, !>H.)`a;(JMġ]/˜8Qc2V=%ktQ1A"f'I jT`}ðbV^Lk}"i31` c`*y<5 0ڪV;4 ,A!u(GrN!:y O$c6ɷCU"Ƙ?gu&G^_rx5p5>yh6eVk}kxOy.Z|W*⇇}`nW<.].d<[ `w r"+Hht1HB%ﰰ&̑zUFM&)4/i@ I~}1)(I)HeU(h.CxNPESlJwra4-0aMDsAV5 +F)*¨=&$jGKHRܶdȧ暷XE2@J_^&%?$IF` !%4#,l.osmgeό~MG/UԱE(`׀݌0=2{Ea4!lUvGi şR\pp2Ү Qaǰ @koM&@o|4C;F4}'bBUㄙ+@ʬ,"3 *&2 9Œtr*k+;2%`ǘ YyĈwRm(‡b1:*@ %늝>*@Sih%Ƹ^yVj|P$<]{VfOyZyi&EP NM:]XxpQJḡa8ofGǧIm NNz?o/ j٠Q-ITA/pْD+G*x2?. `.5ړj/%c$AG=^@}?j.x(ɩbOVh{8 am+>G[X`S&dkӿx?6cl6.yZ`  p2Eً(c3Vſ2Bx駱^-5͆0\ |}PfJXd/#s0:}4PN2bF|^D:8Yū;ҹfAqLà@eQ}^X t1<հֿ2'{ p_ԭEdcSo΁DQ*_D-#I텠v`() ؓS,+w(f4@Wez?JOI1hy'+|L瘲p93\8wIuPxT!\I`꓂™韮;ŢCws%7]e|6v:1&QMaխ;n C@>^-,7(ib&pc}x.fOhq1S5'W/2^\qJxl2K#3ަG6́'핛$R\ e"@ .H~Ha!@?'&QxathOiNb\+juWŶ9r=yE9\rÑJļ-,RhD\5PL,f[IyDjK퐯(֦>K2fNIWpɿGc_kncqE큺=;ؽlFb#@v\:Tjz4U.>Q}.63灧3.l3jcV&ǥQ)hM{ᇿ7u|V _!hSs r0y+({N_M)z] R9RD;jͨ.p `0 Z8籹O{/<8rs@R} \t[SCS`kez5x쁍u|2$+;(Pg iZ8%N0J \|rK&^¥iI0{*?ȗtE%N흖I%3 7fVn9^+'6ZWT%Xuo=%h>h'B及H8wEv [;rYY\l=oOzlq!4}9H4 XDUac>wGS ڃ. !pF ߧO"0^9N+ɲb0.U<ApqJg_ :Gc0 k㠸MοB[#>.;qIF bJؼږߧ\2w0X#k#? Cw|?^(nLEYSD#+l=PEO\Ɏ(%MFt9\ .g}$W^NFO|r PĢN] RF 6ZÙxMjX*+fXfl䁦mȁNy9~5"Q[Goŕf"M>LGt0Ưn!ſSCߋv9$$0(k# 2LW2] ?Xo` Q0oA[}n.7XƯ]nVuOի)ι FٳpM7/yĨڔ0jaίBmAl&5O 5y.A&a OȐX-qD;u^U0I?J"GEFl&x0 UR3xs.XMzRZ B4خxg02!lşk`dn$ 7uxq+>dJ*@r]> upc6JHK%_^~uIRlŸOrƘi!k}{7bb)gEv~z-a#,ْIw-XV wtbn`uÑsy-&#0eAB[{Qm]}z|vc N(6n{p\LZ#]s0/Z^‘ Gd,2]?6F{X@nAu%+qT010z"Lh}z~DCS ~\}`]b<~9`=G:Bg5JDG4y9|IZZ鉿:, }!aRz 0#{w'OTmMhA#7POUӠu X.jٲ:ϹCUHDR"(hDDZaId2V~paCp;vaIl 1t=ggCZ2wsOU$bUݺεַp$3 y5'Uj-l` Jl1rٛgI|dufX71 CXg%&h6(_ko¹DfP$irĐMKFCeXZX.wss oHιqMk5'Cv&^3_S8s# بbӈ!*fNA%6ryEA| 9LNJS}Q mu"2.Q,+T ]g-7j"$d_o-{0P;=bgg'o@3q~8u4Ϭ&u3V{}ZQ}‘+[=}p,+΃Nh*X* $φ5X " cDL|\ag,MKɖ9Ź~hH.sCpvWФ}8AQQqQjk9ցN:!Ydz-s&FhW??vJ C |(eTt2a&uQ JhD\}U@B(f\w *N£)?<.\޸fīo2.&Y߻vkSx̙L%'vp|/\'Oԩx啗'*@b\ k{{<~Q|cE5FB3c<&^Iwz\;vIDATHnP0Fc^A9A?,p83s2V٧vg6JkAFS7Նxt%ςȈ0&(%y ׇNJ⠑M# k)d#"zJ/(NuW-|BBSbtnw= \s +¬;y4!IP <5O Fl$@hStF09 TpVȿ9 tHcܛ 7w=@a18o 'Nv{.X$IuanPL47SO_< E W^שkr0r#9pig %^' ¥p'Oӧq뭷駟% `gg{{{cs$v&f.^}SVgm3*T6(&!\#IتXu4Z 7wpC4 Mr܉CƸ CwD;ٟ_ AC(12àgy} s Ba #焿`J,0xK1f ::iҠ8TfWYF!\z=S|)&C2oEI!z.'$;!bO' S;6hC1d?o%2`ia,4Rb}L!]q|"2L0._gӔQL#eL^ (NA]e_u:!w"1ICfy92Tc^#*[,KceRY(gRlߑ ^l!,YDX+{GdCIjּgV?eKڡ1쐆U]w 05)?v{xB#+S Uvh%in-al}#}ގg{5ChN:SNk__eamɓ'q 0'5qTfOcy;7{ n*$Z,QxinҦv6uzI3{GLÌ؜Qw{ؽ:|U0\ta_2.G7d˙! #!]R_HC*Gɪ7Tpz끝#'.s' 0-K(.p -NJ m%U=vvvpI>}Z#bZU q\x|[܌G]M(5Ez+oz6>`UJ$E 7۴٪&MdgCVBp-l;W U5 KX"ZVG'%  f94e7#uwK811jrXFOL(p 1agoHΝ?}q%uera! z}QFV(ryh& ȐOCie8zAȅh!eFNI)q1Liî%Jle'Ny[vB !r=ӁM\Z MBo Ė^b\Guz*9dneLB/*uYgt|ֹU-wz D" ǟl̸kw =!Bx9/e`'w ?\'`6ߎDD><2y _ 9X\8Үn-%vN,pqqp 8KpIcXn?a] &`ŋxbsM@ַ~wygސ>cRtaq}d BVAdrk١YB`G1[ Ol_ z@'2gS-HgsV1 ]H1bB9"Iǵ+R&&p&a-R[xd)՛`˔N?Aȁ۔Wt&dk(=;wlлvEC.E͞ xn,݉옝l'?RIZ'Lfb`U@绕ڃ5 f͓->V.%G0w۰ yOPVZ<ߔU@WC VfY'W %k5)TK/^ ߂O_~ ~ ulcN k:A1Mmv\*gcDB\ȄH~ , WQRH5\=Xw2 65N<=\xb hQ^on6,Z;ű:i Cooj wqmj<KVӈ7=ȝ2Р٣HI]FJ!D#dEWbO wJ a=Vdm.H0!y*HËb^{:aXXƳkOb9VP>Kstm+܎OƜ;EQeZ"P%c#@YPJ¬z:v $i "mLv+N 24@5l$NL/ Bj}-rs@EE 8gP4XZi#6 IˢrS'/ڼ}7L_'.xWoN̸C %Ϳ/S@VrH)2kKg6-b{s-\3_.'xs8ϟk'{{EW5{{{*]wݥS|˓h;Kka^O\ې#|Ž~px1oN0aw|JaTTUoQtif^HU>mrz!ˑt Iy_@!HlA#8fFAZ|y7-D0АɧFA\ s(69,+pYkh"7{uP7(@qOsK8?ajXE=X$,{d/D2(=g^^$]^`N7MLC`*( JeHHNQhn6;Dmg Q"LY!V¨?lvn$[>'kN nxba p&Xz";yN ؠɱ΀OA'')g]xkxhE -bOƛoٵV+i.0 6?ŋ;^=IMZbp] К\;l!dGO\Df]knoϟX  m,Ȗ8lRҞ? qx4zN̓8VGGU-VNcSu -_P131LjՈ!bLV|_D]İ?Pr"gtyGHVc0E #NkD$ lѧĊ+DLʎM"%}H*y 9E9ەƌēFǧ֥M(1S8आ Qh@\-Ta۩SCQًPG^١w^~£4"D^{ of%E5:u gΜ)X.n1ϾPdL 17!5cK+>D&~X`gW:vwwO<ىwy'Z={Km Rqpp 3ZYEzM+R1 fzx]U3J:Z1,Tc|3#eDJL4y|q3m0|^ }kcvUn!pc%8[38 |f::  C!D8倨C5v"l9T%|yMؐ0M{6?s&gU߻2.ca3Ua &@4 JIwY$U;54kr[eMnŮl]x≟[BJ1ɓ8sL.,`-Vw}~W!|! cQ[/%-3ܿ{jZlї_GGG888ŋg8*bj*^@W8qtto~[x=w]7c'Ν7Tul67 D CO"08Z1n:Id;#Z|DNAnx}x5b1S 6 DFl 2S|qlQ\ 1H<"eގYG5 Lp|:szzφ/Y&K@h.z=hyŠ c;ªqu mJ%&X8G`K}z5PGp-@Eښ }yV?D[oU=(\YGq_:m੿7/ſU70r_v{E"/ ގzr(ͣ>}!'\`<#[oٯpG0wzmdžhC ~ϩa^/K!{\ a!<; ¹d;JL݅sGP$P~Ej߅Ls*6bʎ}iZhHEjX"Rԉc^ RNf:k WLKl(l|M%P0X2EKO&=h/Y_*d8XŞ16Tʤ]]TA*+=PMw 3a ~' 7dKdXJX vuİˇ=O|k/BohŕK^~:4-b՛5p#~ Jȅ*}DEGGGxpZUm&[p{%|3p_:$/=KX]h&eͱs"}ap5x:.M wpv"?q_qxxrZ]>/ƨ YUi{V^o|~n4%vABe]fU6E ʾfl,2*25&vsW$*g[Ś6jk eZw7g`"E"8 &W(Uv̵3>5DNtb0 -k:y#n&$Jn3N nWs u̬N WCcC,O9dv+v熢t~0:jMdK&}[z$41KjYxnCq Xi\"hDu.=xseK=Hy MԹCѯd́)5Lmpǯ*}jO6--ev G[@/ͳ֯cFpލ{, }N5އ]:Uv4_N(nf'?ps^/t^7<__~, i. dűּYTf"2"Ϙk >vcc9yYI%|Y2E}s#&Y YhSk'l/&.blGj]3#*5<& H׬SAmy<p wRKF@XP WdsO su8[@7n^ջ 60DL&VMx# 9Ő`wTO+Ç7>lS݁igjV~uhz#t9Z7dOKeVF-ҵVk̄L'aJx T/x?5 t彬ȌyDis!஻(6.ɎRs`w..z0v#i(Gpp#  Ŵ@۩7-o?q<:J~^BXV6&M |{a|1E )Ech<ka0I.%TNPl2]JZqGp'"mvI ph!=0LEBL2@ ֝j18&G Ӫ+UVѾ߇_6EV!xΎZu~^F1Cc&]Fcddh(yBPs8w ˅㽫H5y T2g VֽJڦV"7 JB6>Vb3+BEOYvT(Tq`8hGرRqh> j?;*NVD_x/RNo >\wu @ -<%7/fii1nlKkޟZ.ёY8m`\e9ƣ#|M7݈oqҠZ6ϕ]xVR6d#ewekPD測拰}<VEɬ|g_=;LhZh2?XFVq&YkC?x) QR`ER~xɒb0 YlrB4<38 ME9yaKlNm!Vc=+~Y$M(ɏ%En J˺VeeXOfUd’.-(JKX E\|pX,Zar 2}C+|)ɽ t^Kj\8%DEsR ӆ}f9<P#EڰsondV=2ox'pBE =܃dbLk2H@; g` M"^`k,N{xއ}{o8X lS` X C5aG]Ie{T; }sOUB;I1JAZ.-6klvj}5p78z!צ%@6ui9X5zGq~ VWhF]FT;(h`hKZh4W6R"S[Ӎq!!ZU+\P&&d#<ѡ]>*03 C00F8b^d#/ nI4Ѷf(g8k gr+9uj: فibaatH:M7%d9jub]|,NS@pc$BVLs0ǥDK*Wd02BxVKM#RM_gS[oSyB#A]q9mGNMW<ã qa@_=O&xnm H@naa2 ^kv?mКd~boQ=೟, gϞ5d8 mls !(Eho|[q-77]g:A:l|ta\#\chۤCi}jۄ ືR6\wj <1"! v#:F] [ǜz͂>sΤʀ6L9Q6i/٠ZU7Ieb9+Ln BIsu RCq.,לFVxdr*( wLyT6˚j*VX޺tCI-%uk%CDcL Jrjcf SdX !ES@[k/@]>wPtbiglV~m+c zWso`y/?h$p&=u@o` v v`-mZ_6@+>?W0UXŀsnR{+misxկ5>~ch6GU2gum!GS$lpV M1*Arf{qH-GA '0~ 2c-H~~v/i>jt$k.X0:G~RƩ ryT?qV tوFDD87k ф[ZL䀰íyQIE HE]}@ p #2sBR!2y8)Po,s2#]wN/.y.Y\X!;f+i' rw<#> ;t4z,yCO hQ)6>fp7r̙=XtOFvȁa1.\؝*$c\T[;HmW&@ 4(-` P}[?7W{D@8u|A_VdBm=~AHc!_Dӂ rSBggZEp}{l\c6mQk=beu+(Gc."6ADԜQ0TF41ی!,A]Qp/G..\2TV% Vl׫uDC؜_XӚq_Ʌ0S)o@+XDE 6%W-4deL$#|\'V86cCh!ƀ8״ FZZ>/;fK?E>iy !H;Y{r,=d=P<ٗm WlK<œTxӟ>Sm"GŽ;Al!$@C%0a& <4^_H{HqȀ]C{}*v߶ɀksqo}_}{'* +(k; 3IKI`krbkU֘dU4zy.dG\>ng/{lf%R{Nq^z/Y댙\ M$等gb@L!6ɰ&{389vN$9|w.x)?,y@uON=0w?YjҟfDbgo t Wr90΅eMI>tye-s&[NseQzX3G.^j,!mJmHt0~cVP$4bBŖ;m{ Me15 z(eBhag%5!@C&4.^Lĉ͐S!8PͅEv27\ 7l7.W\B1B4~B'K_Xu t= QRLf@va=*Jל9̨['yddohɑ~;)d$.怐^~c(DO&Fw%D$%ބAMQoW JBϿ"}j35[{;`M#`x۠ r[@$C>??+Rey-2"mBozm/_~7?i;5K.-<^(Ll4ۆU-kMZ[*EJ3Bb,p8D.AIULݜZf $ '׈^!s 9q#+k#àI~%FjG K;{11<ͳq>M,1${3AqL2@GalD@4yVL pd(~bzC5jG$ +0s~"<5Q[Ot|ŅdXlC-;ϋ9"FeO(Y*)x˚4۹l6W8%$ֳIE3 ׳UP:c*/T{m"#n}C+P;q;sVyFF`wwh'0M *]G6\+V(=(Q}.0u&_yȹe,E7PU.U8ޛi:,|P^srŰ(dOYrR\Ca uz' GyM*[-lr.ޱۖQtgۆvF(aX BdSPEYRt #!n âԁ0{&zI!;axnS&wLl2$?uN[caRbÉvTT }ӕ"D9ڒ0֨sS`..{2O /q+Y&|ӟM7ԅ7sSkFݾ:ה\-1p[\103N8/EQ d"Ծs\}Zn|SG m^ ƶڷڱF7sAō IYl3`Ijcs6%gJYir|H/UhfK(c);WXz͸JScd -ˍB[Ѐi}^Oq]Vv]ԄP_ɗ.]£>Í{M!9s\.Vs0|lO9v&W{f@-: Nw~W^{9Oo↪igϾzP+Bʖ?x'VR]IgtGQ~Uۅ(!<㢫TBHɆ@bd51f4@.1!"u wXJ<<GG ZJ+Y4,זPW&Q(n2'@6Yٺ;7>V1E:وl$]TA =xPw:u;zpҗ:@Q歖yJ #ďThc#?ٯQ-J``X,ԠWD9XAY6*T9 dnLyؤ }MS"cS_p|zOooC !#>ow\*N!*-ڗ _'Nep…uMkeئ' Z6]ut3 hάMGGEdqGM31O5mPB1]E@Th\9N!U_ Jgߘ99>2l=ev{kbbBҙ9PDw1ٳ/)OsF&ټ&QQ_ "I$m*`Mj@YgbDDup@PeE|Mʾ1Mp1+BMi;Ey"&=dgMdcY!^ԁsK\.] {\޵:egJc$z/cu0" mt!AvT|lϟ?ycdvvv~O>s`k&mK%͑ f'> |qRf7jcGvߣu5w=p x{m; <2ϟӵҷ0{'+^}]7ӼJ ٸ a4ه=(Z^D/$-XVz PlQ_ZyG9HЇtn%]x]qKLY3aq<ʖB))R@xT"#֬2iKGg P>QK!b9+$>(E F.msjkoR뉝+ۉCk6?@-A`]D=MGQ\ʪ֫ r%冨FY$cnCoy~O_5S?_?6g/n|:7 hIy-'6!==|hW{M 3|_;^o^`9n:|.]o~[qԩŒo. *aO{O}VV`'9ePxx-너2ܯ!E!!NH %4N*G$`u߱V)Si! 9"Ԇ8NW)l 4TB]KzwI_§LA)|c__vѱb~^2틒by񛿞/'J<<͵9az(lè+S(6b%?gXE61ץ*>,qABq`У#hOxhMc]Bd]^Wd4h=hus8QVK,5ܰa ^&iF>^~;UTyGCJ@ 3=j 0P*K+fF L(B,/kgI;dl !]D>esg(Uhh񛒐}'^YhE PAFcy&qC'͡!t4>wEO} ;;;J5ǭ ~% Aclt;6~_:&? ZrÏo=64sX2J^zfdo ߖ(s]4ԜQch(1#w* `L̯u4,~+ɻ*N&d9y,B 3vI0Un>/>JcHPxBqxwvgK&b8L>rNN6s b<#hKxXga4 @t*V V !1@7&{PH1Gk8f1b9'0l!>RC!J&5ud)ȵ/@ADZ-[} Q 8}jaeFw\A@Cl=FuԋU9<&'Vҧ$J$8Zy5FaQ׮sxӟ>uC;.M !0>яn$tm v @o9/@s>I[%Ms>16(3ӚC9[&^!o]7xcY'#V4-5 Xlm`ܥ 2q14pȒArpZ,R%ݏC櫴DfǢ8*̌˴kQ{*%4flE3"Y88KGf{Dp+&@+l W# S8]l,+Uo7#om'hwtdQ^M˰^s'c~ T=G^jG}/]h}?gfi0G`2%J-, pn̑f9!>_6o_ۤ}k{k4gh$ xŏbx'd>T|T{mP&ndO0A\;byD@dYw{%͙P+N\RcYm1?g$"LN !.N^ә|j&D0~DF';#,d9ʡ05-vl vӺ\zryT#g2C ې&1B\ՙLj3b QOq39sI.EEƘ"L ,3T yаj^d+@Ê GHG\;RBtUi{j*1>um?'LWڵ.G?~oR?rz뭳sInf?G<0p\O@&33nV|K_~9 \%> jW'Vw\c=[nwyg hkSUcv7_ߔ c\fYTN5az4 :`Vw($eaӏSX ĉ},nHQ)n~v1ʦ>^P *%psBE"W;H\ðt/U{X|rJ*ޮ c@@<)]KLJEZم+[ ȱѧ-l#a.SFp7(H!Q}?z BL_'ҿYlB;n߹`iVw\1=y/"siZi_STzՈ?̳;5x~R]nِȐ%rVdmhU1Kn]s&NHjG( aʂ@JcK/ϣɺ kFz1F\ P!+u׆i36(r !5*,B/nD U1p6aRāh7])@`Q^Y|m;BHjjuJCv 3Y XX(1$->Fv5!3AŀeG@œ*(P]暕O.N+>Ž6R%7D5 ke7 1{+oYi^ğ:xشQ*P35sJ]ҡ%P4Z̩Z1?W_}?~?ߔcb;Xhq0\x' +[_m|̌n _W/~}i, :'=a2]tB kBX]C..PZF[V aW824#/rsDLS:AI.ِ^= 3N#6.HhS jbl-~kg7RkowQR^:!_!F &"Vk96Hp?2D sA[AzP&wXpg(?|Ν59G i;;WU}Sm;&mU@s??׾sӊeS`E7IvU X뮿䍭)h֖]nj¬vĐ4*u(M$KqeuB2EN2+ȰS-@33:< 8qJJS~gSOZM_pm;mnަ R+m\ pkMHǶS-܂1U˛Hktl г{uqǝwo/8|M!Pdi·XPCzNs]׬C{jVosmǯa3P&xٹǘbKb ɡOTdS30U57NN21 `x#Յ/5AnVpܰb4T̈<<X߮_-NU1WAooTTreNo 3W@c EBgy2JA^!{=qXP0 堨L MvuSm-hn*D.vF/쥼{&ƨ0JcifkVfVB.۴)}!}Qn5`yqć?a|smmW؂CkoMzm~]`>__q?lZ7ljzEpi7?k' c~c4kU`o|6糂|{{F6[p0{\$}J˪N(\Źо% b&wd`.E3HsX.`}t•ue䗠aŐ\/͗ #\ ^]&[@E [\ 9\%7@;2p${bͪ5pR9g ٘b$ _ *pȬҍ%Q,r!]l|cE3曽ZQ'}07W\#ǬxVP%O~a6wm%/⮻㫺s6H6M>` 8n )e8n߶I=nF}/^|볩 q Cڼ~x~IM|:4ՌДO›֩Y+~js7@;1,0ƪYZf Yۯb,(M;2ܹ|,jCX~He\zO\}0xG oxiEN4G*e8`(H~$޲jhV$L6#5OE[ePģ,dD32Un2_(k1 E7kg1<B%*nC)lB2 f u*𱫺UA>9 B9{"G5 #ڏ\ F:L 6 n2!3qO=!sySKίoG}{?_695|S "n>.Uoӯm~6#33 >Os`{[hcQ*`{<ַqm;n 9kUI5aB fCZqzLoko<nj$PAآͼӳB }vы\Ya)/˓6=tTc y0+ǣu!4r>J4I~ Cpp[|"0$\\s˽$ U14,SKBSi.ȲM`Iw9̅a"b*梞ΏJCFA.ipuBȢ;W^vSuWu[Z6==PrT%g۬"Xe)X!";bA[L3`rU AeJjt3 飏>6YpiOqM7]v?%K}r(@o=i9h徆^{-6ù~ˍ{L][lBj73g`wwmg^EݿI@rΒ]N2B&K,=sGX%dd'H̓C?hq ?**0 y۬[:7s` K.!Fx>bQ#Pڔk=b⡹a }Q(`"O.*>!xp}x\NJ ɷ/yII1_J'+kDqGȦ>БNlbvnGV/[%1.}HKīY|u,AN.FIasBUo*ipmdgO@*])fIY@ aÏ:A;^z{Ь=M[FrL˯ǟ@u~%So Ҷ@="`r^M1WWO~?Y9Z`+5M(@Ix'}Šn]qjg,ڦT_Q G(gz>/Ձ}&-ǵÑ95نrL&"rQR #3Gfȟ ZF͆:IQ RwdecT\M 9tŃnH\djɺOnXi"G86 )MqU!&Ljx.O4ۉ`u^GWcq䅫d]T!#`P#kjm4a۬".Ge_W\.q`+A6i9g0Կ6?MI~sS75+'N%|oql Yצ^sH3*1=c=ƇҭvDjsjtߊZm j?N/Zxj6|5RI"͖7YE$vM-/ZbPs5e 2@Xl K" .{u"J*u򘐘uD BWԄ DH;~ZP pn ת&/G*5R g"wb zPqdT0R=c(DG#t]Ph&R_#9ujQ^M'=42ƾ=cNZXѡ A͉*|i$^OlbS4a9ccKK?3'~7<_r??Ļv%EjQm'ު`J|)YW fx0(({m"}= Sȯ#|w܎SN'i%{Yϟ+rd80C9 Q 7.GۢR { Hti2(5JCN4Wk\x1q*5.MhFf<(HydAE#~b.jkp^uRc. pɤ!u #9ب*yV1ѐPԨ? RxH%Vw1L=a-JHR^jUs~[(*@1K^{zTHJ[^MԙPsU;M~5Uw6S_O~j{? Eg ^q m 6C,/~_pn$mȷ6^ҮZ$@VsI /.~㓿eDlMaVݱI0Dq^$C>[aePLWinٝiFwF_oWUH ~AfظD4M*W{Ӓzdd6,Upbq6Z[R򟝇=cZX* Y&t me2ܹD|rR`0rdKLZ5 (b[&i0@i:q̑ I<4*拴0"UZs407"yxc{m !PuDXF\?iQq2%MS(~$)}e? 2m݆??3g&?߮s.Ms@ooD̩EA[WM(\6¦r[=C=w;,h.@:=LcEu0xW_Td]-a:I+Y'RE.LjlIZ%qiR[k^9]L~;iUc&qZa +V4鐼- PSx oO61[]lt1e}q(DهZp]L Ʉ(`Il./:VtPkit&0B>?#3p2ejK9ĨBF,J 9kl~av[m}ͅ=a pM>}!0{??}ݷoI{5~gQrM*VsMq!x7[F )\jo|7|%n1Ý wܘ4T/i8x6$_ KMC͠ ns-s" e0ʵ0?Jow2,|FԿ[$d,;՚u7PЙ`6Fu91`5ŰX 5$EM`lTzٿ%@)5[];5Fe0ơ^cqWj/0"I!hF-ДմOtb&RJwrHq8qY]zt2 /"IC鬝r4<n ŗLD(KsTZy*k GsxxG{ GGG{oouBَ MޏI6Ծ)g]qĽދO?. `-)PȒзhO=4z_ij/;xlJj̤n 0UEdH!Զ9-]6A;lMl5@b"?}UH(?opr3c\%X,GWަ: 6}l(8eԣrIPxĜXj1ዾ3 vQ1*Q0+yqנNo BVh2dhJz(Y ˻tYrRMޢ :P d@:D i4wYVk8z3!% 952VҰDX ꆬT1+B*?ՠ}o@KL{{isQ~isDxK/^''[&9 •7M!skmA2 z\V?WU':na Pa hz~{q̻&ϣ˽2!6;ĀحBZ!pbv-N*WUK,؋O)u4/&@!J, v1b^kS.)Gq=Z^,r P+2d7<f*SvF 1VGE2բo{M +(y9hX1bx\c"IT-bؐ1MlfH`c2$rWAȀ=i׷lts] ^5V1xt8{ 0u!i2 Sc`L&4ׂG26ΝÓ?y 1nW__mS߮U|+&@N6-mQ3Bx{ߋ|.mx׺h{\9@Y_}5|g| Me"_HØڔ:!jXg= -qRnM./#T}]6`.YO\ ؈uB~V_.wl+&㦕:p!nJV5(fC0bgk.PZ%M!+8q$cE U5<{h rUyPWX^HCOHcsY 6w,sc|mf#9*AbϕËԱ/T(!ղ&K=pj3I{re.7dJ8R?7ϝۚw\bggg.縦lAKնsqqm"ۿ~x4sM.MA? 9.LVv(#}}5%1Pce5e:U7*-TDF3W|:죲*Jқ+!h=RduT9hD"ú#Ra%@Nhkql1)fc\ao' T0wBΉd{.Pj"z5- O }bU՞W]@)M~@6ֱű J)xJ# C5O"UQX&|29wB0,_-LBVM\P4 ^51GA{[+PK,TYi=zP)쬌_450Okkxg]3&w8և޸^㑇gc}o椀]?/s&9 s*t__駟dqU\0PWZoC?& `wy;}Kr+lr:XKq"/E>'oF)=0QxZC֯hB%G>/őG':E"3`ȊppJe50MgW6cFR?W;_- h]a~ʨAăץ>]QvZ)PgsB^đ{` #bd,!OOouc9ǘn& 3LgYDz2vi/jgo< 8SuX7l h{gz bZ§YV`Ҹ=̳xW+kc~mW}C?#mdow%$mmHysļiEЉ\H~;>_g@ kʳ>ߖh|Ri[xᮻ-ܬh]eC<ͪN_CG׶4/UePAC"(e~-#dYk\%Ҧ}84 (M/&82Y\c3QUu5<ǐ  X_>Y'("%:¨֒28 iv ϦEa RCnr>gdU"*ӆRH\AIX^Kcu(AѬlâ g(d ^/ƃ)6< K3f5b;UK[\O΀Ws%<'0Რ??{ލ^sh\Mpk{|GNsVkloywL 2L9f*ibm(Gxuih$X=3(5Ynjݦ- N4=JsPGMԀȺ7C2OV$CGhv>ZNe@DGًJoqS,Q+A | X5vZ`C|'~皀a_f`vO J|75u=8/ƈn> xIJ[8D괤@=@׏xW򫿒UEZC)I8ٸֲCmJ Z{ ّH"娫@~.ٞ?د'a0xUyC0T+ĝ7$6?xq"8:'8zyo Z75D .o{xיw lnjW5/{Y$Mxly)JQ*8jPŻȬ$/Su˫z= ŲPTϞ*~((naІjMICn?<ŇrÁ 9rSŀlfMs -!Ѡdi_AѨApV'r1 Y3'bL72D][^ĕ4tj+ 04;);6iW3BM1|V;,Y d  [@0Smfp?6uzkUW[~pObg?C po@or r w3w 73 #sϟC+ t駞<IDATSO>{@%Ȧj%hμM|3XxPZvj(:t0J!{^6ˇ9ÀJ=;; F7d;hCX3(1 <CPnC IΉܘ uR"?T]!0b[P*zbk K,ΈBLI%o?])STY#}eљh27HI:%q CqrLnUAksYߠFL}ɧÂUPs ߑCXܼv`/<9s*BGȃUxOo?O[a`̋/⩧R}6T!/cXloJV$]*` yomB 69rSGوm5=4"@oo?~q xoékNblhn^}* UWmΰ U\hM0M--cەn`T>bU0k|芈L2l +v\<3,wDX19:P1EΑ 1 灐 `tɂ qw:e?w0_&BV$ƲPBtWڵf&8a<1_8)e(s<_DP̀ ,ř` LI~K' o(M@< kk d- n/>WkYcn)P?kA@dB$*[BԾ\|œ1@6( YK )<fz\b ݽ!91:X.֥2͙/5Aj*!y9!gau*!  4KpX, 7$\i(!;ྕ]5@RX#yLBN+qa5%V WA <3w$Z%qz cI˓O.fpNs⯯v iKy%aD0Uӳ8Hb0AEѢKQѼSw~"st4_3<\7Wm2#bxOzRb6i=)[nN8O}Sxᇱ^' _3Lڴm*$P^Gyw}'n馩3&L Qk!_(S D挰jPoiv\XY C(u*yqLY,<EZ\x>0&Ǩ'^;+>FsLB9f9jU `Uwalra')TI7@V"ԔApi È`r74)LI_YC)1}~NjH}ٿF_nʍĚNr9QPͿ]pM~6d%@beu÷NKeH( & w,(>hBS|VisoQ|򗿌'OBYM0m9sh6P'iShQj$ |]X2pQ=o9B`O C,{n.?n["NIbhE]O T;(?sT%DD*a (L`dI;` + {Hb_B)KӍZ+:)I P Irp"đAEc)&:Z$"Sԛ!1KlaG@H7s8]K8'NM:9Y:|U |ifn9#XO:8d&SX 1MI!'A^z>y:We}s?֫M[Y).8.o%Vk{6%d˻Iћx C-O?gy~ݖ[EvRz%S^f{}(V?x;fmFE_ }Dqq=`)P\b؁w#j2^&/^2fySPєY_LcHDQ5q2HSͱKg8M?w"\Qe\}4f?;2N Kf=ÆP \JZ,BȀcYM,@ݷzGyzlacUUvcl6>$[ `c L-`ڣ#<:K񷇱s=]5ڴ7m>wTtt`۟6oc Qs\%~{コ *di˥Z,X,ow"># 5~ҥeKZ䝑è(ǠaPTګEH+Z ydzFdޥ&BY5GMi-2isq/^VyVXΥ+1F"'2dajsuC&\3Z2 iϻP GIA 5nX eNs%"QW^{ |c@/y,B倁ELƏi(ݗuYy ;&oG59E)b$3Ns661 4f(fw3 ]ӟ ;[,5%/oM`_9pqa?s6h"gM92L2;u~=XUp- \Bm?C2Ѓޯ&ҋ/ɟ<{?t$9tCGyi _ &Wգ_SI) n=C'nA\SE21utʌ9S:NdV qL&\a=nk6|2_+&;Dik`E'3<ãcvbZaoo_pn\ߒpK+%ЂI@7ל un߾1ɓkED{ſF8x'Oc:ۆcE`EhI4)O0(`}6+)9,aH|>[By݊)Qg,51LjP<lxH"y)KS0]|' bHM @dӰv" TN%4/E s kHwDPrc$엹fWI`ejs}.8~(T0FyW/9d (.9 g!d㟂,*u\f&MkCq'ïe-B-3\'CCJᒴ-;cQ?Kz^*Uu,7&d[k9!.!%3 &DgW^">7`;W~Wя~tZ>߷+!n pf.w_qXas?s /Lp:o8'Xy_o?P_qw]~WucjSS4hYmzḐe@C Eu&4a ~> UPL|MΩa^SS:sX/zHUa Jċŀuo_Vń:Sa'-B$ҰVq8fu䷈V4vbIIIqd|&wUB!휒Jk DѸDr3{z-F3DQHch#%NzI-'˴5B%i4&o/I0,9?Ѵ ԰=8<̳li^8uԄ!mS[5 oEp\p߮du>֗o//矯 ](@0T(9b82}M.G~}e6Rx`i,(PY PPU}ߢA},a[oq,gXuYJƴSMnMۀz$F. Au<1Y'1'!VchEcج}jV"H*5?]i-|Tm !B)X(ߩLgO=L\a***v2  ;V&2\Y' ټ YF-RFI/>W$J"=IY%K+Yf?Fx6g<;+ Yދ^z gϾ1ms</">:]>zr z p5~8Ķ9kM `G\sͤyb]aoo80G 7[mD~i}51cQUP`Ơ>X]̯-:X>=B6 -y -?;OUIIcH@t&prz] V!AЌiՁ7@FG a(@v YݖWamrmEU3_5peg^dJMw͋Gdƨ:N$j l vّ R]B#a씥kllC1 lpS[+9stOĻNWeof_\uiV3`520 "2IK\0j$ȑi [POg >[5B@S'Ui+ JX,b4$(vnCb\Zq԰4fBqe[T7yn܆їyNdBkmDyyNpPT5 VAm4WMGq$$%޹"to~l%; .5=c! IȜS-D*w}?Cr.>֮p&o۹:sgё>ec>φ4S\ Ϣ^&h mK טvww}aggg S'l}qym@dnQjWi݂Pևn4H&2vfAA^)ܢDK|1u]ཫ^aL\aЁFRkL\xS19 H5s՝p"ڔ[2߰J%&8GQW .ԠN5U0&\q ټ0GUg:P:Fٹr`SܔZ~rELz|!vU 22Ę9dR`\Er4FfBH~s;#a*%.׊Bo̹sK/'WǙݿ56jlcç?imU7~բ?k4+Q*2/ƓI'2JZ-1)|m`.xN~S M/]6 ګn4H ={ԋ1JmoP_c i,bE*Aes,x36zvj-9ӽw s3YڶAۄ(5)\s PjjUeÀĉߟ4m0G& 80K8O=4.]nx)Gy5W 2+<&i ,W5MxӓJ Ȕ=M&CZ bN%ѐG=Sy 1B2sz\)򧲾\Yktl[r؅K@>IFVIR'C usfC)YNj#Zx 9Ӆ[!=ڢ%7QV(ef4܃0-@&|ۢb (Ws p.Ν; 7yu8N:5*nz;M>9nXQH|_W'd@៴S8.]Vj7z!A=\ៗu׳>}^a>.+ڨA=1V77jFjs)gL?e%հJj_,qS4Y&͇w)sbLR>G-\A.:4G^N&%K:"!$WOCP4Vw#YF*9KӔUY2 ̜Q A oS_ jqW,#&]J2Lh(a eGyan!Dmj΅ةz_h"ѺL&%I!&{1>Qw=3VlÆw,DL6ɵdey]#XO\9),鹾+e{vo:|c;֣~SEffTd7567dC=Fr-;OGGGXUp_j6sO?{{:}2S;eSf^Lw#onq !':QS1BPIiؼJ䱝EEn:"3BCekUPq bim4o:]NRe  0zE&X32674 ( rwj~<5'J۫LӛLQ2gk}ANw"ʄ)I_EjaSٳ8{,oG+ro4ʌ`>n#"p\A߶IkNzdM+dS`mBLJ>!u*8q.]… & |5?rz$9I`ogyF߽* ~_X](WDZ@. %]xZEEjCQlD^mC u.B1sXCH ,a%&YQi(gxʪ"3lDX J$H@LbnqLks'2Gd,Qc oȐ\B:mdJ-SLOӉBtvfOM'M:b1w6HX$*lvkȑ6V̜m%!ڕt^_F`>@1[J_P X6U[" F~…i;uK%9jjS# bg!n'vһi'\ߊU&k๯]s h=>ӧOŋzkm{{{W2qd?f pܯ1;;efNPľm`l0jD[WɠD9'&1*67ݲ^ CB}NԓFrd]eZd0"s簠!={UpSU!Sϥ90잸|B@-LV+^^adQlקo pwCѦCE؈b }R@DaKAH *%K7!&4)d e@?x;2|Bc~&YPL1I4TrSHB%nH嚒_ë=|\:񊤓B4&1_,Mk&ݻV+ŝw޹o+M6mk6fǩ.G&oqq뭷nPZpxxCk%,pooOm`^.s? 8QVѼ!OưuVC jեMa 2>pD&əzz'g?\T>fFB0HT`_̖ieRnyyGEfb!9'W ÕNcqʂq@njG/뱚m_SRcc,;{pr}j@/86MZro96} Zg@cggB=gN[S\@Νo뮽 F6<ӨAYUt.@KRf@Rk )987j@b9Ηr#&`I]4[\i )H!=SFXK Ղf005#n( FrU/RkT!ww 40ceb(Ƅ%X E<1ڃAC] { Y##0%j\.͊hwf<0ÓW!a &l:QU kh䰹1j@}+Mߜ-S3/p:믿=&AoA+i8kř3g&0WN&ƶJ hfƍ7ވ3g^.]<vvv4`XT>۠1l' 'm¥89jnf'&4XHG@OY(*i%$c BTH1Fxԁl$$9 %8[WI2lWvv|@#@cuxP."~*TAW(&zH`;ВځtS+Xepe By Do*]N |Da %bW|GpXCXP1p.R`윝b'(چǑ:#2Eײd6Ī2?{98{uV,6P> Pߦg-{+:I97Qz27kwq^|E,ˉ"r$hggG cc/hS`Wbsb~vkBiؘ{bJm*_Qg06|dv֐"gꇬ255F3Ñ7C'>PV$t`G=bc0ՆBvIR}YWV ,sq9/|''ˆz礑DoU5:s [&hlB~As.eoe+9VdLluY`{US?{$\ AF W Ncy-TJ<@pI茽դȄn 1D0/fE+ォ.LBlˁP&,Y0qj9. -vޫ9z$Enۉrw3פ]ichj *pttZKD>@q1RA馣rsvLr!I:/Y [il+<…iws{0 f 86!37MYz'888Ύ6-moQMMu=xXǙ3҂\!aNzKbAy$&jhl:H.;&ns>T,eX "¸2AjEOfL+Γ0$%rvvvw݀aX8,矕W)hA RC\XWO(Q.0I`$dHd;Js\1FxMYt3I{߂PV 1k0 K:auajYT×؆%zf>W~kVYy)A,v}h>13!xʜ3g`ggg{ Haªڂ pQMۮ9]8>˄Yщl>Ca)U5%^B״l__nW{f4BxH3QχZtVy?WFd=&|rɀ `Jg 9Cp~0_cތ dD Ho~14}tg/%VzeEﴪCyTenrW8!=֔<}&v~=83-2/A꺩^_р!^2-)V^ g;ȠRX'xW"cFџ95tm)NDצZd5{$}o-vSW|/cG]zFQ2Dȸ7@re+- K"$0tlz(;ɡ MV/,d^a]wBz([ĺ4yp >}>lumY^5*@Xٳm#r\H o*mU0=+u 5E,!%E\^H#D!PIz˪@1j4p!/{J H~`.JXΥ(`>p$t_ .\9w%U7-ag;xDJp“{.4֡l]@  imu @%ѓJk]G |qN IebID̰|v%1LMH,֥co-II3Tw7\ K'8j&?*`U0ʪAxgFn{*%qΜ93ˈ}oGrv6w~U %H}vLM&A-*I νy7tSk%@e&,4TH4p9GA5)d' grMEJmX.$:Y#U5YP4#CE>QJKxrk&ȭ H(}f(@N1bRUbΑ#A)FuNao!4hpQBT42$X3Ӛ#H$p$8_,@D-맡9톹uO֪ͭ,@DH.~hhP.E .o]l?#2$抿_+\pӧOo,;+J`n?G º\.qԩJ rVYl,{DMHĦfe'8`Yxx?LwvLolf ;Z5PE(6y1֦#lj"f827dI̙h 1kBX%C q>%b1'$ E.N/6 JD5b.75'Lf]iLAy9dv/x ( ˮD!i$@NX$SX\9W9)fU@vrgrhfw>Nv!]w}T+-^{bw|!u* p:m4A&z%DLZu6p˯vvv&L ۫C!uk_z׻Rwk6cݢXsqE8Nq5:ѐ dk':|윭w=eEY$ h)Vz(}Z܈39A CrQG4)2(7F; O a8fY5fH貅@$5 @+K+\/Ō+?(YH#s.@fo!$iooe *{P !浡"*7^A )1ffozEfGVT *[Q*i~wb L$Wvc39B/]Bb{=o ]d߃qoҾ& E hv_\ަϡiW^7ɓ'*wPrU\j+XypehW[J}?EG`WUEܹshUնmsa5IJUkU Pdѳvљ=1篍O^E刖] tUQ^rG[[\.HO|C` 躴Zvr[]cugUBV\J9!moM9p誂LUdV\TOdb4߈)xu00;Vyd1$産lD=e}G2I". xʶVybp8ߤ9 da5>\9e LVa}yz!D$QP2PJ P[)Z4DD]]޵soݽs- W&@rNPt^&_j(~n9ZϜ9dͫ+.J\E[GR]8W5x[[E"+dRF& G'URFպ|\wzvFXPkQ$$ JVZ|ZG4F@]Q uQ#H u9,B@sNv\T²>7@~NYr5Pj幃'5? v!W]ɥX x3U:_vjcdEH' ij,C6);tsBRwâ]+//z(T+(ITZZ6!GL,/FY7pn|%NNL|~ rcߗ"8\AgÛ8wRE)E;"kggguTcB.s[;_U ?Cӿ=: oa]'"lomg_2T~ iS%{b^Tg2A  zиU?c++"%^%;G!7348(5?:xrz3Onb?ׁd^P|iζ鉈;j9'3upe w(9BDƓkLq L_/ڼ39`jg;*6WHwrs 7 A2FBqKt̅3uq"F7=L,{yjKu^@%! [k.0dYe tDT"kW»f66ٍ5 Psٔpp3 RY6@]lT&{}LgSCV.RVI4. /8i]" `ɫBIזs_S5XHxK94Pct4Ȍ9C!)"Wb, > ]>K &PiM[ZpX/y;XWjeH4o Iv*%mL*$K@Lbph:!w1wqeB TmtO|Wcp7u oDd},,fW !c: Vi8yi]P1ЅӧNhҶ]ǂMl7MsF,M dvu{;-'! ~4N}k`5"C:jc `vo"|VV0~+pkxV6ZEipIq5ksk=#̚s@d.K, d}YݚNsY)KK't\|p/~E1jJ4vFoO`c =5щg*ӹ(,+aYՃ7d +c%uԮEl>G*oYaY;SӠ$"Yߴwo 6V&=R$P}9[trOmbnY0í]`2mlb{smꓲcܓ/4o0 ?Dۻu՗*cb ڔ F_MLYNsJI XjL8{&N>+1#(+3lA*ʊ!CiRl2|sYY_WrAxLg]U5.ZtllL:*vlW279dyby)>%@f+tP%{2μgm &[t5a w~ϹP+`r)',uz1LDp#(*a9<1JJUE"ڮ# '{GVcmL6uӆ̝X888ĹsAnPpxÓX^5u t~7c˱C?cUӿ6}+M o눠%Аϫ~8P3 0+E1G6- O)`Tghy|EU^󊌻XcjX3yLߌj ՉdCL=;N@" IBCe㽨 P*,&*2ڦV -kKS{ b 5g MRj~sYDdw$6ΗhY=^, N  Ș/2hdF?~4)4.77@Q2:([ ˵"sGYS=rrLMM|>\j 2e$+~Ó}:ވ -o^Ύ[Z{ԟ r~fNUW Io >THyw2yg^@;\^ӎc{J{]ᰡi:4uwv1 ͰLPvO4?{(D9wǡrũƶ)Na[6%m3F[XWV-7km?UwLhg21CvW-yUl˽\l2>y`ro,笞w>X3&@QJ=߁)*hCׁޤ=+lJvcѬܧK3MB+5ʽdlDK[غ@՞^lҏẕY}ԝRo]0#!Y]wTۘN.K|!bxs:[mR9 QwK@oHlT&_5¤Gm5T +QEuſAV8؄wFoGt!+W0mo'OM_9Q}ئ{I0V8C$mO?ȧ{>`@?ia{1"# U -OIvQ2Y2^az.*venL5ۈrcԮb~u Sftlxb?d2;d>t F)PjƦMofcpRLRFNZ~յ[BZ ]+|~ޛ*co s+æ{QbւuTp5=8p]ϕ(D8 X]5d$>ꅞqӑkf[|o/{.%گqo ֆ V`!N^SKDx<[${v8m<7 1H#*-'f0XR"8 'S|d&PQ{#RH{II&Ev<}~R9+Q5ch_% : gA D9;]hKOI'Yk@5)yS&[*@]GƉoTq M9ԟxPȴ[}y2&D%UݑDΆ|GBXts\q|1E!fӝtd'U#|JU-1Q;AP/a9Rl,I N:]U[fX,1` *ߋwx1'ZE+M1_1@?(߇׮iJn_5ݯGG)^al3-Ivgh# Y:ErBF@s>6 >bɞ<=XGҹ`dxEsOQc1spE2ܖZVd+;_ 6IMݼX|sdE,! *5Orb^B P =g;B"(d^'OuT_#P"i?iOiJ̤s'NTs}I'Q (C3JR *)* Jp t{w]VH]V6K8uvww38ˮ Nk֑7]!C>Zd@Erxu4j$):ef4$XYJ\&Ɲk*)!8F'_E&{!+E[F;\@)l2y$&H5dA|ũrxtJ RP 05p]6:nrlnߌܷs}:D8&`$gU)ğ]V}_*@nvozaENߓˁlTarnsDp;r" 4uƉ"K9 X,1RX 39t@AhUuMi{Qʲ @El~{9uuЧ0lF Ab&M$K\ [UN.KYwZ JwCTM*.>;Pѥ *%d-q.K>!MfPm~#)Jfb-NFY"sL`o|GhhV]UhsåK/:>^juʅ?FӉSYi?=m_ZSm_g3F>֭.;mb_o Uoe9գrp<b"΄ 4h_WL*saqCHvAQ%\?qL~y[ܸϥ]$(7e=j3Z^]zah~"rqS1*P_4W:dF$PdjHy% B=Hg{PN Mic2)3zA,AЎbU쭼WrmR,^vʣZmUъ^5[#. IfkfԩS1T6$"ɳVon}4Vԝo.o*g 6V~w.Z {_j7C߻:?6q!1';dz =gKeVkW.sa|FLNnV䳫,9D5sssBmbTQK˓SBxP[mQ&,LԼwC$LM↩; z} .:% L)/'+ \Ho'`/&G_ޑO/F[䀎s-6-w81WIT:zT&@W׉#yL,Kp6YjQEV3bE.K.f?(?ra(MD$"ϖ *L}K5 ZM$Μ9>}zi}y*쥟4o58?F#n޼ɥCk{VBx4`դO\,s0BNsJ*VIe\8DZr\&>z"8GYR8ńFcCyn+zVysv:CRtށrdPru6:Ƞ6KEwE! .e4q/ߘ0%WTήq,kf\el!y TvF[,D?ۛThUIPa*JԲ1"Đ?mN5ovT/;h ėQq[4 82N`FhkeEٺE(#ݨ(z}?CJV*#>PdcL~m#XYbQ}L&|f3:u k{X?y{ٰRlnJ6 9izݦM׭Rx+p U' vvvp%\|ϟώvq=::͛7q U֡_>*0L8w\]bLN-Ez]7aOMٱ.Qq-\ŐQZ`o&kv`[)`]ٍwbwUd>\*?|~ݪO,}2Ci8 TïY EF;ŗ] Y;.I~zc6a6@߷gՀNCcu,j0ؔp'V roz}R̙3x衇c… hG*?<<ĭ[pu\zׯ_}aS0XoCٳ.d‚/+^e+Kc)RUJ48)Ĺ\^j B;.L&#@IJu]v2΄q&_NƢ= [[3̏áqn##Ow 2siZ *t-bN&ؼk7dXB -WKұ"f TT34H=o 0oU %A.F%/Cz=;T!X?}ibM[(aN}ڒ Q'9Oۺ%8N \&j/ӻ]/Q՗{"5 Ga}xndڱ*zX`>4Y73C۶y-J`1WU*},'-L﫚 ?5 (~Q?<q rQj|0"_Ϟ= .G۶믿W^y7n@۶Xc2~"f ^I0WRbKFׂ䛧$-J!Q!։g22QOрbV't]YCB\l+5G=x.H=;!v-bh&3lm+q#BQV&D&`yotpg+H HS>gB` NHa@ӛXB!ٹ2kX+>9n`\z=AAݝP;lq )X$E: !r?Y{_C4ٲp!P,DWl3P2(bГ>d2 UbGZ/g qU-^o;בg]#03GҎWOf3QTeVN>I cR1RƉ3Z:'eW;9I糠1ܹākAPX"ie4Y}@5f ͋ΤbaBR$"s \.􎨘'%{c3(T8hzÆ!Jfo.21kjd>gZ T-}W* ȅʟZNGW˜Lg :6Fي8hO{̏g8>[嫌ۋt؂4 -C-I`Bq7 j7oϻɪ`U1|1ǘImlc7n?|pxxXٟ=0+t~?0/͛W3l:` ѬːLdfϛAbS5Ԗ\Q1ȕX3bL&b$vMGcD<ƌ(2'?xFD'\"'BT(!h&jKM}29v1+vkܰ۠PHɺ%Yy!tfN $=IH`lҐ/FjW_u pɍd g;~YghG'36r! 7AMv]#ZX $7!,f,@#PTL!8C(dB8ANnT.p#=?å1qD8}:ٷ#-WS~8`yǸ~:ޥX"cU@뚀7"iku /cUhJ+@9̌GqELDS o?& N>}8887;mq9s:gdm=y8oQFUƽ3!̕ӊ {YvhO]}*<2inbX,*Yq$aGNu#"1ж]V!~?fRXy=}R8P3 үaQqDV ܆PPًs'j9VD+ G-\d1_|l4fmi~qJ0Th`]1r?uRF6s$Rf(ź1)&7I fDi~Rz&EP@B۵?ׯ]I=mGSxB8ױ71 ]=?2ßGO\Պ:9]f3u]MO@n MlO@x'U *U!_3mcxWG}Gq)V 2u~x;ޑbO*PXm;L\)iusp\J|6U\q& Aeu; h]ޓ(8*r9G`G̓9x6K0QdLS: 'WR\#Hx5$7C+DSXKѽm:ma.rS_.=PO۳yݠ 0O{44teEuBb0]fک (?P!dG+])b]QLI)D!>R2R, 8T- "$'8s49ދ >_KXz p`0f?vYԕ9Nǫm4M3 % gjS罓L' SSIϛoC PNuxpwG~G~NlLSmtt{! zVw}9[3gPRUcŭBE$Xn YPWQg)ݞ|R\E,փi kp.cȟ_D@uP=lA}\x"9"b2x$D잔4+eNR ҩ/f`7Lʺ~]q 梒E)Q٭cxJATIH*Jԋ1(|d@KL>,rr= 7CEA䊫I*``wOp9cq=4F2Pr::NNW6#& ȶs*1){`B{ymb~|w?c; aq*7_ n_A8B #!{xxz#[_Og.C1U ⋘fٔlۏSNwojIa?6Ᏹ7! `ã}dG >8::9AO&mlV]ϟ?_۶xL&o2APD%>}BDqExRgX;Y(g Ȩה3]LXڊFѵ!bd؁#)ԔՆv]I>Źب[[~1dߜ`Cd8<@^; LNV!@Yέ\ t'{Co_wRWtWY ._"!U4}%Elжmnџ50N[}M#(͠TȖ$eY]jz}}^J*?]bo]3d,3f.39Ys9BxO d0Ҫ5[!V@yhL@LXW}nbJ7a$\ָ14@rh7p;<Lj=zaA@YR-\npO̊M! xd)+ u54=b1Gx(ûxA g0#=!S!"gOSO1]\iWX3` aݪ؟1fpt*/dp&auſu6%bP_ ;fܺu .\Ⱥ"C2:9mp6akk+[w]K/rD喔=kd8&y pqrLlB]3kW8w"N`B*BAQAA;QSAtkj̑;BCO! vixޖv:ɓ DOWMW YƱKQs]^fc֯dvm2s)?9"BgS?JW:C qIG{;>aUiԎ:ƀAO)D€$RjqvTJ6hH1S\Nk)^1w`Un&O*BҥVf[*bӂmvi<~-l#A-58Mj]`BHſbK6@%|DBv {98wk sUv?#`l?0w'*rP],ΰ$N&U|ٟ1*a(/1k3i5Y 5C GsDEfCMNk1fYt/ev"-L7E"%V!Ds!`0~p]N_b|)pBIK2idȊpH\Bt=mгx +n}oiEP9$.n+xϽWqi_ň6cok33}W !5Gǘϱh]׮y@7G4zH:^Яf`f:ΊU8W>Hl\U٠%aTg5ml'o#/F!`K5M^K81]D}rKf>.RC`JYt2>N[Y)*{Mb<"$W@L >Ao xjӼZ@f ))i!ֽ@ce(bM͜pηt Ml\lz `gvQYeO> \hd@ _ M' 7iVH'!N'uS*ֿ{c|o="m5d,V8"g8K]_=S9k7•=<ry mļh;Μ2,Xʘ~`Jz?r/2ө xUҰss l(dk9s M`ƞXx,j*ekIh;u\vbҖ8d3RzkR s\H[-Z>Xžg]iȺD&XbMf .ߵXk"XϨX8&=)C,@׃CMT!q1Od#q\'EU:e2^>OAWzhC\"h6J8r$Ũ$2;hW$D0+JBb~$|$6qVo Z6`=/[G<|haԴ~O /9qg?s\]l&Pa]- ɟ ~!ap¿qX*қƚ7 ~̰gU80û/O s AЦSWZßw;" [;ƒ ~3/aw?``oūx9}eyy6h83GsF' )"" 0%Q@f4Mb6b2b)PVB}vYo /nzXjVgs&#\bL|6-+*ӑxTi|HMJGRj,c A:%Y3LpHuk{{ ˸ڪ'Mx3)\0j.RBLşPS+?`B5ݦ ,"O J]n9MZhDecuC &"gMgL8ϧ/ t1l3&Iu6vz|&[r(\U5.j3Q60b9c^^A/ > ^/RwUd 19&wq >JzhC?cH }SN&15~l5f`]MNϜo]^E 9CP8 H_G q!;pLG`Cpy \?7G1C`:ڮ<`(p`ZZv I32BIuod abq kq|tm=5fΖD()m #Yž TUy yPl&p-0 7J#)NOralK\y IH 7p4ZP5jfr!څPZ3 '?S5k#>ź/TCɢ HW;d:2 B{sE4`6zO- >_[ \*'汄Kpuµ;nW{s| _}5MF_p|SMc2UYerc~cvCCYwq~g!9ȧ ^$ Q8`JѷrP*WA8 ¹v`4$f Ҕ? -¨LwZ8/\g2"wܢLjxi3O 4Ι{SHp*x"AZLP@kM2?濫=4ylO_'SV?zI#!PBu @ILة)SBʇt0˙ز <W#wm9/$BCS\xx~vqttgs{ۑKQo@:dsJZ*O)3܅4%pAq4F!v2R"C`V2y>d GCu;gS_wYBI¶vXsL(e–%g ؈$^Z[|!x:;%P rsje`<5 ?3˪q^/x6~OMۣj]|sC?lXe<6o&C N{W>cz~ v5x'EXG >ӽׄadkIl냨`P#5Gâ ȇ6d$vLhKfjHhiy`LB yb.z bBW9+))E4vn*FwS^Qi|r4S#@1+MCLhSHr(Y3/U<|lm?p/~ܼzPVf1~ ° iKVƿ)<"1yMqG̹ұ:Eϲ dP6mޟO|͐mн+L[Ch#d漇 VE DYIDAT1 U D%=ţȥhp"x0zFsvˊX6Q!^ oa{wWc26̌ȀC!+ g`0XXlJ2|⿮kƠ'3 ا(ap &idi1[}!<}䯍@.BXSB" ]7Y0b7`2n2c8]%(Nfg:xEbζBN*,WqyL^ϿtpbAvKc2rаW 5,+MG^O{>GKg6Uڶ!ƈ}C:-6\n$fwukX-cȘclOұc;E "/E-Ŋ> kaGO&l@(q'A̛N۩ lNx͸ϻܘ@aA-fnpjkxawpG:=ƚ byPhp$ђN^_=%nrdg_*¾Jګ\WDPJTubLr9 "c:` 77;}Qd rZ|"ȊS\8s6>]:{ ~2wDzT+saC 2?;QjUn5tAxVrH6zP-f O+T'J>U4_r PK'iLm6l6O-}-'ц*&elŒ{qq~<h_.Dơz{bkd@xk=o8::Փ܀b~`f|![e;d%|ߓL'EֱDpMU+J >fM L B:Na('8)g̢ڐRн=9Y8 0W iQjDU!U1<'<-$LN[xq4˜' ]_g66ي0Fa?ܨBFdU}T'-0!tXk6"&$,iJ#Ik6i}S ~ruDn^I8tɻ7^])\ =q6jg18 S "<1&&"oUFm߈%Vhft}Gўs1 +!J\6H3}zbҐGY7}~yGyWw&L%ߘFA;M%2B~%gmIr R(c0/M ŋ@cdO܏.A mLibq*~Wǿb9|ӟF??{ uҹW5'U7S:~L0iBIDA3kN\`}4%9˼ZUYƖTSr/rD9z߀#)0H4i.jz!k%eZX*\\8]U (.bˢ"u9=X,l^I&S# G B#c-!%fm-zW!ApgO9+u%ve(PV\Vj)7%7 nL_-Z@ rv] %Qcb!#AQhs!αm:(% 3"nP)/w3x3_MDfvY)-|#B.l껌 9z܅"\$c)Q RŲW)Nxai#4G6rJ"ag2X$X|oL]G̈́T+23~IҋQ^S-X03=z}gOEWPЊZ}h-#QaIUUUA>RpWS_xuU#e'dO} !|céS 7 0d;$\nz+RNbn+v^X~Ժ;Nv xUf)Hs])d.h^Z=z[2#7 D&P Opfmŏ1+<0yHlP%~ObƐˊ,֦#w@$ DcXC??"'4 -;+' soѻ$Xr=73J ֙a3 G{kxk&h t bn2:][Xfx߳j 50ƔOO2]IdER\u"X K)[lFߺb95!D*$ԅP^lY|g9IB|ʰkֶٰVn{t^z N ̫?4SEbq9kZtOq"?5W",nݽ?(O߇_UXbO~??ӧOBVpV&k17Y+CEAcL1ʑu"jRqmȸa/5X5AhWo @  s9"hcqHCu.]\NN2ϫXnsFY]B >. z 1)A2Pt5`f2izsa!~[Z0kUE9fOf:b0gDA5#/Mi0b1M21bj8}N^~<%ܺjH6qRyTOYwMJ/ ﲍwRIJe!=+뻋UM'?Is?s8{l}HN}h8 j J #VBOnQp0|ǟvo.ط k m.Oh0U ]LL5hOdz޼ilZRJOJ 9bXPS) w!dX*Q\&,CϪ{e.5"&RcwY_x@]?Κf1̘**@...1*>c[?鷰Xє`Ut]ٳg7Ѝ2d&`ӟsXMVoUOAC@@ۓN.=wF&z^k s@kг!6 $CY؁wӠS1kPEU ZSQ㴥hG2 qVu\Q$\'ldX$RB\ Y1jh׿cdy\0O06Z BqN(%@ 9JP8Wo|"fޥ ^8iFo< Z]_P[P"pJ+hL;rX/zm9&_ 1kCnWޤi2ϒ<g-8 wp=RH;c 񂕓萉wىoCZo%c\X$ۯS38)k|a0_ ̟uN7rhతN&,M} \`xbpt|~'yK(mu]n~Ν q8ԇ7WM 6yWuEyeAP%1Dr)x,L#BVʽGC ^w [4n8Ɓ1k3^rݜ?Uʫ$Ce#e'|ңI0Zr*4RL:`niJ cpRYI=`L&@㱿[8w9-ܤxT?{?5yZI< hh#0GG|[o%Δh䚂 }Q.3;  X8Pba #w]^ CP2Ju*/mj R~A+B^Q‡&%iRԦ&"@+5h׵t}7?kTF 2"hIصGq|p NƹY3-f Ks uP<`]444s{A2$*2M']IR Pwn*.lowōചM3˿ .$ъ}^@SNJ86!'E6)c:ɟ-]әCE9 =ؐƆk]<0J[9p,VZ X: )kػv1t:1!n1+U/q!p$F-W,FIds8}1Iabh/ $ϫQJ?_b^E3Ş(Ćv@S*=0$s1@1$ݲ*+2149ї»T+#O:ʯ .^8Z4aT_C -JDa,+` GT)p1PC6 icEuZpO26-lxnfxa6)XȜ}uMfhjU{PrvHir=bTs^ܛM0MrJ8ۛ5:gc0 B01t'37@ sphA+J\Tuj8GEۃgwۈ/Wf6 gIBo[䧨ZH.lj)] Sxk㲬v dڄ{:rJWg%Bk acXu- Ү "igT8gxv]nq`53hNMq6=8G} n+{@u7NG 94l&\dGp#\|=1KLhyg>7˗ѶmUX8&ucu@CD4w(WU `$-;8#(r [W{kXy`"ȁs`IjLA=SIM&!HƫBv")s ;\ZV`%)!s!L_&SfB8[h/w]l0uG834]plCJHρx 6nMPmZ/9\qK!o@S @ '#? 1[-1F|EᄏB{!Q&``ϴ0TWI֭Vm ,476>y.A ^1籟a?m@l Q2ƒ9tsdc\)Wl XF\1k+,uBf ]fe1jCMŘxQ4PQ%D %?(j4ù$cox$9ey<<5Udau*|"u1V5 x'#?w -oӿB{|G&`XYIJ0B\;w'km(E`z'3ϴF"|@8W}a$ GW]Tz ZV_-Mr9'gnB`,P]wpmkk{|Ę8.T>( ߼-at6Cq4Ov8 ,ƩടXMg#W\F;x>`gB8j#N?ĵW?/soW\O"e r%)P" 9vrVr坎+L:l&ΣC[!vL45e*=Ќ&K 7z|5.7766 &VI†ۿ}O⾭W;hTтh!=3/@Xqs3*\SLIkS5#쁦:CX OxcxЅC,⁻N£8%'+18 ::*`irߏ^7@CdM'`ob/m~ޟ `k҂T#(F,sT<+ ĿfU0!5yơe`PU`iԏB󇝦Ia]ʦ$$Zl"ڹB3 y﬷Qj'+jr.03&I6J=74Px^ש^x?t4Ed*"NJT%3xᇱ3k/k ۡlydƨ˔n:ANLX|_Nm,ṟ)l>m<0XPcH8޿UʁMm~7b1zonZ1_.ʨVFSv{7b prLc"#E{h&ZŐ3XM rΥtQx^#J@ꘪSAAKckSʳ4sVTs]Ȝ>K#pA(vtp!59b2ˡn.# jCD@:;w@ : Ӗyd'stٚL'W `6PpbKRr*S|E%YVVh%f2?b p[u \ t;\n?!nFOΩQ:h`\Ŕ由UF:9QxDbQɒ@I ),;#iO<'^=P&KBD!o|"XeCNR#kV!')}h~h?hC ?kiED81s ]?HxLE0u<3|GoM5 b*pqޏ#$OѢIfzvq݅1Zl3S.$ˁSPZFuBؓT]98QaE#GTFF#gC2q^Vw:,#4ΔRJf@qKoJn?@̕bU|+O~s x]<f6 i9F%#"W{y2ވ<ᄵyvtN%pL;{Ny䜬5KnԬpJ EɐW) aiDf˜I$zun5*д> Sՙ_5ZE_!MZ3jhsHEc9PvȉpBC{K?ه_Bhr/| `fo&׾AzD!2 MUo}^YS# #^{][*>QHc=R}C K4a9c3Esfnoj)NᬆPu]f5N8cc- RBF-Za..$,&5J`9-P dfFZY; y _v/Y vl-̚+n~{?㡻`ß|Y',m^mz "ЉUO>zE)"%t v._)5‡H%vQ`wWi{2UiU.tY&b0dOq)Z= 趘fUq{Q7؉=Gi }I5$(/^u$}jFd r@G:<]䩞cFF9̄_^g[2KB{/~Ϟ2fAlpw3!Z !t\ 6U3$&$$>iVKS9,MVO[:%VVr.hDfk 9,ΟGbxp+ Fl)?mObϊ^V 1"TB`HA 1 :KW[{]&1/d|9o&B; T>?ob$)`UcCCh?)qb6lVlC}45RϞ(2z/+.9 \x}.vΗ5Eo=A6mt}8:*5 8$a>Dt2|>^LytM sUO0jdp+.Uq|R^ ǘ\&;looܗΐ wM:C'$ O[8w.l]i "ެ$@~Ʋ? =@1!$n9.8QF(2 ӗI7L0I}jI \aɍfY<洫VX*QO]"JY{n_ߛ{ɠprDSD'$-=Y`xdl$i]G8Dw>ȃ埸8Z@mѩCi` |r (' O0;?d .giWT^hkvCfʯ|1N$^ȎqoЪH2\2R?G[ONKd`St0zw0MIMXV?xT||lq2'EVu] <"DtÍu>3Kch.Lgu01u/K\?ڠ}h.>/G14x!'_SHDwh\BՐu^^r&:TX8f$|> !"X X< tUU P|`+d Piu >B +нD҅Á#O_԰ *JxbaF7hty5B&'p$(ۘ}>7n~_ǹskkrBK*M@_:j֙ ~cĿU$!Pg'1jK^Lo!CgV+Dec<_GS>ƣ;/;Zmikdl5u=%$K`k>vw.N'Y:pTē/(f| |ob}_1#Cj>lbH<.# u. 5aMvp)_>0o_O}z0^ḑΰ1cM "!(F$g7A \۩c̩UJ:yՎ+ZY"I=kd$AW5Eߜ??Im`dt+|cDp1c7S?÷жqxڝ_ڶſ{/>O`:.{EUM:1}* nRȎNHcC4PPyLºhg %OD9⻲Κ;\8=q1kpz}K*IUr_,:vH'%RVpNK5ے|`n2JQI^^kJ< YP|+zk$E +noLw%jt)e^ˇd:D5BCh9He*zaAbBb?t WQǫ"xE [[x{ߋ{2botɡ~#J?A&1*׿1D`徜XFwB0*A~Y-7C|^OmwT#>qSvK۷pxu"Җk6RK;rIdle)FMo 1]Z")FY>bgoeX#v!l}td >CL`ǔhm$ m֫+ [I(BD `?La-E.͙R;9x$ooyߠ]KM!tN\ظ%>O"N`{y 3MOhA?jŭqgl83z?3,DJx³BXMfް dl,Z4'="6^ׁȂJ-f4>S#ꆕu!tYD4X6F ӗqu]& m.pSvKX*yF;)l::f-ݿp_zf^9[?C?ڶE_ >H5%!CuU[ 5c>W=n߾??/&㦭ģćG#f>?VM( \t0"eO˫撥bé4+2,)`eel{G>"Dz74ޝ+Oe֚wBB') u:ZCGIum 鴚lȼJcɸ)(b2dNaH)($~4gl2> !;5}.n`\< bqמZ}Q+OLW#9Ucc"ȗɟ$  F$0⣯Q9$ҥ"C'@16_upm ͌WTNSQ5[gg@u8އ5VahS0@o0DjE (M;&A^\Lxm݅_FQ_x |ȓ|:4BW6]UX0_eh}oo'ٚ9L'T\ĵ=*+K½|z19~FX @lx3< nj@4Óg#^l[a[_G)dPϿ}ROC MGН ^ Qxd!IM*3Kb;9U)?1\ g#z;F, T8> [wu6xKo.`TX|Ţ8 [,7rV?.T%rJ#~8%k;[J$+ 1GX>2UÁϗAy1Aai*c {g/!IvDX%:$-&=a@v@S"/v_:?jCSSc?c|>G4K&_Wƌ6YkUMXTX}yppOxg{:!L<Im%`'J xx+кvsh`]6ei"e=9y* &`;pK^|wv+I"*@Og&E2] ]u1"]Z,Ud&t]( @/נ4^ڐO2x !EhDU $P5X+_ "@R ({@̭VЅ٦o&ȁ >)rv+S^ӹ)', @~r>9\DB%Qh)l #@_gYKei MU18Jj(`;?1Ur D3 |WQA lchlʫjaP(91P 87Ư2!l7n#q, W>z߻TV5?` b I,IxSkMP3U!9#|s7Fa84Tr>In@VG<MIa~̠# HdP%b,h,^̿ASܿ}gХs,:aO|ه;!产ypKІd!.gh萆u! h 6S ru-<{7t%CnE#SZau7U&åF~ޅ![/׿u @3웰p4rusݺ{a*r}ɒ&r|\?RO/v"+,$Bg!Ph}IE̮ IWڈeBů B$ttpS 'gZ1. D9&mDh4*ג>204X+%⢁ P ?b v^\$)8_ ·3+;|} [[[[ɟf}j{N X5寚Wy#tߤ!4SZ~8C 0( d6jN054 pm07f/MtX% w:+Оa̻m*v9U/5@~ mMZg| 4!f9 BmcF̈ƽ&ʚ8rJoR F@]0M D,m&T{W42W|"#F :!W?_c݇S_+p `Ȩ8Q <̗br ̯%,H;zî|[ ŒyI:8]tSCmG&-͞N#TJCv'~ gqPhȨ,rA~Ļ+>ePZ> `%o#c#$ K̴bwA /9}$۬gK1<: i2I ( Qv%!5r!kBÅm& 1Մk᳄&1ް}wNCC׀9[[3y\,95(Ty#!yhhc06ДYƋC,^/}g/vA孖G9@ =_!p ʐ́^L섚2M -" c=-`Xzek?W; E qd4A3bLlԲr$)v ,Hj֒;Ct6'(huA p=(K$`gC d]vw܅s'tsq}~p}ԠN}&U ` XWבV! >ׯ/=yOSskdk_'m\,= 6R},M3\UXQ)g6WxGP&<{[MJ;@.*ÝY {Tct 1'3䁋Ert8y2K[pva0Od`E+]k> 榑x9J>)k6/_ܽ/ _} &jkdg*#5EPCaݧQpH]ӝ"'L%%/t1'(9y_T(1QحZ"a#,"XQec'&B9 qO[9 5>stsxA[f"?X! 17$-鳩GLiqXI WΥr %և?{g^9^2z?{o ah?f3$Mb5'-}Ԥq!^{ <A.tlz8-b`-B;䣱T-_I?I:NKڦ#,>͛}JlIIlT_sk^YB?2k ?a#ɴC?n Tӯ*wJ/{Vp".=p'/)@xN6٭Jťr "95$k|iRpQRKb"K!t]B"yR^E 0~A]&x~|KoKп  ]4\r4ā+%stآ G&{4>(C_ V6&2h8pt4oΉxM=n/>v{i .}{x L|6ʒ&*Xpogu?s<8<<ܸa 4uƀ7>Z%Lvca?E8BC0BKr!1W::'q~}x ^'PM,<)RĢڶڑ.TV10it!,G'NΧ:,f\fB~p 5</\73iH0H3A`,q606s;mĮOz*7^bQrÐsTv}gL(S;TUp7k.@5-,GCT*"T!,(AUy>7FNn~FIa`!O4e+Cz?!7 tu o2 ƀbsxyow<GvoP3I?IX[YSlɅd~{{{?S|Sզ:qx螉uydŐ%X؟O@|3vZ&Xmei_~T%7SƐŔ;0M)3;x |qYz.pYX&z!y[, ;vxĮQDp {lUbϫ\YrB̡ 0Ebmo>$*>! :Z7nx"jn"mEQE3ZW,~C0&]v>G.*N]9 EO@fg1)_=~'Or&95!Ks^6Rȁ0A_E YOE\#lRj$dr&O["?z~uDԃE@ @[ts[?8o[8Ν;;o ]*I:$`D~S_/d_M =sxǽSz?uզ_A6,++JLFuXCc]-#B )=vF6-0 Pdp)IL)盲3 Ynݶ UW$Ϋ9P),kȀ/Kׁhg,Wxdt1 -Ԯz@fDIj G r.RnS1! D3/_b{u +͟\v"`r=0MDIWC, 0tX t tmw,St*$ϢpB!R_ݱF'[͜oMd9dn(QdBdQP(\ ~l)`Goi_ߜ0L#}A ;EiVC.eDbDw+/]ǧ?)|½޻5TOC6] }U>nU<3?cܺuą_Eý&r$qʫ*dj jj^Ý"Ҏm=ChL$!vN?mBDV;.Qܘgđ3AإNJ`9/zSN|L0kP#qTTueΉԲ8G>&NL$Wdb9dtDŽts?4x!~{xf2̎~V]H.\*7!BWwmC&ogt9]%"OHR*NMyQ8%\ J8[}ԕC.;=u_9:n:x}k@0H`Kָ^,f7 h%fy >9Y 1 r⻜E \˼KӮI]ebOY|QB~"UGFt1:ANs, Z*/!>߇mE!2OِbEbD~{F@h[tz_?իW.\F?V7m6Շ "pEl1;/+9̦#-\~0b˫%^95=V 0j?6K~y#c @h ]GZBTFPI| cr}.kЅ(;z$@w7v]>SUu% qB燲/& P2[ >y@udҏ xW`"a%> "AybVD_E|9hj-i\+t'T1A덚 *;wFуGMr\K.,նfIJc0(7wn9&]dԲq,пHTX_V0yeM[*& M1l;F8yK$WDW7I'Pܟ*7@́OD@"pM=}WOի>G}4p )X 򗿌8>>~Å_94N7M|$X!NAx#25\0ԏu:%ߵR;]@؁mavJEݓ\bD.t + Zu972Oc5Eul}>oYB ^щm`LD)#Hp͕Pa! .+"A^|o>w"0pkQ|[pKW掲E?wQF/". wT̋.EGZ}*0i&yd ̨#"0-j@E$!df&ā]gBX8v\e^S'QM 3Fůf\7嵇PZsIMЊpiW(sBB@ ܾk ].>_>\ti%~s0T`OR7)wR\t /'ĕ+W6Z-+?8ôANS@3p:M`Ђeӈ!Ϧ.qZhə{{|Й;B"y05p~&=h\Q/~.i)+JέVr<=_5 H\i'o}1F4ɫPl.R D%9/]̠3h)s ~)9iܔECtO=O<6c<~Y|'|wY<`p&0)F`cMP.avRWҿkwI=Q ײԦhQU^&<3kBW~8O)!ݒ?(O%*rC3 TN(7k @j1)~)7+co]'zO]v4[h9ʤ@2(iwW"6ۧ~\|}1F<쳸z*}Q<8sr+ ǚU<;Wg}vi_xˍl`eކFV]sa /`*6l3Wr?XT/pjw:5~4S.t3R:9zWO"Ny &#@''ӡUo@gP`H}X$)L4 ڶE㽨p\@a/NCX[-XK ྋ1kwssaxD.@< D;dلF52{iKgU0Gk.;xIU)q% TCESh/22ơO9A E I3I+SNAs$Ed"thvo^bfhxU2( (5s[2-7K+’_B%EAy PexMd$ "vG߼K[gģr)Q&}_Ƴ>wxqܹ_5'm6iVi xo~Å Sx8s") 2{? )0L CRU~2L=đhޭΟoM# ?~O/asIeM(˓pR$ӞT`#+_Y`!E5+ T$ -Xӡk5T*cM#kIn VbsN"ۃ1,3J)>db c+ץχ-[n8b"Qi v[XsY>P]xbė9[Zx~̀ХHPr rA GO%!3]ILM98$HؠT!  jsKT?q(-G;_ qIsRgڛD8 I !K@,7Ih=J=5(Ų;`TKd0?эxC71W隣w '|>,{1,Wyb+!``_egPaWQ4-\?pv.WW(IM'| ^;8AO)b 8^,rF:"&9x4i]ڝR#V!d;… '6ɱD`#='D$9mY8jl3t}pK ߗ&@y+?w=p!F〗_ýfZQz9v-,ř4$+⋌P% P:ģ]L&d&WڱC-LQI4$ V0jCCVCD!7Ĉंj*#ؙ2 kZI<_HIo]@h hm9@t(A+@B7@nТի/1Eܒ[nK_z)ƈk#%X^c'$KDH-Y!׀LD\* VF~Xo oui5&kѐ0̋@4) &{/m1߽,x zU0ʄJ}kַsx|A?lNM۷ocww=^~e-BL%>׀Ai(2䖂w6DNJZ~ eTÊ_z?ſ(icX=#LgYjv,Ayv˒Lދ(*N9sѵVs{ mWyB%b6zsYIV %{U}]bqAh^`[DV]';\]^7M>}Kf >b{YE̝&~IU/6`#8xǍ1"r @IW_i- 2fU 辺O(~N) Hu)(sLJ3nc{˃]{N= ^yL7۠+^0t A⯽/_=S3fRXk׮ڵkW{Νýދ M,'m B@۶r \W_}7o 37,Cw-lMoE@+FbU9 s! PPXosRNSO(."pH,D (#M/̨rCsh ~?z,HoEء$(UL%IbŝCx#F$ :mbS:J~~k-OK°;4#oMNH?yR]>('hhbȭpX`>xӧqYLSL&\t .]x S+u68nܸ7n:, ܼy3CBC[ ,D51H0 hE Ɩ%!Ҿ1@+ѯB:7@ΟGsl 3ErcjUc\ًz[G9 #|A_ɶ:ž1\kgsΩsG DI¡ob>/8_ö.Փ)Q $ }}:mfךs?fεs*2'̝;^k15g5Pe#]ܝ)$@j@VXstUبffJT<'`SIÈQ\8⣿/|Q˕ó/ veagIm { p?w"L̓ыW )tLSVs|Tw,y w'7PrcV:,QcV%ʔkWVHUtD_v~Ͻ&z;[D=ن<# pw=@{vh T.ʡSꬂ[@@Npk܇w?^?܋+5wkNiQ8888(4vjsy7ҽu½*=؃#|.g"rзHE'm*~ԉ.r {` xGO:ߌ}JWs&J8Y=-Lmȏ+ExI9,ks6f9/ ^IƙZ r.2P\%gေ }AsdՈ4~]aѼc Z^y@ܐn!G4I dqd-CVcɶ`t@ܤb--{G596$"֧w0@KցDžmOou>]0.z*}+``K ]q|2#Z|O04@(H nݗ_ƃW2}ᭅ1.[{~(Ȑ]]>}G.h*~gq pPUjE{c7}T:D؇dXF;r6 s@RF~1yK#zc 2#BVDT.y)AX.mت,g`J EMŊ~E<}6ݿQPArZ*z1%q%e )d$23Cv j4ͥ;Lt>pHtO(XF*Y $^gн}G!lMDu-Me|(CKCd\V|<$u$HbJ2\cDԋkk$% uvY;N 4|rt=Vf1|w`ݏ[XYGlnl-3ln\_?ǃg?sފ v'H~ok.y_5'GpE~IVݘoɾAv㽧fd?UR_ In>;9_5۟'|T߿`ՆXVNއ .F~syU5ƒZ+RJBr.(HQY1"bUT]C]]blbŝbW!6ߴ]mCK{5.4)3)h (L ׯΛFOl{N{9vvFnNH5hWLB]L} e^@m" T$zraY ;:ye߯!Fuy B@kܢCyI.FlV+3=δ{1ve~{=HQz WϋvА=dD` 6m/= Э:8D\fL'wqk.߇⳿"s/"/d=~uJt)'5&/+S[XRhNԅ?ZA]^$ o(ЂX=V]-12;RdURX1gӨO6Z4H@eB #9ejjs nF^dvi~L3/RhsOm@́?:muw^}׮;?o|M1ҹB߯.r|xҽ'"j!bō&$;svC~OŞa7\`߹e\ 2??} GۘOoy4'wx!UMWlUbjWˆD< $n0 7Et!L:=R 5LjByb NTU٩e΍lBG Z=1Xg\Y 7 '>CVIgZޗJ.o5(gI;0uBڊ6"zn D 02.=ΓCU@(3]7_|gW~}?~`vNw xMOrv/f׎jێ;MoNU+r㛗>joT~v\wLZd_u7_)~/>;>GɺWS!&(T} mt< K>x* }M!vY(!/yoCFia]&WTV@z2IaO. a慂Bgg s0ꃏb<oon|&O:<™)$KC*"1YkQc =UTٕr,$$tb;mB0(מs0 Hi@ઐS{^vkBx^S oC`a?e1<7+<%'V/^ 2ྞӿ.'LJK@ ~ØL+E !AA'3 ;8yU^k9){T`_.蛁Eo?1>؀Rf_wm1rS\@/,+{x.T=R& IDATo1{W_Q_%1>e|3\Q$v5O<;+),X\u[‚UfP„0ioU*tTc rœ3b7ڟiŢ-zV"t2jQ\"~8,GUɬOٿ@Hx|_XJwD9`|) Q&XR)W4W6N຀M@` ۉQ x@~&`V!&+E_{()8;".X(zB̠h-u{eslM ]L }ϳ w ){W|{z>nκ$7b%j M~|C?~>| W7Hx7/jIuGM C!}cvp~7pMw*  A|%V-0Z7(*H+~F,6opf%; ĈUX!"rAɼ)tQ1^Os3[; <$&P1;`ŋm; tE1mN-ӛ4Hs;R)wnojޠ..hBm\^Z$(N<"r)j]{z [@n:R)B:/Pf 5%qfE#Gb#p .6?. C>`u\1qs?S V. Zjd)fP:: uM?i KL'R0  \*ڃ*Ǡ.V QP +6ba4O5sĮ۞H:o#}u}*Y_vePFRb:`wbN۰=e{ zqq70}y03 uF,28,W}j9 Wy\qrS 29_w>wSwq'e&\B&沸zyac:Y]&{DokP+vӛG3k-6aPwi]}G>'Ai xpKo2wIYU[ʜk2v94BiCol;~8gNOC|[zq*qYЁ%W1"*VuB@f)B z.=W 8 > ~\e+A;F(BQkv0M[cP2.TAgM5׾Ҡ /n]U݂b p\c䳿||7v/4r_'3@S~u .a]5|ދw<)J Obٟq>f_-ݛξl:O'ܙ._a*1<(<H^N pnUvJ.ZSF ?B$\qD4qCqwwqwߞ:/y&%-{Ëxvc +)m.y .qD[DU6 [AoUw7z│5(DRE̾٫tdi'4Ѥ{Wta'=L ?@ԟ ^Z^' QNs2F){ ־ D 53x+Prt> yTs1W Bv;+*PIlckK^,uRHNf˄1T4FYb><q+s}-zn}˜!H'4G_~\Jl C.E?  Y\{; IvFQ|`{;T:lu X9NtîC(MK pAq/Ĝ=k2شޱ@ 0~Wq60BD !@nZPDE86^6t޳3D=({0ڀv=z`w_s]Th=w2GG d@`{w!2qߍGE߉[}`{`1DQbtKgg': {+Ӟڽ2PX)*(EB.+Ly AL]ΔRSpV*`.eu8D_?={?VԺYg?x{_Ǖkc{z7xu}44rۻ~4)=m$ƞ]{W-8 :DZ!p!%[<(E)٣(J+'*yu~V"E5c~ ® J4u( >{8~I&1^SI&@OTSLܻ`/vs`eQ]^ & vuk#* :I`6h?VnK1x aH}۝c`'(.](8T\Z18[* j1-v#{{\uꊗn3nۛ 7ȿZ6%Ԁe|#x&?RJjsF<4(-@ۉDUl*,COQFiH~ֺ,Y{۞z3@1Oّ\!$ ~>J vgW <3BG3gY6@3NCEΌJZ:fCrP_/q<]qF=}ۯ [!oOVv&7pUev$(Ztd}2CAߴ FNP˄  dt>, Bp_ + = -CI1i1 ohaW../|$wDifQ j/uUO.AS Nk[{Jy*ѽoz\;֢@ SKAnR}є Och k#pT5Ddi5|/NN5_4.=ѽ:cwM_W_%o~5@4#sDU؈ .v~>4 OsDTj 7!>ڝPp2Ag)[Is*S{)O%ؕMcfH)cSEkB$:W d"w!<50\&l6[7 uB! ec2 nXw5jˀ%j`҆U]O•s" xW>wu@׎k͗~AE]^p€Ԯ"y"?{l0 텪R#@ o=7(sIBTi~;c0J, UR_AǏ|ӯpg\}Kc$M@RI@3 ژe( dbͼt/@* sRw%; B6z)H*o&$(h30Y[Mj 5e;Pk޽;wΝ;X +\=&p>."\{%\_L oDZ2~x~} D1f"Ĩgk0Zt]}GUZgOpTo @H,B\4T K-SȾ/ OPCE+ QyCIyBIɄU.:\B>%kHĵ5 i:<8[ K jQ8l̠RXpBUY5@D1|~]YԊ1|-=rz-=Ğ/EJ HÆ<7_}ttSߠXIQ16_[UVsÿ1Cw?s; Tq1/~W/bHm 2GQȽ˗~OD3^3Ew]pR`׺w {~ ݃o{x-=hwȿ-/z/K8&}n.{j/9Vipvv۷ovVC rl]W'D[%j.)Q=w&%(ɯB'eycxsW; J$`HhART6TA&!nĖ*8kd&ݼְ@wDfvR5dq@2]^=ZH=U8&u@ 㐉 \5Шd!j[pᣣ<] .]bndHNs6C0q,qpx. SnhY΍ܱI)/HΞ\Roh]T)ţkn$u뼬[A"Jy wnϥ6oNW=8S9c/oqgo|W!aBLjs3j@cF8 h ~|4~{Q7q/ܪ` >"Oup.# `ͻ[ynܸ\|.]!aXB4oU)Z4v/׾Z+5޽w'''>Qצ <ƈʹ-*o[y.(O]Tu y{L FgW߇'o]Cŀp4^s'w + v`oU7ozb1 "%nbǨ^=ߠ~#1ɛeC>r2B0bFɚubsyoJ'^N/`}p?ŵ_p870R5ԝBwTxGZVMpP@8/=^Jpn'߅ #/|gԵd w{pwӞfvŭ[0 05{j i/wc o]kG;v>!˿d#3"q 㫏œc~i׊M&ÓG}MNN]K(]B~"E؞HZzqHr&sEJ")1#gwE@1RRMւd\'_9yHC38IHj&x {_V-+ /~W%km$0_48_ xK[=FCAALXG=O1.cM~3)P6 <.2cxu9Pٗfd$nA; @ :>-lNoɷq)_GgH.$Hqy f<-%XipN_p=*} ~~t̀~{ w+{Y辎-z99nMSJ)^4SJ888!VVN{ߣ=1fzz3kl6LӴͰ ߄HIYYM; \Fx&^C'^3/o.~KV'eDKR /^gI:HIb 0ԝPRQ0!6VqS#!R'B'U{\(N7:!i 2myWW=_Mo66\J Woxg~{*N&{Oa{"1=9H=o~Jl I ]\H p IhV^K2o_QmIܻfFsX{J-YaH:?.Y4hoT5 1r'WP/>'x oE#\^!6*[C3.aw uz|un9oBĮ1˾Ule ΁kL㖢1a= 䘒e%Rj3݌7I)aZ8*Ge_)k>wVcRlوBYJDaud/G8D J4iw4Dέ"6\,//nݻ37jSj_W xi{xC i "(|Q3Bi:p^rRfB+/*ъ<-X/LZO%r1sA \_2 fHOyM1 h``00EQlܲAfx\'ݽLןƳQ׷@eB+'^8Â?0hӿ l"⃿;o5 c+Ɵ}'_85b{p1Oh؋PERX@@kDL%xe>W%QYo)Eܩ{Cv({.AhF (a+f̂d.~xLeFSCO: MX=уFO =ᕓ_M_zW85@ ڳ"0HۦxVZ N]&5.Y-yOdUd{.Gw,K"F'v;MSh9y֞6! #`5ip ,jЮ.X@''+;MbGr

Ј^K\Dmrd^" dsCnׄQݙbE#(GG_$?o;v3$|e[SmJm&cyr5~PU)|Σ@\\C~F@`W}mĹ!ϻxE%\+Rn6dgw_t`HEUDKK aAʆak[yC::Bh08Tؖ.,9 jF|ʍ·%[px@/?\,]i4ӹwBqg{2*o$eWaY`-ںV#-ElNޡu/:Ah=QttϦ%"LsFVhO)C] ޜ̌i]_kӚZ.3Ly*t#t N\^" ̗1^=3r蜝 1u<8?q}ĊO1PmU]MoJTiڈYz_ HJcx߃V2D{p>sv$}qo-͕6UͿSƍ3!aHRJI'zHND7gsS;>u}==w'nN K<,CC2k* MrVN֣ 5d qQ!Zon~\[<_/zsI'P!ЭC}M1ty7h `G9 ʚЙ-24 FD^%JΈkȥpO>~k/DpfM1`,4 r~;9 @!$5 Ңvuc  `^Э@R~.lb9آ3m?k@iN [E͈yƆe@Fe`|?8oz{:rpy ALZ I:( 1=t_k9a` Co'wg3y%ۛBFxF.v$ԑm|8N.VYZCb=+s0{^Maxx/{s/|u*cxv¿~*~ )v{w ToHefx\=֔RdMFHtx]-jxMG9` |GnlU/aH eДUC9IׂA`8[5O2RH|b.seYq"!J(ߓ'&prj2 IZ]NJ`QJB&eN̸z1DmUi?x?(Ӻ0,j2© \2Caٍ}*\2yæMW\+wN|;/6kQ+F" Dq`[ 784Ts4Mhu>kG. ͻ #ʥ) bD)?8ֹ`ޮx!&^D8}qɻYj*ȀrQ%N EL*Q ."I>]ɝ-EߚFm H+8G|幊#q0$Д05k:NJBYS}G2Yiߊ\J-,V54rIHd62F=;R9pͰ?'i=nN~ug7bc &\《"ze|wZ߯I˃`9*K "ESJKJ0JL15AQۿiBN$PWp[\\fG1 MP˻<82֛5 H)`b_5t!@m),Eoh{b8+̹ h5d[5ѐP"M{B: U6ҩE;a!!K).M.UTn;1temN k\Y?{LC</!犣k?D4JUm :OsJWxcC4ZxӎN) h?]5Oz^gNݮj~w?ƒ2);+} glo6׾?U/rJbͭ=*;@$a6|'wuT:Ij;*,o)E?:K'ti`Ym;: \өТQV^&9>3K"a.@So h92,ܨW`9*K'z}~ޟ#՝殴5Y4id*h 僁QKF@x4#:jFX.@Hɋ(kUk"BZ^C4(~Q<կϋ;--MHSB P-`aO -[2f+m̵9H CV`ԄIdwNaYݏ7KB m=ĽJT;PU) iѴ o@5T$8BeAUX#0 Ce[ҀRң]BA-)B) 5= ?3g>sZ?q'}k͜ eCa>tϭC h~+YvVe{W"1ps>ƥK+7W2ӗ!6Mwm$]Sv>=Q:tWf+zaо46-,ޑ/kH47Z1|P.g><+ٱu?LNk>8D<7?\~JS־zQ| 5)a+ tA~]Ĩ6S\@8hQ)EWSP[ diyq͘s0>Q"ssHjIonoʱc_I큍o,n!s؍$Tg> 2R4=CnCX'ë0# uxcv|6G[PZAs JRU'iWJТ+K2_Y3ײT8{0Ϯ,t% 8%{lp6{`'R0eG2BARfD]1GWW~obxkxo1pvBBw*F=H磌O[ۤ] Մ5E_? GrPd:aa- l_.}oK;=,`&_:Nni έxs+cx|7WjgNUHI/dÿO[3\?+)"'/~xHN>능!gP>-d!׏}=EޘV$ ?A:9ODCO)ul$mv _] rod$9{1浸iĴ]Z݊-5:Ywsxy:}Yb)JfT0 Ul6N1* 0F1/ӿYp}ѐ]k4;8oH"U )LKbVZQF8R (ƌ ^.,'NbZ*x3w̻nH! XՄ§mP2uOӬ֕˛!ME>Q2-dysɝwJS+AxoS!1\Z 26I6C\<1ʼE^.e߰GW| 3ޓW{?7w+";Ɲ A5x_d{Q 6J5^GDEZR[)#LbCcgG`"ci*mA2e3>A *2r>vF34bb5^?ZS}ڻ&\!SVbGIP+vg5\füt(륲1z$.= >8S|O??tza8ޫ o{ARFӐ6Yv* niл/v yڊyD^2HG=iYMK]^> u X^*H p 煴J CMwn7k%f@)#9-)ι7oJ#Xs5W=Შc p/Wq7q|;x8Ǫ_BoaaGZHKs0oM (6 (U&g͛GX,{IiArֿtB;*nlkfթef kॏ i:jTcb-ϻoSV+"XJ8yJ&WarSx;} +ŅuWQݵϹ&5vZױ[pn/ԈccYIݦxE S~ߏz$u,~S(DSs !Lv%k_g`S"28[ZR z幩BB䊒"20kZ+,p3Ɛm\g4v}^\Rכ"iֱQrrňlgmը%hWY(/~=SA ~}x_S99_rv Ob\o˵M$p;'vl0H ~ÕɹML"Q[@=z7 MlY$bZNMSb"3'Fvdf{M`"iu#¥8LFsF э 2?}o>[x ~g/p>SC ZE.hhGF73kg+ed3]ƿA6]K#VZW Ŀ?1pڱQKkwMBhi;?ZL!&F-i.Ŧ*%Mkއǵ|׭+A}y>BoşQ,̻%d5/8Oz018!Ζכ8x0cJc*ag 3{S`]0 R1IԞ˷MvG@LI.*K2_.U }kT󬫪l' 2nw<߸yBZYi9$-wĴ&E4T㪅 ĤS|\:Q}D^l$E)xp<L[>'/,? w\%&x:[ZnvC"TiE8$P(`=?g Ád Ea{ -z]rݸ/!ژ}0ofu 4:3V~>PX'2IaH} ɩdROvzlJ,"2@V旕\ .[y<_(ε .H+aܞwpot ZSÞO5!|X~ZZIߚ>\,v6ٵi$,?RΦâuRCۃcScDڠڽGՙ-e_ ӮtwWiy%!,_ke7猛7~|+ ߛ^KUI_Jǝtz;n0$Fvik͵! B 8oþ~i ;uUs#bVę|k,Z4`cv,ZŐcpWetE\9}o|n_j:E ~ .m/ݬ^ шoǸb;qjaZM?ozn'uޒOs3¥,j8 QfAv~HdJڽaQemO,ֳR܎p2)[ PDfl~X7x" H'1 MC*l(5ǐO1|sGXcjEޓӲC+)Fu0" Pc uD+hkZq '׺ K_2/Z&JLr)7'!$9P6J! `}v; ڤ]h! eh#Ij욬\ڹOڋNzGNofl % 7_U|~z!\}o~OO ^< zB7gzpDdHJ Ȩ\vo7_΋ i"uvd\ݬ[jP{ E1q&a[ MhO,),uH6ʈ%aQDA4qìZhJH)栐%WG(Pm{_ _K:@N}gO_w>q]->yy,9eaQ2\>X]?$ @J,Y;u~`tܜNY>[#H]AVlwN"@ ]@ti}@ ]1m?VԋE/IIo F*!%ۮGQɌe5Uo/#vƏ[%T}/@Wd},BB&C|n >Ħ]!OiP9_+/-mZ' 7 ?(14isd 9݅;5l~c{9dM$+q֔DFvdBKj`jҎ%<M~za#+Ֆs~km $m׷7?$=MpC" ݄턄tƌeg&1bo8n&AE $0T~q)zT<>8[ϧ_e_& *fcd( Q!?LjC<{sPٞ'vAr^5_Ryh ^ n O6A6řG Z@hf:7k q6*,<* Wa@ \`V.Tn慱b" 6n&{Yjteʥb*ª~=y]8tcKEYsgAi7ś/?p J.k?fLnn4"QZ䂂"lb8 P7u}K`M~R1Yߔps{γUffAg$II?%+p !+;EuR17s~n&ޥ6rLɺgNA B\ r5pC9W EAQt.FhjA8 qm"ƻ/:i#S'jԎ".VnW3:f.>\+-<^4N¦Ns,!ny?EϡanՎ89ޟg\0zp1m6m7jK  3t!VT"8="g.L/y7XoPȷI l:32i|;_ ˟_Ng@ZIɩeɍX;M!,7:g]vHY(QBtyZvZ1&f4>Z᫥X}Ίa9T5.\Ej*L@!Ղ;ZQQWu>|7~O3c% )9 ~,y=p7<DЃ5LҙpuX+{}b;5PF VQ:>Bb^/jƼ9A\KZy La3>Yz/0C3d!'vkٮAa4q'QIԬ 2)=خ6hk֫38=!O&qiZj.pŨ%{n$= dExn !"Íݞ:(~6|_>}y /xe΢–oE_$Mp *oPÀ#<{)..̩y7=il}MR}ӻ?0tN)fַ|rC̣_^4];gSTl)6(0Bd-)O޴ʚ@ fm|=w;T2O:<@JqĔz?.2B.Usl uUϴi6ӌ5 0,W޾c5k8. xyK {4|O}Y%{A9Qk)HZ,km?M=i"]?xIόl8-sv4R ж~5cc;,MS߿S1lY{j 7iʀ.E#5RW:x.^Ԣv1G#@Mcl DS TI3]q9uG:qe>Tƕ:"fBĂUDkuaċtbJkF@`=W jD)\G~im7243%rƔ:tDx4z@De5:gVW)%{FpU\#}YV l$,-0ڵYHO~;Gp: Uw_G{[a3␜SJ ]~+ܔ&9ia<5}.V.7ƻ8*3Vp4H./FgAIpZVҀMxscܮpgJkB RII lHw1F %/QWhq;$쾷ߡRApEU18o5N^5R7+jW8H:@'J-Kؑ#"3'; )kҹ.ufenb;g]wA$ufij:ukC=zuW+A fio$@-C\&U1F T22YHMeAL`<! :(W( Vm-6mj8^̯Si4jLz%, &2W$P\) 2˚'&UˀD 2G 7O!F Ƶ yZٜp)9Ϩ$hm"\ȣ!RfyqT3#;7<'덆]EtBB|MA7EbS|ɯ?sxʡn|GϢq74+qZe^&ͨzD,LSf"PA!h<͸yo.K(䜝Vݔn<;%{;O@ =f3Ȋ@$Z됂+ =Ů29GFY'?C:@ڕN{k`'_<{AUV@&vaX!J63l:aV-`GgIH"eLu2 [sZcJPJn6ȵxJct@^gR~ﱍv]±5x0ϴf^zPephRRHPłz?u&hkIRoV,-fIG"4Ct˧-1eA,vA5W# 3F@ qp?t }X4.͏@${feYdQt6;QȐlyz}5^)%GnjikLehVW=@mRL#H2V#R(LcdZuk=~"Q9ܓ:"u1vh9!I\=CfE)UqfMRn&i f;a4r.w[jT  T sFomMA>5 6eJѰqZC+Ï#[ZŦ zo`C$۰7OIJp(:Cy3c3x՗Q-Vi3Iz1.(=7`aEcFQ ʙ2)n:a|f #ZC3 L.+Nlnm~.b ?2MTS07޵Њ/u혒7ukV ˤa l8E bHr&$Q@'ìEB ~8;DǴ,0s9kbt&2:7@!1!`D]Р趾\V eJ)Rtέ "7v).,z%L} ƨAh1bӫiJt!--kv}=G"etu ]j*5*$?G94hp0/,?CD qW!V\ O%Ƥhi)@W) V@I Didsu AL2-iV@` RʌD0IMtIXЯ u` $̌Uz^c3.ѳJ5ғaSgBݳuݯ υíO[YRs4}!,9.Έn`өnL  }6B;5FzHȄ=KFX=c;p)ÁnRjGvNpCjjr-3kBkXKNW^J10UA.ђ jTJ/˕ )%ѵNz65 \4j)UxVdK;QM[Vn ﲯfֽsh<2Z~:(=@*PH`%U6m]xP<{h_ T݉]xxhDm5`kS]Zs#B(yfE  'S\9ggrF!y}u+*ʃ6i5؊H]ߚ^Rn4}xoʧpcvWkOwGzjh'5کx6&Cr1)ƚTɃA4\g^z/,>qÈi@9 8ɺxt~2 =LUXe mSrx"2}ijz j#yد#26F>ۅ^Dz<1aړD+\g5렱՚TqEWC׽(٧/B)ϟSj]*)nsVcWdu1{1KM ^(+ۻͮ*!=+*:Ğ%⬿1-!m␘HپMWvL޿+eQĠ / ¦oPIhvi%HʰbXvtmJL9P2;o n0+1b|b.z'U x1&.[dÚh E^Kvr(Bj~da*W7U)b~b9@p4uiٸJy0~.)v -U'}0جYE;^aCeZP#_JEne]]5bb#޲Ņ4([1ra*g#N2nNcΧr$,f RE#)Bd{@k~bkޭ:[@4 )T ]+$h9mvhA@"MMqxe,k(C%m IW9ћa'\$ƕEZܤ4?y?n&-h(`7߼bN{Hl)E]S|+Zavx ^Φ+d#>}!ngކSaG09 (9{ls71)O?&r!RvT"'q ̆; SBE3#ݕvPZYvj#m 9^u.umHRsc3<=iv7 Z7霵(S\ sq9YG6gaЇPC$kA{u :jw#BVۍ6f%?uRh"Ts:ݑ&d#W/ǡVqUCif" `5M "V֊B }ut!+@75Z)TC/{f<;o%^Va M˥O%uqQwxƿfitMhZsgB쾰 5ɪs_{oPs'L5@H4<] BS(P*= KU7RC2CKŜtHr:@ e @szZ%/'@iٯc$QL"yF<O? Dk2~VE#UB Y'㸴 c"m+~sț;O$:sC\g!h,~QOlOC8!5甑w_}=ei^y xy~ Flb.dVZ;3(l qMQ]`Tȝ<;`da:"rb5^*+C` ˜df: n]%>'/v m-ܚ\pZ|k/:lC#($irYO,+LY:rlItRl?nnHwPK0ܢʼ=M\Άht6Wh6ͨN׳z!ȺHԬfJAMѦȵe]mذHwLzm"3j"Z;ك=[JnAy1"mfe=OhSEZ SP%JQ<38FlNVB7'8F=Rj)[r}P.ڀT9--!F<#"ECCFqT2pM4K0Չw1Rꫵ\ *fiFՈDW/ʹ ߟ{b H>'ϧj=*RL- 5QmX*jn3u NB[c(58ۭZԒ7b|жڈ*( Mqa"pm\H)f]QA ה32f}ͺ:NF^.Ks&N7k[Q26%MX}:'sg*Z`G7$CU !ET6ϹvQt|??w|uxE֏Á {@}N[Z@Zt]y.Z ` 4E򘀚A1l _K?+8><] >ubqCp]JJ)a݈X i.n$0 by@)bL/f_IQ0S8z0m:֊19hmƸ:CQ+%+95/܋{ŨaCf䜎>6Y0X (fUdXzr;F7WZ("dhT$ S6m勀!Pl9YtG)*Wԋ~&z S=2WAcRL.r"ifii|Ť[MndG&lE# Ʉ:aL۳]o;@MJm?굙b܍\5A-{)Kl:8UpjT|<\*wipm/^a3KS:mE?@S(.qSⶇ1-<7FDw"%;A2J9UP |Zˬ͐ͺi!{`yB2*zRGhsځJ̲<*#avt.۝5%~EuzV>Xu6=6kSV{a8aL<$ZY{g)yF KJ._µkLlia$`2tF?9 6 t W+WyB #Kxݝ3>%D{s*gwAB x/5gWOC=3nn~/T\`KUtCg˿ב`L @l" MP oV}C/]s)y Yp^K)%=-<#Eh 딚W%yQT2͊gZH9ʰ(0-/"ňgFkŶMb\{}soGJ2 Z;(“(%,xQ ߖfJc헁`$ 5 IG(zE-2xTV5@.\dF,ZÐs 5R*YIǂ" bh^%Pe{K;4DƲ $|X ӳ3p8X0(Ӵ]Ϊc0j˗џ xװ΋]BH,;ʹpk>b<%J7U|O:ykr ݼ"vg 7ŷZO~p|0b[*V+>1> /\[G 7ңݿ>zsa|G/_ O`CB0CKTxf tP2ӧ]|Cߘ,'s:k`F   17^zD,Fv^>;3ʐa`6 /#v.`\aZVãAew7l0;x!Dy)%vPK4MƱEe=C+D<.ϓJd,%B[`3JmaQa1qR*f+C"YBP[sj_Y*{sn$U\Ҁ0Dd.~}v,24>o.RzvjDaX5#u=:ϳen[[b`i;#ƄW]|?yY|d 뷨!0Ρ _);ozDjvr3!2b%N*\.T4[ɓPHĂ@i*a c.1s Qߋc_۹ EWWWA A@v7YJD>a8B76>ٿַsIDAT$yilL{& aِúI>tPo^4m1Ox/=ϳ)m]cV!P5@/~[\*ڞKRCZ+N`\T 7M+!`|騥ldg8#y0]›%4wRYZxdr&Ĵ!<9Wmlxp=4@$w؍=C`wULg\iCh^]4 "z>DxXR Gٞ"'o գ?_Ѡ(f<׮އ'_7_^v!_Zfe <lq|6~ᓟ}`3mQyЙMYu΂L8)$_mnY%7ХKkʺ¤? J;d'(Rkzv;921Mj˧PPzgkm-H 3J&{ݫS+)[i~br0Wi*AS?~Ӿ'R>)>Iy d819T0m)W iTb]B$ՅC\xP0Y򹣭:8=D8AI dcՈ+ 2fy$)\+dL.tYZ2b Ԃy^kX0W.`yB3Ry %OS;ے@7Os'O*"w-N6(61zZk*n7 J 2Uɹd[$׊' ǚԜ'YhPJ@!RPQ:V C,0 l* )19ZfoZ6KȤ*M Ej%oAF|A squઇy2薺6ԀGGGXi2!`Øt`dck#o?t72_ _qjydPS\ yj> &a%q3ĈhmuDCDQ'̓(g:O|{zͯ?aԲm 7mPߓ}"鸭7o!!c\>>F}A$cݿ23ZCC $rj$DA"ɢIr?ՠIH\cOOOpHRSJH5ao|brDlZfX(zjWmAKm^=8)m_%䂉'q|K=nҪ$(Ө͒Lh GGG2ٜj`y(ːEV2]sAb]-CIUG89=Q55!<dH uFX.% "־QHzsO`9e 5'i$#$ !E@eF .ggg899inEl6[yW\2j1/Źd @C0g:$!U=#ߏ|U (D) b)vՒR0bJ\7{b5I QeA)Xcm/ʀ gۻw`@TLEW;sV W"DN!s.bvtp2UYTm!<_RNCSɨ+$[`0wčobb."* 4(CaYd% b<7sΨ*W ޮQ\~wn+l [S#L}"tCPUBmi+Я~3W W[<@^Z^ޟ៽ ~G+7q鱏?qMSV/+k^VV'lc.sTsWKm-8?}K>O/ ,{fA\JjmB%#v~1yNz' (8z_q9I302Pƞ002dGKRYh6 bt}Z4I_3XIt;r2ؒTNa}0u雡oL> eǎdz+rfm5t+,<|ӟg~3x0Y#QJAV.$8\Z"i!O#&/EBOļ³6O|aϸ+iNv+)F7_S L' GWq|t%p"SpAM\)+2]0Ʈ4N(575-??|cH 2$%,~5)dw1 V#RڙPp_8$ N `spq/A ݀' +jA=9:3[#;=dE}xKoV9=FGEj8#sFX{l+haܧtk>;͗b yn5 N,VcIPxg@߽V xV-W*B%"v|"{ TA$kXx{`P)]]cE5J5N^(66/AT/e[C$v7D3!T5Q_n|?3SԂ_! Wj}"@9L|vquLˡqHG>5u,=w y _FGN{_ţ#5$Y!F7hHrnd͑4+eB ¥f;ԵzP'\ tzr q&#t2ТĂvʷ.kF W>CǘM='>kXtf]}=4O'sX߽7n I*+ :`3]P]0Qf-ҝf&/M0]7O?o`QvOJʒU"D{#ԫSk-.B`!8˚ :\ͨ9MQ%g7‹4ٲ~ksoȗDbH$ dI&.IYpmGQ;UݪrTED<#Ld"7{{^{{ L"{>g~7䯪Y#0!h^6:Jc+DyluFCqa}aœBx }2p{ A5M<&ӋiF/SwH)@(5=SFZ,+K2{<&=j1Gn)QE,c,^YH}#epgdT@1q&xB#LHdj\t&Gُ=['0lT1%ω*# )b7 JF&Q4Pz5zOS9LYe'HN. G~N Hd߭(V+_Zo*JI}Kt?|Q5 ̹VE&"j*{pP[Ar;kʰV=*jF(Y'.91=} mS?>n&7;÷^54 &Cd;#uAƼN=Y|,J7J6z<LG‹eA7fYԌ ~S8b:ػ_7#,ZDpico}I\>eК@ 9u {_>FMx;pB, I"dE {5mTA(J/^'.&PhN6#v"F!Eyӣl ӱgm;kAQJ]KclyhWQ^$Vj /Szv\GO+w(zH}Ͼo_amc mJ ż-O_lfYHr^4]';)|+` T%i[;\RoK1qeŃgXcXC9RfGeܠke2ϐV1935!b>&U"Q2G׋G})"Y2MպpO]n :q*ص Go(U2!U!ԧDA 9#-JP\,BAtR\eT< sqs8 򏥐ڌ޸4almB(<=(|,L\0jIfk@߫W 2?9]G!3q m k./\lJf`"e}sX͇:"0 //G`gw3fi>7g8z8{헟F];5BU+ \{_SaKl;pׇJV&d߁ /\E-2WHbt.j\$ͬYG),@.qo~/{ ' ռ "@$nZ\z7CFə|ԅXG;ç13!܃[?COy=DJm0 @&-;ӟ鯃ܵ[9*>je $זٳؑ:K BT-PX*C#٬-TCJtkIVɆәZ>( >Nsy}%ҽhDdfڶKMfQ ?s)U8Oރc4iHzgUQ)9~fC*Uw*dI9;=ڐdT6XugLr9?>9Sj1!#|"rD93Cbj7|: Q919WHL!Շ^]1I yT &v 'Nɣ5D˦|8*L-*(Q#\' tϥ+j5Zpo4@LK-eG dŨ{ 4v;oF(lkk}Ej9kԒŖS Wd}^_7[c{< 0|&`0"7`\'ʮN:څx<c?|XZ§zoĮ=un Z P}Җl ґ(UI#璱H .lyoKQ|TbKt ]eL赻2clB+.6m<)( l $Y$AH=9 i'NNdXI^S-le}n<98K{>䀃d%0pJ3$$J|HmUFɵI_f 8 ٤- )/ElN>,#TDKJ;/x4Y<.RnHSpR.h-k>A]d4DZN n !ФВiP !uFĨidGtedJ&GǃPN 1h,7^6ɤ }{>EQϦXٱ_9 yܦ:;WsՀIьS 2|o`+xfcp-%PY[Lr.]yw&i=K$?|7Ilo=e&Zx؃J 9=\l@~X_n}ۏ,..cZLVVSJAٜ-m?W> @N L0s(UIYKck-+xX[IK̰l)!M=Ceζi^]'Nm2t&ཫ+Y w)<-1Åg`E_upP#.\83g"q*H saX`j|\(ӗpu74p,*i:Hw#G%BQr0:nsuEJ^F!jk;A_bvC"1#'Ψ LMYN*b4@:8Y$}dXTyC̑.&AL %y,;ˑ%Kرo&X>?_ۤUXP0^!I!(fҾtF Yxd*x^̒Y%6;{P ` ,=2V*FB AxIn$X_j$R3=!d%dWn: 3w+̧I0u|f˟({TeV(|ϣ^=܏6$ˆ2gVֳx4nn,.,/Oݱg<߉W ^z"3:*n,¹RH6p6B ?ٝdW{ѯaǰg`k :yhS7i{!u~DLT으bq}Iy= pf?˛NY@pqﶅCEX!#LeP'D%DNJM!#2X\?aN/U|4#Vl RRv{(S5+A̚zG>M-G*^XfP, ,+"H!T<L "Q-_a @r0hF>dO&/.z+ܜrCts~(xtfVÒע&R`Q1eeRdz ֯\#`>OΒYJMJYR+]vAg\PΑD\*]-,L^wc>b3ϸᑎqA ,W??FNoq4`၏뽍.@Wc9s,NƌB܃&uǎ?֯03ݻpJ,7C?PȻFRz4X!>>v.;nS7Ƿk6WOrOބ#͋pc/,#i]"/LF9*=`,t qĭb>_ڍ 2{\o}u\1:r =#AǃC2iw]7P!|![Cߨy 5Xk|c O*S9a;Ihܷm#1? =x=;x4n:Wsh7WA1#L9$Cg~%XŰ+ɼ9qJIWm=X !=SJxcN*#Ĝ̵̨v:r&K;Z6:FXhd=&L& M0:&)+"į1E CqRNwIa杗YUM }D.϶Q` QaEBWqF Fe(#"#ѢeR6bF;lC %uJqo]=Y*62uRf:Χ ,bDзk#bסo3;nɷO34e*w-6>*x2\Fh߇ k҈7k!2'D78I1|U]!>zszO8d:;Oɰ1gof}8'V%%%q|e78o '}]{Ïǘ-N__q 36ti,3,I,2@ E_E;};E0]7!I  _JtuƮx Gq~ y|Uu?"JP(8 [G^%B%R̎-/8zϮkgpYBdٙ-H"=י`+\iM `=y>hAV7/hVeI6 ڼ tCŇ:OY֧{e #L.m8.sc'睮i4ic Q:OV2%Ǵ5`Qդ)x)ĤiRΚkG <(:!ֆ2A=Q)DlX" T`V_E(+'Jx\gh@pN;2e?~Ha}=sl;ciiYT]\XTMAR=zףU-gTME}vypI8ƣ}%G`b4YFݞ<;'G;G*[6h.<^ #&ɯ,7EH4&ۙN<[R2@yUX4 5h5^GGN$}9 " ylђ},b AmK W`/7G!MJ0>a678;S/?{bcmJa3,qL2zMV'-W80ߍaIYΈ6O`{| O .[c4ˏayظ0? l *f)kTk @Z܏nzX["AS˸k'4ȅamzk_L&M[XXT1-Qu۽M-YV.F2ڊ1 FOUb Kߧs:DtBH \0Ge(ocB==lir ZNAAB1*""4gs t ˜(* zD' $v7jj(+ QJCbj0f3kpr0TlbQH:b>tQgEeu#.HoW~a"!cImem;dM[4\(^j2H(=ox&A?YK^7doGi@R|J)f\ҺKcAu&\QGzL Mǎ[[3m(|UQ!I0΅DEz1eH){ ޼gz7z+߷(WƋO0^d') di;&<5L܄K(7[7@3(nY$)_\#2H/g&p3)4v;n h7uuӍxeǎÑׁ}$ h<r9 -DL ξ O rJs=n%$WC>n6!Z>KjsȮiy Ȳ Q'!Wy6k@(>o.^Lk!j5 bk\mWqb bhCa+lx+'+H+KNlb_ʕR D46jnRAu")deoNgʖH,HcU;܊H &mD,{BDOpH .Lw hn/Iύ "|H]`|VdNFvgM^45vzT db%n1XcW셵Ly &}q7bC?Džӛ~K'my*㶢\]AqBy8זcȆ"}7ť#8gg.où^J2]L׮`c:ŵ1F^Э]Exb>īo+!NWKC7$Rgrz;ALsX Zcp1et|ԉ>wmgNĎ={ǭlIvtH]P`sښЗ^XyWCoW oiMNJ3Pиq^t"}'R.lf! `!0 \KN^nh?2D>Nn8{b2:jKj-pC$8gL2(!G HT:X\&AygsM+xSd+ODmbUԎ`(gu.22 {,..&3ٜcftKl6|6"KA4KH95'' bN9.dMҲY!|8ai>{}X][|5k*s' T Ο M4{LHxj?4NP+gq?_h1)bf"#Kɑ|ݿ}/]a~^sD؛G=^} _q#qqݴdTBA2h(~)- Kn LZ8ψaz\ۧO᝷ކhF-{%CšD*Xh6.x")'{o'?Z"3;'%¼t)]+eX5Q&\nycYdDDe lΝ>o~;X"@U./w5%߳ςއWUNaReuR 'ԦPCtk A4;6NA  ?׃@ƙ.j;Vv >֛#OEztyg 'pA!*QbzkY ))|~,. s87B㊱,Sf0hZ8q٬a[q?QT%pRʨ2Z6}ޯ{KoޓQm06$vVns{n1\nގ?8/ʠy:' u1#,;=c/ސo e`a5/ccccΏ@.~k~şZX0]>xu{qKoǟ3~q͞EuZ{w/ NI6y/&O! H֙neo}+S;Ph@n$c9, ]1y`O+iy'|xy^l8{tQd>3󦨹Y嬐 epYHi tޛ Q\vs z$mJxDqxeE.d oEk4#!J& M3dr%g.d}m k觛xgǟkǥ7V1$-\эZ39gg{T" *Xחx>*0vZZ#GT|2:lOkBm0YX|6z1rDϧwFl6/3}48 rI%\+Xٹߊ!.^} Y=ٝkqW1j[Đ YôFj!h49'GIDƪ\<}@O(W{<ſ4:x3.+s,z[ރ }P\ +q`FTlQ}af39 /տÛo ] 9&fMKhƘSv56Y'epRX:JsȌ`_ᗿOpm7{C?ه1Jׂ| jFOP|BlK%u/`[3`aQ\|)aw8\.#8F#(؉n60;wmNBSǎo7Obݷqh9r ˘,."DFH IW*&zd2 }"+?+DWnS[ F67CXaf}@:盘_A;17DfWuo i|3/bچz !rC=E!S;ށ>x{hy.gWW""#;+ S2.`cs ^ZD+ Yn?3[k1gxZTQa++LnKD SI2:z&66U|]xZvg.|K+8t0VVЎƘVmn$:IW-sΤ&D ]آ).mNNObl6 e!rX@:vڨ4$AI;*:)85&Z"+8u<]"lo60!mJ@v~r7Vۉ#I"h)̊Vv:l/ U+DhbXA%\&)Bd% gE5r}Jct^b%UQ2b>{g##%T=6ih<q:~_s] DfYW&"!K)$"Q%h$B$>h%SBf\f$%ݼPM ERۑg,K`Cn|AUt@e;PGEEbe/ƥEJ=&ЁgsnݻqbW_%\ǀ!egbkxd$3t\'^"b+q<j`GÍ{>1y1q8z14wgXX.C9 /_GGivKen2t[g,`R蚲;{t9ZыW,9i9R,$nnu]kуq` ή2ڃb%}!w.:"B4{E9<*bHE^k odRz]_)S_Rfo~Xrt]c=;w`Ą'_xǟ{gG@ʳU{m Or BJ%C j|\k5cQ=?Y+Y9&ȘEu ҹ, !k7O8{e8_=g]>SڒV,URlg%Tl\"f*STF7>!V!H/%/hfKx 2ykboyNܱ &G#)..+{kNVoN3G 2` xNEFѤ1SDk̻NIWSG<;RwN'zd*lЗ{Hс匃l*Xx+ DKRQDw0mbss"n8:^ >p(nU>ICЙi]9 oθg&V ^2#GFɻG/v̻Yyyds+CHhت&a!LEFt&yO0 !<&fӫv2n}R@4aPx*"MJT?&>s$8M>8ܹKtfD8uQa}4.~ǮwB3FgW<TvK!C=}H.emtәFN7MFHuyҫo0rQ+ 5!&z1kPKD~%8ny̒Q;LNFw̘f#}H}H=} Tpmqh~s>87=OtC3Jx!O4l)ߎ#@m:I㵓'pYnd o|1]h2X0eC^x/V@c~q \na['mK& %9 /3fNSq Yl.[[5q9z,N>d;p`e7ރ;wb޽صk'-(d#F7ib"h61";^\MОϻx ѴiDɣ/\du]y( Bw' zԎ0Նj=<."0je1KT_mMAo%g Q쏑/#0GtÐZf/<2.o{7ۇ]+XޱSGR};5I)4jN!I 1`S$9:5 1g$w qȹqJO1Ics/G8EJfA:ȥȝd|$ņse#|&g!1}OΌإQ^>+ ,MҡwecxܫoM :>Y<1], (y&6 syw?0V=^xq}'t e+âa!vQBԬr]HkKd% vMDΤ@P:+r <7`}t3w&a8عc.vv,--mr`1c \omFr@vj Nrdy%SziYN1u#Qӂ!Gf~'lynS]X\憘*d;jwMĜ6Kgn {w2._9.E`|5ɝǭ1kycI7<89H2UDivQ"d9Q"DP0UҪ ̉z7#yRc^!JyDMb6hel'~#_Ur!ɻ鳣eURXAdy2jJ],3,=rPp {iLzƩ7ʹU:}Go8]\;]qhɣ 1|^D>xA@٥ $%%=}!=8k,$<ŭo!;U4s"b x)4cs`5hB? oГCvOO% a佌b)1<}xw[3pBxz㄰ A@iuKHq>3$[CΎtNtŞp۟2a]$A)Vo23*>/p#Μ| tf'KSF ?u'@NTL fpثYjpgR d8 o m}=sIY~W! y͛R(&InL=6`l=6.GM όvxMlFV#3(9#!Rt`7F- ̒TS#8glc:s.M d&?Sg@[DH$vMta9M*-Ei TαDo:L5gc$ ƨ;8ߢQ+ޡQ5hnZMhhK;W{ ֧q˗K@ЂϒC9 $'ISu]RxkE/E 6E"!EaU̅jJRcͭ7-E3Zx4<@ؘn$Q`.9[@n |by?:3Cz}lq@q .b6߀kF>DLV%ȡ4w9бe!:g0h15M-;}%!N.CbC 8c+=bfO^[M|*#KFj![@NT9 y:B&4<;@GN"9"7fnBQ/d2dFPmCgʥ2rf2):FI>l9!TN)I/}Bu"Ї$ma3I%oSR1Մ!z:@ԱBrt ZH=@!vyVjJjCh\+š+e=·Flbg{L܋U6W^Fd#:dNPnk3E/{⛓S`FB* g/TSRMq_UNJH#G k.VP# &Uպr&x"te17"w,A68K`P}5 QcN"<]|18 97Fg谎M/b<`a^,/Fjb^")d1Bc߃"9KTČj!9ɦ yqlܨZac>9vqmv|+_on4>ubgѬv"O @SWJ}~NhP)6d#"*zAKXٵ1wt=4W5 yFOedL j4̐ԁ;%1'EA:?!C$?)Z̫6\|ّ9H,DIiؐ5R?hljB F"4Q5d2BAH>D%zŘM\OFX}xJ<rdUjSΔ=s\i`q*G3fpuTe a'H(Gl\u!nߘ%\X).u/Wj3^ZY,~ӱgٹO~ZP3G3N(.с^/i*|7O`DƮ7Vp{ , Sǩχjd R 3 : u ),ҖB/t(Fg-\g8|d]3a T)N8ta 7#0gK1#•Q";m;kFp1qZQŅIbmϒ䰏/gILL+Lj:y )%p"v<#6}KpAM݇q{s!~;)f=EN"dɝd͞>7 "}Lἥ"N:O! l~񮤍Y&>5B,jg"l,ET΁ #re^>_9Y)MBpޚW :0Q;FKl6DGWc:!ȑK<'pfi)j16-:WD%d97/ El@ f  'Q±1)T.ǩh@+{m RR $K*b[p!nn,'Z+xӾ5|*Uetr Dx%|51CˁM?VFܤ`3c/F4[ڿGᡩMz~;wJ [b#Bڰs) l ~V*b{ )Hgy\9̵0iB#fmagB&Ą0.Y" IC"g]=[>g 1;[0*jx}Z3  `7k0砐#w%s2Dbu l,xPoԺ,x'<=܊3oكkߋ>|wqizpc샷Ц` *pǠXtDO4LC 01}6uD[@(kSrY=O.!=ֶ։ bKHcu ;WqL`V9n\HlcI70A`FV;Ց ʹfϖ\d\`=.ŃM&>$9 WqOd>)kR#Gأ 0Ӏ ɀ'3aK[=UƬSD1A|Ӧ?$'DCGA#)@càKN|dsLh&uc(TwըX̰;g .}McyxҬ JI%WM`Qv7 .֠u6{-^s] |b'/x8JЂM﫴E Ju`zћv~$ 7[YҺ b %06 (tYEXB/֢̬N(aI =ܬCOuvR=b'ȷ3R"wzי.9 !锝Ë/{f=n}};ء?>Ϳx3d 2μ'~-uF լt`@If'#@n>$`/qΙ7\ vʆ2a'ht4?=iӈ@x HAD ,3L,u8F_MCbyp-U-2/JJ 2CvjǢ$vӽ8zoHQLȩ33'LW)h#cz s }/eCh"Qe jK\92CdfO,!4( qY/]ŌFF у8aVe]AHS=Bٽ<3nX20h@ѿq# Dgʾ\'A jBo%*sX0f@-;cN+8F{G.>aPWkߎq.$dz :ݨՍ:k5FTqVX_@vyy pNaC!296 -vLYRRDSi;3Nդx}#?X*;cӘcO8krGin`qRTb]׃'DhǴѝxGv4ލ}}p :AZ&V7 J6lv+9y7Ɂ`j—P+mzbZ0ɽ%x( 3sb~ÚNkNnzW */@=6&Q*\r:fg2L.HCb_DIOTap"w059ccY1!E6n ٕ\%Od4ҷt-M ǹ ' )K/9ش֤P1`WV}_:8VsR<# T7EOcU20J"=j3vV쭩lP U'WiE[^msS)Ve`MӚjr1K!=8.O30'#dtG lK$y^+3Z`9WɷI36 g(YZڲW1[ǜok/5ıh@.}Q gB+u1[qmk:<NHʤ<礸1 ]Č0B Kz~g@&h\·bĊppAd:(>q|C~5:[DaQtQ3\Aԃ$[ l/AJhdNyTF+G4 ntӸB?KI!4m~vI<'PL$dQ~)' &R?/(IXOsqKJ,ؘI"RЕ!4OrqKH'UBÄ5%묔+cLyHT 4}/=T069ald\z2@DB 'Q͖#CrPir)pJ05iC_mF#[>u.EzJLppQlg!ҭfds| Arnfu`>Jx@( ith :`OJ3Uvyohʜ[N<LΨ4) (_ʘ$},6hqЛ@2oj|r2l 3-^?./Z]oۇKc94$լLarb;آ?ev*SMj%9dyJUHΑ;.~K fB cf[X=rH5kk'0S.R@ЋԌ ⥟Wρ),9"d;i2⣐,X'p5mA / ϱ&ڥ(féA6>;8n/T(,b p!T́a=<\kWЧ0xnbc":$sAǘL5m2MA: 1У[v93MM}U-L khO4R ?j;Sx!laթQjr-6D&F[_ΙQ){sadP"ګ3"~e~/OܩE4R:1uD  ^Hx җ?7q$O0"!B'B0z|%RVHhۊ 9Њf2r-U0k5R :͓VRdx3^hI*N,#ёr>N,, :a6RHl޵I.7wgpT;dh;乪_Y<[ %UfN8509 jId#g%#e}6yWT*TXڨ$UFX Ud2G)ؠS\T\>OD*j} 8$h \09hQz(V6c[[S;Gk&xnqk%ơ5kY\ef0j XaA u BՒW#ѫV Qּc(c[HW؍qMnt)~*䥰4'bIz=\fd׺fEEA^wKc[Ycd3-_QџA5t נϯѩͦVz"{_uv!|b Qů;HܾN @?BēNVr#-Mrsl,VVnNlVR2Ca/3DIb ,E];i:M!'E}%Q^2s92 f`PfjW LIg t @C2b3fUdPck=9[Yٵ1bòs&llD@bGVc!A; $&mvT6J}.K0B.saj YQ4nSvW%֦'bSQ>}1xɝ*qVqY-M+ݖ0+ods۝+ex[E(<=OejT F^I͙[hI$Q4OP36b>ʅP|Z0/oK1愥OPMq/) 5$YL>Y~T&uZ@Y_ޯ2>4[Cgfl2)-Uh]!z7/.ޓWV̐ui~\"u+ Cd&&A7Q\F'Kb|bi!2H'Y8m]j5B7@.MQW\*M caQӕlOa--ބv!ed` ʲzRDHS0p-f2Ce!ֳ?cPJĆx"ss &| kbPUbvTYsXɐk>9sS@ˡATx:$KPR!i>z@sG8F/\x8èT1ѽzM~`1+QufKd4ҶRrmFrعmh$Ș :lܕ֚g֜op qi @οKm9+>?u%Bߣ s'2)6*wJȅ\U4QI=,\5Sɢj۠rPgws&۵CHՠw]zdBe$Er MC*/#R5[[\llKM=.?NٚƓT7JzaMl@6_OW.NьS+ٞa&ٓij=& \9Gm!Pc_+PX6}j%C^E,0i3Er`g}Hӆ*r:*?8O6wX1JGKƎx%yaޔ\9 z&o!r>+f*rc1B ^Ͱ/UVxPԩ_,g#0dӖKΑlaLJd) m hFٳc)*9C 'V%4^J$r͹[7> }xfjF#~^|h'"FP.%DiٟCSmj/KRӐ .duj| qkZM+~#qAm,p8Dig|jƝjDb_9-3}FYbz $qA$96!K X'a_p/U?[|WdLq ʹP΅(t(#efʁ|\9\{{>}1=*8`߱{羀xyk+{pܣxc*[q#k?Uxo#:03^{iߣ|nGo7opWq۠ŁO3o%D 8:.Z+gXXw4^{_Mv ( O#E/8!9MWk2O(P6k R-/TVÿ_ۯGtXީӸ_,~K9k v'|$aa.EYY_ڇ/ !Nx&4-3DYEUfrt&TS.IrYU t*K+Pd<H5cLl[-]h޴LvS}x"ȵb~n m#TV @=,P[Y5`Tl2_Łډ!9#IÎehN=Bʮ_d -8̛\簧%ݳR&*NE&Y%dMWDXXŠIvFP§kyv/ᶛ/;@ sW{?Ł=X^x.`෾U}0XMGoۧbY^_{3,knX=w~i7>_܃ؿkGǎcpr3gđ+[ v8x#/n=ہ]&=tk[_qmGq n(v^s }fޗ6lm=ޠ׊vk""(r._Wq0C20j\5g³/_,HUw[oxog"T JZUg ,R?2t1pQy"ٕĜr'-a 4cXhҨ,Ghy&;cy2M߳V%C=JGV;څ0P`ˊHm sשS[h@siӉH#Jzp?7<6d81:n4b'X*!((>[<02QW]|5@1nM)lY屦%0Zjy~aB*E+K:0/qL/KyBTtΠDFEm5kgb`kZhr}b/Lpȶss},P>7Q8k^]OPL"KY` ф>Ef S]eIDATAA3aq>-sFMS,x@L}wݎ9Ow݈k Z؍z, 2cG}t=@k9\{p}D}?vxxhGn}wt4Iqs`| hwÞ#qBu["Y#2w>R;lP@m hjC*~;i@•be@W?@ ytr;ol0q~({r ^~`z/"~,@czyvO{Wpx{ &#qKs<أW?0sIe0@sloęB6gl§tgO@&K Q36X}(̶bȆ>g=3e^$;33l0Z 69hQ^=m{UUc5l䉖(TRͼ{`쒡{ߖQnSCGJ AfC[%Wנmsp\=վUeNfe\5eyO9bw;X1QtA k@FQ;-рyM%<Xy|Z>¹U\Sif$іdpx\w{n$bE 37%2$eǛJ 6%ۙkPO2+͙0L ect5cAeB\LC ?cۭCtLDșѢKQ 224lZڈR+J >/; ,<˵ 378-pKD+j9`ϫ}4𮰜b6l.Yߘ5G_m%Mluo) Ǖ~kˋ#D<kx퉿C^ƕc1ܹ{oǿVb6DfYYL9&obm}Kn}{0@ίn.νf;C1nb$\FãOC^zaa"ĴG?{M-/ڴ5 ӷO| ^6cKuRgL5Zā;_ w;B*j٘y{$ 4`:^hpOo@g.~1 %Ms-&$8c* K 1Yo' :t=~䳘LpE?v;g~%\|kg߀-ŭ7ه˫kxp'+I׫G*ÓBdJvY~Fe`g~vmIXQ_z&eҼ)(k (泒 \Zbk;:RxU> m Mg%jk 1kp ̜s CEp5ϦafTTy2\Cl5汾Vb * d6<돠Eb G,^] JltjM^c#+I5v +2U]w5e` PP3MVpOB3^SO4yqz]h'Kr N>{߈y{\“DfXw,^sqW_~|.7؇_s=8kx'*8p]\Aþ±νXt/?(6}uý`e~l^?_zb f~&d_|&LS[Ln 5:vD=y0?_F˻ADІhoV8a;V^f,,T4wCTZe \]7އkV08;wzW9~_Js7ήqģp>sph=&{/G!C#֛ofGM:V&Vx ɃmL OW)Vz3k!QDZfz8Ɓi@ 2`0l2юYЧ6*00fʣ8a6R6v^9 FTԈіg|W~x3h8\]X]I5?K|(ߟl lM'XmWqS9^.L{ƛoO|kjFp~cԧpx3xG+^ 9;z34gN*xpÿ{+xs8sdZvᶇ7.ĻpS9P8n{w wW.1lK;vO"nL/[/x q&ġ~10.n,ZNӉg/Kw_hy#)A+',ݑeaB4l\7jV¸6WZNfH΋ H/07cȽ%y``ݩ@ۭ7FNA|_EؽYM]CxwSon9w.صr{fOaٷġngbIW?p+ٷõn+<"=m?C{p=8~˭Xν}qC_/Cp]8~hN Á[#pƣqZIϿ ۿ_x.ph7nZ&wL2:u8:cm×G6 \[dD32S@B@7OZSix)MɺoFB*2NlC-%$v-ѸR !As;p͞%=j#!=Kp;XDA.XʋB{Zvxx|׌ ȫ3Y=ct*.%&>]Ec;76!T %эvVlh`Vh+60Tm|5k6v5pf cA`5G+mq1`81뗯B Rk mE46χ@0i0jIX90mARKdK!-V=$jς{UrV9?d p$Qs5m}`DUvr|ALZYdy1Fz 8rC ~,MF]Lҿn7= d\{`.?pDZ#XL]olgvp aqiM-1H<(ȅs#{'u( t%hl4 NK\CeX4LH5PkP>j 0pDtn #؎8<Bwؿw7-ceǎJ"܇gvay MlKc{]Xhe?&d!w섛di +ˋ)VK#iXhv ƈK3Y.(. |:ٻgy~S ߢ _LZp(Cw_? ߎ:|FZ4;%שn/1 (l*C]Lߥ[h ^‹/7։gcx#*59uiǞ~ =N&} |ӷQ:,/x0].CL7"*C2N8{C ~Ҟm5l[7E[ՙ1pί]:CT3!!Q5ĦbR\ Kâum vZ!Q1R2r#YR^«0J@^Әb>-k/cz79b@m ְl`e̺+Ff~Zpec oܥ5 1].o{vyuc{8xqCJ v[+x/}|Pbuo*.4 +hvqNO~Z !ĸ csm.v a*ʡz ?}z܃6p'q';0_=o_‘C{qymWOs??Ā'opn=eVk2hҜfl|z YvK0t] h ϯZX 1 Xïe;%%ǘy_jn.kUp|unu6tnqUn'x v2ۻM󯾃o Gس nn/@8px qkgs~?$O{fYhKѓO#xa ?VϾ83O<;~G#0jϾvq>=9 < G['_+o=n8ܕ)N>$|4ZX[εj|RZ9=*&;ǝw~ lWX6hنmCl_TZgm$ކ_}ǸDž|Uv:ӶmINաM{ xIWY2GE\s7z& 8}}YO(7z7vډ+./`vM <ډ!nط}x͓x@Sbݡ#?87^xfϨ:hב[paqy'V/_/=K"=܀,VRk/?<&?k?fJj;rBnu<|(<s7*:C4eR}e˛*|l7,ǬJMQoݼ쿕"7'%Рs..ch?yt~'tW o3s&(̯XX?nZ؇/W}(~rTqG tQGU֎2@ⶻnTk+\~ة OCO);vBO[d[9U3 ~U`k J*~,O>jc֏l&\OQ͡hGO&u)/}- v;W_^}5[:2m~>o^d|1c'ڽ4;΋͔NƶR"#U`u=|FS4[ m*U3;??? >S%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_64x64.png000066400000000000000000000165231403012130000166010ustar00rootroot00000000000000PNG  IHDR@@iqgAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>UIDATxڍk]u{}g8R(zQ,[bGj;tV:-h6Fڦh-(~k6iI`#±,PHć("qg}^w(7R3{k__g~Wy/bP$@ cEQ[8o{SJ21Jߕ&B.{:mf]BP:؞L7m4WS-aX "Hym{o|cRb 5S+(]7yDic||.\gL}ڝƀbcyG{?7[M[ƐmwRdodm1~%(直s{=Q遠AL bPJp=fX$1~N26$ pF%w~۷> :(<+(1( ;2T#ŢR+4E BO rC*پ$! L:{iH " bL~_"IwimoL xaƇqWJaU bϞg5RAҸ~leA0AD0c$ܸ=s8%\(e-$L:a|ZRi]D" )0b߂daUWns+k8C|?zrv`7I h$$ {&+=(I8Y|{nTr//6"kxzk_%O mD pדo!Nb\ޯW?w(b5k0E8t? |q̲= ޹`Ӫ|s(7dJB 8{_)E$llBj_/x*N]ƀ+id7na0zQ8Akͮ1*~nC:5J[O0blLYYDyۅR%'CRUdrk%qRBݤޢ16 ^}bz0HJ%"LbthTۭm{r$)(8q/JrcϫTjhclJ$>-ڭ-<މqj.$&}XW(z TI#J;Geovln>.'Nƍ!3;;!Sva]I(F!) 9&IHkt,n=lM~~!#Rxo cd-&/_W_ʕ+!Aٳ8x _S2[5%*so$%qJY4b`vlIWv墴!MA2T)vd/(8fyeΜ9õkX]]%\ץvr۬olX/ۑ^tj{mEdtAUQ^~5s&l>,.a/A+m"Z/A@lnnayccc Akk`Ja$ZkkJRT׭1'ȭA_㯲2?skpt7`\dJr1-C9g)y^)8&c| ?>}8C9^t:]8ڱFU9;|lX:zc7C)kc}\]x_}_Sso:&q6,sҽyiXDzjyq066Ɠ(asy ?q׿NEOs,/-}k&BNaˎON_?{Fߜ\q{#WdTՈsS.J|/\`{^~;oSLN}7"$Ɛ$Y2α@4#C2SYy}?ɑk7ov;mtQ{ӗ8(6)`$)5lͱ@qHAcE;wf{wy~$!47ѫgj*W,ZPf8hXRVI0a`cqn$p{4bs(bR ҅kQzwy{GQC=>7[ywr @!nڥ-D S@7*J{d)Jtw(E+)yT䔪@ܨt*ǎILbxxzOLtgL] [Zys& CVVVRU.JRd{ݼ3y lCޝTqINEL-{䢈T2RAL8Ð4Cyg7/jVT*\~0 NT@0+˕dFUII8]$0 i=/߁LZ \$FB&fccRY|GSI:BkE3wUqm~:zƵk׹}xĘTfHrYMLT;-Z`O}FW8QHqL"Sj%IT.3%)ݾ,gU"e/SRc"QU!A.^˗yǘ=~qU0ddx(?,}}}q̃PTh6j5&&&frr'|j5:/^ĉgq]GA.)=[423ڀ+gSVj%?_)yx?cǎPٵkn}a|K_W^j!woNa4O>DmY6=ux/DrzVZjl.AaQ6A2Mx$bĉ/|Fbrr}g}c ǎ^Vf}}۷oW_cii(s^VP8ώT;*LɄZ1qA^V+L!^ .^SO=ZyJzF!*`<^z%8@@DXYY{W9u4aaɹ6`)p9%iuOE\R +} ˡ"%Gr9zЭ[3Oq}ky>JZFVRyZkDnˡCxh+++;w߿ERkXPZJ'Apbī YZMAVY0Nqm^|E=88Jf8ql8ݝ8ƍ!fE~YҾxuC$岇A;E]vB ,qq7o+LOO}q]׺h0Z8/q 9ԔH7665õkuK7ONTT^(sA;(m,v7M}&{{˗tx瘜;_hq]77֚$I8t>|i6s m(UEz,VtJL2Lv|P\ <DQaݻwYXX`llG}4Q:$c,'Y/!"FGGT*t:WX[cee% ILclOw]Nr&kI_H(1YrRz: (EF%cP}C6SV<3,..$ Al6iZ4[$Iܓ}L6 F!7ZVGޮoRY%0RtX^^<v{8opܼyV! #hbRe8) bPVcyIJ͙Sm,ߤnK/a2ǛӨAB{nByY]aRUnt'p$vԤW oZ_ѣ۷jV,--iΐR5&,70EfG~Xsnʩ7b[%3A5 ./TPՉlsaS=…]_ù;z9ZV.vDQv:6l6i\tp<qdciTx/W:5~ Ts\8BIѤD v҃ Y& (33DSC~eg8>N:""=)c5>򠃫c$o l)f6iSj\c hjU$LݝEP1.ݜC{EЕ,m7jvYp °' 9TUjjk()H ./<'4A+Z>,eRbz$oe?u# "ESgui/>Bmm*mxW<͂N[[#8N8 ÐV ״[h0m?¦\}rI=mjqkJj-<=͂imA!l-T{ռ^3ާl nT [UZxbr/}j8e7q*FBW-F[L?~kU=>*jl9Zc yKSk $1q$q8K n 3ou*o1tz4#ccGu4/DZ6h6G' 9ktFwG)Nfl8CVXQ%DcWJn:j-dbDDq绘iw:Dqܣ0xaeyh{#kPVRԱ V 79aa"N`dd~jjc1{HRi[I'] y7[\dy׉ЖinRqQdd鸚V*)ZA:8?؃n3$Lh9khK&@MaaqN7Ny~qGFюCswo\du͙7bzj ( bk{Nj؛p\<׵XE:a!*88Ư  )Yٍs I0{>WŸaܹKA9R)NLSx,\%C+g8S3uݠ[* %&_M7DPFJMLI5(h$%C >N Ji]1B A<7G;=|>Ґa6j|7Z|#ORթײ'MVt\zM)I+F!ҏmͱJcWh6XǞ~*D^oJE]DQ{v 8=<^nmߘcZ]n/|[#8a{n _>ř(n*} \q5FbeʂrhG铯3w] ~C9յu\gfmv|Qnm! s< qVwZ $ 1*IЀ_Ei71qL7fR&"D]i6SU}Ϧ}Pʁ$1ADS/冈r|Sm|FL[L}KثW,7 im"dUpLpbj`$o/\SR~䷤LJu=^aG!FMyrpz?8*Dh^&&Q?A]<ϵi*>`>w ZZ)ʈ.P;eQ'zEGQCVLr]>"@ҩx":o~q͟qkkVPJMkJ3Ș 1;iQJ(xΧgf=O }Z75,/& ;֛x#8Yn/SPJ錞%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_72x72.png000066400000000000000000000214551403012130000165770ustar00rootroot00000000000000PNG  IHDRHHUGgAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>"/IDATxڅyeW{sWU*  bchLMeB+-!H!R'HK"::-ujRN#L]y~;a9g钮ޫ{;ko}ǿ-;qVsBqZo{ %;_#yC5; I1IBHjcӔ+7kG |w:}l/zT"H.ZZVeKe 1tE`"]|G87ӿʞӜAx ܸ c@Ϯ?ž=,]/1=3C0||eOUygOb{kم;6.n+Co7Xj fB&( m/tR ͭi67CJ9⚲W^t ֠ǻ?yE"`a.vͻ&cm.il9Zk"h"^/EHT!LhHB(m:w\ʸG{O3?5JBJcrO xsƖxs ֨fJfKy5jQJQ.Uw;=w~ȭB:Mx IB)8ɿ'0^E1RJH9&EvGB\is8dF Ɍ*N !RO[,U'=j:=>?}7sJ! rsz>L5Fx8R'AٛNAV:M(lt2kt~E%m.Hgi6nI5(wÃ#A)=i$'%{g/DJ)m6!B"wJ)g=!O! ayx}<ϼg56VqDDxR\_a}}0)˼2ިl (M h4GT&bJjNt;m(4a<(^g'8R&F[B i= ƹ V801IK%RFcif&FXo@|K*JJ7F*{q8cViaWZlBqN~FffnLMN2kjj5:NaUjJi4 }mKiXqFRT+F*K2Cd1c e40{^:V8 iI":IRjFڵk?%>j>ߟ/t20B!4J *B8ID&<KA(lgmbmBLin.t[[tz=*'Oѣ\p>[oqe>s( Wm?!R)=s6~GiM),֘__Q7j۩ ڜzs0 Y]]h7^ٳ,--tc)&N (17?t8kUU86-"SA .QMi mS5!0Ր.TPl4[67t2?я8}4nݢ$Iuĸ'Np1~7>frByLNwC@ {KT2M+L*F0>m"l6)Y8?Vl69y$oV9IP.`tt!nUN:C/f2@4 ץB3INj&##54>ۥ@m',Sc⍔Ob!! c>IjȶUTbzz],,,033Ҁ%z2ۗ_{A|gtQ鶔>չ]l|rY _D[w㿖ӗv6Ml+)Q1W(E&j l+iyҿSffvRD$z=0D '}<:/%2~/$wAeѻRi ,שOz|G# 7gxSOSI44WJ_NKl%-6P)0?\ƍ|_eb|fe.?NpvE E@$OBy`BJ 'f36[~hx賟q7umRCUzVKyCh]2*n_{r>'gٷ/t +XOV¨,#)ydD2F$^ߢxSO#"7;7jޤSxF p[3oPҿ̙3vk35F}V'?ƍlnn8/#߰F%lK+'Nҽȶˁ+2]k`ZzSkZ,KIP9UZ`dFբ<7nP&;i4|K~]{0VG*IvW93E.ozNFP(A;.ǒDHHܰcp^zҔ+;M67[ ?ME_m:@ȵ oERnKX*RRt15R:+bLZ4Яv tVlf&s4y""$>>Ҙ`%@0f63JGneӫ[W)[GsGR[`rJ(`Ox/ ( 3IAJc8LOGap k`3IC[%33yI@T|Q^>dL uROdGشT+.Z1dmT/&Dic>|X z7|xW6s}S'}{ 6vN SM-Js"Ný4z-0W.q% K_Ƶ۫g9 Hxc4|mndjj'O˯g>"@9?t7N׍CáQJ]kgm7f{5A! ;G{s%aqIZ ~ȹ=\hqt7WE8~(8ob=:/O"(bJTB[+'@W_LAXlB3s"\vO L_!nݺ err 믿Ξ={t]{yffh4)v UE5%Q LhP5.:uCv8U׸x";Bk]HYzZY&&&'_2v V8q;ﺓC)I{!G:iLmHd[Bn:XȗYn(L…=zfG?Q:Q}^G\μ\.Oo~Ǐg*ʼ,,;g0E P qP; zӒ‘T;+.3宗Bvڼ˜?裏}jJ0 }zNV<>ٳgQJY[[ڵkk~I n1GIyQB ;֘νHTqy݊9`$ʼ?y_;Fgeff!S.ezz9i4A`$'?FRDeyygKDZSz*V*{p V'Mr"U`); s!i;*W^ BCj*J^l3I㘱1yzlll2?9t viҖT$Y0,mc$?e ?o9c-D&J9szŌJL^l6Y]YK;z<öȾvR %巬z-RVh I8QJ1 t2Vݻwsf3+;°HB0daa0 ٳgqLbkk7nvm3FgTwZ#J(A J _(/4R "߾uٳg$~rIJIETURlmmQ*NvVI2NUj=T헨,)~>bƍZgv J܆"׬ att_i;9 ˗/g`@&"z~(V;0<hplTK ёe #M۴v(НB1M.ziټ}t(y&fR\?8j)eRo lnn­[XZ^fO a?2Q%nSk7qt֦VVjB]`{Vxae_1D7AE*4fL^|3|+_T*CQ*5-SX[[ciiEZMvw 싎 9ȯjf?{N BUSiHsT8%ϳ>OfIϯTHK=p!0G4jy&'OdzzZţ(t:Z-X[[nJyQ4ICB-ľ/)tUXVJ[LKjfɢ(aSb(&I&I<}^Pfn*Ν^ vbkk`*RgZ*٩-)AT{W)ÕtIg\שFUC$X_]!KHǁu 䁬jfB~#|{qյuz^V)?"0$ C^ѣGY[[g@:dG2foQO__Ҕ+rIYN019 )yץ"L8!DmJn j-|ߣTKfL#MF!Q"⯰ӔRaW4MR:+4֡A 9Y(uRVeY*@g 4HdJ΍1c<_2>1x_33Nbۂކܭ*߹p# :Wn(ҳ|um:8QktLL4%^#$o.SZ~1F J^&\XD~y0 '#<3E{T6+%H"m 6V=^1wbÛafz 'R-94CZH $"g/KiHHsh8(o+ 1O\dsn[;Kmxq55ˉALY3I6]mJ͉O.j^UM>HcZFZ\ *DTh&C+5r>(-Nt^^j蟨nKfEW&cJ%91K42Ek׻YmpGF)0 ͬ#N9•KҪ,ԹzJL\JA@x4JՔ{҉m*8d2?Vɜsnd JWh zDi9M$ kCئ!CJmFAkBOwz~hbqyϓV#ĉ$vI 0 kl4;{y/DQ}?JnyA{ W8uM~C$JG1[Jy“xO`="-Idi80 #63fj"!-?HjuJt&KQ)ΤԪUB?VUX%4IrA?$DY?4 wF:1K/0݆N( c~+˿@ ;0OD*Kxkٷ4{*:JQv8#;zn#*MSV* ?s(=j/$9qzvF]i:U# yi_l=L1$z֥$|d ):|A'\G6+lLB09of*2mu Op;8֍7C1cTFOqm:B@c!6:nr;HҊYOyzG䰇dPAۋf8i5$&˔G8~8KR*%{Oݷ%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_96x96.png000066400000000000000000000334601403012130000166120ustar00rootroot00000000000000PNG  IHDR``w8gAMA a cHRMz&u0`:pQ<bKGD pHYsHHFk>62IDATxڝi%u;~=w1M 2AIMZL(('++YY?dWh_dr(+E8Y Ѝnwj8'ԩSu/8OR;V}x?G~ oQ8J*Ak4ٟ7 9=?{黝O go(ybwEI!h]E GPkNGD~m׼ }Nj4ڝ. ͫ=TFA%hR`07:g"8/ĿcO8F`vøk藾!}(_Z(JI+:] W>67ݟ Vxࣟ C)@*Bi I',-wa*bB(hY/]ڍvit[P.|Vta[ οOu勪,Fhtv}ZYP_Gc8#tٗp2 wE5i9R/>y> ^YJB;U}4i]u=ŭhnPm$lAI|o n?zdJ%H)S\D)G3W/WiWPϹ~7z{t{=VQ7RR7yӳym<(Hk "#HEVcxGF(H@"0&I(P41& C);fZ|9| .5B, IP*!cJaDh!>)~w=3jkFAGCDIX\\|0d:ESnB#]UdшVW%'Z036EHP:ZB$IHBA SVUN?J36S~^L_>*I#%R8(D#B[H,#p33_i.J$QJ҅ITy D%ʱƑa:Wr3TR\T|5F>|B Y9;@| 9b9#R8p{AB-lZx_f4s1{=Ξ=o+W١3NQJ>fnp8}>G]l# 1'#wZ{R(UD% ͖OqllnXfȢZ-ItPD ;'<ѮPOSwh-,pM^x^}U.]]!L&V ?[o[(U3 # 7ZX74U$LBMk#P%c RIN0k HkUr#\$[ѮvhDǜ;w^{K.qMz]gIx"/ Guܖ*d@+e*X9`1&,RWj1Nb <{]|h[}אZq?/]A#klΒ0c+KaUBٮRt]unr1JO>$NVlR(鲊gɠ|KlSd@ dMLKU|;_k,:a-<4^(SAx \XEMyf+ad(d2{#} oV!^ZZ{sLS^>*_{gA'I%Vp i8W )J7N93SۈIzQ IWo!~<|}[^޻t9ii׊{L8Z\.g-[0Y)E^Ghœ$Gb_++<Ӽk>t<|8.Kn!ٌ5c96[ԀY(5Ϣ̉ @%.~OW׎*kkgߦ\sТn!EX?m^TY:{a3\IMeE}IZʕ+.јzooEF׿u^׾u&Z4!tʼ5Vfa ' .mMQXfN}A2ܡw#~O$`0 u;5飓(PS.3Gf R.9.%Stv:o׮]KZ#"Z LÐ_~ k3 Lڳm^sP36ࢳVcm,'i\Q(TYIh2Aoؒ Gs 2*q#Q вX sn?&>_P=ccc"C/q[_ Čn&H,KaR0#"s;QP1'#,7`|/To2a=EW uBVca٨#dc NZ.@g=g!hY fb&~XV@35ϘgePG x<7bj_gaDtj$mJ.fwPa'iOX^^66>T/`ڬdIэp se f{(d3Rе4pDהX7`+-D],qt\H&goHWb7,Jp$hln6h8;M.ΩS~:;;;<y7֟f© 8~̔0S?/kLQ0,w}W M;m˓7 1rfrRfDnzrkld8,AE'\n>s2}&U7X(A:HoיN?v%?kl54A}>[[*N⥗^̙3r-!H˗7яS!BJ٬ÈZ(00[^q'= ׮B2Ir0c}ĜO6:;;;uN `muxY_Xhطo+++4M_%~i.\@E%Nv+s /sB^b?[atdž/[xjfrzn=r#"6b-{ߧ=INx׹t;;;<#?~z*FF۵|~A'Nlvݸ^h(dRVovA [1'S/[ BC+ҁm>w\z=ΜyMFY__7)xaaUٿ?+++Z-*6A9r/}Kj5|O Q`0`oo-}y67̉ nk g#J| 吖9L9 "ĜI[;X,EKً ;IC>/'l\6wO=SxGR^ +++,---|4 &!n=66Ҩh:@1)i%ڿr:Ev~7}v;M\TL2("*O[ךzsαb}}\}߷ܟjjjh4,+ӵ&c2˴Z-˞|믿ٳra ;wKƵZ,EwTS[Ak"3g~:{{{|3JBRZ AX~FO0 >oxDkUS~kMXynF/6 )-L4#qk7A2U[vq"Ν=ǻ^dkkGj5x3L}<+4$It:lSOYZ8z=^/([^,l=c.5%JL% L糲d@8+2>=9LgϽiί|+8q)]y'?3EI0Lx9uZuf= fYͰjp$EDP;I8&JR7nܰNӴZB( BX< CN8h4Vq1*J)k)u;'*$)ݢ5BiWvmE Ep5 #aEDSkڍ tڄ#yeEܼI!9~xa ,LnT4NY\\}677Y^^ԕE= ÈmTG*AmzR:3C|B8Ӆ"`& 5"sL9{[X t1t@ݝ]1 ,,,j:6(=BemȞY\\իxh4""0s =w !T*5cf;eWȬs (҄3I E2M cbE|Pf /Z,( ƶ+ 8IvO?Y6uWN& oZ#,gmuR3usW%hBafê0W*vX%a!Q ш8I۪!Zk( ?˾S\)7.Nt(qH0eP8ɛ.S22kT: OV#_,C:eg W$7ܸ#-0NT*˦Zy3=8fkk5?NDQh4b<l6Sl) / _P3ņ}W!EvВ̢vB*~َ^yLH5C6x4 ]ޔkزjFW].-0 Ncq3>r=j"[M̙٘+h^偈3RIgE.V. @)P9W)FyQlW͡|,NBzR;I埽jMhJV (-F:N9} 4^՝tc]ʭ'nUW Ip_STi:GEjajcKJiN|ҞgBWaLJP0^2q > wы#Gc=V(de ,;l>AW~]D1w}S%)vےXޡN-v}ѶEKʘCO#͵_2 T\` -;1CH+E]^c%g-d-C;4:Vs0&kilk4-:)+4e5}`rzx*oW+\0BԕJB4 [xLeww]6^G#tE [+ @6Ii(UV2͒vWO&BaGxbȑP@HTn,-^Z rveJU5%/Ň[/2N׾d2iZ6 H;]0|^rHc<KlLݷQ?o$A>6 VnP(]j2A'Ō[ QLe ڐ~t$ads=*nK۵Uo_zQ6( б#1 ]X,iSPIʎPڌׅy( ߁--Z;3Gte EЃkU"XdY2K1_x7s-=z+Wh4j@ ; c23rv?+W&+Gb!9AL]-^_,NsW/ cf|L tN߅5t?¶CJ9LKpF4HlLo=17nܰ< W2'2 z^ӣbkaZ%:2ָ6)uT$)R5ԪU?y 2j6f,Hܖ>!d%ҨJBг-s!Ȋ&XcZZ6Src,4㘫W/~5gUR&&sI(imXنE;T\l.%Lm2/df9OL+QB ROsnkgGJFա8mE[mw0BNq.^HHjrlM.G?jNh76lh`*SN gV=GYG`&ԐrXrϐ]L)&S}<=* FԺ$,Ǩ\E ZZmʧor瞣VZ"npE[glTAT N<(0$to}WQ'uDH["*L9QL"&JCF3Y8َi! FtPj$qk=Y2Brz5M}oݽ¹kK\ҿz8g2j9tŀkܶfv͖Sx(u|.pgC f p3<)R0w øP's )fFp J̈́6aD6V"1c @,+PiBPYlr}GiAǝ-KڭT*sծyp $SA؇{-~2V>L3Y5蓨:u4 IʔvZhL'h=3aSwJrn}7&QnObG<ҍgVFY6D-ArHOW4 񈚞l6QXɄvR#ZjG9AxÎ*޾~V I Y7Lt ScA J{EKz/ Ŵz̤] Tb.)=;R>P>]{oPi{>ԩ@|c}N˜M x uuj,/R"=i2~(aA4L{v.+A]ei0!O_7^>G+ DDAS6NLj!Zx ]Dsjr Dt%5[RhXR洆vѨ1q:sl)ebh#di?.d,ཝzi?gzԚ5*i;TR!Ty7z%+gB'ulBz4Z-*me#=A5oLe$N%wa&Gm;O}%:j_'Ț@VZ`'xωncuer !D\A"Մ,CSĂpÞxc?o+ -ӎeRR^R >/ٲbgM*O8)̵3Q_A SϓXl~GNCCNAiOҌV5&"Kws)hT6RDqwmt!gy9e8e9Di~v# 4P{l ^71p2++iϱYFN^KVM`NðD:+S3h4p4"ra"gLxèF$է8:%6$9x䜞Ga5T5"~v>V z7 0ul,PTOpb+dN J3T6_1NGE5L/q"KKiwբ^Q|Z:Ccy*a8'Si6[a^LȚBJm:Ab2@ `80N9*fcDO@6y<-VHOPQ1(͊ɼQCl638A|JK)O{E{&1IX5_bMڞ* l e&٨qo|@t:]abm˼s=eۦ/fK9uǝ(^@c2q稓UpLe3STR{son$2wBZRRP,j }n(&*,-UQ8M fTp6W3 k)E4q&?~eڝml (N?4GAr`%1xժ^eݕ,3NZnO$8f4PըjxNb^~U.]kid2&d2j6h(GoIv/O~>t("F$i3#^(ҷXR=psfjbӥ2j =S ٬/j,64M[LkM^}&_?qm 0J饬/.N(or4HOЀJ/iT~+V|T>wT0y& T=O>o@ Qai?>^P+J/ H;fRxsx-ٛG>8?Al=357uqP0ӷ]~pd[CE&T/PK ; *P(h5ւxH;-;/Y*HRJ~G67wy˜y8m̓(e~8$:F3ByUIKƼ{ <^ $8X ,K7E +i&:IL"*tzΨS'$ Fhs`t0e> Ͻ?IWA.3)5&vǔ1:6 0ITjӮHf !qę+GD*H Jcu aY`!u@6h/~k)$aZEHt8f2DA 8{R,}R9^f06p611!)NEΊ:=--^xRϝ J!H7ZABW,;l ۽INn` <1A@}Nô30S#8l|ig[vm~azUP9-^P-&IevieFE+֏Ͻ$Q؆#LsvFJX^?/7( Vd;3s8+]V< {:Z:l8)d13p<>'ha8e: YXX`4H+^qw?;|+?Y]?sCKv qtiwxϸA0>dT'q404={x>ܙ&Js,Q@~q`~8_(bN+u0DV4j LJsG4W!szk?%VeGj¯ $X>X)T l H.m0RVߎDsf ck;7}L=QhŚET^V" *UAhF!Z !$ɘF֚[{J^|^| !udͳ- [%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/icons/CPU-X_original.png000066400000000000000000023621271403012130000176200ustar00rootroot00000000000000PNG  IHDR""Mw^gAMA a cHRMz&u0`:pQ<bKGDIDATx{m[z1\k}=޾}[V[% lyq%;U)r*UT媤L%qCdcB juݷ㜳k9o|cι{nGպ|9 ɍEmS} 3_ngݼmmxsϑ~6Gq证KnV3wMˉd/YNbkFwwꦼ #ZTߩz{{›\-.1nG:9-!K//fz,^%ZF݊RcgrO;Ir9M} OS̯~7ZV󄻬;V=Kq SN/  c% P C'{8LsE0g#B쮱^g?45@oimC8ڵzn=qvmzzo* >[sё7;?3_^KBwooqfqNJu~>y{,8A?G$촨Ldtǵ^=ϿV fYTDwV'K}Mvm|sjPĿTgSKD@%9$YbUuP9ܴ69ߏ\N\'1}jd*E}sk38>AЭ{'I,oy}=#~!7tḾvugi:`kxI?={EƐٸ>ff}iGcZ@D/`e5(XzÒn5ot>tcyϳ7W7#ik8`Nc>|;ǥuAW.q+HK'O-9hg~t\v!6z}vza-?_@-oOtw>0I0avma!Ix }9 fVyXUhs}l/ߺ~;C6syn>ݜ\G_{&d^E ߍĤιó9=q_>؄{OTt\y=W7DžeOٛ6~<γkJ۞;qo~ r͝ p^N=OxwaZo}KM]mXo%%%KBy tl EQ.:Y.9Γř]9NkI;23COj&\ Szv;"%.Bb&f cyYnArCS#kٽ>g?$Pٺó9e'%mď_Epp*)X' CN>Z.0<ak5G6_=.^O<_/:&ؤj=t'X{ǜOwA Z07lBy oD {p:=J9\oаG8{xqlq*Y~"(5,(-͚sL:gs_9?4uEyXkiѾ[cDDk;q{vzߞ=U]US|TmU_$X]|*TU"59,d%7Lqs &9om'Z >.|?NEsy}!jqx[w=jv2Xwó9!vk{0ȌE" i]gy=sJ4ЪAqK2,>z8<+ xDiG3?չtE3"0juVA{ "G9?u ?7y[V"+2'Wπ뵺DC!,EQ@z4q?p<򃯀3\o[P!߼ṗ{G_77o`/qlw\9ŵBe )N 5Ϥ\O'Éw9HVR ȷߘ_s@Hgĥ!o?ן+;W Y>ピTvw2 &}Q֐Xzd[睼:]!! hw-Ypoׂ[k2I.w%'[0B{XR%HDk(M!#=>ӓy1ZXgGc?|^.K~˿pv 0#.oߍⷼTp=<ΟYa xHEʮ!s 8ɘN8At#(J+Xv?EWنfժQƵWW1BB0˝nxAdmw['|<JK˹UcK)m{OEik<<эjzSMq7>N&k O+*mD [{^=Fp]=da6$-yR ⓼7Ը>c< 5+ kAYa6E}_uR}UM?$'\s 4UǗ>??#/ᕫDC/ ??1}S1<|Ϗx3\o[k >xEu YPqxBfwasob<(b/UJK9a='LD:%eg+h)ƻ”&i'|âbG"8aԮDkQlcUh˩ «jM-:*9yiԸ \` `@F@#XU\Kl::aqGI zLooi_T%_q*6oURX\ۣ9n`Xu)z^u+y΀[zx"ysޫF"Ït>o8&@ Ch]~G!x69]3w/ۍQ׃X8o}he{X8G0Fm ޹"KVF@n.u{\w ʗEza.GG~y|n aΌ1xo)ᓌ0~/mW2vf}]O}p9ׅNΎL˦w{͑$RW8) FMG4Q t$q@A"$R%a'Dcġ ްfk [/Aq.BR5dI3 銀te+erа$×P6o*nk\n DN/љlI͇tn(9)oxϲH-~!j z^vB9F (.U8gм9]XҳJVWL1hc,ǪE68g|07n3H7O9tpvگ&½ۂ8N\/ܛ/$?Z`ۆ4m.@yxBK{uG+h؃∳o>|o={FO=gQ3:_`; ܰONc $ysnIFײ(UXttT<õIM]*E,/*FShMYijca@bh6'ct]Gx qmwdr]tur?x"gP*E *? Tǜp7Юwjt]dSAaâkDyqَݞߗZH*.J+v2Il`|G9^ \&';N mT>uK A@|㝸nOe:y;燤$zdg<"/6h>OMLA\Q#P&\x%~5kw5O.9@#麢~-Zԣ8nf_M.^(oMxy|-.!`?s%ѠY ϥ&H^.^.8 \e|p{=:^?|;Ԭ3y<5kgq GJڞk قe38M )'|ܾA]7{{\θ4WRZb~\%tkQ+2OԊYmEYsB';tAɸKZe fz]uNLIunaw`-SR0LNaL+\PJU:CبP'~&@l¨yirꥶB͐+jh=3mIó9@eVE[%:gp[װ̱uj l4N/Μz^Ωvb+yj}8#߼a"&}ӠrBZCOi{4kVH^kpWbԀي5$ߧE0s OZ(hxGV-xEg_P=/E-bYWq~H$n]f54ǏIaI5. QH8̌Tsf{("ˌcŎ0e. vJmϖ{0Ux+s(+d}w{~ \v }qduDVr) XKmKa Lڵˌщ7+\ưrPrP%M*񛛴UnMmR4oWVI{i in69o6wa^c/`3~)E+yynm uD KԠ}9 %}7\:v;kmS:91NmX;/pkwj؟pԍ hUwy å E,8Syrf+̭n̾] "#2ݺJ} JD@ɏGg;sGzI^y%PE㼂F{EƠq Zp*ZUJ#3YB=oJkԫI#d-ɜdL=l$Fsp nA(ʼU};p31wq33I8;_z֎OJisB@"ݎ/x?)Py."?p">z tDLSVMM FI$ۀ(`ZR1!TˢC 8V1詒~%irPPX ,.ڳͭ^yEӂ XZRp8 1U Yra6'sPѵ܌6#, @ ZTIZu抃Ԥ+w6A3uº"?$஽ܠPkASj R'NJ.w!*;5tRQ\#R-|w2e#|EwhhXSyy|^y? g9QC,q:D?q= pίɸ@MOG0;CxzsdtX u 98I/;"Ư_Z dF>j\y!ltXx.j(_$(+D ڱ!m' Gi2c U@?P#OO79-+\ǟ¯=B O5L_K}~} #>€/Ko'qOhH'|s1F9?kҽB  Sf܉|AB^e߲嵆w|j$'`$gӼ} .(T3 1@e%!Ԯ Պs_aqM}3CrŹoB5U7̲xxJW &m {\`% AV z)TE+;wvq`9V[KdjoWIKq|w5[ oa=#m,T[2~>Nv"H9w dޔ.KUON>/չ0|*s NԊ[ w^ڸԠN炟>`]Un& N[7 8yB!tm>n4n~-?6[U7Nq労W?"t\KBUoxUiG}K^Ȗ>Ź_y)6w{㛗,~]N+.;lm#苦V,'9`q&dV"e5nxu\H;.as Ɨ>|g0KWG8D9^c~c|χ%3?OpA_"_,\-h8i:9R s>DžY"#럿B~%EZC=%tJTj6ܪ Uh-}#)[wX[C:/A#?j:.Xg3RrKg畽*hFu Q̔dmKa/eѩײpK48Ře.sE֛)s [: y9Lov0ZѦ0χ8NUz5)˸JBNMiG +^ӜD-zaWŢP V l,f/㗼"8'<T-_.dH-KR)DujdSc{h}u#ClOkqbĶ%~)*3:PܯQ̸: >ƌ?/W>|އV'|n2_)~!߼t(Ӎ֢[:܋wi0̮m9RrΠxn0^EOgWthpwVqOŠ˒84O tWfF;Fm=UеGЍ.n#jUA&Xfq>}n]]u_HUJQIe6> v KdF>}+sV4'?LmA.NDn$ltp݀wu;Xѣ׳6~vN7N.a75juq1~q iBZ$;_?Vgǟ}D7;7}DwVɋ/np)f`Q#vI$9}lB *`\د\B%x>1-kG .50ϒ`A~Hp\~w=?3zqϟo7c~Wb?ůQ߆ҝo2sF|;/3ȷ=J'BD9^ Oe>OQMB{q73GJwcP[f,~A|߂!~cD%S۲ٔ(5gZQ:rSkUP۰l\t RiAUښ't~5zb j֔51}p=SAcųU` ,\%k_Êgc8vtmCϳV PkA;ZUgI5H'48I +l+< *ΧNv{8].lpV VVP_#<3s@7D $* o'{0%˱It],a4BRZUu=YSreBS|^Qm~ՎEk]\fpTFWz8Y<#54'5hiVàNǸv ~O>>_9.ߏNfxQ<^WzJ5ڇ bi| CUds0IiwzTGڵw"JKұ5%!5?-YDƽH念Ή*Sdr8M;]{?;+ ?/ȇ{q? #~_ag#aJ~~(TyN|| Yq#:LW_@H^1(+e+-޻-JN?6tÛZJ8D.@Aï[FsƭY1("{ܙǑޅ"Y~\R_E&#K#8:ƈllIX#qY` *i%?3^jE8Dw}ٿԟQtN52XUMfh"h.-dbrܴkwj鮳Հˢe.pȪ+)Œ:ؕwLl\%*QaUMaOs4.2sϺ ~,4pf,PFXbfj q% Ԟ8&/; _-u񼞹v-.֝xwz\9i.M˷>K;45.c~& ?1g+Hj+8bhnQj\an=hqr7+~Ξsrͥ#K퐬WI KM=)GMPkѲ~ت,vw/݉3㾚pqu, #~}wWo^gxHB(O6>xR 72ĺXF6Κl<(X5>4{t@z HDf^N&J,Ќ_:J( 8ͦ%#_Rҽ/HVFP,(:B*ʦhb*[Zŵ+bˌ.kW,D}[b\c-D!SNuQnDZx\ %ځj`1w*%j?w8+*hi 4 JV+Bz^CY/F$꯷c/wc'ZZzE`Gc#Yj0~/'jc$"П޲U߀}XȇeC` [Y:rA3tC2ӸsKX.vϋ:0*}*}8 Nً{o>v8krZVr[E#%tzMClCkj*kW xsLFMU Jm4:wVszT2~.㙔SqB5e]*#3B5v Uikܷ& aoF$:/loLnqq@ @x"F%kG8=`|#sf @L{ c$|{r"7Be0|}#@C3>kt(z~Ooy .nx&"\ ղ"ZQ$rxxC/|wn Wqɿ ߼nt0QlYl^c$ۦh0"0JNJ\x6BaJ ժJ}dFB8U.5琦FתnVFÑkꝘ&"^{nUQv.1 ^;9cB՞,IIFŒJpP(5Xnh}ʍ|.2lvCNꮎ>ZT!`l]AB 8p5hQႥ(ɰGx3 ܨfH7n3.A s9hI j %~Y'FTZԻ ׯIqp< %G~o߿Ƿy%ne g- IEEa7)qvmU]O3N/uQq/kyQ D+YݪE= 7w , Q~ pSyӡ^ڽծb: 95;=c6K $k`UL]kwʢ笜:.Q^%(+ϚmUkKRxp_6F艿~ Zm@l*5h1 $y O請pPʅdrYRE3D`Eee:( =rv;2΁!?WS] 9]Oxq@.cа>-l5f\!1)po;K /1'x^]ⵄ iSY_ Ժ.]{n^ I/䦫j5'K2_KE.V J) aan֣׳5~z7Įì>Yk]4iϣ De>Pj4| mrp&h}ׅĥNۨp*0Q0ⱂ< .b,h\;5uW_/닚8 7fl@ cQ5 v4wkhH1W4dD;>N2yl5UYka%_H;of˗#>// ̯?o;01Jd?>?o& VP8 0*B-d[۸Ohp6BhGޤfLX-"eIM9C!oRKWQCPL{@qŷ0_v*8&!(} wnиo+dsx{+WH&Ay%Fyܴs9F݂܆R>`43"=zV##'\Ae'WU,Y^՜u,3l* <[Bo4-q5,e^p@S!_ OxxI`_Jv$>nAS]Iӂd m-U~|qA,p#9Y==N٪f ]eޛĥ'/eG;@[r=gj*Oce0=?  W.`[ÏÝt~=+qgڽo>onGKd{ ?{QEPݻC} |B>p#^è/0`u*Z:+vxv^a$rSh ]T&MO ,;bO(rMMD\9~g_}=T0gϋ#~心K?xeD*},'/%>n2{"g`%ah|DՔI{iߍk9wBB;@yg;"' Z]k5)kq_?7Y'K?J绀 pʌ7n2>҈~/s~zl_9BC<'k\7*qvO( {2p]+:xKIm2w {><- #)k9\;JD8ǚt^<^ N.E[7J\~%lƦi;inaթfhT\^8_'u0䴘|^**U䤓>ys ݯ.9:ek?6(]ب٭d*Sz~\Ĵ#/Zi9z̍_ r U O(eQ"EgBd~}D~6R_k[}NDR&{_;?}8qhO~:D0BŶ=)z[Ѣۜ%A ܨ `\UU`bĹp9؄6A`Z $ M'uCꜨ4^%|}LKfp q#~~?^?>#~#~\d~_8~៊x!BP3R\UuJi{Y{NqȃW>a3$Ԁ[LzڵGg,Y޼~7G8o?CʂNR."p/?x)ڳ&NG ۝q}JIb|w΀v`G 껺rK =S%5TNҮҌ$צ SVƝx-׳6~>ٯ|:^Udz\D9AwuQّ놯fTBݸ*b>v͍ay(Lpxȯ).-Ӯqi6 J "O[Zz:5+{H%1Yw$P;1[w8 D{`+h|4P2'HKCCn'=.hQ :;d*<W@DYa*u:EV_*Cqe>vE@Hw+W_9< _ϴ~Q48~_ /~lWbI V˃a7XSCx*g]{ފϷԛ@MBP!4ފLxȇJVłYvW~#cG @:|ο_'%G~HbԵk@=7e+'CyU (Mwٞ'ʂcTku3ʙ-CI1q!J-^]~npHZJ^}[S4ɣ6~7bz0MWJ"^9m2X 5*X$!Wб흒ӥ 3RpjU@Z]F  `r 1vVk&)ԫuVzXxP6VX"i%!qXt1Uν|^?VoQn qxeE`*xy359bEjr ,FT;mܯ-U7F}K*qWހ%:;XH[ϩ, vm) b}suGa?3EۏTyI=3Й+uuvs/m\:%dU:ثS6 #³%c졖9 +u-#8]\Ư5V2:W댌n޶hAP|o[]Q*U%Uh gW_uI%YRy<7Oש-F{;7-UN&sd~' `Uh rDGpѲ0c}nUm>DB?@, {FڦUW'gbƂm@I!\=Z֭ P ,0~5/#'p\#qWy51 =q-p9Y|<' q1 n 7ֵ ;_bd`_ NK&.Lq׸ATYKuӯ`&ݐRD2JHXqLN tDG?gn;c`ǫKdV$n{\+ /ִk^ܸR3wr@ωs9!;[?ݺ|?~/9c츱ztt%2THKeUe΁ɇiFaq٠ ME{pfKjX?`/:CM^U$^"͈7uՠvw:wsx`zsL!jNem\ [p:t CgF2w<ڿ}3,uCFа"Ly߬XQv d&)= 4B*Z"Tտv>" @J^PƝ}@ʌ\z@qDgIR>{|QF1^l,@v",e=F5:nm!Ҷ؜yQV$YՀ:4LJJ 2$w GEǰ(gd1{#wݱ+,6n\[J/HڇAZrBƱ-X@U=E/" a@ߌ5Lƽlx,9t;g Hj^ hhsc<|ղ@k闍1 ;IYwoPLI^IVS >;u!!Zދ'W jV=JݘteM>;HSn杮VOUK#ׅ3+\~FRGQiD:yqu] Nccp{q{e,Xeh4[\Wy}6^tu¨GB]6CJXzME1EPX5. _ v 6)&ŭ!^cA1 4]Q;?qhYϟA4P@1k^a83ƪ(IqpM.aj|Lއ\QK,Ck'kKq+ӭ< ]F=쵫2ogUTs_|ˊc.`n'qgGMQmX|uMȩC'\oB˗Qǫl2#/GMP-q3q]Ɠ5\__}4o^)e# :VmqIJFy'WF鉃p]oua˾կfC·ۀ !~$ m*]Ǫsdzɰk K9UXV+gRpPb / ㏐ a{ ms-b|(G`]qbottñU_V$ϮoCy 4/hoh]xn_1]uqu@ N=y=Kwj>hr ܦLyFm+$~\-Z &2& BcUs_ri!5IUg]g"n PV}a]W}e(kx}]9 4E4 8Q®p5ȸ* 8VU7̷r jeZs3pB5xwV qԂo}'r $wsNRo 'ϵֆ6<#.Qy8ŪGa\LFo* ,QlJcPK?<¸tn3+RswoXSչɉHr{i-xޕI ZswCGv'p.b*uet@gȰ ȱK|'[$p[WɏWC&RB'hw1s m F6RHEk:6f[T%ܯu(}Ewnv9N` ʈɺUWZbK a..AR+G*5b%v)PpOh-`2a]Ly[v9P?FIA;b=SE .`_^X BN867&!N u#mN oTKS[9.`Z]&v$[`Lhx[vf"7!4bn +F €ǨE ~A}J6=J'?' GRPYeI.=G|^qL*@" ]RS}ݛK'eiIf>T}5܉;*aX(<Βvt01yݩs& g(otc~ %$׮l($7t+(;ykcn||ϝGO.![ YώHҰQ@9^2&S2ثc%K₅L/0 Xa~ScSQGmM#QЍ>o?+1-MKi􅹡,kV4sW$̌3Fsxu~ — ra'Bp$ou @N}m1AUq%;a},,/JIL'Kn2 YPkY{uN]$4'#Wgy4Jܒ ͥTzn@I+xX-.Ih-׺( puQvn^uld]ƮM]4O~. ^{2"9/|w/0C@py9#2!8)'0RJ9gL"B%e0a8ap~~a#q{ܔ#aD` !uR ,C oÀa@eBgcQt͘rBjt!ؿEL׷PxC @cw88"qxÜƳ=[)`#grݙ3dJp QSJ,9PJA")#q.x, 0 " TZQFeN .S5" 4 fԚI(ϧn҉>D|b!cYuRF;J%kZ:YI~gBC6BC:_볯cTCD.q! QogdbctrM +D"@ 1gaIc Q3@<@g18*Ռ q "qe #(n,RJ1c< 5s&v#”ePnK(Cİ;w67P`D {<Ϙ H |@W8ߟ:ԡ|Ti8Z|+p$ԪzU-pnj:ePz)_SW8w|L)Z\ t.}"F7-1: `tqV2 @)&9/A/9![j}5 HXϤ3۬~0Q*8f\5fo.]^"sQBnZL#VFhWҚt3hHo|?]~÷ɦGu}C፴wlΌo >ˆ/1O髿x^Auh#4-IRkynFdU^Z|[[{fy3f^pURVmMoXЈ]+I1ɜ,$'UI%c9 ǞHP]f Q94a3tLd8ȧ)Q3h\t ۡie1:0Z=qablƯ)M4˒W.Xl~V\RO5\v}JU3IcG渉 TL3Lso&]t;o;)բu5HY|c_]B5y'RB9oJqL=j<|ܺ"rkCCtBޭP 🧖)(WD&ӄx_E˸Y= 2&eq.WpF8{^<7C%_,'r0. d4Y*uW4{K6:%TIs:(W)[%$JcT$/Ȋ-i&5j7 z;e y^Ff.Wb%3L!z>NAŸ_fk,!oFmTqGxQM`)a}gu ۤr[M9<@_:wY%|:\l  >so$ൟOPWoK~n-B kЋe[;ؐ=^)C+t(yTs"0[k_W̰*O]CѶX)B,RʼndU("ׅY&ZTy9hWY"Ss=6.:8|ƒa3n󙰝0Esb1 A!*$ZU(B'>ڲVIZjkL$ " H*!U?S" #R@ԼB-(4xN$xi+5b aF)B˕AQE?"4'!d1X,8bU|JMzeQjnOhˠU|.8DVSI()& I_Q1) tf -# k(RqhDŽ0lMTz\v%J;eԮ ,&qw;@%V+쌸-3TeQ\+R$nJMI="Ǫ&c&ץ㴈J,_Pg`^8rFAAbĎ`d5f=Ou͑"蘄@H{!iNa5PV'NP dx !\}N+2*1k 'Q qgHu1兘k|w YngwsW~ ÿ˗9G u ??7q/~ v(8p6iԲj=$j($gZQ`ixCĕ?D=PBRחh-XI4^+yr5ˤ`Гwj ]A iU Uh-~Fu;O[uV~d=*x^R^tu#0=iv$A[ B  %IJ_C^z]#Kuٙ5 >htaHFYgu]z(ܱ%6OdE쐢$dTMהPz89u3s-!B ?Px ,6F=%+e!mܞm*Cѹ 3| y5x>[z#*8bKe@xy Ĵ)rLXl/T3SΒ;2R~ɺxu$L7&f 1M_5ìδ G,Y /xQ vl^GY]'n}dpxgcuoP.>vמHml1iRWC/%R뵶$b;A#[%N%#l-BQ5(g#yi|~%\~׿|;cb|Wi~o!=xa)Xa|SQ=7`sĽҰhsμ[}]k\@䩻YMkI>y˜йA/*IM"YLTܔd_! M<5F Ou(ZfDZ,տu@mJlsxulZXBT -[ʀ#+a, J.YxShP΢6hb8D`Y*Pt Ì4c6H%a3ԠH6[WZ4 D׊<Ln 5'q;H!߁hvUa ec] $+9IhHҵUq/$J)ٵD$r4+4 ӈ ~t頓pp\]5(dؼ,]GiE%KK DUݡ7kTMf)Tq(`dзQ'f1yҰJ›PS+faپkśZmEE0Nr=wqG.kqn2i.@ޗ}Ž|*t pH^Z(..(q3yjEΛY ]B' r8iUkSh]E3[i9%p%+MPdLnb.Zs-P_6h#\j\Tka VqԨhKKmu~{ҢKG=2:x4ms-8"?k]70·8#;A m& #cP[R[PU%6̕ЂjEWK"2 #*W81I:Hw̢WtF vgyKA:InϽY ~y擘"FU⽹l'P*’# Ny,Thlɳtq*SUUIx4wGfwxǣ36L2qyoMm Ƿ8UebB>SiiIKh@ypD> NU=u)R@(WTFSu*^|:h\/8W&T{2OA1uݪu _-x7\^ j4tfm?j=j {h}z}=˜ACFH^k(BCK:< kŰosbyO9tLDBKV8&(ȸ="r= 9@1CAg2@t33J.F%_3x 2B 4Q$3-Є sJ@`!#KPj{ޕf Q ؁0R՗ u@ĔU]+UբLT9=ჄPFJ@2&I9z>+1P`.h@R;*[PXN@=Fm~YW2$";#ZsujwYL1DrcDs@&f:b#,XgCjI2d͠k?w'h&Y18#JXp «h k-Dr ]%Y9aW"Tbh`;$rۡ`PTMsaXz2#XdM:gYHYV#"a@H$2^d A=wSWO#l_w?¬5I],\hDsRD'+' ONw$ T&FjO7*W,EE;4cU:mz jcVh$f@NvFڍ3QC,MR*`ԓ|e|Xu8EEC5J}Q4wr|pp5(-2{̷Mr"LRuU/};ϓZq蓠Ψzcy3@(a!5gOok|B-wɇ%L ÿ\fvU' (^u++tx/ -VA$*&]oeQyU&pS[U`d  cmrN]'Zvw8`H(ҎHȠm.4k{dB < T4b9Lq\՞Y*LEQbdU)u 5Iդr)k <&EK`GC+bhHȌ=U{-iF$|ƃ 9c ѼDB/|eR5QTrΈQR BʗQOi>B|=?ĉ)[*IRJ(gS# գ~р Y&,tœUNUg1FCIdKqYafܖ!DSy +Atdn.& k`A%APTlG(;À9)߅9"P/̌bV3QmbΦUJg9hM d enݣjp1# ͯHl<"Tf PXÐ6ø7! #"1)p3#$ 0nf Hgg-G]EǷV] Us3#=݀2.NPjtL=D8sfׁhDjLy[Z|`Rj Aɚ9*?~n>Q*u^@w=C ԝUź2e}jcr-mP#6{Z WY5;rEwz3jhЬ-' QDlbl٘x̊wTlŮ&3Gf*Eġx&ȝO[TU07'D0ysZ;*sVOfV\fz97QL2Ui~aN* ^*~@*?~?WM:=mwCx?>"]'-͵srxU Ru+c5j0; MV 0Y43*[(yx3cҝPA ΄Hy`~FGChr~!Ex;A{;j{]Xyq9>Z4;7wU*g3F딒B$Ԉݪ4U n5ڨrRF&&mz51t+R0V:۹ | dJnC؏sv-Tr52szp+4'qDGDѨDj'Sspa=8 rҠy(.X#d\ #룯pPMvrƞyl:RSpʱl*lB&P3r5ȩ'<0Ji{<mX)ylvGZb632W2Co[wYTƼ;sKr՗)L Ӣ͇ŕt M=OpT w! M c3z4J&yFv?P=X-nMc5 a%4ZF ZYrNH64NwE5YUO'ZQK%3zxقʞUCOp}u5SX,ΏfJt*`̸&SjOҊDVaj@"5I —Wq5{HP'.H}̦Td)ռ:SSG3TۄB'Ut=GJ#3h\ !б"+f  :^i@vTPA5*捂q1&28.tMMx+rIMYx69*tJqB XzSX&[tԄ2oWWj%}( q;T8\Y4JG ߼X+űqadv:^aT9 >Cx_XT+ξ7>݄E % U3 vqar8TÜ:gqx%&ι.KU\m qf#;nO <Z:gZS .uI5cvNjw͗ +haK/6@q5~PM3dp\Cǡ@ܽYu9(^)`Ͻ8\K@\`R+) D]| pcFr!,A9X{o3M;\ڦqLr'vb]bw1֊$\3e >O¥ 寄seВS]Vn)L>EBJɎ.koI WnQp|Q<eg&Cj93#J y|N^SvJbN`]Wkڵh bVAHTIDAT!*LyFƵ]㒊p| {$ҹ5JvW#V Qy;c.>YV)':9N[Hit }Q\;sa9o%s{)m-\SmQY&x!1R:6 D|`cꈜ*ถ.]~ˆ+;,~eՒqю2ɐo[[3,q曑]1 X"uƼ$,Tۑ\(;vF]+ًJFq.&9 4{LJÙBgЈHT) Vlt#ҝ 8h wvܽy "H?˦cխ\^ݮK^xTu@DF54DKQ!NUIʛ=Z0H%*ܸ"_xWWWV[,!aTV&J)ȿyF$¾\!`L)gLӄ/` 'FJ 1bOMfW&X3ڡ@G"@iu|ǥ*( <1X>+p9xgZc ͚ X$_rsh#Ȕ5w>#5dE(oڠݐ#nAsxG]RxkGӵ3WRoZgUB.Narn13fnHA\U;?4M:'[TIr% xnV5A`T,0(9M%$]Wg+򽜅R2HWx Kb@QX:ԬМ0g,U(B %lT:v*Mڹ(a{3Hc;_2? .T.gsy>ƽK9&;λ1܌gˢ;-gNډ\gǝ7jߣ6O͇ɐ ܟZ!.I4(KTcCOVCdz hSs=nű? aw! ٬,I[(V~. n {U*:\`hmtgTdkֆ:zQw~ma ZtVnu Yr"[/͎R=FJ9 R22u&!&I%i5M%e*9xSٵ">TlС1A~ Hj$ (RкAMLʨ1vDтT"y a*#cG0Й\k0GQx4j$<7FH\##`g&"p;PR€|rfxM4@*Vjn sbGILv;\__[3k Q8+ħkGDakg#BI|0Xei ,J#V[Q3ZT B"wB.;3ϊQHTjڂJD "@PȐ A+)% er\.Ax5`Gu%@vFd=]Z y.4QR\ , p  sO)a ~u%- |A3f\FQ/, Dp@+2TԶ1b$1"0(w18At!n')JPQb#8ukYuR0M0v#ͭ#5 !$/, W~(D$xs*SJ&)!޵@bD) B0jǦB\sxJ-F̃)&q'80Ml\w$Xi9 kE:xْ ¢wn|"K:qrjPYA< R!pnRpȢ#`%M(iƅspn1z}E9?0 c=o@q)[ ΎG{ˆzp̘\0<(8&kW@ ͊\ɇ֎d8c>OF%0H՘x /׿joC%N UQR̘ O*;) ДҖcD%`>kq t#!߈AY"C< LɪM% #޳! nbXG)MS`(")A Y3q7vw=(8N3;}y?>px (Ѻbq< qgk4k3$0"փ+p!߹Zsb ƢKF&fn35Ze4~13#vx7:^}UYG㈳|C8@"K=xps믾nggw.o\~y13Q̋~/ 0bN'L8DZtp@ݛOQ HGrP5 4q]ZLj^2=&vׯL71u-a z<ㆆ7({UZaF% r:Wtz (u.KH`Q[kh/qY8ͱaxzalݟP LA>Fq/]r p^+p7q9//߃}/\{{>Ƌ%Q4Y3nh d5,}?q̣͌7'V_Ax;jUœVRuR:tpanCj RJ8w,DBɦiHv=db}"t<q<x<*s...VTTb6ϲM,lAܸ9|;x4#@6x`s~ tMhU o3"v Lm#Al#,_ZOBD8 th}Z.e׊O)Iy~I!={yG:a5fv1F5Q Un /;5h-pnR!|(d^2ĚpF#H#kV)ϵ&"8Zw&c7؟qԹ¥)"yb@GghIIo-@quun o0 66`&P0 )JI:% (?y4M8;;kO)agyWwЯCN׀^_Œt7qGV$08ha$t+B9!S.?u-ƈ2nnnp~~5n٤IŅq;XqoJy:~pVזc_.ںP >=q-qI$*T̘G B0SqصnZBYwd~]]_`< NwRKk cl `u=nkdfQuKŸA1e-`w6J&YM+|-(dBf;zM 9#;kg>{f|K__ n_^CZfu4_[S (;~70kbF )x{Q,T}.MBƧy<\P!%inTU',M$UR0<[r ^ZA8_xnCAڐ:!jȮAY܉I?<\R 8V%c5bRVdq.qB$ Zt/WY+D{c/9T4!HR8"?D. 倏pя| w{ރh2I2/.@M]QL$^1(|Cyloj94K'a=_"LIHf0KuҚ;F _&d{(ZX7$in{ag.1 Nx54m=\Uf3랺ۘ5kiUfX vYe"SF9c?1H޽5X>*HPᅷI Q(a"NaODS[bnEAC4(ZDdrSȹ "8I0J n|u*L=X$=GKkg%g5 wulq%VĤ^NvIrk 7ݫjUxTy0I׭taRL$"P8 IqhvԔvjv&J0DZre'=$ k7o>0qz|1#;x3;%A|=pE`q3MAǰB:KEfqgwcݗ@,| ")=.t_~҄-no7n;15%\}_B4% =,;!+?dLҺoQ%tXo L Z!8NuqjΡM[R U^ɦ4T4{uj T`x+8":Zg'L 7חh,Ȇډ ˂vվn+-nP/ѻiy(&dq/Aah CE2>|_؇?_߅ox֙,܊iXLAVT R¬r*̸ |'c"0Em(M͂СS!(]͝7J\uA<7[r 8U_U(8R/tЛIu{u#q Lnjy%iu<|fgVT[!< 2{1֤.54 :_œJXy[o^,h[ UZyMmt!qʑ#1;MmHO!uVK*"yq8.Vɮ^ B8\nw "# ޔ2I^ 2kjP-5qg RwC(`~k}0P;5NA^':L 8`IOV)!S !9*&`|KǬfi,a6scLES~l1 ^( -3n'|'L߹vsCܭdĝ8AH(aq<^=d]8\-Bnȑ1X @0O(a1x QoW?_+/| #9[ ԂaU/“ک:CQ'Wz01%:ru55^w*2G8 A):Nr],*}j<EIA织д!PB~c//GML=jC+fW|JT_X$E mtlXwOoqQ$z3/Lל?C|W}7_U?sƔ45{~9gk; ڮʕp`Yv*@P?*(HHreਮ^˱ۜ{dNZ6mAt6 Z@^ ,vZ#6R B.1LƃH{QQrJRufT [H(8S* t]A:ӄˀ}7Iq Qgl(V2u΃HXBs SR9L+Dpe5Q={fBKXj{FCDj$Р],O$Ud[L=H$>w-*X 1&lE8}3!QGQlR2@SP4O5.F$?_4ו$s8]z)t,[b<\v+"~N]($e{z' zCq5eZ!3{AH&^kpRAG"°[t|;DD .CL2W8si0OBAϑZpuܹg86OqĻ D"<,)&Kyx.tD޸ =b:o23)k/kPJ++w9τ8:r:@K\U^+ y}ai;ѩr糂+U$Cs_ +BB#BhA(rl4JD>P'T"U`"c'`ґKv~w'߻t[}+xU?׫[M=LL`gwK7o~7Wxw y+4KDNA`V<9a3!P&Pb*Z:d*AI7qVS02ø2' A _fpl\]us 0BW|nJ+UUwL=hHb{[~_ÇbKxcF~<υi&`I<͘ 39ƨȹ3xՂVV"` =0dCqX\|\"H(GBଁҐJA1@2fGqRˀg.N* ])"J,.de߫ w œm6Y2 p*R- H*G;ߣPAIo`r Ao *\ #pB֜RL#+ԃP%atpr7W U$ H{-t{4E]ׂ KRvD_ Ԍ޴ |4i+d/ni;3$Uvo2:bD \0%ynT^@IHaJ0! n rлHr>Q4!tVc qV$q+q yFLR]ﺐop6[8"!`$&*(R\!x9#zb ;*|GI0rJ@ (͕9!!Y58%Hj$@H*ݰGNtJߓ|>f8:lZvS*(%8 Ǜ7Jkҟ2eFsPrXEЧiqS>Z"fuB0Q0:DxqQ2{ -ySI󨐱Yo d)*}mj7uf52Mץ Dl'8# A`ƝvgH! b@=wC2Ɓ ˻S#{q8ʫȯ}~Ǿ_?p_GE6W%h+ʸ#&3\ C3^)x*+D, Z6epLY,T_\8+c#qT]'Nv$&bN wY Wxgb]qE̍S:#0: y M% LgI5٭?E_$^)CB 1 _oƿC???}̃xr> ܓ8 < E*E 0He2FL9c F a@)` -TyVlε$`$!iR q@ T$. dbbaUX+Q"@;X52ϒΌjLWa= bPT`<#XFQJb`3 ȂQ zVJ1' ISQ bǢ1V+@wGqR@%#93ϩ|sqx_;uFrJ"5 ȽtPS(J {(ɔ_HOY4?gTߚd8ؔJA(b0V MA0 q@ݨ DużG ;XqNډ0|de&X@)&q\TV<{FG0DY)D]~&!8#,@( bXxƔYr.Gy휵sU0ƈ(6.̳t8$ cn)gt%Ih ]k01H@^Vh8-O)aӏu$Y3e-N8(y8VQ.Rd**AJB $}Y Iv$b S*HԺYP *S2B^EQ) b*:;IXm 8!&\=RΖd11*ςX֌tTq8D@G!%Ĝ1.%Q `@T 1It1Y;sҔÈQ;MӜeX$w! HjN]ED|~Ԛ I1;U侮0S(z(.e 9'䒰QR4_79vM/g$Ft\GqkW7Fqsgmyfε^\ 6HIQ5%zHe[8Jĩ⧼*)ǩ$qXqP EJIHDלs4y:~ .gZs9_ww G86% {>Q|?_gn _C8;Le)(ld>b&`Tl;uл\6/۪C9e'uJitzș  w.F':T$:-dɕ6!!&rѣUfɘcWBD{4KN\pNT6}k> M;ExH*!T>x8PEC&9ȟQ$ -+Lx-E)ga]OfȦq<^[8<` !s-׌$0^;qplȲ!Nyp5F6l(*OH> 6#Āu͈ec iؖ@oȵ8j#Ja]5'c@iK81>8˔>S|MS|=,'ͮwwd(Q*OjBGGpꑷ\ 5V +\ T@M ҤLl}Pp8`Yl)U@d$2sDZ?Ig[(<] EڨMmLJ :< JhK/4w !S=; [2. à V5@gS[E'P*\0M^{5\]]!פk_eò9+ _)FB(:bc\ajbvt<#ɚR.Z<&\yu88}q8̼#")S҆iȅК)NLM(ڙ4X &m?PhѡXoϹ1]i洞)1xDܢT|n6VQ2ןsgب\jߛ{tSe5E+!j l_[II565iܨ FUj-lXS((_~mQ.QvݮE䂜'$ozRJAE\O]]/vbPa^)hEYns[ř?#LwW;_·߽W>i'AJ4-;aPЦob㟭;xxtPR'wFձg9\sN7R9IXu6_3X|jl GR5 KjVo,}B}[uG }}#X\Э#E8O;UM>r=nk\Ty'kD'{byd׹y.V{,Rskk# XDE@)Jz}΃+Y5%gDfc\kmNE|gE{s؇sڠ]{,Ĉ_s\5u#n|NTPu``)pV47[?+6Siﺎsbo׭yVSem5.XIb .?Tԛk}5{fu%9k73 %ZmtO=-Yp\֔Þt>p yNj_?M#cbZ e}95odcFBLau[hX6aYSS)'Eڃ~Xr{~yI+#rH,kof ynߴșxfn's:f= ni}jmCZTRP?ha?v O.u-lvbWi&k uق^S|e|mv<㾘k:+FZp83쐽ߛ5 ku'j!]D%,P;4\ŀ3qP%Ź}F.ʾU{a,Zu޻м63;^i!!+ }6?HH߇9zz]vcngO~ӟw9| së?4k4wuˊYJTup>uu_v)Le k gg P!VYI)lwuUjW3Z֘1(n'9{i]e7k#R\?V^)QS=M6nr@׮@"]mc!&U>-8u#ų3ϙ04ߵSJI͛{lMSMӌ q墳YÑݚ߳#{y(نLJY]0_vyl]:9)VOSoȈx2]^w&a q-16͝ ^GtҮoٌqeYHo YRp0aǞ`:22q#劒+n[ފ :|/哘_y'^ƫg?Q U( E!*&ԄNN fX7_º2w2ɋ86N5p͹0^WL!#k_';WD&MieLp_Ceeԯ:z(hL/H6!M;b }]ciz}h#k;䠄q ܱn8]\eCznbQ΅H!4S{*n^ğ ߄?~/+Bs#A z-R,aV: GǍcܸы Y7'b'2 y3_[p-Efcai[KN9m07!) frP 1FUCl?[<6{SSjkcAnQ l)cSC{= m:U{tNG:5&P &[`E f\ǻё'ƨvپQ +{sά g ]#{(o u#Jh)= =-qkN-f3l,iPQ˽ 6왨6N{| 1ȡs~f;,gQ/34Ѣ10 MrE'JO$ ocHž4=vbQ :enh/͞9Zy5{sՁ}߄-jFRY3>.Rl_W4J|H%d)Bk9Ix%Co/Om ;z] Fu3|ݏd5{C׆z1Fy;p6K8hjbo$A<0<2kQFu`[eDk({s ESG*JRzz4sHR!%Xzt </^?_E,t x2oO{ӟַc>\^Z, GK^ ë{S^[6{=M| x#mfoZi'CvB7RFZD}6-lq71tٔaq6ZUڟŨurnLXWىXВZJ‘ gt /rZd0tNuQqmKOw$N)knۖ3H~EE*!u\XiTwf5tyO_#w[D[ּ|7Z^s{MvXi,N^Ugg;5o#eY{,i3a\_fBقX-ƨs?X0cMЌ3JQ.{}-Z :g^jF}v?k{N:h},kkZ<نAq_2{ArV&ӮM^dMwͳg@dvF]Yz(έbY] 5DdG-hGgө+NFڗm6-Ul,uśh-H34YٰoH@fvf)=AѱϭKklflEPz,rH(,=m>Fm voTČu)r%̹!/[ۂ8)l[O/>>TY YBC)SߤY13}h]+{8@uͳh4 zg>m1{v^__w md qZg1p=xtw|}IЙ9xgʗ_}o_z%lw@s75UuR E^r9c+m]$;[||y f8Bto}ֆ:#sHC" ;O/޿rZ#e̠?uhgk&dS4D;jk1Ili-v<, ň-nC_zq< tElBCP9|$iVaB"³ۨZ)`<.Wv8RhZ޽{:eEm,z}b;p8д*mkV.hlY Np.`v:?#Es!x{*6w_GC~g i:h:4@ajsE!L5zሔJK&&L1,XEÆ@Ma~YJᆛӵsƺ&릅ct&s=V(?]0V~I߃sEvN֜?u؂mtt6rJ&ۨDuSޏȵiU[\Ks`UY=78!osnzypZP=HhT#_lѴy-it 4Rno9NLLiPy6YW Y R BĶeefҩT  }xWWWXQGq'M.*O~Ҧj]78;x*RiT۶pi–(27ɲ?>(s?kn!!O>4MB_֨Xʒg)-j d db>{Nn>gT2C5jF1]/VC(~[V1_b F65&Ꮍ.#b-eAY>y?wwwڈXŮϫ+777b=7,*P-lόb4?%/^NNd\uVڜZ3:M:% E\&2e8?p3|Tāȍ+VI*^Ě0[*r K< r~5 R̀5 x(S!*ҵ9ñ݅H6R5P+ oW|Zz(W[ 4ܼl 6,[}L#e Q.  yDp? wĹ4D_WWWƚ6Ol!g],f'v8}״x+I6ssTG3j2VB9 mӮ;-G#Չ15Y#b0NE"8Hq(!4=7=-e =Hc{p6UYmG*.g„s.3~0EԻBz14snh֣U#ڔGJ<1dTW=eTu+xmW(q#BFhvmk߆8|`7\`}VӃ`!pu!QOiSWiz;XYKӜfg'䫗n_w~CXz7 w .(n s 8);ertɠ s'T`PD*ӧ^NKz{HNgMNG݈E)Xpu0{#Ln=.vΰglᓠeV7eތH?yŹcC7i бX?+&$~$[H-M(׸N-oHYq-|vZJx섛ָc?$ɫ-ҭf4 PuBzF߮~6`۵,E]GvacHݴkEdƽu{먉blt!ԴXD҆FAv/L(Ƶ7!{Rq<CW<˵8MDRֆҊF=h`4c`Ew=sx\.LFo$,0] ϋ]{+з5CTם|@M5WxD';.Ä|3xOᇾ{qMݲpܠ$%gzҸai{+psEJۖs=+Dc`^>׍S1LJO%ݚz:#]lԾQ$;zi:k =vl؍ҌƆN{t8푯nIa\z0Z6r;m9Ū-o7bx]'$;ѷ~o>0۵ bCnyMk=%ZpYNnmݾs`Qrq5CLdPZj->D٨Q(o冀EmoN$hAEl.ӻ;EeʺT(i =M=>32ZE53r-t,(тk7M aͷd[lZ((EVl#S+5} :'cRAlh-dd[Q)CL©  *r-wp[KM٨XR_Ҋ7ԚQJbFqf&*MߣPÆ8Jfu6?Rl=:_?-eknZ:8 EX~qΡf֙^xid[fFY-ZyMkڐJtt=:Wm6JIض,DΞBѹu(k"m7^t=%H7jY6qaaU{*5gu=66Ubasp":_{&R@CMJEptD8tuD5o"(Σ_uƇ>|>>oԏ*gtE5(l]q߂6y pVW9FiDv]mQB7Y-u"_=H*0.7#ydp[T70ʿZeDWJѲrg֨Z9!RVH\9IDHLJ_7?}яe|{3GS!p8؉=iC.ZCL4h׸s,գeG=ݑ?Z1p,GRlF-GZ5?Ƅxx=(s"g(.NuELTs-T;+R3壘RPKԱ9NrqmQY۪x7x]3 ,u27.#i!f ^FEKs&^(ˈ94{v{.A{TKک2jh/L'kTɑ&{ lxgu,{mFӉd )@bR1k.@-  S,t/}#2gnd4\F+`K0jqJ4Ȑ^m7$fs3{E)߳mW3ql9!@>#j|qZvE~g =>1'-:Y9D.xǻ_k&g}y7?; [zL)4stsdQ9,up3mmԞC̞@%5lĉXjup;:bKQ!(u^># wtΡX76c:F(P8kƢIr~FJ]#Mg6[Oג;`.gJ2C:f? |.4yr(>G6qobdKo å@VF{w(:faԙ|\̃Fxm4=أZd:IQ'Yj>CX&.ތTKݽU_A}lsECF+t۲'u >)IġkTɒ=p8{Ç8fOWc?l[sB)^%? yb f(-Nj!9*N[I Ӱt@0Ov %Hy}] "oB׬:P.;guY/-i]kۥNt ˭[Tu8yH=&QD~2\uS!? O]N;em4)935"NՇvBDkT[M !yqh7$ Q(Qa*V4`Dsl!3*Vb={qJ=fL{.7*49q}"FSQk]aGjy]{nC]d/N.\F'1d,~Q|46n'py}(gB:+p2REѰ> z2szlQ7 10clFm,^BHV1a㚽D]sڻ?wtObGl j}2o483F*i }/@p[C^gj1#BQeȐspll eObGݠ39/:KϪX^jQ;9Z.[J۸EX_жg<#, *j|ϻQ ~ko_E9%O@Zj@YR0u,RcA䁌;pW1PNaGjս85Crlq-\ұ^ lv0أ>.M3M ӞHyqP{MՈ\LT5M^ϻm9>CRa&e~ς@ԑ ./|w3@ "NPKĖoB== ih{ Α}-kCRXM\8NG(wu`{tK{ƥLi=|&~ԞDܳcO;\KW1WA=\jCwdlBWʟ:{ȃg߈YQ=5IawB hlH|{m+xw5ϣ{Fj%-] g\gu65QkUԾ{VwqV"x ܮQmb?4ccaK@&tlܑ= l/p\j\'趗^kt KG4DdyNZnop&?u>Kb~o7au05.\ ֙Y J$ ^ݥb>^?O~ ?ʟCKc?Y6 fTo+6UukMag9Qu(Q^m%${yޤH. CAlZ`;XҤQTu< lwmѡ#eqRsrz7@Cw{va +8wOÓO[u VP{W3V~달[xyoc8D{(ɸ#'Vbw(!R~K˟$W>iN1MY a!ЦĮ&h`{E3yoHlCyI簗ˠ``= Ovo‘fQ=$w@Xh.`_Ԇ{66?vOVJρ\ʵp8hՈԡ EQ [{n]"/r?7޻w:Ju>zDG'nsozz:܏9唙u;,fרi!VԘh-)dH7ס8jM8A^!X[ۿ:7 HRZr0|A͹C-\@d ' ^UEE!JԾ.#\ɢ(7! p+{cD/w%kytD ,XP 70M .lJvvys)o X6[Ȍ=7mQ 4 :`s;n%Pй&2 AekƬvDK"(x1pD߅=-gk2Q?e=shʳVi%g94{zcѡU4_ߙ`@{C)] 2<+H,z׌y- }-ںR ci@ l rQSJAR*-=RPJ&up\$k NM#v_ĹM'l` ~=mCx%[[Ǣv&Ic3ڍw+xk:73FJ8FkvZt{4k  T{dhpQ`,FaɴJ\ 9{ոV-g^u1t:u|DR=Qo&͆Mhea>p&X` /vCIYJ(ǬE֪ٽ:m'uR\*=YE},κHdY͡hQ$+,ƀ†8;jh!Ju(iy{‡?"8[L!1b4laD+֒"LAEtA;jɤ1a]w@WYkqC:yPHY|޾ϙŸD~޻0KQLgkm:(ATZ>\lP9 -(S:yMmoQ=^X>n?{a{.56e# b#"y{nsYT=6QKf6{F#]Ep˺`bZK=}{1^sߴ5m9cbop"5EhtGKc.a˕ɹr:x6]>猼$\x!b|~gN;?_ߏ/' ՙ$0q>V1ڐb* C a+q*LNg͍GMPTO}m ƛݾ ?4\ou#ScuPҎ3V54bf5Bj{nqA b.{۾WOT A ɩ@d8IaJi`D8Ɖ {BKA=cȸ- =!{䘏W^e\ҒX_o IpFK^*G1~Rew=Ȟq ~vD({&oEI{hҥR|P]1cF=%L_Zg#tlɣF/!Y#"wIgC>ϑ7CHfYN=Aج?Rl=goFKMDΥgc q dBVu|NQ=hl~Rwm~BΜ-g?b YiHWAs9^P47{[1tꔵM3OKX&~, N˂;$vBQG}ۜA"eYSu&ue/F|KK>{T= z,ƿ+0ķ+=;K!^Rq#~s _wQmoYo/]KI˂-\ҷ45 쭻q7k/ܿs!AqyRwIl;ޓG{^O{ Hco{RPn>܋1{Os]Qv4ek8('{eB21e8,4fMU\ګhbQu m?; rp-ϥe:Hc褸Q cDtx<y-?psә SG٪% 4!:ZVZ)QA'IDAT%*@oQh48ZMFӼvYFoRHy!HhH^4s!݆zg,,z=%HVY08 \ă\k7fM}!x$e]p:OnByiBۊ 4R9ԬΆN9ca۴iL,^r"g|\qp˴L]ɼ89$O_nTJ.v н}a-ۙ@Tz^]}e+GH}ghwmIC'h/^E9Mߜspa/P +Z(f $+@.YXј.ѳPpYQXT]8X{0M{%cwaoFrtq{dj``^QfcqЎKG3.c˙ ^҈9{|ZhYaa7gDWqb=m z; ^wI'/H^ubs)&]ǥ}Z_O{,5Ϟ0WPQ-}铗S[[ft=l 7AR :QAb7%ӝjg蚣1(D=dN3$;,ۊ#+{ ǫK_~ۿ# exS9|-4- ΉRبAa4Y39aQQݻ|Hoaz6"BY[b 3575o~G'r ^ce]Ch@|.+?>|oC@ e[P6`K4i(C%Vu]E,v 2MKwfmȗ'oT8vW_3x/{FȩT}Dio:hU݅1({qiK*SĮ`F;rf%:{: UK=7ZS/!{rk-Z7tT7x~/ $,&4qL}s{Ne#߾=RNꘞsÁ/d:d>_`M.!n{v֮HCk3lJ4ZhȒOl8> fGXYܝ3gP1lO@Jf_tY^籥 VP>3?R:(t'X-"M41^Gm#+hRց{[Qׅ8w!I?H5gJA?M,R.y9c]]}v~W#$#uz4<8'EL >mAp:ps %ULSA/??׿%I]a.3|&;}=cʹsS[e⅒{ta$Չo.ՙs_N/]9߂Yj.Eo8=}OgYq%jX{x??'07)mx}rASS1=Ĥ(18M\gG${L3Z[quK龄(H ֹ(u|^͊4z)nvh[+M1LW$ZoS߬n߁~OH1= ƂqN^~1i81+ 場ZxXJ=-BF}|8w &F!|gYDU'-h=)Qe]p<맰FTpA ܴm3NUDق#ս,Y?{ڜ1rVK21F䔐 %O9j]ѸVBRݧrtW_v!I{ZJbіΡ=\eë'{MgװXPGtԂeYCˮj^ {h9L&XqDL(b'Rp8v[jNB\~f {LضVfsV Rjz>4! m )m:mzHYab>u#S]A<quuPq@WgzɥkLK!gy5HqYiSq6)`&L9O8g)Xw,Ⱥk׏WW]ݯo622M ;iºC&0twpJr_?.~!Us!2qaͅCB^Ws%s>jODm꬛ RX1 wE?f0&v>RrD NlTh7$6A]"8w,ůd9wN'Viauek0 ÿO>.1`2%GlHF ARD3DSd>iӘy+>,~cB ۶u I.|D)L=(JiPȯ#SuvӘ~f&u:=H[ֿȞvNsp1 H;W+xQqb`Z7(6YXc1~叾sUDY(퐖v+TG%b'%'{T: @{Z x7Seeiq~R<}2*gr&X?xʦH TRwWg;ӄ)ZR=Y3}8WwB׶ ֐tT-u)sa\u% ]=STm[QjҦY) CNES'!y"OY"drsL˺x8Z(Yʶ)~X9Gaےq bڛ4R*nnk6%SRv!>3`_dݫ)Re&ğM\.ÜJ6smX1$(YqEO< 9', A-ME&ŷg66ɑ&f&k.kq )-[/"bxHx7_4Mxꩧp<ējDM"ִ0gLu]qssVTL5`Yzp(yC)k֕t6פB$BZ*;dn)p;~'my5$ Oj2PJUњ´#1 ?iz&<7@ݦ0&e>.3".FDP735kDRL`nڐ95A:Dv eC|jR"*iRǯ0'|7{ .̅6G-H2u1!R6pBRINks݅5k$8IGL8s<=؉ >Izc#.zlKKT8F=shMD * !#"WK=zgM rs s֊›Z7ZB^E8myj봼pMPIX.S\KEiDLǍ@S16ZZ=EeTИ-%mILN>kfYc(9EUrZ8.JF0"E``3̪̌HcbdBWRRrf;xxdQgvK%,rtjM4PdN?㖍``goi&.[m`NjL$yhR.Ep-F(/}j ?+!R VoMm-VLMBAڂc7- uFPA 73KPK4V okE_T]۵VjB瓚v?LS!WU\jaKf'(Y֧^S%pFc,Iv[W_]]u ưQKaA)~ -{4.ӄypwwu]p803^}UN'|7O駟m5Gnۆ{5Ä;#h&uԊ'~+>O?G{q3glCti!U 3>0yZTe :C! Zc˛UT~:O/qyٌ_ryWq|>ھܴ}+M3~]rA*|B݊nòu,{GX Þ-l,["" Ԓì=#ݻc׼&Uw#cOFG9wj)3ڄf/M-+[\6){G-*PXpAgiZlEnxF< 2Lh^ .2JD߭hlE${ a+7mi:7v_SQXLBJeg8Ͼh:>ڮhQsAuT`gDT;ȷL0q8!sS ET yTUoL+# tmj:[YZ Q=h3+rz/R9+֍(Dt"ukZ.}cCCLO;A])d'g>Y#]2q Y䚖W cj!xbpp#᭥¡*<*#q(Zp BZ3yY<*U%'ވpJN4(z6*MOہ-(0 lsDɦ )'J xTSDVn}19ASE{4fvI}hC8E%BSdؠ=m4˰I>n̘Ŭ)NFσw\\_?-/cmxǻ߉{a:Hf>o uE~HZ .3|f1!vCr;{?s?o}݇P\+p ?_}N  !\FEgbd$l7-hXdNY/df1Y($OohBDF|ӱ`:!$ZN/ҹ\Ї<!$|M8\U|=vdL-wH)a}x5 \)yn )aIQB9TjFCxnnpss} abۗ})&pT.p^?x)ex8dp/wLTO*ό- I9 2k==ajK1P? Qxl ~'ň\s{?Stz5oΛ ʁ U12XRsy-VD`hި&E=*ؑ*~> $ E{}BGMhʅ&4ѮQ)3Sl^aζ B|*|pt 'BF^4fF>^Sь3~_4%]YÃ7 7Vg]6-Zb4;4Ez{?EDB{A r4MXc;ܻwKe/PREΛSs,'8p6VNҵ~%!CK)gSJbj>Fsz<Q-|ƿ| ug|( aX4͇ dmLQj+H:P+Nv>6d竁~Bևp^{QAz?A0)t "x;kD.umhuDw 6i8riʿO $ #du1LH/La@ '{/c,-)ZWzZA۽wL7+âpx&! D-YA{hQ~Ԋ1rt_WW3'e#}340K2V-h%TT )R^x`gjD ri0,(> &jEIIfT)ŲGHPGC'-[ (/i"L{Ƒr g3ڠ^ j)rETꫫ[ZZڈէgMVd}D4A#b\u؁¯ )RSyw5IՊP}\U"Y51Nٵf3*u@l&Ag!D )pޡ(XN%BWk!c&"MLems}(^v7.,{Oe/4Wf;QmI ~ّaO.3'X'=i F]eU]&6GL=ӉZϓK,W,FG;+# kp<q}Zq}%|7+:Ko*Bu24f{hrYY-A`_7_.I<_S7wɨۉ jڐ^ӦDž״S#ׯ]ylBlfМl*_  Յ՘ymuF'Gz0[xJnj ߉BRx-jOEޝ"߹0ڿa]}w#dLw/5ab펡Tst"mj2qm s]g#oGVVxlyc>CYY8/[Zr kr.5;o{BNPHlܺ3ؑW+l7 I=oBJ.nGVp9tl4n,&y}eE,F8(ޟ!LVsETH${9:7 hBr \Z 3Ԋijq8aAnAhj媃Y;['TOa[ڴ!&4~1ヱFBi$T 瑫c`xj1 wS^K9YҎ8nH(#_)*Rʔ>YWQ%3ơt%EZa"CN]B", \ Yַ8}TsZgĄ}dk9ΒYP6U>SΙO_CJ1ؐ"jC(`Ch<5,=7[iHh*znGGI{ަޟ=~VcQjҐe[Iw}CC"(N8=[}W ??ook|FWFlsN&Z- b$ɣe$̛kψpkr8^XO>V?/߄9p*KfK]o&բȍ9ۂ/0!\=@YPy&Dra&e[kab4,?ߠq31 DGDv }kCQ8P.+!)c`CK`WW$3Y[j:n?_i#Ss2ޅFt$ݨT7]Yq2p}ѯ8*.6w)y_khF;ߵѽN m;K?N!W;eꯉa{Jl~.PD&]>J629̝ vB R`#F6TCbޘSG4E$MZ(\HVftcKI0"TmJ09Z*6&_B'еOzmNW݅vѡw^4ׇ>E!8ܴ2«R1C#;`G&q%0HƑgj6Qu&6B0[vIתb+ c%G-MK;jRk̓yWuaq2Y6!nja -"xw I;Sȹ`BYL+ڧ˱.+|)/j2QAlvj^;`i heER1c'[4GZlUH|:7 YUIt/NhWT*rz&JYQL}.BmԆiP8Ӏñ%!xaU4*CRR&A)h*AN~*sVTCFpU97gaA]a(\bP<@흝6g!K H%x*h"`;b>cʵ!7 ]@tg0MJ ,;l لfQz0l(j(Y3i$tӵxfq4&̮5p-k.yKNƈr=pcOSh)j/til¼4xgiVGKma}])6ă剩 D.$V@m[L_0іDuziLdİ*=|ӂbrs4ŚĢi* bL XW ę.:ǬVBy:-I>9k#2LJI*s(MrӒx{<zQ)Y@!KcLD9|~>F-Պrl( nhAI)ٳmD'R<&v1xLA0yh]EC^s>*3i(4Ju54í"LM JeUə4OslEYeƆ[P2as2gYɶ5w `ԁRa_PJ$掵EpCVZwwT`NrRN5k4tVJzx_]lEF|ց8цRe* ߋT2=&]~M{48s]W.E1"m)mp-22nL Ɩ nn҆O~Ҋ]|\)yK+]ӊ' ;9NLnz#&|ՅmfmR0&JJ{V8G(5b-n?o s.<_ ]pӑ&C*k k˄>puO"=z!iA)5'"&J`*ޤ,XF# 2f0Hj]낥Hɞ(Gh R,Wi+!~͈nIȿ88u]5Bl7o56XDi2-.bSoy Hq9:nUzPXcDv:`P=^'6hO?D]x7`Y:C-?^qd]e X,ԫ17D2dg9)jt(zFɗ5P*  QQˁq &u[JE?`: V)*ŝ7r˹QqÝ'{T-XpMAkbF$*&4<Qhc4Ƞ†gynr9vK 0Zq)J%qV lZajiNE2z%2J+:j`UQeC_۷8i#]KF|*Bn"YZp'IZyQ#nz MLp\B\7Oۚ)9?${l&;JC:yFՀ[:*ƛ5bqzYӲ&s\E׾5 }m9.b(c+y~ѐ 6UHc(D59)ex]kbE.!|W;y - 4Ԉdz kFcX@v?T\+iR*s6\&e8P@51 ubkg'՜7zT&4wzl) = v ZxKPJ;N;4vV!Vòn)J̢64d,TH\+K1IY~چ`o4gK2]^LJ_!΂f{Z*6=I#zUByȹb҂eY,+^ye|S»l+99J{2FJ SĶzR ^G45#ݟMtpo}x_G;g*>+tEs!+A" Nd?h.DnkC.}oMKٕu;Q9WlY&i9\vMqW132B>Knت >R~|*|`a|{[(k'(١YJqLY[rF%'8SOtZdܻwO?4- ӿ̇SۖHf˲6HFiX9s0d#_>O]|~>@G E8fU/!r8% _;#HsDVqnx>ڠ$?JIX;BÛuVAUSZ_V3tV"9(X}cBYvgQhZЂ9w|!• 9g3q&g'gƳ{{p}s#^7u'0Ϣ*xMWld*ѱ\rəZjȝ^QJB[եrP9Rz0[&,Vćw`Eamf6Uq%Trk c-X]  JIHF$sLrQpc!8pFUl[p# V!*x9xVEe/Eb [6 DMӦJi#7^)VS%5G`UiUTid~p>x sk!آ\qcejrKMyT_̱RtMhEIy[m !H(,QY^joZ{i!,6Egۺ$tA l{[0E@ҾjͧT4k#LO71 qS?%3MXeߞ߈-Cr;iXm9"Tlt]YnT'8T}*m-:7JBAtA8 GM"1Fo;4=R{TK)AX5&=6/7"Hm! !~yW1FB E3* , /Çxu|s?a\]q{{ #<bo+?5v47EK>Q|𸺺Uױo߈xivCBnϛjB)Ǻh8=q{d;)x GL+>8_8*_ _;jP \8#gN;q]3bN3ajH"GYH__㦼o}sxrR tjRk=8s/&c|_{8'Ivh:.`'EB:W-#{\ fg-W휽y^Ҹfv!m!Y-3ފ3 (DWXZg^xw9\ͱȜ-Q 9ZIS(ƌ i3sW4Ձ CnN+ "NSTQ ]YkQ,uQ-1,Y7Q~ i0uM#AXZʹХ\FTN(.sa{ToD gtȷBF '98Y}wΣ{s@0s#„- Ĵ3'JnD@v3th́Wʁd TԉJ5ZzK'Dw Qt2`z$:?z;uht'1D6 IؔZIxi&>/ 6Fq,sfjm-;WPq+}J4EDt@i$ޛShNεsG'A, =)[w79ysE~Xʢ6P dz/UG+$a4SPDԈy+}+PjjG:,797G<}>,^}U,߈_#z NIkvmyst%' l Ƚ ͅ|k߿W^y U~[ނYx$g ⍓k%&MV7fLG0;' 궐$5%-~jwCX@|woFq KEu=+ApݥI9c nыpMp.z<^|}+6҈LqRD2Sc d'tjaŘjj $ NVu ;zN%6PbJ<顦k7:49kc_ ƂA"sr8ә(ZWz:=%׬ ~^5~̀f$]qȬg E 0g҈lu&6T#x }ܾڹkA\ay$F"wռn%-OJ<6UlhlبSFb\ L_=#D\:  g[9lE"Y0d`j_=KmXM=jP nfž : O3_f0,n@E Y|9Bg$~v0Ϟ0+2#]p\1UD]D9QL,Ӯ(_srZEӋL{4"> ojZt}8"M^'Nr0dB^ZFEE}ӣ&U:25aR]J@ib%;:KC :SDBp@*mw"z\}N`K\ rb͍\'TeBʟ+"\o(:mEi?<(4H8f:V7?e#{R SyPrf)gH%؎Vd!s ki8*YDPrK2ˈiF.-Qh᦭pN!d++9ME+Z (Qar䜹*[WQ5 K>4"#ql)-S#d_>˲KߌiЀNY`+֪h\UY5‡bģ_(Uݒ kfՇబz;/ѣGⓟ$>᳼ c+-9r$ D/[WI>N޽{H9tB) lkgox4+A~VZ=JWpEQSԆ h o!'8 ߤ} hH@ʝ3!zpeo\oOQZL7_|c-\<":mA]y )CQ m< j=„Re4X&6 $?kkvJZu$؆hfoEP CcZո TN}nYk1.M?)>PN q#jܹ)")pZjgk\(M2TsTSmCCQ2 ~"L$"$i1S+)mLyLY)SRrǨ>:vk(kP9by3L|懲 ,ޮbb+n_ t DK|JC6jsgOV=9U LڸGf4 U2H**m"BfTվ iU5 {Z=;ձͨJ̽KjRڤTwI3%E tY mKz.ˢjAPNNbq襳 쫙˄gi[N'A"9o;WD+*21 +hϨ%s>]o=aˊIRrPjŶn_5$4?{8֦jS2YO}>|>L1'NkS!X疇',tvP7yzaÏ9!&\~˧7-D9n}+>ޓH>ഝH,PN}Xk/-yAq!H9zhm^hlZ{N=,LtcAji1-Um/oeDWuszCa1wnf"Pg ߥkdKT.0fKqvt+`sU- e3hdgTLS@jEpBR)E%E:qm80*exlX54qRer>,@#Oz[ ,Bf _ ) P 4` mOc4]h#5+@g[E-mkT!T{&"XropB֛$MkAK0qD%eE7=QQkhcz?ADtJ.U:gS(19D1 'Y`cI֠R#kO4 ™X(ߑD(!Vtsj}\6L+m؂Zh9XjEJP"ԻF)$8o8k5wQ 9&7'ĚO}Oؙ/_55O h|@dN"( %z3Ϟw賛PRJ!",׳֖YdnXESke:Vp0|lg^ֱ.^}UܿW k7a%7V}mz5P: ZM&%V#|!f)lE Lǫ+G8| xہO~u=$^Qw %Ўejg}Muz_J*FD=KQE Ц;[jVBh⌧go> ^Q.Չ)P@6R m8^9777gnX&KAJhۚ'r#BG|X6cHOSs]6R Y1~՛ZZr< ?uNӞumN! h"ຆQ2I|&wT4'~ԧeȼ{X cGBDN*m ?uُn=1ng?uB*%#e Ȣ$p0RFHxYwMh'mFP70i r.=*%}KMWO(칽HFhJ%.^:388W.iuGCF#SKl,Zv-,ڟZ`m,EK x޳xjKҟB5h0jХ4.fqcVxdQ wgT^tO>4'ERwyGsH0M\qqc(w&a2w򉘋9ElNEU -\l*knh%u:VHz$5vOft:{񵶂^nz_nŮ#ᰮ܌򌮛 D7#*L3ݏ6p昶 iA`M۶X+i3nc0mʴ[v~;簬 ߿N!<쳔)KK<`3A,O hU_#$,+ln5nN.ZtPF>- V0Pԏ׹uR78e}u&ص=iiZzz!%iYۆEz \C^6T4Xs:z1W)rhT0%04kg=(;uxΙ ɳͲMUQkX9/=U S K5FOkkT80tDI7FX9McUL 萩\M ;Z#V5)YYSĄ}u?TJ-LDKn¥fM'շ{Ě<PL84FЀ/rE *bLKi袖4q!n ]SB̓,9氣$.䰢57JWgLd*G"ȴT~gZ,>˺KA\sKu:C%*j%$vwzL`A=K9{g˭aq y^x3xw#h)#`iXQldXk>u Hڱ}]{nh"жiN z/z^o [gpYm0Lc k!Tkb#b/e!?b،YdgfnDyS9}/&|Qmnlz% }}}nAfahDFl߻iPIs͊Hx ɡJ`6M 2]B7P_ww3[ [B:t)u%ho{D7P!;&*VtAݛҤ+ī3Te+-}4:ĹG\Įh"RG*8c R5 0DXdh8ߺkh.F  ik:g]RP}Q2/ŏdd8R l#* !b ӟT섅TMA&0ᷓYT'$h ˲ЄkRry`N咵+F_Pj4nfFdz_KA,(聮!ȹ4 ~n"x4򼉕5 NQ©AP0P{-92h_v,skb+ޖYB6v9*+zsiAg Z)/C"N\]>6 ?3C!r6lI%%n_8CIղg83G_XOu8ݝ4}<64M$Qg6HБiV%̀A[Ƀ{n(%vֆ SbYY=G;ŴmH>Xk4ϜsQAks08ehVp" 9GqL֨Yr iRJmx[ނnooquuy>pȸ< 6-,X;;F8)ިq?R]j7!d3?.xW3WTtk1Hk LeЂofp^Yu/lX[E1Lp>sڷUZUͪpE9$bF.5y/ت%;>kL=$KS26$W+I$pѲW : R gnҔJg+^X:֜llغh[,ea$s9 QuB^ѩ̊$J (.rAXLaA1ݠx.WCD0°nL1(uVmK <-k'MKܣhq,dB_٥'1zef?U[b.ϪMQB8o 0jcӵ!5B 6msv8W6l;!ACm -&_n*r9xJШo>x7uRҼjh-nJ#{LəҝuYnz4 HwY\.61h_E#xI 5272n&|]7rsېG0A35Zw 9tV:!ft5)U:NM?4xs#5WpZ$c&eh )9gIC&6Q[B|Pې!gS\!%GmT!v/ɫв:T/u&K9ESXqK<"˲bYxiN$m:ֵq |l,r{,fz:@Id 'B}N~}} a'pt_2{[/}~RS foyVju[~jr]i9j};)4W_E/<w)N (b:ps{(,;"n$4z$PMPfYiU] 㫻Pky |quH5"*ȵ'>(Ěx72RJYsi/Ŵ-~LIHB&|mT(߉GmB*Aw rS_Yޮ5[sQKEڸ k@!oKsض I)6|֒qURNͬ Yna,;"C*TkyNU\h.쩉`Gmr KR ƹhv.yt&DPB .NsE,YưJlcΈ8%RbtдvK+MlLϠI ˙ ֨R1WxCd$6-tl]Jӿco4WCI!%(MB!Z]Y{_ GtAM-jfbVfO_bCWo( ]ȴ7X=CRj*-rԏ\"̃wqF',u7S=s0tsgN@\޼{yn3iS.t6Ρu4 Z(f nt!FU^Kq鎜fOVRnwJ*#Ѳd:+2[}`[E9aڟbkA)8H#.wTʒ{i͓ F4hќsZ2sps5Ҷ.Q:zJWEG;u\źfEjJH<$ƆҺN}PhasY)eUw 8rKGPm!gR%͆KgZB L 3痢/䩹m?G]NfP:[X)3Om۲ 7ks}/_LIVk 7$>PUMTP&LSUPP.j pCc0P6 [,Rf=朣>f: 2*3#nN^ݜc_ԭ5QW-_?x4a0^>G(~H*(`_-Eü"Tdl#Pa EN߿\^ldK@Fx$KS) ~~S[ E>(>)`GBCQ^Lqr]d=|UJFBYljlf;lzk:RՇecA?'b7X aM5r3z&Dg7psR06`~PdU3,aTlL7=?B"; Ԯ7M9dh(*?#au]T~hZ\}dL)4 wB 'Jt >sg W<}eYgVydd49B Ƭ^4҅7j H<^;7iIu`bL>&h?sqg8zuOCM]liX!ۆEڝgr \ ;Ii}eD,0nvnAL*BoHi60Mpꊸu7lkDB+-6qVh SK}z}h%idҕNbeY}f]5hS}NkK#ny5bm,E +vEϔRIخ[J}m<4=D bVu\Kꆬikfxqr>{_3n`߯^HYv3m}hH+M'd8ȞǦix౉#go]~Ǘp<5t2(IM)AoL eikl䀲Oϴ7k& A E u+?kCvv#ke/Ҏ75zfl9P*O&a|('aaLYsg}#zciTx$nOYdAiH @ݺ_NS*Hy.6w[P='2q)IJ|#8B<0&h?= z <&kl RhIZ[w+Y$u|ہNt]bIb7%^QdW$Kf b4mjSAcܚ\x$a}>Ji*YBYC?8,o 1,,l͉6!Ԗ`dݤ)K(d%8ؤ9 pRWTghk(F$t}[x͙Sk y~O{@*sx㌐ysnLhoGr`7gnMКs-i9j"ňd c$XTLGb %<p "SpP׾]Gr~) l+r"7d 1X mU}X(=b?GDhԔϠc,QOP̍jj10z %{\iS@fHMD:/f~;*ynS eƶ?"Q޿iB}@NctK2`Svʝ4wH6S}Q"P\ZhqZÚ.`lێ;d)tDY턯Nf i|ਊi9o< ?:F7wg\(̆kl4Ol?tE;52'/<| 4U:C`~W$v @GDѧD[=\OЁ}a͉k"|]BC"khFz;2Ji${殍f":}aVԞU`{iE,4v )\ǯdmLRC⡅~,@EtM#`d$EDݹeY&ǫN^ӽgxׇ (>8{k h> vM%"Dڻ19s $E4!)IFAeuR] FP%!>zD53-=܊d~HJyJVJ@ 2NM-hKF(nkGܶs6Ԯ|z-E?f%Yva"t :kg]54Z ZCJf4vɝdpm"ELROhmÕ!.]GMU/֮EQV+#<ıZ`_4a7QnkòP2feQFRΰi&t <ફMs(^&N~U40FuY SL LVrƮ kP}FZkWhLH:Ѡ<'3r.bQ{V/ ^cRҔm(@jn'vm8) mҎU,e=$e$crt3`2,BhƨmHIЌyiӵMh =fI}Q]߹۷~N. r'x ^+ĚX*9I72!ިuF7cZk">jCUlCZI7'8hGd""֮{!{&)Hqg,ÃrUgLڢ79&SqR{Dz~,EcI FDa>{ɾ70Nc"ca8-pдfwtӽ2$ly8W,y 9"N" eT\loqjSQ P.yA^ G Vɽ zW1ص AQBb`bÛUKr}wl7ժN5PD)8i^EwWf-H[k&{XJct-U zE.ԣgCٹB&yqWN*FJ3UYʒĜи;R։fMe(I,kD=!릝4,dww7f*OY)Y᪤f^PsW. L2 -sCCU$SYY"gVҧ;Ke("ҚԶmՔǪQfQ-#'K'2pJ;Zfy4 õ+F")1p.Mو3N:e?3#%ְm} @Kv+"BYWgj-d;g$ ]>X9gukKN*O]BLt!)ik&`9  9.2hj hP]@#; غr2+r*h]l%(OnW/\/fIQ"dtJң,DHA].^3!ۈt@y aѪby9&ڨ Y0[eFWJ!ЦrX [Y$~l44/*"bSH 5!c^.?iZE֞JՅrU HX)/ʇzOޣoZAs0|A6 >y-:裿]W264%/#dsFnh]=tyC><'?C͚Px~*mGZuY=xVpDžߦ}SkHh0{CYy<62Dոy1'PLJX/]P'xۧ&Khg2˩ΣomMNu!584s0ry#I:H/,KAh)E[}õx&hz#e;٣B2!;VQi]Vf۴ysZ='f]뵍 ʦ[Fy4nA8.Tzb%%1Ou/=&DX !6xSi[-"Y3prʪ0 9H(=dEtOٹ}oJ&bV9rYDwOr֫y`,) M"k 뭢,Z@ZP*PV 45-5=DE|kK󜱦n/+ e%j5X_(t(NIVлP efG"TÊVR"liaWTEIDATDI| SdjwE}왰5PkVMyӄ턌"$q(8``.VHlᣴLXpA16mb[+VrUˑX,0RdI{4baͭ%ێ\fUk zEB#c;|_Vhr.vG}G=D}Р0nWp{~]V<]3/S\:㶃"2bt=HҵX *;-:$Ǔ 3:^߿/Lz&nV^rJz51YDC̮(S )ќ=n( ,#Q=%傾_*U#7s'6/N,4*N2ux3SgEnБHM9KnYf=aoSbp|OQя.7˾wE<5%VDk/(%rE:1 _†F$sþV_Y2#6:c&'>ZvXYBU}&4ezfsis:u Y1ENA9 6eI5M!fhChH([^BsB B,7)KFE?i8 VpGaƒnbEh<97C қ K.E)2^dYAD8;m24RFBZ2,N@%jY he,i`!g-%˲8=hYێy;@Re۷1FQ\Y&kZ7W@(RtϮ$8-ګI5u1adK*CjR E]&nǪ#3&tc\>ʨ+%<=>b{ OoQJƶonq֭͑AQk;Wwē^׆fltUrPuE)r|)۷_5yO7gd6f](sE-'F >*4iB"5鱭Ο<2D#rlBީ! ő651MsvzMp(;2\]'y}{iĢOukHb9Ni;({±995+G{Y/a\O tS%.R}4\͉ьy͐A['Ǽi`RDիCۮ _/}ɓ?#|~w} b-ElbFv;8˴(:s4*&wvQ 3䘫s3Yjbd^wi|zoC3]Kk kȻ9ge);xѕf~"Rk׶5UMm'jwdV985}\{ ,XhZ=[k* D+b(Z)Ƅ奬XfCd _nϞ/] .kvÍK֧TPݝXҽkmMJQ?̂ȹ&\o^aߡ4恩6uld]땬CkR],oM!-ֽɰuTGhm&%-҄'X,_[77'ȱ[ZǛ/$HT.+Zg|aaY9uZCelD z,0z K ;Ʋ駟" /_ǫW|2B4,O҉f' +(/#/;W,MNu_&OG'o8m{0d"LB},4~Bd^􋈰n2P剎40Xጄ:r+V7oh>8riZ߃;?بx4'L ʬ.}.Lbarlb^gUv}D|b) l䦁;{.yOU3fl*7NJjm,|hqz%hO Z}2 pG~&NcDR%rhdx%\IDHKWf':t)֕%iX-wj&Myp"γ)6C| xR¢^V=Qd/JJvP̫V4xWjGcږQ,WLK=[HfxlAkV)_oowE؏ 1*ED;L/~qz~W'|mPJ|Wʠ3fM;v+4 1ܲr}Fy d{-3qo{&jf.nWC;t98u3D\䜘ВL&W=T)J* fZ@R<[rڒR:( cͅ[7{fTbd\a2DW\5Tuu~6q!FvW%V&8SvkO(NTAEgCkiDĨ(aSxeuukBɡQ/Yjirm.͎#,gcZE(/q+tdCCwt?d{ɶ]fzsڞ^,4'ׯ_[@|e/-Q=k!=;f8C~rPژLKb0|xhmR "T"9|%TZ_mڮzPy>̠&ӆ5&C<-mܽ*̄t >kL +o&VP~Qٛ]oPToh9emD;W Nܙ@lB!gȢTcUK*JTJbM#< ] FaC/GiHN4C[e$h䘩mlMu}?: j\7lඬȽcY,|4*?Ĩuw 5vEm[Mwqȍu F@WwF5c6z(VԕGl-CuۦT^E, u Nښbe(B>PQ렜 ΓFBExYվW38rno mW^;lo;ֵUƂ2<(*T2Kt_&j4Suu5(M3nxeYr{ιҡ(Z&ֽ6u3T.ro@cis ?J}G3oX׬uS$)Ѱp z"uAEO۽AZqX8LvG}9ױ+ضm "  WGw9ZMa@nZ4i\fmAl EOK ^ы<ŎLFg?|bcMfdtz [kXE0 f=qYi7:V%ul@,ؚ-;Q^YdoIE"UD0Ѳ#u@ ii'ś " 0dܱw\@9[W\Ȍf%&M'NWXdV *ͪ?_iSP:WR e]>_Yܗg̟ŧo>w{=<5gƱو/1o99[cۦ߂(9?C/#m7&GzRmP&obgFɱͤtvi^[dmb$ +cSI48zVzAb> H>tvS3;~W5~U _$x?mCcP[sj"ɬU'4~Ҁθ4b."r;"/{`|uAxFR |a 4T*ͅO;HsV 329l_zGY+޼y3(Ձ]m,' 8cڟ~De唰<>>>EBLk]mm ᾛhR&yF^>xZ,P?Cp:B}2 d>E Ytqu@'’ t/φ"Cc$,"rA*E^լlHEEDFU}CMp+3ݺ5HOsS7F[~P&gڄ`BJ67 8rՀ.ۀfjݼz:MrF ʗn)@ħ(Ba\N'ǻ/9([MCgb/zSnTE&Nm牯o e;9r(SGqⵈZ\v:B#wƾoⰕR:؃d>14޵6,:bMK ݍ  RDWI(za6lMSY]>^+BK'+sv,Ȯ"rd4;fYpx,iI#Ep4$L Id%makkRRE G\bSs(sODƢ_Wom sh ?o<<ԈߋRr|NCEΚ`8H9zH)W*' ȏ0KJGjj֋qµ7yB9-O|Rw1&7# ˞=0{Aof,w xWSd*CC? ɗzJ E3]ZjSlr˞?ʎ.˪:Bij\2D{%%4}uCfi!5i=͈7G[^B[)ƚWyĝ&١< 0 :ᴈ""j`RTN+֒|1YXĦ4[y昣.a"| I( ԫoH>}4$'y;g L(ы<';&ZFk#=j #](eP$q$:ʧ.{ "5 SڪÛ5vNe20V&G% j%ЧnS7- D{)'H݂c]8. uɩEJ& u![kiv퉂ɀMR1,k{ɪfa^grXp)vI )]k}X*}uwՀ@~{^Bv\Wџ9|w~~׏&^5'K_I șh9s;R$#m5W^>;|w~=n =[)Y\bZAkB7z32J z0z5L&ڱQhg`l>!ȂRӝ̏[ӵIH-Q~^0)ZZG]6lS:hERNh=&ЦF Xa^wu 5Ӛah^Q]Dk&yZWRbUe[Rn9%ƬKXZe7H: Yw rR=elHmAwÅP޺.<{cnr?S\Wg~xsT\Y(h߾}΂^[>۷oqw';>+*ȕX[c$zPY^<X?<b ݝ[S^ԂR U")JHNhژPx]ޯ:5kW=傴J^ q E=PwqQ^HaD : #Y!y|[[gǟO~:(OM\Pi4i2c #hX& 4ӌb e(i"(,EhߙA>цM%|͟tDtP=P2rdfb E8Pa[k t1\Q iZ8gMI~K)QwYP2aN^SFEug5CmI4HĤyc5C !i]QdH=V21J^R@y1ϫhP2 A F Esm YvC;Gjf:XA,iNb,%Bu(XA`Yu5B b^ 7O "߽'R* h$L憞:%Phd-jrFfvKHɮ"ĩ1UZ R ?=VRO$n*GPBR^ ;:ʲC b-{ "4Oodm"Ѩib )2`EDK)ңJ#PgISѼË&Re!SZR چЃ",9"}tޣ‹)5 (LD) EE`sNDS߁b1aBc?au5}#SӤ8~e&xO5ؓjbf;a)PX|s.*^WB#ivs!aݫǵUI5˲xedO*%eѩ&ùʴCHN%PGUkL>tJ 3#:ґZ }{E%55H*fQ?<#~Uz$lH$S{r1kJ7 nkE <>>hp;4Rk OOB-!=Kc6J 斴.vrwwJv=*Uv7o|e]˂G\5~7\[tQw7\FKa`DZV+Q&v4}BĊ)l=RH'f%x M2uh?́E,T-CNR>^joDrCg|ynb-PQ>ϰYSA巇'jqѲ#Eqo+zucN;:#u9ЮW,l"7I]X][ gvYj0Nsr΋ JYPP꯸{l]U7jsCQfO,F]mJ !}NJJrAeJ(e]ԝזӜ\ w5d\:3݆E76Չr^ԧQYpP"llV),joc-sK)/~?yJ:I/ְcs;CH^r:6C=q<6GzY#bT':'؟o_eQ覔$^hjN6eUtS;Ejo 5RXrWBTwEJiܚHnNm۵ .ڸ6 i3ZJg()>@`!"?~C5r-MH@BI tZy }zsY8.رt' z :7ֱ|5Y-٢Y@Og:=+HpNEG)Ŧ6 Hk7քaARg8X|,h9sА#r# =s7JIZ^xKsŦjw̠%? u(UB.)%hQ݌k@mZm~² J1]^Є`uxerW=;OaU.M W1v Kcw*wP&w!띜.]ՠ4Ȏք ,T 9Y?.Ap!):j?7e)\DKb,6Y2/ ?c?̥L\CrZ\c#sO#bŕ}+?Qr'Prh$@J+]+]픒OLZ='-p lIc)I-Y%ĕ.IjV]^dͬ;92*F) ˊNu noޔbe)%wRԘ!J=OEq̯ZH]|BȐĞ])EVͲrЩKil31]i"BU8°P4sqTԻ4N5XScRt1x>1 :Vr>FjDK}VJ0DG1m߰mO2 BC~~>? Qa`b/꽣,Q",ŽIeěeb$N\./8j}sPyqզ XG=g}h?F8~kDfiXg(MY l\uw8$z5f7)aX.qs)jBČZO8N\{e눘b`>:W֦aJ"M#C:ũ ަHL o( ^ SPPF>=h抭1Iw:h@4OS:>LwC#-Ks.BUӘt0c?.Uw mUcV{!,0s E-7[BCL}Nunly L}_җpk13e;Fbt:0uefqF7ܧ&>c4~ED^&0gGD%'t'|Ea=A$ZP>A\҃۠.XhI$ l=h.* ,E3nfNVMf(`h_AN[ Io, QDY$RNl!S Dg쎼-I_YkJ1DwkX0+s9"69iAv?Z!O=أRhD/Ejߣ$E8yɾ6,(&G nP)R?=-F޲11sKډZ=## t, 8ya`!?׿7wj@{Ək4G5x8uuj"G~5+cHkW_?GC¬)UL{ͶZs壢MI=I:=[: A$K۳(鰅\ʑr)6NFIx{r)Epb0a\kf%4RP.9/Vͅ'aMv2aڙ%BdQPhB3wSTW$mÃLsJjxU'DoN{iBqpΤ?Gws!)tv.R?LϽaNi|Aach P6w6=HA$EZT7:ӍF\0Y>7a)^! ?D"Xj{# 7Ұ n krD^xcC *!H#62$<o(P>_%uuiRaM8YMvݰѴi:r]󁅣nt.9FP/H[2ryLlP% ^An.zI7Ef56(IŶ۲X'p4nP0h*\۶g ???ukc@Y?gNZ>uF {y3#N>Ϛ3_~m-Y ,ejTuJl͛N!-I]jtzDpLa4))r:-6PaiN_p1POí6E.wz]V[UNvjqݮ4_".6B=Sye@V^yI|AY Z@{* ] R)X6 ˲NJ΃`kI/][9kV9\%lNzT 㣚MT=PRP/ K5Il>qõ j31Ӿȴ?)}l:iPR`LA>yY^7~S Xx?C MAWzemi 2nt(tI@Λqdw>&6!NxeB28wv4D ϐ,Xf TǦWa|ca"ԟGqZDwv@sW-U6XS"4N<VlޑܹKӼBq7~yOMAf┞8=k:}5;"#F9d},`،~G4"g£>CCRr&_ " Z߿i| _?c@F/eRhqj 3 'N8A, '1h~Tcr QV^*MVO͎qHXTǘ6~FD \4Lྠ]S]hBT۶#;5UeyZmۆM=s`ömhqt|mDz4\%ut|81;\Ycሉ1x}FH"ttK`=!Ӎ!X-6 K5E~Y< iL hveĎLMC|𒕯p H@ͯՂ@mYRkj) ;,t5Pӿ]6A sI_?aVP'?n4$<9sy a*JnklyecsD^\rp&KIk59e9gKڲi(c\[2&˺3Nv;DT4ZSֆOX} Q Z1mC|cI^/G uO MIcc$6m' >mmzuD8o脇T#sMٿ3D9df8ApZw4"/[_K)'_u;GU\кPMKY0ɒ4]t:Jش9%htub _ lr[MzЊ8# 3:F9cc: 5K)F`%{!;eԦXS06eQtkn_C;¬UL}&Uhvj@zDօ rۖڕ%Oc-Li-0^&s u,yl=gClJCcnjPÇ IkȦa 0zuF3[yzzIJ],scoFJuDd>iLo|eJ̮֊rE~~桇_җ"ʔmDIhhvd ǬEj ȋ)Z_:nQkM?+NY˭n2_D7XFS"]ZQ;̲=CIMȍ߈q()UKZqzhapO ao;=Z&H[ n/гN:uk<&K1ɕ'9ʎˆCԂýfEatJ~Qo!Bcꨎ3u=i):䰊օ˔T)n.y<75t {lDTo"QbMEN,A..uSmFN(G0şC7{ڤ:gG޻ݯ|gwݍ8&^S6 y, :I7mu:<ݑ&C)ЌLt髅-nN"LQ-j4[L$0ݧ TI}ٟOOZkDMz.x(F9k@t#:6/"GѱQNp<g3%osww ~?{n!447»䘛Ӻ|-Sy4Iv$k1EChn̊t!;uFW@Ǐ¾_Jq:dZs~fZktwßstSq~ BRn}򡕢'd@:6cI`[cR03 hŦIAxGZ[ 0:DLg²Z=(f!(6 M*]C>ZcQ2<+5zY<>>R{QjòH 7) asjX#boߺ>i۰wx^XOd|tSV/EsSj7}  4NxFc4FyZ;Ӎ|VEOǁm7ӽmL"9罜vLĮp& ]+lZ5>c+9'wAJ`;A{ɋ~竷!@v ol;GQMs.7l G LE$S^6Q2.F++o~)֘ar#X8#?xDAΚk@mng^9CDfZ? ?9 }=6$|Ŀ߷?~7~~ʔT6}J׹dse҂[ڒRP8fBdJJ-ϱ!gX&h$J&N2_5Hf X `75"7XTD`aUt?ᡆ]a˝4 ^3^DttRvGmL촫 qÚgR52 BM`tRQĆNRbz&QgYOL(FsrDv9z>$`^e/}VOhsrCg IhOԣK@CrYU{LA-"}/_}P'_[U\)q[ݼHb39Ez=ie #4RQMJӧc|9FЈL)A9b҂gjNCZu#v)n$9Ǭb󩸐=u@18ݦ@4+r"F 伯]q2sXf2H?s)!db2QSۦ_<޳S"{U ݇s\>A]&/?6\nHQ\U' sRm Y`Yqm I5Χy;+ 2@B9i4G txԊfJ gܥu i62{U(1#BE75k2UTJH=sirbzX/~'rψSW|6Q rl E1%iCXUlZJPD;a{9y0f="eYfWwڮ\Dq ~&,0жLN s:5[LaQ#b׫FD*oRQh؂/a"wi܈!3kFr~n=gmCD^n6jc<|rAڂm'`!fD,;I -+#U9d5y')m)9mlTY>it[H,SX8s1]= ]g +MI=v2d|:qI֒ҳ253oGynêCj~&3&o)e4w yI9͛R\9^7YĻ_B  [)ᾴit?'?5 &S:m2A`]ש yI5$Zq(ujm} 96jD`/} ?kVZ A4y (mEhiNܑEQ pZM.:t8rtHuc·)cË;է}dq A)e( 'iQԢQ r=GS&rn 6\2>mG CfoDnOhA5p2Ё4X"RFQR%@q͹$͑ ,q]G ˪km:&MC=-'xoGwT~YKw\r=nI]^ZGWL jZQ3q!lԄ#y407CsՂ Mi%Gd4(_?@PqQ'TfӤ%bfaAN)dSm6EqѨ7t>M=*[3dR$a"ZvZ w cNgyQy(AZ2'iE&Ӕ:M {ݽHtL!S@Nќ>5Wfh8Ddt,@B<(09vFӓVUh6&C9$6ic$~p`C0 ʂ 1{A\9/r /G!EՙƼ0ߚk6"aHlBY4#b_yDC,G䥆l]z9ӌ؟A7-g-eYп9N`vJ܎vfS]bzӬ٥qH2՝dMe$BbN Y4Sk@C$b2N >Pĉ pNzk2"?R# WZGרɲedeY~) {ݫ7Pq"Zm9S  @C]JQ{b7eլـ:C,6 5=SkMs`K=(WH`ΡOO^#uyL/ٮ5|xu>(ھI;sv͈)}JI^Oa!L, ]/Ra>sݛ"x NDՂs`St7wVH^Ks .*0ѱ7MYՔQR{UH*zkD&oЮ.x.79ByO%"Wͣo[IpUZB@Mx;X/<>$]v]}o&C$1v ڰLj|{,cxs#yFqR<5b7 O䗩[浧saK<}5QZ 0lv۶58Nӂf4zuېB PEqSKp&?c.s5}IUEbyڳ6[ZzJ5(C3(/(C1$PY__ord]M E>\.!z=mJ"rl@bfHeя#r 9M;4"F$E3),YtkPkhXkRww7@ᣉzj1rAFVGo#`~Z)t6J >(yeጦjÛߚluYbhKKI)qw_ ic0]P{GB O .+ݟm:6nCtu77C[:Xmo蛺 KZ-]M.Zյvl})M DнV,*}R"wBe];N7<<^%LQ8IZ;a] 6}>ob^ڞй 9ݣKZI@.KJuN'rwd콡p7콡^:=kbs hrW I?ʐ_5@9eirރgP^4Đ?p^Q݇Ǥocx".7/By?k7ǭzr]ůs5ȺΜIqQDEo>gV̷<|`u#N7[TXX THG!qwBWO Yy)ssN3wG[- cgğimʌaE0lkiY X"!hµA`p"V%zYn:c ,RbV "N1NnX]W_}>> [,^,ئxlBI 5 &%R#-YYQjxe$Vit4LjT=׈5N!83~?℁::l{_0QwoBa^qg`5D=obzyAIZxP|LI(~cyRǭz ab[ ,QoY;%0}fR۷o8.۷oArܽ*X?tSYnOcCKhh"&Mo}Gwrl:hVڤp@yEZ_˾XR^^_W؛ 5h:By^_Aj7K#BgnW:s(`{='+4aϭ;R2DT|'ȒOMCz+0 mg,zd4Ӥ3}f%ǣ}o?~Q".NiNư%8bS1 +xχPHC"B^łv7[!}E֫84nYZGO½,RĞf.Z[ Z 2:W{pqs,ݴػS-$X"eZcpYr a=QVA$h5hSL02fRZDE ȤvT$gGG\'\.Ƨ1 $6!Ǿ\!%9b؀qАԳF$6$|s"g__ǟ/K1<m3kvOʢ@gvh .K(!/E\2 V0ge))z(u]'Iz}6!zeES]JC_I)R4KRÞ؀Mu](׫jRBAN]:]ruW,<>d0~F #P+_zD78Ȑc Li!Gus\Eyd24[6 A;GXw{qkB@Y!蓙CNX#QrZ5>z X9Z' Do;J~%M9 Z9f|8JSm.^! SƎ>F~EO~mXCb"VSC,G}MT7a;#-Ak*K,TpV &HALH1m]pə`z SwI F',iɳS-ä9>G1R\|T@O/:6)F8kBܕ֩iOmzm#Bm(|i8VDRޏ=% OLF1"|_C4'*RNbTC5tid)Sd)jFHmG֐i7Ɠn`7u3Iy^W7w%ˊM.!H(#0$E#Y8}ON'Vv 7ĔhZ 5ݛR!fIfN,i Ҹmh|uGJIy 68 WGL V?.m% $gXsˡ\CKl^p6l[۷o[G}W^+x-^}^ƪ𨷄g4fsDP8=|mu">KڎR JE6{q:#ژ/OyAWi%w$/j|E%=v̛{Xl3 M#Gbք >¿]>HLPut7r'LڇLۆ"gjؔ9rm"gc2q><-ryWAGz֘~miÒc]c2*9`Yr0$_:J~8/Xk_˰6G@zcfeX0$JjDjb|soh;&r:u2;P,MMeJ%dM9_i5mmz6,˂?4>PYSONq}KgWv%gZeNW֚  0](d̨֧˺m!ڄA_\nj'Ԭ6ܲou}[&y>mjR[sBX7CaN_ JNs"SlMܘ̔f \Li2X;U~Guo唰t`YWl.{'|˥U;0 tCVNţ^U9kuS+ ?@ao.NSӏ>F*B+Bџ }VĄۆ`}3TBbrtZ_qmr&r{oPKwe #eK'1s ^uI6MHըXɩ;Q(|HV~pgⶅ{~nZK=G*g}BJɶxph+o(LDĮcyF8G'طd9 ]Ď2hRVrFbQ"uNs! P_0;ĜdٳZ5QTLy@yiY$KQU+iэ TXyɞX}>= U ԪRPOߚlYvU }dp⒥>uy1+pCA^zW^-Am#^x||A9Κ#-(`?\xl@ܐ理crFz =k@ξ, ??O|GPD/YCQ!©Ec n j"rplb&;:ic4r'FkkWič|OD0 vf>K|C-MtDY^ܨ/HU )b-ܥawUs)X8jwYܦ*VfgF)iq;kiZ܌>VqvDdWv1'q[8O !l"Y?ܯbtbY/`320cu?g¦kՊ7Ž kU9 *eA._ @zYRf(\ZhlH hgz oDÏݠ\fR O aիwo(zDȯ> @Dex']5IJk'V dDa-[a"8ݨ AlB" kl&B*x :PGJ@D6&=hDdGԙhu,E3ȁOюq\}OeZD7!e!)=$OO󳏐,B4i< tr`YV|sÛpr>˲ 0;.p&GMɑbֵ2Hק'u!xzo.ˌxHNBU JpŌT.ҠԫhӶȄ2D2,"~^"9h J#a='@Ͳ!oݰ(Yc J5EX;I;I|4!avb3[@#a]AHJԪ}3{i)>!lY; *u""PZfWE1P{ӦA衰=LT127l{wפЪ$/eAaYV_#R{ : m"wqHJR j2> oꀮDً:T<ǩ{F 9LxG!3yxYGqDHMW,h]5WV"˽ͷG_zUП>CiзP*nkF{}+[޳Wojd_]y(ncX[`"E5vz.YK!99| GEAd(KSjI\ױ`tl1 ~!  Xe50%u9ه MmջH<^3 6G96 OTBV΢0? 8%9M;y`Ey|GkY20DL ]Oݚl<-0χQPm Jhӣ8= +"!OOOx >3<<<ܠǾn^ 9" QrfrBՄDܙ9V ėf}t}-~?C?4ӆ^vf}[Y+X 6tnoA4}v}6dC0-ˉl}ڳ=g2I4%˻cL~6%::cpN,tț6&F=.&"iZg˪`Ѣu2U m%g쵩əB}⡬)뺛AɞrZwIz+ImDj\q&^AZUzuǾohurnӱ[k$gþ8WA@؞7zYe Di:'O??JQ *zշx܉(OAV$*,Vݛюf6ّaqoa&zzzgCުӳECiXO M6n߫~} ޟ@$a7A2D4*1FCZP?;zAZA5ԈXmr iQ-Fw i.w44wGSqH99k3w71.*pňMGgfX X/O&]>u*''5-NHyR[z|lj8Lg ;AtsoJ(`hl6i1J{R vޝh8(B?hM 0+LϲF֜ChVcFA 踹\Ld*M%{GXc46h'vc?ďOXF4 25!V<>>>g}oiY5!GmD&p5 Ggf}ӟ|i#]-yAV3,eQw$j'L/bc*DJʊ)p-r4\1w/. oӰMF7PO ~l{}̉~00ڒe>@RqoMmۆ18튜 6M9gl׫#4 Au֯vljZDzduG͉Y."fEwM&Eqi~͈a_CΈث(#$c۵{gwdb#=㣄^.h*5p$d|sbv|kfeYfF h4,}8} j3BeK5u\c\'"/w0uxSiO$ͱШViFLb?ֻid2]G|Xws}rLG #+^p`+@Rg{c7ZnXŽo[fjLCCܭA +RG"](Ҵǂ*g6w#RxG\wFnJ{l4A;2N7L7RA1owc1sG~H6FifkPF>-3L6(aW>6+mZQ*ص(^AOp7ƻ.!mS(pS1o?2J\: lcBGUeiX^`kH)>N iGǞuav,(D[^F}}SHөe .Yg"琐3ޣ6ֈqztf{֜5%g#G!s͈ s~':lX?g 4” \NY&ɽsZЂ.}NW,I .%O,)]HfwPOC7uv|%цVT2$Gw_{f̰f>H:jk ։\v,zZ&3Vftq!`701ia]̪嵸`{).Hպ,&wܭ:{{Y[-=zih `Z] SCh"dhu^Qr'<==eY2MzGHJ rq*YU?`eV+k6o[נCMY ګq,CVJV"-)&"+јaBSLcGY(=b]4Bƅ\rvDO&dq >N#?M+?5>y-#<90@)BLE/6`}o2 N-y0I>niN~f|Cm\tC3-qw gO 5^͹ϛ;Rbwqq\@12 \{1KQC8$" RAH {u?"Mp7T9j0)&k 7{cS(FBuH/,Yq?ǔ^ؽ -f^KMȨQ 1J ٶmjFch]Y.؄UsEZf'5Ohh@Ӥ5>_'_"p41ZRv״C=[dz ٶu#VAq4=]AFiFrhuck e+drd alh5BlmЂD>$Rc"jR z&N2h8Ef-wC_}Q|)p5UF9h2+_'Rꑤn_=i&SJX,>  q|ZEkFCSOr7ύ̲x*{]lPk)mxn7,oQ,K X6} ZH%+RŚy߂ܣo)!,|(X@傾u*gx<#x^u44$W#B7֑t d<+LF#PD|mQA7B幜uMsLz%|nȁ$Z@$u V̓ ' K".6~]/JQtڞ5;mbr9#n=Ҏo.549|@#H!5W@?H? ;΢GLYք<>>h@ՌXz# rlx~ꨅEYo~!B߅L]wP6vٜ'GV%CaʽO5 +)FMJ&3&ǣZm5'pZ2M kRN&{@gFTz!:ŞAUi Dpb>Bf|)VyeGMk,ˮ#}&jYeM˂_VO_zujNgf AQmᇱw6]5|^$hC tX k։ 15(<XF6Ilr̾'uGjtQin_ߔX'A?C5\҆ 4#%8ӆć6nbçNTav/6 NuvL.W P#ǵ̡8i3Y Gc-W8N^`t˹Wo~q)瑎{ӓ! yI~&N./䈄uwl@^}IHK4ӳ&H:jx_=ȱ늟?Ou" %MkEIx"/0E@NL+|{o, 2aRc٢nH\k"Ra>&$k'; Z5?v<ֻ猦N\U٩^M\NPhƦn^4#NQ{7i)˟^g!W}=ҚV#AXDh[Ee[uYlh8H%XHH(BuvZt*ybqp~Kbs^ffV* .SpEX=-)z 5mIVȫׯq>׫ ms pMar)ERl29;4kR/.HE Z@h}CnKts$WB,hH"p;_ l[W-5q4>~ "-5 NѴǦ{EO(|et.ދNqZ]YV 7M?ڿ9, Bdۈ7یI m+ )GpaH#8һLn M'm1OED3A5<8HX;seN%1~9Lt)oާrKM6iBdЄ$uy}x(EٝՌf3[VߘSZCRlV-9%2]Yv(T @OSцƅY&hcaH=q /QՄOQw ]Y#Ro}_U|w},{YVE^n*|OB,?ކ={m xh5YQވaL@@qyϙ|mvI^d mTMXWLi|+4.Q J]=k6ZL t}0;d :в棘 {oJ%rw6 ^Sm$"iv%QB6lsD,(!1&}8Uֲˊ%el[ZeA#X]/GX(xc"^.Sױ5Rba,I @z:(%$Z$6fj"n+{Z.͡Z_ӶkӈX ?oKO)i!־h<^ҜN"iM(^ۓ? -.gvͽp'<4(T|w ɯ' Dy$A )섌΍o7HG1 D#llFV@yxعwiך쀙_k 8McQ_k޾}M6n}O/!!兜5!G޳n=w=CF^B>"EuF$_?_֌ /_ F{db)j?n`'CQ;V#.kbkdȫOs?Lhh,i=pERpb> rI؇'rͳՐ^~7jXzm4PC~UZ 0PQ(Gq̸ 2B)vV-x9Z}2A0ŞYBrs>CN,PJ)aswE ||xIJx||TE]?}\ג5 emQA3KYc E31";4{ǧ}C{B*Pַ/žu/0w,Mg!c:"Q1m)OO.XAՈ\+OPEiOexqF!o $h_x6C}{1PJm]qzj.Hb aXwzɠE]mh@;N'.> Y]_ܘד e 3IƜ(#'uBzЗTўlMB=#4u'Va{C3*@~$|&=[՝q\dA^$ p3*q >m@*eY(Yu-DzŔc;*|-/ &7<Ɔ3Ȏ"Nf?938 :7 &_>ӆk ض 7cziB? yWrlDg96#%{޿9tbېϝN%dxUB}ǯw~w۴i6hT+2\I>RD*iTMåQ  g(yC3m-f۾Na OdyahP뱮X4ҨmuQrAdloM\K綫#h6r]q)gFHSaZ;9%P)0 PA9Zq4q ۵Yj%˂GE(.rqڰmO,rWpC,; 3v0r K2huFF#C ֐"hVzkhOx1}7 Y`}0ZGV\_}^L?zx5&S2#R7h24M@DhJ 4Y}H kֈ_SeIMhY|]pI t䱊@K4B !f#Makc7;O)両δlq|D3_?0A!Pk )4FxV~$q)iwG- nv!OAi5[_`9bH"'#rхvΉ!TXXa3 @mM3{ 2]H:<;ݚ-0ĥEYe2-dBXS4  7@0&_jG1>ryzz# ӭو"cvș0uԈZ%P!lK߃>-k@b3R/_K7낡$y`f9;&SN磣ai9zK? .ӱ(hlrN@LnO*oyFDSpEע<io\*Y6n \'\.[CY.nulJz,=cE6¦FC*;eފ}#sCRe]sr%*nxzzBMsV,낧7=VO_gHg, 76qFv2huŮ5k- %OJa5 rt  Tס{|*"*u"1C U½)}19B!R7*fpFf1} NFpvS@ByL7W#g)۞uQls3I9q ֚6Kb5!RnD^a2'gn?0k&&-D )<|,7~o{{l)$P77؄ё|ݱ sB\Tu,؄bX NG5I) ko1犊NjVXU"ӌ!NK<7Ze3鰗E]ݔRFBCyiF-hR;Öl2w0Dtc!"9W a=W7ԫHYMϛ~8${Ų.6t%46vgv[5DC]1X3DzN-xW{Ւl-h)!CHth}DdHHK▿hHqY/.N&iYW䒱)+z!aߤ{ 因' w!p ]oscm;֕],jy$CKHlOW}|U)Ұŵdr,ʋ6:%^^מ 9k@" >m@צՍ<4><׌؄&3猟_畊;HSz 5P)"&4C 8lhb}6# vx\~͇EO!X\;kJa4&Rޢ6Jm7OdO5/Gi ̬0;m3籆k!qoI BL+g4SFуv4펖M%& JMeŬzX ڵz@TӬ5*]{Z{c5$7޷>ɧ`裏p>(W3%o22C5eI=$+*R:$a4UJ3qDF@2 Ώov&O-Pʞ9ir7¹bN&zʂFQKV_::nDPMW88BG7*yQx tLq[Lq!@D7[y9Nz qSW ^V[(4,M&rDSԌ9DXǤ9H;h"L<|kh '=F]x~Qw#3``iw؟F6>ۧY 2ܧȿO NDchU|L8aMe&mkkiw2/wœ 'b`uA%h+M(iGP*),Uvi5;Ug ZTLR:v$8QF@K+tM2i aw,y +ksaGh{imyjLDJAS7|ϽZfQx4@TWBj5 \.BՂ:ɡ ZU +` 7i=߰Z E1$cW>"u{KY/̎c6{LG”Ǽ~ FLB9hiG|G!s ٍy!l^9/$Or!U>c(%əچaDN41LSzj`'C^{'wd 26.T("Dn" Ѭ_0Np#Q> r*@[rjRҔ#Awij|@7zֻ75L#$SBM]v_o[||TQC5Q~;j@DZHWZ rԆc?h\<0݈o`R1ԒR4h0aN ]L:4%RZgޑ uuY\{kv-]XՇ.q39j:9 Y⾵ZCFxL(].9M4 ^-Zض+jk,xxxoZ'| @~g]pꁓ9)pD, mv?sO e1i kPፙ)h(/n"R=P xޣ=~ *!wPw#Q^[:G' [C4N0)8|C_Dg X><%(.fj rgӣrp D?G#]3 !Mo& RK-7p̭{N֊\w⠰CLj>s;`06={VYѪVއ  vi\]j *,Ȧ Z,a=kQ+G`=)''Jr8-bi*?>IipmBŵQuN4͡s OCClɽZ +q_+ᩩ ƭ u5 H!$&$"O _E jsBΚAAާ jPRX7x<"?~?_=+ :U2ƾ/O *Ӻ؝kۍ CV TT ƅ~>^Lk݋Lɝ,`SęӼu]QJm-fM t1uWL&4>oa-ljm̮U2/[k9q^4 J>Dk5{nò.Xʂ>o'$BqDv$6! I;XRVtjoXʂ RR G\`je $a)p(|}{@dD=Nz?vA&sW󍃈Ф[߬5S@G֡|b5d;E1nltiBDKSO\di֬9*dLIY!ÆNXLZvc;eWRE+]Cj5+`Bbh qwv1tf"a4ޥ[0NyjyMG6$ˢidQ>R\{z |3eMּUĭx|&MtZร}l&=yc_Ǧ&()|e:eL?d4(|{{O k@Z/k",$ ҏMH}39qcOrvҫ]ϠOĆ$1$~9T)~y@/3 Cq Ń>C܀<TsMc'!ST$]@Ygq,ks kT v_ha i@Sssݏmm&׳ͺb:pDɁY7esŏ$[^}BD֛7;uu41d9:JNKV3s5-")%O?zk7WOW%UL7yl&Q EO@ap뾔9ڤUe',i_pYﰬKn@3,pPʫ4T{u}%06!M菟=UgЄwWDpZ5xq1F$2`'UP%F߮"ɋLNfsH ּRb = (rTpHJ(@׎zHԐDL_XJER(dj雄89ODwb=&JB9#eDq=e_E p?ze!G1zDB!96!G1=yN !_ fAG^Ϛ\7kl,9:Z>.90w`:bW /p1@4=)ƹg:nt藎RoTk $%Sq/J'v] g,Sѭ Õ92C4!Ŭn]Fr`k&UH >:WYG--LdӍSj4O {ݐeUkGN ޾y!ޟۖ\oEϹ|rPJF KmALVQ?|LUMCllWv\6`̴@c BC)޽眽#VVT5W_wgCZ7)" NS֙pFgCKSj6p9p).[ẴP6:L:ial{c^}_Trs` :ီS)pNNz&thոt8h&Ø?R"Eqb= %4 r=o6`ĬCǔíWdJIÛR򿅓=[dX6 K)q)*SZ`^q9c]D4IU-V0FmƷT Zf2_'jbр hM\DiS+/,Z.VԴ 7B*~yC AcdLM&g~01L5J7L#LbLhD;?DMѕ7bKQ|\z,xE아"I&`)"Tɵ*jf5A&^ذGzG6duJ?DMq& ?~kMHKh6m@A%]EB$1NUdG^kF5WmCb&}l6x;ށLJX~LE=]y6Cr_j"5ȴϕFX;%Vo(b9a]Y g^mO69v;CH{9ܺu >&q0lBfurSuVt.&võkwa"L{c4NQqJ0EUJ{7}"PO"S7NM#s 5dŭ8}{n aZPǠ[ePߥϷ]f,r'wȋ_k"aوDiiyhAݶ>g⪥HH\mH.=pJ垠;gW"uK""Č$H3QtyӉnWm(ҡiSS`Ti eSnFJ#h0^ZWEy׻VPyiXѡH*nY#-%謶hI}M1gJPنL, Ɗ *Ƣ)1D0b,$?nqmCu4 A)iݹ`|Jh)O&H7œt%UPRSǚ sI\ 5L1S)mX=I{]#ƀ)G Q-UϓP\~<m-,m(fdI.hH Rx-Т 5!e\%C񵆎kF.kHZ1jՊm>'~ +xpѬ`G}(-.i!9^ Yy]P<޳n[4Z皜)՗P9CxgAhA`W X׼I&;B2AQ39?TۣׄT1vB$#זDʥcHt+mQ6Yj+sR/.> x6@@>4 $_s멵cHSxjN6G420M<MnV3~![ԃ*קtM=i܊X[-R#zvSC% Xgc7e1-KŒHm W/t# SҌ$sC(4:ůǓSbd59!!`<5c\ba:=WaipT b"-1&/'Fc%1q*QB^P5ˉI|ψxߍj+P_i֒w1Y҃Cֱ5$X^ȇ{rfXCv~l~ך%T: o_{lU^Su?7 PPtBt5ѝ=Ќeq_Das_)f0/Cgu.f#7Ǜ ak-Lӿ9kp|Im2JO)~p8TIJ({ӢSh! ÐP=9~:U:f ;dNEB@Qaou*y1볳SLӈA8]_|\.bчaf1ql861RǍӔz CZoDT!i[W[A]-˜_{ Ativʩqܫ$FzՈKlf:<1:OQbqǩ3EZ={4O5%<{3%%JB {r--b'Db'"zB%:TQ%BW)e<к4<PZ^dTș׶5@23}݈(JAs J|<`X!F .ꚽB^+s2yMc ڰf' 6[-,2l:2Y +w5ǹNPj\]DH$h ;䗁-J?cTdmA&_u0O ^Jgj-ېV>ː%:1MȓՄ|0ˌ+u5#kzF 9lѐcұ!xы>vM]#ERdz|F:8ZqWz$Xw2L*fS~`aKH̸R)-✩DH5SН`;=g.Cዾ#┨ܙv. o*:gEf #"(>k>z$#f ] fw֚]fLq=;̉pqq00 =v!ios2Ho#ƀ圍;pͯ`;xbrG{2tyS(Mi\%4b?`l_Ŕf$8i| KHP4npQΧߥ(9P̴Uձt#ipFP墥(F.$,]H2ҌoxKX1$2=ɮ~|+ZtMh$!o>_Nv[dJE7k{XqQ(Y09A`Z]rȐVےu kñ"DKT [0-@J t^8d+ m@QeB!|&-dv.(yvBEX I #esP-P=bSk#-*Eu fɲDoiV|/M5(0UVPz4hFcwV۱ԀI1*I&*MU~iQZیU~n l4-S#0K*%EE2=RC-M, ( i+-"N^WM G]F_}Lh(b&WY7%DE4ezdj&YE~Wh-fhx糋*qE"vlrY4kI#:)bs-^֬BF S u&l Χ{)lMBQ\ߨiEk$h UAr|OZG $[¤+ђHmLKc&Qt8#qug6@Q8H_/`qa䙕/îyo1(DHΰ'h,6$!`똳e!74S} u'ZKwG0*bp6ƈaDwژ:r1|-#v]sm(0w}>vɱJ͐Fk. #ELIM>_~^aB9d8KMHJ|? "PB#lpRxj$#ƜH4 3o$Åf0ՐWA17F^Q̀s 4%ׅiL!wBAHS"V5V n{NF"ZiRi Qe۬TkQ!Y@l)֮:jlu+ 7KRs!`fDV*z-֊avYEp1Lb *$eʄLLB֢k14iR,UYt\HATAJ^>Ʀ*FKU>R쇙ת4-aR\6Yq^0,¨4(buc-#rR^Dɕ$5D>M@ZEf"H7|DP7yablAy*y`@I֩0jtr"n[%\D6qXj*O\,L@Uې͝kR@yL󣓳!i^ϳ3D`& WszlJh!0ɯ]{Dk'p\BMaG>ǼwMӈ۷q5v^n֭[o4=ݦZ>WrFFKt.A@lKU! s2.%#nݺ8Cߕe A'g]8GSO\3 *CHy궈s<F]ܥӺOMmS8⑔T@'mgۄK {"bCϰ2h/.X/ki4T?ofYbDbɵ[BBlſr,;fLP',:<)ġkmt(nU!Zލ8`ŖUeVP5X@R? 2ͳ0Ddt ȲK8$ӄtM~IcƼ)Yj_ɣ3LńA<rYI"Am]WyR6ciFr<(g.Wsur'Z5tiBhX-!&k e J՞buMcrzeڑ_؏YlT|yٿbN yڱʬB[:nTWf=:7ݚNŋ1^)Ϻ/b9pO459+-1F`ʹRSYe7iA&5Ma4 -@AC[R ;tH(b=Pi;Qv bꥡGuҾpinBHŨ&ds)G-L a+J)P/ƱulMxw37Ȓ~/ ;]aHެBe6Q\`4:\JVWif2+\P qdnl0 ] u}P-Ż4pu2s;d%xim69:Es6!yϼhd4aR(4f}sKzm{OIW)ʷ@vU$@ %L&pJ"R^P aJ8VdLm9׍zAyҶV@! /u(K7\C: fȅ|VrߞKPVU:Ht/5C, OkAlY)hPO5ȯS")֢wg/{ w7*mϮ] ݫ-EEC<ЎcIN$ bD*H,$>/y5tRL ZZB1zE+>h{ s)-m)fX3s 4ubƑ*|ը9[dȬ4!T,Ǭ#A@&Ĥ&3MÔ58"rP4b DmT!B}tXA>[q3H!]E6Lu(%mFL:;bHno灤 'Ai n{ BxF߷B)䁜눾'|Hblă /iGc)Vf"th. AD/Źpuͨ wrt۩Shl&G((pkE˥HF;BP T 2E9 ;-:A8ع"?c);JӊֽHA{ʴq4+KZmC,7V$eU?`^Vʜ 7?؞ cEb kiJZ:eVwx5WqZkB֨W6ȤtcRS._FϺVeIjQMr!dU斾5\vPa5؇.cr r )ʂQףLISq,iR;Ɇ[+qyb5IvURcť@QZ?*2PMVhbUm+4jcv$Μ?p&ui @AXFҠdȿ9kE dngy.\MB B8d1F*^Z3OWp^X ;N?J!V˱.%zTD H݈4;o-BDYw,oWJ x_Bo#h_d4^֮ꘛ֊c-6с[1h6ĐwAM"ye͘R[9\ZXcV@.q1D5P s$ NZ0 f41!FLV'#_)LY! crrRpwl tL}a{:=4ou׮_v`KԯfoՋe=hx6ݐXW:\c ]_{$hK;A÷oDLu8!}t=h#b6:qdp!!wAMS9"M˟ރg4&ȍzܓV W}m#^<;t^Oxnn绡l%A űMh zӏtj;⼇2/Yrua}]vdp&bDȋ83FD)ߏTk=SLHj'!*74j46a"QcX7eU"bL|P[WKSw`= Ҹ4c䊂R8瑦IE* >*"yY)ot:v0m{b9P[(S!qD3%QaReF"5 8X9741u rxW#it k:^j<֊wMsԄ|9քkrD׫_:w"o~< RV JMqcYBiM e;\F:f{9 Ko]TV lY IъW"ĚIv<,By=QDqcRyJC>Rykğ\x}4%$"kYK J%6G}#r@9t]o֤`Bt;QT-ӻ$ݼy37Qiµkגzg)s މ#| վa `XW݄jZgH[Xr1;A@ZcAoYuXMi3i`CS`P H՞6Jo']m8ԓaԴ:W`0lTZ&-.^;YS{K:t 9V kMm@lu"2Ҋ׏5Wщh\@h]ls6WIk?&^SD7o[)Y:h%xKq^q+E4&QjazDBBxf;kJK*qۊ7;]i5 AjD.pjht&I&/2t-FDGpUw1=1h ze0q''[51w8P0:߁:R8+}7(ۻ^b1Sυn%l)Lv}jD%AY$x~eZTns}KЬ! n o[⸪ZUa0e-,A.YW\HaėmR{h`DyW.=妃eu Fpۻ(XօK܀ྐW޻O<oS')xۤCr?"wEgW48P\{!Q ѣJ"b9Q J%gvl1fb]艅p*)Z!HEb`41z$HDK.fӰ[0#y6 YM1DVTYS^eԁc!s4^EZ^Qp)cd=̲~5"(WkJzMqR7++g+1I>dPĹE ] 3' sF٥3{yepQt^<Ŝ;LS  1"=# {”zv[%BD]Ei XN,jNgK,1` i0w*hKy$f2z[[?]t]~!FDf u H%+`PIY:#H2FxmOL"pyszN0Oo\O5o6 -ኈ|\_?>|翿wcDgR L_!5+äh()KXk'j!Jt2$4əE<Vr!GX'd"=6^Ľ0{Une1Q;WX#hNpi¦U2mzXj?+igKVB01B\Kn#r ܞB-hPݼFQDRTgz- , (Ve39lIPvDAMjJ`񙗩'Ϛbix+߸gXQȀbɾu[BL&A5 WiH5!kּKh4 H\hڼABl3takn[kcWi)JB qj?4FK6+Ꮛ9lk|YSp鎶1wǵ%ئZ?θ4=J-EN1,; 2;Te}gLTGr4At%F( Ž*:=1yrRFS nȢ*N1 Хa^ehi1`$T@4'ND-n=@6 LA ~ sBy*d1Ze{s07sčEbk._PA!U*Dh6DUɫ^" <퓮$SҠ?'~sF'|1> E9%5E #"TnU $"5 s, R35 [fGXZ7%} - EEFu⺀IC҉ɴ9CY5k¢6Ҙ 5HUSV>w? j8h-מe+4…fPD-YXѥ A" d׌X*cm]1Hlդ[yye&3ٲj/S7Ӝ /p !]wߘ5ðG6n J[l%OT~H-{cֻVw&2AU.yilW)GKI=ΐ5ąc'ɳf-ڵB9jE PJ`=ѠȮG%؛Uk`B21sN#3Xߵ%%"b8hj =:WRΧ?uqۙC?tY'I !$L1I1'BKl0uqRg(ǀ.8ٞ)Bd 82B-jm  >{縎P2$fov3cVrrET (gBוAn8-wAu<_|Oׇ$G3>wsߡb)6gsTIJz3`=+\q"^ٔiATIBL5Fѐd_UӱDh9Gaڜ]l2̘INqaP84-P^kʖv뉥sE㡋~L.Ea޸ { !}|^5-\mnm mBur̦i>L q<ӾtшM:֡WHfD.;oKTu봕u!n{4ƮWlnx/LJIoDa=Y/F=6W}ğOo!Ό#$^x=&jr8M maL. {~OΉ;(A2[dB84 ru.|mY뜌2HFeT'7=-RKc[7 6M ^'uaF3153 {Dzȳ^hnZjS:ޔY@ɐ);5z]7'dBLRc g,6G݄rzTϥc欅rU\0Jg\xɏ>W9-%s 1MGuFRZe 8F+DА%ٱ&dDw@K}=&_h- ֗=hoWAE~ߎ{k n]؂GI\n^EVEȲ{&,}-#LDГA`=rf\Wuons*exBqC1XS")iF ~^4'!C:ly,nl%p)N=M VH;L*Vևr{69)p 8S]']B=&5yl ߅!:cNqYD(;s(ܔl|oc(5YZ$@:]#u1Y ^ۀo l !MQ֔| _^T4"҄׃w';?uC E(Aq)# !.STWNT41!ɢv1u**E=y9 RP rzcn22rHJ1jO\~FRU[!' :;uP#b;BZB$&iH+onB+)H9lQPU֩P ITئPRJA*n@tTg #FLQ)q<Đ4yb_\@l53Ni~v)gqhAz2Kt0V cǼ;|aO4eby(ji:~8 }w7y4s@|v [!#fd)'g 1=:L.ܸtE93w/HP֔PIxl;a=hѓ$ }9p0q W|=xjugӧ}[?Oj̧~=' G$?6-aM>/0]Ss~Q/,̑t[lXSc Mf+{WK3@A8k+髒¤7oZ,c޵/yfl^* to)KbIg~kyl*Z5NhAǕ`SnIC)FlbmL:ٓis'~t t0ARa-V-QS r$gc Pzm2M ӵktqҧr%Չ,ѽ.CEl|0(ZkcU`k[R38X:Q.CDҤ<9؎뵭C #ua7MCZDAj mcp5P T-_ Nu%d`WhZw粶 =L2*d Vd CCKQkl Ʊ 7bILS~z F'F.:Ѱ@aOeEaR7QP:HrrC!iE#صw;8Rzz»a3eTW2-mΡ*Z/LݬeEI< C<qCcL !ֹ́f.hH,uy]؉XϯQO:<_OS|)|m|=#|^wo*CxLB x -gn$)<{_nD !!f2IIq [ɹܜ\6FՓUr0l +ܫfC婴,(W2;`f3i0Cd^}.pvW\<j([EQӸhq: i Y>SK (Ac,234D)M_--AVcUԠzbl˦+7av Ӥ'UBZ4"YcfcK4%msnVȯѱQ> eeǒ 6oѿ&4FС#gCb*vЏ''Icdʟ٪Ujxb#.QTˀ^1Zn;9vYi9'^ 95BOfTKF@';a^)@$M]lDѕRSbuQ^,ʰ<>v)Ce ձmk+hЮ2C0 JBo6jcx܃ ?9ҏNxF%}˿y~5ȮӐɪ T HR(T? >j$D!&nyslf}!S4Y`}*$mbqy"l 58ZH "k_S 6~ OSaKBLDel3G`bI MMiv|\#b}6GE*S5˗vJSw1_P`T2FIcK8_Z)WHɾq[^cdVZAy M} Y^Fu@3C1vq \z57elv1UBdѴ+]Ӭl׶%B\ Z _N9F5$Kh"(eX4VZ!ׁ+IɤyB8M( zFb 0\ (vYKC@C;}BnJ#Ep1Hlqʢu'C$-ByVHd46eT%je}.;UKi%uM(>2^jCUƉ8]-ƈX vKM5{m(9M!}/g]Qd7i_v4~_ _w|8^`|¾璇iQ~|FN[dD#AWt$B;CÑ" Ҕק <@#`ceJ,nBrT'IG'WzF}@l6 dbJKa3z&S OB1{X) XzUzp]WA.[vfB$ŁVm7u'NXb9L0;q5BR#U P-H;mrܲ9saZ+J[PĎ44!KE6!!,T*Mzv'˂ t:Dz^ZpT; \kLQxnsd8qBZ %+ޱnՎiْJtU#ԥupٯN%\D1 !K1UWO&0R3rA`zl5&' b"xfCG u݄a)n I7pu2*i5 fBD$.F'R6{VZT'Ŋv7YJah9wynK~ac.t*.)##?RFaM\m$Bm$qjCQG4y=fbT]#_.C1Ytfw"rDb dËP?=~բBVҢ-X~NMȒ;ٚYED,=k Źcq9"<9f"a{] +Ӽn8}ūyu4zذZ2Ϗd5$UBV I'wgqQ =.:G1d>Njx\B^du]Ǣ0Ki4]tRk"t~ a,hn!LXE+"T*rx@ 8q=z q2obRo/vJCsnfcruCt Зa4vf:^΃?PI !ՙy%rk/|7ihDwop/Z)eTcn&:atPss4hDδy%949taE{)b؈M|&R ߺNbPXB2:Eo0c#UHB(9a3m ޤWs YnJLlťu>56\,veڣDMMA8>%av>chL)Mifh V!FZMM[E9z=zk7.ʯnu[7i%ՁX$d 9j]) g%4cв^Ia; =^EE^z-}}c;A~BQPרW̚vаG۠n=?-}'~ߍ\kDw@-ԢAun8A8wUAD*z_e,fYǿ50 ߼P#.SC5]oB5+v#p-ݳے4!4˿1mbQi[{x;mFZʩ^K*JП|w}Od}q09{79, Ut9f?ld_-#xԤ#P07.Rj}-::XAyF8e Lᬓՙj]=OU-qU8-1b^ڞfxH Ly̙N}Ic 梅QЌ4q#Ix?uDŽ$|ّ˲>R1)Z"vSr!SY898 8Ȟ2P |gqbvXԘ8@ ~zoLrW/ N{sq%RSqY8N u}%'#tw#xz}uO7>nw?6I?myZtd3T4#+\ 0V88\ӄHqqL+DÍ{$:tU(=f4peqKDeQ+Rn2 ʋsՂ>O((E@vHv{A}C+"oja,cR8pyڢ*iP9GiD,h60 t2Ѕ-YFXd*:\<ͩa Pul 0hVVu4 ۈѷM?%שP->?})=/y x33z44}}{K'*M)lKK{]jH֜x MɝىSWj9aTr+d'1^F1pj^Z_(H;!c=Ol PrTH++Ι=){sn8N5q~$g]fyON|R%I=8̇+kÀ>h|4b lܾ} Q%1n<}BzOSQ_'pl6d89ق+D 1 Y\=f6\h]cn#Ā&0=B$'wd̄Աh m:s/9QΆN[]U6"k_g`|]\vs})Oҽ$u'6%hx 0r42-v)ħ,Eŷ^ OK*v+٤jOun8ˢ-St˦H |aƦӒUii^9VqO=v2ǑuN7I0Ղq&>1bxif`L|qtY <*digRrFdBsXXұLnѓ]kI?r1x2hYkZ~㋿K◼0I &M&p{ŵs||}.7_~wKW eWKZa\vԬw_uffmVhѸT6̅s:/-jFu{li1QZ$LwkVnSɿt0gDSִBΌB6쑹Pb葦 MU4*]ӡZ8(8^Br.Dr3|Bz!WD-)ѥEm:߁x{itvvu8?O]ާiIDAT1SXS{^;6 6À.;pض9?BsBՂ<]aaq2./XV #ڐĐ} ժr)kDbE<{'p6#ۼPɴS̚kM NW9ɹwo%?\>(̜2RD@\͇hCZ"&e5#^:kYe|0]%EW?{t}uO ٤[n_\༡n7[8|| /w3-k5{cMy[Bn>~ϸI~Eli'9#_mٙǯ m #ai\B̌S|_Kx];0lw0`zt}-mUnO4$^ktAwOGEoz\dwcIGҚ5 5|?@#8@ x yrhhU) ĸ5췺F >W.a ͊&tNo#=-Re%f?Wkg==-D]שHUKCy,V-#NNO_~5' 16&ĕoy &2r^<7ٸ+#/50)6Zi2GZVUgBAXFT^&*965D$TP]rm4p:K6}+uIcnHJCK!9JX8IkHDK+}KX JFwjD#.TVCEx9GЃ:){q#' b0*S=r=CPk!4ABDl2tAPu]N=c@r,Iu[V$]ϺiU?='~0 *"`(t*XZd,ꆂh6DiBy=xydC --)lp"fcL̒Ci(@ED}a6znZg@3Yl)Y$aVEX3BA8 S>G9e1\yh֍j-MiA*@}W uNrZpp[m;C&׫hO3 }㱼Sc9m! {|^g[8&GJ0 q.zy_*\v~'~|MXoZD6!t#K_0`ڦv%"ƺPKe 6OxNj{uJҨEλk5fLLW;Rn+1'c*0 |^OyEO״Ǥ Eʤ0d.MJ(hZF7b)5#hn߾ܧZ>fd4rY {j]]eskei {ql0:H(r}o;eO2:A\j^p q̌vӓ3\ ㆺ4"fFd%d$.jgZ$ fS5AotU5^jӰ '퇛blB>kDl 6X RfM`C('%K5:^>f[X\v yIS??o-{;-v?ȱ5|} N'8;=)N[lafi7SA]v7r%Js0Ol_/^}7"yfI'}bHnO{:*Cwy>K0LGiI=MS8CD "0&VQ}Em=Bnhp q9xQ"p[<^6mwx6zjDD`4SiPm ecF$XsB7W,M֊sMqh~n*iXh׮nnxhP"vqI1[K,c[i]ZD,6#1tS? |Am̭ tW3B^CpwKO|9#-5 V0NN899S\v64ֲl !&LSACNSA9z.g~+-=߶ 5 1i.kB=y]DSķ6zUь|%d~LPn4x+D0{_]%ߚ:=CCl,QُTeDF2Vw(V}W5͑'fw]J ѠQ jɸ5 c $hOMp@&B98tܚ2j@9<9I H$] `cz&|ic#FfPp~~EfHK"gs3MPCD#GJw>Cu:nnw(666ݦP 7r(N9?"Cd{oMۈz{}8'X+0 #/tucX8  Gp.HWn|cNݶ\8Vt{iJ׽mp7GN'#V m#BJ ,)Ÿ )7i PymsE3 a{FjjJ< <]pu0R\lm4lΖ0m*PK ZqOqR&,M֌gJݢ ?gg𾈮 "|>y/x/{;k'bo^ӓ\v gggnZ(j!1p 6u}:5HCMB!7}Sh>K'-T i]n\i4eOѩ*#c% &LՈeqCR#i|| edG Uv1;OQ~h$sq\&3S=D)X9bCiH ^<ŏymY7I91 e8 ZϨGjlSzsY+R @d@3NOO v;]wkff{l6[8xl{0NYe7Ε _GeO"x2!2]E3 pp%4w)`%G뷮{ZS:c,FU:+Wmj֬bIAz"#|{B4d^dSP˨ :Fl9;&1d$G&`Y#]!;D]aNF9X4i%.hF!f=_4 TAkHhˁ]WaUbG6M&.. kDafAol"d|ak P{PA, e.!&py)L],/[v83lq 3 e ҨTqY7&S6I<ۿȱ[ o u*{ˮXq” ګߕuAB8*9ӇDbu^0;U%3H;2C yժ9YU sU&mvx3MqQ,9R-Z*H_7>lvWcm6^pRڈUnBB%}DХb_)5M/~|Z)CEP"6x9䣽-جra18 UF Tai9 X>RYLV3JpiܲNlyeߠc0C7U R^a%{^}Auݮ‰qH81سiJ{%)ur ԼL:9j'KMuIZׄL Xw3Gt}{I$ؠw]aY82ZY%T5kyUC{pN'x<_#fLUڢֺ:`q3浘cBK˜~0""K_?%\?8*/NяTN9ǢQeCbun-`f Ϝ$vR|lkg s@ckS5$`ARwNgHƺ]C]#ySxK+,UpM?O|17cE#C2 w=MӸjl1<AbZ<- K|x=|.x]h8niG Y(r,kKB%GibddsYKDzڐ^ZEG2rO+tH-1ú&/W-ozS2>W|>?g m{j2kN`PNX <82|Lh!qʖ^s @='?/.6"KP'`r?g8ڵQ<&냀\˺|4At 3fF xJ_3'PmZ3$<֠6-:[Ss,vJCZs:}-`3pq3"^ϑ=Ksj ̀.7%:k&̕}ҩR{(_:u,H!p to[E=}{|BB.=~S}w>+KLAe_iJ!C\\a3M>ւ}C˜jBk 3Úo q$KH.%Oȴ`j{y|}6"K_O1cctP 닳5[^R`ƅm/9n҈H.~3 )_K-PhM`l6i:ht)~)oC3/v/EH)tYj$0q_c%4Q&15ꫠX`, #?IE}κ*c,\Om O*0vJ4Ee‹wG *h9k {`D`7q^x-iDƬƪEbSՎVz B+g}Y!]Ag2Y~HrҼ֨{;O^p\ pB ŒWs&"if}߃!!(eMBndO>77*`帺'ʄX!d;aUc^|'.RFEi+V_BR,-7;|fy֕NY@ض$VB/1MmB?]ES41Oq{T V.':yrHkDadxNJ,J*W̴@G#bsb}l5 K.mˆ =`AVbgi'D\F%rMd^<#!3 QҹEmf8E/xǽW~y>Y}9Wd޳3 }X({-tS)9 Q'wt]nDm{#?hĕnlF8u}W"58;5$ {|G𑛇tF|6NU_!5тfEkF0seo4Igj炨>өVX;HuO(ѳ #)*%0V6_1\.%*1^a E,dqCng5C싅\(۷ot}BBFiP%EhT!lf9BjhxE8`}ߣ{} nqLv&O^u~6WUn,1ͯte8=&YPpH){ǻ#~z$>W{0=PERIUXuX `%]W*+z5k$F q>5$v4ї}ݪr\[b(oE- 6nyژ4!)&NbmZjْ{-w@Ux6I:/$!=VVЖ TA YI2|P֙f9Wv S\Ӽੳh&Ԃ ?v͸ 񚀽 [RʤQc'ղ>{V)D4 1SF,b!,xEp[fJfvdFM Gl|_ywd<Mɫll8v0m@|6+'RM13#zΥw~ZH&|??Vפ5#'}>g!,yA (S;Űi}ag~x \"TD4u*OTdH>`d;WQEV? $Gܴҩ%X"NA冢b{LK&0&)U$f#k@e$FZِ!8\uX aRQw Nl "]W…Aqq\E.O~T5ktS*mPͻ4PΥO)Do6ۓ3|wYqm{Z]R5P>W&X{v]cCdcgo?Ԭޚ#'~[#24ʤ꜕vk+ޔ! O!D~B ]\`V鹦} <;Λ.`e2Q6P6La0s%"w|@]ؓdt)5-M)T{064 9?4QMV$ijZbn+H%)URp]'S#W {)% Wi@G]^h\A\6{cEHE7"䙔\&vK PSIRM}0L_ K޶"7K_ j(WX2ri\WkuTvoh'c'Ơ<â#3O2C̀awߍ!k6V7kluX,B+J+Z"l(QH(:Vq"s@eڱ[ n|rYɯ] %4>6H%:%PoؼL|P; \WK@jy)h&ȉu3)^bQUf*Z qKW<kl>%gRtj4gF#Ӧ/2={sG)Ǩh81iOjf[nwA6&5Qa4f Dq'nbzn7"pJ\' 6S`$w)qr" ]& @ԓ-&5Dt=}Nw'8q9G9Y9BJz\gtƁ+7$bkiRa{:_53uO9*5"?[C#h4%ye+jU!Vul~E:Es Cz)Y@*j25-c<BW:fT4M<1F]_P$f2t).TłR=|l"rשI97w^]R#U|O,䃡Qr?aۤt45CjVpD3+WFNy@8jwJ"uZkԬGS)L,VpY˸$&+'BDA9N(|$Ia}eF5-K.ȿNT&S OU>KI7uZ.+E7])e,,~^.dӁ) <*{6z)""KEN kliY') ,Mt4BaRAk(Di'By{w8]4־q3Sx؄&v,T 0`p?ij\mo{ʄ}?K_j Qd0 H ?3?C=>|ٗ}nܸQ5lhEӀrQ݈~{Q# ɓk=<_@7#]&q+O,;@BקFpu)vcScsad*\b#h9j֒d}6M Y)>nVfؒlʨ0JjHfޥ}cluE5/1Q5%=}e%݇lpqSCo[u><:\eWyvUQ\Z]L?Šw=0?ZK i+c( ف$Sr^),A:..t>yA߃ԫ9ۘKف }p8|<ίz7"߉{ oxqrrRl3m߆oo~=ynH\UoMv9'׮-YOx;Λ<( yZV%e3\U;H;aE".[`$2h\ѯUT2W٠ɗ:q|xuG2ԑ<āqa^yp1]4i-;xz2+q 9q<3iKܿ-IiAG7ƀ0>f)o0:%8kVCzwźH He,dH5N _d4!:; ;ܵt zt17+J:<^ n_/FTODՊ!5=o׿)EFF'~|7H $'[n,4q*V|~✎JCKsITZttƪtÙm[Pf-vJbլ'HMe_&{XSUy3 !Sr VNfFA4 `ȔPޓB8tէE'PQf2q2龎#5 anSP5(>b7_ȈX6|>_0 ~:a| vٰ-oV]kZ{в&R&W\c(ZcDw99vnO3MWKXIڵ8mklV"sAMs׻8svQ0sU6԰:BBKQ=qBլ5}8 =X tZ5xbk|bR6ǰhJ"s \- |%:m>DfY~HʼnU[R,t K,G{ai1&m LA8s7]!Iu=Yfi]\iܸhWz'T+%|6u.Z9tpkq٠ǵ$Cbl90ͬ ܌<9tWzF_" ~鑷kߊog}ț'6V݅15!>Di9Dq7S0CjduM7ZM;Žr7^,xӅo^л& T8mBr"i6f6P[֏Aaȓ.>v,|]z4 a#"XnH,T&.vC)Xgq.Shb,!g+Y.{Ó2:h;ɻь3tLom؛dxo|C,s@:YS.fSce uK`ZX7u._^5"*|PߎC=ׯڵk{q=ě&oPy&{Fyksf%eLs[ڠ#i4A*du]815]qy`!G)EۗTw8djL ѓpLӀ)547rH4c%Ŋ{KX1Xś1i w@e"ݱ+Lu!vBzX-2k^&z S?LE]'" gHNv.v(MSF3_jy͛ "Ԯ+]Z:]xYC{黪RJ''9n=Ww(6__3w}xg?s7{pG|w}|9C?&dD{Ǿ)ODabž//>s=QQL|ʧ| ==9*/C?Cß B-}|ڈ|炑#dpVƊwלEsil~.0[*UbXe3 l#տJ&o.7@k+XD`_Td2$BWB^1[˾R2v TUrW1LyKi |~ݐl{g 1eD~ꌙ(]~A냲ϗ0M4-A=ӥyﰻ8q@^iaD^1d vBм2, %vyq9_,^GC$\' |2be"3SRϱ`KN4 *hHn!z !4afNb'?p[?ڏ⛞r6#>iHɓֈ7/R~GF6q PgZqˆx8O$+p=$߭VjK*GYGmud;-2ks8!v`D!O=ީp I%ˡ9!7zr97?!ywSЛ-"6r 9j&E,ʕR4NR%9Iphe?jim}d&E*N%rM.2Pal7f% 7F Q35B!x3K[$E@J-gi\*((Ed.iu?Eׯ| э77n!~}=w|||^W}kC _Ỿ;WYC?Vd3 3WFkPg@x^`3,hgdnGha msrՐ]h?J@F*ٻJ\;z˞5eڹ0Bm6eSc[kV2^|,txL!];r05R*bAiZ]ۍvMnyN4*ДsdhSDdzB U\H>1&;qSO:M4!(7M6HLu}a*|]j,e&Nj@6K}<&1r#pk@8uA{o_/Nj?fu@.%9/DO<[SsH͂sȖbk|E^Ӵ\Y"Z7M ?-@G)  ӃOZl_o{QbWT-*eQi* W.>$:~y:4%u3Uk WpWfJ.Li b0.NP* E^őŕnJ.5.d}`S!c EF) ug ^agХ-ptWYPUgתՋ[ո5_oƷ}۷ <^WUznܸwxߨ%Ƨ{u}4ap^җ?/"M?eqno+qms=x _//}ozӛ_%=n83C?c??Yuix`20nsN_)祿?V Kb###5lnaV?yg-j܂wY`U۷y9 z'̠|>4s)R*{ywp(Bf%]”s;c7K.iy%?OU! I I2_n}htxFjRqU]33: 8$D2YIQݺ: ̢5,4e34.iLC5tTFNqmlp؏l->ܸq#b+x;f|0'~st]~]כ<{?ykW{O4_un޼Yc~>T[/ KL霾T|q38_(x1- P-b\DYl(Tl8jP_(gV82#><֤07SA CYS+xYaа]n|0f#g5*n@J_/G J 2Ċ9R q\Q 9i&"J9VGn]%PK> MjPFE E "KW0bHdP4Af)D֘(5fe嫈H~uzs!9fMSx8`!3X8^X#k>$\iTɐR$TH`\3kI F%#4:8Iڈ4!5Gi d8Y29$X _g޿6*NkQ%OnNDAƿ-'@N>m\?Jqn95lPk%m tmDlA ^bdF+P2Ы$[*!lrZ3x1Eb 祬 _ B߸*s i//=( O?_s\tArS`?x!-_SXu"w7x3?>s>9O~G~o}[>(n߾Pq׾~G4++tj]Ld3;_]zVTX)KDo\6^vhL5b&G$d^AՌXՖsޠB1KQ)eK\zlrYg׮,2ŝ4Qw9"o -^Fk^iN)3Ktm4:x:#DwKϪ\4snx<AQ8“)iϜB/.0ƀ~w湈qL}pȽ w'P(DE:|p̙d'u+7t hD [lBKujj$B\ngj/9iV#8vII#-lk*\TԤ&xZZDD5+Uu]؅blwem*DApVw.YIrdt}W=kBYv-d,ih;bDЦ1FCM8FO"9Z}ϭs U+ܫ!Dž>Xv,@OkR!~1F<4~  mD>?0OO]znݺ~ o-wo~5c9y~ tN1M߄vׯ>^W9ɟOOmo{G[[fcxHQ6Y ΢6qi /h.ocdnR nZ`]HK5uC#v'T&%zj껋MTA 2f)]C\ȉً1L3HBktiiYHWC#G/9o65JoB*ͼa =u+۫!5=}ߧ= 5H*;FS (avSÑ"^l7 w89SseDpp<3Է6˄NFb ֹl\BP!dgSc !G? nAi]cL')FM5jn:%kaI3t+96O:q/gpML~{hsߦX(=Ŧ^LJ)"f<-WNVK^#G* )+BqiА䞵g8k yZ!ԡDEB7@ OI+ fTzRhhqE%j7r*mn0RD́kegJv.MXAE3{`j圪"U%IΕs+ ϣOd8i@P$mP̽оBwi$%T d'DøHHIJ3UtJΙR[eafW,Hi~=cy2)C{\\\஻vō7Bmo{R||f <:,}ýP־>/в_+ wu^|'|nuOO?0n޼yGM|U@(͵29WCi46,n[ôarY TKӲ=< >Bi! +?&x_E`MviD.- - %JIJ>AX<;C9V6~Tӟ +Vsn ,΃A5Eɏ #y/ρ!θ6W !M  '6CN9aɀ&pHDO!Áqq=cǒA{$eݨyЌ7jօTk\DCv9z3tӸ!ˌ=[j2Dh-34ved'濃}G`8M͈i9:!0ED4Soojk2!]]|PwmdUzE[UIVw*{% 6&)r':td.-h\!R5MLH,!`̊^|*xx0r~(-pߋ-x_wx#h36(Y-R}W.Ei*v?ji;I']f3X`\:ܩJVʖJxԠdϐ^C?{];:=Y Znm 7K&5QT5x, tHN:e+8j“/46 쓘 Ѻ(5ǒ^B\$սhc"i=|o|lvҝOΰܼy3 0!=#0^΁HRMwkݤaAl%;rdMI1qi7ufSiPJׂot̴b`B eŘ^X>[;LA {{W]lDF΅Ҧ8`,i!'<)OjcOɊW]2A`sI/+DE1ÐY\IKa Yw:f|Cufcz/$b}T^=%Q63{|1tC]QrNnZ_\90)BA3wp~HB69{X uly,$pN{]r^^ 'Ŕ!)$g?i8Z3G+Gn84-]9ct>9"e7,|wCMan8cruư\'ٞ/ďdm"|.Y0)SHo pbpYBC6mސ_OV7n0yHsE a:"5>OCH|ZBe,i=da'-9~0 xNEJexjݹ9&B(*~ 5/dbUUd}M*J`b)hmHG砺=MҖkGR`a-x8ggkW[nޠmn޼i(7#/9wk~'txF:|ijڈ|W{o.XBk_n7o|?0}Q<8??'C*jTrEhm6z׻>dhitxë}ՠ6CZ3 el־':>^8ls)iK/ =.Ӻ(4&:fOdH0t-*#HP1AQ lݾ,%#'/*%Y6_2t=[F9,8.i18l6zy(?G!Y %9"Zv]L %2K\y .;SR6nNoû* JDSgA8Rmn08EA-iRsSDi){al68 pnݮPbF,4 @\ĹcJdT+2l>#'1ړ4pzBW '>qZ=0MO6{2u^;"UqRpHn8ItHΗf))c ?s?k׮a À~ٟ{^R,@24lLJM"1)iCl4Q*e! @&ABxqZs1z}ǘsΉW"nk^{=s=qlgSsfScyr_eKy_]<Ν;ܽ{W7xk?y󛍛\7g xŢ--xDZLIyB...J xNON]uvFcP/A> dmBO3ʤ{:3[n֮6T)V\t`C7O ZPQwrI&[/fͯͅ4MdH]J8a2!GP\]B*md4%Ҧ[%#&L<Y':> 9,%0!Q3~""n)F5A-Q')i0yZBnyͻ^XfѾT ~"m81iY+lM^]3S,64e( ίCEY!1ԃ@4H&tq,)4ڤacM•q E;En}ԱЅ B@&Wfnjf0/al5GPxhcX7\I30oxvXqt[b5/1Dф/ `RnsXe]PQT/s2w b4k,+֕X/ nc+ǡ)߱^X߯͆o{b6m鋌nZ `fl7T!s韎'|x'JXQ/a\-prz,8NY7?uZ<ϸ½{MBfO L*)hck}ŵ4:֮ZH0 7֍uM4wl*iej{3l L^ˆ*ϯ '.OSB6ZLd-ZZÀtj&:>5%0/ )*=Li&̇c^d$[l*3ilX, n Zg7*f~- ba *14+6MzXA_G{c2 h1` & U02mqv0a+V-t,=ײft^P!yT?2@4&ɽ+O~x"?N 0 A<<(n-=ܣG.k`F/, -c/xmZEtdOFt}In{U ~(lxOjTD7in;)W/3>p}}2Y 5oPuq3pyy^ |899}QlP97Dre9..q}}%bT] X~ޠyv2K>X|be_'ӐCnўK ѝJOW:^'Ui@Pfbb`iV3Kvݺ\B!m԰"*}iQY&\8I*'Uغq\S}77ZMjM`sɾTupƝEwȬLuJ)8>X2ʫ`8iJQx]¬kP `a~^5sJR1ՑrY/ʩ%I]"ix0MRcYkM,T ;G@E+L# B9ƚSf4P뫾Q^>@d~(*V#Zw)\m~=6 VA&jV !p9Sa&\&VXjlqq?wAh\z[nyh'')նƊ5;B!{6y4Ó;.T,.UYKWn2Je"1+3LM]8̐R'h5ަs@nC8. NY~ϸ1߰KYvz_j0r|~/puuUh֮\,Op(1&Qjr"n$7syy}nǘ .//puuy!P); ,׽u57D `CIyLDqį=G4>7Bh랥2Ug4Gc">48,׮+ zgM+a޷Da;n iAͅ|sU;- a%PE۔kSL=4 u젆b9ADߢ"߼5? Px 3 戤{Frދnn쫨 ڱWLc _!qH(tE,Gͦl6MH6w-3%LIrJBѾq,=aCD)`~vvRRtmXEv?%tN,>/bqrKkhbfX^"M1XWEs:PH ]'U^VNLzUk"S6LNJ{Z)st[jV'ӍVUR3 x 8y*(]&9Dɯqs` Ġ~K8?9MFץݽ> V?>R[+w. P)n͖mbpms-t~4|(ttFd/-_瀞!__+\^^WiIT&̀f"cw "P h@Db+m b50tg dauS5*L7f:7x1[k+SfY@բP-W(>!=` X&:7*^En9zSKFjE6t6JW-͟t*^SS^~mE +H%')Ʈdbfh?Ay.+e69;tE!`Te8:A1Durxl Qb fѩꞹ9TbyM`G>SL˵4MB"q+-YH&48lqk{*8Le֖DdЧBdi]N_lKR 'Di(t{|m(b@]5+BD*;BtN[4j1Fvt.e,\@ 鳛IN5~[!4vѳVT/b&T:&UbC`NpH::݈#BRe2v!8'"TOqrMB…*ǟAC5)Bv%ݙYs?0e~6b4$"E*%SMn9"v#:)`2l~75x䛬=VGd>{^ajS ısD̙NfDt*^/SJFQih.sU&V/MC.?X ( qk["8__Tw(1R:h~'5K#E(XRKǭLsg,A0`g8rCy,s ir0nN~%j%3D&#xt-hIףNJc'0)^9%wq!< ꊕJ>92-U sv*{mKJM$Lҧ(nI XJ5G㎅oS ",c<.0`%vTT)Ziv.GDiXs:HQ7vHs,qiʆf*ӪރW΃ _Zl2(屴!"R`4@:;qh%9:ClGPn1Amlk9Lڨm/\ ,.4 *PG_[4A]&40%>My#ѲQ[z4*Ԥ o/4M8=6W|Wkk 59W24BZG8~_e_['~ga`Z;u߫^ |Qq2yx?~Œw;03+bXocP}k`z wE'0\=_wR9/͞XDA6a]}Ι1 H"Rj ,  n,)ekʱ6蛋vnlf5/3A?FJ Qa9?tXJZxa7]$j1A[C}t(u4_مQ&!"L]*/][+>؅k5bUR@K:&-|^?seQR >=^w$|L=(XtujeEm08y1sg9[UwӲՍ9Sϥhxö:n^UB]le4=$?`$vGinmJU?耠URxn?zI5C8կv|{>s8kh{˿/0N ۑ1 j ~gO_Y/x͟Nxcݱ:w|y/|_`w3޽{0#inwb{rzH70Oq$c8xG8۾?gs?op}uSh/?=tr+*ip"frӵv.ͦd)v?9xb/ӌ]_|x2ޏ0?U3fҐ#\> o*8bip4ySW)dyqLzw碾YS}~h/u'k Y c² pΔMk^'Axg~( rHJYd)&)Qi^)& ~D0:5/wj,c@nO Eۜ34{?H;i͕`X^ݮ\ Ю \`9΀t\op=45&ˍ>jJ;8K76ZZ$}K"d/(c wʣ&&9Vɦ-Ԙ !tddh].O^8j"%_+*c^T'vEdՖπfs\^dՕùfaϏ3 .@03>wqzzyŢ"=}ز8Ѳ>ap0/)#\=S@gp2FnN䷼36bdd~zi{qh";6-{L!hLiBv0L,q)3=ܺI4_6#'|&՚P9SI*55үE Pf@J%0ĭj}:CK& >gN`O1)̕= T=uǴ1J)wA@֨-q"vN *M6grN& ZffvM7Brf=V1] $ [Q.f3B_ѹ2<MH_gJ_E;&l]1RXP˚/* DډI@Ntd%{O8(֚ z4~_%'9_O?oo%pn2Nx|מV84cs>7^4,ϼ`3YiH57 lW*W?s[BJG]ODY@Rtn`#dfl` l4yS߈OA9yc\{mCFô{XB\,t@RdPjDAp hA j6mMi h1z"iջϵv".eQVΩzq"^F^BέPFl\$YhLۅd%^LH5~EobiGN;*-iǡan*v)cGG\h*SIy00j6L^DԉԽ$Q+eS6EcdDp܅,HXz @nJiLq쭼/~nYE;wz苾;3 8wOW)p̠0Oqy \^;7MH%X؟4Sk'& L›^C@[&_]_7C@f,\av`ADN{7.) hRw\~>hWj,-:ȶM[0"="\Z?zubNt22]ee1ͬи :hą1`}1OEW?pz(f<@dD/$w}'~[ނql\ZO$|}K$fN6 p=&4Wsޥפo3\|^ǫ7d .@ EPn ˧w?[oA| D[3 un7v%vH9if8Rj l:50v bݲ'-_|n`ϫ+<77f{ڤsj3֎1VoB 7kW߼V* L#k)*LbcB5m>IK&g47A5Zg<:ùA],K9J qbRT7Kœۍ6R$䦨W,Y ޔ)Fsf)a[Wr1LӌNN6`8y`wvY0q= : .`s[N~7|NAIff^Ri< Ɛ/ 9lY&:VC 9IW 7 JI`gpI"VOꞂnP I:i*2JT,lhJ\E(}DH]j1ӹ`8qwZ ba:#o;a(~t7zjy]lFAtꐱ:MbiO&hWfub&6n)0nFd1\DT4/{0jTAdԝJ:4(QYR7G(1$KG3V/Cn@o.o"I}]²PGH<#z~:Ї\_0XS Y+ws8|R4M |3VX{br&[;f-dKx!yë[Fxy7m?5R)_PT#u5Lz?њ+.KSt!QD^B G`o09j|)<أՆ\KPMŽ4f˫TާC`diW6w^$tNXE%{d-N#EY)QDZXo g:@fύ%lPQwIXb$b-'L}p*4ᅬ50D]KoFxIv A6K _\9?<hEl##xݸ2 ~@tP"I:d4%dpw6{&O\tϓԠzqhka9n/lGgOHY(RdP4N_o]X޴gSd,Bk44^bDfamt,[+JWPFV+Ot;L1[LlHx V߾Sϱp k8/LnsW4v^qq;wM`&v^:vf|yBvBB:֗?Lx#h^a1y7į1>~ Ay"ܺƻcY*/cU$|oIFPۧQ`#9ѷhJc#Py$s{AI'vNBbnqK?cRMI./:L:?h*@&ؓB.9CZ T'ڨ{Ҫxm}qE-urm+M\yݪF^i*.k,Rjq%|wp&Or)@Pdw\{Qf\[Z̪ĸf{8~A!cH`DfP'k?\NZĔ0xI'! P ,HG\mg8Q"78‘4;F”TH!NBCtD0Q♱l0]\og[RJ O 36 k4l`@3HH )a'5PN9 DMt"©9j g_&E]bqxs&_]Z$(97N&ZދB*#QhhYFVQFE%VB?.+le]y6e5e+wu%I@ LAB' ۊm}`S- f²', !X5Ri3:羳 i ,ET)>j:t괓+`i&Ah9CZ"2K@#џy.޾oU1͟wUI!=_?FxlOKZŻ޹!ob›~ y78MZ6kwxWDjR̤5/m4~?p̳pu |+^;Rrb[ \Y ն7;h)/'|iǃRy1\J=){'`p+ÓڵoxE#7dˠt"wrԮYpP9:H^S_֖>+^];Iy_u#wE;uދ؝RR 6X–NB2{ffDԦ/IILJ8EBubD,!! ;Ƭ$O)!;b=:&/E Pqe4٬msŎ;`%ؕ9?H6#𲗾By٘-C1YgwӕRAt #x U $x/#gԌBA"B.Ͱ?PXbk v*7se,Yu,TT#buXᎫKRj s.)ZaއR-U@fNJ)ƭx;R2>xQVܞ'/Pg᏿f|/&|O1]NEvӈ7NAGJj>b>*|6Y#~A(X&ȴл HVk}E=/sH4><4sY\t{ /1Y(u@^7VJ=XFʦNHck5 X𑴮Sk@ ³e~x}!7)җ{ށw~yܾ&\? /lPCtWx H~|k 09q8\49M"Swd·8c#F>1y$hH$6J5ƈBo*1S}ZC_WW{ia֘mn"4 tز{rj|ʇF74)x56p9Gn)Brm(X􂝽yvBN;`D@' Q)u9SKQ,`Y'viS*)\El>~^a+kFYm su*Sr 1qʮw A1L.F͞}YburB%/[erTb#1FM| ./n4%I-UߧXaTTg1~)t;]b'4lKһIi |5Xczq5"ku-2E,tb`h}bZS9@Ac"qRQzJGL,J&\:mۄ±"y4kLAYTZ+rpq)T/E{(VIZI.)[AI-u)6+虻B1;x)京D8B(-&MeI|#g1Ԛ~2woMbh΁_I\G:_ |0.gTŕ*vT ŊC!᷽@v.Z፬l$nmo, 4^S/iGZ{݄fnN{v-]{]ԬA5~ui'^ڛlZ*!WMyh>%*M:qݢr IXlaJ憇o% Q{`%['Ch]Q]ӳoLI36}LWg~t0' 0`7M,qX4"ڟ"B6"Pܻȹ藁=ΣɫKށy<]Z#$`dzf#, x`65؉Hg`Dp_tu8\!Mp)G "yͮs A"x?6b|"NDG @t#4n>VѺ "%͗)H;,Bwq5 Ԃ"Zx.9=%/ٝLa@_0x/.6%+;`)YDOqմU0Ea@\:0֛ҔSpQiujScd2'XPavV+wU h!^6 F^&0͖lրvװcXH7 > (QbDH}9R{]5qv9ԏzsעue&vaDί%^D5=OIܾExןA_sb_C@v-5f#?(47`> ^u9XиMW1wNkoK)i/С#,Ao*"'AC1 '! (1h S( Γ"e03)g/=Q'^6.,r\(e`Ֆ.jV^ c,~[[P`i^v|ciDT,Z bfզ- ܸ٨Mf!`b/1dD4* N! >f(BR?rMJʿ۳Nzats}νӞ9Y? Ek4csH,X <կ7 譟=u8yIU)-i_F+Qdov>qWZĜm:6'77Vhaa?c>Tx%'~pCu\Z8nL E^8Zܵ. [3l=mS_{\{β猐݆ 9gR^0hF^jqy :6 q19wj$ypz-mV' zF'Z)ɸ:0n6v>8 QԇaPC}!0t܂iDzpp^|M^L"xxx ;;$ 78LJ#N}1BYjav,a0M| Y g\$T)3ׯPa*`9+~EHUMWJnͩLZfS9סыNDS^CNwMvkFŊ̺`oW:r{; F4 ʀ"ܭ+rX#~ӝc0ca F?Zep_9wLLyWft,eeqH5qeol|ENKd nۼ>oD a#`}C[boN_B N(wGND^Q/tϴȷ1ֵ!kUV#?+xoK`NFjmB]Z<)H J2m6Aa5%tdĺ{{QSi 'އ\J߂Oï/O\|.Xr?wGGZfZ5$XAP7\s}7=ڔd2HaajUP5ix]H,{l{^Eĉ^cЭ4mHast>!FL /C4W*NCdYnriң(ӲrҼadnvk4Tx+Ͳ<\eWio 9ㅙűP4;?@6/..)|9l69o}ݏ.di1Ms ,5*Ծ|EQR4P% w]4GDSD|6rhT.V yWzfs#@ R'phJbc.3`JÕD6:ٯ椼9ĘV@DxqP@UZ},$"tt?B;׆(ڏdvPxx .[ 23*9oSOvʼX#𚓕т~=aQ Zay"ILQWdZSMi(º$1/oEjad qsNG3M@s[c$?f3.+Bٱ«Fj|+ 4@3@n./|M:|pd1 uR7_z`ϩe-}#cb: :ͅ:Q>=>: wη>buӇ0FCݨHКJeP!ii후:A:V&#:nhQM#khQCEF\e]$ƟS )*O69D0Du)Ʃɪ-3֩B>Es2p8iP)Qi#1d-c7Pm4ɲxcJ! 49lO6Q>DN3ܘ~F6? ꆥtbݫWY_r}uUʧgcw=k frNT6(SvSU v^&^D JӭHкF+XA&0έ6?q\ Elz{ 7(d5j׻|, &du*9tF[?t_ቋ}n)QM5.sY(gk.*}pc\r𽸃,ZP(#҉P,[qAjk,R"+@ dV^ g66=N[-rf /&@ je>H#?5Q]c!cf .b1~>+V9i.X^AY2dHq<3>%+zз`V膂u:bގOxl0> ;ş]=o!>MFMAo8f%C?Dp'#w *WOTChG*5RܶL`ՙ܋L5kD,m67%ay ڬ*F(ugt!TLerD`×\ 376cq 2c$My6,D rvwޑduY)49r6 :cc;_r 2ֽ H=IuǪhJYiwF bYJpuOc1UJ7F0iHj~1]H՛dv{ѝX][ޖ8!>ԬFpV V"pd]5!t\I͔9M7,r*^R} ,k1rcX~]k0a@,N: H8, u)MD|6|=5e/}l`ى%=Ju:f{x8W~,8 m_h!/~3?gggU $Vq*?' BNK>hJr]ÁG;SKi[ܽ/' FB{,/}ۮU ~FrddMH>xxnvG0d4мBh-p=YU),7%p)R?R m pdUI#|݊F$cO=JE?B<?i#|u޽e u*L3vn :ͯRL <zW8_SًNr<~cAO }^GI4(8Qx9 N~zuoF2DnY(ի8p(C7gfm֟J;(J wu &XQ{$nKnXCCe 6 (|N!IXρFvqCmMfE-5 xEB }j/:%ƲR*m%.ao5Vh[7K|s/&E>xkM-ٵT/y nUZsR2)3z%sаրvdB}t+- ZSC"r>x짟_; cg @2DnJ[?S~bq6Lk)Ãoб ,s$UMf2X /lj1IQLڙY3m)!/tZͼɜLHkT \s_2Ke?Ēƹ(d 꺖kiEu\h-{fv4lw gmFuJdT1F증Uy|i&ﮮ1M㰅ϵ`U'"?JWjk& &k к#z=>K!/Do4q^7v ϹP)e20K:&?`3nꅒ8cŒt"–Ctߴ&jOwnYΞ=B˯k-+uKU(=?}WKNP0LJɌBqĬW*iq&'_P޶蔵v- m~:-fmKE6:ux+uYǏ{nvԺc\c|_JV*ebR 5-|`xu;l*ng9{0H |߸9uSHlN. h!Ia3%NW|' _5z&Vf1#,A=Cx"#x-9uak&sRwktuꆐ%GgA64VGK$RquR$#Z \0m^QrI`41gXX>ٲ6ӓ~^{bX+rSXVATUANn0x챗|Zt訩=+ >7NIj0WKaLGæ0׻o݌#.w#̫N7k^O9& nIH޻ͬK ]Ǵi`E*ԤDk܏|AVӧ:dM, ڹgPFL%L7prQPSe×ҀDѐcf$=7j3U3N "_L`2yi$CEf7%pA37&{F)qift1Ny\; V^$ 8T2!*? MSO"0n6MAm:u@cYv'. xHɷ c\R:R[Π8V7b2̅V%V]f"N;=/P7DDV=uh '4rB\LT1C`=cD`qVؕR ~y]nT8㪑 vt;jGufjr[K[dMI"Gb bꐒJ9[u(hH' 5VBzC!LL,h,6_ ӋdIkQ 9rXCk2|0#7X̌/  "Ju0{PTkld]ZqG JsT?p NTSB_HB$`b0& [wEdx,Y})qX=]S?s #Zkvpw*cԠ *hRTwh k?6)M NXOڗ b(Xr6 eQ) )IzJBHN;/A Ęm8@^d3jӗ-ih:I:Skbc*Hr%RbHE?#q,bC#Ah=˨+ z@0MX'qXR ; X6KY 6ujv;9%BJDj3/eu ^ۙaA؇8@$RzpB15SLǪ+dԟ("Ru]I2˴†YD =|UQrDhY`EIލN_R/PlH#a-苰Dfbo.wJqG`dL"tݤv$nOBvQE<DMYx*ӧVbVc}ttl PsAb0;{> 7WʙRj`֒nBK7Jor-WILC%J )~#p͢W@1H R$NHZ" s_0KEI_MN ?I ic3ctQ[2ݧ:0axodF_7c VNܖfB慨'h҉J';lX4 2X JȔ/qħf5+E9Xy ?>}5.[`uڱ4%{CMC®]ɘ6C =ͼb2S 2JhBkLvspyY 5|ݟm[& ^{߷HgfsDȗP1?D+U0`r]#PÜ*as`۝7%IXl8f`aS (̀jw ۽cMx~HV&kf#=0C0yΟI|ڧܑo3yӀˬe кWYWt?t*QM.\]K3ԺּLOjf:R{ :ݪزEf%rA]s)\ ñSlV\h1Fdo6 ELq , Ƹ4Ӽc )%~@kaК(;#pzA^9F-kT#s6q)#U'A|YO4M/.٭vAc29r)pxXԃUT,ԷL6Me9y:Sfn|+ D8N+8u%I*0ɱOCCI$r)3 al6BBi24轈ܴtV?p{qe-6>=6)HݒMceAy>VC$ :;XWE2&81 1Da0 k3LT"MRC\lɑFu$&2]ǞT+ne)=9fpZr@#Zf4of峱XwJ,Nr\31jXico'.fq15}EgK&0 FX:QFP#-I(H&,P'@u @ <N(;jr";8C"~S>>uMDiO)=ޕQhNlm;/sBxLE>עynIYcC1 x t_oh b5" `v6A\mjG+4tu4ᴗU,Ƒ/f TDդ|bcia6d~ `ݝO]]3>7B|ێ1d#Wqy&gNl"^D)otT<< +< KF-9siHke18Z}'mEqr$Y NͧW^k48Λk'g-J&Ot}yݍϞn4G99p p (sI:Xٽ VfĻw|yY`du#:uGҳzГza@NL#\;F.wK˙1M"R& en77.ԝY7Z3ϖ=~iR4@0hk=|lOZquJiM2娬dlATFCA.|EC2@Uh%aP@݁6QܶkςkM:QbE#}vYXťb'h7y.]Z  GXYlL$Ol{yaڅB^9G:#jvm3C@8/̍:NJUX&$H,LCX_GʓNE,5 Ց{#-H2,I:4 B&` q0M qqpy\ 3M`c"G{R聈5Z!ҋקi/o|>jB_><'W5uqJ1# v zdpqB_ItcA&{ձKc0t R; RœbG#B)0Q\>?(B\xA>"Doxh[6Z![)٘ sȅN  /@~M ㈨яa*[y1/ɲ1 ըfPW*&G8D8:1&$mQNӼ 6ĵpVt(Q' AC4 6?#9 X'Mʻ-zqa^:l~K$NHztMM \uj\ڕIfn7W`;N}pˇ^}{tAL5/;$AallBNHQ4%wIH(`3Ihz1x \n20H:jAoS BcB'JX6T`8=qe^oi\ͪ ksaHԸE 4r1VL OU5;aĵ9G2sȊ'+a4df܈L5Y=LtbwyhJ͸Ai7i=o!&>"܀&.yGɁ#h*ι&~4)R)Id'G'<җs3:iǰkkö8qrN9Ѩ4(BsEAnP*Cpchgea"‹,N5Fl7t%3U ǖտ&K2ey"zOߘř"_=sgYg\ 1F[AP>?砭z-܌sXA7S4ַ0ǫL"x,lrN ( mTllL̺ҚB;Ieo?p0kMvm&RL&.Ǔyac3(Zytt&znoCC'C<汻 މ%0 \ YLGFrFb0BRj𐽭l m4Eu{}SP>&[7l<%)t,B6 3!ݵ|]\1+=D%\٘0ms ?2(.=Oiy7i@Bnj:ol|<5w5[hA]GDŽj?߬B9iݬX7aBI\A9gzS8)R!{wWx153AR[|eTK*\!5ũmPq, F9~0B899n'N_4Ν;v T8w 4q,`F@J M\ ݁.//qoƣ=V74CZ0>uԻ7~T,R^t!! 4(JrӿkcރR̟(DN0֕J)L1XE.cjl*;I254-):s.ErU9z)ϏU"CP׾rWylĄӢB  ?\>^U-n%E."eq֜x~Ծ '*T c_Hjumg`^H#o; v)yh& X7{x7u{G oI}>_dD_2B#>|Y,V_]ZH&4jg&' R6m4r#Z-[`\6cZdbcX71TTMOAL^-'*9q"&`k%p{ܻLwEx~G4t'5"Srau|"v"?SVܵ9h=svR,;hQ4Z86n7n>p3}78V6Q=k0ߚgq 1:yvS,jQȕ<yXjIOp2ƞjCQvZ ӑt$T\A4$ձ:Kt90ㆂ4+M\ > JCֺeMg>F̌y4)ipzrqld꽍YWI]!)p 6:V2$!SDlތ wls~alzYMi%ʏ`7B9T8qc톒-W@{'3js,A.X #g0 Hw ю~$:!uB)%dѤ$eBz*wt@;r ; svׄ{ 9 {0j^Xl³Hp1_ 7M|Nw4>-oYVO#)779kp4ts3c"܏{kwYVU݉V$6{|R5yIjѦ$P-&vΪ0*Rh-iƵ_DjN%88)ECM1P+`iNȅ{Lb36ۭ$g \f Xz?"a#=qquݹz=`nt1Ӹ|k_(;/Y.̥͸EW8:7H};']+ȋvN& w.Mw9QU)E{̆>/XXM?Ǧ Rhۏz0Q]%H2,V}[ԓk(\5rlcYf dHسpMSkW*m`SH-hV:\LaknTQ~6a6\M\| ~Py_\buc[.}7N,y -W&7?g)"P<~|hZl á`^0BbӘ4d-:[5ڢ œ0O aL71%(7`H<˄F20 Q#N'$Xi2t-52Q16?k 9e0BLA$D1V%#\M58 <x񜂐1b$x: < T6xPkR ZȨ 1*aV۫h) @5u/O;:`&iτI>g+5=bӯ\n E;I< :GEً$RMe{nz؂%%(U\k6}>0% 'Xtu H#BH͉Z3DGR#o:)jk=6S'2AĚ/{x;)4ӆfSՈ4#E(^"tIJAÀ4]{7IB1GA:#KVFʾNY24u >,LR}-mHz։3-]wIHN(PHvTm^uT#%nke"m8 1"FA?6&z!rJ= |U$EKHAO s'y1).Tk fjÌUJX:Q,X HA!:n#0*.N'2ɾܶԧؠ΂c_;^C>]xrtGzJq5sLɌa!!!R RNInꮅ=_0t!{N^`?ĽI}H2Sh]|mQ#ۚ(& _M+р_=g<9]'+eԯ td>~@!ֲA {v3q+T0t8'jJ?,< kcHLkZ괘s+hWǬTN tR Z({hJQ)\(:Xсy*JbGX[pHx/NO\L "k_V@~'qCi(#Q֮?3zVziNX Մpw˚"p@ H5b~ 1(bǸ$ܽdܻx9=%ct#  aDt;z;iD!Y->ѳJyՃLBlx#e4 $5?gȺ1rW*=aid1gRPkb d -l]b- !HJIi ɯXi;A%/ Tw\\0z39Z1I q2``gG.s{*@Rxmȝ l6%'$76ۭhE9%fGn"bĽ{M%ن=f iCy;%5D`bb0f]vsn^#xG8dc2h7JXk^Pmx   hmo6_Ui(Z9y'5D<%HLec DJnGQ#.TYckYER J_Z+I_\/ kIQ$;&H<8e-ˎ< Tqh#1sHNHTvBaI^G2jDBbaI"+ +sCo`P^ۀOv _6p ȁХT)k+‘˃B4ck9;r~&VW)ZTvͦXLfH$܋(׽$В˱BЁie)>Y || sSb*ч#No3xd8N1($NYLCFHͱ5֯`s D>b r_?'39b`=0τ8'Oc`F`|@<#ӲRc@(g+HmD3h $/ b%z(zzfB81B$L_LsƝs{'$>|PJ7,BfƇuib*v)vcqEo%tQqJ_32!%k )54k1ᲷU8_EWĝQ~5I9c;cbE@p rUk$/_LyP빶In zwvyR9v\(0BT Ȣb[\8\ybMgQ:+ySujBh5Ul@W Hl][iwb(UhjAk]^^i_y '5Qns.b"FGpG2vi4xeH/bY!Bg+pځ er^7ZYf5iXTJ I$/bIH@.k x\ܰx?nm2F&#Q8: փ7ȿ4z`*H=g0MBrQMdd}~|+8|k!f|U8aMbV8x R1s*N1c2=A3:-liU{ "$Eʞ>biiyuW+}89};/KšqnCvbפMLis؞SD{ykpbuv RԀ'%.՛ؤn6%E]fx.Buζ4˹idf$n4)Jc>h=OIEGYBsL7FK 4"] dp: .S);eb،A:z/c.;!ÊH;RouGu -M]-iݼ삚:[<%janx,_I9;S]#߿:((s#y)Ɔ )]9I"S@*WgͦtRb hȡU䨸$6g jjoy?ejbśUVkN\/r/^Kih%@RFe;#sp|bL(ߛtڲ& ( 1^8kȡ0mZ\8[fmFXۉil6v:[LSnO\Da"8MN>w/|s7`gPA5,:?x WWW ø,cfCrŝ6j)tM7 ˓ ?J3|Uunsb,i$FF@t7lO.9oD!õz;Eכ̐8NPCe{~P*X\ P(m^xUˁT.7a'0톙==( n"QײCzA׭raFc¬ɱΌ."`k&'t +;e%مF1+A Hҩ 1-yeB Ce=nvuZ8'JG̼gAQ≏s I ~RZ -y=%?!btLx@1*|XR6 CTIkQ(W ̚$9I5՝ƗXl|9#ROg^aS` %t$)WKYj<3R0+E 8{\$<W;#(WׄҀtd~36#vF>5k}SܵSKҭi$='q:fαϐ_|ߴ6yZ]:8B&W-.+-fט)yʼ?Zk-7N풭+T ]cg7g$-։{2 59bsHdlcpu0 %OB 4B$)Q Yh?[ܽ{;qrzh)1&x$.1|Lpd5ZwhkP#K>&>1-R6K2#='C""FW"jZOd| `[\eFqjk}̀*ž< wʗk([*wY0-UyV'՞nVuAlP}'̨y>.i-(9 N-J' 2*;y p:1 CMÔ*>$v ps|[+ыpMR%>$ѩŔTPS\9:>x%a(YS$Ƃc6&}@d=`ϣ3hK~ev;{/^#6m$b {;y)Sb:=~C'EEΡWd=t$ſӾ+GXjܦ.SPX^fx9 Seґ"aR4Bv5pwg>̑-ts 2mɼBNnA2OGxLZhzzMbaʗ؉e՞lkm}&<|w~'_Œ'ye@I@?1&"A+ >xܮK)am%lrrN'^'I2s ֨b b\Ü 5Hɰ'~4a)&I*o]IC'SB4JKJ:y阃PDプ+( ~l)frJ'[YnƱ4Hw]1 j40F`zL%g-5e6xL*Ur]Yq6.b&1޽#\&8O:fF;ֺ~($kċ=tم$J&EF'RP+u?{Da3]p"ubGZiܨhxq*jy#EJ?&9Tqq׼GF{ 4 *b=H*AA;-90BwMfA\8vιšb`FbYDsJ[vc.0Y$̽Xys1W:cu!bCH X*2JdrX@Ni siU6d5.l,vqd)A@7}(!VP4C/Vh=UoNG>@$ӟ}-Ws%p^]3y08p`8!8I38DyW'!f4sh-s]C3{A+qJld(Peqg BW,a7 p2ᙻvOxٙdV3;|NBNE6#f7O68z|_M>?ՋW$v̮FM^WCPWZ"3+FƑ` уpwyqxde-Xn{$RM,qVhvvb!cUIDATWE̛EJj(Ⱥ&2%{6""s{?LGy;_I qaO&;_~N DpBѦiDnFCMOj]k,iTA 5Lmbȵ#a):|iV6J Ϩw*Mee;1_ |@bϯ#z'If`fKD%X81^ڀlPÀY~) pdnI.Ooi8eDU^]&PO޿lԭU~;H)/܈n? bī Kp)JpB~_"G$b#'x;]bW;~@@@4oLŇ1O{!BJs0PHthn.fYi%q"9lY"VYTnQ5]xށ"AQ$uE9{-"~y@N(ђ9^38>ڵLlH7Q~}]<:?OC  UqK@I)#n #< nʨ-Iy˛lP)bHb@lTS8Ϻ?I@I,SYWawi\Wc<{%җA^ӠI^!Xt@n3dG^|{Ň>VM #$~U3LoD{}S}ޛj7w+Rժ~4TOs:/ry͡+>5h$!ck`'QI8:S`gVX0zm=&BD"/l4PMw-7a1Ϡnk.Y4i 9hS1L/vPR1Dip}+? 6M7ec5bTa*8M%)~&" TASBǹ8bMO38g JNHvܜhYsLCД}|'WgMM"C¿~Ly|WFndt!y2ی_ XqdTo,U+TF*ZHS*Ǭ{qI9ŮPـԈn։F^Vo1vN^7"zyNcL mD'*+'t ] L\:`䈫N:zPaGP.XY Z(&kN!?i/σoi<ԖvpaQ>{WV"z/ ;\ό`vt23='Qan""d'ީk KĽ7wy?1@ gFju2X-h_'LՃ =dg ;%p^ĄGNۣ||1SװR amMHt%ˍ58_q aE 3O5p9W՜=Ƴw˝PGnF't$&  ` BFq6#fCxw ''''''899^W6@d߄dMnHDZKu}B {dL?)kS{y!|q7]Ch:_[RK4E5AkS(f̹ЉKi;4$4whK=0t97rGJ_p4yi(Kav0WƉ6I\9) À0 XrxsIRL;i)tFUpoAS?O;0KTS)qYs2kggGl300 1BH,@qݻ3Ww0=6쉔!nEVֻ8 dgF7Z#+E(CubFDmYɛ Z|r+KѲ<{F|`hS$d:(QIUvv"roSsaXYg.Ջx7C7Zhmt@ю$N DZ,j7BD U".XXT\a͇*Ƌb9XˣtdJZvT*E9ƽY#|aG/=piƠ@w |_?=WAL:~4@ =;n / ~NNaZ縸@jR\. BL\b;hYԃ#0Ϣۘg`rvi.ϝ X9W&r>P2B& RTuBFuڌ'1=/v)Ӑ ɟK:&p=k;<yb;u}}OEߋ//\}\&|bɇ;]9h&Pbō~ҬR=y3hPcڇ6 _-mIv,eY2WB9 (sLZ XQN>2@CSJML2vdWPG$I94H9g$;e7r/Dlpq8АKT`j13t4{k!my/fdze}2d[SbR)` 1 'qS @J5Ð߇Ôa2k8{&I@^,g1+|q3faJM4qiF&5QE8` ޏ^pqySMso+sAtz-RSB>8'6Ѱޔoa]t29Gӫ,=HL n*}HKDwkXL39M '9Xgϰ5OFא(`f:Ii&n8a>`F0%Mj1FpYn7;i0Os1G~lį:!IVZߺu  8*U];@̙Mip꣞źMxddctxj/C! fշ=7Ѱ6 nզ䡇츝6JR-6OMWo4[)z_}6Fu|fϺ/w#BGXsf-ܤ͏R*S)cgʰ+J&p7UJ0A1"a),#' ebRvL(NQ̤M͂ FU昦91U>OwDpމqibLZLk_L.C@9x > esD6qDLŚ8;8pΏb+Z%P* 4ŊtgsHB*m`XseÕ0u^J1~D א"* K0Jֈw)_aGF?4ܖo3cFȏi:9OIRQ7笂'#'nSQy48m +}IS*`K1Du2mMfLcY7= -|l&1i3/B|+,k$kiKd cvβНQQ542ZT*Zt3 80$uD'I-4]g,dǨ\O:M&ۉS \fv_98UzFSՠ"53~?o۩daF~/'^y*nq\J.- xVhϫ'q$;Q0:a"d# ^8 cc:u) exM)\\.+{d\NM/Z"MpQRϜ+^emzS/mw-!/3nLܤ9YZW>HYNqOwރ U}ȱĞ?i_ '(:q.5adlF`;epF$SDqoǸ n-a'zwC eaiB"$i sHZ脆E)e0pa+`EmLR4Du!wmnݺuBwzmFٹڡziJ&'6?^3aq s~h>ݤm4fV |łOZ)B S]G7eBwwx-/,\kT ڔbCcf$#!\'Ţ=/Dɲ hD,)CJY(Y+5~pQ,X/f>USa|)g!&AI ~8{Ν;nkڻaO0`p.dK;xccb\XQ5*Kj۷oﻳ-:J|q-sH:?6:? uTC~^ӐiMd\ CNH65Xb#y TF'RNLr:T +5+piNX1z %xTJS))407[1sr_*adBN<;cE/܆>KwR( qrdTY^wN,R4 iʀ e(OQG8|FՠH<4 a3cnK/8abZ߬ 3ۿ3RZ gOnР蟷gڐc1~D>pw_ /WraN5c& xbv$c{'f٘ KϊRЫOd?~ ;np6FPmZ&z`^YۈT {.*ᲕuW# {lp9-piM-΁16fiBa՗ X&R,B-q hLdU#\'vP'[s;P־O"4E4/fH0dZiJ_TŎwgp9%GٺWC_+K>"xW\aAE9&Xʶ:b3D2&Č rRS5+tv^fǒq.\wh >$'=} o"\ ^P9,?kp/_1]MdhDN-WZ"'dK.τd{}SPMPLXc(%lOM(' 3 K3"CYTqEb _y'10bz<\j, NY"ruz^#1b܄*MkLK9&(EEZ>(G7oLjmchS?̬S#0lXqUw8wop|#Rq TV$y \9]rC|bַd c}d}t*Rצ۰>D ތ!JFN#C{bADh,#"vWiA!-̳z.  K@Ij/̕;QF26^h%]+]}-QJ "X7&W) }: GtWY;L:t9/~qvy|ɋ1O E6 nKTh`Q p{Ki&xLى3'{TY 4:VB+v2F`6(ei$$( p)%}B@Ɣ~qr1ˆ/2<,(]mB6 ^җkntZȌcEN\ENS;:tĿ{#>3?,*Ӎ@ǚqZNjp> &{J p7Du#EݳrXbz@ARۇ!Q<9V@nv;UA:~Y3sy+RхQrPMn6n\Gܺop;w)׭:d7*uVWb,+M˝tz@p{I7lh5ݍHCݵuB:d ,awuKFP̉lMw3ŪZ֨ڷh BrξEUsД4 l "s$qPҖrC@p^ĹBgMva0QF:J9ظpǡ)oVՍys )+{lnӢ'U/^UX;T\'Cd03};~9Ӭ!! /~q5iSx|? Ǡـ!v[Ji݈I%bD@Hwv:KdJxs-^d3Wq}te悴(+HwFXg1B',?2/paА (Jg]Y(DXͩރVĮf"z=|5 m/>ݻOWI Ϡ5fTYMaSQL:+LtAUS3SݦP\lmbz9v >KϲLG~7ވgLlNe%9ULE†q 0 XcsZAιybg_Y#Pi19HY,I엇/j+E9ۋ LE"cjQ Fqi@A.R2Tcnݲ`dg̎YYPoؘ]pyFz y;ߊ.SjX>ə |,{qywEۡx/7ڤX\ X&9KhZ2 &u֊fc/úl 2> H`mŦ4HAd 6y9;w"*

^菺h-jH00d!6#^Ƒ'6=*3?_(k<~EZ_ThZk‹Jp">Be-wKV!Vn4^IǹP$(!SH kpa{a7o0 hۀXEAwNDx+^??""kh:,}K|U#bSHߛ}k?~׮' - W=ǼbSlz*X˞Xtz[+a4rGBqoX7AQ ]:iSϨij.۸Ԥ {߻ i΃ +Nh{-wnCǸ/t x >˙wMmұ?* 2o_NFA_Vbڄh#ki_m6 uOi~~Y"kzYiI{w&>}n]tB^ nϼ3) tPζOAh:E*ğ);cT e /ʞEo *]fqQeګyLp"猯D3?Ly8VC9]A\T\o% ǔ~&"Q\i9Lf 9S b70qF "d D=L!@KqtO\B{Rr-g?7t?&8M* ^QB=rj&C<@s'Wj[H:JLGSu/Ţ_%ZjCՈ4#1n-I( Q[>iΜdu4 Wg4a[P1cϩ9qV,g.rG}g+fzBrԦTt*'HfZ^0X4T>obt> ¦8!2/mȐ<`Tj>3u%Jwc6@O829L|m3Lsls[\*^y??w"59Y"/yKB-h}WwwfW a)gHhfu(B.$=GviJ*J?Vͮ%4E \WI=Sr0݋w}4 ufѐ HĢ*F/=MGv"lyc]@L6GJѳAڣfmb7{[ZՑ;Qm*BMɮdM^TLתhNHlsE(Lh3t C547farJ@ҘP; `P.EXK{d-.W!_$I~p \v^CvSءhjBkB s9#nAn")8Op(wq1 qHGB|` ĀI5x7#֍LS*'SoY` q}:1'MRck\v_6Nm^??+?Â6džCCFE64D:6Sh{ZX@$SٰhA3z amB7m_ Q4Նn6ȷ͞]sx?< j X8sFDvREt=*b"f= ɟ~Wg& AQޛlTDWֽ ]lP^5`iĝOn؝lVB-S@T D.4}cL]+go`Pl4~f+v\&r%Mƅb?(B8!!׻(D~BI`l6<&WR^+b鞝 Mב\֑FJ[͸IqYWRMc? [< ܭ1}Dz7v.;dAE }J I;>! )ɍ^G矧aΪ~HY%#pmBFDw "&TCoWi&jmDACΗMܪdoI"%Fb*Ң%6D4'ͮL87r~zIa zX)=_,^ZGuݚCTqDYЧ SC|%/A> 3HMFk-b 3KZDsa:c4$9l=b]Zr&9 ܆d yK^\zmB=Y/C˥W[j:Lszy.,.@R~pIBM"IS.! ͞D2 Fa;2~/pPV6ͦzEBs~g|7DCzi !d$DZ=G_ev(FEE 2+={Ajl_+QbM?26xc=Oԉqƈݙ  XGsx0@JSVFȮ|N&zD"Zl6#ݻFd b%aemhxGI>QY 76qAݭ9ks qCas0>mkҠ 2?bH 8ixjW#{8C߀G_I}Qt[dA(ds59"fo۔hv|47o]8|V^uF/y"Z)ɛW.;S-l'MN^}_y^kz<GYe_.V#h"(O" R>k$ TD?Ddp-~2#ZXEDlqآ":Y^a<类*=lm6rC. Lmfb Ұsp 4^+D?$ďf8xÌ[aрhF],fN-%JYG^MozSN&DkFľn 6XȚVO<~g~9:iy=NtƜD׬Y&2 ޟj]Um9 &&7fg3)0+%v|uO9IeJǘ?w]_Ai"aN^<.֔ rӜD)@MnN[nz6Mr9J 19#HSUFbS, 9yI}pCI {xsy Уvx{zT8>mn΃WBC%m:W`?mnmjApa/k>d%״D`bK><`/7"yRsօ*9y#Us  %ɯa]N% x 2b7rC:/vC#Oo av\!"A]qtRV+7fR Mj+~UNgT&,o.+IiL19ĐDIyvQPbu2:%3\ }mbiO?3d"sU:V(D(NC+^9H1T`9{=`VHn vsRCՄJHǂ [' qkٸBaY8 8`fY•@9Ҳdٻ]h+‡/C׍@%Ϩ4,fsMD+ VhuWsGrz۷+4Z)Ǭc͈^ڄhaݾ=8|;^د* a34#l9ҢJv]Oy'\ AΧMi1xǸpy ~?y9Zh5z,KYu=6ڌؐB4!mDDxK^O}9˶Pi0]v"V2&DU?uGQ$I{lЇ0@ q ): =...p U8|e0ZfLP0$mm(ѳ bOb\\\+p w.=vCuEQ;>pT@4lX8?bq7]gwR&) fmb)$ χDrX5FQv&h@cV@a:UFՄhR8:SU(oע*=B?pz\❊:FQj( \saVeJk<ʵ(X փkYE絅17f=)4aFAzޏy'G&9!?6W`CAQ`e;O,?$٪kcBbF :U(R ϫ|X2 cu3vXTNk˿Fh9I{4Xa^~5sx~>\K.ff* a&bKBb ĺ\ >?Dl=zgȻnJi(l#blom3>3ַlDDQTۀxsbQ>oK!;y{4H[-=|>lgNs<₎Oԕd!gzU30SsоCoܴtBl6fO՝Ŋ8߂Ndc]QoBoI M {8FSh)#Yl׀q~?+kC5*Aa4`UA(ƤFW^nos?Fm[m)؜7UP?ezw't/.XCB@6[?|~6 F6!ιEj@,'No5g[.ɚmMu bk$6\uXa ?(:T1}z~qY 0Y1 39VTcZ2vgl02:@+df43 R} ץuRg$ G8#ڴwٸ}r S弩 w7B{Ysj GLQ67R1 #'=r`Rl9Lٽ5!%qN槺t  ##x>__ JmёfOeaoBFɦ1߲(qJTx$#, KB>%p7rak3h []9 I`xK;3I?fɘ,^*H(pZE2Eqk`GNybDlYPXMnkdFNv( V,7&eީω^a$@Kֽ&5qdG CElN6ȱ@db:г(Y`J5V9)a aVN8F\ 3zXt x?GC|TrLn|s?PFnݴlC>ǽ'/MP_j$c|h4"JRW?8p|h;bo/ - fWeޢ zL-U~s?ssXt6$j6$mckM^Mu$ m:;^.($ %jBp Z< PBW@8hC聆% L0]ѓm^3֛*F_$YrE;#JY؝BRgl6*#V> }8sVuӤtcvI1KnȘC-MafL);9Am &Scp~gRYf2="3pp1̚(AiN5"{Ydh&As#U$QDGiWlrcfsjև1yZj46y ^š)&bM7XܱRP1{5+tXfg&Dlm1TKL4ɕc֬zz(! j˧z0Q^ld\G!P۩[{æ^/Z,oi! "+IXI4O.,\wɶ6"/C lhygl?AN˵zi"JM+* :ա&T5+#PF]\zxDG(tʂx+1ϱUǬ}D棵ibX;ϯ{ލxO~Oq.WY#lv'YD7 LcaȺV7)RZj[Tk4+Jۮ+O8"a) $KӯHe84k<Í>Y>2B*{aMp&g~v.QT01g{p0! FC"i{GlK~хɓh[rDmK҃Lk`ڵ3X; _/-Vz'idtЦ,` Cv0ϣ9I5gfM6J@5dSPq- =["tjxFn<[RCEg ʇ)?gDrHiNl,0(.TB@Y Wnȴ1$&^GL] Ն- 2و 3΍h2m0S0#O Lgѻh|ġc4-ۘD꽦_%DpxXCFl;30O |pA=jƽ!Z0: 0:[ǝ-<<\wZT1JV+nk iWUɁg_ՊȈholCK Ϗ,o?ckbi x|=4Xwg6K"`=jp4ф|~ u8r5f+!k6TQpmpPJ,§!J"fVօ02BgE%;WJ~jQf2xP0=RN 1~0Aw%<ۋŠ|ƨf -AԽ,CŊPQs:h$ c fQ)y *]$zŐ?G) KcU/^5ɬÄDm*gX󿽠'J5jYCpMpZJyՋH&NnM):87 N}Ť#5"EiWYIJg/1' mE$<sWZ) yשlZt(c4Ft"-_܄ԋIB L|YvȔ^( ٰEkbJt*wn,|yjG$Oys:I2ooeFCzRkz Ң6!JҀ1y'Cϯ Ys=@4°֐5޵?ujQcHHs`...w߭&w i&=63!1,4kVmjFlSw&/1>>jq/I5nRܥ-J1Xӗ\Lfm~9&5f qŲ>7^i <ɂ>2ΡanXಶ "Ro Y?eB]M.OڞPepK &Fu y_J)8rɺ\zG}6<9vIXj4ƍIv ˗(i9#DŽ=xuu֕=-a[LL^ 4T4 $?=*-ԠX:RC AK ^D;U x=7x?}"+yzO9}΢*ѠD?ӢbDta:$`4/sȺl(=dh"7ұ㬲y׭Y>nrTMYR5e>f<0gћ8q9Ӯc}5L\8jOev"䝃\%7$Ky J!^s\ k |epigX ^{)iᖛ)1sַcfdow֭[]h}g~f|^3Pې$}M+bmsL"wݴ]8!6a 9MH}'~'bc͈=F4uG9Mfh1sfu'wafuߏjA"4ͮmA ݄61w5wz\T_ 2 'evy$k]YV#XG}EYn'haJ.AЛ,RoQBg-GFс<'H8s@I >mι2kKBN٧E;;Af1#i`chb#`G7r8 P6N]?lտi_"ÌmJsl0 UVj02e*"u @4ꎕkL9,3w#,N'?p8ΪP={YB =//$քeq^EQ ,z6v66B\hX b xsj]:va^zBӴ$ILݻ0,XTK_\^ ]N(-)r툈ߑBV6.qI{("$v@rr|KJPVyL C*?քqm-~.іlMnq=\__k&r(9&!]σK88p:U^SOf61Pa@R0D،).L{l|qvc#cnd\L<[+x{?T%2F)Q4(4Fhr"7$AJ&5+V%K-E ʺxfŚQSӘX Zx0n+A^rG2ZdeX -{kdkuаEb9Rc# Af3b9P] Q_! uk.FO[n4n9墏LϓK#;T)P$ 9DIEnL`"܀ P0x DJ&@[hHԥ9Vy+%όI6e s]!oÈ0"_{x>5F0P킸2|&@Sݎ$ ;n䬏VdjaRrJ#&AKnр TKt3Xf(.\3rJ&k-lWWQHCfXفSf8} jI(EҶH:&ȏ&:Uw'~)'#Rq%S|Z Fk6Hf2)/ͩ GI,a̅]ѝq=ky뽐(F/s3c.9 E,lf@V4CaaG\cuҦف@^B^PDcr3@q%gbݴyt51lԣiMx@{oqyyۄT'&TUE7Zmaѿ"sǐjl 9U䷈HO&6=ȚS1;_}g}g> jz,n{^֐o:XkE03wx_E}a!)i.jODPL-YQlzxhh=ܴ-\bed%%L` $,IA[έ5l#8*jGS`r4NhÄM=mt(03 JGqKbunΥp0@&5b !Bj4M w5ڬ(2U-u(Dc6AÌ>8#^(R 2a ~PRB7⌦4Vf3K3 T,㜩`+;0hDzl1j!;Г%P*ꚛ]Ğ\_BҐVvIe1<#a6FyI! մ"Ih@eI- ZN|Q̹hi>SF* ڱ r~fDq9g< w7 CRf :0/ӮD+CH }R?&My ߘ%pK((Mܐik#ؤZC2G|~,1tK<#m;wֵ!d{ wBC-mFZ;Vt+ZRi~5G.{m]CDZ޶Ys_I eE>Q:K9xt476I7=T~w?Y M=ޟ9;w,Ŷ_`QZnkT5TKT#rs6!d{kXze|OԪ`UWVVwDѣcn6F߇7U̿E_1; Yʬi@z@h֏u̧]n7Q>Kv}A9*t1{ѱFօ>ybbO͉2䓃lY2‘s {,ѯBB559'`2:0n62LE~ҍxẋ) m5g٨MĈIrGFAFJd'3 -8$k~꼜/$Zydѹq*ͨ3sFA4Pvg`wN/d(?U(rd9n.$fhшiN `&: 7:b{—K NodgRcݑvExڙ5T t7n(JJpnZ5BӤgYĈqKb;euyQL;l! `2 /LUӆqõŝR8k~GNJ0fDԬgbo`T,hb(hKvǤbeΓ^ u&Аӑzv6:8~bS$ ^_6g{̲W^Ww^~Hxi֨Y"iZk4MUxZ6ʱ&cm@z5!D=dž77Ut"w^k8о^bTahQk -}~^5wUj5$ Rnly-IE)&/FThT"VGu3R+-RV(ۈu93#QrrZCEPQ1!u|ːs &Z{qL *O4O9M6_! I%E>pE'O1QGsF(a:\LE}̬vl.)^a\ 6u120pClzᄊӔ5=%p. ~#tsuIR9gQv*whx7MO.B\(}&̃:_|۲6DѐYkBnb|, )zKjm~c ꢣA uS"-5k-Y}ek#-s,%/TGإhKzIicNY=t?-6"-:ߌOԗrIx%뉚{MJƝqڼ(1wސRcUg~xMGqR7+ntCκ*Dk.>;D.9Ab,a'10WzHEZsAEJ./H0]Q=\y rP  S#.jԣZ]H)M 9rF`Ba1 Ӱƙ5\C-#lZdSBtx~8L<5=.R񼸾rd&/[1mRD=~u.Đ-k9C΢.XބljDS尤aAT1,BծcY #UIiބΗ&" #x ؛#؅|:r`x3@I]`Ul\r9de;մ4oFLɲcHXTZtǣxjHg b9͚ͭ~[ehy0RbjU{] J2W-, `ِĝ vP,ٞ/9[8y{0pv ScR(aT&e]My$x.G˳dgbQnOzc(5\^^ѲzMgg,⁛ [S6cmH2(HFe[tђNZ#sZkBܴABN!#95ww/AO,=АFF?osbPJQc5oZ`{r;`a,*T9S"PP6!h|h3ax# yA֚&B PTKS .Q qĕɽ)6\'#c6vr%Zv,9R|FubVCm Cm+Q\[gMܾ1[}rJtU1i9E.!ňH]7[ddp8FxykBL" ~ @lWM]jL"ϩA!d&6)P]8"]ka8f%xsAy=aP:bl 4q݊ޮJmfx,] 9A--"Oyes6Ui۪!&i($̘(Mp̟9?޵vik11-Sjb8clǦB,)(Q7܈y*aHa+J)Y\Ӭhei]fQLٱ@RmXUѡ3[16 >Gq 9uR?{衇W?c?ֽhZǚֈ4"=DjGϫ5~oOG}G- oZԥQT0SCB>o1\"3.R=ZWUsiBw@^[Jr0x90Rd_XD[4:S2N(KTBR aaTO.ma:3c e0?0xЍq̉D(5lsalPT"79ΓP͆|: Amb'&tTnvw v}4Eԗb-'ΩP,f8qwy@_)7l3C(s祹$g%"+LBrrd݌噢)+""C&I1 FRI^ω4KڬM\D7qY4Y ɾ@1!BFD._)TQ75WDi,k<]E'|pw-֊%i{d' .UrU.nF}\jH'24%\*.70ಈQѪlh%zJFh2 5oÉM]det'\ܼzvN] }F&@:&=UL!l[W;7~2D_ڀ<zֱ4//S ɚ΢6ՊmFp@n}^a+ךi)^ $kv:9yի^x;yѫqBֆ=TĚ@ivɰZ#"#̄׽WUHuqMLPztϼ˵Nv9p? 1#̙<R5ɩޟ4)DvU[Ռ$º}vdTe2ZE[kG1kn3iX>,]0.B2ތl0Cy 5%*Ԑ,x hzhKybjvS"8AASv1$zivKf ]"-9!){(!L !WI:{"1zb|]a4^H,.pQzń  ϮF-WPqhyINlm,ZdfhWz qkgڠ"! !3SȈL= Fdtgd\]=Vk](\Uk'vl7=4!eS-ox "1"hOY+H]WRRY轠h1%L`τth"|/9ZK$Fbs0Yowi^Ÿ6bhEnŵ}5QX.[dw۷ocEA5=zVn_;U苉(ZCGzH0j-O&B:駜k*9$0%m\gk\v xL1>r̺KKp/^kPiH=c5*-ѳZʗE܄ny&Yk//ww~Ó IkaG+kѱ޺6k={-?OOn-ֱ$#dk4m~&? 잜b)e]r򂎗H.ъi$G&UAgJS sDoF bBQj[!7WW9eFhuobaIfN8bc:aFx U Tcf8٤NkU!ЊH%H Hsph'pq@<\ADJV<܃/dV Fh}m]3ԐJcP,]zWpe糄Շwk&0(ǕǺNq6^Va삙D&̰If^ͦH xi4fBHa?0PaW—HS\iB:b-AEͦ& c'j֔Ѐ0Kϡs29wҴL`Ԅk&H9 BDsuŴ Ʋ3TePF VS.f|caOAXEzE3ĦكhܺF>cm+^:l69e]CC4>7[䔝-CK:[ր/&&ki(Y=J {G ֜D^3/5~=䢇ZY*WdZELz{ZMh%PYwGqP-*F{հ3mch?jCx[ . -j%􏸬}L\T"?|͈YܝBs\W Agꕤ[ 2Υ=87=kpyw ie:0:Reؤ{8( 11BZ8 F !LPR 0I7H1V<#:q, BB} U>*jVn1+0v;;<@ö${W5VY%1l!-/Tn[_gW0/uQGiވT\#>c%B4x,!l9f=2%+2*miW)'&j],y>Ne'Fdv) Fk0")͈HjTp#啎CMPIBS+^FȗE=ipE4/J"bч7fZc\H/gPG4"\rd$0!Qѿ`2cWNTgɾ9 5Cp/*lt4b=kz^:# 8"Gˎ&Rգ8T&.BZ+ OiBy.HUOr *=+T,0$ OD|gPf6zߵj }vʿp~B%D+ru ҿW}?gx4XccEzmN^E\;,Б5Vo?ނR7∛jiKeJkLFI\,ϥiVmGSrJ # Ҫt=/6Q, ʆ2 Y(G욧J%v.(m܀C*ՙЈxE*\B BւB7-l_•\ 1a93{fZ [rdsS)JsQNzX)Rms%ȉgIerҠi} ss]^pAc[\نRö_=z)5"7k8?7`fV~)5!SVی|WYE釃e'~ƤD(+IG~Q/{=,+X_kLъ<,y6 ӣA-quz5G&4)ENz#~'>k1ueQ7rb6k9&DT-5TE݄D^;ZZ^)G|PIN^3pν☲қNɩp>#s6O3]9SEiL4a|h$6C5dg D•Ȇ!ѺđJЬx;"* OMʸ"!#ݑj_}l4JQ eDĴYrD^"j!_\5̥ @򄌈3O`PtuՖL RzD,\whlm] W!(J@a kY /+\;r Jͅ " 1IP jѲs\;qB̒4ks5F#OB@d~SLQ'7@0N.7_X9!5HX9f̏ӄa 8FxW:!`pP83cddA& m.G7OICBАWxsBj˶A!: vV#f66;hjpJs==G*{ H,eĵzc|M#b586;<=Ώ ͭ kǭd4ºea'E LCTYLŠaDJٹ Υ&5(ׅq>+.X3]h=1W|Cl@F`>hŪh]JmPJA|ⱢzL{=.Y9]ꂸJCŞ eQ\20qH,esb)c5\V}^Zp;/2eg!stM;ap8}ֵ̅\rbYY:? iJ׈q,Yr2M]*AgAPR:GCu W__w] rܐu#\NE5XӋQЌ 4ڄ5%kǚ5F m)XNjOx׻~'RsI)̥Y)FK^kJ[R"Lr@jDn/RxssP|]'ʹZZRU;j".K9Q>='=GmtzcA4p8, 1T(8' 4kiviR0gxJ G!&`GhZO 86p JHaS1iO5%g0{x\%õ1GN@)AptxYu-gځ-O:qA̗Rc"'-^~V~DQXEnEXFFEk^>W68E*)&/aku6fҜ|bsr-=% t'VCmbbj\(@SIBԝRԭGk@ o/9ZRrÊ{e@MqIt*ޕAP pnK6t 5K6.T?:1SVhu|.B'S$zd.XuEZ!kuIBITo>?zիN" "7h&iBѶqhݒ,2n]&{zv`lMDrf䜦OCkk/ſ6sk0Ƕf/fu7Sm,zGvRz9'߄OOH*ú A7lև1ƳW(v8E:Xn!%KLB^y4Tz: TB534 >xK^ :%_JNC%oPm1ռ276q*lzrV"/!DEI/M,f@,gX[:5 @A*Ds`q8U.7' QCZTE{vMCXZ]h9H9>|7ɭj2y #lEu00uTGX9[ѹHf(QLabD~MxJ![i0ctcŊPKCiz}mۼ{_ڜs}RE>#5k Ju(<ϸBx LFy2>b;r@)%հD $4ƙt2 Ek&0=@U*.;dS*|5&9va䆪)Zma f!w}F0"6,@^#*PY !zXq ͑u/ǹQ2HrICgo dXN23Ֆ!DYxb<L2RKQHK aDmDmF 7͝ݻ#sǜ!NsC)6` 5=Մ*_%ݳIȥ)x rQ,&̙$7EEѕ$wxɫ6Nz*ByD.r?w(])XL soхkBZׄ㈿M3M לzziCFTbddٿE/W~Wu{]<9֔CEzYkkQ|}l9hzuug?sqwMbQ نZa{H@Ccsa6ɚ7SE!sTSzUrO.J͞Yܣ}Kkr0ٜDЮYMҤ? eXʉ C, Ł3e&Y(ZI,!^2E8LSjP,s3h}\čRĒFi^!Luc7M..7DzQ̓fRGB;nICjPDB@d"U2o@È+3 .\w `ֽrsC= ? &Xj,3 6M46.Gnئnu$[#H19|1.pdѦ) ˄siH![BQ)Mm .MP >YDEϔNkVsIa2lڳGWexU'P23#sɭD,#Gi 5kRj&0#RT~9 2S%cU+}h dH-D8Rc)ނ;m4WńG2{ңbXt~& hY_E_z44RC7ɖj^g|4_X2M󙕫أa?$mѓHPIpMԟ EXF!=ef+7&O[4X9sYII/R YCG=﹂5T}Q!!e׸XkF㵯}[Ng2!y{MUBPr%]',2iQi`(fQr٦W/P s̈[T=QRkT)B.&ZVzшT{YhzppD bcҫr'f1r!0R!Ob)}|ݜ%Ԅ|u!1AjEb Sd ̠bu\U9*^H7! C"b8wn{w؊ºY-:4ּbkv8A;&4n7\_q&d an;һ>+-I#CdBbtpKxNc4PX^r% )z9J]g/ȱO8ñjib`/&YB;!nTdEB p#uQc>/ųǛR c)ۡ?GYf =ujֹ:SMdu!(rߞj}8l@J[ScxшFGjsDZmFOWYI+ȫotKpLk-sjVXJ;R5l 5C^ܪPEP4!9+pnepeoAwV(ιj_IU3!iAc".EfDJ%<#Y5*so5 "gtg@!>4u޹"`7{ :*d@PvJd{¹I,Tz|af~c?ÏpeNNY3h؀%6XiPCppwD3i>x,V)p&R=jpсuʕ4>MC V5-~t7 f6,/KmPe2UZNgVi6Eё766zY#of(մф,soE)S FB;B,J?hH}?QKlsA$);DCs$m5mc&TrÀ Nqq@ Pkvf(9Y6#khȓm..V&vb0XM5 )d\SAA.x_Kx[ߺxBrzXysjv`C=$0ƹ2 ΜC9L;O@ e+q>%[,E؜r"nL{ȹL]oS &sFט !wu:1~,duy஁n].-MP'J՞9;C~,3|xN/p^oؘ{'T~;[lݍU-xH9lٴ[`BN_/8HG8f<9&Q4ZPU`ÐRJx)2]Pj}E^tJMIވ6X>]nuY*)Q' pj#o#lNApK& 9pHU]J+ 2M-M4VaqvjLdjF#V/7>y#ѽDzF {.40'w\޺u2Tc 2}݇گ}.ZkE-u-;IO>XaiƢG:'?䙲=!ov-o9;^jHzn[9k{KZCzm@l>E~ވq9@3Zk+u fcTq>9\ZRk1BQvM(X"]ЊYCyRŽ9$aOt"#NlfK&IܯC\0 ŋ9xܾM15_3^(,6%Ja& es*Jz!D i.'=eZ )_eG\^^Kt\؎` JwsF n=tAq2j/(s,YMϦFdFub%K.0dy (lCzz}ZY5q֞8ם:mVi[8aȊA1Fޗ32,Ro[BtY+9+6!i*0C҇zLLʨQZb6PY3z竜t|9Cڠq*vV6g(K0\*[;UT8{煟htEhs H,%Fל(VrY>˾ގ[ow)Xв! ǨYoM<O ]ȓyyL/IwQEFZV/GdME__#` b]fqMOa,V!H!leaiӭ%jR]v EJ`N<{N=4)& ),%U5W:H%jG'HuCC8TԢ| bYE# L^piڍjly˖%C{xqu}0,wqfITbm}l5=j*]D鐲EC1a wi¸ fxtxۋt6{K FwHe/J"@䌳x G -o;1!2N\|,P 9NOZx6"DSA鄨~?EKж@$$+ن)ћzT:QiOR RL N9(4'QlkN09Dw:' L&3Bx[$%,2 96vA+44L.=iER^79A\^\H6&h7aIϙQ`%2ӸUWB Ѫ6cCj(nJM*{pwAEGZAGU:o5u?/֍ ך|kBn߾oo|cN u99 9}e"̧B otD/wѪsА^;gǜ°`\AZ1Ddc?___ ,cQQnՃuWj֡6ֺD)Gd&14!EJ8\c [d,pT5M9Y#b%ay_9fq?m.+GN" m7WeONnUB ٥aD@'PwydWBnS`c 2O n!O"9<:Y4(yfȉl` _T0rnN Xl7Ef~(HA_=!7I,P0NLC jAЄ4%4ꤢtՈ2WNZT]5̉52UIGEPwOð|>s~8dHԶ~)M7<7>\im3ZZNی5Z1t}CDA?SMS9߁V }/ [cf|L޻fz6kH9s7oGnk:,ǸF48Qy2:ܹBP63N?S]) թLEv=9s*cHu= #qؤ\lpF)ᇞӴ|Q.sF8.;kc+M#(ԀCl9)p%D%C:ĬS# S ̚h; :4 4l A4.$7ۅrs.8ˢMQ=)iyabuEU&Ore!L!^-4o\WYלwiilhKeBntڍI &L&A0,3Lξ8EC˄2MTL QX9%bƍ?Ѷ4ELtO2!osVe` } wo^n!\\\`(E>S}ᡇzА'K:t -饬(_]ЇSY-Jr*E=iV˾ /kk'iYG _o8m\֞kیܱzȩFS_ggFe*\LEM:-Mtq[P|I Tc'k* !&"4FEIi)tez6br.Y K#18"H93c:LtDqL!2!<@Y#1iD:8bw}nC80G2wIފOt"30qׁVy8NשyR̬_΍B2=\i0dPJO/L95>X4.z2s OdgXAD$S&|zD>|'ЀҘRA6I+(ZIFjdӏ=QeI.M%2Tw'v#P0t+pX87B1ƼXV6)iZɳ[M"f2ۈ}AL}!#ӦֺT!]0/0OYӢA&9i}dfXG;I+(*7P |MO+zLKRјu\8Ff_,Q?s@ α6}PK."fx\B2D! 5w$di$]NSa*M0x0^b0 <1S # `LctG8J7&>St0cLrWqmf G-fl=+:NӐxzH1#"0ӉdcwetFir7 4[͘-œh`:1r(nq=z/G- .xֲЩyJU\ܵrLwriM)Y #-ԏk^3 {::`<٠µ&47E/뻾 __~9=hs{lek^@6ъ\]]~mx+B"18p V_n,\/<R&2W y͕6@`HQᘆ]Qw(5]֢p,A>-}gfDP쵤2 bLVz^û4!ƈ &S֜%\0 뽬Uq$a48Idn C1kdZ+Ѩ#B 8f`yIs8Fwffz "pksH' ?= b"%(:f$PaS$dq( VhUJ<ҏppX7"۠$BՎSC)Vz/NG`ɧ-|Сf{&IX;!2(jC`vixp\R7ݏB6y+1,@RidF Ykn?-!%r c ݋½ ˟mG9߱IKS-&\zf:q)jfAP+5IZe* +^f~ g ԟL+k?3ֈk ɞֹK֔k@Υg 6<'uZt^rg{W/!Z]oVБB;"ZkHCci`?sqyy١cI{CdZBe5SJ,m>F uD:myѻpŮWu,vd9Af(0)7T:*xC7Pt'\^\dPfn08l6#vkL=n]\=쯯wqƳ:>eJM$ ̀/5kb\,~ϦK`8WI IU<Q\z7׵ kD8mY\8EDjb(Q}ogsJ1"Hȕ'oyI,j2zZ}ʲ7RЧ3> T.J`nT:ikG+b$jr`Sͧ\3 S^IzBb}3kO̴YZ(W݀фdؤ{g}9v4UH)C` xW#9Cܰ.xi^,l7:UxʰNDx8 y[ނ;wX~ 96&ѐs#ӌa۔rǺ)r*H1g )mw~wo}ItS#ki-guѣeP"r 4t޽hg+~ jV b[uWB2|Y+Tl$쾋첨!y'y`4d u2X_V-4#-aH֘Y0$-nEG,lK~O-S8 rа=Ms HvSJo-6yCkg{}yFt.<r)0yW$V#v|ݻz-b>I n߾ +NגQZݜ ~8q|Ω4}Ԯ8#ra%v( ÙַLm,iff#9ٯߜ:MlVVڼ6Zs3; B~̍ Ӌ#F`nW^wB7'%rΙkiJRQr΋5WG5Vv*l!h[x-SqMIEc57֍,)$\ mR>r6) M#I8/|x? f*Fs'ΥFEn$ʴM8I}j0Lb=5̘^1ۣ5uhPpںHk.lۅ\$X145y ^>F鰆=|FmqT+ MXqJrؿW/Ro|R%7u1V%Ia{=_|>i-i5"lC:9w얏!{ÐBTJYCZ[QXer\=>PXV%DA+e#lxy>$+kb<9VkˁA!u3Ef#ja"./np8`ߥi3f4{MK*A‘'ܐ{=&a%wfB)!>=wv;O cn@RX9LY4P A-\zKMBDѲ UoҜJ)ǑqRH*$*Vz`bX6RL:3O>:Bhz*REad!Whރ_)mZurF,`¯)[*BCH:W<-%҆ 6GI(Js4(})G8A uI^ 3Ez κoL;1Tw <{U&[va^(`w8lk>~10a J1t01rTLv@8xJa} 0Q\Gj5݋=(nצ p~#u,U,Z3jyo|y_FpDCCfp̙v:"95",7eAN\:HS)mJ^SI stqDUE_L͂ V P޿G۶]u1Z{sͽI$5=<ӽxӪ}{Fyo^_D 1YE ?=sPm۠Re4C1zVƹ&p/i7d@ 2I uٚXC!gH5'96,/4X+'$fC݈6"`5xgCSc Ͱ BpӅ21̌5׻+ܹsa~?>ͭZK0¸ZPHw ysӪВkA$)h68͠YEĭڈߌp(BO(չihV5Ԑ!"Ri.n ayv4$9U pV>eXyѥMhA9n "O17<؜DeLЅYMHu5waQR6@Q$-BդrlOb>F k.0oyRݧ ȴ$ErWJ06B8*FFfTmSLC=D#kY\VܮR!wYRDeI؝RsPzfUmE Q 6w]e;Ąq,(O:i)n'Wpm!5.qe. 6}Q%[o@vbRkJ:sqE_UnR$݂;Ċp_ b!p!G fS*T?,D7_9Z7x=W,5ƈ@ŀR¢mkW37iʠܮ$>\2<–D&6&ԧR7FT"]6 ;TWqtd^[x-9zj@ߝjUܞ5I?3?;wbǣ&Xcr ʯJ|YڇX|uѵEFN !c?Y[ 9GфK""[7 o}[z?KuXC1 ?qތ҇ 9?ȏ?Ӱld'_Jc /DZ }9#Ò6d溶wS:} +Rt'U05}]B ݇QA~Tauib p.[`yjc󺦔8 MPFIjF9c*|q!Fv;n 4H1W1e hM;hlZ-$M iIPK8NZ-C<&l~Ý˪Z7-)nH@åHJ~q Zpk (&VvNrc"!5j%ASSEiZ8hM oy>u<԰v!E]Ziۤ<DD$$\}]B8q#QX ݔ"g Xbihh4M5]ιR,1Ba1*y* B!b>x-04HT-GB6- 4B)OH.Ju(i)IלP=EdYH)yÛ8kbnov9C0 9 떹=pI3~}ȢU 7-o;>OODrS*SOG.^~]gY*fk)aXsV g<ք52ܦ y-7|7;;m!=u^i+gQ-{_hӌ,>O;xja%955V@*.[iɁk-XTDWtV%K Y;Ӑ ?4do"¥pZ^9?R:6a87buT:TF|pN)jHF$$ܨXR+f1A4MALb(T ԧ Su^]̇t1\9Gm_:it֛cUJ֒Kֱ?/cwm}t[$X}SzNSM99zK_/'sQ!Kk*F[kn揻DZBEnӌEF;۷OX%Z<5熻rE{;r 6YPxb5|6hnYko?8y+v0Դ{VKJG|eF?O hbn5~VL s5Y)8EotⰹXpkxJ5pB~_U#!Re{/B|g}և-Ek-u{uM+6)?zǴ)k McS$a[VЉߕ u EKI--^,6NlH- N)aw0ʺ;Xg[k@1A 0Xqf\M {'v|#.X] y!JS6ppsSfM:T#Sϭ{q50 skCRPEw@g̋Z-eBFϻąp XaO-.Ϩ ]3oU1PCw+/3Cqyo(mz/xsSRa԰L s>~>FU{&QQx o`zL+ˁ:-=1osﱬo=}OyuX/ I k_K#9PP[?fK3}3)1Zpqdw%7\RrkVH3^N|{Sa3AT.p{]l'Xkoj4CiXn#pEY^h?OK^r~sz/NGլS\BJk~SJױ=&@I꫾ Y6"d4bѶhZ(Zk OeoI}ʽ䰥Zn9،KZ:oŮ E9saq{:Z06= hAUMB@ Tx5Dds"\g 5"ۿ=&A~G΢Ŝh.Pn6MՖxc$a;Rl%u44>T c^)8S6N!b$0 (9c\:Ū7]-%# 5Qݚ@2^tEha{xP(l!"m{qɠaM#eMPmy-`)`6,Υ~sυuApF6:VxV" ePTUvmp"mфN@xPd(+)v?j͋.Lߝ#ObU)EDMy5L8BT?EL\bTM6Y:ARBqPk]fds.C6Bu%v%Qn&Y"K13 w͒ > m|,c8m{f)9wb7q?/Qx[H7e#[-OA- st%:Ej[bp2#WbH&3l5NJ %w(Q@4@s53 Fg"ko/߮V[j,Uh*z*MP0H 5&L\,}=4l0w\_cbw=NV=0 .{^vT9Fq{ge{0c3܆BPhsPm$G$mEn ebWFHu(m@O c`@'yEDJ2D9a-73^7.=bW{˯g~+WLGl <;^>m, eK[Z(h6Ɣ[9IgDM-mkpڦ$+dHRDi]G6P㔆&4,N:l ŖX:} 'M2:m90H n!>յRu@"ƒ'<|S|?>(9Mm߁;w,&/QM9!k77s-y?>'񜼑ܧr9Qn*J?F KK{5#4"0~0Pv *֌5&~ַ~;H="v@~y\~ݴ?QnAiN[uCaE,A^#Rp2BX 2HU7f55CC V;s^T>l)cF@)V T=j^ #el@ lw/.DGfNJj3H*xޚ3y 1J}T\YS{vŰg&C%3 rNk[j:*Y#(%x`^C【6ڴO.{=P ọ/YyR!jC@\­Y;5"€a[W-ʧESx$\) K,K|$ NuU_Ž%ÿN I"4R]`R$DߗX=JS YK2 Lp;tmop](nXX4OxŐ,nP j]N_@a:WVܟy|Taq}odţldn5$ktX:m nrLohܦ195 kߟD'^B`qjx[ڹ~y!r?'|zr,$ _:7HV͆,tp}nh\-ϩ7[B{RzPPKF{Dsu(u|_R4f^UjH5GA5L*$BuhWX  Ϫ9rZsbV=ۤCbn66KሬnĐBVsz\L1yi)P1U$ɘuu1%G\_@;gfCWx ]3Pp")e!JHL=@AbHb*s5$$iDI @x1 "g؛4yn֡8j`îYa^| gY[ڥz_.";h."p^-KAV-@ 5h$ٓC ̐PgՃY ʺ!<:atZtKEͱfտ{M JW \ZP=5`4=ܵP>\ZLIL]H^Ax ċMn6~\+舨j|Ͼ]ߍwzVrLR'Z![[>dҷECրY?j:V2uct}XvirmN z:|7}و1ֽs ߵKMlOzXTdwAmߎʯX\o1>:C5#VoH=Ap-j usQZ7} 3rr;r{;DU ([&ÐTLVXOQ:qNx04Es) Eex\k8gL~쎵)miBztVUntq6-bZ#vWWl؈X +G|qrs .ŽՃvi PyؽbG\\\5c5!4*h72yZaj]i5 ei4BrgK]CatϵQTݸA@yfuRD <&\ @/ )Ayz"huEkHt0` ~qp 29au*Di]Y{41iT](lU{&T$"O\aUYъ\ߜuy)'?5y WtvHQ-I(`fAL.&sW؂kl+ia택>(4n GQH:@s Rs6 DJ4!e 7kcjՒHk(Y6G=ߋ]ZF9S_c=vPm\5{.dIDAT.Ѱ֚&)N,6Tߟj:UO?&YoQy35$fdެ-!#+ǚ5TdsʘCėUunDTy^w|;>:Ժj M) S V$sr\4?wTh* Bөr?jLj硖^$4fxgMcMȺ=hRڻ182J ie0nJr&ӈ/ /+>(F:-\LVJn(5b 4 V 9O}nHiZ][ZSbC$rq8@ AlzAMlp4͝_O`A":iTzV Z#E҈tȼ9g(I_Ԯp}+& 6.>G$,bs\Ԇp/eX4芃ZnƉ di(Vs&U~{~S4K^@(*.n:I[+z A-BH@"H=QJ@(_Aq0JbOl2r_ A/zm*z2!56-au&;pL @onKv캹j-v iZ?{>l6ᅧ51?G_- ͽ Z|ҵN5Sz\zعt6 k[Y>s?__\mBւO/5#XRcDtcM)gC||!UƭEъE5G0}{:سג_Z,:/u D$.nwufZDݣYHf5\8 :J+bThr]4hnS;. eG";}S =;WȈӔd89K4)˂\35޹S5q6J&?9z[`PS}}?$b<LxG~p|FseDi FP% sH8A8)i-G4!8נ!5K Èv'X NàȈr!fPtVHcNcu̒n9kՓ9ckv&m[ e@#F-Bi;LthbM%K(mBa%OSk(,1#E03BJ.)BϚ+c/xa3ZS#80lK DHi>\p씒sk>UPNfܱй{͞lM2[^vwIqskC蓻3*P`ciȼ؆2?:injvǬzNY}/wGt^qw{ǣjSmu Km&1ۢ&hfO??g8}_/|u sDd~тҖ, ~gO /y+zh `10/!hTF?-?'!e{Mֹh΍ܭ(uA5HTǬEs[`*mpKb}K!X wrntP쀃5 d"R%6LQ!"BeaN)[ vPê1fmrZ hVH뀍.XD!-rKve#d!DD C rW@ݤ_a_TQ<^Q~sE{/ MoJ A Pu{QJ[c8D]KSCծcqmiP=~:Z`6N"l;J_FAv' 3?({Mkb Y  ooSO=uۀ-yX!Z/:=׍9Z4ǚs~ kM7?ӋyZ8&Ku[׭07#і^ZRܲ<3߶$\o{;>\q,5!CS:iuCCgP+q3\XbkEm Z) 629O Sk# D4hb9+B9~NnP3)&C(es"͘=z%:Bx~ *e Wssqa,Yh(X9ÚkY>5YԴ+!IRho)_$/Ѵx< +Q, . ֽ71ݴ"΢{jZ7:Ɣ'mPsZo}M4 C4釥 F!*1vW/rXWH]|RFqGƩɚHpߐRJsUi~ly.H(_:Wooln1"͢9׀bpf]dl.‚C&ط%O"p,'\mBnc׻}C]asx?ܤx ]ǚSk1LGhVۄܶ!9y[ނ-*2wZu-}mY{sR8F[ υO?/~}g,@\y5_\N#irz؝;Y)šDPQζ•.3Jο?G:b T(Q1%=Tyk"X{S0AC0*s WkT꘳B@ {=AԤA\2&TѽgtY7冠etpc 텡{/F*}ѓ5q4I3b͉qJuezx[^<6h`F\(RDZ^/ Z`MuIW+ԝ奙[MW>ۉխ oò +%60a{ZQL6B2azLUz ȇQĴ+͹tݸkjF`aU8p7Ϸ¶JbOOiJ RowhKYqDZ[TcV!N^\:u0/RBa]?4uz>mr-H-PY.-Pk 2C)-Fd0hN5cepJ:bHR ;4 C\5*\`sSAKcBi #9=DDUgϧ ~w=@CMQ_gdſ)X#Us2B\:mzk&gg4!\~''a9iu Şw;K"I9zTwmoM_<DžБ!?n}̏6<NǩohŖ?G/:l+y3ZlgtbPh@FuwH0 ȻkY:P/8r,TSt$k<weY{piuMō"E!uf:ͷ%xr ųLC2;)%>Ai>6е!$P3㈤JѤjO c 4 ?P+nK&fsaI-0zHj@X׵N HR5b PxvEJa5;|RT)HZH+=ܴ9fk oJvAO0߂ !mt%+1ᎳZߘ6Z"f49(l.;D(xW#C:si~4W ڏeͰ{uM_@T2=_zB4rA!͂aPèA54م>@CC^jPJIVyެRE'{N+e¼ wfx )5`bԇܦ&> }Y""!(R\>7vX{ust\ "A747MɪBފ>&9i=~0 $d 9bߛEQ45EnN.}nϡ^ 2\rdZjZ:r 8xȩ7֌"yHRք,Ak(Ț$}C{M[A=5_!(xiֹ& 0s>"P!$Wlo&~?JE6vp8t'̎F:TGB_"tfrgłfmT7-yiAnddۄ86rv=yBa`cb?sq\ jDiחg@MBӤ 1ڐT-, ,NeZ̎C6iBHH5\rmJdARB7c)6hsˡ0u 9>5瘝^:kKQ~Mk@sS*p3 R ط"A{~Z97x.Ϝ*âg6txCFII*Dʜ| NϱTYa~L|H82&A=33eDmN<Յ1/h#ys_|xUfZ, BusS8AKU?A4M55+cy3Dsm ۿCCn}J>oL7j@i8>GѨsqoBozM6$Ns%6(>?EvT5s>ŭ5k$-9`kDc3z=Mp9Xh8hiL^,~&ť$=}(T06>̹e.9ѿ6jCQ(]c@% kIO=-\|tI4)i;,þH`Cn504a\_G{Iv6,FT Wy25ֲ%xډgp|斗S65˚j#rrqQuTL(gu8-ji\D _ӎqIuQI?\D(ӑ"w]e˽2P6͐,r0ܡΤ( o~O&DI>hMBΡc=\1Mǩfd!ZH'mhZPc0åk%1dd)Os;qqqU{Vu(4-M 'H:jnUٹ(rnbi)@K ~R1Q!*ZKX.H-UXƸk`blttGs$fǡ`\#|Ղ KQgUŘ4MgHF&,t+?Sޅ`Vġ^7v;d~55^ܽs]"nf>yT:0lRó^%&φQR1*;7Wbk~gSM|x#"{.HsqIRKj4 efg3$i$Bmp,cþd* i30HNC)_ gqyZL+煍j.e&P&Pө֖A!բ0꘦* n %pj7I,"zFk,qB9vTm I^~ؐE/NIVpA8X[*\P&M_wCK_ 2fzӜ{DQTo{H4߁ۉ~,/}ң ΒRq4ɰ6wY aEDa}'dgMN=vVSݾ?h)!rEZ1j]|.\\,K4'+TiascMBᦻ  ÚPus7zOh#BQ4%ìԠ𾆊0;+JO+|[ !E2tBUPў~ec&䣐4ꦣ9;Ph"!y+ |ԹgjX qhy{n7BC6#/{ܟ;:>ՐT#(!8G(aAᘯC\یs\&/}KGEȩk)dg )=똋= {NO4EW.^-5+U L:>q;Bu$^M3'ՑxZ=d@t71ZeCˤ:bt iZU/@ڐӄM Aq|'Vz5!J]jWyl2qDЁ`LІ09O/yI{ChIV JK)`e65zoo({9&#ΧzbN¸ ߽6">^+,vp>^h-/LD)֗|4xg }:i/Z6K< ɂ̤NO>\b> D=+ h6x@(6^6(40ZaU :&c:%DF);wT$65t+^(8-ɜC< K~ u%#RnC]ЬIšrǖ#t\+5BޣEZrК79wތ0߇/o,ZXGX+9\*5l\MH)2_Rh Fɭ̜,M@Au3=ozf41uؿ:ܹ{39h[ў5(YP刜ܖ 9whGN_o k5Tvl?,ks),ߜQK| [?-^ BUgHEsajkroKB5]_["+*lL aj[z= 6v$pv3S>J~۱RS^]] d DRd0^Q^0ȐaB\l a n)ZW,Yj1DDh7Z$ӇpfԻP5&Z7(`9$a#t5 )m\-}]SQ]Mj#l)'|yױcDbQsjfC\^bu L&6jCA! lg(EM"x/@J+9Pi2?'˄=3g !?2wPm NN>hA -UxGQF"([ALvqש@i< 9XQ"#E|瓜G =jak>s6R/<K-w7w`Dx߀xTRV͎K͗vBPb5cv\\uaUUHsYBS+?e^Cmȹ!khȚ8Yйoo>95^19uM}i?zus{S__E_wwޢ{-*F2Rw-Ez*r =|[yqm\`oRk]z62hhͼQ uȵE1L3y`MLRuiyadH?JqʚJL6P1%@5\vy^8pAIs'l[}N5!4N(=&Mo>ܿ_nuXפEo,n^1m, ڴNkCYqג:mI0}{~?v{Ht5 z]5as:4 @@LEX yV.^9HύEF5nWsaSOXtN AݷKN< 9Mɹ׽u/B&E:Ne@ɺ E&ǣ@DnӨ!Kιcnck$ov|\lFEEE\|t|=ԝkJБ5c?׽ι[9iC:u44;;k\!Yίű7< ^gBnG i |% utqrՒ7aJ)2iBHiGPӁ׵ć*9H%+Jq JԲTbDLJ"tF eh-P^o\cxOG˚Q^Hl|̣SV 4][/a4lA5xjsRj~ţiت;P>L:9]M EP:\ўRPmZѹ>@|q[l!uŠtMP 1l,ї4xcKMr2|YV^K/\ň9:w<qu/`¶(&TA! ҵkB6T]j,yB1R"od" -},"7X\ܹ./ϱ= YBCnt,sE췡dݦx.䋜[D߶!yXuLt͜$-J9w|ٗ}>JS:EZ%7ذ㷦W XCE5R ԘpΎu4;hu J MO}}CeZFZpubh!TyƘ0[¥5?ڒҊ+Yd'n!~XCN&T0fy朧\n'ˋ NBAnzlYk9V˺xe{W wj9p v57$ [WP4T%Rbo5=h;S x]iY Łb.Cw+G@&]k$|%"⋃s:- ìe ex+Pg6 C&CB ҳW?%8-pYᵓpT+ NT) }]#:X ,ӤQ@ƩbB `*ܥjQ74CTNq &Gܳ6ME">xߏnWzXa!a;Eo0D.!!F>P@s1DQ=6k "lc^E?R5&.5S n5S<3,P_is'o߫%k] p)t_$;@A~5WDb { Nf9c4(@ yUι,1j`^hauBrśbB}3 IP*v , { ,YI8bF).!Mxy\svۊ*(mW G[C-'3w{\ºQS΄zދԭȥk** R]U:0NpFj*A'MjziѲ|Fâ!q:x/ꦎ4$ "ED:6 MSrmёSȹ4s M1ձ:e_ei_:k֔,!%t-sJ)T䘍oR֚cxWFfRJ'ۤӡ q0lBuR 19V$=NBk6B@@AI2j4@jKR}8Qk [ZxpΏ栙S%`ƚnk? U'\l/dGP\=wSvt*$l[og~o9a:YKILPz״RҬwHrzvGrvˮEpiBd@_Ѫ۵3I\y%|咄R'PH(iP"y |A̗,OU;(h7)IHwB9EA#Yҷ]* g%R&PY4iBܷ^1# )a>]F )[sg0{ik*R KQ&B> :M{(WRyD5^^#;/I-5Flznzq"@'z @AafiYUa .>Q$(Sk. m(5[pIAE>G]% zQh~ w~W /yɓgߤ!pqq;:z0i꧚aYkƹt۠#kts\ǚsSh1X>~ov]:YϯcikMK l8,e"kԬ]=˟ǧ|n$ :SOW:yX-rP辅` SŅDSAv$FLھbZEkq$ P[8#A(\RZ_#jaHiĸ":`M(ޱ^oEBQunjf;wSO0>3"&&>[ a? Y[R֊!GT8$gcw.{Ո|]?lO>$RJ쳵)l(XI=t,)_8asW ONsGq&ePoݓ9$R58:Ij|hyDɡ*qB؀yWy_y6ׇ$6v9#bd8Xn)M-rbC^gAi6.vitB?c-5/# olLQ!Ku2Ht(]*եe;] L4wVd>遚35!!l6CJLtb@ B5±̚;Ϛ\Ȁ6PMQ(;{x {54k+~/jc+Rԏ!_E_:1 a0(Ț}m|wO~.]nQ\ϣڜ'kHͨ2 W= -YXZ#^hȆ bPDn2hSqTR_̹)tFWrЁstIð~5~1Ei&EC\^FҚ$ 8d0R^81c2gHJ AR3Q plfp!I1{ 1Q"JJ@L}:nw񧞬w)YTQ-T~"sSаj%ZB${)hveUtJJO>dPyډ|Ë pUm4+ WTŋ{i8}Ȅ7k$=s2qks, 5RD u zvMo>&榙"ę , :7֖N*V#dpYD'B&OzZ=C)-6#ڵe.st!5k1kcǻp6zզ,54*o RqD~׷KFLHaҾ-ORk'1 r97 7}7ᩧZmB0ԬM:mYg=fd>%OyS4G QW|W&FĚ; m\j6k:V=|O?'x6?gZucoލkffm,%Ӈ MSR8˦ .XkMMI!!-<7#lͅhC&ƚтNSnDuӵh'͜'g^:}"=T )Jَ)N0B dl7_]TBByrܩS,qQgC0aof0]ӈWv@4a\? $3#mSʿmvy T, ER vN{@FsǬ%7* 1<e짳Uԉ &ďo(~uOǪťuu~MX8!]& 9`dڨ\͹h>qm+l(E׆.eI`GȐIڅKAP&UOӨԦ6EY@_'CO#T8ibPttBJѦΎOZ%.)|2@0PBk@\/n-{zZ4 z¼jN|G&?lVѼ  U趔m@^GՐ=k>fÛ #K] [=ek_Z|:~~8v2U4#kYDzJ!kȒ]95T$}wW:b}e34kG7Ub>/ScܽN0CՔN+5R;+k6NtE)W]nuj)$}5E Hɉ}<=!@U^`Մf9Q}BЀEj8XXpb)ȹH+BE)M>q^D'(@֠>[ڔЉSE2R[dns 룔ؘӺ?:k> :C0T1MRi %w#wG\Kױ kp]TOE1u"gAiXjJYkH0y4$ƈRO[ *Zߖb-|>sYR:cӌ{cȱ9ʟo,2r ?ޜ?~Ԩ9^sΚ#"jEOWZ7MHROםQV~eV͈U\@b9;t"5z<:d XHcjd8EMk$V$̂}COEtL>Ϻ1 ƄaG/ӋX!? 1cn؝57lv ,9V^9$d|4Ք씥viM" &J b+!rNk ;(6ƎվWU߄ewO(ap cI ڈHJv#xÙGuyQvlYA-؂8!*MxT-]RCg-$$Lŀʢ-hDЦN^0V?Ah~݆L/wZ("hDȅ1M{ Cpj6 j~WL{4= sĬ ְ̨S5N379Q-iRrnV6LPj]E\o6i~gtی60G>CYAi\|Gt 9G2o>goP̌گPgs oB˺)2bk@n۔$Zssl{50E k֔:))O4/0l,}/!#k ~Y-%ѳc&Lɯdsԑo+JԌ n0^6ǛZu~L1 Q}cʚOђ2Ne@Ӌma1$`#RI#e4\LWCP*ֽGiHM$0"hؓ|yN{w}|bm,X0( X'rc k40:R>HRkjnѽc|'>>l$Ji|—~P}^sɚO5 Ms۠!EFnc4S)De7MK/-f}x5? 5hϷjt=붨HJ~G~]9Я|աP^(P. ?̂jDC.ݚ(P cDD]8i͈_iDkXyʭ"`3$LyB.b_L08vPaFP A4,\M7Sm0sn!$0&ӄ.1ibl9"Z؀ aL"T tRJu}]G w\8kIꬔ0\$mq¼E$Z^'akLC y\d#"›؈qO2.KShК ZSN*9ГvRANi}-&YAv[ZۢJDieF8&F 8˿Au!$+J \f/ B(}_u-S?eT 5NӔ1 QCx)ۇ], ]jvbBT'v`FKG'{md䒑bc>F.YKiV)S͵!_Aa9پiݦ y ȹwhHnE[zSsMqYk\KaOd\-bpo۬Mcꧮ%z֩`yr YzM nqf [xv_E/;Z0Y`"f[=:ۢksm73 Ҩ ͇BAzvp!+FEjT/j7jr4WDq@008NsUAlL{j-Ċhc5GdUHhRHպ1pRE(=1 ݀ #hj>Hu YPb$ }IE;irQ*z.Rj(auo56xUE唶(Kiw\6Ħ3{:܎9z~`uΜ4\QT Q]C3 ժ6rbs儨VL(##dOpMNad:|JWCSAAF4TҊnNLjǖGKY 2A>tYx$!)$t,M˖20 5DD/!dT+\ O9"~s_eMd7ˀZ/5KBg1 rW@jѰ$49%7oǨs꧇ E+b N1sЁBakl NZHCmt 2OVvKMG>h9p[*"sEχMsA q55- :(v,Dѿ}7@fA9u׾I__],B ;nΫRʴFG sMʚEZSrޏ|xɧf+\+5PNM/BxCZxZPkrJ7it̗*oZ焔>(}5UA\K~*^淔qBDjѫ")Z358P5c OB'SLV+FqE2ZBjT,hHR|F=l5^9g\=xL W׸}3guͯkH5hWf+n*[džzjfبϠύx,{6"D23cVj2BAN"I@ExMƽ'_xSP;_QpZ hE+veՈLżYX6b0Dd Nt6} PIYX2$;~ʣAZ"$;װ$9^eUDXZYX7R,9,=\7Q_P(w$=hR0Ѽ M%DI8uϼ!x%s7)x}Y?ο|K?,Rh,LLqW$qlphBy*չȣjJn|4#״vsøh۔r?GW_]L-kz\ñۏ׬՚fX9vW|՗ t̓ز7U@E?sWG7/}nkPB,ٴ+*(I7P]WNr zDݠΨZuXB2B,7Àw;D3YR 29jݵGNd8`l}P\ s.(xi3']PDbԑq f@`P 4H0!fk5!^:pQk)rS݋'js؈01XY @ji&%)qk/M|848:9\ֱt|?7X5C)$uM ݮ˙ 72sv Cy0M^ZYj!4S_[+i"(mZm?/5xQK"ʮp4JcY`xJC|U֡}utD\yzmqSh/8bf V*\B=Zmk0JQ#^Bm?b<>wޘ5GD 3xem[|WQ^oIJ?֐Ӥ(~<}h{q!n&*-T}`i8=𖳆dԥrD2sߘ# 2ł~2|Vdvݱ2s@y,T ž3&ozsz1Od սAbC.B^U7j: ?A%D0sp1\ y)k5( |}| /R2>1\`j:&Q 6$7qzu΋Ns2|Υi-%Mk/b|Sqo %j\a͈(iEN XCbkroTOo !GԎ5GinW]HfOI kԨc5V;ik22J0匜 q_tSɈ$i{5TqM(\J>Nra~4-L!*ji )ڢD$OX ן9 50$ gL%HP3f:zx J[;O`&4We&LP=Dh#A j2JRlN܈xJAS$#k)(ъ( HRl3:-h"!*tTxڴwQtF ./s5aܘqIVYR^Q5Kф̧k57gѥX~v*Ԁ?{y3ε#y#$&_C"kTSh)Td)tH}&kk蒫q*]C۱Pǯ5Nn91+r;"3Oo x1J-E]Fh䒳BMa>0ۺ=1;L9睦fHj&q 0Zk=2α{eõwSbJqqn p}phDA߀E: lӜ Pu"{:oYs#clf0+Wypo8k=dMGTtuS έS'TrƤv SQ:x(Rktޜlj4nYR&bvǬ0b45jV -DȎŠ?}7)Ԁ*/MKB1Pt։m97A " \ÑBf>禃9 -p۵8Kf?z?x_H:e`F&}ְxDܴU-|&Q4#Ӑ,ǨO7ACNeB>nj;G%+`X!ODou,,co5e͛9USOQECY|Y.]w?,>gIDgf,h -#$AFIG1MpTq(}QKuʥ=CV)vzNٞC%)*B)O \^b?Z l!ʸ!!ǽP4Y= MaMZij-2jNdp\߇RqR̹D_0Nނ^C$bBMN>6ރĜI"m{]^vH!uM#QD244ќ[]hد`EMKǂtp. =8 zKu"u S)&+&"\C 9"xuz)80T 9s[nC@03vI Pʒ_@%Q6Bz u [Qqz׫iJ1[zQ@fy 3 o1$猠5M2W$/MKa^_5,YoB˪ ΋x0M*(k sw2}1胼JG g ߞ5ϋ+03>?WR~z&&ƇyMCrà!KMűgNkY;&^akݿo}[ZZM9Ԭfd1GYM5%> |_ЦjIm >Ik<*-QL @qy]=_fk{7""jS*U*cPȕQ8bzJOBm?$bu'.%cৠBq HIiPljnqu%8$ð꛹=&fbOc5@f,MT!aó~nusL! i?k(K9ip!)_2u&zń_Z7!NǾ( S[Bf`\b jT!|BshzҸ|Z*%RC](K戫r۰TeM-8U I:K :#m CuU/8i*a WWPJobPhVE*r`!Rc'Rjea׹XDv׎-C0K|Wu3]M>D*e-ܗg"Cޜ5?>^F)f 2]*,}a[lVNcB?K܀aӌk`I4,MSҴЂ n\%kn폇zvD>OdN/mB"%'srDIZ]v[WC_k**J _z6<ذK4-@I$udJ7آ6̌2'9qyCeE^GEws,)"0M'[sg ]jD Q 606J̃JZm): ' XIbbY(4z*A:X619Mz\;##Ntȓ< ^ ;j8)t$K(Պp]p UK)W {6R\ri~Y /`׬cMI+䨾'p\KBhVJ *И>YBE|~:wEOJ $|hsC wE[J &i&oO\^mH>`5 `v&T ^$m+ܷn"v;enNP2E *͡m 4"NA&R9A ԒoAi+äKfѷ]#͚B!JM~N3C=n(!D2']`jvrX̢qMYw}7>c?$2o@&P\Y׼ykN ӗ=Pé y>hYe3r{Tcr5&)Pnj$?4?0ՂUy4̋/"FǙ[D~cZ;ށ/i[DlRh\*[- buJu_uDv PڔB6Tcb(8F'ܮ+휵ς3)%{(lѭ2B:\Ijl5@CAQ 8:eSs(\P( Z9 aսacf\*=9U1d>w[Td kx^ٟ]E2ZBE2KךNX95-{{?nBܐ&f[D-2z=3B#s\=ښ坘u|>oga;Ӥ/R4PhTY]5c)BҤ sQPfHJhBPJfm~J E}qq"h GٳJ ngQHĨc_34#;+;4+ )?w+e>kۀ~iFLjU(c@xL<:Q:TLW_刔#s;( r9 ZN5C$9hKJMįZ!EpsX'2z^MJF ^ysk0-tK[,g .026v6[H>F) .JȂen֦h#sO=}TjVQZ%N(ſ29#{+Qg\8KiE/.E%Dtk,x0鋛2樇&8b\*D[6Pw RwR o+$~8x_WՋ7k璎uA_xz궛4n[jXO5K9 oIp %XslHkDf: ÀfSߙx{:O5&TRl|]cJR &HF@B6ZrEՑ2?4g:(t͑s bjvm9Qo\c79OO.dXd;޻w̌YZug6!kɣjB/t֌yzsZPSy',iiwm4w:̙X#"-9X)$:h]=f#[+ 7LU*I.&ʓ|-Pv\=}H M._Zx\"fo@]@\m3DsqJltjDimԿ50 * 2I J?K)aH i<` 8I퓭ɓ,j:tMm*+n藛H,F2 lO + \'QSEr\YPNָf053KH7/^%g['l`=~WF s>|3wJ)i|$FIQ(2>\ s_ȹ_Ӂ,9r[:x6J0:+??l,5!sTģsHaY*Pӛi@5#u}lk5Ua.x8HòE]^̨$/QhD(eвT00!J*EANz! &GW-?Hvj3Aw`f\l/F\]?@J !a܏6ר68aR\\.:a"ih 2kxXzc;o6Z iZkqD qл1@\Xx'  CW#sÅsR2kUPƫ ۻ8 ;}Xld. ֆ#`pXx4"8'C-\'5(ܐ Ґl6 0rnMHա6e!\AZŴ@lJnoAB&oӰ x0$Y v <44"}`M]|3wX!RV)!<JfhQϤFE-sAPkfyX zqJs&4]Q6! y^-W|m ۚu5)ބ^ԣ{LnM9"ynw h&< >s>x+ 9%\>s/&d^0䱞7q:&X_?,|מk-3k=r|}??ꚐyCb fiWo,tΊ9*2wʛS"^(9ӌ?yk ^H\A_+tO֨P62Ή z- ѧِYfp&mpY# <8e:T"uĹj)iDL樍eQ5Nn1gPpu}f[)f~wa r& ( GܻwLCvE]j\h߬ FC )R3f"O`,\FW*s'Э*m+mAi 'P,WP415MzYϏFģ"l˄TH L *Un0 B_ޫ7HVھ#>G0 lBƄ8ȄtIc+4@n~s\ Ĺ6׿郼rНj' LQaH"rxppWd'ZC)_7J傌 IūFm9SU p[5ѡ;yzM]8RC\v+etbC8@@@ =Q^im߅W~ҫ*Ԅ,Q;|Xo@T-eIxӛtHs)JM3Mȣև<sՌ$k<T!})h}9v],ox? ۆazok8}s6<joY _9Ek^12!"p/FǾskD%(E%Ƹ/l<Z^` I27F7Үŀˋ 0KCbCd[ O4([]c*¦jB?#,a٠*IՑK]eMnL,C{4yzN{[byi;u;@Tx (Zv%Uu,+ZBC'# 7pe.5Hժv)p>ҀS\-Mlc0KB ZaQҰ+ODzrr⳶6uu?'DC> Xx 65NsHhP (!F4EE X2$b7xv,z41[q ]w>vuhlj% b8h("iB1vQ8NQ|%ev囃gy__zB4Y ya|=sq15sBŞk7||Ϊ7"V&\v%sR32VC#\%ZMC|;5Rŀ8*;(a0l6mlo9t5 xCUfy@:Ƚ@Isf c4H y*JN!nE‡-6N+=-q¼~35;Y` qR:?4 ] ic ._EDDh+둈(^sła Ci G! O7W8z!Br*;s$yjkyn;o&Cl>Jːp &%+>X P,MpCKVrգ&;L#; LZznrxUO6%!QAd8Bb4U; [08kY.TzR@c҃됬M*EvڟvX7 c)駚Gوom)Z7EEnrߥ;W+rNy}Ϳ7{{?bGvcȒVģkksP%D{֚uuK:մ!r2BgK֋B#)w$;Zj+yOZb@k2T"e/Ր 5Iǂ @l`41 j^Do}s* X4s+xp}H +S20h+Z)gL-jcPcgXR{s{,zU;f% 7/Ȃ  LŽ 0qJϲLN_ju z򅲦WUNYKH|x'oׅO?7񍸼<@,劬,[KT!ҳ>4oKZϣЭ5#编y|QoosErQKvKRRʺc j2׊]Duẵ(s{Qf2fC5DQ+ymc~ BlΗ"OÀ<R}&ŷ@fujZ"9$1%YPݱR)V%s SR0撑1&1[sXP bj"Kq3tÐ:4MsyPZ`4M|``Wµepnb"688R~g?Yi?\'9~7Bջ&u6jtՃD]|& v<P Obt6O/4ԄqS;Q :HE씮ǫjUXQ-(]ՋwZ[3]?mZO?~_O%:żwQ駟'3A%Xqu\ӭ>"ErTds{_ 9Kj~fR|۷}bYggsTs(ZhYgݻ_x+?[@ %[b[=Ka?_?k զK цn5*c iq$V +%=n?fit⌁B Qw$%̲8*0b|m}EkX0k#4u"YtvU0=GGTvY=kFNOQ}C%/v6-_ =lPuo+E48 bJUtb)K*=3s)(bkbj!1EO5y-R$Cۃ91JRJoJlCI4)b뀬v;y^oJ i ɏFm~l{d2J5)U7~$$)$b8հ\o Ķs*J*- Z2wB R(S Y+ gԬ6"rtw-;Y:G(:%D a!'!P4@ޒjct+v(h  45_D=aqg G L` X{Q ׸d2ـDZ *&#T!0iXP TdrI%:|pZ7%2$&$P6+ QrW G "( 5t.b 14/4!D4ݺTG :4@nJ&0pS#rh֐h7F毧o͚}_??W'y29 76| }n4S-\&z9CP!'KuD~S _9ɧz ~KK]?FZh"ͦ6")Jњ7%)K4sR֏剜ӌ_[...&^YD=Mk^RrK.ZY!S֡[h q!ˤ.3iF-Zk1MPcA]Gٙ %*@F!qǸ˕q m}j>8kRJ-vbcuq{)KE@=SO 0(}*Q8/AsAf=L8_"LJe"̹z1K@iŘ5M$ .S7x'[vBr.&bpC_PRKo݄L +7to83-w-wV|,QX֊3ik^U.]ki pӦ҄< 4LzX$&ZS9#lEQykbw߅__\uZ J[ۇa(Zם{ֱx 5f\dRЏٗAQc\q709@B,J6p:Mrǀ@@D7~m^aBDe#(FcӒ~ˉ*fe?~D.YG SvRw ٰ^rk2+*Fd;xZˡZ$S DR]F.CL4Tv1)"k`X8'DȃSR*xH6r\7̊^ ҃B$׶הi(SeT ̌ {Bu0a7ijaO5 (rK[zbl!Y¦ "jDU-6i+-kޅZF 4!SaQw)5ҡlM7o=iYўwDž;8N:%X?5$8'N:fO5% :y7CmѥtG &4&&nv=BV:-5EٳZ5%0M4 N=ؖ9-8!Kk!_V{`7ȃ!Jbs0N[;Z&mdqtǵf,+d :R-=o$~ܼx?q-rXK %tAV:ZCG;xew%:kBDi-eU2 a* Gђ7E&釴?G؆ V {G[%:@MCt¶[ZWY`z"d H[4, ͒d tqa,lpvCfq_5MSX/'α(B59c`bǡlLا ejTSq8A9ORr1KXSH̷HJ4 idԔQ&=Y9%+ĽUx/6.Nh.* wFtvmN< 'ͶOѝ9k?%q8w4!yZi?JUzO[B5ohEi2|iuNչ)v>ȩ\}:޼Wo眪K!tQu6OͨSE]'Țm&*mlNe$5!{aa3Zв.iRyUK %6Rz hې8 YQ62ް$iMj1q}}%V(("I {;c1Kg ; sP .G|Ջh7ojaR_$28pӯBL($w g6Cmr]EP}8zAMA4sNjV z)1a :T{u50s}\1JbjRtJIj,F9z9}E5X.=dDJS=.7V=>N ӔxŦQ8S&:f_4$j`,Is 8җtzT sܩ!AyҀHfgah9-hPlצBT y&݄ZcbD:& Jjy;]VV8_~/҆l9l kb'7//m <&ᜋOvPiYyKmN5#k26%/O9goBもtѳ )Zrrl 9\Sk@={a)@,I@=gݜѬ.oRfk]HqC)fPc9'6NEmFRJQ! ' eoYr"RcHHSDj1a6{'iBf n0v Mn7Jh7!+1]C)eECM>?ƸN>Z%s6A׿YztвF|#=˚Hzp3ؖ9T*rכ{__lHvT ̧z>8" [RwNO\F6P'"qYdgDDEkS PZt1:, f ଋy0 9%17fR5+=O=zR*\P{NQKu2ƂכT)ũ{p-hZ+,nqԵs@;L| .v/4¿ΟZKY;:oܪ= V(ix2"]^ZdЇߦKVMGXr2ZP<ф47"[` D/j?&o,!zmZ\ n@8o fvQ/I 77˄$!]QG_ub_3Ihhuc)iX:aQ{qCRz!@C ?6AP8:3 FQʌf$.`x׆᩹)ݲ(,75$ȄrvWgH.^$D珀ZB@!/ݿ%΢kjClT h4uoWW77->}zp*Z/K >9wxc/3З?"BDl"[DNrF9sZc~>g7NQ4$,-VwndwɪӤFxP"38Za!ІLTMi[ZcU kJU!(THRyv$Ab'2"WWT͑5?lcrd4Cwyƣqi2V*9#Wj"d=@M 4Z&kC#!0`g)&*@xk?MiMieFAn[&GyFoAy4Ԑ[: kюn mNJ*6֬AݲjJ}'*D G/[d5=iktdBp5m lA/M.GQE9nΕ+E.n9q<HJ 89x&s[޺NNL0x"NH琒d5kWlxg>󙓔5K)BAG`k0Аue=[g/'6tZӳ5= sM)NfM%u\R4GsJO3;3TkCu(f264͹2v`b'/sVjmCc5k'B=ǡI(vkY 1@,"ud5f{rƐPFIϓ;gY# S5nv 7v"֩72rs( A .mb&Aqr, DpZM׉KzQwQW%?(}ʭ7b 4;bߜQ"7bܘe M_?8ٿ{M2}:QN-(ËMiNe l 9it50z&{Dhږ#g ZQ+8zWOH3rhV݋ZSm}STY1YOB z-W犵s\4!.K@T֩kRӜ@Z5d|?GhSݳrΘX3b]g6܇ҝL[3rκ9A ppBV€$R "n|I ֚S ERZk)#')ܣT0pyAJNm}i<4i7`0DoI)IG8l!uh&|!gEKԬZ2V[EwǵYʪNC< B4-,9=jDžk(6M-~{=Un^$]enE6i6^DUX.ȁFYq8[Z;i[孭BO4O^#‹,uBJy |HPCI@oʶw"[D)Pk(V=\ɣXSPY839F3! Q\jњRB Ű% =Jr;q[@9PҝݺyG3Cֺ07zVP{_VԜ1 N_B(H! Vi3#Mf_e3,76$ܽ- ?yv3bve/ 9%P]7* ڟao qncV d)mocEe1cHjt^?0|"sW׺'BhY'xr8F)- BYL q>Ld^X3kHJ$lһ C2+S[%I#)22E4LPv0nҠ `MYo:zH3Dyu@N)y׶״wxUQ^XaL2GБ~mj^j+Nj/t1Hы!7x_җ6Q\jF}TTl0FN(ئޗU8sL#I=PH%}չss tyY[5]ֆڳ_ΔCN^:A 64A|tXW]ЀS"PiK)u,?M kkMDCFU.xK(ϴrzj%̌³TYPJ_M<0ܨ,uP!z!z4m}}u+lneL.VrZmAѣ0jE% ݐ'@>ExR*ΉZiϮkBnY(YC {%ဦР 0_#4rC+IP169YBr1SZmj(]j!rCV뵔Z4;`h L_3\$5Y,Rhڢ[܀Qk"f]652k,F{y ЫJd\Z^/Ept|6@3^/ yĺqyC bE(4hk ÂF?o܋QsTð(!e׿٩Lsּ>m1es ybphȺ~W}t "sEǣSyfm4 |KR>)gA`S皈K/~99h^4͟yrQlrP"{$_ x\ҚïEzx->|R0I2~irRFCҟSbs|2Cof@ ?)I sF&Tn(Nź,;rј~RgRT,d(>*1)g7ǃRl85 Z|#eEy&.ռ9DH"j WMS*)L=AݞVo[QG?Ԭ؄p}J'٬PhׂX#"",YpgڛΈ 6IuC@YB8* ,ܫ;R-0T:(^Kx!3+4t%EDc,5P֨_|ȾBMA)vD^zӚhٍujA+myMP5 FW/?  c(SNtTڴOQu?Z7=K WXs?y&ĆHVEK5l\ҘB":E롡~q#DA8!v?oa]=+)ɒ 9xKHp_h1"".\Ln3qVDvoDxi:E3JA`َ,N2P悢w&PJROm4aA{n0 ]Dzj80GlL^I|:%kCs?yed@SOA7ɋ``{@ 7@];@jMXkQN`| "tayoD5E8*u` *Cm!гrբ:r<K»l'84$) ;׋p^/~)Nޑ< (b5prXdα"V,[`}+׋}ZMk=Qy%;4%6AkeMp"S/y>l5(b7:lӱ zםnRl#|LDX\2~~N'b/(p=Dq\O5 P.EL.ь^"Tz[ȜMi Y+vRڞAPЊ +X. #d=[ HEGR°2!˚2J5xo9ϕU}!UƼg׊R屻U ;E%ʱ _0#v.Bn:Lhh\#44T )Ӑ7vLo}C`~1yRkW;ʚNʒn{g3f 1%U-[v4oS$ y arN;5Nb#B*]@B<97ޤpGІxZxyh -j38kU-Ø0 a*R.HtlҿV9! :%@VdsF]V<Ƃp<I geٔ¬.$R)(u,'OnsL{irHsڲϛ-b(3cDžPO'N U-ӋsيM $mj}eY]X8-&OXowm~O}/mڧ~=Ƌ/99=5E>1MOSٟw^8Gڲ^?&ų![yq<S)Kz?Ps,"+|o^xā .{E~C &X-aT*cԅ#xCČȜҭ~LnV~̔C& =8c/YɜkiJ K~k'yo4hTq5WmB2*5͹&pa8£;r&r REu1?D3(q@I@g:QPSzGs/ṫO:}2w heQFT?K(а4úPaiGʠ4[fl46RScw>FH QGNMEt" EQn&p!3NRHp+7>"˔3r7yq6qVłuZ1 lYSWW F'CCb` RBNOwo^g#hȚe.b"jzBwe4),Ia[x^,LIO3G[R|hl;[.0;~/ 0.nkF!di~uKtIqC򓇆%{/ I˺D?rJ7a(HG-} 4TQYBG7&Kd~q >sv΄j5I@ܛRf^ ! `4*Qu|'6 >")4=l1!.wR a~i:0% 2wMZDJ"{puyiMQ5T4f}p^3tbCwIooӲy&&QeݻZ[ok_ 2f:p}P|A5Cܬ.m^K'3bY|Zo,kF,0%! O}pÇ%dܷ^zm>K}(Yd 4_P|2@D7ꤔĶNQL*g'Nb-g;"f1٩Y.v_5+j׭)Zhx~>ivԤYkw#ivIuth硔"VSq*R&[[@B4QJv%QK 2 &;r {Uv740.2$0P#419NAjQB#պܩ]9\Qum ]aI1p-E[( 'U(A]Ԫ֊Z eqXlJ7Dٳ'fNC K4\%!g4-YFZ7?qGģւLi1I};.D8t\ =I+Dؿ7f)R/4vy% A|Ztң`H#]5hi(" g[W)RZ ?Q#oxSz}(f{k=ytb\C@)28Mw|컆={"Ln"t&ϕ;}Sl:V ˑPyQj+nf\v p"H,ZGȆySgohhZt ̽҄e.+2ns\S(5Sl"HqiJn@:˱V~Vun7t8: unK#Dm)EoRf\O5 [>Hx "<  B3TE_'+ԅT@}^SH/c`Zlzk?CƯ{jBѐEo^~TޟTpIU5ZV),MP+Wܨpy#"t9k%_$M(2 kYdȞOnSJ~745豜0qjEz˩ Z-_h@Exu-0侗׸yEW_I&;&DY[*@U:,J֤1%Mo"!*tl< ڗ-9~& (am(|"!ﴴ Z!XL`MNC{Q1\KKt qPol7%HD;;B̳_%YxbG5;^AYi 5*żqfՂyѨj<378%4c !:ݙ d]!A;ђ"ز'r*F*P3=,x"EE2:ԌW"r1|u ? jHP;ŝP7{7q'I^mZօ[oш.A?>vǹyy҄לl%oצ$fGlDtЌl^B:yDТ#9B4xץ9wR0)IF!N ajM` [Iݖ5\DIl|ewZ5#cuF4 CtB"l˼2D~u%B)N8ZzҺU`FE:)0VzUr-MƼ6I kV^ЩD6(7jS[o2Ab:yC@MjTj݆6H: !r>5?I*5C-NџajuZڏ«Y IiC'я6AZjתYF4 @HETg3*a?0 ZZq}}%>ӓh$j)ش4`H:MdY7n Z&oY-4Mㄔ Ø Mf jhtS$|jC)L b%mjnX b@*RZ ٚ fXJvʌwk4/Jݪ甔+u4 Ck/Iv#_@MZ(blL.)}ǩd]ݲN5o~W~"ԇ #7}8Ə<^R)-f/|" m?58EB!N;[iKhaZp;~&k'>3f"pm@aUP71h[[]1 Fߪ]XPd۱wwY#=j-8aGKj͞np) qHb\8i~'Voi- J2Q#BR!79@)k5ծp71\T`s epZ(*oKi2&q{BLU*_RXp04o|Vֶl2ZZօ0h"X#B'ru'sm.^_कԢݞ[ Gc0GV6 hM3a*ߚ>GqSJr2㶲E1ڋuЛhfP(uRbՌEsGIj)R0g3i vܑ:R9t}1]O被;d챵6%K!&4 >ѱ4CK5qܰ{ZA)OQwIא.9I7/+'=Y0FmHgE-k7xg?F0\^2u -# ~Gb#bEѷ9YkF+O9K"!6#=2(tUJ3)B;=|F)lcRlŜ0{=A$U*RnRTmiIqNTߏӵjy8Ҵ0 C J>XVgVSFel'e2f&FȒ Ҫ眑tgٴr\fv{=BCtH\L(S8̫$c@ZoN@%[  ZDUgl`vϠQʝT$mޮ AƆ:Bd--g DCtXrpC7\`І$&SzXX{^R񭊦~aڅ[n0jY:pXl %d)9cwu2HM/!GfnERRfYc'filֳ֌VlRVoXn`5dtx($q5nDQM ,Q|̛6(=Ff !+JņrgחǴH55{?= &:};Z Msw~/Sem9fE#GV?'?ɋ}|,>>7%PNL>O㭷ԇHòFd{N~q$oNds>Dr7""|SB)ͽ L:IJ)wY 3u .)ߵ`O)3haKi!Xl3f6R.4ەQv6Gv;E4Rܳ3f%n0 4f È+hsA,jKNRJo}Yd^)Ҙw;չkV#xo?y9w;|NU\%6b! \mL,0Njd6>#" ,~ |" 'Ղ`Pո:2`.dIqY F85+V?;9t=ڳ-h<+bF~m*RI:;wNIk jŸہapf Ày|8 -[;v=)Y8nuQ}CeAUrw$VȥA \Pٛ$y|0xpϋ2Ѣc&c}C M1Z,ݜ9 &6LO Yp<gE\PpPx{y=|?zϽ MX/Ml#Љa8kcQ]$߯`"N f02@g}%TBM)E12JxHZp`&T7 E0i4\@znh4$ӖMqH0rS,!祳iijf>@ӆN363) 5PZ ^om"i)B_]TlG 1ԧ^L>׀-;caVzDD9x饗T&1].|?a=}cA4 sZ'3W_= I^Hz霽oݧQjF? ?qULFd<~,ֽr^Ŵ@ Cu_}D'ԝSRE=IA3%g4o%wJ)]PNaXfixZ8ssAD;@k\9CUwMV9*0F:Q4p8jVF䈏]nwpkavG}5 fOa^MMKXJv2jY"ׁ#`Mt9IDV|AT&R)4$BrZ5? 8diHD/(9gERn0v׵qAp[# ,<&izxAwD5y1R-D:W {4MUkj#*Ĉϝ,*ˬZ6Mc7 n&ѧS 9f:PEbRJ>|Ǜg)}2o~a0o@D8jggV2eXAZɯgcU0(5ȣ愈֚nE\<|ƯըVJ=op4шCF(buxFϪtR+K rէkuk|g@i p;E^䟺k 7"#yᖋ܂ËXJ>SLa~%ZOv!N쒄 MH%JnJX!koaĐG05%rhͅ"Iu; NHeϾ G=/P F E?bzKU{?"foc_c|߼>E:Sk;K3o6"禹)s§q5-ЃSE) h{ߚ`tCAl\h҇<}hک5\CP1CP[[v=!9/辞1e"v2"X}4D29M gʍ!-0Nq@ܕPڞPm?DWij*RRA^wXdGz.YP0Ur SYPH؃|hu Dw9Al VeF}!"[MfTuHъ"c.M,ry~?< Մ3?N[Xh(>lBY= ۧ6׵59|Ŋ4i:d̶)jT.Vnfxzpܘ#v,+-\[WרZ?ZnP*tsJR<*v{-7gJj8FsTE 1ҽ2ʣtqm^vDUiahJ[wQH4)ai3mB^WJ TTda\ օ]'nBfz`q{K *z} i"QYnR J-Nʙ0Xz |" Ġ_ 6ky,̃iJ !Cikv4BZż)[9ViR|wzDDakr&"٭~mQhU΍i^dvt+&JO"B-d*=Kc ͤH Mwb]pOنǹ(֧ľ?) ʥOOFk!"DDc:=ܽHH;""fTjyѣkƢCY3!6,wJ\`C6}Baxh$11weSilNm!T^jFQ=w}|֢1G"$0 0Ϙ 2i8zw%sGdTuBکSe$91h iT=ӥj]Rf>vv1ӌČ`&B݆=$e+-x H.zڮMss5`55y{?{NL4u"Fn;'lwT#B &J-=OHq#䇴VvN <[VI"qw]lHbr"Nޝ7RHV"D70ojRDBa'_f>Voސnnn/>O'q{ }݇\u40^T-|ccbh}KР" [?uw)Bb;Jb!fBBj|XUm0wf$&wVYIT[;f?A,"8 ޴1k~{ZsrzVnj< |cj:Aќ/~Brhucڍ:@F]h0P?Onnp<}ͭ!NZۓ꜍*a rxpU<+.i]EDZ'[O 26v~1k`17$"󪁩;}^"$7YjK#)J S `jZSEjzm!~E`iyX:)]u1U iOJlQҶZ7)iL]$s*E-JZ2Qi(H,!YqHCH*.Z['=kzAI(G܂37-xT>''xQJ4-Ut-?@CD ;v{pmDړS~%҆ĬRݮmYPvZK#ۜ kGp:`bx9Sњntښ3>]j7Cm8wY(-ee-qOdnבՀ԰}+ )z e#nF@vD uzx)%YiVDa59ՀmDV8j=Li +zhg" bt(A2;Э[FiNKIդ$E1ja}I`-~B`QJ=G:W%^̌ZR@I^K뢰<:G RA",‡AtMiHEqE?<ӻAB/~p{TқOUl$h,#O3&׭ttQ"q\` MkƥiC[m}p8rҪ eU1ՐDtdd?~%t$k!>F;ޟF9w_佮sD"H{;~$Y}?Yuk;,ʔv45ܒާDeSj {`Y+[sZ"Zt<8r ZziҰ$oLS­!4hP+J-&AGM Ero`Z.JD D(uMPN5Đu(L}8\o)k8tDj[*JȉZ.WFitn kGv;Ky"Ev"jX>>pfxAa]qŻ +/~G!C,X2K h ҐE){ !C?>Qk F-=iYu>[NZquuutF2t Uqx}| sJw[o<Ո5r}r.EDnC\@z.PBc˞Rt H5Vu!IY}FJ0YCY?f-8_爘dh 笻u˜,iĽԆޏkXFF#Vpd%}Fd;7d7l[L,J-ItIY 'P %6hRtSQvLFZ=čх~$t)b̑Vк'жnҜ=P[evAE㓺3&I0ɂy{fӜqp%p\ⓟԽ Makmk3kѠ}M)GQ^h%OYl,hWȭr["K \:"KWZU'$-Dj;dq4GpH"'s>g5 0b⹺tÀY"ԥ',R75O v[cÛKڄ6KT$6+AE>Ǩʇ1]*9D>ѩ&eߟ (.0Ø!r_rGuO[ԻG a۞qN9" 56K$B9'wÊ̌'wj!H HGt}1&_Фu4EByDB;M bgY#rnAJ."_"IrtăB˶H+:/ʱcbCw3׎O0H fs:o yc/ аࠜ3<)LADnD<Ϯ}'EQ24E]9[t"6(s9A"۩FS Zo:,ci;=2ƝNH@|p88=k)j.4_!#9eO^o|^22j)8*Rja&ZZnt\bjD-6hceNkm?.A]Fvs1["MD{ߔcQGq}{{I]b{F7NurҋÇw" /8|1YT,&ֹrgE!;-_SН z0 69gi0X=&+ba8w&)=uUUsᦸd52kf{ Ѻެ.?!.M7!7td)X*^ְ8_XBd10ÂuHcMT 5HXn0q<CP`S͈ ɣ8A/V!Cm(VV4S@9вC]]Y==wϜ^kF$ҲbCbAt̊ 3.Kt%pBG(Sr4´5X;rSmIp𜍸 ¨t2͈=9&rm;־Fz,UGM ƌZjCFI&: F i2I=/9uA^e 8faT.sk<r#W{yE&9fL/7ݪ9 9IY,#(uOg*ȋ¤F$pyݜzH\ h .q*X&M[Qل2N!0GY(#w 3?KF皉UEAW 9j9$8~A<>7/K{gDkx"sUݚʬ9|;u(IE,;wlUHsGw␸\p|||jS^ӵ܃tħ?SO%DDzl{hzʥG~R?j}CS%H橁sm/8{=0/8f}uРeZgەIY&9WmjC+C[;` tȂ4W XkRVC;I5{3Aw!zGV=ZJE.4qҭb)d0 <oܬIvŘ8Il{qi*}"B\s)`C9%5E ׏p4Ʋ vaDRY )8g *{bvK櫫+쮮0ͥzt:H-š{ﷷw$|MfҲӦ_ǥ>Ք̈́ط gB!$fuq8QZBeE"2F 6V4逐$gBMX<%q[4 LBk1 xEm 9VӨH]XRG1wwVGd-跚Ika0|)2{l{Q͵q{woTZ=ʹ@t9wԦ5`%:ٙ>==vY9vBfx!%s(I/ulS620@E,;d-L_5iE0pvp+s&$!-A#uqNl^d%yd{zkǸk*,bMir0hi DOkwy1[$PaB$U$M#cvw+E'%9[Ԍ _8dPM}oB[,Q&VeE9-5Q Qn,yțM[(#knnn9GY?fKѣE~kB{~hȳVp?C4g8:Ҡ]]dzC ^o]t 3ֈ}`a\҄|4s҇6'~?'>aUGyh@2*6'a^ܼޗsTl}VsnnnN҈RK%Ԫ-5':>-peGHlDҐ .(wC^Kumt{GKƀl]@tF^# >*%N VlY &I)%yT À8JcuR`L$1v(sQ]*VGM) D9MIw頨 +v]$f nn. bRXΓ#^ҺaY8vas岬Kg5(]A21D!&uf'3L Sf@C%-qk8$uPߜG2x R+ȨqaS^ n.\?#eRHpcϤ`p7O|">Jĺ@]sߧdg{ ^jp.n3>*Ӡ%s=>4:֥F|LιDȾFU#ꔽok OzC-f)ǹ׊_V|KӚ={3LNӅa.Wq*Q[-;A{_"uԀC5i|56Ner5wA};_ah&[!p;`vU zF@<2\7͒-2)0NFϛÐ3r04"0+Lk݆KoJ BD[m6& wEJaCr;y]pBJajcvLm89QvT&E] oڪ'7HC=6c[»CE$R[^/10p!2txS,rLUR0]dyn 7󀵻ʚN[ou/\qlmQ\Tg]#~?irI.SC/_]:][ShR|sz:Yd~~ -9Ez睷=ʆHwݪ^ШhP!N4kJ  Vt\Ң'Šp0r:o܍P KZ4!"s5PޜD\Q4غVmX nno1WxdF4֔t3*j`IIСaH ̵gc:v\4l q=S [_o< ]GF{$b:+G5rд 9y"g$"7z֖ɭ*2)ULTN@rv׋ukJȚn=xp?L ,^M* R޶vD@o< h%J03T ԥܧmAHQY$Z4 G EȬLb.~`krSy $.hS2>fD-rꉳ3`ѹqJ,0/a8ݴlF7L0܎1%Z/S9M/M,L `!{W>T˩fduպ BDRJxW' Fd{V>ĹZբn= CВKt§=_҄<\gRϓ'O6m{Ͻ⒵u/_ϡ SŹRDp8`ZRae? Os `mA sLp\*6k8!i C^R翶0ZE͌ 0" W# UCޡiit3&RD=ܸe%ړ0Nki ,U(V)gG׏9vℕNCX7$($74\h倔aI_W&y^ZKG7 `fjWŘvbygi;l:)oZ\ Ziii!a ::2DWJ*VIְ5Q/b2/ &ܮ)JofB>%VAxCNP@RR턺H)-Nb,?k@KPRFke"|¾jbnkNJ Y* & ^WBx!j {w `. d^GÛ ^+)qTAc˶(RvM `;֍C'rH"M ZY_?{i>~MMz R9*}qr*!!" Nȹ!ѷ5%sWtڅ&C")4֡҂٨׾[Y-%GiݬE1?"KƂjl5γςV`?dkauXiWWN 4 s]PQaŴ~ϐ"85ƸN1nq<9t`pUdbpI*iV# 9>r5ɸZÛD(epb"jXR1s 9'F&NP@KzʵsŠ+G/(-zT/nr5Of .*)Qmn w",k\ Os&BXICh䵧iR(5~k*|џ/,ނd5i(h$K C=Ҭ3ҊJ%;^9'e5\ZGX8d^ 7 9u~Ǔ'7JQ0[LW<xg?X}j:Бun OQQ>*Cgx?BT!i/EZY"[ײWrYmݿ64t(GDu}=HZfjjQQZ^))%2wyynt_ڶ7":6^8LkNІzn|}HNIP+c=(4{4M*fq<1 JyuTToOMc#f M4,BoٺKD.f}'8qs<ɓwpxXk!xHf4CPt@sYw鰝"z962m@ Ew+JވDʓN&j nkvV@[Wt pMN24 ZRA,l'ܑ̊V {:JPKZa[I"c8`uBSs~YAՉ.3f&*I"0V_ Tܡuu[:7вdވhi}z sDCu3)g>T167zf}MCw%.h[yK7ˢ SJ1eMj10qhujь\ 0\(BҚV5>F_0,񖮎;8qLkDtVtmF uF͐ -oP1P52Es44g.QSЖR1ѭ VfLt':.>? j"H Q։\\RLԦH.(֤ ˩&_}s- zfI_M*+4&qdr;byJ>Ǭ bHc+:),8X=j-hvʺQRf~uuW_}?~_'r:>aD~i*Ci?CQACNѳ+O5kZ}ԧ "8dMY#&T ֽu{Ħ!9*եCS[~>2rÚ /t&^RliqVDe:I9NWkyQ`.lcV((m%]"u4gepv8t$9_4a nG ;H0h@B bljA`Zifϊk!8y<~' fQZkAUhDd"@,hJǙ+2b -\Y* D2F:݉fa5֙Mo6Ρ )y\kSbߗR\<$MFȗpҐQK_HSޕKTQzxr)9|RֲJ-cJm-)r T;bbp3Ƚ-!!-K t61f.1o+#猟oW^yNq / W]kYz2>P.Y?پYy_#$u!~R&_xHqI3r{ p~^KN }: .ErqԮֹ5}3y0( kk]XAgGfnZ=z^rC4:<#UoI9h 0 9 0] xJ`T!:IX6"b4# )ZY&.z5+Bxq V֤`czeJ nl"g$3P40OPyk(zcYdm 1g($V\|6 6oq-Mc!"2Zng96( Qlۍezw2}*Zh ְڣrFtR#nt <ئV9fTƌ4dV8Qꛉ7 ae?N]&S"থP[v]bSmq_0.ω0gL55evM??_h7s;9(Ⱥ0:'Xy)ȟE{h6&snYRO4:?ޏ?6s?8_Fk d%§ч<6s]/Ax[_{5x.۠S `l&F еR!)= ͞ęnm*EERE]qimjus3J-.^qA\=aR\s lnY,r," j$f ]oAQjqO,ܡĩg͡UwRP C#gpa(B"H 8QXX8D}ń?ba^ӵ֛YOб)K[E:ky(IЋ5#x3ݗr kCюK琖}{'#Č^z g?|ܼΦi<8 .~?~୷:DiYV|_ӽCj=lfvsFw1qd_Uݙ3ڔ/ɐY(FL \' c3`V;hJR5xZcu&!9gmҭrꨍ P8R fELh^ĘiFJ2DYv,Hq4m mc_$ME]Ba8~,0~(@a9Ԭ^]M2`z@6T}Hh&₞BX^vs,R\г6]ۖMyh E[kr(`IrJD&~\EJ(\@a*0sC>xDŔC!'iv+R)EyEЖ9 pcXkmIw-Uq»'izfwĐ7jY5 Wvw" >R' AM7 I{+f5%@H4Zلx-`:ʑ|16ɠSRG:a hA[niD[-{ݘTu"vF|Mw#:ucH 9d?΁.yg{?d]~*OQhY皘eG:fwY}s7ٟ{T&KW_}}-OOMF'~8Jm=hUѬܵXdJisbf0PXb1su{+eľCȰo܍KRʐ{&v;l&pHjihڢ0hqC2ãGԦ`;|\VaK?ֆԒCsE1sq1"ip~)IϽ6EKI( U{DjC>SY# YJҀI4jibhRukQ?׳MJohz"7#y5,D6qiB+iiOTӉ\*jH@ rCM;hb e?bRurb(JL?5vCZmj0SU*80gDX[m"F)I*PK<\HZ n]-wID _Bq9'GVAZ2emZ{D]!I]'^,;7N $%ڠJg )9ddKn5<"ؔ{9_>Oo9du"tjHȏ#2rRǙuir q r%("2v3Xkbc9gw߽WCED+&>Oxo9DրqKK׾Z+oOO\mHz|╗docnwN]id$n;xkE!1P0hZP 2.F#.-6̫MhyȝnIgYղ_QzЪRhJ5ٚYLD!z `R*wXz3qns͌~f=[ 9{޼*y8cxG6\Z`Pk8}Ly ̨7O0$SkF\?zy)O9rv\2ܖYLsCˡQЅ8iC&tO L惷,F o"aA@-8lyfZv<~ybZGQ7w|!דNna""rܬ§-@mֱ13ЊxwXtYUMtGǮPwvP74Ya/\-pC먂Qᢥ!-"k#C{Xr]; +n%16|VХQZ\ݝVK]N9ɬ*6^zI3z(H&k:`m㻦eь?}E{ɍy֛CK5'[y С.e_)r*={x뭷*_'?G 8r[ۓ~g_җ@Dow'O<rCqW~:Kx[Ę@S3ՍHc!{ZD U8p%>.U@&4En~A3EX,H)y 㠎}dC3!(b"Le" t#e* &eh^X)&D؍KJپwuaE(jDy:;=a@ */u6qMa%mb`b;e St-^lBՀSU'b퐵(i1{ 6Y0KM =rg(z,0[PZ"3Z-f+NMW\anFfEfv-HVFJ -R*,OҝQwG=xkSL<ް%C_nGWy q'j[@ =Z5D;z5QK4a B:,)dc#Q.F O34X..`w%fcE]'uw]V!t'aNOiVqss^xSڢ7TV~8i8P4\a6!O|f^C$* Cvuu o~]NxQGKz;Xzk*mdք Я3^|W~yrjK7nH4#4UiBoRwa $*R5&#>)7տs<~wQhݽs_ХÐunHN5w5~w~_ ɚxJuoUTSa%DȫA#BDidfҞi(s<,'Ӻ/MjϢr<1}WZgm6ֲqY&0Pn2Ѳ9gLqq\_?R{Z磤j)Onn^:i.8u=[%$1!5ST(ɕƾIɓ>@IUiCh%X!\$$H/QJ>"]H@z"Q &W !-)3t) 4YoyP{l@C+Ms-3O^;; 1 Q7#V<"Z N#ZRǍރ $ca~6zOeiZqX7# s֖C4!T皈ۚiUmBj5y.>iDNQ#223o-_Uo>.iDNd[h""?0W_p8gT~]/(PMiyeK9X"2Ĝ SKLu5$ÌFst::X}6VЇ=Z B42g9V[C [Ӎ]-,Č`Bv& ܑMI74ˡ;,.aRY.S{@bTp@4UK^|%\0O:7DjԲW$#{qO4&X .Z="i0!6"qZGW#D@DN43E BOKX Ec 1X9-jxsH)pRUQVQGK^Y|*-7.9k'o@N 2\Yj %r7LRPAUZ-;$fsZX&9ɓ5yՠjw!*M䅽e_ԑ/w \GԧuaM*\3l9!!`./}K_fqh׾_2i;(OFy16"Eho~n'K^pe# X#o_7Cu3rnNeK[?D&\q_09}}?kc5&[sç믿<WyfFk}hȺYk_lS }ȗŰAe>4w͈jA6q=,dls"cئ]_b31{F$2&4-rКA]Cmxi{QA~cd{Lb65ÀY(nGpmwLiHl)]S^ϒc  7\ ;pzj\kHz_x/"h׸Fr9m@luƝ׮J0^RF;>VzʣY>7VJY륄{~>HnXc ,&== DK9-vh@R $wv)Cz.p2+?%MHH#"$w܂ bCCޔ2Q>[-Rښgv6.y JoKxh<ɔ"fԥt:b+sk,d%=ȤH lL_Ьs=ǡo| ZFyQn@y1pq"G?>%:WPƿnԭַ__;ֈ'[-Y'U6&_|mm>&dy皐5 x*jrκw}/:%V?>4 &Rߢi]҈\Y##[)ȺaW5'6#By/|[~~𴘏Ǿy*5b?E $~˾F-yDܤ94S8EuaӮjc$ @('S\-ABZȑ֚d(MD<-R>HHi&4&gϺo66N U7G)(fI8ڴfN94 fu>j:=Y Go!g]#Dl\3AN|@n*SDovͨXZMȮ Yؑ)m$')rvx>HXQEg$q,G0v5np 7Jc"e& I(ʐT}!6N@JAja٬m4y9n䘤,BYQqn0GV?NRI 8 jxVnj;M)K(NoJUכtO9M!(UoL)Qk 96̗p qn)뉳oV$LA(짎kΫB:>A=5ԛ<>h[@ }C'jPpr(ˬb݂ok:2H3E?%|m}X 'V [ɺHTp%S#`oJ,sH"cPCS[%qV۪Q/n"aF Wgr&Y0x: #jr6vhRQKS:!Qś*KbpiڂBuU|KKC~,u?= `CV.v~_=%L)%/1#~zь/ ibf}>}{[=D{zNl@$䡯Ez?(Y1EY"qߩpZB{jDދc}z"52ֆ~? |MnpJ?t6)V[%2Sh/5 m۝*([AA|5r;n5w$F2 z_[z 5MX2}VmKMj!\jC"K̚w04y,׊5C>\vzC :9猝搀: JJ[ 9(țwŘ3oՊۃ4XHIЁvZ ߃팤 4vd&$yU4No Y{B#@bK@N1"ka! P ݶ\Q} A ^Gt1[5k CтnSwm hM$w"6TPT`S} щ)J?w"n{CX'Ptn MLCU$J@T&x61N"0W Gh2}EMXLaꕒ2&,1R5u 3cDĄ!=hqFZtq!81P1 maV/hu@(&VУVqZyό]'O.ܼ~bBjWBOcf\XTh"0i#?[n Pj4lN.k@ʖ_̕j`MҲ숈$8%MUO@[c61GM_o@GOa+uDO)h\&Wj 6=H'kcjZC?fsE+jzy&g3Jh^G#Jhߔ?l͊`gy'zk=B\l[y.7)-sg:dii㵹2Msd1^ҊGӲkx)<4dIBqvv m۔yt/OjW ].Hj=3Ɛl)CVtèXTᜇ."YLyC܄%u3:B6iTBg cb&)U e"ζiᕮޠ[uMe/C@['+1VʍIM~jZp`ח~%bGĉk,V'>6|"6fzy?3DJz(H%DSbU'dX˔B<0$n"uj1EτQ`ԩ륀Σm\nBsXꡔR_\šzzUbyѶm憖TUsVNZ1 Ľ&Umx.PkmTSŦU ?_8RDʰMRgLgQ)4Mm/ߖܖIQ5.7_C 4p_GL`TN@rةx! V7 /Ѓ &\ov"8ɥ{iFMȴ!^$nxΣrԺxgo\y886x m&.*\?t^DZcqy姼 v S]c$mC|Bx݄lBאc}?r|p7$urCʱzj9O]c>_|niTn̢\v|e.1\UEs&{0Nz0ؾsT*Zl5Eq 3\ ֎0&H]~wcwpU4u&! 6R`ê넒ޒ4:kb*gFfY$>ϛ-UU6Zzg7o^껶).O@ Ա&v>5B| W+yCHIB^?e%E{WkG+,2!GF:jJn %ХoŁ#?ubM %}j6D kK <Ѐ} [4 ġ柧0\b Xt]Ra7iz{ 4EV^fQr9*f!Mvss圹M8ݴ͉h 0,TcDju R-Ǽh牑r?)M:!.Ș+ a!5'0٨by=iuj:,0 En>*o/gR<<$Mnx#-'7־ۜ2ZEhZ(FDT_Bß5x7 nOH7dH M`؏˾ wu׎ܾ7Xsz]_Ϲkh}O_u]ߏb=qȏ˿.]"\ڥSͩbg)dI31M+uFd^=Ry5QBgx5|ckq?_!%hR3R?Rr!4dg諫rB *ʠ3G_\2&u|5'&bSeQ7% yܴhRL!8JZ*S1ae DrdmT:"Ƅ)1~[j%݇qsl5 )RI^O u~5.̩ mTP:,7ʶ 1#, 0dsqv6b(prz[6:([S\m*c! z{.Rً UAэ^s*PP.eDT@$h:tiԀ!f'1?D1IFn1iJ1sj#H;ɇ_c8kCE"ȣ#klFBm 0"wYŒ $6+_\<)7yVͅ@Bu sK Zڃb ^ Sƌ`PI2jM=k D2 hH<|Z۽o0.'9hør bzy.NEpC?m:}]\ḧiD׭"czlnុA<dC H%]L5Pri7^hN0ZZlpo#7A:lEh<}JIr +ME>rY_ C@r\iR*!N-Ym#`󭝎(?/kE&_g3ґ]-xF$ŘJPdC]NNSo5`\ 1"cF>L+k;$N9 m[jaN'!`ƶm8)\Պ|q[0h69pTߟT,|Ju/E,4E9"ńUR-1ok)%6_qڢJ%M@εHQu;/)=9ḱ)KǾ&fN'ӆe/Us:&а~>)%| ~ T(+¨D3LODeiSNnKFe"fT_X]m<>x=z [Ƿxχ7xx{GoKȥF8D;1ľgtmpB7 eC4!S͠]`Z' jjP.Te˱FHꋴ1bŽUmӪIucPN j1(׆NR!Z΢@#db !7j9-d642dz9hx㘣jD.}q;b^>I,H[[׽%\w rU z*4.)ʐZ A\>"/bdX^M8U .hD8k<0YMn(".Ӵ+ubVu:f9dqgQ~-B—k [GN:O+oꚛ7#=UaDUgST)/xȺ M IhDDy`4<|JkSMj`xMTW vfή ˔-LVقJC3/LBd}o{Tp i?8<}4!ADUljenև[C‰IH SU. S@Bn/x>LJhy4\b z]0l6moW~W{ΩYuR}~-חcVNdnwu8NEYwCu Z2cM^iH;RfEѐ; @4ǣXwR)eøZ6m:[жHDZ&s.9yz 0ưŭMGonGz,#k| <ʲ2Ar@HKCmDlWǹ֪rqJĭe=@lѰ(4aI /{Z=N46Ws8 &*Ti}W.`n@LmS)krmG@Bʟu>3}23]l]N\%6:7|<oۇ*(P&.LY\e}pgy_~ f$m: |#wtO5Mv/꫾ O{vDVnLQ$KBc'"|2r8!A˺&dݩH}\~ Y&^w Y 81(e19'uZEJIQ$9.Ȩ( ɳ?o&y N bepoq=yIղx1% ;ѝOa*h S@L#buoG[ܼn߃o=Qwˤƙ3ƀ0ZoC 3{8B4pi^u̒:oe(Fq.̓+{utQЦpM\7KK9{&뗵QBžsMBYF1*HnyV{v o߮j Q~ 1nFIMC/]HLr,87"UHyCԠ̺ф:h싦Cpm:-1ytSW%F6 , ph ;g71mJA舻hOVDd!eBjǪ.0GVE;4&h ! zڧXՄŜ4Ʌ45mZOS^paEVcrLc1"U菥{E[KPL*,9uEmlP:Ys h927YדM,P4Ϋ+.x_l \htv'BD|NŔ$ $Ēs*Vr >OCnٜ 50R(^6BϠf}BEDvI4ҝzrhheȉHHi$tsǟGnZu=~~__>Q%E>? BrjֱNXw9Fq}р)NXCDgpM8wEdK2z n ` @ h=亶ƃWA 'CD1hdD얗 Q`+|`RhCe!sa I*]gyO!d-cc۹8 АcȺjFPj33C8ɗ5j!~:P.BcԠJ"}SΊާ 3Vޚ" <1sd[;ur HsczL{<7+L"Eč6pxTlSN^X`<O{Kˆu8|MES;#OF3crWԣ:;w1`'ѱ/"6`؞f {W I,f@Qd1;=ܨDm )1Ä9$˶|)_wQ+"u5-.YU:ޡ7Һ)4:찦ռZ$'Ű _(TAN2:,AccDVj'BLXMP>'LKd MAuVڇ .p<> ƫ@^yH W=uO;ʆr6ҫQG8f|%L8IH_E{/?o4v. k2[V|W5g-s z9cLq1E{~qItX;iBe9uLrL!dϿ##qA<3=@U$U֯Rp G0B9G\4m:\R-XO ( hEGR>kr.x&]Cq)!CFj;2/`kFgM(Zud*~*pITM6;G3%M$GCe<3)qR5ClRL1[$5!k&8&q̯.)aLthTuCMzt-ձ3}LbH.]!?M559K!6`tޒ}! |"bXwB{ ?܂m4=e} P9 *Qu% Aה9y\~͛ Ÿ}vN NS\< CIv*gMDoʉ"3u[ݾw ØLb$Nu$*ͼIk*u)'M/.kSrRYʔ*IsAdͤШ,``iYh꺹MdtkGDӥ)Ŋ[XNR~g6:Qa_*IQ7OßT'A?Rӟ *QpNq)Dx|#8p<\H ] A40yKTNC l.Z'R*0H&N&h8O\WbGo nxs?ok@sMj}yz[ߊR5zQu^w)9V~;s]ueׄ\Dr(+M1̻nf2q%R ppw?TiVS6H~h m-Gꠧ0W"s5H[ih g_b nT2_ dMeĐ5Ps 4f(nڼ": N4ix\#kAMZ\jVO?g{v΁lh8BFVētpCʹhjjlb)fX#zL}9a #ڦ͍J$81fӶxѣd hz-cB(f@}ߣ:mƚIQZh7kyal5/*+.\FĀa }6n޼Uӂ3 v5v+Qvbqt9M<\"j@NG0`]Z\z W}9m)' >ӞC)iΓ9ka(}L&nB2͊c)۲kR ֣YԮVuB- P+11k0Rַ"Hw:C-8Xm38db?ay" lUMGèI0C *jE}Z$dA,/Qmy-ޫ yR`5I1t#j@K~TqA(H})քXsgЭd<ԳsDXV-JdQU^4^G+HP N\D6tB{0.]<é3ɢ6}{Ac 4DPn_C'SxIeѲꦴ̈́}2=oB:$Z_2AX7$ssc)Zw`f,-%cQ<υ9 هیkB(](Y4&ץH2JQrڌ 5GKT]h&T\3Y霢䰰ebvCSQ2(8u!JNQ=W UHTe5Id*YQES!l%&6TaIH<Zu("\g-蛲;\nsP(_kӈmE cD:V'Cd)%z(;>VY)PGk:lmEݜ =i 6h@$j޲?|lɤ$C=Z'.2en=KUg 0ˈn$='Ddjt+ez*fΗu-EO/GK.[KO4"r'MȒ3V=V:%k_q޿wu7J ɐu)A xqfwOx`ay!pvؼi\^ӛ645>rC#7{D0Q@t'quʀ+S "̤CF|N+Ãx˾~2ΚBXھ[ZczqW}d5LyBŕ^q^",Թ@'Z'!ԍN zͰAY">ӵʌA^|i8iI۶&ɀ^ʚb3uP|)m]="3[uwLP2_NE0 ʵPhG0 0|ĨH=jp96>kD{PBO{cIDAT7Fn:iLL+5"s-ȬF5n>NHwg~a;!֫4 T 1NA4v9 XMiAށewbk.eyU I$j+Lnbn7BzXx,rش16\dx}f,WIu;hw4)672 ǦҍU煲)ĕo?e%UD[J xϻގg7(> :(e]UyKciը{ gW %.O/|oҗ"3ܵ di @h8힃׽7'fmA9/$k|oWFz&Z:iR/Lb A9eo^h1i$p14*틔mu|`& G1MyvyV+V8J:K=IQEMlczU+Z*Q:9iVA͑:i@H ٣ɱ.xBCKkF$DWkm~b O, ֈeȇWB_ɏ\t7)Oy 소-o#/zыRG?3F}}MRy6)R@{'=ssCT}Iu1׃IӱwO=QDǤ!s8 ]P.3+s}P*fczH^+k-5ճ }s_5IPEQ^R"0*y<;W̚5Hq,(kzE/tp@(#&p'|Cbop}ǤWb]\MIy )FDMvU=BUYGOkn⎙Tj ζRӌc#(0YKx:R&1qq>d-{SJ('cE?kl1?l 1Fl6_"D7݈m?C}M|QեLV?3" fFiWq2&9ຖ&sD7x>kK+FWn :ANV-BB 4$d"O\#R;JHXVя9uK<6EdMoǪ{sz8PIQTE.Z)$ń4^q*j(Z"ՔdEPF"侘B8lڼc˒Ql]AmA- 0cΨg 9cI /6'PJjUIm!ʞ'wa>цMP1yrTB䨔bMKi2}Sqj֔4Jsj)st9)1N/i Jא+@J-mAQg7ahVn MjI?)qҌ(š@^HA"][3H]c-D*;3RԾ"tOHpAɫK, 0";Wl2A˫L$g{pZ > qZDʴb;&Lza&ЇF3]$YXiIF-gf 'uN[ňar EjaVC5Q9ٹìV2mj'O5R򺨍D0쮝yִ>i]J&$%0H$ԺmuhH'Y:;|W>ʛ1^1SB|?W)WPͪ.FӖ:8Ie/k {sn''͆҈~#F7SVShl2p 1(9n㖥])[_':tv}/{9{.B"ܽvj ׿~ ;n]_??ͦ OF6IZH(G% 7dă)2HzDZ]\a՘,f .2VUi~)!!a ZlG!wr!EU=uΡi S&NZY\-D\U˥2X"/שILj@!r!dU$%TZ[S,L4}mLX+c( n'LQQK&4OJ>|/ __  Wxk >a:QՄfޏM\+Y"Waʹ4. :@#n >yҋ}t];oC^Mo+^bv^<ǒニ5UoX:W/5NKɾz!9&d"4c(Z"}ftOf0BbxeGN Z5dUCɰ!Y!π3/ǬZ0`ݾ4kS2L3Fty.5H8&$u{(jT|Q/Z.Fb mЇ O7pb^eHe03!Gj?;Z8QWXe`Li4A`%ƪmwɴ("w{\'#ue9QtM`B$}#' ʐ<4 B,%MֹA=qȖ;D^Xۈr04V{M#27Cg=$얦i0l0b{-u3+(Mj_cVDMpJK01lgfʓu5jJ&C|+\~齀opI~W$<]:3sy\]a9LHP>gU]UQKj0PR Of>WbD.x <UNٴaK^HԵ2MTs:OubRH\a.47ۭ<ժNNs⹓OduȡNň.gެd^F{/~ٳu > p|\k7bzJX:G58ahD傺zy]b ԱN:p# S|g_{̵yf>VW7GJ|}yn'^?& ׳%-1!QE7MR]xjd(cۨc,S=Y\ZVLP dwϊAJ9`ɦ)%i(>Әh(|\xE!![!H b&>ޏK3 @JtG%HGtS; (ךcӂ2Ԩ:&S5"&EMLo0+g1![p m{^?К Cӌc^syQ^W>>>TPP78!EEiXi*D7r׈=& ދBhȾd8B%EVZvQ^@Dg5}j}IUgDW&[S)Y'&-5"p͚:qv蚠fbeLR[&Iψto 'с1IF؍Xs<_WiOb8(RSڡprA5̲$gDQQTg"k8qVv6$$a 2Aj&xq,n7bTB `D6M cu5=9̌[3Am01is 9*?4 I!K1-5hnt&CtNA-!:GMn@*xX,SdJLJ^"jAKp'੯r_{}7q^Вł ͰTSUaLgog.!Om0KPGT lZPݦA}7Ts} #gn8LpsZ(#s'!k`¢ ]hYIs.-s*ޙͥyY336N54$8[5<0IJQ9KCc}'6׏Z6/ 6IwyE"}$#?V-n50x߂8b?Uҥ XDBhHi;L54锖 ahQ,V&ZOw-1'qC -xH)>OЃ!LP}b }2nX*֭y_F 'f}9MrJ1R.5EAi;.}.Q5aoJ؞9NX=>)} .Eobt0#5b2*B㚼 N5ʑnK5u& ŵuQ*ϜJmHӠC*ya䁲^۷7G #с}j47g2$iTF:I!cдT(^y _O}E|'oo_~pA?]cՓj)I^1욲,/r櫷Ns(kƍMEȡmZI4%eI([ʔ%ٞp?w.ݣyk"$8Y$SmUT!R$ȅ 4GJM,!2ljqxO#݄(7&\TDurk b̿S`.屛L W7o;Iu2Y?5O VM@]RïQW5}L>И.\ 4Y^D,DYwzpaƷaRJ)?7)%oE__wS:T4ib|xjYVt,ۤu\IyyyMȝ!IF?%"y]7lhGR[9OSF>PJ'V_;TI>4"5ґpRtdjfbsEyg[aJۙT5+PLS .lu&Cz3{0GWp+}'{3ˀS*nTپ[pmsA< 3ZX1-(M~ccIhҚ ĕY è%/:1*8Bo1V\ʅ!"XrLl oۭ: 80"ƈJTIS ӓhUwtJhaڮۗ67oaoatLk׮# gBROe^ Ņ2VhަÖ&ڭ@O ?-8i /z o|K~%ܝdՈdX!2?hba^x̹!X9HBGBnQ|pL#+ܘ0! - J^ϺXp͙bwfJ48D ]C b,ةV9+5T.S,6iiYRnZ2&C27r0yA?AtgNJlN1/PqNbudj+ O`y aSko!?( t4^Hà 6c+6a+nˌI2D6p%@2*Su'8 \G+)?_?P9Ye|?bxpt[Yj~"xlHXqBOuQCJMEұ5e驗VX& p[I,&q";аhjUnMG:0ѕ-o՘ǣ*cdŰK>IH!t%kkmα#O݇(/J $Шڪ*JQihэѽDRk{M'6ɶFˢpN~z Fə\J4 Rvٍ+25}Q]԰D_o! ńηu^RMn8qn^^ 1؞m[ܾ}^q/x6{hnPWJ(rI$*g1Y'k;4aDHJph%u 7jZ8t!NZM 4D릘@.y3W~ sՔ2#9w7Y/G~{~S+ /Pv|ߙYPH7mtx~8漥trͤ!"dzZBt=mVgjߪTۊȍBHA4,)Ѷvz)!B B=[!:މ41$0dNhFjrRM jM2,)NDQ]c4 W lK .WT;Em2r*%mXI/t"/}!p4^dx#p|{E}^yC O.*B%k_^|U|q7tW73Q-{1їLr dwwJъ< oOΏ]jFj[ f~^ȗ~.K: +P>*־|ٗ~ r9UR Rh9g`ېKɲ>?eLN4!Ҥa!Y9yo ,SI`PW5;u^nd0ӽ ELjJӗI,Qg&Fr %0ɃÀ{C \FIKFcQF9扤*{iGS-ˀvD罼r([&b(SSѱXz=k5C5h`H9=ڦE4{-6 .瘄`: ?y푪`ᆮ\k<<>[öszyݸׄ&8jx^qLO1(")AۇbIPN\ew !CZOG-3}UXݓT?6r8x]ygizkc PB;iSUV_@y!S#˜0"gČ kխybuRz4~RJH.HRnfӍ%jXːjKTDg=pS ~Q@%aBUZ(ɢ 95*1[u3ʴs)aN]'z-7-#ix|c5_ pNg@A 0^p ) bө;RreÍ> /cdZ2MPZJ 9qJ1SD؞k 'zbL g }fɳzNiT??q_G s/^BH`ZrPA~Py#s=8O'sk;ԄÎysp Jrm>El&hLPI8)dւ հcŬi4{H\sDcGCCI;i8-Vb|dh_!r$#r\C`L5*L WR(U/T.d"'z87ѽ)RaqȔ.4ʒH%kX6:qHBn6h?PfRXAL:,7ŐgJK.ލpڃ8Spk0t&spQ39 0Y2vc3Jh=l`\8ԞfnoEd׈T+nϝcRz6`445)LY7%\G,`qv80[4omf K4NUu$( cnNDP4)1)K"Va |ẏm)  AAa$ 4!6c0 =8rkk_Cu{ @:[ O@I "VLb 7o7>~"fqm>t|nPo{BW}WAq;F-5Az&o;5ONt1$ẏww[\SmܴcRF<4'̥AE N#ΖΔZ8j]:䳩k{1Ā[[޺͹tb0LHɷ zF+uη9"y&hbҚ xË/G'wVqiqw9a9'k#2ܭ\˜'NXus)TIE,IFS>+H(&ϻiiLfh?e U{k|iRҲ(V#Ac[>s}.;}mDLWQi`w_q7iq7"55FM>T>>:y;=Hq"d{,Brk}IՋ9QYZgt$S~<嘑⻢T=M]jQ14cb[! F`ɅYl<1Lc؊cNSUʄf1W ;9B82"Y qB XE)m4ztX ݄ uB 9&fX$[uezܨ1(hFAZeC PԂ9vn* 3|>e03ڎtg8xDb{ÀGo lns{˴y;dcnv+PӺR6 {,cuL7Ykg-Tî"(YȢ& h& }RvU SxBZDV)RZpmJ17q|=XrFV vxF44$%ATjYQ5b^-\byZrN'^Eo0YAb5NJ"nL=̹̒)񾙠MNj{uUߧ.k'#n r3ЊA+ ~X^s^5HH4y n:0\AQ7@i oхpϻ.ژ`*V[[IE ЈFqъ 1h(D8Wy-xo5Ro }jP1#RncN"C򔢾'.1ҳX;@)ao}ླྀd~{P!Y؞BYla>iT(pBb!\YoGݞG%‰>50 1r6:Dw`ؤ'vAQB"aXtu !|=b:D%4 ea=sTGG-pǬ1}%gNDla y,]5c8=plۚos񬮭]cɩ9d%F}]M pڡ| vlbW?p ܎rȈyx8益DHD5";BfQn\0!(;J{#ǚ+~]sv3\ ?0őBNbqINr',jUo&DL7SkDg1-WZDUqSE"}{ӟs3 2WI5U8"7qrfԳR$I{̎Unu(*(iֵH祦d_ԤC+kT C3.r9s^r' K>E%+k0>X..J:ȱDuP@i(0MzĻ|[ Z^@/]|`e%:Yj*ߧT5M[QhZj> O_"y[5:F";wWGrcYe E3cjhYg$`~}?Е4̒"{Ѕ0 :AkGxmM!ΊC63amIShSmT62IRK,ۭt9yڦY"$ѻF+[cm65+gRdLff;uz\A/p hHO~0?{=Y~o?#~K*:Ԭs'p&I+7#unH, Wֽ]oj)]$VX2(,ݨѳT1* hەҘjA#4r"g0yGl*ն-Pmr&XgkgSt1M^r8djBz΍>b.BiGS3>z=5&ָiIW2V?f$g/ O _@'Pqpe{S?gxq@0BsP 8uiBUpx 8 ^)&di=1ʎ^dtvId#DR8& N}ё 5#3Bs<|>{{Gx|H<-NpGGB}-FT!s'̲Fd})}dn]x KαǺE!!g:/=tcޘ #!MM@4jF'HtUn戕C |LCLs8#grϬr:I!.jZ4TfSL,$U,g\?FJ#N#]Pp5F %.1 QL,{"gCYh+iԪ]u; *V5i+da9w}U1B6 |q>Q΀' w`/Dλ8IE48L A#R`;7 xR0xίqGqi+4d!P*xTYBTuPc1ŽdjAM'uqGQ7>6uK­.# g?k0\w&Χ)œ%Pm:+B8·Ԯڕf=G!\V τ"DP~,=&\<L:oZ(\}֮EM[C@ *`o*E8H1VSRp s'**ݩN6pI3Ayiieyz߀yQ bNМ&N`̄ipnݺO?g>y/ +tsF\H[ mn5x57 ķ CcE:g"'}D'b7ɤtVs$/,FnI&b[HgW|{-_'}yA:׋sr'~'0#`!!j$0_jP =Pr<}ciB5%4&NJ^f*Pa STv-+[kԀPEV E5̐W:g-d/Z=H:i kc:8&edRD1g!;T.d'#UbIm>*r=R Y;*Ukǜ> Uth4q]+۶z3s4Br Vj^ }o!FcX:=B FB#cL])sb9t{4Ц] 淬8\_mS^jZ5^8^7%pEo,:$rd⠅0(O6_9Y4KHZkƫxDr ]ybY ll5(2^ qcmBͥ@EYCYN)+O#aĨnRCQ;01+VqsyY7TPk̗,Hq߶mn (GLAԏ<݄֔88 s H& M_N=, wYp;tǜo]P_SW?|xsg 2udF"` mϤ@ gk£hAK=qyFMlD3Mf2RZUN'pUHkEK(m_ ?Ȓ.Z8/P~!?/ӽ cCMj>.b{x<qKEc>4$(Ե)ǽ1-[9tT_sw4jQEL> %IX cXˍRvI>\9to@C@H DEwcBnx߻~/yrQubVejR;G2ZS$l%_y*p@: o*4Ú.ؙUZ_m&5*mֵU׉hߢsm5bl.Y:4d:$V3j,Tn{HTi +D& nkHGG5`7"bD ;H#ze"ÐO"3 r,HS7NeX`E'wßރ}_7| ̀[}/}t? N)*=yCڐ;vp5D)Z"&g*{!R|tW]r(OON1)yuXQKbrN~UTl/N=$ϽJgM40oƔ/>-7TYu"4E`տ< mo"4kPw CDPCFĜF\!"bGſ~yp޸/QѶKTd{^cu!;m@BΣ-5"K%vMuv ,8YEꍹ%2X p*BuN*:QċY8NQTAN޹2H)EGcC)%[c p頒J#Ezos>Mc MFJ!D-m(6 5QM7a?YNJCiit&NN¥KN9{Br\( #<,}LDPH3֘: A$W]o_!>݋+ p C/MBRSnH{"ؐdÆ4Z~VGʝv).\z߽\Ά+otƯx%?މ;$IzYfГƭ֤Peёq&MYN\DƄZaW!]M.T6P]qGGwi'<5d3K;vs MM3S.r;Ǫ71S8! $1k Xm&i3twsIȤ@W ޣ8ڵxo|xsJqs &\6 z>( FA>xC@Jڈ`x#{8UrYѴ_TP~ݜmL0glt&F"5h?bNE>ƴ,Tbi\l)6n%/ >/T~i_7&t}MA]ww[[Z̛}",RwH Du;8tCw*P?ԄЏiBo鵜z-8jqvɒyBEqRx yz=/<9Q9`r"Q#|=Դ}>=MI%BRRT]p@v*Xc])0{JtJc9z!kѨ脜aqRȺXP)Dj6p^)- uǜàMc)gwv>@9PCZ 5iI"68Lq1eҚ kܺu CӴX: öaZr3_{Em?YY6bAVc5m ^[f>2Mj+X.M'fӋτubwI"S2SH(`!W>zJej$Q!Z }_^u1lsf䋍hh /ܖw 18 7nA /cvww_A\7$V/7+ 0E}1Œ0},ѤPk E" cJy >MH\ 1S#sqwiAС[$lΊ*MXtPYS,dp`?0whXucʴt]p";Wv-e0FA|ĝCRgjc$$p8*ZDz7UԔ伖%gd+TVjuŔVL0|و&4.a=^xN5@S'Fqb:gYX5:2}/'JN qE+٩T_M~gx>\H M6׭5&MIBC2_k!T\4oHG,FJ%wUZ^n :Z1t,Om˾ɹ7nJ.+9w۳sa"7+jvW0{|[kHЃE)k\oViOYNms);KExsTe7]s: ۶EDF.NCcqhcD.LΞRbv  ͆ҧo5"$"yx/ _ҏ7#`Dm&hQs|T"HH,ucFL'1(Nm4Pq6 BǀtSϟsɁf ge dŒ6yY# + ]΍Δxas|c{\|׿w?S,/iD6`x;߉W*۾ .]Zl\%7%Fe_S2 6[hPA3k_D@B.҄SQuڇNQvsʂ!8ӶMH>yB9kf䚒 p9戗|7&BLdhFe["h'm mH{jSҌ )~nrJ!`2͎RW"f ޔ퇛*δޅ)#%"cmVVm}!g1DG$cFÀ qbxC.iM|K&+')bSz]\5Xp.3Bd(WU)@̔\No7*Ctu] 6+l|ֲp6$ĸlHr1CHyf6"r!VHQ!&\"Zx+7IyZx(ISBԦ8-z>FMXyNdL5 bB͊7#$ yְ%dx/Y4GFsWKaӨsww)%++8d֍IQ}_KO$;GjAft! 3lg$֯E+ۅP|k&S$wCKIH)aV 4)!D1#$0#B X̢E%BAN-bJr 0:c8; Ɛ&ɜҽ딄4zq/#\Y 1*9aIrAm]Q7#gzJGnGhwC'~DFBy2B_#'c vBHc/'JMͪ>T$FBa⨂89 c} ) Χ5g|ǡD""+M=?bF?.iJimN{L1P5wHhI]&;5SdAI1i} *,]ڶ"p:r21'& #r}'>x4 <0G}O`W(zYiTLFaXm MB6߷tw~;>뻶xL|NSǟ6Dd~{ـuX3 F0=4[=pkמg⋾gvkEnPy32/[[]]뮻l\BGj:$ HpUk.uQCȾ}BiB~>5m{pEm Q;NHH5+[KNQ5 rHrd{kE%"essGhk#H4C~ge9BCQ 5D ?9HJI"}~>L*4\P>dc 6 u8yEE2!D&FiR8U(yT^!M'niHSJhG뛉cOb'Ib]Zim9L)Yg>ADV.r Ļ/7?2B .r0F?-U5SUHOVDӂ*N*`ܖwrL<)&\uU%Pn>Ҥ k<߀B(iݍZ1J2? 1  %N".)NB jj\cHQAs)" KX-u"b0i#op(\Ih h%yB5KM'g=a3q]ﳞcO_jL~WM NQlp5b+ͺ,Ͻ&Φ^Xq1 1ŋ/|_CGw[[7wuW`5jԈ9q߇%Tx@汸bK:8iZK ǒNd*ru^sjtE"CP>G&;iba" ȜM蝴p%=ɹƃcK(DB1H\=˜)N`#"wgw^Tc dm29U!myB9BZs'돚@9һRN &e:TIjzc]` 8 T._8ƀD6Ð"kL;6 m;W[~qrdr~ddhwuVUgCDBf@MG= C s4C:JvYP!qX1)! a)_)N ?3l=3qٹODʋ.7&FI`fVkVKMNNxNV~jҮt) =0g]i#:,qM(YP*]sۚ*D „f.;[X w1m͂"A(BF} !n>]/q$L O ~Qj2L,"lZpz}LQ#c2ErX;"$*zO`Eb96uO&G7#K}AKl}{ۿo~qzz:5=Аc4#9[Z~ ʾ9EуCѰфb/Y% ϦG/O΄&J2A:$ ^!'(GuLa<1u3ᅥ??]+uKxvĿx=eS.'޿ yYQ@cA0b@IRgo[2D$!TWf&NxzOB)ktc p!u iByqw9IA MXul)h8i& -sCScP]$̍ Qbb0h5Y:`rqn)y(Na8ѤH"+">O)ц@Z݂#@rxj U$uNԒ9{'Z0Ŕτ$44JLU7%&ƛ+t ޷;ypPEkwװ^RRUkI/<=EEPc)cAAKL?O2oL 0\j6kBiBiBk 56DA5X Hif L&&N9\-QHy74 ;6¼3Dx KC`gm, V 4)4Zm'89nz;fuB4BӔ}=ցƑ JI] bEf8u*Cd$),M$s5*Zvՠ? nn]V$$nBUBj49k=6 ֫bJa !bZkNЏ#p f~/_F 8E160&AWicRcռİQy9-&5`8ݍ^5'bINL/]KN1 p_j~^gWc I㣿ʇa_]s,n>䓐#r=ɨ8lXOipGfSڡ ? ىcu'B޸dqΣr"SuT e^{LWܼвz[3J)^v֎]s0&w0 `jf?ˋ0Ey'I *<~ 8T&LH7i~W߸ П'ϛ} ־߁I5, gl, %BM!04!K Ecl{CAu:&p_7$D'$fR@j)Aaj 4*MKǞi0'PpykZC`\ӂuf@UPdYq\:(. IS _pzڶ }.'͊5Blb#M+͒rfD4BI_P!;`ir " PRc\yva(, 4t钄 :Vk# $^V"`&i:4] ҥKh7aMU\x4MS%^k*b7o t mۢ8sWD?F$ջWk26,+kgj(ET5͑!IލHkD E-nv-'׾wY0G%/g8{BV_0 E^f -LEhL 1<ɩ;6#Վgӭ<hX >^@`;Cuۘ̚l,7wњO.LH|K\V|E  7봱e >YdL=5NW5_%GcBs ]߅oo cё yȡyᾆb c`!!ҳkBΣA-5KY6!>du,VwTٻje9lL]<LGss@pRcvE4#d>kUukNBiɀ+H鸂`}# gQ󈻱ƍ_q﫿It$H`FiL2ՔjjIeS{V qsz ̝+xe*!q Yª/J9C? 8"7pР ʎà5Z^D5_QsAܽJJ1&Mm[_'J~icO=0Gж-V'kPwԽCLfU~HAV˂!WY̢}5V~G>`!iD.,ʿ R(XjZiL8*RB,Sզ4=Xt/箕-EJȋ21Eч8jP$d/z\(1^ *B6B-( )Uywdc60es""rjH;j >]-Ps2>w9>a(i1k?[5\@A ##DC>x, Cc>^3ĽwHBi@Lp]1WN,FpۛͣxӞ??ȢaތZKԬC oo,5F}t9Ul_T[p.]8V' }Ǽ99,lt]Sz)yGI0ɧIq#>_Olc<сEBXwK#H㘳D9gBYXe1gՂ gp$wnmzkФ>8}q 9 *یE28˰i~č14Q,Ը&$}>p%T5rR3ja 9/e:F | .d*t-F$NdQ)"U;3yyY/6\_8O! gpIg랸6wJsڒeEm0b 1T !t"Iljܮ\GrMX2G:P5"y#\kX_V;_h]E0)>&T-d]Ybrq1c1 <_vpv8; hˎ[;E](y7kB ︄9A6*%.MH/+1, SMjh-W:xIٱmc晶g5<|*RGdnT_t=ڷg&6qpQ?2܀vҾ"~=={ݗ +rSvKġLC 뜿O@8dk&PP&yzLBDhTAmaP}H"  yv"Q:$\ԧqL]Ɣ";)|Zs6\IO~ch}9l]1g8o9TR G8D @1?B@ӶX:!smDWB^_9 d'sҷ(n<52"ʁlR4Y\M*1Pź5I )tmP6%qr~HjgEOEj"4ִB*i9p5M)4Ԗ+Ōs,䤢vk$~7ъMx3>_̵[PW`/ggW~XNu7~_ < mZ*5KEcnuHHފ!.1XyW?_ !u!%XBg B?S'st:wD:3Gi a#b$ÓMAгbkFR_|&rJh6Ø@ƛ lwgiTדV7D %9c}"rBJSbr҂q Nj=V5RJ^u^qȷ13(L LᎇwݪC6nBH={U| ÀijV;׸.fBK1kjsz a>}2* - Ic1ץѮї9"2uh{Oú!^ރ]ϛSvXUvL)Z3ʃd4=^(ys)o#޺F-]KԬ\s仿я~졢N*=D[}(T?\KY}".%]_YiQ3qZhh*8bX-s/ JZѭct& f4MU(+al)vUD_,9Hp\(1X7w~e$t TAЫj&ZÀr=cu]Hr 0` -NI#&4e0]Йj8Ӑ &$<,Ǵr]//Veȹ{ } EZ\Qɠu]֭6M֪5}z"F8=YK6J3ǰJlGEAT CF&%YfereA2$ \{1DFLňfLBsr+YabsǺs4"XLSrj ӳ~wL ˵@L { ,WȠJD8ɣh%\-HIpp.!rc ƣm$::! Hj<`ԍBRQv654[ -m[f)QHw^F)!AP=|ӢiZ)IMyY@HQ|CH3Ik$ VQ81_LtnprA=LP}V ̓Ѽ$\`NOq"(K %MfB }ybr^Eg5)X(aۈb{oz"db_]7!֭[o]UqE&NB,5ۀ>-ȡkr{ۄ,>HfOr33^YNvZQ ]J/C 5 F"74˯СIsf_y᪴ 5$u`om:7B3HHg)=xϿ 4G 'Q |DU VѷB\wrQT *Nʂ:UXN SkDr60 M-Q'-[w"Ӟzq +K8fFzH#i>4.zqp Uf!"סYD}3*Qe$,b1EjCmfa(=sT=a'dI4`A-ትK#B53":^(V|eDA]lRsˆ}ɂfYJr>ͩ/73ğhh.UA ZjjvǀMȒj׎&d!1$Gc9|0j$-:I,R8\B@ =h{5{{35涺K!~^}ڈo|<@ NumLRͧhZU[ Zɡ;уXw9F#%~ 9;VR)INAd 2LIg} ZUX,ޥ:1-7!dRUX!YCvwZsc`Cna'֮dlUY"Fp!=龗?wm[r/">w9RR&@1rrE7v^\k.wժvu۫nQ-€ A 4Xh&RV )37{9{G|_Ďgs}R-\;{ٱ,Z^Qċ^sGz\Ca#vm D0)2 ސ 4Jѫ^ dѸTgWBZ5~:bX FֈKt})b41C$L)2V !d^hKBԕr 7:,$>%CĽhP/U]mgzs2$E*axlq Gh-& C>-T5=8H ~(xI7fۀFҳR}6G^XRz.|)<9E,+e!9* rLO϶mFo $&"oFvYY Lk08U9}|Ѧq}L&pY7Y$6y zr~<}Zi"3ϱĪ<iqXsY> dWRV ,8As8˓\#0/IDATqg SZJ+]dZ`AAfVeĬ*> dx~ޟ]ɂ_,:׈D˘cT{wC6#~ }\$)Y8,A`T:oC&ߓ!Iӿ%P`i^˔%7S‹ Y3k\.-8;X'EpdXhß\O}]g@^])cv__Ngyv;D+:sw5p}EZȍ]ř!)]S\+B,TD/U~F>y_S+4eޤa>Nȼ-cyҌTEuVy*4#9E>X:`4r $MPBEkM?3{>ۇ$a;R3L!A26GkT$Mz0h6*nS:IˤB14dtv,9Ds< hB0WGSCS`dWyNOO<ͬf("5()ݺY,@2ly3'Ez}!sf} gI'kW,]z> DQY!-k&T^Z'@HɊLI-Gꄼ*-r3x+3t7lS\Ǖ$#8,Q6聨~ 7.&)si7A}3dj'ksK>` MӌJ*ZFBA4&`^{?̓x>L<.γ*#sӼf n݃rm+Td}z6"!!Har%ʻ, $w'"PFz&O3 ".\!,dm>zg]AKαIHR "[X֣8,:Xg/=ao"bL̵E¬! y-8LO$Ndݠ`ĺdz#dJ,ɳDNiuXt.%+V !{c%zl&҆ӈ!TzAqb'BF,KV"ѭ(IJiD 2D?9mbԐnchU|on"t3\riI&I#Fb}:&0Z9??{<~\`5ϵј(ń+L}ůn;b`1;!f -d2* [_DZL\ʠγO1M[ UsȌ^HUh׏)~\'X|isb//-m7#9 i DI DzN$¸ k*Jrif xq0#ubD$Y~V/,MC۶}Db3 Ih!vu89=mГSOZ(AZf+4GfgY}pM~aAU .Cpw*H߽Z >ɮ k&Sl"2=g\U)$mwNԻuAn4Kp eLE> MUZ4i`8`HEczd/ln(Om]Egڅp#Ptf lĸ489=Eu888aDZҠ̌]e&> bQ5 ^NDDo&XYoڜC^(_n 2A&ui)|ȼc68GI21>XU!ObÂԍė:s3^kw֣bΖ#L}X˥!H($;HiX?i`JP<_WG?ϽKf5~ uJվ%x=;lHgJ11G+9k l*7>Β-M p+:3Szn`IߤK9b (񃭮{*|.MH`LLS9V؎>`9g^߱] /S! P >c0 H R$Z@PbD7_|O/|`C$64*!xQ~1Vik4$=>D ;I9J8wA%ĘJV8gȹn3HKĘXZbqՓqttbg-crt? J^y$"0ibZ X+G?-YaYTeٴ Glth,3F20kM|&Oۀ۰eWEħ}w 燶LiO;Fޘm#J .vVzi-PdM%iCfcfҟ~#a`xlc"Zl±`.FR4rrnσMZM~[ ӛD8+:( ;粟%i;-L "X^AT~e͑mJ;yr0j͛xc,[22t…U^]ңFu_Q1Q<>IM|9ESR$K"%Ea,Ըs&O _ 9Vx`2-tz4c9߳sxv!|!)ѹ, r]zP{czh<vd]KΓ5q?#?2rs6ICtRВ-#ct6bAh:Z4!U-ňZJqk6V bC@՟qq ҿ+zp1V&p` vf8^Wn\l!DD~<|/q~MYzm+iOd lc3 !jX,5Š0t}/^`-`Ek 2#8 QZk0> /-tx.:z=vaprZ A'2HaBfֵhT>432;mOuMN | p1e%zM;a5 ax,dXbV-r1'U : 5(HS:22{tx;_z|s x? au"3_P-$󍩢{C6~)/%*\(_ q5y`a ":2*nSl5m+o~3'F jɃGJ*Y"5~ ΥG\djl eWDa=d1Nr/242i~R X[U3xRt6)\Ĩ$ZɷMƶފ9qD:V% c $ݜJ&7~|6|?) '{DdINa;zDIKCaK0l' :uYϼx?'q_0r#ʯ|L1 Sdά^$!O5ٕ5%:I}NuR 7**?˗GwtTr4ĈaS"`A6SocQb+JwBl \L*dHJ*:FWPɰfRsBE/Jc{_pD"YZw^Wp}PXr{;H|#ଃ MvIfE_S,Y|?I–CZs' mI7M%I4;q/\_cbAPf^&}c򲃠zI M}p}K03lpzzk׮R+2#UP$%bUzbX$l))KA 1飗;뻿y!w 95?gދ؝( xzVi&FcH-I,è1=9*fD5h 1.ՃKtc-EAMVJob5&{ Rw*.f =l1ꋕ90RQR(AjA@yߥ=IB:p 7夋Om:LH :)Q$s؀M GF{0|vL*mo9 s5H~)2@&5ʻn4"C8jϸoBxo3[Y$!^`̠i}2]8ADA=!^q {ǷGcrwbZMo NwHJ9V 6j62 F@vyDv} O ']tɟI<[wP"CYڬ>7c6?N3Υ3@ Jw}@ttc15!`0fh.#cQMc"rO--EKf s,oq{NW| ͛Iޔ@IhA0Gi<׍>rܭ_K10.KK+<|KԃEnlx˫y*5K@DZ-%:d@ %kOg0>H/X` NMS#KEx*5 xz2sp֡HrQētc$HӨZ3*loI7 a֘  EU%CQ! mMocO*e{#VH iBt]n>Gw<0΁4@ _2svgB!XI1pR uV,`EXg%T1{9E3 f11")A+)L*10i,@^\qBo. nj<^Woo\Љrq$x/#cT0(*hJ_GJ^_؅a.,1wI3>90_8Q2<(%_JZS yP )2.2j]-̀Ƽ ~Pc1P8d& JOU” % Aу~}p ?o]Fvm~ttoo!S,HɀLyC<">F,> 0{˞ KU?~O|b9>95d[ts7beQOI }@ `+=.qw! M6QMOK 20Sl>{? ٘;qEơX7#"#!,Vub1nFqu`:O]J $ǎ1afQh% byFrB@X$9#y^¬mJ .%n *XܪnMm. *Ϙ0wEN9hzn@-k8F1'43LٹwR!o̿3(@k-2ԥFA,g-lp/25ufߏș^}}#S@;;Mxfߧd?],2JvN}zDYaξ yc$Y}c;?hi@mTg1 E su轇@H#.nð8T\w]D,Ƕʐ犵`8q{]sqrRp9:Ba< I"~N3^8\ hbՇ<[k"ph,͘0UczIg_aA<8hUDD~~ОT(:ⓩ(5m pmpόӎA1B Qt"="iN#=A\+udBv4fLY7GVH:qPs%" B&E! A^^kL\]M &UA--Z۽ȇ '!lU6e:3(ISe d3asP:#Gbj$jAMS0# dǀn9t.ڢ"Č'BFL0\gy&r_1LĺUBfqjL 9a7ʮ$_x |cx&|o UiҲjd*6S,y'9A} @ɴJd!sw?x`a7c ✺T2#6UuS9N%Ū)njbYiur2ӨM[qsةu63.~K;yc[AA&^ab8}g}{_gTчq~kd s%i@?ɱ:Ct]7#p\ AIxO4!{1' "]],`շ}[nf`d`/pkaI4Y[2`3O HZ,Ncܚ8ga"W10\8X"GRPO@"GDZptu0>$ъ,X2{f/{w'jd#R")=")~7@S'6h)Am`ym7Jɜ$b!RzA ^mm"c60AbO/#6-hJ`rz|4-35X$8 ؒ,څB6']iM/ZGJ|Z(eD_̜9 &ɋ̥ -/ YC uI,oܵ쉶%,4-"'s W7IvgfLr<$Ӄ3 $Q%Z3IѢ-K]=OHѰU:!ڙLEX}.Yy@H)pVH-:Kuy2XzB|;oϽ4z֤CA<& i+2ń~~9/'Bc$(+3Zдn`p' 3ӠhM.?*07$ʴV2`#dIV{HφY7(~O5?$YF[i(&-,jX i]"A?.Ž熷% DKa4~jR1h +o#UHC8pk׾(aѶX.z|Ѵxz1u-MnZX 8g:t :k`XТ2K-,}8BH`Co,*@p0}p 6DbbS?^F󟍲ɟ%|ntG fi,.606O[ 2{'%v^dSqJVDcmRv`uep EE>w!6Y%=<2çbӴTflN`C{mӢo:rkl: D5%O F}n4Ft#ɬK j|Mo$;@l1IΒ>A%7xmMau̦lU4*$'rS$a,3ʒ*7 au.; 4VRV5 vyCFK^ûȾ>"g'+:+rwLY's@dJV~JD5Pnr Rѱz3, FQ쎳e9q9bN:v > Ng)$<=(6OVIi'((B3 噟»>? ᬅ1.4)B1ȽZsCMth`Cd?$e1Adތ sòڲDۈz%rdQL*J^4tLJҮJj@V?70& #)dF]X6KN$:,] [r6k1888#zj[=;,-_ǵe8Dl0"ä,~jJWĈOf-,v=Bws X=o!G +Qt=$ eSȈJ( ~Ȍ<&dP`h]!*"ǒܘLIƒ7lK{m/I61eЖmbR2 $ 8>u:iݨ+/5{e4byKR8fSP1j;6Er';Fbzσv!H+5M<8`ң,5+pEѾ dqeLDSO/p-XZ5Hj`2RDjV <@,_bI ,2Gdx~l ©vb\lH/ œdBG3g"H2uޏ*/4S\pZpId(1D`CKZTx={ߢ}xٹaJި=^^sD) !7&7Cu 31"z"0R,6WMRA gj9@h4!ӻ,b^[By=q5,v+64Xum>=Ky62c^8"E2b}f9`h]vYUá;IW{n}L/]}'k^|kVG>vq+ϐ<-Ŝ]+?gʶf<&Xq.BjRsNoRf^(8r &/v@Y B+##)uq1BÅv"Ef 2$[#_YȁrɅo4ŁUL9%˘Af`-[jjAgÒ=xFen P>ÂlF&nj@M̥cv2fp\nVg ~r RZo&؇&- $j6Es:"Ld x} ? w͇gX~73l::;}'R"Sms0"7bߜ}@ydV_oC=tv٘ Ǚ眜U.8k?L֗/Ȭ!kz>G'os3+ ?LӀ~ZTY22f9 $~5֏cs:lD;~o{_G۶`Bp0ScI;dsD˂tԙ CHJhIkD} t=ڦA:#lN>߫jCҳ$0xy.*J ݚO%)j2M:q||z%!Y ,%{8lXA̹$!"FEdz^gIAo~w?~YÒY^*$*):D(wjE< 91k@ lMswH BRSJUҨ=sa+1Z'TQ3]mMDl| QZdci;V 4 B9)* sģ}R(q xHuB*t`J007&v 1G支Բ( dZXJ/Mn*?FQ`XoI2%٪nDƱIp¬AvפDaJzZt2.2A:iޔ<#ihexFs8IzWNƟCG͕I>`kkWr T˨Js*$u/#rYbWy= Xʱ瞙ַnv62laIWo̭E `8p68;:=>G&tlAgBt(΅gW&RgaE3t]ąч1X(e\ß]HD~aX,:SJ%H`T!bYT؀F)[cfp 禕Yk9pʘ _3Ce׮]Em+}m^ҳ 5-W:1Fڏb]3\! l64m.54MU>_Åk NޏT|} ") 8I٫bRߑәFe_ F`-{p }3?I:~şFV D|"9NyhBϲ)cG`eYU9R-E(`l% jz$mF8ʷ#)?΢'ihb?R4] j0 alI4香~2Y/ߑ[$[Q} N6 `!},5S~?$N)}k|5X]m$jg+o"ûGb"'@Ȥ$2|s1poH')7Y:Y6mn+xJd'XX:R-0AAX7 j# /I$:P*x_*^:ecj )GاU}N5':Oj>@d8(. dL!-o˗o^h$1(YX$h8򖋏:y}*@Ȝdy SKǂ[ ͅ9@Ѹ<_K h*0Cz`NkN^#xqţ‘5pB# K6mub h\BA>@ +R3D?EbcVjmb }$ɡ>,VrkXgG#nMdB%C 5ԃQ!DXRKk]],pzz k$u`3h՛ ўs~G 񤀊G&2AK.ԒL\\@θ1q׌Gmpآc$^#b> I]KLq1XWr,#IG(鐼g˜,"YvRU!5Ps2EV\/L;0.x33 i0MI۹<2*(: ^{1=i#wIA!i@0t?g9`=^nAYbC4<Fnˎ)c_Ydo2bB**Ll6xߌjn֔sW#NΑπ[i)gۦc.{fc|Sƹ{^%Kcv 0NL)Ѷt- iZO FԡQ rlf0XYR,ޅGxpxBQ N9$SW+X-ؐmVaz5œTR`#9+91i``Ӊims(YďdvY,888zo ]97ഹ=jnZ0Xk4! nHڞFuU$Ljr;_7'?Fܶ:F5)2sEFz=)6 ?b"k0 X>+?W,*́ _aHC@P"A7R.Iшt#K Q`2LG9ve0_ :spZ#F>/I}QݰM(SmG/1/0AFӌ0 H(jQ 4@ـc~'LCcgzG;Wۂ K, "oŊXYSlʭ|y"LKsco;LZxАfuHBFcd+9pTg~~=)!=\ČH+'Wy#~ B**A^#L4Cv{58^Ժn4=KP,`*>,LlHFsHjAA !I$3$6ޜ $\-`UW*'&5exXg(HqMgbRYHZJi |xږz{x+5 Ƀ\;鏎.97AB:q Upj! Y5i)-y X i$NXYTF9 s!m@As}jFmǧ'8Z^@l-dFpj]MC*箐t9-BrB1P+t +q->ͣ [,[U'[8 2-9l)LhF';=CjX񪂃6XZJ @n"\8S(689]r ,j/R0LCzTr"COY EW#YBi U^16D=R<VΡqFYa&œst]!`irW`lЙ"TpNЂ9%Ntlc!#dJ] [4q c`M!Y.c4mY Ƃ-[Փ _z?^j3I)9!"2ж u9`m^c#8 9/7z"$2]VBtI$cw8>b8p ka4A\yD4,4V%# F!A%~}RF#F[᠑F- @\,. Bm#>RBKqGfYo\">\U/?CzƲ!~h?{.9"\(eK)fE 8d%b[` `;>8F1I 2]}i &'pb%Yk#A:t]u)))=X(˻h,k *HcxpD U+}ȇ`@Hd$0u$M!_F/{YfD~@Gl6hh-$gۑR%5PFnj@ ϯosq7pumm'!50[RK;jP2%"EtPyQ&aYHa!#%@TdBVmKaDw9Aeoo>x"7{*4t؏9@+wwy~P;Aɍx<9gbU??W44֝Yߘ-C@Xw"8xb^B/s.%ѯ("~,y s"{>JO jquqeipyp!\]X*d a)lV1yƪD-_!w4yő&.'g`-896]~E4G)defHOB A!wl@3OmFIӶ"URb2%&U!%R' $pQ64XDgB$>26٭abCn>1"(g kAM'ҳnI4S &'$1sm4j2"!SldYlÕ^A) 8u#P.1pدAp.7ݎzMobA乩}gN9`250$7"ڕ'2ǔ+1.P8* ??>**Y "WEѠnPbM1+Ln>Js4O{(Y] Lvu"3RѣsH1îs.tV\s/D&)U=Ɛ" @a$Mp)aܿ}"Rt& Uq 1DbD :M9b X.C&gnAN %49e7E!K^Gc \X.и9hz^jsp ifVk-ڶEuSl"#X``&6jPgQdzVhe~ mU!71c32gXD߃#^|WkFc GkG 1q}=ňd&$pYzC*LI S320C1`# 뚁@+7$Ǫ@`Byp/nM%ut7X2b!4N"!BFv!*mb9 ቬgxI[1,>~U~F f-7.N!kSzPTx *SMTSq%kauiFK='mWzeZD%:lE3ҥoTꆴTms!ߓC+B"( t| ɫO!mo`@YwiX)ɾ7#F}Y.Սʱx;yH={iCF[s_ n05g9_TO0oTR1=i |̓;M쓀 G}My }Ղ|;F:o둞FqIA|ڿ%@`/@ xD psx+]G)/(pZ؇_'*' ~L^јICF>4Z{/m}/ PC0f#zagkyIba |߷\&OkM_9'lH#tk8aaҬz:EWf[4K1aM}\ #[7S-VqTBFQ-%:ġ0d>0b`!O@Wx{|oy[7 .]bCj02lɔl|mqHn&dYH D<O) 4('kAHf2TavBjUTˋ\1&؎J3)e44Ru~cM0GHޭVhL¤HKS,@C%Y(EWp@ G(/D򟉌wGH&Fl1FA@P_$wf} SL:Y[1Zm:'U\D^pF!:^fHacWy &GðXLin1€¼َx]i[|[SM c44Bvy){AmG9zf c''C#F<2KYϠogQ!KGv_$֟y'& (LOK ct7Bk441?8p'[I7C왮F9*#d[ҵéh,JHn2lɰiݴn$-! &"6g#1!T (c?7# .#T_^pdjƂ >T _La ߂lOtSh*RgI5 b[pE]c|b)2'c؆c7}SRt`NW= mtfH"')g127 }^GGqrrrS V4ċkO$t qJ¢HqwQ\#˿xOxߡQ fǍDx@ȳ*,'-I'/#xU*!,K,n%فg3}B:iE[ͦ[,=Hu[X,2HIW$zp }sx߸Oɴ.z͊_#O%ه o~#>xS΂~|Rq7)6DJg |TT=b{ CUƮe.R–-s?!:,,G5ؘ<ľ(sE7|*>U'> <k?2Ő"ijWS'+˺Ӎ|G5O={mo?ͭZ$L(W!%)p2b'&%P7| >'j<斘չ<DXqgsl74bΣ>'4̾x<ʄdСQ@lHP3;+h@$GKjRlms!+4PF"Iùho|fPȌ^b<h\El˞#' `6%s6+]UA=_u.4Cϋ5W*)b`" Ųi` SփcD㤘0EJ|ͪ!z#6uE1 ƵQ綜OOF*2NL?Nb)*,cU֟y//~ xW|Db Bg5J&,Cd%5K )X1ǡ(sS#''~G8B0C޲#=E6` !#e7Ƴ0J y`{hg՛D 1I@>rDbn*iKն]h+2l6wpP 2Cp)Uǩ\:5'zB![1 Reyi00ݶ>/L~b*-۪Ӷt`p%*쉪he +h$JSp Tlb$c>E ?s/?|~>Ї>r#}zH޾ FdYH$R7 H >kH%ľƣ>e S[tt # 2/3pO=TgX:{xz՛TkvxLuLEpЎڂx[P;@muK{)?s51T :I<u%T'&&)\s_d,k0d'"^"~^_$ ,KuZ[^̌EXKO2I*XO11l6p(\'D[KS.c<պ4x i}6 MwA-M# (2v@h700%=w3Tlbe>L1?F"|)F}TnI8M& wW1fvaV|~׿3=NicaGD|PTV"ڬ~55Co4'Œ&"{ْ4*.e^;Sx'H k1ZH̬‡:i!{/3*o_f/xB$̐)$sEzh.jL9υhtLbZJ{\hE0lu ЎeO2DOEJX Jx?H|$`&$RCXh7ȸc%+ŅzN2\ȲӴ !l#%},K)Kh?ʀc_+roFQeQ%Ikդ)ǻaXV+aMтh^Zt#BijX^$*5~NJ #Gp6r)mѣAfmqpxӓ@o٣mMFeMm$1<Ë+xdLz{z!Z^m[h? Yl/=?nq4܅A~Ji W6Jv )1;rS>s3~Y4%㐫jE"?Ti5-쑛s=r/l(Z.2y}`bvrkG`-`FAGQr!)AF.*zΆ3'K*&fB<y !˚9{t}sJ. bUzã~}Cr7 \9n#S+2Rc[>1@ĹLE3[> Ąlg߃'6S5Lظ^v>DD<%;R䃥WkbbدП^v {Ǻ=y>໾ptt4+3UWn_~"Sgט O}S$/rjl%191hb >L4y_ȄcN5 B&H x1n YGua**ea幸յĩO`< $y߽#1B 10l5hǂlpqgL#JW8'bY+1>xX`58G$9t5k{Ѽ!<4sl9m%*P1F87(]5c2d!814u!ldwzē feJ$1sńj*(23 00ऒ]mI*SK2e@AZ-٪8;R7h SVeTf`ayLAֲip#/W})ַ/9^nX}̱"sf Dn@bInD5FO|_3}ۍy Fˀ')D JFX`N*ۺ&:CϷRjg99g%4&ф'n|#o*6+Q RnHRgŠIB$ %(#HᛆYkgL@û{= dJrVYpMKwE'N@!nSr>V=saB ,K6򹽀2g 1m,Y_4C4V$ddƀҟ/yIK4m "2$yM:]Y-:³NY%+5 jAܧ,)J ɱ1@E|ya,L{ݳF|ˆp4#ӂ᝟7gʧ#7=d`!F PD n_5&i%9(zn,p(fѣuփgTlr S>pMv,= h(GuFO!=E/o"x[AF'g ~@$ %c@3*(Mibx0v`_$K\)Z99(/ o lnʜo$A(e\O׋uS@7udaxτg6^3uɅ:H_ L[DJF!74&:p- +WtE}W x+F}԰oyAǍ<'#êWo;o:q$)Ron1SZa~|=M1U(9nh+:_@HeBRSz@ <}zrH YXj`0 ~&?*R(le0DP% ~\.Q%QKGGa4Md'#IYaS7p1JM_kIpY6$Ylд-ߕD !*ǍBNNNdN[4X`!>^QYS7cO+*ݢI ĨvmDu4yd­ 618QLF<c95Eن\ ;EV(&hѺ%zo$5w_sY2իL)!K$,#yD\_€l3)c~ҟG=#jZVQ4yLf^#Wn%1kFŌ]g>qJ"߼DU/=fjeރ!mV};@H-O4tc{lxz8'K*@cTg-e[E"m,эzT7ET+f銲"Wz@Ta#_B$ E/҃]װix=~Ußzl{{ߋ=xk_̧؁f]., dِ}'!{/y䑛~,jFӒmؖEQ e[@5#+הk2"xL˥E-O'Q!M?wLKB;0Ljn )# ,59+FH9%+lWia7Bi\^R#.JSlNgY/zzgCtX#sL^KH4@l!MXhjNzڶ7\.EJKctrWIJ 00P/.G.;ROxZ 0FxEӌ;|د`G1K%\¸%$Iz F_x-NiqE͵U5˗J33VuH5 tM [F;'7X, יּiL{w}؜\ƚ ⩃k=g[lb&x}'s:I`0D|H+"npE<?FI^hAW#IRDb!'m8A,"Inu :5,ፑAlRFfw}X] `8˾I+9ذ@L%[djԝ!$QHF '؇]dc$à IXSlMܖm!u MTUeQ8d/*by==kIEH}t| s!o{%~#|tw oo77Gqh |5^Sv{D >!~YW ;/I#d%I6T+I]EkW'斫e f@HP^3=gSg~ eX[=J} 2Ԣy/,ha%Z>hOr,)c87x~?9E+J5Bit = Ի{-kIqaâ!7+&)>Wgt'ȫe %a$Qj}>XCl6\x fӫpG`I8S,/Cv"77J4DrѴX24BIKdg,]Oa { _8Sňmы6暀!kZ>ncDCABԮ7>uݳ@;f[,zG8 8 A\yfԔgYTt!|#9hIvetHh4C2G!COOD/Tm"nXz%1JiqΡQf!Qʏ7ߥfKd.0r*Vq 0$כ7=զ"lcr;M-];dNJ !(JU˳&MG-5ؒda Bmgn;j7L{Dxm֫cݴ^>Gs^wL'Y>W<ǑDW*:#aKiզgH(h@ cPs/ ?˸~||A8up\/tLד(E#J?\"9cѿ(# 끠%j>OH..Lu&5W40-VFxi5cB:3()KE60Fg?h'z||%Mۢd!d\ l6k0DD-nV,HؗKl6l6h$U)ckw ÅgӜYEZUSqfBDA#5pZF: 9Y+LmN/#yRT4 V:?0кh8O}iN5(νy_Ey% ŦuWt7muX_p9E")k<ݑFN&7 H#\lOQuXn}gp>ݾTlC.dl3!SZ25avCxΛYOڔtl8IIb6h,"hH?Ej>6 x0 `"c/"WAY*vuw z׻x0p^c{uFn|HP'woxF֯=s@Ѡ, EV=Yz'엦5)-/ M7I r,CJ'jDDVŅ&f1,C1}?(z/ \Lf<kӹEݩ{C~ea-g%l,AYmབྷՇTAZ1ՠ.t)ޣp0aF&AT#\ι(@I*%U=H RCLU'E] cn=(|B J4'wܡ1E N,"+ݪ}tWp;z#^xg6==Iݫ/[ɿlfiHҢ@EHoF1eځ dmv0UBkS)0DZ tD%daX/RD{ E DO.R rՄaܤ T.VeY&_"m%Ia֚ m7DƩtڶw6 %o 'feH6}s_ ?SS`[N4 h}6%~, dCFrJu$ ʄ 'x[>+J<[тTðGD#b :=v'|k^_w^113++_es=:u]74?7 X03yo_8I}`ԼH|A+Gb6 +rdy")kk0፛k` iE7̆z ͍PyW13 $j' DVcȯTUxB|xJ @wqB2D=b|$qipPӬjQUaA$KZ Sγu rXur, #`jw<O&Vz7IZܲIDATOkj/ضH1O^R*`HDXOp !vm̐$[i9tv0=Yr \ڶAk=X `XQs2rH/ae"PѸLPG(g{CV=9f`aWd/L1FĮ7CR I^ib "xuV$iT \1.Bf~HcJ? 6d˜U!t5Q(|r5si1@h <5S9_m3?\ &JGi@1*GmSH&JM~}\ma.w>n񶷽 DK_R\tit7# 7ʟ3 |A\v)@Ɠa?[)Q %(Jj2#Ŕ+/[Zr4Qևa#@Cí`NRIUAHֵBQ,,9FW21gC-BN6#;kmhr4Z3?%/i冝(R i%s瘏f}XۈjRvVy(l,N ۋ)y=g/5.!%1Bu;kz&Uϐ%YXRHʄI~n7 Wa߀? M>q++q… gFT a< -z2ϽAk[pw": `A 1"95%0ۆ`8x.J'y_z%[.h˾=U1R}򙝳sh I @ُ<0!!Hsz̄L[ʿ㥤ER . 0HQIe> ='B,X=%Z6ih]'۾+eyt'95C:-dD+g8c6-/~6k.Z44,7(眨m=oM)fPwI1>/}=88z^hVK&++ R*1+ˬeȺl sp ^/sooopO䋠 /S;eh^ybY7U)K21E)"NO"$$.c];P]:lX&QX)J kxLQo2XV2Yc0HR1!bm^1ߚɉ` > W9]ah-JzrY}Wu||d"ޒ|Kci=ua!m$͡{nyKȞ>`j[ZϩBrDM'm#k}KhddT'Fsa#nV_.L2O,?K_~W~%_?x{Y YzdW#{ =~߳ԫ'#s`{pUR7gAej]M$_ Adz@dom>bCf_76CfYؙݿ:W4ƭN w9F $I|(ұOɌNaĔ:XCw|?,iOA/cUIl:sHdž.t>v[ZCf( #rFˌLN0Ԡ]^.}庀KbDQqm tzZcYo{k ua,YV ?+ϣMEs27dT!14@P謂kڵ#愌y8JZe,: 0G4w>|/U%}%v3u;2#CT/4J*ɸl&ʀG``BG>_eC_?O3eTXg>|3.x3n +IM: {GG>|_!81B ?A!GP,0ڱ<"f&l5db+ՙ,f:f{\]dnչUJ́E1%H)AJHӲ" CǕ,b?0 Q!L 2ŔF \|?^DEbeUcYnVj:dE\x76>iO xs߅ʣ <݀a?fRNEJL2KZDCkͼurjEUT6Fh(˔|L,ʳKbXMDr%2B4->*bx3-bԬ*&f9:Kn%PA Q>5`HxzϺKH۫˓7b3|y9dk>f6lfHcS{ܬS >Jb~=!Aw,![˲yZ1Bi9OWSL:x?$7@ΐxx%q8E;wr(hȉXGB^KaɌ>HRj(P}ʙʘ|:.TqB2Q$WljW_tzhiɒ-!@AQO_$uPuM%1RdH NX0^mW`%!0k1>Fə5u]Mסqq8lX:=~eb:ܽXd_]#PnV7VVC}׶ݫ8̓֍ιe0ESuۻ_oz@c !2c;.X\Zo"^tWw+ AR 曕ԡafb-Wo&N6"|M3`8p8lR;iz^"ef? Q6R#UQe{HA D1lܲH>QѼ κP}|Bn'm%!aITLeDbHzG]3{G9 nG7}E;AƮjY,2q!zhݡ?m{2myHUI.f'i_:ƒaHJ+1Z,GA 5K4-&}%ZSH||[=5[q뭷bX?ID ]nɂ]2O K .^oN5QA!f$n61nA3,M0|L`ׂgPُ*1v}OŒ%'xű$+rҹ= %AR#:C!\4tI5ce }ߓ1p$U1@r@e089GZڂKr ,읁ѲD;Db&H,m2vo:X:l:Ij1xDsNg`k4M5 f{p2;b{Qvgc׹)9mH@ohq8="$`4V<.L2TAMFcPԈE jpǏ=B"0^ ߽2-7{;oiDkIِͱ!5+:?$݌m35 Ex+IGwrnE6ME)QU#W˂!E=IDql(O~C355uQG+8 `"+KҾ`V2 {"ەҒ Re=\C.s;1yncw]'ٛ:y!涊lv̀VtPNCi7 ?S U@+E2U Bn-gP#R1,kI#؊{j: x 7x`͸T*u'],)V@S g@ uYNa n: gl6׏j-/y 7L%s.@2J~|#Ú7~9R|JL#Te8wY(PWVo/$hvsqs$aM| L;Ru #L w` YF0 {͠ O9o%*&! Ƿ܂O?g>O᳴<("Zl rO $ I ƪa{(<{9,(/:]Red iaf4 \*%j%9Ҧl[o=q@<11 v"IR.`U;=48%beenx׮~ k 1DhS-ƌ8dt1;E@`Hȵs*8G/<%l|KK A>'Ǖtfޙ&ǎ"5KpViv`V2Ȳ0$Exah*W$ b~:ͬzm#e}{v|}ىi;٬^ܸ:psA4egAY=h=9(p&&ǔ|k ̢( 1'q13)XDR b\"DV'p̛Cz*O$F*d& 7ѷ$ #<\LgX(@2Ұ]Ku}D~Lqi I,\ ߜX_Y\@8_oOWN.SYd9 kN >/PbJaE/U1ْ9{0^!3@$a:XL)L̬&N$cO`q`$mG8~cg_P1pۡ!ip>K0#A6fD44d3:dD6 @[,RBlɭS{K}ʓ\L)jx$#ɩ1;Fd89U:\TkBXXXmc[<]ޚ$FsY50%6'LtnA/체Q+v &*呣Ysk#lV1DWaڄnLTuLɸ(9&MȔca>qWOKЩ7$9Dӿ4_sm&"?%|$j.,Yl[bޑѾ6j{PoOOY\Fsp{5_|ހ_d &g}Y7x^ʮ}. ,Ꭳ@e (uP^t cҠB%?{Fyx@3@FǴ|cY*(=P$na&"Kޠ S!E2 prt?=_"v-\(=#}لi`˪"MS!Da֟=&/x6 "J̈{8&9&a~M hz ֭|XM]=VUN b9r(et(}in#C[l7]>Ct躕JMWၮgS,s`h,re3s1A>'` ߿G_Z4VkUY#_܇v/sS/͢/ح`mö@ d/ SIsu1H5y5R,^iNYLHMk[8h(KtSIHQ]tu$)ubXbD)gl[}sbMO3EϹ$l 'խRj;v'L9SHλQ<,vI~=M1(89O]7s`n !9Wd\dVuMU􀌢x+(̙*CPf=R*V>*'$ɯIF!R ѣůA?;aT-`wb ʦE:50iG\^15dDS5Ema!hW'HVTy1MXk^Pf'%mQMB41Ag cD#pxpj#.]zsz"UrIrZ|/4svuH.\htY Q â]$:cѩߦ52EϦ  &9tz-hc$aQ K}R"t8_O!^oǷOq;i\dFE;0krD:mKȈy'fVD^9@-:ha{ KvSăq`NϢmuC1P9 r`ݰ0p:E8|KZ#ی)쳟$x]'#FIMdGU!X<%_e-C 9)YOLDznBMt`3bL0-J3{t`:.%Y!F ۢݒ!2H_bs*bvyވ?;ɄF@ɾZSf/GྠZo%(R:)ƌ7C:&sȱv!y,x RA!U,yar d=ux0Q Saa)5.⽷Iu{6^1<$qhF@AAQsBjZgٵ},-NW+tv!_Wދ7Usd98 (CK!`yȗ\0^&}d#0FsXCo&sGd4pNNN`,ˬƤ:}Ѵ./IQԀe0/%|Xә̩Àb^cѴ8X,qrz\6JTDXeнo!`Npj:fpw*i (Md5&nņ i`}13`2fS.|,&!G\{O7{eh|`,6m i/hJpeOo 2C$YFHS+ziYX2 F(_NqyY(#[OF,'znM$X")#8oh\8Xڝ Mْh$1N/q+;|)e>{4MkQ>Lүa -+M4"c)Nx/wG; v`Aʕs5hdf¶q* <=EYNz?q܊v ҞxKLGhۀ^Nz;]ے!K"a͋)9EeIx:+]"F\B$ =6ۃU^ `. 9Z{s}{ @Lǀq')WIb'v!0F#ꑐkz{םsk9Gc9|wg.߭[}k9uUEiJnjHnjJ^dIkAA^+F"O߻*"A\JҞ;fI8k<7h_ E")GoeКnB\,ز:Ζ3}nno< ^^U JfN8~ɿne{wAR Rcz`d cH@Ư.%z .]70S-;k 0X<} ¼5z701 Sv 1Àဳ3HP..A!`"u)WH&Ks 庴TyFva}4{IyrՊidUƕOt}KXo{Xs6Ѹ4Z1}C8|6Z dfPJSfY $N]@^Пh[0-ף~*_Fm @ v,b%4r͊,(;AiR4w/+dk6 1Œ׸ .(k@ZX/N IFgجH&~ER Vu N RS"u ;jִ:Dj}p&^@Cq(0B%TrpX]Jv{3 ggO\y5y5(ȗ* Tz˙ڝ*)0I򐚰VNmlSY1Oykȑ% ]kLu":Nou] CeKELDKoPx+?r}:47* ֞ {*/2g-Fe}LUD %4E%7)"єpd&8s2*in͇ Mgav• 9>D"gƣK I svvY#uץ1I[4BBzL1#fDXMeFA+ =Mama=HVGŊ-Ea.6?0$$Jc!3Toj;o_$1\@4fy]SAоoTY?!;(uڡ/HOlxֽ 2QzlYWZ, hC JԑsCDÈ\mwPvB樺,͙+)ҊbTH8CD)Gk6M>$@H[5"!y¶؄c]|J 4@ǘw\We.t,sZURgӆy|*e"q#'8ռ}QW@8Ѭ~W*HK_'o||i̡"f 7lZ$;o)Dz NT}*sep hZnwOE-yա-а! fotYuA(ŋ: C WSF6ގ~ۿSf||Sg߃"?+Za ot׈WPB·cx:cqFi+_hs(A-:={ǭ.Wk-l/9OQŵC5,fdUw;ĩS}|f7AUbDi@ C9=wD 1RVZ֥qGuH \"ܾui'ye\W \{}xc W ?hQꦗxGq|CSr!N4#XG?Ѥ(|`5E5|&db 29U3Z"WB ۊJ? Kn^~5驑'5&׃F7" yRho'e(:pdMtezE[66<%;}4dx~c5Z4ԣUf&DZԑr^ki9aUCF̎W s**RGDe`>?߆w|b`*1di@2͂vkFib<3}i4x~CP1 (z\Lɥ.Happ4.I/JMqs 5FRR8 s"ϽvQl[BP$ RP3c`1&yOr|/\!UҀZ5Z;I[K6]|s%0b%5 qp%d]6pCEMU4., LTQK@zڷ>M"U|뗟w}kqBV7{TQuhU(PBXG>UBitPm,"襄L3\:h!-ma^jwKAx#*|Hz圁@ TpDh\ŮNsEǐcCR\e%:|XRB3B N%H&2BEYbs[R׹xtU5T/ٞm |\5 \,0o*8"ܬ(v"8p1'{7;ISE~՗rAP<%.YдPS)NRL@UΈ6db"FG>t.gR_ R;͚w#1޺3~+=U7YyMȓx%{5y"믿u ǠB+ *@'G{B;~L3rEoM<5xs#j x,E}bh8ʁ՜2uo֯]Bcw0R$p -\ BT\Uz 3qQ,jFQRQ7) BAr!ҐtqjR;>YjA4gf46yDGjH$Ca \k8 iÀR+yf⚕3R1#5skW Hp(Y #6 9m8`aPP.T*C)qxRwXhiӺZr%(X(ؾW|sOg抯z~}_Au#ҚAi&fU@z{ܶ-]]!HL3(y24j烾^%Bơz6ifr}Bh~ݫWkBnQMu6AkipAW{>s{Sb TFYj;ȉ 3{s3!%5&4 s&O2!*B=:lkK0+ ujߤȽmFid"4N1J_ iDa+ua}h4R]7$D7׌8d8-_J6 :BK\x-P+C?Zs\ZĺP2/$Y!vLb]1k>p۷WOD@uX#Od+ #|=oDZwc9Vi>ň c.36&7ҭY XȭʹZ+ڳ ?u ;- ߵ&D! *͆)b"XfB|[dOR4 14Z:G=cfQ3YO0#5AUv9"@Y1 ϒQWs,. {,9K1uAUk^ yph Q:{ ?`4~ap~~+Rquu:i-7wZ0PA->!3sc|hxJqPLD:HJep P:TH]l8t^$tVegybays~^U\OwI"5\3`߂|oo⨯%Y~4iPK4;ϋCBQk篙 9*j+7ҜEXdb{~z"-<0]q8M9jP]?nƁП\๝6ϰzho9f | >qL>xh8xdY"(Dҵ4>P(AE8(ZYmM' mS.oL+ZҚ̧&zi/nt1?F3{ғ?9 5\_1p)Z4\_?RX˴Ğ /d ;tr"64y@=|탇x߲0x5r:r뚊z"#Vh@^&IMŮ0a"CX2|3 q'n+eb=9ՐbF$ea׌, [WuɑeFkV,hauv-Ѵmp7?}~" w)EA/B(iTgs Ti8V[4LIfѤVJCVZ8n0(DŽB҃uPI1&Yr?1thh!% H:V1FP)`w}q%=ϒՑ+jAۋ3&ygggV6J܆x~.Rj1)DqW\QS %ąH3nJwkuե&RG]aC=bSL lΟ׽9\SE;]?m??_x,ήi`˿욉| *b7q;)篋hlq1g !lJtn*Q>j ѣp>4M5ʌqHzL^evjH@%MJg}&MXcF ݬT.n2mW&r8B~f`;b\rFrt@ 緞G!SNRr"P`7#cemMy>xq6\Z.Zql7dvYO&q3^ArS 隑2R*|Ѫ٤qΊ6 GVZp3QB $TjATUO 7~ VŌpy݃8{ݸ}<&fԯxRF@^+JJS߿Y`kV܂e%WWam6>pnmsD3ZI^ů"H;[5(_glk acͤcӃRaf_`vC61 jP*#jtԨY$4g {)č=RPQ0ٴ$ FJ$A^j\J$i*ζgԝ 0čXp 0q@AK< iq&d9 ~?#3̳ 9a #1{{|WD"F.(ӗX֑۔dsi"&1%ܾsח3hP7##ޚr81/Φȍ5K=[ƈۡq9 SFzZp5@ό!sA 31 gw' ZGffYE7`LnFb WY:׊0 FIJRS)e2zfC2k$HT@Nh|uzBJNحo'Vaaؼuon#m ~7ކ8|7c<u\u4E 8Gqz u<ۑ^S p%+bQsR52r6/8N;!1a85@8J"rrB~'3E+gfV44^=NC'EsGdC(^BjU19b!QCML^CW%M˹'5.{;S5rgD֒=mIz ф:`~/ ! BҋE=txyz:NzS3r#=49*V7 B+ξtu&]6H Q^eYR3Rjg/ :{{QA7A-"%,W130 ʯD8^ Sڐ?OrE3bB&jvoV)@tp&]>c8c%|/geM Tu9O!IZ ζg`$L=4(ef㪛VP}IFc͸5 !s4SscYd jt`u`TˀIjMۛ˙ j5Ko7.А\ӳ(TL.e5mѾnoM^Wm1FDT0ϷKD7%`cEߵ!s Jq]KmZ)B=*vψ0D`!,\jKy6;nID\Bڼ "BVqXT Ks%-wy_gdzxZ"<_f bڧ킖tޚju??BuZ9l-u^GuE@+SE-sxB)'Y'5{m M)T7[rjo,7=Oc3lEes^ Zfii~7j<8uW҈< yZhB^m#rmOjDַu3>WMT txZhX7Ugx*w TqFO,+ݕ̚ @T(Vtek8D K]X\r`HMxa2xNTސ.1ӉȤKU(:,pVlJh1Ls"Hܪdm%5QfA^r 涨H x :"$O)aZncR8^(f ܺ8v{98Ls`To\\jQA (@yQkCPӲH -C-:bDBE6ę0*A]_;yFX#lRY/nUԭ+>£ 6BAg!?NqoF䕾p^x蕦F&'vx 1L9؃4U60+zu+彧[zTx₰֊[Z**@7>F]G3<uh:W MXRT fC{6(#J;bzOqIauk!]{BGkZy>ڌ.+4OЫfd-_7d&$*H=Mo,:XE5߫;Pp hpQ/eڀhJ6SdJK:yzw={q]$@\ZSk}כ~zbRdoKR֐Pؗ@ S!7:nBFv}.2psQwrRuI -*Ga9O&:"tCK* pPEEiA6ѿnsjad>W!7ň\*!!hE=QS+W* C-LabsǦKC !Ĩf 2A챘f!vX RW ƀaH 4i>ƨ*% C;$> s\]_crťqEuVJS|kR99cG#%K]Wp(tklE{H)a J[#BǮ E]~7%lb e|HmN`"vk]DޫyoXp!4aeh7/fڒb& À??`S'"5I1ho/Fݱ=Z4LOucJ`?ǚ&bQX׶X4kcQ?XzUJ+?A:#'Q BΒ61XhI &$6u+p@]4Ojc`SqӍ)BEN6Y7XVY/Z/5%xZ:VƗ4fVDjءWTp(it]TzJT~SCJ~jPWҐV]Mȫс<-{n' _V ԩїqNd<.ST'yS&{X.Ŷ_Z]F!II:6p GNbz-K>9b+<邀W_6 qqR7:[N)DU\Y9QOFl4ׂjJjHY6ТjN+WTTIf8HSP;R^~EAA[劚fк&qmkDCȹbq$"Y3 $_/1*v+(-Q%_ã\03il1& sJ {ՙ"/Y9T5JxifʓCՃAqY$^~~|⅏ybYQ  ·J×$0KOMyI\"Z5(m^kfgII70x20R+ KW0F@; ;SǁPWXte NhEbI[r2&;zb u|KMQ?V2d8•R78dӉDg%#OL|>zzkfڐWKz+Ղ܄< CEd) uaqg)3nMGiDT#"z]ZܨV=9rͭu5r>[vbHkC+Y̕bg|s~T].K )!4YEP"2H'zHw-)űgi=bacB͹YKv4栵=;;y͓йbJ 1Ԍyٸ5+q5 UB@R*!$Ax&}NJ ӄf~uVc|@ ׻15EjMX xc[k)M=;nJO:z lHFMvE0"]PZ <#O '5otrF !VrS6rnnYUn @"ܜN7ѵpLâ4!G'ht:H/FFcIC 9 ՉH /4䃋 Z 0Ts-g~xVBjEiJ)o4keRСA՞:2dNq#4)]HdjQ!-bi uJniΞ*Q54jQCLj~ъ(Y̐ZI& 0d a49Z܏[kٛ I]T[^JJԃNʮ2M9ivhy8\ jt24 Au-V"u"it1jJ*PO'1 DjF@Z gxS?%9}V[-J`. 7o#BÇ}3AOQ*:z`!M%nqu?0WpPÈB Cbe8{`1lFm'^ dq1i!Wj<n#I 5r(MbXҺq4ĒS}O-ڨyj),,Tf̵.GS}owcÒiC?H3(H* 4$X :io'ȱeMˍx^b^=Q\'8f,}Kާ DQQ_iцI.QZiX땼'5~9gV&jIi8Ha.cBR (I1ւcݻϠ-V#js.xML2g`6IJi:!h]S 444Fo{6\Po*c Ҧ g0sl5n+J{ 4>DX93XKQS!F:5 AΌBV<AA!7Q`5$ R@u\n*sAVFR;?bvgHqLQ9t V *6qGLTNGb葥i\zR(LB+ݸ#>1Чi[XzWc`ac̓G#ha3 wuz8S' kw}m:IUcpYݲc{oб]]WXS8QzuN>c549EQCʮ3祙" et TM:dY5 _󊀘uv7̞QmʠH (6gJ;TΉ19bZ~dyb+%3c&(N :d0=K\u8Zmb+"IuϦi4!D =n]`vTJA'EzwHgY$m49;w``'O4c&bphٙd9<,LnVܹsfԺǝm2㰯RA[l֢uG縷Vn/Њch:7鐌ae;$xY?ֻ_׿~/"g^~eܻwOh#{&S˪Pk")A&DL7YU/Wpi&$7-p_WeWnU0v?Q΅ut赕Չ4, l,kDrBrV^ pC F 9u}LRВB 9+ RXօ!TN.ؐV 劔Em?`= Ҙ9ȎI Uծ2J!*Hi@e>a[5Ⓗ(a;WDJ%0gL! 8ӁCOX@`% QdrO =BWW)\40v*'rH9AԊR0;|(Qj֐`w0Ϣ t.\R56!5XKv`@a0IаL>$G!8o[_s|RRxo o_B,@  ?,DM*ո+̉=TOO|D8ܰuc@N.4M]Sz.bAc4>4 N?Ҹ ^;E1_ѲTPBmXXޢ9횳V+N.Wɹ7_mZݲ)k}z4 lwO5 vn^z Z^Gwstg|c'=CKN7ѣogP~ g!It?7 βqZV興`ŌS5| 1>P "T)(H ϼE>i* xX R+Lm߫F"q}(Dv `O5 IjaJFl(hhUSSٓ$UYh&b #-8&iCJf );C@Jyp~~H4AS9c;Yi=ſ6ZC9vmI>DnQ{{$ >n; #$ 1nRGHz*iC)Eur{UҌ@u!({HDY o}?~7 C'C$Ll͘_DJoVDiZpB[g8skWI~C 6iiVIA=kk׎t\mtHA rwsH<ap84$!4 4Zj]/ZQ!B rC3!杸W{sZC\/"@^t4y`f#vCG+Y㗿[?֏# ꄋSVAK(H '~T?rD7 x[T}'h i)LiEAaJ?B' r :E85ڊ `B+~ ay-k ױױDe7>n `oZ1 r;i =YRm2y#z7yZՓ2fnt^z O}3h#+"b kf*n2Ͱ7;eaMytװ0.vȞBGNoJJQaiSb!U\ u r͈?ƣ| A' JTdDAKbzDq D"X:*pF s%$U34  PQͰEι蓹R0\px%@<=GD&VXƿ> '.i=kv:HQH(Dx"_x;=PPWݡMIZѮuz 3l.M D)4J~čMLlES6q:, ZƂ*U wsz`^ B4[ÀôCIj6}9gI5[;tA_TFFY(*f3l;٢q3/[e1QQY)RoB=ͳ k Êj6i1EOa1i 8^{U0'f7de='`0u8]q$oJl^\Mn\SM/Qpb¹BH\PӎЛOЇ.3g٫*xY!-4"Oӄ|2l}{w,,:J>n N$ qYJ.jfupMIjJZuG֢>!H;MSkmnHCjy Ҭ(';qQ f=I# -ileWoS6Z}Eyt-F _/b3ZEU'v tRUĩ)E(8+26cs :-XQ LgFӶs...pܾ}8d"Ī6!k^/6 á ߿#['5p&f< lA.Ju֡JzLOu^rƢ/tPZRH|LhCCK5Hmcec5a~e:L=x1:#[J/n6+0Qe-ma0$5Tx& %a(n4im6'q@,G0{?p _3 80CVH6$bіT[)QLlͿ ,@W}Wk~>n_Xӎ`??QYj/Up 1i]c%? :X'3{c( =fsw k /ӜMfVv֠xj{arcQ / ƈ;w- -y\!]R C^-*JQm>>|=e4:/ W08ф@xE_83ߐ#@& _e%X#G'PO",PoN^" RN2E3",s*Cw{.1 ug,귯v^-=Ǔ!'xYȒuOMD\$A}+qHnP+0Dq*LY2&\R W*4@b$nUC1W<$$ 8NԘ̘4c6KUq3pÜ%4o'ܺk. f&4p[Ө+_ՆHJhQ\/nRñMA;ay۟~.8|3çq|"Ӳt ,YCЛ;O/h J9M [$tas{)bEvZ2NͭOݔ-!"+8NCnp<Aܾ. 䂜sR3VSP!vSuະ[C}>}䛞fӼbi(_^|U/-ynZ =R B_Ӗڄ37fa]MZHAG>gT 肒e 4tEצ]k&8Mgl-G\˿_NhdhJc^AvEQ=ɺ%E. 7U7x6|q#\^^<1bWC!z=EC^IS3 p8(ciҺ PWڄMMtbP8Z"sAɥMPy1Fv-Oa ӳk5E_MF ߏKJV C_%vYۘHLЂu|kFXk#HڌjZP{.Q+2]ۖ߄%E}BV'GTUMX ὖcX[RKb"ހ'3 @FҔzrG0NP--)ik.WWl6 pvvJWڄq}}~+{\__cnuu76gػ1ҡ 6֯V%őfm/n8WlX%T 5g[Rd=K׆ݒэRjtCAaME+WRހ@E*n"g~y-Wu$$?%yB!0lBTȡ*\8e 4Uh9'%[1>Y6%X 3\ x({,A,>.w M]-å PQ#$"! A&XOàq [ H&m,"EˆËy_~H-7M6Э~`\ʂ ] |jrJNKeQ7֩1f%wSaH;TGvW^eePAiJǦ N7-5y~@Ci8ѹV±~(q2Μ7!QrOˌ074)"x^Vho6l aXzXmf ks/QH- rtOe`+k6ۣGnaګ戨JhcM&v=,߈1F~w2蔋]@6F} ή-[CXp?E>wqsC( a:VN]Q2pBݗ%NCm@֐\7+ ܻG6hIZx;;;g2 M'bx0!f1"m /Z3bhQQ!atUWa0$ a1ɛUDz*Ji9Ia:`M Nv$'OjI唏On70P #餜H!4?vxVk| -K"N q)/\C {D)~(gj_PfS-P0o?}'>uA?OkM əղn2VX"IWPȉIc`͘RAYpAptQFr憜HDJY➴nlR1l'5ކ4&4Emh mH w=p@ubIfn2=|ZQ۴HNx:C55gCmyF=@& 12xp'A akBkcͦo*18҈ay;^+asr}O>$Ǧ/> FDNPN? ^γt1'+/8ޠظ3hzfyKS$H刴T9gĈlIK&Ռ?G<%*mP:ǹx;^FnnRF-$Q(`IEvþM._OTZֈ]멅P5#B&E4/4a2ˬ-[ӿ |_">3vx_ܞu{{ ǦSG hd#i+'&GZS\`gi5kTխ5ll+imM~8c*IDATz`WhjőMjOd%4-7Л3 8)`زJ 0hsΓҾv$,dZxOC:-ĚRӳMFt?fdݘ؅x}H8,noxX U (e+/Ѕ`ClI>:#H%,uP k,)7lXֵFh \ kX eu}w`Ǧn35wRD~A kfߍCIi?>t(BkϷl9Py\#3WBe qYn *wYC RWS/~?PJFsH\A(ӡ&sØ5G +DR )qQ ƔPZvh!aH@o]\ 4! Bޜ Nu̬GCTiQ駨jo;֘l8k=;C^"'xA(h|hZy"rȵ9p#kGPPwk w|W\NO6?!\p8(\K_4 mD LwBI*1QJo'O85 dDJ׺18FͲb[ooIJ@f-{uM~ *.B6':AQaGk& M0$YhGqם)y~oS\!iJb8ׂ\a80cHZU*Mb4kw}[3B|!mʝܬCh9+D7*JFK9 4M֘R߲flS^L6eQ\ dXOf\CGbю@W2o}XqȚO\i2OWN Qѱ>uRcah)+;>vu!!1ꕉseZ?k&2kEn٩Xd5BXu+G*!Vtn vk I:$975)&Ml i涏V)( J`$'PQݿHB} Ytȥ+# AQ5?v a7F({(`FҚ*$z5Pn{/ѓ4=풝>#k(Lw ;Kc=8`|8w%knIVs2jo 3S#mJATn]%P1kp5Vww2~7Ư{oߝO5ւ7X4 4уC1Vv}n$ "#rAβGD]NisG: Sg-Eވا Bڥ̡s+ׅE炲8qM\_w?8DM4RʉͯokrCDmQP4/1D̜ACDp O2e{r>)E)R&2cЬ0bovOatJ،T8\{?w8?섖Q6P ɜ{7N/9s.dvNlRwܦ؞ \ 6tLZW_Xt$t,^$Jȼԟxwq䥰nN|5 d`)X6B IC]g[s|c?ikC ;3<'Z4'c@8rI2$ȻAwckzbZwt.- N4+;?ɪ3I3iuaQt'PO5H25k!L_]/v\L/ v_ lsA7 BjJF%cԣ:RUdх ۈ}x7GC DMl>BЩU?C~YVI&FF 1.X aQÊel7:y&61=EU%0R=z=(ՋH4 B40 O!kEF\0Y]9ϒΚ Zߓ:a*$9l޽PJ9r.8;;C NI,ϳ zQP<6,]7"AQm4|El6-[.Č Vg ӵ{3͹էkj),kI< ;s 4^ l-_kϏ샌@🏄/3nm3/aqqqbrh}LήY7GKB /Oc ӕBcpG9bNg 5"{ (aaPkf dYZZ1De~>$#MNh(]aCm̅C6ɴgδXbA):Um(q]G8>JjjNh q.Q jBvqaK?h4J nvմ!hcwF}"J9A[<:C5+;JRhYEp͊MjUyIE=/.ʪ۵efm$EﹹKL9ZC]+ߨ5 Z?h/UV }bN>mjN6 |q_#ouÂ=(W>աRGMqnmPQ[Y!X@XWDď/\n۰ϨjmPKkSt8:sc5hذ:>N@!w}(\+A 4c3d~V*/LE-3\\1#y.HCpcNѳRB-^1$(sņ*ډrb=!wf]JѲNbfݼJW7A.qL(%cnQ8{Mm+8f#3N3!&i@ Ti @Je+EjO@:;Gn8K[ܾq{ E5|  7jr!zs0Yܤ wY nm.ov_- 0;؛a]i9XcI[6|۲[K픭u M0Z94]n9oV-&nyFá"e]hE/ֵzW(Esc9̴z.7.Δ n-Bo9kI ).ޏp#ezT*].XA\r층&/S5<#jr}}q1F0o-(VA "J͎>ҩ֔4}CB%eSc #/1}?H-\PkIohmBB XfKQ.vW뵵0:deDk-hS`W^nJ]Ŋ+u4{W+l`jTy\@6*-++1'd-BӇDapG?\1bL1F$:D!| ,kk t>=Cmbޚ%nEUrbٝ5B]О\i0x!gY"NƮ !^^77 jbbQNX'9?1[۰;#%EIOZX7hBe'YaCCnV\=ZMKk,Ȉ4&\QV:uɪ ,T,FCr;*'|߻P.ePj(4hk956=%ib!z2Z]g4*T}/.: Y댊S/pD; PsT/EݫQ$]qPjlNTyeF),ꄨCХε.db4 5 {)q0ѣG(`n],EJT:}֟ űOL?ccJxϬ'k:P1 iPg=z$8 *Rj#5(ű5! %}D4)eAAKMK.f ;ۀ^D|3| ?4:44:/V*Ww=ar4#*з.H ~B%9zH:[q; CLLkxP-!ϊ.xxnq < +qbi1! 8G%{MycƘbwjsnADگȘ.n5l^ sʥ,-6ْE"\X5\T/Pu)%v[þx5K"iD.Eðu_ ocg{{xW012-&^DNfm+j5 2{ >r',mH9ŷUo{\tRZ3ph5ʆ`|2@`-j]L'손xAOfG}$MC(Y  %A7:EuP ˎyouY! HB A-u;5(yQt-rGHs;%`-+bMCGV F`G1!VĆU.0T*Vnq9PP }T^)G߯,Q%Ksj6;Psk4,RAY4U3oKTꮉ< IR!Fhjs ,4*upB 9kȦiH(s^4$u  Yid27>7THǧh q$(G)i((UjbQ*lZWK)1qK ^~o]aJn'Z;wMH1%i£q}ua0+Bf̍WJiÈa 5m&1ZlP{}}aA8@punY@<01\Kц%KœΘGO¸xrݳ)3uW~2 I2FropAD >2i>\W%#l.i,Fk0=Nߪ=rل,GqG^gQ9V[֜N3ggK@v whfB;L hQ>5=F&-?l9Kr^)iZhi0s^d0WarTPhJ4}1.c:lmej,g#9[ɘ3y¸5s |'~o,S>{BxqTZr+.݀V@kcÊe!ǩ̆jP/U˂i9mHʑ] ؜ndYs 4UX Y)EXyֈ b\/8.PH.M9?)a|yV]9iUTdoNpZ \uENg 8Ehr˝NwTwY7khRЎS߬@-Q_,ohmqauKTws{uSGA ˓X~ms+q:PvrǔE I&H%TV8DԳ?>{BV{@*f~eהD(,]ؑE. ꒆԚ{Ws0޻dR)& bѐoE}Ѯ@HǨͼM&=%(17 ׽ T"ILJឧ<ܾui}nR}n61Q$ ˵ AbCI]w)5di`l[bdF^"id4l j\ 'UT. 4ZPje\D?6*%3^ /9ʟjQkht:HhKzS-NaˆDpZ?Q:gX ! ~ \W>8|ubuPZrsӏp7|x_[_ukB$98 "7R^BSu#oZoMu65ܚo~]5DRZ/кF!MM+EfpTiMz.Pؽekgnt:(2sw-9WUWƝ :U:vul<579+杺6ܤGu"ͮ5C@~E K!$B@ ǃ]t Xs ]ڞ)v`a qQ"(jjvƆc-^k1>*2bbt",Djh2nܽwdZwgQr*?;?G涧n6e;wPJEĮǟC7N k{-6Ml=އZYie逐}rrE@!,?_7%)~WC}[ Rr.." 1nk0V iP>?Ϸ~Gkޤ+ [ez^gh;p>`9Iiߣ5]W.\ZHTu(bR.܇AlbDi\_1,ݴRF+U _:թWFZ.XwQ)mqaw)Uj6֊ 0ͦM@yv(7&l6#JfDE  U`Ea&ht7:_X,J[ؗ6'"t2^m2h9p\Rp/އ>~x8. Mp72j<q]>#V:I/p<\2&ڛvT,Y1G.mդ܂ݜly(_*mvn"vk4XԐvֽպ!bsw/_o1cF:|0osaӥicPY]/nZ`'OV2T: ~u+ˆִb!dZF<.܍VK$z?^t-3Fu=^)m_6 vkDx8gZ*"Z7S3 3:k +Gp/ -vT̺|EI5xr6#Pƨ_  RU"HE_%R+!SGm=N3KiTAuf>KPn2†\#kf۞iDBh{YjwӜƚܵ TH;ިUF"i -"ƺA(W }֗!>,FjDH@ij([fʄ~p8PA_!qAv ~1FlZqv(v{M4u@Y&8A̞^~qq*dXYiq&i'0pKǬK%AjC\D6y߇-xs@/|q_`zgwϣ6#E]ef-ϵ.(;B[F:h² v-ntSTbuLXڹM-vA} OJ3p+-Ç̵-` /~e.39 )PPN&97Z2CNaېdNW8̓c!?ԎK.DB3O?@4gQÛy`bSuTiMCӎQNٌx,OӴKfFeZZpa֩ݡ)|7,k)H_+yc2Tr)¹Q5`î6ttaBJӚf(bz6#ۡ5 C5(YA&]iYK5+Xfq-[=Y-,K#Z-"X9Gt$,փeD(NK]Iz$0ػzEq,*ņrFz3{iU{Zj)t:9"z붟lHZ'qXN:v}= XB:$њEfO^Fbn2>ږ\sw7jwXQ9궤i B(CCY3}oҤE U Ͷ8 gf`e!%gs``1` C*?32aD./ 5)qqj)xtyye?Aiaajݴ>ϳP7`pC@DDsqk܂u&shEDQP%{,f>JE!CH _ԆZ1UJ")%.14TLgtikݗZ@ipq' ?)/(HZgdy*ZHUzadڦPw+z Z>Aݹ}5,2ErKwdA)ow+,P .ߠtAEELjn|'avkf#G2D$)>)@\%"UuB+%c!6B:ִ*fKD^Eϧ9>(-غXTZ¢!C< kF,f̘sntyӻJB_5c Z @j᝞WoԨEu Am(YYa3AСҨX" F [?G)uz-Xۚtihȉ7]5&SwM3#CwV@H=1#9^ Fv!8F81BcL;Y(9#AWylY&Q0AZF-0"Z̎<ƨ>dRe5LFS4\ B"DEe/Ԙ |۷í[#.=]l3r@dT& fsCC`jEVâ> m!İ˸}}0JIJW+Bڴώku$et ҵzdP B҈r}_=9txSRPr6OЫ(`&$gBK'L9¸A=\-臽xUiBt6i=RE8rG1wӦ91ykJC ERmpl6k+ݧ ,ݻoy8kx Q* Eqi0 =r1&=HC.X526*LNhn3(Tu ¿ݮmza@ֿM?ghmB(\ڐ6Q!ٶQ}K^ŸiWF96ɲFm3R __pEwOA'm nAV4-rM=*bkfŰP/̭+v:e,Xc%E..GZޒ [вD4'Bt?J۠E6o ~LPټe0q)jT[\P\96Q.Pxx˧m e[\ZuYJRfS A3N**'hb+}aw-0:% 6@4PٜskRdԢSeSAsUH SpԞf!Vl@Kx;>+%͖PzV靗8V8 txzJސ3Qӈszepwk)z}f I먔+faQP{^L -0Fu0CF*b^s FaNGH 35ZP:z1 eMܱBRz-k(*Eڔ2F? 2F FRT"ef5&5CyV̂H+_sbOn4?cֈNi2 0Ol#I\8=zfB=0!LɼenafGY#VoIEj5k3;Ű\$ql!7t *7$U4SlPV`7̐ˬtԄĬ sD؜`ί5(ȏ^`~|@z\#>盒O5ʰ6W,s(j!\9!S$ZQ"5oՁK W`]OR͛S}/Y&oί ye&dM.]۸.^[;8@VrQ?jXjmM x)16xSF+>u'L4{Y؆$pBUkҸ冘3VR(U>uHX ٥P+mhfz;O~;?ƍ1kJrwrKpmt)QA!*eA2k[sRoJj#Te7Θcy(ٕ3C0p96YC+B=2"iW0 =X64K{n?ǟŒYvWg[l6Mzi5=`HR_RpF3ՕG8ZW " _jD$B檋c䔩#'!exQPu\H1A)y[ߌN]̸w SCu9I*7s)Ox{u Y9j+Hja0{H&>Γ4= $JJ '㤇(lJ (%‹Ef[#MrŁp^wmkLhhSo~sxG yO,*kxU3C"` `".Lyn^CFKZ&C$AʣF<975fA_)(7[^tH(,u4bJv>q!5 R1ߖ%n7ip;|ӄP(.j!U4?QK.e-ζCCi>MX]S55\ mh-m/E v5 #sNK_>Ǥi2L4N¨HRrEU{ҫZ{ ",D=4t; Z RP+@4(n(跪38f,C+vfŽxP;T56Lüt"kXvmUdt .TMHQ=CA焿s'ϗz =_iBh胳RÂYuWb 67 Z$@B@B>K`FӚz+y1=e .{ -n޿"vsn[ b:#yFj(}Ձoui4۳y[ SJnÜ qR]yqm#Pev;ܹs<|\lE"m15WZ+*: ) H;2fً5亘wŗL2%f f~*WqzrE|l9"sfEn*'A1 B" غfb{7g \G"ʤ[\\ "N6 kmȞd6EXG[z)g,G1[>?5`gك0KY /1[/f?i dFFu) ǵޚ3fx_P}+=.m6ERoZhY>|S8 Fe|]okϕRSnwݐijAJY62gijE-Uv^V3į i<5*MGHQEnFq"@gTW< `^d5=4!܋DsH@Ν'oHgW"އ!ĈaȀfka@Gs)2YZZ:L*bʋ¥q a0,s@O6_nha5g^MT4U*Io瞧Cִ&]^- !!iu[*fg4Xu%h(Cݘ,nA!(,it{C-6v= /rTзI"ѐu}kaHe•.5ͤ :*OjoBfPF*Sĸ[.GQ$}ʍ`fDEݶF{5.#^cktͲbF3ws_9Aq3hy;4/]hI[|hB؆TLGEMZքPzXb FZs[u2#m0_[0j7 8 ŷş@㹢3ۧ}I\($0>-eo:)ZfZNucC3l$ . 1+tU P,⣫y+&KM)%8ג٭1Kzire騈T_52mvm+ћyV k'5;ME?o ?^MdCggg)J)xzN?E0uI2кL4v7iU xUfFւ"6\iQ^QHR0i<^o4̘h1jd8ћcsѩ_ws|r)wTe:^sOfi(QLKVN>Y7U:nOO9![,ӟ -N?͎ĵR߹~٠!cV4q܄6Mvт>zM:F~fTaynFsrדa)jKbHزRK7Pm9i M\T"yY j`PBUkܚy6m$S 9XF[PB.U͡i eL. 8(/ ` ZϾ+h\&q!qF 7s([v7ҋW{悥. &lDO^T|MG1CCr PX noss n隌xrԚcmyZt@fbt&R7P-*Q;wmi 4AxQvkiP u {Ur M~eVCP)-tfl6zMsWEʧfГZ{γB6\!bHY5?,OPhR奸H1J`{iř1l6{\>z<͸8۬! >$ GQW#fz&libA20Eq{4JNj~n(o0!9ѱ-kiZրqQg%#3"ae;n'&YxYo|%}cY+"Jɢz罆 j:}ljU*%X5'l a<{AJTH>ϞsF5$:_;ԃtV*EG7R7=k>,>Pxq1_7!k[_ nif#i2 !d 9݉¬p4<>[8;Wz-pݨ;бͶ\W(^Yd-m{@DR:+`jA QS{CݾpY&m%(as%w}b-wIiC@e*.l-p`E]Ѝtjk&R͝'s(lA6M}*bF}SP"jƘ?w6\*M 0 ipyy&u6e^uFvT0ͧ sD~RfE#v][wa@! lX؛;5\%6AsCZ(e+1mHN:Ǧf8$i|& "X*ڪ ͇NkK`2 )G)o C @tJ-T[L+3M)Ͼ??/~o7b{oT"nZ@ h+挘\h y=ݲIY"OY& wAJ /6;F %nJҀ4D:t:@'Tls[^cDU2 (e^ny=f P0Z 02c]LXr8ǂm6B P(9u`HZ ycU傚rc bB0χv[E xSeE'D=ЈeC%gyZA%ڍZbhN\ LƳg{h#`QE\U*")#"F*P{t^h&E=V2uZfMT/hU ~yaTU[5ޘ =&:GӃXEPdZVTZ^,+3jҀj,P^36æ95ݡUHmX蜦fP 6Ma>$]{PF =Iu佛M - Ny 3(flePJ(MeҀRIk͈6BsP0WIXv>ۂ9#<8n]7ibI4vgXOru!jJńfhtu!rČ 4'>o[gomr>By46yvGuP9q5ؠZ)UUKbhޫ5jRU#-@]v\T=jZ1 ]_/ޫGG 5@/Mlkº(Ht /\V7)yFhhqӟog-<{VJǪm;3"UWxͭY4KqG؜naflM & 1"^&M:u/Bg$Ze)BЌaYv;W`NB8<0Dw0HsK1,ZN1wÏx/|SSnsJ +.FNYn׻W[#R8~8!儠"?7ŭ[Dl"%A&xAϿր CygBmagp 7v(vQ>Ĩ6f@illRP#j.mm4mI(J67ѹK k!CxWI0Ґ(*"%&AQ(WQ+uskT_q;/Ii1a1 A BȎ!K ϕ_.luBHP u&mfq]Y%z7(ulzӰ*,ֶ-?þι{n"TD"PЁ%#n@b<5/@,$H!Fr,)X(%*Ubum{mk+IT@{g|8+?H:?K lpw /C:e npRr(55wd $t2,0:Wt0:0-S0YЦOjfzjDӬZX<8URy _3ƕk[R:m3cN>/ßݦu"l}z651JìF#޶zVIpX iG˲Z@ ^=뷸E2]Q'@0BژZK[tPp|Ψ&rV $j   y1 uDsl1,MOX:fЅ% 2`* J1&0Lfx<8<"ѼW/$;&BC;2tb;FZP>6!P1FfZdd=NglNh@;o7'̦gmc }z@߫^^*9>N,yC۶)1N%MTc hӌF5:;˦O wj]R[mviOyz:x'_ISZCPSR4s c3F^IΕ(4WmгȋbPTFsOz.?G78ԗ$Ui)v8 ʛ%νubyH~rJ65Ѹ%)Px#M|W)c വ䍩+${|c:pÔN,}=q7*R0Ձ^5#(:Tf)BDNeq庵58c`cD ZyjC?#|0P9YJ m:S捘 s[i3dcҩy uEUWmևChXTQQP"ƱtloV 8ƉGD`܀<}gvcx4(s!rނlb5TPhFoXBV)9Da, AʁCxc\8]2YЍ>ˎr(ࢵE[z/C` hPjBmygR3m"0mgIg}w{{VLm۰xC)3nonp>ЍM|mt0\i xfT5;Fp7B b DTdpâD u0kK0biL H5|Wh8,({% ?>'x:X;Tko%O"L8PL<7[z#">m-%{anW)_#.3U ,Kԍޔ"luA4{ aJ16A&*FD?񂨏1r1dRDYސX."tj5BOEӦ:U&>/7%F:;lgnooګiy#3PыrkX̥ V}bbILb/9ZuH"Bhl4WOg.r'* )emaD*?m(V2kVN=z54X|dp?/?߸п{K:t-x<Qh؛MK/kII+MUHPoo`׈eX`Z8PlVjɴRΟA7 1hc?BHiL^ m"T4߽1֚m'8+Qn6HFwn-a:.+T?ŮKQs#e,s蹦m%3N5 f).:."\e[@sk(#SYCwVuj )彦!&k?$_tvn,#vAg ShcC{r.:ҪY(VFyJ8Hx/$pj@^q07?yw!gp*W9!WnYO4RHPHZ 62K+YX*P~^Y*-6QFicpXX@4#=ry}ȹr7#QqEng@l!}'/3U, 3rYR1yJ BS5( hpLD.ޣ`58g}>_JkU&#U޸]?~w~oUO!o} 0t%Sގ'_'/F~H{BΓ-'on7dF:ό4 "o}ܠM` dd6@swssIMl zgf䔪/J D{/[!E`\Xt;5 . ^Jk9A\_.Q kQisPbSbN,{XHDF5\ ɯ⌇vS;2?W*:Yya{gLEW52od(>M51vk@eI4pU[ ELĞ-< /?◿ql%3$Žx@$܋TQ me …C:m*50"Fd@QN6 eJlA/tTY '0z+3J[r)膦L>k,S%iM.7iJ c`95"Ҋ7Tq!CiU3&߅r гg>^hǂ~7Ԭr-쩣 Smޟԙu>n@AyiRjXΰa\s/D:pռ>:HW*oxB' TA7(/-tA~ ?pې'24"͚2]/Z`3˽0<҅3 mT97@r!N׽W,QҜ#jbaL  qՌЃPut:?'.f!_sPR-Zϙ%-*ZԄր}H.‡Lk ʥ^ORJV zwWjb/ȯi]#M`6TF96oK9|rX"˟d3 ;>&E57ݨc ɞx`@2o}S h,RH(]RYyʛewiÜ&[WyҰ9L Y,49)I8E|w_2t&4PD*{I4O)A2jCh]v8 7 r0両pA2:>a`b;!]Y d ;is63M.`/;$kE)Q,Sp)j^=*:YTҥ{9eh-myZՍNpdl-PĐKD5"_#)sK(OV AT5n"#VrCP!ܟByFY>kO7REBwWehOeXٰr.47U&@ t +PH]" {|MfTu.0ҴHJg< >j*Kdg`w NזP.3 esf4G$ VeLGkoÊZ/^ Se>k<|.\)?M򾌥w"1tG꧔ެ@Ar~Spx_J.]k}ψqE LW%p}d bO,%#:ƺaDI*/hPz5Q>0C.3s|}1O0ߒҬ/jI q[qma7f}xU.O*CVR Ow8g iL^퍩ό)a=%Y|[k+n*peR2S8Bzfrya)ۑ ?S_oT 9g8^mfp\nhLץrUW 2KQdެEwGb9Y1J΄unLSQNKkMj=t;\jcUռ:gHP|1a}ݑyPZzk-M5c-vn%k$YWXOʔ,-D#\Hq?gFޫ4G$jug:pdRum){!׊e*J6e4c^i2N&:ζm*sr_MKİKWz5p7orNzQtYk OVDh1!#Zu'|2m2*ZiJ`щyi)!DyYZ'ƯѴ\,ݳy2r0 Λۜ9Ήž%q5&. 1F/d2ֹÜ#V&˥8~͒о|oi|8{)`jؒtW9jOO eHz41L"F&O)b$Cy]12Ω}U|GGI0TT&9 XCɮIL*a^LWqt"|ygR2}Vd }H9% jAipPpލR;² dT'ULY&*:)9sc\I].E^}@U~ȬJ^4zkB$XXD2> h#bő__F>K$sfo&s.ˆ/סpK %g|%L65Ƣ٦C CIȠH<.hmuCvR ;18z@#Y T&ƈ͑ (Z+noo|@;63=,>RүN3̇tIaXJ}FLYaV~6WMuEoÁMQ±/:i,?( JWQCx; oÇo=Rh;[ny ?Wp7Z W>ވ\$|]2 ֭΢'ˆ~+tjQ=nb"rLФOS{1zi TFA/TlVhی45O,Kl4( F*("p8aYB ZL V}mJ;}MI-+nK$#/lЍ̓05$N!餤{ɖDD9WLA%#2\KM d0zMmLp9V5m?/iq΢i#ŁhU6v=u.61LHɵv ZԔ,'Y:og `IL-E5Kogk?߆/DފHFaw;*q@1jֳ=g`n^,~2P:>v<7tv-> u+co ˅k֕cl$hR"s pg:@) @R O%Ġό牭1(hn`gQ]QYqkPj} rN҄Z"a>+)pa]譡_X9eZq ieTBB&_͙hu>$*hD1ƠێV7U"o3!0~x1O߇?p*<x4blS0$"A YXn8%hNSѭu*\$R̉sɶFNͅ|=  bQLy'*s3*rT[*ClP 1nApقfN$WSyzw\5 ujN35:6X6PE7@4,S6tCW`hcr$&q `c`衭"XԌ픅;ݓPȏ#ҖDƒAY7f!#eA%0$0 sU{<6 E;ќ/iٯdؑAI; l%|f4WBG;l7ݨfI%&렝Z`UO&`Zuw?o~ |'#8o?Qo~z~֯mV6?݊ /ioQ𐽎&'GƄkZyrȰk$KcR3Ynw& ;ӥ@F’+eNLlq:KQ"\8,Iȴ_z!>9>_h窾;1ާ!!h5uon߆0 ZC5PiFg}3)PL:M/O4S5&9YuiIhu޸1E?T@.deZEl\S4VԜX2J- IAn8-<>? 1:nD8;$svR{P>_==[y:73}ނʦY,: o:Ii E$G=+Y"8p8І?#J*u4KBÂ8Ggi p74XKM,MUֱDZMG'U5":{>ѭwd9,8N(S{3Z\˦BtG$FMd#פ$sm9-HT*t>Cgy#sAhlif;L-CG42zt8?LcXw O`+Qjp՗[6sxkϨ!W :\_ {3ZqQ2ꘈ<1̴!irRtȴh,&xlTtY(=rћsVim?$|N,)R"45'tͨl)炲'," pi..Z+Jrא"?{o.(̈́GLA%WvJjJ< D?WBTᯱ,Lr>?-_=G)IeW6\9P<CdDQ.ФQVp'TE% y8Wí d"x.z ![C 6y&4Jl`&fpo]>Kް9ܦćxBW8^Q P\@ Ax9Kۘ BS h`bl\px YM-#a=˭*'y;kC2"f:dF9JVfi35akP(vX7 4mcmtAK@l|>x,R|@In[. Ν,`yU& 0E(.W 2ƐE}|*P4i}CǽNTzmi{q7ן^KRDR/ 2S$MIݒrBstKrAҙSa_* Tl4 N Ddf %lR6B`vU?L㪸<hx!txF "' ;!sE@5)8p$p8 K'dl!e:nh,u emXzܶp.tΈ|!D9@ $.Y*p~g& ܘ9}R !w:AqO=]uOүbaKTn89?&5~xwIi& i7ܘ6DՑLaFZFrE ea#3kNL82v3_:mFzCsth-,5O $N~V+gih϶4zFRϛvϛ5:LJ||DA.Zq̟MJpMs#B@itZ ZdrdDd<7x=~c=e [1Eˍx`be rŻ iԏBP~7zIq $.z N 0%VOQ76Ѩ 5q88X|݌b R3ԇ"~G |oD|v)0E4l 2 w5 e1qQ/C 'vVM|w~Mɰn' jry. U5%'v(D^$- 67pS+"f) LJ! @@4O~ ;i-(ך'JT`o$TiNh7xѮǫf;8CfbA6;M4Q3C:4@B䡔oe pb3k~{YJkyLS@4y9@eFBa:hߖLr΍w1&۶%g2nԼ- ܔzyzj-KD,lŕaHK& " k-oZ H򅪅w+x$dUNܤ.yL:Nk o9o6X SM#gH`<RN[.)ǖL[1 TA 'b5ܨL>{eపF'"Kia~i#AyR`:+CDhlAR/=[ZW^f)犼gXo$]9e͕43?AvjڒN[k*a5-c ۼ1k0?ZN8(\²7M2Zo jOgᰲq{3ڲ͑"Kl`H>ɼ$t[Fޢ~-XIrDNK#QvF;4;b~I 1(0΀&{I6| Vh@*5g~:Z&-tPixM|RP2e>4ǜ/B6Oۢ}iZW ."x~癩vo!!}E us%Yrr](2<`{>D dFF?kţEy,ͤS,/B%"ôzfR<(^mxBaC;a)% cP['ƝDnŵ[#>iS0`D$kۢ)}1wY>G:• IT4ɡF0D%')%G N[B!6W8{g- ܨcYtO7>~ǏⵃVe=l {##} @Xp\5b8g`FUҐʤ Qh"x{c% 4!miJ2~zG^*J"oIS8M5ƨ+_:jrxsN:ZOb?4] jɄ^ lDC@֠b,WQV&˜5a9eW Ώض  :?"rMl  ׿qHZtIu4M<]/lŰlM;5TZs,HZ4,'9g<\}.1e!r(sp~4[ƁT12N6)Q}dB콣o},{שRei0IF,?5K=7Q.gU !3Z;\Q}Ai {qw:"7E +)A ^ 6O⛛QS)ML&9\ZѐTFj-#ްʔ7ksxV:S5&5O4}翷׭3(La.YjƼ|>sG ^12"YK-KzC_c{"I򀍷\ Z8NQjE}CZ8H0ٶo<ZYY.`g)4a9\X"K0p\@z4#?U=Kj׉† r(pQz4FT%yx9铎]#s︒Wk͐J,Eo*_tKʣ:*dtt~oY@I#"~=mXךB6ݴZW< Yx loJ&ƎyuD^.QZzԐYB9a鿊z|[Ëg7?埃GS|{4"ӛ&;TF8{x?hB:gnwLHR+Š]'V Mv5&Ol/|_} .Y=='<;0*p X;V3 ؑp 9F& ptF 5 exL&iO0vЧ,,rbOTlT-C\gj‚u@-|8)Wmj0bK&쵰hlJYK 4PpQkHi ixADGi8p0ƈt9dT𨦠e=ZhW&\3JuYrҎݴvnYnCY\6&+5-*:B$-j^.9k^HNčLFR Lg#Xmߔ$D QuWbTDDtHkR ʙ0!+Oyz|e,iSNZxtt,qB-WޣՂ2⁧@J>Ed̴:p~Rڜw676RN@Lzрʟ{xle)6e/,߱\reGR;/7ֱ ;xg`atR# gGekeR3VKpDJ;K㍆&ID:#C 0,k Mj nP|@7zFݳoQ@#7`xvm }L%wө U{ g}FigzonnoiD7 ٔtOC.580z%(ɐTM  TXB_Wd;oP7nHUړ%)< PGCbGG3c?C@jp"7(vV3!g)WA- r9CǾ|s?Η}ga]7Mf]5d+1GڋѮư̫_Wmpyt:GljBK:Og>jJnL _$'Ҫ(?"7j3 J=Ix)vQ| \.9q+CLG \. 79C&nBbk\P:ٜFreSǖv&Vأ#rdg8K{ udcC^9s|V "L);q=څ2jY!(HC), >8B쇰ء$@ -ә&xgNyHt_ VonQmyIO^ 5;$'0=  QaD,lh,`]W݈F'm5i 7bI Mg OĠ/1pҚE&S)2ɢҴ!-eDg\*ݬv W֚9"rXaJEY*Jc j>;c0 M!vm8-Ռ^"`"'9PcH,7S[..[5geFŋ(Rs8ɎZ2ʡ5Ҹ ˦g`7 ou-m?@nrV<$5$+,st6熌띇8UVB tã'PVT$'-Z ӽCPy%Rq8 .!VYތq,9ه_eʆy:4V]8.#"gNsoh+#a_AId.Tw4LaVt.w{G7* y*pxFXCk7334d=h᝷Ϥ m;76!P77*Y,D`7TN]_y;awe BiLvc+1sd1H'"3'*>9T+c*~=,8OO#ߋYa;"+5":pPr0|!<l鳤Cޘ:tW2942'-L-F կ#)T; A̬#3]IAOhNscSJH) ױ|́|VRp!bZ{%ސxrj䶗 gFq7SJWyVszQ1ɟ?/5@F) y}ETe=71k C^eO2Kf J̕s"q}OHyp8 M~ZR$V4Qd0 %FJ#4IIo g=P.Y" Å< M5DCIOVTe ˊk9tȓ0mi'&Pv Rc;QX+E z8tSǤcRjb W3cȺm 1 pzΉQzQLUX|Mc~҈ T(9kY B#`u]~$d^ 2:?$<0¦[;F%֩tCtK9sV > Vp;y:ˊ=m p8aՉ~e\fԲ "!rI:$3Ń2Xj-X5r9 NZrBkRνc"LDt+%T:84gԵ{ Us4MqOoeC\8G-Qx=f2u*EKeو]#HgegHBscLa lt?f>ʀ^.cY !^)XxКRk^~q.m,4H4| 1~jR̍a=*?zUF'Lts `-zّu؊>BMX'6iD{ԩ M;.VS.:cQoIQK%fy9XT= [/~V Y_Nדɳ qޔ\M&Stne,(9QP PIjy)g+. k|sY5)W۶ bEn&4r0d&$I-ܨQ,&q0C)Ϣs2Qk=3mzfԲLW$#:%]5c2Lu%ֆ}4k6y_ɀu57\.'dn.yyvġu!Y I`U 팸QX6DwX|DI_ 1sgEf69:PBm]auF v%ҡmٺ eW8uZq`; u$'b 1(0*#!a Ƕohx_yOHHĖsic IBaF&] 9nf<* ,$Bz[$MiЬH>`=Ҝ&\0%8ʺz:^`n!MiqVuNfg*RPFf~[+8_(ٙ~vm`h Zk4u>W0ɲږ<,ʢ;vu*Pe$M-h2L!MuTπqKt<ڎy(03E0#cXjFf!_uVkY"#$-j/:,N6JUQs-aȵ"KF4 Jo3Ω 3Hi#.W9*%#8n097j[+ȹҔȁ-0:8`Yw0Hӆ^2J2cZ N8c9͵VngC7`˾8\U2 /WmejC\N޸zVpo jf O4ؿ h]Ze׭vn`uIZilSv{?C0_> G/M&J}FeCa!$㺚9;ЊJ,;Q濽jX=蹠n9%$gXgPG\p[ L2WOïSHY,'aN׌k;jၓ>-ZKƒv,{ۦE&# HpRGA<9RE5K8A~}߯x\\Ҭ2-TX\+PG`did z4#[_rX[k;y!0]fD1 pn"Wg>J+_"š"'4LmAX.-e <*5Hlr1VFhK㨡3i/in,C+fԵsm$)7OrHb"VŔAB|J;R;1z63W2̀fID*aIUx*= !6]L,Iސ#2>g͸ CFNːBcik,d5YeYHv4!cM)!+^zTba/S`\YEULN3hhὲo00xūcdթ{:lX)]}&foHSJx%KC65+zMD`Dk<^6&x-EHG5Wo#= !@$T_Mͳ񐚪[ŴgwZ7 K2ЈJ´JNz@sVcEt}. @C\](bL!wQ1Px B/ iBp +J*{ BX| $k1ȟ52ǖ26 쓠iGBu]p0lc %<ƨ0\Qk1MCYmy_+IA)*q99(1HZk /i4&GH_.ەLhhKJ-@L"Q.%!&چ @"8MIfa72i<*0:CNz BQdqmTL!3|)Q+ NlVfuiF*5xF FS2ذx7ع#5]u0כ 1[t@fQRF-~+_W%Qsa#O{pWz]ƴjh4+EkIrȆߦzrQA׃C{Gd"7O SJkxZvCEus88GU542lγp!j#'Lob(m)}M}"uXj[&scDX4f8=&Xȵ ȿc NԐɔ0ӁSKH;m i&s Xޏ'A%Fx%}>Hati3p`4(I5% *I D6x#Ӽ $aдs䘘JES.˂m`ᰢbqw{s"Y+[wޢáw(| \g 0⡢QP[4Y[uYͬwm _#e--m*SjblkM$]2hjNhi_:QoT)PZwYhrdjI#XyZ,vi&rD"lɨ ҖЌd='IڜAv֊H\25h^'hHaK__eX`C:H*ǸfHh%gIԶZD_hSCS*=t&fpKIх(u CD*-0Թ0NB7\,|~U$]2i<$".ɧu a&%PP=loF1Uh ٹ8M7kdCb;]M#A+IxZ`ZEΌgowGN;w_)4hn̈́O ;Aԓk-IH xؾV3tz\?leRni\R˾"Z( >Au,V+LX:to pN#~w^'-[ެn z%yRݮ(ƾhyPyga3T {/VzE)w1G|_/Oǰ;u;/rJ3¹О/9r:;sP؁RAZE LG~~ݘƂdbzy9e-z{5tsWPFuf[x6yGE4+`Kz${YO;*2 yxAMD PW5<8yQ1hW˲()X8ԦYyukD[޲oC_-v5wR?9256;.!r/ ɧZk믽? 3KfOuT(~:![F3"'Ry86P:7wwwxݗҗ [:WU@V}6HS{,FiM*Ydj[`/` @w&q#Xʳ;> \>{2,!z"Fo%E-5름0s竐BF1+_7!O Cޠqf\I{(e3 NW9Gp7b~I|Ʋ,*ˬҳDS)hQ-, %Ӻy ΏҊ\4֒1wb%VcCGґm,H5[ڱr!-ѪJAwFRCa]a#J`-*c,76@''Fw\ Jߐ WEG朐3l)Eu>59% rF ^m4pzf /7 v#+JHyx9-piKm2a;'v [|o2"VhB H؛-rX%r9,$ @kF Xg Qzh\4Zx:Q[G o<FtcT:wtLo8zȑ ӵLI%d57̞J:{T2,H0ΰ#'n$;ku`#Ƙr ZA摊gE֐7p &u]Vp`l vHLӴqm[*Q=. pp+5oh[G!(j1K? UeE"%#7,.~,02t4П},E$rB48Xp<2k/,d+xxOeSX-kp,sꔲ?BN{B!ذ ) e{;t7 c9\;ʞ"):*IXl p[5#7%U2XcMRÃrrmQJ|>r>2JErZJA}|9OIi6A0x߯浠'.#NzH7lX-9 rjEvq8{iKcrrDt!%鿇PKť^tZÖ5y]~ R8a]G{*wR)z2mǯ+,˪&^ \L9)Ssz8M.)GX0ɪSze [J@trmf>rcS(, MG:rN&흃 O퍳l fNH.1Y tpwxO\]PG*, ޘ-40~Ѵg266gݘZIR*5|x6YWFr<1&N E&}1yAD=aY5qQ77.&ꅥ3{H'/x~IJG *Bݳ!NRМ !C 9S e[Y;B%I6pILSFD)uAt?[QPa o: H 4/8ҦJ2+Y 8;D$*3I\#gMQȩPAejCk/ nk+mwyмx+b k <`=Ý+{梗MWeR襗\rfkŖ;Ω ܐ+mFZ_g*sDC;熼_b/#ZI ҅ 5'_qwTbY2]Y]1nU>/]L|uƢ"r~>= Y|sΓ :A*s8-&C/`;;C3Jw[~K?JxyU'^cOWLX)wF+_|s7"&\犨nlB .i֊AKLX#Ixa21kM87skoܿ??GX B%B&s6gT̡O$݌ªqүqutmEc gePz5rk 餇.IIXOF)dJ;\:kQɺ3V1F\iEkZS?LRR nnnhkq:]MVr A )NG572ȍAlp<:a:E#Ms 9G2F6d1zFi ,SykL;L0XBDBϟ+DpY`uYhQY RϨr0Γ!P#WZiϥwψ2{sD 7f4a 1*4bkDIC4>V8G!nrs\raѦNt4)J%tsA"S61;ąǴqAazޜJemjD6 dJ iox)5pش18 ^ ۶! >u⁍s8ߣe2Z͸=˜eG?_p7QzC6~sse&%2nfוA8b#Y$킏FHpS=}8kZ5:( 9d_Wo7R+]KAzs?|wt[Rg$$QMjBNUW4<^贵ʲ\*瓞k"fR(HdߛO!x W''b(,DʴFrD i5)?|mj'5 xmU|1Z: (7jFvݐ:r&ȼޘw`Ǯk:gL޻ c I[pN f:KJ? ˲r.y |"Ёm'yhtҀ) Yyȉt)|W)uk!B^(υlCdH6+2^|IRQWDA'pZl Cd+{Gv/.4/-?CWh u\ߎTu"PƪK=B퍒Ukx*?|t8"pw@O0>N o'|dZ`$qXayH~F/NdaSpq; Iei!7#GZS-hq/_b/;nJE0.j!Rd9S K83*w^{%4k>30ƫ| ಝA)ZW2_.O'XOr,Ȩoc"S{4#84Z*z*D|{wbiԜq:|R[Fm#R;nwdVmۮ\. ZŵԚWgpsM1@Ypt8j{HAdu|ٗR D#a+X=[H\}'6/B1J)y')2"Ok14-ޣ.2WS~{?)SgP^}/r9?oӈ< F1WU]2Oω ٤):r7Bz2НU(|6M,[7Ԝ]+9 (e}{;$pԠO1ڜ97̐'i{h)gXG$f__ 5p vڌ~;IWկU*rtMLJܢ&@+I?|KcUP7#Ce)ӤU}{hd׿5.~e-*Z"Q Y,2mP;0oFXRӳx<"ƈwy tx={W^)|>kCt: DbE+8ǫ2t`q:=Ap>oc/"[FMye}$p8t^}[ eN8ޠe0{!N "u+5JYߍW9 123|'8 +ԭjF)mf>K1xC-¹>`XZŶW~;B x5+3$W ZL [?xigï@Y/+b֢ f W.qh D 3аlXG1܌ G:F7 ])XSw9LNrT ^VZAz==MIޏ Wib \.Y CN !gMMɒ%y󹐩҈$,h0)ʼn`ٛ%[HY1YCa-ѻz\ݴlrI8- "Y٨)x EXy`bQ[kx᪑IzJ8~ `0K.=EdLVbpሔvmhh~~gX4VqlySEMA"-ӆD6.Rp@aE.$ xQ !7^Ծo XP[L7YEigL9]p$XOZQa43Hyc E g!sn5JGfiD{zMBWH[ˊˉ>}s뵡3jm)r;ON42{9='{yဇ˕ϱւ֌2~M)xH'T.4} Q7{R" KX+7I#R*j[Vtn;o#YN&Iv8:oY5iI]0{Qh_J>+lE3a'P%ӌxh؃*.Nw$AW9#9V |Yn>w*ۿ9~-HިukoUi֓ދo$uBrt}0-Ԍ&^FSF^uO}jFؒH%ح$®πo !^מ#_<9UnQJÞwMZ$n 8$]$ilS4[ MqorXv,Ӗq8P1.Dd +/p9`BeZT|]JeóT elx$XciKhx;#}_V*J g;OOSžQcyy{wT,M~덮t_kū $Bt.S\ =\E3={-'EsfԊ2֚KA PLb('ڰsc& GQJ{J4%ޑۛ^.'866^`C?06,X?xRΩ˯Cǩ!/6#߄U_F6!5ޡ$`#9gA29^R0j^1>ҭm%K:Ɖ켶1@ގp*zوT <\05w}w;?=8 ω6dXRg9ֿӴSMS.k剪uevYd:?x<=.TB{|yN)ҟ"I)1)6+*DK!9"hNqwn8>X-S:B_8Rir(T&◑ ȶ$qXpvRϧ+6F%"PF@d]=|,˄SQh<[86Cs۟ZR4CϗvNfOv0E1V-!G&~„a^E*GrM@hXzZ!JaӢ:#?F<7/YTަsMqYus2$F^"B `aQgiZ=Mh^#),"5Ĉ%,2}L08K0{< N9Pܒ$J$\mO3.~ &D̓ z>y&,[ۮRz\g#s Q~~LpY!úҷe:I2Oɥ-H|Nf^Э,{*fJɊ~6T%;a[SF۞].rʸ\6ezq ~j4 +2{nf̛Bo!?NPmL TC2D!i'/`a?߃"m4Ln1HNgv4&y,q UU1e mFQ255Z&,R[e]E܅)U~yx*#-l"" F䍽w<>>tu]u;&X {lKXD;M|,w-'Tp uCaWu|퍯ck c[aa(3qhě ;t*e㽕=*3R\`A;jJxx GϽo~ B^3zKfuꥏ+/d0IQ9:;r x.0p>w?"z?cpWNW~vG5g?7fu6p2tAA}#Ư0oy$5=*Wssh\s*[c=mE=<\hx_[o}})02JΌ,'',yMO>33yE|_/}X{r4^6 lI {i3mn7x'}NqnZ%sʛvP5%774/i`#?NtPU4!P"l4Y[N'&G-"i⮂ MPƪ w-Gm 1xpOn2gBm֫|Ad6%cTc`9xO;BXRqX|!%v^)`\y>pwh]W@U6cBDi"U,KT-K\I&vJfHg4PFS)8, y4 ʆA/Wp#=Nȥ*-nUY$uLȵR2Ošf_7D0*3=Uʖ);jhSKE `-5` O0ɀJĆwQ$̑sh;8E KhB8b4D["|q =SE"- shЖSH+V7˂Jޞe386|Q9{9L}#Zn(9V )##< uEs5/_"#:z6OӠ奤^ΉCH6ԈSymdBAK)q1`-sz78~s=b}w#I?b)OabX/W~ #=%I(j1#ߙa|U|@yvm v`k4)==<իWQMiXu]s*.Roפ?~z777CtM+-qBE˗/ڳgz"$ %`3C.)eZ'D*i0<(x|);put99_19wd5XVI4YO(JRۆZ+(03z# q%Ԯ2y`Ik%t>8D9OmWa!C.0y ۞zCtdl7+MIa q""RYgQMm3KFx2,FᆀMG;Ѣh`GA Y򠂗 ThuޗH9RΔ8n=yzLx;yDaR?y/ >ν8} 031h]vgAOgL5;N9k/^av?V|?W^18|}Oc ݐ$K! -!(Lc m 6y6ѯny>vwL$ W8UggJr42FԆ2~-~W$^R7#"C9?Ri9~{/`go}W jț(b67lnpL4^mG tѭC놂rvڰr~3=?4/:1p_y <^јڮRgLlRTb!W֜3Âe c+rA2A-tTeP~F9Pe!!~iJFy}8t(Y!5_JIaՋA_y.E͍UO8,dΉa7wϰ!3q8JF.e2w68;cB\c2E{||N)) Gc 6 Ac˾WS^Ygs}c>)azk 7N>35[3>Fڴr!i=M"p>Wˍ 3 ,Z/({ #\Xd&ۄ@bՑ.Ly᚝(5 D%qOvV+@j/h9M&w(׊r\ۆT 55ɺ֊5FɶYZ8jL2iBEe0YӺ6베3NX7pgVn.uY]+n6fRhC8MM㒿rsѶeY -1׾/"#2"JtJ9B$$(J*h h 5.(ՠMA jMp0ZIH*R".2#"3|3םs[9^{Tّ{sf9"58MӲFQi60 kQ@l띇cqܬR^ E%n|M65&eYk7/Ȼ庒EîP{|eI\Dv <7kU*d!u]'W22\0–s(LuPV1:2ReķX,&kQ)XX4'gP1۲v[[:( #x2R{lP,*u+^ Tew{p0BL&7!F)L?-7 ܼdT%ZAz=Bۣ5?aBzM8{όKiRQ1dU'kpJPz~{vw+ w :Q"֕qλuͯy !V 87=J%h~|7ߙו`  4}2ٳQӑwbכБL $IJCRwR:@hn@!n;`{ z7yJkaJSC>$n޼ z~qãCČrcJ#$f#:Ö{c/–Si7-t+,_:CcXkq)(MG 0k6u6M#oRO1 1}?m11;9z7P5gCUrZd]ϝ5Kڽ\_(fK cDIA2Yt1w =1o8-&@j -ʔ$|dH$A=QMqF(hs>Z]EQ-l6JPO!T Eƒ+sYÉ楰8{4W925̐CQY"(h[P~ Hw!{,(4 M"$n!D1% rBҴ_(Z ֠u)؏ hvj"R.$|}v4P\!wēլvi>8;;KPKӲX,Y=eZ)c " ʹ }<1>8&*X]/Dꕃxpzz,q{\atW}ƽbp=*0!𜮮t>筧H3KC+ha`B bWCW!v_Ohvg[\^ GPEE!Ӵv%^#s"_!dHiq2J}rLrL͜S4Mnlycրi)$iq1B&)B`(Ѳ=]s>I#޶-$O"1 2~5moMm}7 D?bjClYMې=V }7$L }ײKc1$qiN캞PlHjѵ;!""qL[&TeŹ' A(mѤіPB\OBߡ05 .4,J`Cz_ (jJwhybB@ߵ}o6; sfdM9?=#l-oQa4 ځQKhMYA*in{}(.toaYTCc}-(pב=rSHeu],TjIz.qlat={T PD{E@؄au||EUZ(m2E҆Ƞ*+keUbQ/8feAkb ((Djxc(Q 6 9c Viz\*Q"*^v) j\cU !*&܀XڠzKXkb+ 'K$^b}3r3HʩXo 4 О-Kb)ҐviC]eT/nCud_>T7n܋ggw:=mSewD!V͹h e,60&Cp!+4RSrx划Mac jМ1oiͩQ$h*1NtN:bp@ْ6 )<8@yex7Jc]ilc>L?qeD?|M7"Kߌ?}o¢|Yp4_O~#]Z8LWķKs>1ztNx"Tㅒ\ :" Rd] A_aP͛F;' S\CA4(Wc _I@ ]=K.ZI , ppzy;PГ|l74EwLKoHyj¢^``@ش@6i1n R۶촢YѰXEF$-P#Jړ\,3PQZ$(ZtCmQ1KkQi`B#} tzz `8׋E(т#RpP%kvLŴBX^ =Jo{F95hEb8@1k;;?\NF hچcHҶ-\. HӶP4;){"r%HD{Ӷ V)I@4F\t}ϙ4UFs@H0\r]jIaUU%FYUk2X.( ;;r`j=Ζ%jJFsȫjQ#nv q읃s# M$G`(@ŐBӊ1\V#ŅM3Ey&( Źݖtj Eu_qZ75R |$m',V%a.z ncm 22,v`,fFA 1ƀKFX1XVqc\ӽ*k81UjYQD[t*:!"!("s'?Ϩ5uHhR =ZX E{#cd_&ue؉V}*/.y@4, QZ+v n'S.3Wb:STئih],Rp À }4UUQf7Fg55W+ByquypWckAl'''v.UC{<zkI44 d)fYc L -Pex,<[BH),q32G#}(F{vs^¯{ )00Y@SztpEd1b+QmB9tVx橧\(8:9,X5Mz XnV!\\s:l²+F׵\,߻鰨mw#4ܞӖD* ]`XaZuhmpCl;k,K\l6X1lK_YUЖ8E',qݠZbƝSlv[ /@;bh[vۤ{Z{n-|qS R=%!QorVb`oo Sv 5sE֠ `+G ڦGU(Lk lQqQk8&˵Nz#JCa jvrIY1VkB+ԋu@aa]:,{,+eQao}@\c[VuzU2,$|F۷huC»>2m*Rj}=vE  ھM)Qm;D 9}2裃|}I"<[S( [h Jm\`F+X ~F""UY$|iɾHCM, My9(*[@50 a iD*[qs`R8(>*άEYY't 10E SPk/Za D Q 9YCȔN&.Byk{b!mU/ ]OgZiPǶP آ90#CctdX(*nk~P/иHnTGum4P@Y8;?)J8 fGn.6(J˔3UZaKZwʠ(*/ ,+MP-hA f5vh"-K\;8·͸50j JIDAT|ُa:8LTQF#cDoe`PEkn (پi i#0254AHhD jSЩsNdR26蚕)S(ȴ*foD4(GGGXЖX~eBݹ^7e%k m}r5EA+^#,5nmZ[UO;- k|!J.FJ$a9 OnBFF%!S m 4nsvEp~f Ţ^1}'gLTUEJZk2ڌ_!2ivLm2VH({5dJ eM{)YӴUUs=2S(l mA)ߍPW%...aM6.s.9,RsO 7{&Lvnp4mkږ%iʢ3 $@Q/D$nEf etB3 U#W+(+8VH${1^b  Cжnp/QIӬ} Q\{{QԩdN]eQ'=7Q݆1Wu]ψ\mlq8д]h#ZסZiw\]Ab ui%)c;mbp'- D5j&DDoّ-g^AyM0 u04 tߵ=Z.*]Cۡ2%QzvH}CRn4UQ;öۢZCw] c5]ktÀu>F ޣwQh1EU%6 q׾DU;@]:MDX`O+##բA_kޑ.H}vǎTeCaJG K `Ѷ=2[!Z)tmC!1c@ gEf6&(-UUa\fgptPUi XhCZ_w-PUggwQQ/J۳qw\jBa [lADDDl..}08P0D2t r.`o=Xf5I0o& dӎ(lYKCrrnwNWx߀#d_,㱧@ j 5di X auc X3ּ9 X%WDb`ڛpC=p=o~&m)!I]aҼKn&lWPHS~{ }zCxZvi;szg>M..j "_zt|#:q  f^t='Dz,=%;O ;reDgMJ~1$ F?RII9]Rgp]pC]З.xyu.cEaɅB n?NG0`E1'xO>!L8)e:s% 0' L||xb[noI$˚ }ܺu ;TZiܹ}JeY&[³qSkͮz1e QXl'(T,UDk;6Vh~\u 899vLC(DE7v"o-D]WI|ݶ-i[f!>OلCڦʚܼ'g?׆li EGfoo&W]Rr]۶زrH1ȪALp]ס.:{mnw@(aCB'KQ&w]?`p@ؖthS8?Ghf]CD<\ۣJl BF@xG.E_s]OCPTtU@@sdp6{kσ (tWaS2Xʙ]9XU<"tmwu@Ȕ%̦m^aLR4q)ջ[XK4-Vsvg{F[M  6p htbF8xh+Ɔ>X(,Mwj@sk*+YUX-i6h]QC$ Q,;};t` !.JS5^Xb&;O?CErs7a>\4jF<"!Rp!v{Te <΀P%z펩71$뢮GU }5 imQriP5Dm9"]bXCqWcCJղDd&"qۡ(JA4{GyBhEQ5; 18kO=[+`Z!:#VX+(򟝝Q">>JInN5 TՂ~:XݵpЮ }rf> Cv>F,EڿdOkB^+ 5a0tD6omQD!;??Zpv򼎏0C_o~kl#Wy (- \FLfN뇊@B .WJ -6/X@)$uEc l@0`Qaw77> ѻ,B&Iiᆶ<)#RHbIv$9 )soǧ<=(=]ΞFG ^ mJWQO>MwF3Xo֣s-92,| /qmi[=>op4&H cgv"땊+YIdAzrъ>s:fx40NúA{ @g /2߅*- }-Jc&|B4XĮX%\ˍүy ⵩U|>!ـzt>j^{ǖ-n/..pqq f۠^ThQ{{{Zuc x<쳔 8ppp#zSm7жrJ +X.I`/ L叏{ K2z-~Z,q]MȢд-.ΰd s%m]v#.~΀Zh"-hftӦsƭV+lZ,0F:Ɛ|ete5DQumsϤSmÅ8HaBjo ȉP GZ@U`5mEYq"u AOC20 ]b*1lU^հvC@k^Ӳe [(EY`P#^wڰ듇TB-DwZ!oQ,m:[oC1Un$b];!5 \#yeɬh1mqi_njt0_,q|PzoP5<'w[maqj< ` 0 ?[P%Lj1`;XzؠrAmΡ=v- wGhTCMcYV ABb  < CeWO.E}ʲA^~,jF!0pحgggumeuhBCa!UMâa#-ӒD.jkmZ1mZ}19jTD!_rh] ܳNzB*i jc i!4EUP H>`F=`{s,| g^ǟP[b^'?|ctO}(!ևB˒!a}E&M%@ o>%Z!vt{y _!ܼ8jJUѠ&!_q0 0h:!q&cL דFF3mA~OPq0eT|!Ўf"R(E$$.&C_{.Ms aYߐ'i B?}F tii^d<1`(~LfȤ( TUZʂbqp9.^,X8sgy vF<)H- IK)a\NMCy fkt{(aapp46gxPq.KTer\~p~: ً>Ѓ{shw;_2, [qSmpu4ar h_{E]҃?mW! RW4S,xmZ)PP+,4Cu~AYVmbӟKZ *vw*EY5Iq˽=t<ͯ@) jZalt1Fa5wu7Fs۾C\ghQׯ߅rh`Z^_Ǵ/ {{dkA\Zk{" &fu]cb#+ۧ'XW{X ׯ_jysx'z/_zJ{;yQyQ8~ Mᡗ>vgzO's7Ǯ=C(K' #zR,iJv#Y2t2Q\o3PR8`ĺ᳟"> @mYjbք$xľMw1rc$\(ˢt48NC8Dl:nr:([A}ѯD?p戼h~w2_-[+ *|?/ކ߁ꞯ'~׭ܸd;XYx k ٕ#n2ӆ`\,sK~G3O3p;0 5fY@,Q5[ƽ_GٶEYWw.XmR1FЯ{J2;b/7@6t[OdbzaV , ,]Eq*˒`hm&7}i)HB|jofRaBibj[Y3 2:5RX2,Jܨq\r@GeG\1j#[Y!߃|ya #xS z\k$vQc.MEyTiRB|IUIʊ¤*Yy!Bգ(*b~p-BBRr?аvPC8]` =4Mayvb}%߮k^Ov_b>ղRuAHfeY(u^Ҩˊliu|c#A=dYOB }Z=7*+kP$ik-OͶ${A)UQ@)`Y/ڶbQc۶PLDadX arw]a !tYQ~JEd!eE vL \.YZCbRޡ6-i'C{n܇^5CNVG*Nc"϶²{'{GhCla,5(낝KEa+ 5tUJGY.8sWJ0/Mn> Hm-1:a cG 49hh*eiȐE}@{( aHC]P0զ_cL$_*DTE=8q^Y<;-RmBL`Ƶ4#t*oECVFV{@U 1@{;Bžk39B)Z'G-;eMJc7 Bߠ)]1Ͼ y1t`7@l| %Dq6)E?a A1)Yyϗ慒#߉7[X`]iyo߃] 3PTA/Gx؋/bu"ѣa|yn/ԙ'G?=15;^4%,px >0oƻ?([1GNpVb Jm"ѕK2E ]:nrE(\hk}z3O9'r7VZO:K4"y OJ[D[#'Ze 8RyB  {[F"beHA_EH.w=I槪Fğ3OuVdD!3#lxUU##z#V';A%b?(W\~G6ﺮѻEYJ'!\su#&b ?vtUBZܗLilQLl%皲 %TGE&$j矓@#V+BS&*!ptt J)w o{O|w.A $v>a]\`P%UzCn] @#j mKh[b)JΓ-J޼^wEYCi*b#,à<*1%bPVP"\P57nmg :hDO-bPEy4.byWN) Ơ<-qtsmz谀s.X(XtC@9t\) F [P7@t|ol=-0C"CDx8gtLB})Ѕ>"cv/6XmGy]/~3}kGGdw͆.n D.")T1CI rWim8xrdrOy + (ĴXV%Bb^0J*nB@(!x?BmA6SƇ bW]צ<\ D.!Dc v=550@I]C5%tXeUIT~ZKHHa0 ~a0JCj|(444c^ip~rk}]`;6~QYg+nSH}1gJkv/Fk17x1V=a8^*z e-NFNʔC(ϋ-V  fu:<]Ý=МC «//c<{PY]OpEGUgp: r]BAH瑡l,9 vI.+<sϝl=JVfҖX?eN=w]rQCl/t Zk?.l34\">ewuÔd1 %ICzvs"?v -ٓQ щگX3GH& !n[gOeAG{L%OD@]ko. F}‡h/ zrD/?/ZiDbd+~;1 Nzn @,rr U$~3,ƌE#qAWJYum8C&ēM_:tƪh7ph3Wm4 |:6@V轻x56*5!]x1:9`J*صX#!Y aZISPK{\"*oBBBR%ia"OWUZ0J e S̠"֨9*ٓO>4J lL537,T =de咁QH&fDcT :KCTF!dZs~'>zLD:_ ^cY]Ym4fyU.qkpme;uXזhZ!RRwTznrмM C"Q:>_Vm4= v40fZW~W?_FX" bL2QL·a@Q/FC%zN!K{srX cD*(o \zko^ ʐ F@4q+2\eNE;$4,?rs:ωhHtcљO{ |̸Z{>qӚ&VD &ISќvL eQk{aBp kJ5Mi`&;i)XX$}S&k~prR4#E`=Fjf@n^1;2M1&L^}O aD&S8Nzl!˫&A%#2R\sk'hn^ɓ @'"iD JFǙD[* G=SS:j 13vHp F$s (<[ 0}*~^}S x+_;gFhභ!D }}XcZ3a3瞱s7Yk"2ˎL#%}_]y +)N.)_?~_2ԫ, =%k54r gT7Z)0RT98#b̵yQ2Qw3&ty qlUPБ+M{{B'̐I?r]:\ Q#z%kؕ/R .E͑9,Ktap(] : }{GWcv%\"K]9cE=J$j.lZH%LSӶ#ѩ{ϢsuPVyW=}eYJ'y18 5GK8m<>xW`w#OZ kmq{_iz\_|d@S#!'S$290j.`OEy>8آP="n{2ٷ+epzz`E:ФI;Sa&3CrS^(tq3 M\!u(,`S{)X&P.,(?Y@(S[$_*qA̓d'2}?"M9F(] =LTQU3\=1)lfLwU,WFc }gsoP4R! ZnEEk4<eSG?!p~qC@y pP먒'#%[ZK B16 r:O#_ONtm k/<>~sx+^ۉ٪6.2FD)hSi꬐'1fl^TZG9 ulz/7-9IL>l5RI!fNAzv\Fy#УU'ʨW &Gl=|͘ 3Z:+Mv$Xy# uvaIiK{eDB :(QAp4&_!=`= hNbXs8Z@oѫFt4^#%F Bܐv5jO$0DOCsy2*"4gGKn2\LCG 4ơM~84T-BC?_5|hVQx =ϭ0<%-|.?LϢ@>F06wy]ѐdhKKeF#RJtPWu#@.LSTXV8}O<MG"V%ٔp좕o*GXkI੶ )FD"/&f Fyu:[DT&qJo !,LEV۔xx 2XS m,lQZR"f:A.v)=N+?V?#!)F{ ,e,j|l Dd2N1&MT h' ]tj^4WpԔjr>|3Ud5&QWs0FprvE@bg}Jh>df3ʐO ȝiO~4Eg6 *5'y_T%mڦ*/'|?fǚȓwt*UN78kH- Bt_cS')5&4P{_+Ru"͐>;oZcc4̓UivpnH0qu<,Q3$ ,6d-(@Bg~d@ѽ3؀ jE,k t}p7 Vz;3bgٌ$!:|zFV"yn\kk59Vas:D倶A[wov >ϢXC5T?2nDЍF ؎b2/&0NHs<$, KK^o {>~v$qt''ޙ"1/Xӈ{o!y-E- NgDź=gߞ x{x]o`- ?~?Hbt0'+5J󛈂WRӅn@!{i1:jAT P,*|7qM!bYc3t.٥U]ra>\m4wޚp5$vWQjl\BwVZCn"z7 YFw/=aPN>8s̋wϩN17es' tQIsaYܡ ᲋HWN7A==auޥ]ؠ4B{N9C:^?_G"rDղO=oxÛc-ܿ11ZQZft(AްD.$hO484t\yz*űqr^4o*ox@dUlUQܹQ2з ۄE&{t/iWli1V(lp{cɱ6"([mҿ(ٶ0VAl(͎⁃VڨID9 *Λ #ClM%PVާkofspG {)ѿWKMމO.i8-B&՜4x#{5*&Cf{ZZ5;:7xo{-8 ]֕Ʀ׿+nVPf+jl>K/Z#Uӈ1BaQ V368X֑(Bzrm\5WM8?/ԜL%qnN"%14IHh\0][4CAM&3ʐ:q3jmPB&ikV)E劚q~t#5 .Q^Mz ӄ\J@@GIJ[QB^"v$#PqA Jc o&߄۷nSA6 X{] J%XddkL"gMΥ< 6iD ӫ3.Qpg+6O)UZ ^1̛9zvBWki=AGrZZFv/ZcLE  嘙[8j@!H95T\CT>(r F"b/?<οh,LI84Pb-SŬD+iaKKd6GXxQsEn; uk6J0HwDgҜGR]H6ZJc9A+pmIn5YpN o$گ|fyS̥1" t렛Y"1oEJP8״G}P 2Ѡ5|w_?D֠,|-{ZXlY؉>CDɺY ~t#dg6Rϛ";{HHhPHElc>-hH"l6McKaI ^:2%&05"s1)!i%O7D(hs{X(\Orq;)oOl3y|sIO%1B@К.r@}e@.Su]'{n,Q C@Y) P8W0U ,y*?CdoIzc$m$h mKr8. Wk8eyDf!,K_nĎ5{qPC/]Cf}DjR/G>$SH>mPͺ&f5IdznteY(Z?Kcᜈc``.؍G 5Js }.E[MȧLQGPJ,to_ע,K@Hb*O*L4(/xƼQKtp) H&9 f*ۡQ/ f YttEOI/y-r?'nb uey:yim |$+6Mjoι`be4EaU<1#B@2[9?t|#iEҵm2Wآ BpC`Vn,V8~[xjkA^hy"EP *aƬCbtN)h*u֛@qi}7?^{E<ۀߣ|W]jgQz;Y҈X Rkk+j@]@i)AK7a.{g T|NUOI(|3/ì>.T/ l=7~okhoWӈG^6?'?Oǀ0HRqLKiw9oT65ZkQujF$A\K$̧1 Dȗ)USy!Oyra|%(*K?q&8yZq >@Ř34+"&E*ZO)w4nLPDhxr~ˋiAHf+. i1y?kX9+Lg1:y׆?C/O J5Ms gB^͛7z?_ǿӨÝP"C8 Հ'ʴ\13. ʄJH]π:B4FQyh^`t$/O?}e+ cPfq05eRLvE*fyz0Z .>_?y_}?'oN-oţxyvÔ,|s֣;2$N?q&nǂd$p]D66@m{PEAiT <o~{ebh:,6rPEt~ !U&,$Cfȟ/\T8ʒYH֚>S6"{Ǵ(95&[&`8\c!%,v b5hv&;ԐY1Y57F4 '(Lm4/:V[0CySB'"Yj9ߓNf,S&LDN95'q (_EtZރJo.U"7Β!C{B 5nϓ5 a,񙽤* cK]?m_SזZ)DYf)*+ t$<, SGѨDLVL* [N(_~ )ƈu%CҘ&z$oU'sQYpv|~1;=чEw}GMh-з=1QqD6GZKT˵bD*!WQ!%TBSK{OuRV#0[r[ h mBԑ2Vx(C9 m#²+`{j#R<tYʊttm,`T,|>cVi>{DO1Lp` +60*&+@KjZ nDk`󁐴Q > p$hvh(^4lQB-q&ĖX[@FyTeIË/=[ڛ^X:`h ? X5Yg5UMA %kC^ä;vޜ_gѺ2kLfI`y gzMo¿nBh[2PkY&x'4gxz{+lzWJƾ/|z/ ~~|C Q- a{כ3`h=,] ⤳:gtAQ@%"SƁ>CxGWw޻&PW5vGLȍE/izY,ч I)Xn3#!)$mɗL[D*xFe&R\"}|N#e"LGY)+e!iWQWYU-$a]sjB#eMIFD'6۬,eY^0u( u=NR~$4+/ i߿o>-"DDK#DhR 9 dܨ?b2SJVs-&Z>4n&ډ'@ MrBTP1C .C:3 M:a4#QsRJ#̗ʩ9qD6CcѮ4?> 9>̛u~ՉnS@dpCzH'"C.b>Lwv {TKd:w ptpyELgJL0*! "oo)Jz Pge(*;%WebkK3we#R+,Nk~LBx(SY)&VSY[\k p臩Κ c o&4lh> !ëK{W JU2O)CKPccPro&T 9Jޔq7%5S>'{G>kysVC ll浥m[v;,УV S|[ n?v@(CfێKΞz1+ܩ&n/А\pE.IMf&C%.A47XwսA7Bt-D[%G/X҈ zm:<_7_8Zvyw'N^?6SOިu8{s"p;J\@:4 vʂ`NbLL GLE c{{^Yhg^zi-JTp~p@á^]9@Mox!$ m'/w8.M֒%l^`T':شwm7#)&ךhlt4 k4DP2Z#ԁd'( 24YN(d^q6V#ˢL:6l&z\F YbVSyΏ1h84<j:TۗC\kXSZ( SAſ%zA4 ޢH.z{JZqy#D d#z*x?1* l 2)L%992 M& wV\n=!'eUPB bQ rJ60Lg)'[Ɋy̚eQN|mvΥddeYehN)2aOneJ~Os\[~*AÐc!hI?9X4X2319XkHQN9I ~?B/jLL(t40 OP_t]j&! Zz;9V| ]BT,yEj2X4i=~3 h.8}l,:3m5/Y?Q"$ {o!Oͯyנ-8KO| PڲH͙kQbp<]Oۀ?gwK q0{IйExAG4d|(n:bw)e3H)IG*n"O^Ai01ByT>OM} |-p,Arm;/ǂ(OE|ӧ/نfEt*t^ MgH$e%avR64)˚eiZBZpi[jUgQȏM ^6(Etqr~2JURawhB@uD5q&Ge,Q&SP٬`z4 0@x{'y1XF۷B2T*Ũf/[kSC`Y X=:MZ_vaZ tjc&ZzkZ؁'<d<ŏBƘl{BR[f| 'QNѲ5&Cn8! !Q cxmǴq?NǩuLwQϖ55ʺfԢkҢ,+,dmk,d0QF)c4Zx;T,@&|'ZSfATeާ|1Bmߎ< v펬V-MLC7tH׆ػ{"(.^j\Ddcq> |3Vc0^#b2"$s|}Q9Kk. ҠjLT6v|={k/7hN5AԌ_6 Sn03@ k%gι,?/bԓ7rZk8?~xh`p z^7;'o Oܹ m0'txgd32C+G\ny{ǖ$)DNiENr%֯k؝Bc)W/K?@1Bu~X]Bu~(_m12M@a.G`z~MKy_k{5oPhCTO\Ϝ$$}?L["FR:Pm 5#3GsgogQ߇7}:܇-4&+jo/dq=@+5jѤ ܻ&**LKc~hOˮgi"OӃQ1S]M)z ڷ%a8&#x Ä3|$ ɢU"n"wrÏ1q#ѧb(Vdy<7Ƙ b8G"W},Ēڄ90_ ћ6*="LJh(-H1=n?bYg*]e(BE5Oft&+k z6M~/O~L~2/Q0&@jDl,*Mg'ލeCD#<00_H{悟|9in4nz9m1eYk˖e =q:zE}#I앇5 J<À9Bck:<n?/<$L} oؑ") B"YC2SPEت U'8P^{w}_5`&(qⷿW> {pc lY҇aL*e{?w-lxJ9!b6}^yPSswF4#XIʚFC@[#.ЫUUMᢁ-ۡC]z'} E]w6h>- ! L)}^O~F;>)qK|A"8_(? ӿsL>sOΡ'eY&,1o9WwZ̓q $os"?N4Mڸa>71yn9\yc&r"wΑ0^ӯd-PA} .N𲗽 |=fDhtaU~\rh#&/3\e)P>JC! +jMDPZ0*!')R< 4S9I=݃6'@Ї5"s\):ˍdщYLc1y<0P>VU3\bsk ''8??u=R}|%CBcSz)kB*S@6*EK3z5}4 MxӳY g*@0!tkٮ*Ts7|/בM]|'/(9vWs'żPk/s'G,^/7aW_\#|] UoK7 ,?^y((׹ 0WcVLI2RG\*׀eû(,|cQo*]ٛ! =Q!y0yEdVZ8knFä> guK*Y+S@7ju^74Kb56O3_SO/ V#@Ö":A#(L]{e|/y=?w>etP |o#R<chjMq,sH5scN ѵꐬ0 Ϝ ϓW6 &4 K8f4#K>v"TcnY BܗV2Q~D0d.ɍ Bۺ,S? aD syA B>LN!Tjbp>iDJJ_Vi9P.wb4)6P3Bv18hRcl@Vra"ʖKkyU 19bw1ĄuLzH;cuHS'{?"4??qb`4AE),fqHB(^SyÑuul}b =A(]=5dJ0@t{{{(N;J ZZtT\)j"6 u{~X1PVUZ/ .JtQy3q 3Oq 0ܲ${l:t0l. 6oRϚ:- OWePKD5mZviXOG,y Jk'-c M6Yc703vwhqrMcsq߇;mK Kijb}ChtQ!k(i3u"ƅkǐ)KFXfc&J '7>bxt8Xh >"*0oxn|Woogx`#Cw=|=ۀeNvSíp'p߁nYUx[t~>u 9E }vK2[P$乄.5ZIϯaB lo8:B/qk'?<߸*MH>/ff3;c䨃ēހea|tzUR m'tctɢf93b;? ˚OeHSQj29\>Ea/=,Q9c/NTsX$(GS}5M3sm;ud19ޥY0!B`*y](mێ ; 9`JkJ xb{Av I1On!R3kZǼɹ#2CcYer38^Q$'ʓN&Yn+P {0 B*bCOT .d&Bub)*2RWsLJM ȚUdN⠥1gMU3*dĐ9F (oV{'dB!Fqe>G&Eu8yFeA3x^M#//:srkF ImQ80Zʎx(eY@6] L֦k^g'syƨʇstu@TVa6ِCV_ƋHRczxKjzzi/ (IX)Lѡo;ԕ^8, ЪǵЊB 9:( | m} JQ bp ?-BЀLi(8xMhF uwFhҗntr>2 *KuʎQ1ݹ~4Q,5zOB}nNFJ(30ㄐ @R'7n cu)zQT^2đ1Vm1k춛XkRbB&K)H H4*Msn& , ]M>ZY]((% [0%.pt@i-,@_\aaKYAVS@J[*t?ɗ2ټB+KI{Ġеis>o]P>X5Y }ۍZ.Q2jskve}Sats+j6t+Oh+:z|m[ ](^v\xЊ2cAYWt"v޻4MZ'mkk50t82|c}"m<, vѣT0(Ca9[|/O~FB$P&m,:j$$I2DR`^~/wca ,e{1 )Crf.]֣ @?-BOËz]7 VS d Rd_kk#p'O⽏n^å @"~C}u|2a(H\|DnT&|w[Yr%vIcmңAEf6CFƇ>awgĭ7qW(t#:Q1i O=Onߦ:IsBmr1AUrzDm2?& ٦۹~Mi2&3(*^Z`K<ȓlG/B E}OѸV=w-sׄFeZH=q_Q&`'6@ɐM9 qFqyD8>:ß{P(-MJFcգ87[UĂ1K! Sf~=S*wH9 I65J$+_"[jHGZP<7O LDŊI8P-r(X89 ɖ7 M-H IXZh9)ZϮfڇdsb\h!^bHKГ]vJkCmi >,yAčBhe*;zkG璅FOz jrgߵ U*F|Nә49m50ea1k6h5]4lSS;EAS40KH\!k h5uk|s |OȇX n"ZӚ `8@4;ݼy1$vd͋JqE zԖ%9ڠ%"@.nЪE#е;>Q/}<"^РuSxFF4jmF{?#@*cI~W-  89MmG&Tu  1@=PLP7&U~V.-kkvh,&l4y> dd 4N]%nRɹE'jԃDDTJdm,W5ߑ#6WZR;"o7KM^kt=;k#i/ y4*B7tҘy2ᇼ9E9L99o^Hgv.`ʹ6"ʀ& \iәszR*M=4b]Dx3 /8vwߞC+C5/!$!QrcB׆4QgT$FJח^3Q}mW<>Ps8?}O2~ߏ?=F Qg:̿ v_M5"jfw߾E"BaדH(`V2z9CtMG]GMl6 S:UqNBI')bKoD!q]DNP9t@zx?)?P/׽}تPm L@D\9Jx \V>+7aJo<<6_%9S|έ|sX{'r4.O83QBy 9)JbO'͔l$>۔2Dw^TD$\B\RA| \^LE\MGyJ+frqb& hT k}6&C] 0"~TH |zQ1U/\Yd,.3"ˉtMd`Օ%L9i)%NX- xF>CQK!*='4lQC, fLGJD30LU74kZ<+wↁ(T: ɞZg^Cs^Zy.NUBٜGOpan5{0Jrr<'gPh8NP ygQLD[0sʓ*6|Mˑ|M￾";e6do|m' \= ]5ɹ|Z5}!yn,Q[4a )HOmPsW=&-̓[kA/*-vziRp}4GX>ݨQsܘ%_S}/c~M%Z'ŜeJ7}Ok[ɵ#7G6殙 PHGd5Ax椌l$}ɑ,gG]$oKDב~_3k=oߢs ?RcME]?Wooi1xϡyzgUN:[vʼЯ$S<]gb˯9Ԅ*CM .=X9ܮC. (_ |OG~~27C[jFsʦ qjz6N '&YD>=уQ%}PV擶yC}*s OԴ|26/_OdxJcu]j,hqD~HDq޳7A~ ˧Yrsܳ]h b6)֩x2)OBUa{= 0} Z9'}\ax7A6&2"uUqk!#*":>ě)uuDδg؟Sk1yfq='cg})K/т8]hR1R`zVk2S ?)@'[i [h,K ( K؜!)}Ixaʓz/4Wv AOtCiIc|pÞ0z6U{x][ ^mߍ[':RwVUX⠃! mP!6 -KaQ쮗K)kl6dǺZϧs oȜ$F>pv'?oX&<^X+k/e푵E'b|U zkGBc@v9 )!v䴪~6If- A9H-4An4 buu~^j߂OO}\y7łjK3"3ZaPNYaZ`Cr,]eP1$Xg5adoxmIZ{ߜ!>Yjxzd*1d@E^dz:i|sê(qT/!! =.ƅP'9/n_  X|L\yFDf0 y4,>#o.Yc]&EaNJS QL4"$СqKixr̖[6&#ӽ>"&\l%c-CuM4pe"*'qJ:8)(B:uwof:*FҀ+L0rm̃keOA% Ð-Ekt$w.5sNB!L' 0%#Ĺ;\.s95ex̉ &cIDATV#hIqRIvr3 @)E+hx_ϝr\=vZsh sYd%a+ m߅E?{?༅R҃/U;M ShpAL&ufzclXObImx0sjL <^km e,8Cuk b*LaY7"1BK-?0+_ "F?n\k}ι~뤧:˲lIlpƢ1` d$TaՄQU! @2 UESErFe˖d朳^kcιOVՈDD<{9{֜'_/^z͸u1ea;Iq1d 5%Shé~Pi1FC(tF ҹ=y/WS9G^ lhw?[ChJڱ\{;.^P!MN˹U*A_{a\^\b.t;a 8a'>tpa҈Zq{,2j)%'36ȳ:oٰ2ivܜ[r=|jD@hvDvNΰ8w'Bof4<]js;VN[x+z4WCnHEK-PmbQv'w<X{5>pa`LqYҺN3Mњbt[g9OtҬ5 U{Y#p؆ g1ZtQ"6̈E̦i*."3"ӈ%8/{[~7^S ~Ky< B2ʾ=h.Pu=`3m暥HK 65CͅK;;8߉U//Ő~$΀8>\xC~u㭸o6Ƨ]ݱVRNhjۈ|4" ]=E{=~~Q<G$/Őqkf`ɅMxx?_x-oq,\ݲHX/"D" v QɩxZt^GpGL- iyznƧ>\?{/<جWp0{$M % !CSą$# lȑTOr蒄 Mi $Y8$;ȓ Ag cS8X)6 +' )k8-'W&vI' qnH9;jpsBׅY#j꒖sB߭fi,W>O >xdddA\R,7)YtrR,MBdG^ơ';{X3B'Zz C>AWHY6nK14;SBБ cԱK~d?M8qqq7NV~?յy'9Ad6f/z1#1 R%L-BN9f@IYCmsftSLU#'=НF͹H9E?n3RXC= Pݣw%Wz\l-DP.;bJϨ5P?=*F$N -g+p6A|sN6J\6kIm4TR QQ.vh;G* 8)J3B p^8t]~NULekCƊ0 M۰՜3S71\P()mHBR$il+n98 )>p8[uz%=c?#sBAAaNg0#uB j'pw:Qi[JlKyjP76a#BuجHSDrp$`U# ]ơ]@S1Yӄd\ZM}&q^ ڬVr1uB@f8;^^:0t*V7-.y1e8b9ߊ33j[w3`w& ut`Pp0#f5iFmCߡ')Fap:pNv1"mm~!ߎ8   0a5 *8&X/<[5i@aɎkjJۢ:dWFMfWߔa+ˆ`1bN^736f٭Nq-~xxo}KcOJcZv+\?jFDp\Y|ݏ<g4B 傃4!ff|]TW!a6ڭe0ߟCG֖Fjhc9< yC"ipݯ~>/}13  ί.cj j"9B^aL0z2Fʯ)_QlB6Nc*@`ӿV5H9"Rs{>) ڵRA;&%2)uWGXIQiXz8˿ )0 3wkm(ت1N3L i, խ4فuވ~+4Jx;7s _øjXDqu~&nqzvC,T!OYB{E>3!A%Q[ꄼR96)UBB+]T8M ^}|T4/ OzI)PYP-zQlQe8ZRRŃх 9i#Pj݋+eRV=B߃a^W򵮇]z_+j+`y*%Nu>۳sतMk*zYIMRKkbjp?1cKh9^Wƭ6}_ҭ/E8U[0=!kNiZ@Ki&l֛uS؏R}PŜ0(+Jq=s"^hF7emҮ״vX+ͨKPЁ`x Uo6򮠶RÎX %HkGl2.T5I#Mvin{{N[ 7n'~އ瞸7+Ók*Vq64zn4!ؕ{y:6x}ZRWFVcV9sؼ1|KOp5 RvcJ^p~0=.{[{ +\~|uPX!~͜Wax*79[1%F Cd\_;#}~·~-=,ϽMo۷{Q :ªC{^&f$~Χ5c>h-544M 綼FݱF +„fhȡ@-9 kO G#bL%;v4"2sIr%\ -e)&({zrV1*@o55en<`!=3ivhL}[!#vJz='iw-OƩɤQkq7"p`t9aJN{s_x'>?\bNH Ęed8 JӲR睬iY*gro %4& )JAUlKX:5ɶ=40TYv0e$) (S9C'(Et,)7kx`mZUISױUi^("aq.M| jvAGYb{G2{lW Zw6"N b2c461~IS]f,;Op\8oGCO]܁s>~~um d]Oj#S$p$80'bi `?ADXSS4t;4L03gkLV9PƔF}N IR57""rƔ^܎ԁ/3n8xEW;?րZ- 8GWXJ6뵞1Y>I}#[PjgOfoi"=/(Z!~%4 Ìz\٧sP\x8Gfso~ q: 34 1E7N^.\OMhR^:a3[*: ry܂|p'mmB̌cw#vz_CM` !6Mf|EA~ x~M0[Bl9kލP \&H.C0b؂zc=<~~^G1~x^[<nuCC߉~QJ̈́uf0dXxDlJ_6)&pĹvϜ4TTZ-%{K,K4z6;! 5Xr𥶩2G#D@#B:1kZ6Xovz`$SVx{IuIP,cBT/itǭN@A–vׁ1{h3=t]]oa3u'Y. g*̌8P*X^!FDϾz;(tBATM\N֤W@HCq(UGcAlNjU?(2v?:QF6 BPdm*Z\}f#s J0j0TU!ညNu~kJ&H4:)'\߃A*.0@V(X?$S|Lͨ:6^&7 h=bp8)Cw^>dX8DA.̹2V {O4VoWbk΋Q3_]I: pz]:6԰={_i h)?vp޽^gehkhL@w`w˟jfhZ 2|Mo2]skB$9%f4 Q뵴m i$ A(vߗA1@A۩[2+n~&Ah<_ kYɗ(S;:fi WO/oݿW]D5DABh6 1 &œWjɛK<:|bK3։fkTTMHf9iKNmOn+1Ÿupw͍ǫpVӈh+@DEh]8ljaU2CK@m_±g6|Sn !pPٸfUPN*2ȈA`+ l 8<r16MMڼ[f<01:$BwWH-=[xK_O~oƋ^"i~Р '\`Ȧ=c謨5 hkvCpsʢiYY^̫\ Rĭ Qx۴ᏽr%8̈́ W;ͤ H cZ5vV݁ۋהg>@.cE9M50 naDa[K{R t!(B nˋKxH#Ŋ|٧qzz?!8aJIX`Y'AbZ"yS $JX<+JhHZ7f江rM$GɵPPDԮLrAnl*jX`Yˍ;Yii։5fkO{yj6(o:6E&oNm٨L^PQМ1"WPEΕnUt%0zS3 T,iD$ԛcF0YCOlb#FC ^ueWLAJyN|oal3$-T[$ueØ kxڸ5ǮU)QKS\GمPx~:Ͻ.mZf`R5W=.۳~#mTp,ZdݚnFQnۀT}{>qDk9:1c#zy#_;5s<]|^&KjHQ)Fvq4CЈh907iݺ2XG\t$q-jH!61$L|/1$(p!o) EK]_"Y^ ":Q䂐WxK^k:Ccw'_cx3\ B_Bc AR.s$ml4<.ƽKF. E yL3{&8auzヿȜ׿Qsg>9ܻ+4 9cOSR>GDHS~1FyX?4UzUNBڑP'w Ő=,꜓aBdh1FJ\nrV|M~ER{"i>L55]dk:sFzw ۧ8iSJ蛩b }n>Hzq045<6j)7D(ƈaM 1gLÀv8Mp>aO_O⡇_??k70M 9۬WWZ4`]Ycne?9gDũk^,cr9R7ֵ-'LEW{sc4ʴFFlNڈx]\[2ɇDґզӣRTvBaVĩ*ab)M Š+hLScӬ:1\ID+7E3Ri)ZX&W\'4 ӌ$X\:j&SZ:CG}89W@ꔒ <{4{AΌ庅SOƃbP}g(TGr 4k6 (X6ícXQ[=_Hȑeoi_.{i`rN椹8\(`-R$]+l(Xm a)ﳦ/;W&GuCl^6|jQf&i@DTd m" kRBŭЏ`/XPpMeI`L) VQԸ2N{;=w~7[[zOo?Ï7;~ϾcO<͛+>@iAd (nX-dgvj{:)GhNXp-unGTc$9&yGȌ)cGa/}zAqg?8xm6=_&+p8_B׉Aoq3'lY{T[t~XbzrۉuX/PN6mp9"!jŸטtMxq,juG4gt$wT7q8qN ;i/Ma:&%M@DIva7k`Bh fiXlSH/H"h)M wCpww}=_g?Xzb6]I4ed1M } -P)k5p-Hl`@L Աiv),"T fl‚qJ `]"Iet\̒a!h'óZDHB[\\52m@ҌӗgF="Q.|թɔ&6UXTѨj"U噥Pm^ZTt\j Qgɰv čX.&,$Sap~U[t-&֚pƙW1ϣX4K2E3jp~wn b2K}1Vkg,{Yp81a{TB?̘J63v(TS02+ٟ!VŔ37 .:Q)Y{x(ﳼd{fE̺w&ΦUF$S'qE&9 15aIJ2}c_XYSk,~n.TV9-F$axrC". v5w~ nO/'I|SSà 88H\mf\DG=T)7c55<0W,P0X7l5dAvf(+dGE^l!Y O ӝ'' pDxބa Up?KsZzjV8p-"O J[Gt{>'<0y y\oڐ 9k8t )\BCWqF3:/0gf/t KgMB@ꬕ](9 .u;G& F)L)wxg"t6'+n6899gx衇p9od[)޽_&xW6:fS)N U 4W(Bu XE-z,i",Pˣ4FƳFĖ1 HY7Y&9_x}@׀q?t>\XK)~Q<Gz~ c rWvjwZvanM1}nz]܃Z4yNy~6 ƈzp#ܹxބ W_)#|pZWXчoOSpBQҏDU=hgq33 q9$;)JrJx'ɨ ù,O=DH]& 1D- QiRI } %$$ T9)F!V ě-ۻP̝˪ȅDMu)"^ Yv;͐vвqy~! 5GSB:LÀY']2p()gq i)Nvba.2w찿Pk"^CE.I0Ww< }fDYR۟^FoW6OȂxMӄnx_OO}W̏}u<< `x:zl(uRޝC벲SijuTsאַj7^ϩkT1!j:.Hw>HwAC)kB %W7rC?7.FPAޟ~gnR)ӗY$eÿNs#8=H/^Gu Hn~F6e#f@΂GC.݈#:!؟X`nu ?-3R=J(A"%^f"}Jn"n0ms"t4cnk3\ȍ ܮ]WάHR4SbC|g7ߊ|"ݢHӺ49EzSVDMd{4a|#}50@C'U: tyWml q $PH\h[IڈҜ5@9sh]q&yP`(ZQ۫-U<6'rNwny˵haoSk,ړY֢ $]>]Z$J@czṚTH{ugIιPBG^#ƒ_2U/Nj_bONpv7oeNC~?"u}yd0n޼Q~_֔&A3YЂZBU'SNiz<SE wY0TfA1F8S/wS,C"`o ő3t&lV}AR9w]qC JHЉ{9qRy$ª =y{4A+~ Nm~ޅ z64c{.n1e8 JK}䡇 ^x9|įG~>Lu]V!rH8g- I8^fzt_|^wQ  Oǰ77JCg,:}!"Nܑ]lI6o."ynтgF8YeYA_Uڐ9DfFk{Yq@\t͂,F륹9F:BuR<0 A!>MRC)Dn.e<;]@gD)nn_+'jjjkkfSD\ ٗ8bOQ[pG:nu]ilRJXN*5߻WI3/20)D&>q'q=Y [k|eBexŹijwYD߹" <%EDrx]~v'ݪB =u8==-,.xܻw|zu )qv~7>ࡇð;0/ z#VhM_|#xK_7[99k~]~KlwbH1 sAZ$ܦ͟;gVƑglڨtZRxDE|gDދ5Z׳ZvU X#emLE22w!2zFm!梇Za[Hd{&'cIA_RrU@L{G|'w2Yf(ŠyMnN̸:Lul6 8B6(17/Cqjȡ46fjR?R+TzYa"Q8h%pv G)Īi'vВ\],xˤ{9}v...3/x y~N9eqQ˄•~@/XpZQ]!MIΌ#3ƫyh&[t>RF4jpү@Z?{<|@ajl zVX9pҭ0l sHn*bf,9 3eX;i)V] !C'W4{;0=n. `>B)\M>H8!P.Fq]D@u$XeXfIqD'ӓܼ~cx#s~>A:-s4{kbjPp39dJ e fc;q-ҡ|/bx5g4Ա|܇6]*AoĪwXS 3D''ayp(*_{xBUJͲJn= QS(mɗ{q9Y~su=r9NVkT5 }1!5E,@dȱH$Z*>w:scǪmH Ċ80$Cd;id~4^`;Z3b n¸ۗ\L^@W899Q M軵Ry7&T% +*]5\ (HӦ?2j֖&}4NȻ jJd^s899fA{Ya}b_|j;%bNv7ob8?e 9 lΐ|AKl6}t!6g7BIWGB W//x1N CN9!elI?suj9^1ױń1TPRT{ĩ+[!_<#dUN}/*ޔ+YY pyR$9ՂӮ~v˯1ё/40U+Wʀ d[jRu+# f/$&]@H9ۘeZ֡& 2JEN΄8ë́ˈΟðbH@qr)Fy!C]ҽ[tXĮO^?exo.RjxQZkM5!P#䐑N۝)A4 [aSvoh]tpQLri/H):9 wAs: n6 ^~815$_Dof$HB] S ř  ڛFX;/eKVO!/6١IzTOI<NSJ19Z:P Uly@IbGT[u:MR6+a#W N{+9ve3㴓{"FOY,8i4L4!]]`vr|mӳ0b{qia c)8'rsTrϬr2Bk:XJ4"y!]BNZ0KΒfie R㝦8ZrF$bFD}51GpދmsMpwkaҩm'M9Zw*AWȺdƪ -[s-½7N`jJpSשq&|SA:KB󡹸Ep9l%#zlpyj]=SRljxP5j \`46 :kw(3;{J֤T- f=TQK*0rb 1c(z K=qH4)& 8eI)_F }h ,I2sĕ=8O H!V/zS4*ř(2jj)\1%AM"@G$>%>pV8FqDj6;qac9J H!y1> 1l Lng̓d{ EPX2B ]oĺ&vC'~"muFM#5i}@Epk,)\;] EeG6&?cƺ_a tzmD a,ЮX b.qǨv!}Laͷ_. ( YX,7$kZL* WrkT5Lk3ؕVF-Yf#B+Y?#繸43߿E y= ,&m8}<Ӡ,^Ԅ~iafl['gzVhksq5m 1~/4EG%#rdl/4qyOfi\hx-}Y^24"LX嬴s +lߓ3FHjZ ѳ$v}06^49bs~Vcr9>Azq (# mLj?lڐb˒\6FW:vNrf& }S ;5Ϫd$Agt. !( …$SэwrZK3v-v1.D'9T,{0'S 4%8\\m[2~S4m]8Ƞ"gxÕ\/f5i6fLY;p:cEPSA ʚ?RsQ m}id^fg „8mn( 4z{=>ښ ȖzEqK4i*H 5hR-7DYU݈ ޯIO ֵ8^En&H$fQ7]YY#Ay r􍕮EASy[D y,0-{ "k(kF+pWUn%'9*@}D̪ј 2$ gpDFd_dO8}@G8cw)c؍߹ tzou60na 4ㄨ]ywڎ!IT7i(ejS.(=JFEqpP}ur_}M4)vZnB5া>"p=N=t|ۿwrgL$z)]%4e9IGFL<=d\@'y}^"rHARCFuNӔ1J91'-߬kiDP4#)%)tme2@0](sJj++ˌ4ðdr98vt=3y<W [ ʘX"" δ`)2$2x0iՈ*=HHҰeh $v' kQ^yĆI3;}BжSe Pېs`R;S.CJ`GsF@yPp^Er+T&V5xk)4CCpxt ! 3S/MPXIݱLm.w^5΢I祖Zƚ7ii3>"`o,v/Q;SϒW?F3̬/g#Bs ڂKi]HJr±nn+\EZ&-4 ?ՉS3!T+T",m#߁'lQV`>i@aߛ2qqBM9y51,caVq!`nVS=g0S)C2"1r\Hp!\ycxx÷_om:8v$?F%$g1 \W"64a:A e^Fr}Q nf9$Hl)G% 3n4xk~Cr6͟Klٰ[/HY{OUv_31& 5U״,&[L6`<%^J)+ZX5p\"<L $̆h,:2$5glC:FvBM.pDv9Iqroѭ#C.!oOrn1Em6{RAE*E[Bn}-%&/j-m,iZRJSD֣Cc>C-_NrE*9ƵhS jٰS)xS<_?_jV;h6 .Hx`7sPd&x՟qP`E7C J+2ZheCR_#hJ%vҵfqW5ͦ X]),E}c6{،.g%ZR6}fu(gmjdzpӁV61($ |%bY}Ʉ#N9pKA!ISjC:D L̞ R 8@9u D8Yi,ø8 8qwƇ~iHR~w\#s+߁y{x7| >g~o!=^~52u 9E4wRیg f r3ly :"{ RbŴh kH6}I*gFY:Ql*>)J}\r)sn EL؆ZS63ZB,b5K ߜfB/޿˚n%6͛ nC yP9sZiya_h4Fg9\% ϵiYdTRPEj/\L!gt'b|`A|T]RZ isoSoQ{bU %K0q2O%jbÉ&xI-D.Gг²Y`:ӎ&M~K]wk7Rvi"rSk#~՘$C)[yi"~U$4e9!_{NRL*v9b]!8/뗒Lv)>$4CX@pAS٫'./>dP8y3No= jP,@4_l!4-Ej̕zSB7sFL :Q)4ש!L-$D67sTfTDAB4t$XN K U !Yj)Q5F_U;@tVUD΅h"y]i|4Ah4%ѺV \*6 DrFʣ4ٜ\YU9# n (kkA6 y,$XEh -m)fXiXdw<ށC&h +"2ݧz^7mN:Y5j!=3U,: L2b|,xwk޷hNf d~N&B9רJJ3qx/L͆( Y VqS,[G ɒkkuq) Cc՚#r 4MH 1,#ݐVS^dh}xoi4RPT8q~kqC8X4 r<+J<"ԣ}m|uJ(VYzƖ o4}ڴHL5u)APcK-8+iuTjRdPPKFD c)/Hplu 2" L"ԉ tR Lք0ks5襯/~5ٻ>sz>^j; _wا~?gOHM>۴NpW A8< P--Ğk*.:U"d54شE>ڦfIj_ћFlR<[*5/t.HtJɬnSApe hfΨSE6%A\/[n5jV/=Pڤ"S*I=qciZzZe1F8}v+f%/Fij>R#^MF(v8 U@RtA6iA2y~*:C}XkC.$AbPqZ4u=38`E 9st%jrTFNI)?$ccNDϳ>L bYq"3mBCv|WOGkeݲtRa;V#C2X2::W5JiJ{3\# ZT* q0gHu~Y͒:J3 U+,'w#۔ ă-wNuMK{VE#]>g47K<\, u,R.Mͦt2E ,56HFQaŦ7Y5S[з͐5i\m3(0GMb\9ygZ@t,Sa"A#ןίK&q_An-I9p9# 846~kqcYh_N )CZcFRblr^h Eĝj0981N MlN:Pf_ů_#9ǟ vw.p n؜=~.5>cJaĵul"VBgbJJm}.̴HuR?GVZ/$2 |+]HEG%LsBgFFUf+&Ò,2nUvvzvpC/dY1o)g"pi85;zH@ ?kW+ɍ)&fqr PlZ^}kR "ܴv1X\r%Z$Q!&`Ӭ|0yCsjO -g)WSK_oH !Bw?RP N{jtF"_X(8 ew@Z/ui!Hi3ZT$UHДx 0Ҳ.+6-EymG_Ȣ lP>7"Й-EEMЍ:c_ъ4UATɱadKxmRg0Eu`24 &iHrN[Ǡs3<sLp}$'fEZgY?i )VK0乚8BuʐT?狣9{B]~?g,g }e {n- C#-E5 Ҭ%_]a:,ʀRMB\sIn X_D}y6!Rٺ0-r3w)hjgŢMTKMkn֘-5w0LyVS#&K,r gY4)iZjQKwjVD:! v Cd&3f|A2.EnK=WZ6Y[}p=CimW}/4)QOJJŚ}tsT! JsDs᧽^ś69u%ĥvPïj-Xieq:`Y`ۄ,E퍀R̷FC7+Z ʲ(F`8絁hVǬi#L4 D+<[ t" -9) F*(Gn Z1#4 O) +m`sL /Q ianS zz)t(-:)bY#g`wpޣci}aѯ;FgBX= =V(D 4Er+.b6tX2&[4"RXVR^и or=WmdX#!59gGGx4^":g57 CNQ@4EJjQr] khb=BmR Zp4;U=BS݂ڵ2AгCy2' shݰ: EYؼ*vdw5.0Kͥ4 !`sM1#Gs@Hn,@:eLϻDhhְY_A hjM [) "vR#.X&e3KP[ܼEggMt-qFk\4X3f}kDJ 8|RNas!&2^ ByB Ja<Э|1ȱ4Brl*w8ZFboս#n{):8&g ""jM!\-R"+m{;PŞM&Udpd:4{Dޣsk*W 8똆K)4%`D zw)`'(V6zͼϜ)idn BҔiCq{k("WC'.` OrvΙc'eRA퀄fɚI5):%c6aSIP0bI!'8N :/AaMY]YD\2K5I9d^Ut3<5v^:,fKO. e>Ip^5fK8rgNsPXHb qӵĺf& ^SEnHzD(04Epa 1Z_p)+.{DRS2-"Bw 5: Za#14[׫ ;Ρ[$/$JFyՎR-)|3|>9AJ 58ECI558? J(O=ܐq1]"e=b~F.|/i[[0LەY&d 0@å$^3Pݼ6AC$=4LqJ#J9L$ +ǬUtAT,9[iHxI@4q}k7ôșmβ+viT1SCn{CMJS8RR*? ib*fvyO٭1PS\K됊Pk#HPR@Sf p*{es]-"` DنxfwָkR?6CJ责n4j5\VOxj̭j/8ΐ.x* Rv"ڃ-VK%b[x 3Y9OʧL5i>biEi&GRf6YRiq9Է[ HP~q GB/9r]B{ kaMےڄ=6|<^A#A >Gr|R1ZR~?']Y<L`rYz0˱.M\g\/Tm7JDXЙ:Y4:Ņi&(@Y!8nU}Y"'(gv&k٦*cYd*K}UeYߩs*ZP&30E1]ARNb:RFLD23"W͔%#gw20pQ!~V-7ܠz i Ok놔=p(.,Lu9Hmg14bKdfVD# _F (]愔CMi/5fctq0Muo 3 h)Ff~ĒH4s/] -NMhtyͥA-gb.,ݳ6^Gŭ927Nd MvgM3?<\#]='|عITwAņf㫾&tun'S_)qE/EsZIkq?ϲXBcC+ZL]ln`  (@FmUf Pfrbh8g. Ysbi;̴4䐇97Ab ̬ :6SX31Jg gHլCfmsKaD?G'7?/UUڈ,;q Ji]w#G)sVkSM\Omp]TiĮɹpb^5HI zt 1Bd'⚔2(O3@ 8 G-R@=+"ꐓCƥYjmRFOa\kLY9LBRE\"bAb4!)\N߳v* *3c _VDւNbEoR;O#Iݻbѣk1GvK: 0+L w'5Eç ܤ/?0s5 YҢ\4Tap{Y-CE'6ZQr.;jQKna3Uޯ|Ӿ?axAbe 5Js˦*@5N3ߩ^[ZgȇF:8~S^R~>t56)mȡո?=ύpC'uಘEu1%uH`:tAbSfg Qbη`y`̇&€K|A:H5xBspv0ia ]s}HMK3G1l{Nqu%E{x)͇R4r/i<{L ,|{l ފ,ur[X&m I;)N& cq(9l6%UT NC,h(1=u-#Í4G`n0O fe-b綔D3T[״Nj!GKvF[4#< FIYIfk`%5g\=$; W50Bj3Bʣ߾Q-8bLRn25ϲiluG /ӛ|m\ af$GZ66*/ 9CREg}j[!߈N1 "bQ]"] JQ;=nTbɢr5» z~4{`zZ)"'m0o<3 `bIDAT' *%ƴq#Lk&0kQ9\a g:҂:kUK֦N5{7{v&}D @3Z(5|r:_";LIڰ~ҦsB}ab`]~>;.gBm:`REӿnzY k:,k)eyT~ }{Cy6՘i@r@XJͪT wh&y9Hݛ@IӠBS)vRV:bR4/G(4= tm5w#SDZYWiTe rsxNo8RpX~!XgLzxPI}e5MSSS3ۣr" r^FoVqI p˪ 1^~q܃<)5oF8EJj)j ߔ=RJuV By,4QS֘)3P4OɊ‹w"@u蔳Ћdw*[*Y5djJe(VK%[w2$'Qf2h{\Y)P8I[9ja9 gÚ0LR^=҂qEyA5k1,s,װJ.uKP6 K h 7 Xw͇`+k?kVe'MЧ;SU}[%raRPLk}ۚ& 2v~)BU Mz@VrڐKz۔) fo A ֍j&p? xƟ޷rfa!G~AW9"B\Rh4t#в JPKĜb) *fZH_}:)p "ik[X;9pHr脕Ɠ٭fp'n z\SDl4Jf.qCj 9g|bfjh*R,'.̙(h1N};#Ե(qy/cMkWrNs$6QTx\WsN7đϴw='2!R!^:eӖF9 Z'L2ߦ <.!w"7FqԂL1@_jVjgLOE5_-+]-kЊ2nrvoo):|jS=(MLiZ/Z f;eݜ"EdP 6뭓!bg6u"QT$NJXB^.12'`{kj6ԟ m!tง[ ywoW1M7!e(2VГy_ߨ= H3GY%[*H =ef.șW>PY5ViNP#f{ls})ԂͰ&'yR)cL]6 ey?EY*maKVL^ %Xs Pdkќ])^k@6lҴs^[PqLP5<z .N+g[md9/qWB}i'F,iS5b1mCޟ0:#Jj}__Dt{V1Fis"ryp\=?WM90I7:Y4CbZз] .]eCg^AjO_DT݈ƒT0Za]/Dc 5x][[A2 Ojz*;ȂihPkucnUc"I#˜ܬ4 iy6q B2eihvI0/ .21 [ވDm !N(ܟsT76m gԬq P槒P9TdE\7(ȒQ]t*lj]x\L>Bf&'Vnɲk;%ƾ84ۗMCD7&"7H<$XRw*52 f-gZyQ?Nvir/-(~eϡJE-~ZuM;0uh!ҝϔ5s:+$/4仒Qi\hqOa4RQ>&UE4ZA@ ja(l&`$՟= (v͵4Q֬M)kFDߥʨ2B404&.mb֮/y|+R4ɰ߀9`m,j- V Y p, n}M4a <\8m%uݭϐwt8kp @i{ 2yU+F=Cbui 4{}q[_7a<0k +Kq?-}"e\EseFAl\Ǚf )l"JQ C#8Kp?ލa7el:::?vU |mM'e8qAe*2, IYS¦\ 7cxtVgi~G^x3hpkñDУ/x=M S'@uprL_pQ _ %ww^i^ez,Kj&ƥVBtڃ0C6lvR^׌ɋ!" iM,9г&ZP@Y_&򶅸j/vi>OVu9ӡDzhkQE.o:Bl_do] l}5 0}iKGKA5aM"R j1f6SimחƵe4^(4ٚԹֆ55 B᳓:ϙs^:4gT湔fzl3(WMiaF'5^,o% ͌䃸i9QPQʙgp%vNIMHxA6Ѻva-T֜Œ,l*uj9Z*br1ˣ:"\ sZqb?C*"O$½虓caV 915V-4Pƅ6$qBXI$4,< 5RY>j fT՜U<ЗW,t7}uaNkKF 7gjkӃ]O}ʞgeOn"kSVby7(V7 *щɃRәҩ[rr Oe8ˆIcup8 ;mir c}V#p'ϗu+2<+VJ=s3iJ9 K7:ȅ=Vgy0%VZ2.`id~1IpsS+q|+>x~q҉-TَRHCMoj0 ˡ 0+cʰ8znD;lT`h^Wb>\B Zfd, "Oxo~|kN0%":- 5߆ߋS<}cu'e 7gGnxLI|?s<W{T:\4}sr>[UZNŴj$f!g]w|ţ^ ;\(&Ӂ?lֱ4eF y˭&FѦ5!(M#`b\j󒈛+t&cq\LY٬55aфqD L@"-`җ}ﳾ蘥"'A9l}Zg}I>X_Mj1_&m1 b!)zGL'4l6Y (B+Pb9gᧅ8~xx :6eJ\ֆ/k`m s=+REs3jw8.F?FƂj񨨫Q||vHynP^u+5Il@ᆊ5RA #]7wK,:Ou$̹RMw`s/? :!Q:數"0OJO,EfΉ"yyy/;.g<$rsqE΋(3} <ōt}V?}`= \{/:z~ݧ~W1Bדۜ0 b+pī xnt)\}0ƔE6CG&' o&쓜8k3W=or&dJ|ʋI1/?gAM봸 7+hnM^\Ҡ4VQU`^y['xBD5xߝnoķ?o~c~d Go7^!}zl^v{~q ;瞏GVx^_Ї t@a` m|=ԹIiFC1oVGaT@rn|-pi|)tbi>U~74 hM^F\q媕0_qٓ M7_N(<<^#hƧve]_:PŨq\LOb9Oְ9Z.RMpVIbnulٵ7j4$z/UBVphO旸 !毘5^^ rQE9l2[9ïNVX=&a#׿xo|+0t[5\[_~ßoko[o'?t$"H~[_{Km~ok)dƻᅤw/]8!|͛>琮[!94Vemg-9,Bïŵ7.{&Gp5f Y\C4j|ڟ =.>F Y"gz",H"lsN.Cgs"GAi)TE?}vUpN@]O./~ȧV c /o ЎO_'>!k ~[^S#'Cpݔ~#~gd†Fuky._ sۤNХ\LxZVk\*BnAp ϟ>V.UYJ26]A% j$HScRvEMõ9bXAաʚR\8k:UeW% +Hc'n]V ȋ9*E0PVx8LZ__[_CO85iGP0 fBWe8a&ֻ ФZH֜j+oZ(Ĝc5Yun_9:4zFݣ S֋׮%I z9K(r(ϛ`އigfi~LA]_-"??klU[_7v}5t/i}3nNfE:^'x)|g'<8[9\36xB.@#q10ƌg-/Z(`76vdtyDf^->{Ј7~}(L\ }#/~>gIrpg_;x2aLMlȫszğ_;ی11E}gBfq㭯y!>_c$ b4;[\[>}yd٪?j}Ÿ<½]w픑2a9L Yݔ!;[]JyшPqelDb]\^l2^5x49S] )L,RBD jC뤹$Nn>]ȸ  H Q \ b"l0&Y!\{k+Gz]wˌ׼EE'bwm%M>kP>:cWaW Ê6&o94x&- ձІ[i^ í xf.hBBCӮ %_' 5*޴ 8GqP1J6& j9wQ{(5f\|7FIvחy}AsL+p37"B 92/{(by d_쾆Gr4Ȯt{},`0A$!pLIMZb%Gd[v(K;*WUqRr9XN,bQJDJA H+ 03[ҝ}},$Π Eͼt-;'{`Ȉc.ժPMbĔqjPHHN9]Jt2Gh=ARWb<8WItP$tpER{ⴒa{]TQ@2jJ< \u. 4BlWD )1|%ˈ2`\ ȴl4|8Nj/J$u@z 1p5Ȋv*xJc^[ue"D=v.@P_aYj݃5CJt-G +!P9I.E4P#<BTKgu#pUIBl{%qnNU@J}v1tÇG!65=(1Zfٶ70p'TJ!Z &9␡ZbC5q5su\.ZvR >r:īw1ӿ_О%s2Goٍw5!3VZ}X;|fz+(Sc7/yI[D^`.w\@BFW+Жuc#{aBO4N({zT%"R ކ#SC'P] @Of0 t/Lac,3lΔp,M190~Ju cR.q"M+/|% E;Ck;"PI)nRfѩS+69 Ƣ7 +(HiXALxS _WFU$)`5{)zXq[({+ un."!Z4Z؄vnߒ}]nssϾ@Ёb֐tL;=ȄWE((# 3iWj&3e2 :^l%SZ&"$OgE*"Rj9gNs~!)% 6nHHO'Jh C#]cWIz}S&~Bݻiգ+&؃2E&>#˺e i3TA6`*]NRKz{7!8s-L;|n&͔Q-)?bؐuG!MXAH\(_VX;abch5?gڶ@Kc0SJ)F#ZDy.ܽZ# jI9UUj;7.2 V5R 0αJO3:&-߄Z# ER{K 4bT↍˵2,kwsܣhfhnslz7\UvXݎ Ȅ(]{=XE%$8R9!?an=33ۊ~~ܧr ˟cV$-c D(fTi'ِ T)+iXt(xcH<= wILrD`Y\ U3Z%GȚSfʰk%JNٶN&TH&Afͥ8ı&-#tVP Ysڲy"[p9~daiͼ9Y-(rh맏BρQz$;JJ^VfU9a\ɬ`x݃ʒGYZ-8T\I[BX5]I1wS:;· so:'MP/u煰:Ku+M~ ER1e3$OYLOgڴ'lHc ug /Fz ͻu-cU+s]MbA_[.E"@@}j gl EIz*KcD#>)Uq! NJzP'] T(%\HD?! TU# r0VCJ+A)PՙJ r򡆫xy,Q7,Ōs0T PxuؒMPtGz8,Eח "%W]ڶ_˪JΙ}@,q /a?@č%/Pe&A=5Oz ֳͩBu?oNͦCJWZdPY<37z,r 9NfkjV"W'| b'WP-q T"? <)NXp~kfg`.` #x(ƕ/3$ō@Z^"g3n0'MjԁvhxR z+Vn64{,INi!/%Ƞ8MˬG 8א24@ %-$X]3_JOPk4z lkE{=w?ϼu|B^ܷ^\]}++xYvrsocR7RG=ѡzA)oTQ Fw` k?I6bE=D9djP(;Y>f!3Rɗϫh*#\mϢaRacҩCC15BX=]|Cg5]]DJŚ%&ed!}l΀_y :'Ԓzd$c(t[XiȟMt R#Pe }BJa'2O!gNo"DO ,&=kq.daB"q̺ [y,,DXJb tKv/10*#\sm'g?4km+0,xh #ȬYBWJC䙅Z0YpteA%>}"?32YT, ,hvѳ;UsPj49;F׈d[m_"+{ sd^Ⱦ fVfCOعT$B; ȅs)Dw9<%063Ų5>U%c)sKdilցmWՍgYE64~+A)6&!<Br6т- 9\bx˪ tTӷ5|IL01h uv>G%63VXnH28cm H21wv'Z9PIMo?9w#)&*֝6XP/|G֢qGX,|Ճ!J+$ $%kmqIDF,]?W5˕eEޞq 5'wg*4/&zIi ]%5],Fe SG)̔aɣ-C?F#:0zLOr(]{y|{hxubcE{GgU8r.B ^(0$Z,y(}桘TlH15OI P\[Rِl#[lg'NMDY12w9`UE]W2Qd7 "Ob걂&1r!vEpS7c` %&I& /,*㌡4E5 H5No|}`A 3N4UWp5P%@+ VxlgEd㊭1m nځ-+Jh0PMOic#8r:bu6c2|&HZ%J&XU`%@+2}e=Dgβɤ,p޾mc 9p/ eѲn _apd5sm-$OsC}mF?d3'fM4)RSM7ztNޚXf(ݣ+X``[eP~Ҁ~ "x'{_s? >!?]mRLC6{{><<&Ǐڳ`*W57"^*SG/Lu<~^~Q|Qt^{Am;*l.;Cjeq}KHħ>[>E̼U֖Youk2Ynn3RZG8CϙRkKv' YzPIl()uLnHnFp(d5թ`5tVۉz3Rg[iqTV H!,YF "K6/@JbD@IDȖOcܰ-()zhcȳ7=FcyGhc=E14:66: H^ eo5E71~6Z8MSx 6QA/5wb򻖢7'=8sٗװ;`dl0Ot'c?UlYsx9[***h%N$c0Rjz)5Jõ8@t/?5,adN8ڡHC+ o=ڇbtNQ 6Bġ]H=-SGsXXa`lek_?B䈴 LyÒ5>,?8; il=ub|9 Jw$T)f]}y\GƏ3F$8;a.@> n6;=wͮ|'b~σHJ CX|'O l0.zI>t.7wCt)RE"4z(Z%xދq/硐>co0 ҴFjb0)K Yp۠ Xv,V(fjQۇCi4 9j ˿d_oOZd},a6c[X[(bbFl~6q"i2U{w>A Op 3RA獎 uB\RXHm0*j<۷.܎YIYh؝?n_H0%b*h,U{ؒ}%+$뉴6hh5J+E84sǐύ#?p` A}J)֌HnRJD 'U܀+:b*V^; E5AtOǵޚъeoDi嵈oT׉HD2yı8X]W#Z{K578㑯%, plZ1OlXp{ 3O| əhb'iC=d)=ނyu?[=ζgSͮ)irZ 䠷ɸôO&s1'~ދ2IgWƏ:I͑'A6 tK/ YgT¨7):C^vL@EƋ4ՋC;ӹq ~Ъ>#9 ^rgC`c^9 MDpu#D!} @;40jd_ @lUB*QX#vX;nShy#OHhT1|o(s<{&|!t>M\M'CP{]kHā &_~#_8uT/U!Eڝhv2pbj{>8#aֻ1>ܶ+ 9{@1B5MSTa UyYtO5mj q7݅CϤ8vp?:{rU67gh(I߿}xas1Xh& 8pv>5+JV݀W{nR~p3NfȄ5ZDe{!6rw:~QiJ\3mlq:>͐Np )K})h`^=.mӿ e Էres|RY0ŠY\CڨZVP7w3C%i`L杼1Oiܔ={`CaY@{tsa؂h́e KwY]oʒ}h[mJ%no +g*W$e&ysoA`q4SSz _cE^K y7^0ZT6wpom5f{~'OV h~$YäoɎ~a_TdxRj4 aSi *|ɾ%\ NB B On׶^ ۶m @-2V\E-V[FKx8}iU͹RǶ>؍ laYWMY~HOhvdAڻ+.Z,[aBޜRQ0x/# >{Bl[cצXu' HQAXWƇ7aY 7qU۴ ~%Z J?~&l+%lsZ,x=H> 6n~Sعw_3ۮAr* b:e1DrB)ݻjè]~|_qE9=ߣW$L01=HZԏcvyuzDljz|~,+C[iسAq8!4cy9Vl7IgaOB7w2_E+0SA®u*LH$9*Oi#9{Auw L*:Ïz0Ğ^Bvxu06b#jq iYy9^$)]H`Vσao$* #c 8Kx8yS߃vmFҲ<Ê\1q~$Y,5gs(`0p(f>Y5}SSG=UC+v5t/־@qݳIa=#a MΒ#ƽZu6Y ym>6Pd[k~Ovs;>.=O {Rڮm2w̨9ͺ 2X\4/yμيH;%H& BֆK{<~Iֵmi&rL T#W-$g{} ߴZD,$ >6q6l"8h%=|x{ZZmZ}C-9|nq*&04ص輶[ .&qdž L$8R"cফW`iƴ~aE=ľ.JC.ٶlۈ1^Lw~C r)-kpCA@戯ځ̈́Mϴsb+bn闟̹Խ!R8Bu3/G}LJOk}3QMIS&D늈f$SzI?<{?atV"WefgH1PD2f{7hA3m>ק11Zf4 (s\)k^ T%1g2-zo<2 ocW v2z iZ)ٛ6,錨{/v]s{45a{(Aߞ[DVGtz| ^tZy;d:AȒ}*4@; K9(s2Jߩst8x%Svtq.t:CAf}Y-0̏]G}E߫3Kê<*pSâ#E SZ)]жabɾ.վTPeD5XEߍFh)f\b|D`;?ppL߱ (+<9\bP;6VQ^Q>w)cZRN!jI=\'ǽ[(2y6pf^jV"1Qp޵MwSp -i5C8ciZr{}2T6܌ufJh4gsc 7uTFNeՔ)#RkMkn(1,x\=B,5p%2NP-Dl\0빞ce4Fl©/y >/|4ޱJZ?^5(ZRL1qHX #\@D4JMqҧ!}9X]*i./.jekzM1qha2H:ZD^Rb8LD{RGF#GԸ?!b?jQ!C]o  İ,C^M7z<0$i6=ڙ}؜ ,p]?,[ƼC\{AzțC\ >AosMXMfQ]gK/i:f ACX7> sdۛ#Eމԃ%IAE^_ޞ wGa hXfW7jvN;>h/s{^qim+㔭q¸GKuq%!sM꣉>dB8;V88X0ɓVG8(@6 gC*uf>pcזtju!a?8t΀((ߦ)&'!FLHL6spP^Kq6P\HJ0PXVU lX/L!ـ[7 a!hzRNNJ78>kkQ2i"^wlxуnũs*T/7$[WGhfhvIȝ2m#w$$?^@eӻ/~ y'Fj :DK3gGlG,$*0k%gZ=$*T:aQ`?-p-H@5ZP%WZUƱ̨)$nT mg*b`* "iOsý1R(]iXxG`A obˊ%Rkad9bp՘bTs}6U@en> EQY*w-a~4CKFlY?AdƮXI":F5 D7"_H;eA?;H=w J-R1ꎆP<(@t9\[ J5v*rCf Dwqpv p,*SFfß[8e/|7jށ昡x!.{bQR>:hIPuA=Y̵x=I6|qxeTT)3Ol͇4[w}L z^v,)8TK sh+S^Qۆ:9l8^jyҠT؀Mu)8ޡ1/8׶ xuTt=199{&s_H'>d3҄/(V;d}%hd /e>4Cc^"h~m1e_:)RϜ/@u֢<+(S yMW<{He] ,8qLH3F1>}a{><ٯ<xy9}Y$eH.=]^(vz~:SmcKxg9h"9-S;=RsBp둙M{ "LiBwOu9)E)C! EqnUK~-{.^SYq{^{}(e):jjOg\zI%ʑBd@7{{O}g`aΉ=C¥`ZmM쪆{^@@ tKXjIU)r #C?)::\8T} $\XT6>'gU!8S Mϙ"95!<=o}[Bک WJ,~ʇJq^UG{gB@R5!Q{.{u֨^!U6, p0CqMiyT@ SI#wѫqͣl+{ "/Q/152% ^* ͟kqS+\s WsHʙ6F>aE{+ V Ds7'T,'61?9s֬߄[WP?Ƒ/uQ,APP IWExϽBx.FR38-~פ8I)E_ (E=ʿ1Z~=7zu.a/w}cbhKE{}^<;V/ Jj}q^3wzأkJKK]{Wj`DgK~d_/C$-,X1gcPZc.S]>niY1RvHn*F"|%ݧ^F"!jSitN<{bNׁGEP[5lV_T4B8,/CޜT弨,@QDkWu#lQ ]c 5-#?8zTrȝo= *LËpFg/&p}^FfÛ_i߱fsṃN}K^ Rɞ.kd:m vXd}-ۗHZ-EeXumu7^lb3hڈLZn [o]kX3a! _Z?EUa9\}n[%]AOb~﷐ύ[?'oς哸s\d7ݍ/L)Vܲn&l_Y tOBuHz.ymEG{!]3D GzY /)OIͻO7̞d_?A7){X{=m,mJ,*6q'%T4dQc&ܺqI DNiH<ƿ+=p`}R0ӧtI7!.*^9zcy]Bc&PY}9%>}1￞]K%WChŰϚ>:%"Xyz $ύ+6+84J AP_HdҩݦUF*DRK2 H!=wU”)aB%`QۄhMoϚShyJE72iAmT6܆-@">=GAuQ2W,3.2O!}g2[ᛳ6 )l="Zr"G$9i <^I.!.1D_Ř"%tȗEeLC ]R &f55@-Y̨,,t} L+iqfg'o`'7A]0ȵEVg,;ǾJ$bHVгK&糯K|N:>KuŸE8Hq `Dƕ@&DLZWyθeLA34 )t ԈCUM`@8bIBLɂ{}}os/R=u{] O3@: in($8n7My˂AT@O 㪱u\po`,}8Sxp+2Cm"Ysπ36 LΛn [23$`A2c^1FKEYɕ{vǨ"u7ɳۯB KJYf2'bG!UdmH~dJ{36ߖ8/w3g 7O9;,~ cOiRٯ?Lޛ;bк%skJ ϼŌ0?#*̝?U],2iDR0cf\K.b d7H]nz髩vIyY[|zϼs~dQ}].: td3-3VeIvz*Q.! @S]tPܳXGf/4à->rYQD27%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/000077500000000000000000000000001403012130000143655ustar00rootroot00000000000000CPU-X-4.2.0/data/logos/AMD.png000066400000000000000000000740221403012130000155010ustar00rootroot00000000000000PNG  IHDR9~.igAMA a cHRMz&u0`:pQ<bKGDw)IDATx{lTբ<;Ni)m鋶RjP=s-A_\:3y> pc1Ƙc14B !N-鴴|> Nkg=>KdT]UuͧmoWuR|]WꚳmvU׼^JԨDﻗpQwUͧ\lZnch[k֤ͭs~DZz{gWu{.wVE|WQͣS\~z<ԨTugzKjyz^'*zW5{ ;YU]uߞ+zyWGj9V]޷+U׬jTVǣm.gGL\y}|=%fUbƞ˧D5U]u_[k_s+V{Ojec]Bg۫m~cj'TjkppFɞ'xԾ~ }O+o{riާV)s=F3ƴ=PҚw"oף w?нmO.:me;]Q?S{tOyۓKox`}n&de>o{0 ?{^_҉6kS3ZWή߷a}֎}{6߷amR^:eƕ_LyZ4u'߸B˒}߷aݍyɖx;_;^?x͉^8>qgu9&~jc[6&>qڻϾw=pA[3G-tDD89[[9[[{#͟YM#vv3ui9hm9ަ|ሴm+th];"-Gڢ;[[={?s爴h]pu嗙>D8!ʂݏY 9.~^E(p앿_?C=B>9 \c/pb㯼K]o%p,<{OD8p|\(x /~v>K]>s|.wkts"8w=t3t<|˱;ݵ?Gcu_y9xs=c/1#}.oף6.pKc+7@G ި_uq|` '{}D7^_#QK8{=oIs z9ϽBޤW?>^{;=eԳN Kqg톓3@!2B\CqNs۹iCz!& P/1i!,'{mz f¸6@Ӈ;W! W0iD}&7x Es 'sH<@>8[ x{q{~PBo={rB]7MUo᢯D㟨$&ߡBr_=K}_o7`O7&NOx%s' ZN%B9Օ$fi_m+ :moPbo!}N↞ݤ  n2C>n.|; {<!%I~ o܃#t8{P2CS ?#=9`:gk˩<}Ì۵װM ~Wu7Poz~cm3ߠ@cе7!>{E3_&9}{sߛ|(z< | ^%1Wnu]յB`Jwm; Mm+ ? IM ]48cNƀ^=kAJG(L(y'?G }|P7>'0Kv8k9!I '3|OO籟Xpޯ5PJi+nf*W*ޱ:'x O2t(QOLo_7ք*4t@r *z } #Va&`rx9qo8ZsJpI@⟅I,z.z%;'-޽~pʁp{~P ?CL*g dyG[GZWU$ = .pUB- +:PC U}-15؟?$`aC6?LxseuᮏV7/ $9ǒ;jy>oΉ}u)Jbx'H<:ɹ/ e P O<9xr ԣ Gzc<9xrczO=9϶E: xr'Ǭjc?0t)m]E<9xrcJONkSAl߽FE<9xrc:Osr {tݏ붹$<9xr1'itw}2oךxr'T&!?yXй'O<9xrEm- 'OsHx>߽'O<9xr$W;@9:7x9w"'O<9xr䴫ǝ gl{a՟'Oi=9 W$ՙ1c2E<9xr'T8[[v^'O<9xrg*og~ؕ'O<9xrdrr8|{O<9xrH9F5/w1>ζD> O<9xrړCHGǾH6cGLFƓ'O<9xr̀m*Ѷ]v“'O<9xr̄kuy|'O<9xr/Dkn<9xr' w$\="8'O<9xr arkeƁ;-<:xr'OXߊ:zt'OQ<9ܝ gfڽf/<9xr1'*$Zsc22<9xrI' myv9"Kxr''zrE&z<9xrI'0t=:ڭ/'Oa\Rum*w#ͱ‚ݏO<9xr 'Go+n0EyU'O<9xrdg'+ң'O<9xrœF5/w aU"ey9<9xr*O!`8YqtG}6#Ϳ'O!䰺 `Qu-o[G'O<9c['O<9xrL֣3i3'OΐxrX]J;};yҎ'O<9xrۓqH]o]յ>xqGk)<9xr3hvU*Eo~''OΠ=)Uj}}OXu'O<9xrѓC0u'O<9xr Uѵ?ܲi9 <9xrs\յ\1KKS 6xrޞH:G'77t<9xr߄Nmlip'O<9W_U]@9:Qw;[['Oc;=:ޛ<9xr͓cs/,r'O<9xrrs0IЙspBG禞xrޞBٸЫO8"ͧw'OG'o8"?]=O<9xrƓӮF &dMxt'OEo˽kk-'' =9]`r O<9xrztmysnZ'O<9iaN@:ٶ6 <9xrIO?@RG<9xrIONkմii O<9xrsp+AO<9xr9F5;->@4'O<9&䴫6 MݽO<9xr0 Qt::[['O<9Z-=@0O<9xrѵJZyt:Q-^^lmO<9xrن>zm=|O<9xrLx ]N+<9xrɑۓCW1Ŏ֖'GfO9eMxr#']+K-xr#']յBZsk[?xyٕUWxr#'xzeuG'O<9mh qNTztU[@'Oq=9 W@RVvU<7'O <9ը$N[Iɞ';'О59i_9i=/'OA=9l uHI<9xr1'm`CWQ-wAG<9xr1':fdO<9xr x tfBG'Oxr90h=:E8xL'皐H8XhmN'']s01um''Şs6V97-rнǓ'Oa\Tu_ZhmO<9xrRa**ny|gkxrO`Pu_Y^'O<9xr,6M83<9xrs_it'O<9xr\=:f;Z[~Ɠ'OaTu^Qc֖ol-?[M_"_psgk˷"gE{㛾r;Z[HW!E(#MsYϛ| [+kKgkK5elmi]xK8Ep. k髎=-㽋pϺ+in~}t|@cy{ouy\;[[N#vFoǠ9,n4}%Bϭ}8[W~+B.^7:?#-U|>Gk7p  v{?Ƕty?<8I<9Ryr.DJUrըVWjVuޣȮF.m5V|U]vy\k5w>ah[kjTw<5xk5jG^#W5_y.ϕ{.ѥZeƞOjyP{r%5u}~%fUW>[u츺:Tm+Wת]sƎOI}]QRzر5k~wwzZnY۟E<9xrΨVOk bǓ#'99PW<9xrLr0]HɆ<92xrYB =9xr 9޹ 1'O=9HniWu П'GO!`!O) <9xrLG涇`>a 9@Rɑ͓s @t WɑȓsO@{g^ē#'' |%ɑ*H4OUrF5'G 9xr­|O?oai'Hݓ'GONMDr8C֖3ZWnU2膪knipeBHē#'*m˝-t6>Hf%Y9: Z<9RyrըVB!A5/h]}-kA6B'GOqc*t߾vݱUj.HriWu ^U-?P|ϱxBH <9||*GkOWM|윯 Q9{ra ;(WNo !$$oףxrWu- ´whm9q{rޮG5U<1xr@F54pX]yaUgNEvu<9NG<~֖6nqmr*<9yrQf|gk/` YMlɑΓ*8<7#UoY? v?v@5G"r<9xrT{//q8$!O=9MqGk˩^|ݏWuB<9TZ:zpNmloX]2}N<9ZHGrz%doGG3j99 9;O\j-kJsUwF(p9O]GR<92xrU]@?|EO6T$Oƈ :AF2=Odu=8;98n'r@Fƽ~/ɑƓp￴ʅW_aN)'G*O!%HO|VWt[]'GONJЍtd%5Z䰭H <9gT]oEHd7zrFZ󶢷!ؠODURs@(\+CTIv='a d${ O\5Y Quu 9ܛ{֕[fȃL\m<ƓcpO! y罿gk"8߿yrrv>S57G"ޜ<9Pi;}yx{r) uمOcDGkK{ߤٓCy{rHiWum* spb{TK7{a6٨F<9yrt cx /K<3bǪJ99 H<9RyrH'T]˝o,G姸bOyrdd;]'G*Ot A_pҀr{W1']յjj.{p߼7d4Hcrv>r?<9]5-7 O '*m/œ' m-D8x,aL(xy8=9l 2Rxrޖ;Ӄ0pyrw9r<92zrXB`Fypuk0Gc`OUfCյ_Z4ԭ;_fh=9y|F 9 c#']յ<*.GT߫*R|dt=9xrD5'=897-tDJKz<9Z({W\s3<9ըHmsOٿgk:6zNN''wU]p@*B={rޓc{p7x~ \Q5 ''oך䀔=9xrd䰭=8_y Oi=K߾LauHIKO<9nyHy/'<9#sKQu- 0t:WwœCOHw1 <9J۞wDZ~JjRyr9 }#'UC/.G{ xr <9< $'<9xrEo>=@|'D!4Z5#'0xG˝=2W`VT]L}l`O!*<9xrjփc8Z[' W]xr= ymē#''9qx{-?^L|ÓCOH=ҼOTM >زi>@'R'G:Oί2  wU!|ɑ͓w%cN<9yr9 8[߼i>x#O0WO<9~}nGuuTܥxrB<9XBd}E8yK6sٓ'B@_(Q]֖.kOsrٓö}XJGk/"My,^ <9`ޞ<9xr_iSwN{r9Pt-oMl^5l'O*<9xr8mys:Ι1=<9I{r,li|=9xr$䴫VOZ 8}\!<9P}fQ@ڞ<9RxrؠවSx/?i4V_+˓#E2@'ODjTRqyoyH<6xrɓ#"(Tɑ͓s :!Qm{q=&c%zr9 #xrV \H:sKIo0xrD8xzs _'@۞|e/&sMzr@Jx m#\s|OΠzr9`'O"Nm7k0\<9yr9^(z^\-kx\'o B xrPk!}NTx%W$3ԃ'g<9l\Ot oɑœC@5M#K7OMク 2qO=9L<87x|7L\5)Opxr^7 RoN#{rsD۬snRW6ی33?=<9CaNȆ=ҼO\5٩`iosp zUHLާ6ɑʓ+:iX&kr]xr<99`|ptL<^ē#']յیƬ1mO-=9_,So,kem[zwzF;V{j|?lzE8_*Tᝇ^'O|^ksTpk>bgOߜWjFz7ߜ?J^ CU|dz'Px7>}?|o.'u3o޺k X:?Cw}uBg/rozŲI)k_[,rף97㹳X䓿M zfoU裭uKxraN0AO=9"8-3"<#"<'s"8ɎJ(xۿ;sF=nzˆ~~%;)D77d?`p=)$o 'ŢL/sBS=R #.B+<9䴕s) O  hȲ9LMj% 'VLtPٓrϒĄIF{UלӷfdXo<9FMn r<9Rzr>N 0ZN;cHk?&ţ&݋-t~߆jTȵӷ{wVƓp`N<9ti'K}'~|P@rsΩI6HHzGg_>Nj)t 0'O>L֎<wszu%{_W`3z8ugXD}&;H"D&s[Mg>o类~dKxrR9`<9zr67a %>$|1禐_ t?>`ZPo2%SIEDD.dV%2糄}zc>Z]-I'猪k)Axr$$3@ =2G+_R!70>f) #~SkLۓ//Ǔ3L`99xrIKO%<3(C :g'$rc O5t`coڢNc݅xr. 2뉭“'OK8x~3kj\K2Oߚ1GǪ+<9xr zr#'i>Tmܐ~ :϶MlW'}N<9xrX}.Hk'D5;xtɁ4'O4k6d Wyw:v%I֓CO$'G*O-twjVuͩLb٧oMܥGON_! W'G O-tb;mV 7룭;VE<9IjTR{@ڋ O<9rxr3cm.ZsG['xrr@Z~O<92xrᦓ%{xΏ^;E.stW'K8x~߆ CTtZ^]$9`'O{r~7pw~k<S'ǨK8x>gh[!-6ޮ~''n'zrc ONRumi"WݹԻcտ\<%'P[Dm^zzGǹHxw*ONOу&“'OQ<9ƾ95JN}jotYBknjrcO-tjLۓ~PËms-e#v<-icO5trTG딲+ײOC CWxr`<9xrړc /N޿qkL06ˏdXyM=H%ާ_Ǔ'ON=9>f5VFd;X_O@{r*O%t^Dkd/ӳ֣'@'OxrᦳmxHaC}yGοГsFյzjr3[wݬmED?7Է㑯E(x1<9T]s W'gX<9Hs}PJZ!izt\o};Ol!O<9ɱENԾ>O Y"'@*<9xr ''6g5spɿaSK;V}v5pA<9xr 'xwB'O<9C)Gѝ ;ԯ=Op'g<9pܝ76YYiuLvfoW7'0YO<9xr͓c4:y3+U]+Ǵ!ǾΆ;V}%BK&ГR_m'OA"MgbCW> M|+\4'0p<9xrOr;OFie%费~SёÙs<9xr 'i:[~s!-L[K\V~.Bxr 1\'OA䜙EiaҶ]Vc;V1'f'O5{rB%{XpjZ#;V}wer9=90A'Oεq8Su5VBjGwNXHiO<9xrɱN> &%Y=Ӝ]Ozr'i:Q^T?olW'O~yrlO=FېA_A7xrR5\'O·-^Tv$Qmーn:-xr9`'O<9H}p=:QfgWxrm O<9xrᦓS}vŃ5}G |sey=9j0''ę7`\ЕHxgzvU9c yO<9xrp`c;qN}U iO<9xrz` 7.kZ!- rбxWȓCS'9ENx JTs*0 :9W0b#ГӮm^WT}U<9xr\mi>5euyh-`cyrYJs}z+<9xr-|jgPuGKt\>}kш>3'縪knr7}U<9xrt Eh%`Wf<~EbO!d9>:<9xrxpxMyi! Erѽߜٮ@Ɋ'O?-i>Պh m]c 7bOq5ʄ{BƓ''=9f[O$ :eȷÿ-/zOGdh:^cC;Vc"8 v5pA<9xrēc4KY~9}{✝|9 B K8xaRhd:6ۗرۡp=9xrۓc OstKwC!ݞ'ǤV \`6ܪbUH'Oyrl3{0oб;v>w蚏$踖 7\ zrU]肬<9"g#UqC4ط#9F5/G'$kܔըVm.pHGn-ö`'O <9p/nPu@,pӏiWu# #'q¦=+{ǪɁ4'G^O^U[M@:^Omœ'GVO-tv{/%' y'K8x_z+`ztJ&߸OAO<9X#M'n<\tʦl%l%<9`<9xr ɱE'Q5+W+{[Mzrlf9xr̓c4F yq{k/vvUmG9xr̓c4Fpisy9KT!Oxrl=ݨma :m>i:p!c(O5tn{/> eWާytx &9xrc /U#@ US}v%oUo+爀cO%<56:i>x <9xrRɉmՀ'Oa"};٠Z.W# fwd샛6\2%w'Шꚓ0A'z[ky=UVﶼj *ըV{mpZ狽h[}ǫz[ke?ժѶ=߳]Z~U]+TuNvmyy{>^9ZT]Sumx.%+Qڮm؞sNwNNa!V!nmivvvy^^^nJBccc8.q?SWWGoNqPz뭷r\] W9/8t:9r'ZV(LiHgvUUޜ4 9AS:nY.; ʯDYY~!(6-ˏWfsuuu%g4B"ঈꌌ] PzsByyyn{(>b3~* qF.\B-++[Gc1L@!T. ![,sssB,}衇 Mĉ999{ĉ8ir.[,[:=zr(ɔB 6eee2e!iUG^˙MtJJJ6sgΜB1FQ 2Z֓9r:Nyy9 /-r(Cf]v8ߏ5qUUh H}} a W YTWW9rnNFuuuYff7ʐ9جY0Vu0ɲފf;(vZB_+++7tް 9Xy|Yb&NXyTKk7Msb)//߀SQQb PWf}=~쓕bJKKWp8~Xd cirbAtFF{p$8J*F=Ϟ;SV$(lҨ]_Mo!Gt rbCIYNFFƿ***UUŜ<ϰөr>\B\fVnB! B%|O;vaa~1bا#vj!Krٲet'a5YYY_ s,L PRAgմ.C(UߧcEN!!koX]/Ltr((FJWs)gƏ?Z@RfggJb=8f 9CL$C4T_qvwJ!Kǎ(4o\oLȡm/]wZEQ &ӦMeΤss?!'N9]UUD`UU_VՌtBŐ_*++tDM8*EWTT6rD222d*⮪zj25Oȡ9]YYхVeXSeŜ9sJr…ut25&8{tu>\~O/o6( BN>{{I!ď& 9_שpmLbZzRQ|j!'^>|*3˗Wycr(l93Ю[̙3Q;9 οMHKKKYvv r(2,Y0?j|ov3jO,˵N]j겲Ň'%KrIٳgX,vBMܙ 9 ?~YUUuzxU[[[ȭ& jjjӤKz@iȑ{%>q)o (vWRrrb@UU9sr%7pB!֬=ms QL6-&$~BUU6i$5t.USSfL뜐#a3glt{2330kZ5̚5k@7gܸqϩjrEf5!$!gp;wn 7`vvv\LbZOU"Efܸqb?3 EEEOm53eʔB 7G!$Q.y4E>`!'BNװSRRBTyyBn=1~t~Lx_o]wu "//ϰVWW[}>Q!']CN'sΝ_rrrʲr!(++[*pHUUzs9I6mڃFFVU>bĈuBN=Gnv_tFNQɌ=-#~s:?=)ΈjJ!Μ8q⃊BAzC!tg_ Il㎒L4nۈ'tnVZZZҠbvv[Farix~q8 pǏ0r9}2vزEF1cƄcr03ƍ[$sέtur:9ӟ'33w]ʓv_8BN_VtAp0a¢~gVVQ#ϧMU0WVVnaIֲ\z3rȽK,)K YdIYFFg"r9 :d:xw.X, xR.j7nlbȥ}nrw߰w}%yyy{ 8BNP]UUb6Iךiw¼^g9\#EnNVse9 :>o0~9r!3k5vصBșEIScccg#dggq AvsEQr3kD| pr9ڣ㬫{Bs2=nּF6gX.5{Յ.[=OHZ'fΜ|(7~9rBoB!Yb3//oLA-EQnĀc2e2r9Ct,jZn/((h2c #X,_6m36QӐHG:=!spɒ%Eq333';8BQZZ,+Ƿׂ\\\\" ˪ԓ8q-¸s Z.{Bε tn˜OB!4y ?leZϖS cPp 7$Kb٠RAA桜@JI{ٲey9w_aAAN!3UST"BaNqqK.BKykCCC¨)##㨪4 rbœ333l'a殻,BNpw!ڍ|mZrnPPP`XZ&]X,grr6Q\z3:1!Nddd|ck__#݁1cT1ϐuҤIs3OAWY,YYYsx1pz>SSS8MqCN'o V\,'|>CB!' !3>Ted!?? 0ҽwqG:&(+**"tY*^XXF?!!C1X~Gp̘1uè&Lx|>aN4ia\ 90lFk8뢢TUWP'r ͶHbbnn 6edd|_UUU2a„F=.B˥%rb !>Os-EQI!Vgdd}O<㆜z#/Ν|0lKuuu5!G#nN4 9DŽZ)I!rO0~^e|o7|AAFB|!GQM7ݴ ##t 8N3gοF!r9Ltш#ZhQa*Qvv,a.;&NXckܔ!3D/Bp9sk熐CI7E)t8_r@VVrƠS*3gN:ju~ܸqk9Nc_TNx u#?B!'M9*9'??өpܓ1cƬ^NzuEQ̺qCxFABff:!5a!rpeXtAͫZpxpMVxjk!Gΐkr v0\(((أj ur9r].O?v3UUU=h$x5 _ؤYE :_.p-r9rx<^1ߴOz뭆L;cƌzaཇ,r3&!Duu,v fp9B!')*!ȑ#7zq3zCdvr9B1{{vBc.//:!!VTWWϰg!'9~tֹKbVTTV(Cӧ/q8FMkӗ\J*B!]e`#wgff~2bM曽.#WQF=17BXбlDžMS.QeHzb 9B!7j#h9r:a ǥ[\ ¸s.nB]irbΜ9{<+85C9C!L:u!Լy󼹹b4it#׶ 8i w!//L9ir{-ׄW\]5j6mڴ!0CI7' Eɓ0O8?(Ckޜ fٝPF,Cj5<=iҤsjgX8bNN A rC5L)+++q\ml6ۗ~?O VwFxgnBiB9sVhC?!r9鄢(&Ɲt푩ƞ vfܸqrrbAgf3fϘ1an 9VzrFF/eeey(zplN͖}%v+WKo7&o3fLPؾmۏO嬬)=Hͫ56VdVVVK49srr=0AbnniӦl!.̙3^q!ܹsS)..^# CINja555E{n\kjj*nZUUYz $u,PGwiĈ?r9@ccerf@͵lF}#lZ-//˱5gȉZ:q!d#|VB!'Xti0A te0?!X!y9bx177w?!Ǵ=9B!Ojrrj+ 9t~XYm6qK&{1erByCAѱZ'2fB٩fgg ?=);P0ΥaE 9& 91YYY{tiijEQFpB٩)}&YN^Yi}2 LxUUk 99bѢE5>k:3335!hC13}>&ap˱Q͛7ϕ5o޼*QRT 4@΁#Fx…\@!䘙cu~%ͳ n8r}{7rr"O#F뮻 ⑐C1s/NNNf!4&MZ QR4Yp%!!G!***Ǿux㍆$rJEEEQb%eM?č"[.//ϓ'\[(O4IB㳜-[5!rLȑ#Hҋs\%7rJ߾cN2e71SLY)\-B!njTWWOBYYYjJKKI|cP.{;].)IƎ;!'֘:UU*UwUU|B!l/Qĥ1cIUwd ͎x<E1zo!9S2mڴz:S\\nU!@bb+**fr9B!g{VݣFzC:_:o޼|7nJ{sjjjr9B!gx]wFxBMMMj6䬨x@02p8lٲ|B!C! f!ٮ㇚ :haSX΍3f!C!rniF5%jIp |nWuBr9`…Snײ#Neee!$Y_O1VGr9B!gh? d%U^)ٌW;IS r9BSXXv)ap8~LM/NQQ&MviӦM%r9BΠWѣ7!~1!.|~~r8MyyyaB!C!\;7 W>Ǐ_hѢY647g ,#r9B΀Íu޼y3<8W}MY/Bo)\F6k$!#_۪A{}yJdlP zcvB>}B2_/ת؋32lyyB!Cnannn^!Y\Sv@kjj\^}(CٛEHB!hZQQ1777wb9iNKVw);w}-B_SҤ7B!;wnyUUJ{f&kZO| S~{nn?Pz/FO>>B!CIS[[[UTT0ǜ ~ߕʱJ/e~Jf/EEE+ v__O!r9rTU744\ fzH'##X{my<Ͽ&MT0eʔ{|KW >ok0LrrBr9]\?WQ"([\v{xĈ_ޯY{lo\nnoVV~睫OS7՛scƌL!r9rLа`KUUUbCגӚQVk-biH][[0.r ijn9or9BŔ_S~qF@{*24P>osccpn@B!_{5kjjn5;vl^ffc7tp^8 r(ɷѧ^sO/朜QGK{466Z VJp];v샄B!C1ThZO;Fc;bv3cǎfw0YtlgnÓ&Mr9Bf#Fe_c-((P v第5-pǞyR36&36Ñh$MDD$MFύU+RZ!S:g!$JʘL3RH!\9g|_"3`rj\gLJ)xtw]xwtww4͕B&!Dd2 pccc8OܴDlۆR]-zݟ,sŖ_{ur4nՊm L.xW:0JU({/&Jc1(@J#X3mqBw:9 $@  DJHiċ 8@'R@HY)YJIQE! RcC}ް~b!K&]]][,o*JM !u{B<BN7~_3vR2 Mur9Y V,_~=mߵwS0U~oxƚImez0t/޹DJ+!zApA (RT Lt_DV+y5(EMb-PJ'bH$yRxKޮ_{GFEa[鱱cPa!^.[\U"çD|p7!Ϫ`c 1pFK kZU,˂0L=.Dq яƧpE^;6:v|ۦx;vlO-4~Y ]S-]LU5Z)wv{>ջPJuݖΞֶP @B$@ͧ8!jHPx!*!Hi! xH)&=̈$ -7Z[tHpIz;ָ"p8wBкaT\.X0?.E8D"s^N!( cVpRJ(RbֵٔyK˖….`AQG%cw/u|qϥgּc{ns!׿^JR۵b!oX,]]pFjO;QA**BQBWx!bimzY}BO\pEBc' } $Å h ޫu=aer@!cO_LzX1?Vw]H$|>j0)eL&%j78`0fphP1 ׽2Jc5u9,ۂk;`*(U*ǒa/3} g!!7r;{ܾu1ˍ_Dt=l5hIUjۖӫ\~ꄨ`ܸI/y=ɦu1ik!5oẈi hHBBG^(s.??7Ù,^/gٖT*US8p]BPJ_M9c RJeNjdr@.+RJ-*aT&)BBRPJ2r+JsNϛL&=Jzl>JխҩN^EQu+ֻo=՘;xeËڶmyBQEeLQTJ)g͚=E_Dm]=soy]5BH=SKSQ#' Z u• )g0 Rr8hUU) :G)ԼoPP)ǁ6g8)<60LZs㣃/oX;6I$IvmH4 ѶmPJ;d=i; UU. ;=7nZ[{%RCG=E-#.Xy9aT]p酶a8;~y'7;)R @ !TU"xB4]!.ҫ1U vϞd܅$`LziTH B$lӨJBԶP0Jw=;oBz!!#NkϞ3oe^"!U EÔP/c\& @q`B6 vxs&X{! f?ܘ3Jm&W^yEoPp]@s@ BHTUytuum޺u'>m{2SJáp4|eW|dQMȁ]ϾLJH$̝1E`;>OK!5.8BzµeeR!\N1#\6=)Q*uj2F߿spϖ+V^rFeVWzbXRJOF±kD0 Ԁt,9B65^ARv{8o+0IRz/0p4 u]hvH)i* "Hvpp;w\v<b,^&|{ nߡ[O=)(J)c …VtttΕRE";w 7a(g3 ;8]^Y߃RQTDpױ,8Hif`wʳFIEUuUQu~ 7+Ku]0p=!i1&!`x~BQ:m k,8L#~+_sO=rr-䪫t,ZR`ΕLt'!i|B_{?v3`(Yuett,\xko Jغ~K?c}/= H5MQƘdيK-1ELzM;gbvm(#RHryɁ{wB6ضeTx._K65D&۶n^~B45w>'i`p]R!T8g-y] @%\)`(fF|g^~:·~?J{ӥjR~a#X,H[K=KW{ "\پ-/ox~x.N-`0tste/n=\lfll&=@㸎pk~YB`Xl%\v-W]{[;{UM#L v8\ ]YŹj"DBr0°ᙇ~7OK[&ͻlժUOs@Ӧbi}`׮]wߊݳf/λ?1{UT{"4pd^x|GCȼy;̞3gm#+V|mȠe3B>ϲݣvÛK/% -蚛u` \؂@@a vIPpH"!@бK/{-O /d2]~L((p٣G|+CJ)gϝw޹/ko_tj=R%$*bqu=C?<|pE-B@NN51$I(N8VK.K F≦9s$ȍ/nÁBw]a6z ')%цګB BVL3ֈׯ LQiơJ SwƗzeKO55ڶmkozEI FcQ(HJ\&oü*`!Mx[7 ]b.B$zد)U*^x\= mɦTUxuKe*޿嗟|o2ᡁQvO*"' Q*@ @8LJ!\Q$4Lj4MTcд5 R "kXe"8^Z WV%QG2J Hwxe!~:AƲlr#gݏz*斎EK]-a].?ImR ptoz&X]Ӵ+TU>{gg/˲*㜟7cM_EУM1t"h:=O>t`זM[^zLz|\p-^D)4x$H"w: /J88e0 ҞDzv.UրFh L<VQ8 @@8RC_'Iox5]W/;n uo ,ǙaxR`PC<GLZZZzKҲSsbgd!Uz%YwL: ‘Ξٔ1ee펮TQ :+Y|o7m|CuMz^TUz{{ߗdB~SHkF }RJT).$(#p]!'t{PH!Z 4~B0V7SJq! =q@s ~B֯{᭯n|јV&• z5"ԚDN@zNA) ! 0@0{K$\N~\kBjx.3 S-->4(T CaR± <}㱟G> xLӼֶmzT`29XU!u2IK ] `  :}z($86ˍx>&RJ麎S,rYWH8(BBHV2~.7NPN\ꅠo0[,ˊNaR EQPV9G,ms㹳&~q.p_s4759QQ0XFظ~{_;JR=)4EQDZZZZ:WX?8 DT:LZP"LBӴz4e/IS!}8u`*˓YR" AQ Iu%~̶m~ Mo~TP p.A {#n $$a(J$뀻I(J~id:Dkۮi ÀZT0M37'cLUTm\q[5sP*ZܨTD~tdO?s/j|=`0VUUw]׎FI(===BЊ^KU!˲E"~s&r>JRvHEQܱ>TUU9GTB[[ۀLTLQ$6~PJEiWR$ à ۶m=hEkBhEռD9 ܻkob28N])m`880 @ \(j0wv|{~6kE/,ӱRO?<:|W|LJ)=̎;6f2?RjuoP8V*޴4ڵkL&O5mK9G0{MzJ2F!stuuپGfiV7oxK_N lk*gJjzP)sOlϮe`޾ʶtCcrWRiwtvϺ+owV0utʗsUyy?}՗T̤{ ØTY\.sdZ4/os"Hzpppӛιd3 p݄ϗ{_{ӭnilLpz,#*9 \*KؐoI2q/j4Wom1J224='W~s_lOF/GPR }|pp>{vV=I9G.D" GGGΘqkL8mk璜/9m?}__dőÖ(cu볰|\;!;7oxn  L\׽¦&3 r|>0T?gU^p@kg|2( ẐQLzxdmm+>ɚ:hx s0FFGG1cL{ldm[.%5'o3!5=Y9pretd(y&T;L|]dnc~DʙLuɦTK(^sk.B xeC~g|^|DDgg4ٗIa:ϝQFOZ5,s$po4(஋x6c+Od0Y|{\ם3뀪PUp)p$[jUBѦyK.E"[B! 01z|yc˫/2ξ577/r7jG|f˟CĶ JwTƛqQp]ڼ''hq.d2x%@"ipmLujZW\}ݻ;]暖^BegH$i29\KgMb &XEKwg^ 0m0dv8(#!kQ|>۠X0g(c8uU7h4%%ҐҪITU RJ8W<͡(ut__߶!!@&9p (vv,Ha6 BHt||u};L^h̙TAґL)sYTf2鑑eM @K.3U*UU5ҸBUՈa-[<4p ϟYaƚ.XlǨ] } èX5$QO^CQT`B,YzaθPD߁=ۿo8EyT**J)4M;_BNg#U{4l)@WApבX$P(̎?_xʪa_I4`ddz89=S=}?`t]NJ+zСCe˖᜻2]?7[y cŊ~ӟ^o޷o_5IwrJgyO Bv +9% $WNT*pW1L&ǻ gBm? /V:;k֬뺟eY`A4!@P9s &ݿuر[j5&ٓ7o#۶m{@LZZZ .ɜTE@`&4ˈ066oڊB 50fK@T]%HOց6cI4ׯ{䴜֖jtf%52GR#'J Br !]uLgۦ};=" BeKTUc r?_V*{yzB 0Z @<clN> iy(n6%@w~N:BH[[Ry$ 74455ÇgO]15}X,;::͜g|eCt#BX,v]2]MR44ErT圻Pyߗx\GժF)E"bbRB" ݅gH&XM' B`UF(C[{;VB(c}>{uϞ)>o`B)Dbi_#cj|myhI)  :XB"Mgݽ|*I,[|ݱ-):**(I'1k"(EA2D ؘ>gΜONEQ]M*:O_hRX,"d)qeP( H #Np8r9n+nB9Uqw7oe-,Ǚv=i]ch4 08λΝ>Y\^!1~ONEA6kY֔|PJg mHd~?򭭭d2$)kBSa͌bK?{`S< T&)܌H$rړ/+ffw]{)\n$qy,s˲vRL42IOCU*n)%AIӴz뺈F`x$LUUU(NVyE~ ٟh\.tkzEQ@ 5N[FDJ)cx<>u@ 4[m^&PQE---۷O"u;2}/ؿWJ)L=vI<Ρ:@6s(p$Jق0\ PQK TR"՜B"GqkDJp?voߺ~ &XT*-D"ud=&Z#tΚ ))(c@%;rh7f+?e+]۾UWɄB@Qֆ|3ꫧo}[~hT#'3_UUp8<0IzPBH$zرF/o{,K/3J[\ny!ǁQ"c,x{K&pX,ɼ4|04 Gg:tGСCgeLoՆacgJUXZ=i#6W\hFPUe׉,@Rʢ8rW" ?cJ @ DJXB1&R: m¬Z` LSQ6oܵ}닣#ǏN455u&ɦr|xr;pHͭ5iϤs?ϯWEѓR9i:N1pxs\ B) 477# $z;xN:ZZZH)WdiH$Hc.c||Pu^qT*;MFcEaبKr*O?Db&Gա]h4N)q:ex<4mhB8r8!|UT*SRWEmoooS@Ӵ:7Ԡk,OKFqƽA"lE+/Fgg 0O# u6 "lP)ؖkwyƘq!?u}a}1X6tw"mwEMOt7g1WQ ƳY$j?.%Ǻ1iW__JpݣR{v\~h60ٍrGTbqZ5&^x>=l6Nh.flSJh\nжmsH$ru\m|8:u !qw6ϝ0 蘳W\3ZRm. 1!]茢R,BJ q! '鷞{ `&BЬL&p8\'N &'gpypBHIJ! 4mT?~|gVT-w%+*0M 0 Ri鯽!?/`Sv?65\OE杈Sєhc*6<}7:v=5EQ K|F"x<~ilZ J)yRmFy 6F[|ۨdz}}}Y`mdaC#_7ba;0zzz/^xJ2ZjιOxLI~8 `TΝ{;~Cv$N:ikkk,Km0W* ޡZ'xJ͊\iZ^]@EJ(6[a hLc@al$ 9o`JBe~9/33' T>z#[a >tpk;i Tu`mmtvvN* 9Qz0k&  ,lXi&Lt]G  S ^!@0eY ĝ?~ZD"8Z3y'< BnRiS+Wz…_>vu~M,љ4˲YkB JYǏM,rͧ"l9bT*NTR! 577(Z4M_[& 3W*^-݄ JBW$ZZ 9J4+';^y{7 4\0NkϏ?OwP " J\ׁm[hn#_:$5u,KtO ( yuO_>X/dbcj?,- /ZUj8[EiV۠u]Ml٩^!B0xm暦3iRH$RNcjO ̛79sk6'7A?7ƬeYOv?MH$v=ҰiYlvRRR 0@):0Ʀis^Quj [6 %4Ux.wD+V|PL) TMP5RpIJ"1 Bpk%F4 HGJRgA(j<%pS{,1pCR T0 MG4SHG.JxRx/~QuOu tݺu, ~({Z0 ߿qC% EC!?~kW0PJ7<<tX,2kV,bqzhK"įj K)7 #R . <}0 TUzd_5>J~iu21=Ny.=%`~c, (pA<;phą42' FRZxyUBg\@zB{o~?rdaճ5̛; k/ʚ=bضj:%@ Нg1MAUUeX4MkH$ވO*B:wL&K۶mmu}UTb~yumxT*q'O/!vٿK,0|Fnƶm\~cm(>Ri=700e ÀRxe(S$RƷJIjpMٷ}צ:xp?&]=. i.N?z񋭲,ܹi-Bdϒ7+Jw]~ᙦiP(14aYփRi_CL |>GHS& EAaѡ3R;BW_ڽmfcbu0!EQԶMPZ (SlL1ْR;'[ZZd2z"lۖ>ȧ2n&5BJVU9X22ϯ1{V#G3ommmS8$DcJ[[%j^`NOsm^d۶_WoǙ6jL#6l{!REj543qA/) |c)j@ g%ᠩE  L >PTZm7j*LǁMM-zu%T)vmyo6SJlI,O~?+h+D.(,EKfZ}0iYK L̿p*ڹe˖Sz@gϾ0 FPIB ᢟ߷m bǚ/U'Ztww_;ʥ"(AB&ᵚAw o kFGG Q  Da#ñm0H0J ]R1W<+C96lizgWܻ?߻|Ba\#!l4e7mR)_MMMBnfczG>j|Ќ1ettxuJ5lT?7w~驺6SLD"nYl~dz"~VRn{]k޵ʫmrxHEG_au B:L;5M<}{ҽH!s]K)|T]Js $5-J-)̍zj\NsU*n음8D"vXFAS؍52[ %h@R1#J{X)7ծ冦xSQaY;U֪m1 c8J\.7RB)XE0k"Y샊0A,{~H?h4jY$i8^+wBQ,D"ɮ4]fX{OK*Z;#G !xyاM7}[n uKK#s#CO?|e$~o`AR@UT8vA HI4&eY:w%YdHR}07՝$А<^NMZӴPggedmv?X,fN{`0&ɐʦ,˂6Z|Y,&7i!s='$obFhLYBkZ1t:,ˈD"蔳 ,XK(Ta+aUJԚ!.g$p%WW~폮V tfՄR(DnCEKk+2oݼyúgo+/=V~`B)c磟 DSK P(i*rF P0i|# 򑑑9S*anooq]7XșBmb|?vLNŬ(%gZc->8)_F]=mc… #h=I;υB!Ͳ,䝚vjT=X, !~8W6f t]/e١i LODzA EWwOwl= 2LϋB >RH !%xgm[^}o6(^r5 t90h t!lm!plP">Gb:ҍi˧``CUU0eq57-_\ӴzttNOfCm6IR\Nl,#4NR,^]CCC9]"DiYq ~__B___+FR4>;E7NL4Mf1+ꪇl6^ !! #L6{A$@] Ea.еFi!@W;BGJ UQvmbSMf[lWp? (jZFqAB5>M ]SVsET\.Fͯ/pEAX\Ҳ&.錺ȊbR|ѓ[xse<́(; Øz*P(|Sy&ad èfP(? j,?00pڎRdሯ2{W"q7K?hfB~SigT\MӐF_M&xyƘ駑x0~׬H '!4UETjRAJ &0zz 0:E0x.ܻƯ]a0JJB&35Gc>z@@e(Mڐ72OiP(DBg2#K.YJhxIkpDTD4Sʕ 40ĉ5q^UA0~?:nB`´,8O5Η ^i)ϝ#P>TdY=ɸ ~Udss{N  }iΜ9{ȑO eYN̎ťRzu$T!\tEd2dQ0zTZkkjunt<YBnifkOy=a m:SQa.xG?>o޼͚5D"14c,ӅR'b+BhkkÇp߾}nfͺs^!puC5(d޽Չh 7nҥKGVX^MX7hD8H$#ԦYp.lڿwړ`T;ީ7(v+\Դ Ơ*@rxmWtljB(b"DzvK-_[t%WD-4PqCOJ)v=ly%D4"lӌs|44Ϟ|?{3`DU6&00 !cL圻R&uPJTqu)| UUCsl&վR ۶H oۅB._q2rLM6J.a bJשmd2^`uBP88M)edri))+GMR+GϐyGٵVAH}$\mKX:s٣z Wt, 5:1 ( @ DS"Ӫ|_upϖgŒIg@h>rCm.`z.hɅ]Ɠy؎BH( ATH4r ӭh{{ܻw1&0SR=ފ7o[ZZ!.yF=թNX<ѴhtΏY.Jئ FOBHFe/= ;z $ So듿6LWiW( eQ (TUayL;ClF\088̖?gmiiYlYV'8'pӴ~öAيp{?>D`I=}˪B S=~{[d+>۟R-%7ߗ'~1*44nyU7d >\.]3ep8L)]m6g3ig@!`0%Bjfvo(tͥW[p9a*W@ cZ#0 P"-iZ\nw~oG0T{\IIR*A\E&&$ Mcqsd2L&36>{ny,rg/F1 H山o=+W:^( 7okj<[5{ />'-i^i-@B%~pࣃGڱuB9s$e5|vQJpS;e e! 2 ¦ԨE)pJwެRuCI>L^ |Vud:ԞJ,Jc;wnnƍw 8;f]xњkny{?6gxS0` B TKsoض_T`(>5k|(5 v x J%M)ND9S`VTT1Ne*܌M/ikk~bZN9N۶H$J}}}o}^fvTݽ{c*sG7q/Yd)q85IPdrYsY$"hm޳ݿk&+VVRJa mSCJ@$Z!SpT@NӹPT\mmst=p iEJE+E%&SS~u]Rtvŋ)PR{Q>OBŋoë՞PFQe|||޽{D,m, ue]zsPJݑ84!\]p @ : +ccc8peXl+/]-V~@< ?Rj ?g]_Y|@u;D V~#A @ -ATUa( MWРl4(M!!`Fո[n'ۢIQ cL,iھ},6za㌙SRz#*9w@))eWX/)0 jFj#UImz_~W^ykBT `ڶm J)S,sؘwݔHUUZ bL$RB\N__߶yXߪ+ġqEQB!YT㺌Rtuu}8J1@XKK? 34pCAI`imo]{㠹#oǀLBƅiQBp]!/5M7p⢋.O4Xa1ƫ*a5Kb //?ݻww:2'g%uuu-S.!Q.GNU]K)esν9/w]sG>dǷmiiWE"AblݺH]#NT*E٪uoz.1njJXRdSTb2mCpǻ?q+Ŗgx'A,ǭ7\N8zi!t-۲,SaLuL8UՎd2M]x<[oU{/֯_ui XDz.\xO.[fΝ{GU\ő#G(2Lmd2}qQTZDUBT:kĹ"8RJO5|Ի zb Qē1\ @ 50pil` p#JA!^Ub+R\Y1y6 J)YZUAPsYJ>}JZJ)Es.oH$˗o#Gf*b388OQL=CQǟǗxXp!bX?tP3R* è&jGr(JJJy%jz2_ Uӧ!>q{Qw9Xz2ܶ CS* ES#S_H-# \bR=_5E/WՑw8th6jrZe94Mϙ|H4\FO$m# I]ץad޼y'lBRASS3+d*:(Bp=O"_hU*]FP @^emNft $Bű}2;^ۏB t]G{{ryXQ9sgcٲ TU?QHR.bQimN&y1Ƥ\.gϮG`]K[UTVs]0pTUb1mrhѢ{ժ?rPT꺰@@,+8t]wSj5/w'=e#H"%`;:;qU0m ؆e85J8B)C0A /(BR$B6=u߯qttt۷o歪8[u jJH@ C"an<^m F#l Boo/_v}^ycсR4 ?O:tB ˲Z`k Rl>1 'ێpX"e-W( D.plPlZ. ښ[jiFJq@pV#BÇ0 Ԧl;wR@WUbqp׮]Rϟs``Kkk+͛8TUE{{;^0zQVRVZ]QQפ-3|lJoT!ՕP5^ U/`pp !7P07.p  pׁͨ !'!%NxQM鑑wz='NNhFϑP0FLxnѶֶnUїJE4I8.{b===wXs(Vwܹs,+̮^?[ʕl{j0B t-R~>y'.-XcݺgC,Q FF_=BMcWriBa,ZhΝ;smfT8oߎt: M0<<J뿾y 7 ۶L&J_F\@{{P(266h4JCUsaR)L&8(I|'3(`(8̛LZSZsQTpTs f5(`Z*l˂[Cוզʥ#iTUJ)Ϧ!(%`FJa 9{JH):D"t$Jzyc875o  $8ȧ?;_ڽg /P(RJRd2^h v6%^pܓ?Bzzz6==z=>L(۫2i֭Ǐ4B0@)\n(Թh, FE&H,;p Q49)K_~X1 j(,[,2myLYiٲm_n-FBZZm˲{֬Ӵl)o{4RTҲP(Da |ĶǜsW]el?iT*]׃r[z{{/p]wm18s[KK]nGGGP(@˲\/qVk?~Ou,mnmn?mW3 ԫBxJ):#()&1)\ `ph`~bM0cg.µU(^ C4Kdžn":k =dWQuhFnJUU9?T(UU « :pB`P(K$8q+aR~{o|K.X,]122.J_Xm}  8R/h4ڶEH2(<7Zd[{Nau:M8ժqSUU=H,BD]pZUU9}Bh4:OJI8RJ𖖖yK,JR |󩧞5 !PJ֊+>l6KT7o|YY??TU}QCF0!Ca UG2֔ `L4o q=yXHdc3p쪫p0NLjt,ӂiwmot=tيo?rH$1L퀻w?|gXiAQyV,HƘ"Blٲ_WՖd2錎~~׮]kjjZbYV4ZvYJ)hիQq8Ν㥗^бc>68P xj Sz%+dbpgX$%PEF(T^Y_$,_][^yvӏ̨V˖[ow w?~` Fe&О׽V]|յ7+h"1tXn|]6{'/R뮻Y/d2qM۷'K.︮+c!DRRJq|>ڰm gsvmݴ}j-Fon=QN^W(BJP: ^&  PBH ~`HJ(PUW|xʅ?ѿݳjZ-CPLQB\׵|޼yK)i%qjbH~T:z!SX, ՗]uˇ??I6z pvm}C6mxlzl=BQEQK)t`w}45{/^+):ڶcwuϹ % RZ8Dr0)0raӬZ(T%TpyS9wB7--Q=w.&[{`,nVK-/=}?W;eG61ub8[X㼥CDD G"nW~WX"& Ie yV5;\No $(˶l2&Ǐ ڳc+t6\8ʃ|~!v]: V_KqB)%D)J˜ B]g˗,2m`"%%R@(z0"kH^% ޿]eY*~^*-[c#Z8wn=QZF_#M֛o}=wW>ճKIңK?m[^y\.1coG5 |~]0O_ш6HLCL)Cm+M A;m u\oZ= )! !K)%Aʋ}B>C)~,FHM.n1I$ !\TUYs.I5u5+ZBA(%Q-]dMcR˖H)qږp$(#_|CRtlI%Zc!A]@؎4Aۘ;3J*a[o߯u޹lO?3鑁_xa۶Lql!N[e9c39؊Ǔ=stǝ~M麢0Ri#E2) HMKǭ52$%(x$$_.I\ NdHP%y~W !BRS`??EQrݷg疱cSyBP( ۅ''7Im'[.sEKVg@SKk\fx_{Φ9cL|4MpTM±8V{.NS N+9}, 0J>BO%5`vrX:ޤ/O R*@کdF>qB.+RPbW__cBe\63V,!!$ -X,ww]?Wܶ-#@`(ǛU;z{-'S-QHyҡMꛊ@'6@)N8 Z/$ u൘W]iԺiτԉdBBr!t R-::R.8|`ϯضmQƘcYf~<3/QUUS5]_tEkw(Fbჯu*Rqfdvooli똳tŪ+t-PRA)H}Sza eJhmz ؿRSħ™v;!u5^@1 O6A6^%@D-4kɗ^]RڦixT2Jrܳs`?eCC}9>K+ ވT0.p]~_y>w-׭{l_0-ٔj[ H4q׽77Z r2j h^!!;{Ѡ(c:f'!j-ChӄskIksj l2r@!\24ؿǖMBJnfuӆ<68p}QX2jI6/_{ͭ+VR-sãǏzۯJm'_0hh,-BC5b'Mm.x_EW Tr0X,nBH@ܫr>VuMBrH)ܳcm_|^k9ܵ98:hfI5T%Vv].{zΞ;o}`ߞW^۹}̓3Z{{GO$MR(iV,\r 7~=RTσv-!mZK^4l^ #B(2cGgABzp.mZ뺮ms<@_ߡ}=Bp.+l=\H0 G"x(x{?tpkێ>}GyJ3`- 5U m&BeY1weW]{#Xb*RB6w|$Ξ];6ؾyjԠ QضR8c̸ot=Ƣxa cjX4D*mjla/#<&36cS a4MgLQX"%(Bpè+rɲ/z̀Ɍ 4M[) j\Lx8&36c`0u=(Je!aTJsȌ̀Ɍ`H״iU鉜2ι9wOb) iC`0u èTf<;w  Y%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/Cyrix.png000066400000000000000000000175461403012130000162060ustar00rootroot00000000000000PNG  IHDRe1*igAMA a cHRMz&u0`:pQ<PLTEĄêkM3r"f_\ Y9vV%iPST,mƮ؞м]c`Oc{)k1o`_iκov̷JGDz;w VZQՓʴ~D}/p=y6wsǰޢѾaX_%RtRNS@fbKGDLotIME1(1FoIDATx]Z[KhB,gp&CI8}?jRlp_LFUTYZOz767QgYeJ"ѵl{gl[vlol[L|J@ WG`&"ADx}E~G@ 8&b6޾#% +{mK'x7Vb E=qIͧ'yU( @h.,hRC><9Z=-!|bVP*FJo>gy.7 tQ<| NpHErIËjarp "&"_1HJ*KsDB|޴J,D'K7H*\tvJ_K-!2\--g( J gy8k~ J9',6 le.Q&+S{؈XXruk&H`k˺k r'0 gEDwKH4u!3p#zBa! 2ȋZ@!$Y*?À"8{ 1%x2<[߲p&xwv4_gUOEXQ5&k+$8qـ@]92%ˣ0/Q,D Ǐ,60GzgL7XHXJ[_{vyԀ~Rawn~äG\.b+63R+v#b=Y؇?_.%~A˃DV)}@Z-[c/p—u#K!b8PxeaG/4NύriDw/wAx ℄ߏwADWO)Qo'vh_lUβA%0Ozw9to/ZJ>Qa!0}X'm"Pe'.?.VHyQDr[Yzr-_tϠsy\xD*ڮ쉬D?V1hǻ"lm|ĉ~5#.NTΞ:7Sb򸄌'1 y߾^t9(?%Rz)gG ٵF^|/NWWd2ٛL&{{瓫Lkkw2:?L&j|29?ۛL'{{WWd7maYb4.ţ?_ U. d!& 3W$w}da&fb2J1v7; aYeK?[v:݌nFh4݌nnFf0Fyf4 Fft37h4nfZ_6LQthH$B0 m6(8`(pA﷭,o4ih" #| &NA-דbF)ܳXZ%*L=jͬQmKy;ads ?ڀ"C`X}/$L`0:1 O(ET4}.˘w/KT+BL"֕=AIbC;/x4H/l?0)Vg_ʿ_.\K4""u7d$M߲/9]&[#d7ۖrʽD&=ǃx? 7v\/t`Ej2.F7K=t܉X]>P`l0s-$ a\! ug\:~f-WgQ孲"NnJH,!R,lrٲ5W*6XC4"+/@K$am+b1s;FN% *k?Eΰ?\2,yu⍅Y*A O"Tok6; > (v!x`O 1BY`%;rF%M~Ș$`Lnn^p9>xUo ҝd'Dnhb80(_8[23LcX.:1ű^WU] ܰ1}(ctE`7ufc[KilX!#tY (r!LDz8춐?ږ=#8};M |c"S]71,ME}i%}K_!U']=UA aOn[Ԗ$[DHs]B&%%)F?V")'IKanzecCd*"d'VXiX,i-1ĕN@ɪJGe3R! -$V9q<^1UqRSb&R?*1cwxئŨ~a.f۰ X P5CK[A2Wҍކ+XFPG"A e$g,|(0dQ{*iˣD=E6˹/,7s8Fz]+#u1Y(;;.c꽟* C6Ԟ{ӭ`"m81\,yfI4"mt&GӐ?߇LrO^$?1}KU*f"{s`D܍{$è b.Q!bfJT 2%N:U)9ZTK@DS0Pz%?(G{rhCk*)U B2 b)*$qN!_0 ^m78HTq|gC/Ji_(,*b.%";s&Kşho#~[jV> &ώ&Hd!em+z Ą]@T)aI%BU(ls`N.6ns4qmg49,+`֨An07 D4U;yL{ H(aΗUFDE1)JJ>%Jo.LɕZc~^uAI*Q1})ISk숀uvv-x:4+B߁<tI<ܷR A"U"cQ&@Q46\2(fHm ~yP4)j`b-3߇![NrQ|.쎪QWQ(2++uqEDQdoLbe0oV .1.ITUh:.gr1jV"= [xB|2Wj5|~?>jɐm|t/IJE@E'/촖OU,M`Ņ49Dʦ6ExI̧n Yi ̬KamCbSLGabbHD*OD7⮨7(Mci<`NLq6O@Ҡz5=2EuE&>- ڛg5髨z%IUWլn % ~ԥBgU#/\ŲebE{ccKR5aI8BKs+ Te8oH߅y TKK.˼.Y[( xlI;j^g%S),Cܑ4yWJN [ܜK9̆뜩)~xc.LJ/7)١ss\٪Z^Pb>!e~\c`F塈'7 iɽ.E蜭 \`s?w-ULAu*ncNB+>B^j9?fIx1̅$4_ 檜Rq!9-';ٲIKgsDr4Y kG!-F.\͒ʉSQMb*ffHpvbHy˕\K)Cb|vI;l}΍HDJ9 EnT% /Ca>vc)'8^rufD\QH!p(:Qgٌz`(Zd~;e[їT`]{3%sCA7 jx\Qlt"~q~+)֢DeCVN(RfL˜ܺO$EN&@ELOéf=Z%9b t}'顓FeS˜Jp3o^JՐxS ްfvJ~@'32I?nT6jP+{b!Ѽ ؉~莤R?Cc^9˲hsjq@"uK5)q`ѵ;ctL@,"D9|\BBԘOGG儕G^\$, ?r /Mc8by>`$ɿ%J1X "Iov<&rʠf}W}!Rh`eO7>'8F_Ti$$xz Q =ř#(s.),\ l'e(S8[عEEyO.)D2PRDY86#rh :NvS45IC \u@/d ]8`wYE>fcef-?&? <>?vC<1_EK_!hb&s`>F5ٟaS?6ҎlȱÜk<a^ins<,$<,+w):sӂr/+EgME'?$C ?(oa/`)81dΆ`6a"vmIvaWDL@D{gŕy1,lO.qWq,lXX|^efs>H8#Ŝd>GQkom2笘א}|lܱ=S32<`'@BQEςx<OƓX٤qNuvu:Nlu:N}5nl:Nt:Vzvcou:ͦ=y}N_ǻGV{8l5w>\pAډj>Oz>\Z}^Nkt:]jZ>NZ6k^[w߯keʳ^j5}~m:M]zm7:##C}3#͡DFI+a%6 ͕]$_*/&ɼdI`_G=!"Y i $0qҢkT!ʕ02\JJ~P!{+!-6ڈH9jd%Eׅ=nPJHÂi%E8Oވj3j5J_E?`%E:43>:&IWRZt5R}ę!鬭z *yҢu1̈{\Y`{JJ .}l$d?ͫ[Q+||dǕ\gwjDe֖ub?1;:ٺ]}ZZj׎%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/Intel.png000066400000000000000000000406641403012130000161600ustar00rootroot00000000000000PNG  IHDRdkgMsRGBbKGD pHYs.#.#x?v@IDATxuƳ$@ hii⮁⥸RECq ;G$̽s;{N!TP5p].Y W0mļ S1_f|qW#Qq7Og}\w<miyg5K5dcf{PW}oB!2HhU+e|LUzY?c~<<<$P W!36%Pɼyi<:!PѡpgSQf>|z~`\хp['4lży1sH B!/V]jkL{m9k|%a,a# UP1D9'o0?eP  Q'yY9&[yy@!XPo}j1 y/RyS/ 0P~JBBM** 9yDUp"""+AȜ!7!J ][!{ʫ':AhSNO.%B.z(b}աK"8OVg>ּS; !SzN`8Dh1z /Y['z1XN^+EpSv>B(`xy6%oO 3EpGsPц B%u:^8yk%? jHw*t^`$֢BQ9A2H.6-^'1懕t:?5?BEz4WZmI8EbIֱ8cWS_ZmUsj{'& &*vRѹ(W9O~IׇFg~i'teF#(|Zn1=a^cX=9TYl/~$a o1KPϘYUDLT,aWJߚn*OTRUw5|KLTz,CyuP Q Gh}x?h=z^*ūR.L/Bi.Tu.XqPYZf[?w7d"Pc^LosO!*Q*Y|Pu@}[WẄ́Z;Nd6L(h].J{|Wi9EuJksmfouiwmOז}1"D<@[}t4{ ԣuϽ9Aݖ!{3ll#NX}??*Gb%-c!7+d6maU@>A8 Ljy|Gi-ȸZGW',hn̻kc.mytd-3Ҡ%OH4:Qk|<i-u _/w&[ȼ*ԹrZ 0A(uAW\5 HQnF1PËm`E9QyvK ϱ/[JfZ;3e+Dm6Ck5\JvaLm?@Ź&+^YJLYw}KJ12"!:7@cM,#(: K4!d/ #RZ|xÑvtbP@R\!hW*CgdBߛGF CV/и"˚Pع#RM+қBy|5W#`PB]_D|>!J j̭/ɟGx֡cF јK7G5A$![7A$@*$/9Ǽwrd$B9`[f9$(@cE 4'*غ:P #hnt)@451eE`-":2g"(ѼN ͸ż"*Z[HHcR;!:Ih /Gtu/Q^xV|4AMT4;! s,z Gg⪬(I|yDьR^&!45 =x<؝O1,:GV4,R2+=OnM)OCq7Bk#"8.{'WP['{&Rhd0I!TY('f a#yk5%񊊂 (BYG:>7/tMy$yN P1@dDPKu*?cMB(:ϊ 4N& .RHm wV,zj h Py75}2yfF%MJ.zpB(5O>Q3ZA^7!=:Mj+p{ɼʜsB(uݽ sF8ճmw !rK߇Z:O;B]\i@́c6 Bfm~2íI E"Bo_EFyYFDY@2DA:2 !P+ޒpPF!*tm8#1 !P9c:ܵBόB:28ƙ0!P9|jF770 !P9û~p|c^@!˰[ wxmzR_YBR,c!P >&5y_E͇0g>ټW|^8<ҟB(k8" O)^K,l<o-P 4чsPtݎ !dA/֑{5<Y)oW2rlO~0w '24qy~Ap$1 z~ ܏TE{{Eq/;~xn 0]LP8O>x#OE*ټj O07W6+`5o/GtyiY_oj{fw pd}ޫ(ziRhFepD+֘VQP7Dŕjt -:0\8Zuo/JK`tcߊ_9 G<ɼ1 s8]uO$^b$l !9lCb_d>dAqT?tvζѝ.C"}^81}ǐ8]'7OfT3Z~'!(sţܫ7 $eҼeךuA paNw-̽m9yT%͋Z<xbuZ8~sZOշڲ8xo5Hqx5 lODdpa$޶\_I{*pdޚYBթTA |]|`!8p[;xrWEC\C 3ڧA d'pඖ p-`yn=Gf8fZ/Jp,/( H8hx-Ca?w4?"7y_JGacmcG}&ON਽HFJhoh['>Mxkp(HtF_G[X/UvQۿ6%pdLאvY̩?'zBO{L{!p$b VtZ 䂗=Wi8Pa$Ǫg;cCz) (ڳv\$h{iE9LWtZ.t#Mz;/ #1%xթ f7,p\3YИ`2KVBSF׵3Q8X?픯Qҋ <?GӐZhA?H֖YeH9ߡzQIsRѶwḩ3ܵᩖ>8_oUY ^t2NE75mLav6GacӜXsak +gmz%rܒtuH#rd)h,d2}A9H#Qu褼^ _GC"Y\op8sD7>1NtaB?Iu/8d'U5]l }%y,|2pGɢ)uI]JGyћr:G1꿄Sr,p1loX1#+p6:\'6K2y^ 9L}o 5-[|&^}N- p8QKq}ynv8xul; >Kk p:OFߠ==;(4LXiR1 ?hsC/n pq*`ϒpz0#u_Rr>p9NO,S^)8rnatҤSқ (A8 ׹^!מɣ8rݸ̠-W&r\Ga?J8h5(grs$\ӽm6'r\z/"lzNksp̯u Hmx3n<9VI\Hv-{h(PY*'k{@UIMnh2 pn~%,s-ߩ+H9`٩ŤºL=k>8YPiR9Są<0#;h[ddP1l8Œ j+嶌-`a?ζ pG;o =,?-T:U:8J eOχQWKf|*Oᚗq7w pǮ&GkUn}ALbX80?/(:׊OM%h`h)L]8ۗ=QAj{{~i] Xqpx};8 [W 6ƚ?7 yͣ&p5^&t8 FY<*qv8 i^ѷ%Z$8Ǫ347??H;42p?n[g(pceˇo?s#؜C60/w7W ,8I1m_GԊ.0>dp$p}=pyw" >sй}W%8L#5z/ Qõv҉ё†.O}cpv8#u݀_~v^g#r݅=3W ,}8cx9yGϽۄ$mxV`.<<pyj2ׯ^3s?okeoE pu~D9VD5*`RtN_8~j$:)~hTe b;A]$89pGa,tcUCdƜؘn 1LKRxHw8)4o8!oyM,2ڝ#].$<r;pGdV_K2!^{`cw͇ɪ"9ߖ[PTc #85 (p w{n U] [p{Q:BɁտ^:1plp?M&Kp8Lxvw >s!4w=2{8lϏi;FpGOo|x>ޞU{>R)ҡPZ.[32G%)p8<:6-蓴`6*9tD[3eZeIj%ci8Z2XFja]c&fo+UBmo1߽\#u(Qj}['p2pt 'g}DřBF;|[|mƋ7v,tKAI~25* p|\thO8,SXJ p1f)4al3w2f^< ׼yL y>r|gǟxlWġw,"mw8"3O1-0X@k}l[#$*-}ud*ݻT8]?S6еoc؊^PmŔ?8l5'Qs#xHg(pWv>pdߕ8|^0$O̫8GW EW+"MA8&6G >`<pZe]{ C"ܔh'%oxy@^#RQM|Hz'G$>^\/Kv1)_X7 ~j+F$]!/8o 8cEhRVH8z -Sɷ%]^pTzL(pTH"\3*\o b])ݼ^kpT_UFwTaDQkܛJ~/jh}_t^Iýec5{GU؜EzjD멺Mes*]) vpDʎ_8tԓh V? KO}^.p4iwaHыd6iCM w( p1GtlGW{Ϸk{=^=^e!^8 HQy`g7*ٽt%p2/q');i6mX`2e]V)NFpJ{s9pTp7x{0J=妒']y"\?)og^I8+OcdfGR_8tT»G^וox9IZS79x#x,>%u:48b*#Uϧ}ה^XaX0=94>޹'+h];.<:I>,%[X}Q'!p$y͝Lj>x_ Ԣ 'y,SyqG4P_c*7'|US8/x*jhz-R4AB౼/7Eϙw.F7!}wn2*2X!m* p4] 627vNu.OSiDlw{e|^`|h0Dh~" II#TtۡHq ~,'!zf^/ (}?%pLVnr^BZuSエ|:ζe8G9ۿ~$WӖy>~[EB>"/D=~g= ~E G]Yv37L9pt%u\2%z{Sտl bIb1VB]{ tUX{Ep܃N?|ume!%~QCQ'Y[X@Ì.܉dnb)k Vz gxpQKԟa`~^_Vtm 8=oǍGpx5,w!TD-MG_2zLT؇mJBD}ER^B! ptPܴF! CTػD!PcMϞ=B8B$z!PyG/P%ϻ2v#B兎L@(B!TnX$P`!B?xf&erBrq\E! oqBr汁"8B!TNd~!pˁB8ܧƙ;B:Qo߬]G!]r/ pxayB|14 pT:#J54n1 =I E!{= \z-!ܕx6IB%}͇?f< -A UB(X7W8"F#}[+!jxyu'N=pD6`'6B6KoN#iQ;3!Ẓ[8" 2ӛQ@!4w{N~8"Хh-4pV( jј|v_H~TvO\B9lzg3!T^'^8".G3 *hc>Q&~c %߳c$BO)g8rx2Cp܏@‚_X |"7ʠXs{k/F! ~ +ot*IጁIUсBpdቕjܓQAܽGf23?7^'qtΰ.G=zWB(\N!#Gt뿉:ZdGA'b"Lߙ5B%V[T =C"PNWR !j^̋H8Џ'`yڼBm^Q%o#9 p|Rv^Y B{nƪji'MORZ#!^&bgBo 2n~%g GI'W6kz2F !T^vіɘCQI'擽#*͛g8J8Cͣ#p=K!Tuy]JepI8<3#*:]MӼ;8 piNNs2@nڌB(뮗(X|m (e~"GÌw4:B(kl]U$8J@YW ܜiZPW92&ǔ$!/r8)p3Q?:N\aHM[w:!-MPu+~Ϋ:(mDA~(BiړUP kbmٮWT (8PXgx^T'9VxoU[%pt҂P_ûU֝jhP9u̧3o -σgo*PЯc\^QFk'P=w(x`.lr=7pO[aH#TѼy[%JM#m̿(;7ؓtXZe*ĺ4odg԰%qFcޞDT^MZ/:BZ*6P&E =aDF}+q0|y(5=0f``c j)Lybj? OUTS.]wꔃU=7S"eD=Q<~9-^kRYc:*vWoմ[n>@ gnӆoIy]<;fBm^K*۵޵z}%pߥ9c܃K߱usa~D|lͼ!M3zှy/B5{Z 5{(ɯջm яvl>"[^_MTX\7pck2mm֙+揵5BrgqxN5 _9B C izDAP>.s'F~D_б D.J/U>` &!Ar6kor^gYerwFEG\:*v}R#jQ5mXC eX ėNϩ Ov6pufJ!29utAyiy;N2Sq [,@8QW]oVG6 pg "UwĀWؼ^{ w@.7[h< T3= ~(YF`g2YF+O9̇PzJ0|)t+_KQ̞Ho^N[d;+JuߧO#l(p inТ,QgOs%>eNxg΃r@#Ћs&}^o5 ^q'][WEfE=H0*YeԖ8"8&_^Pю]ß$W啼Pߕxn0-+`s-|酽TV{>ݘj-ķʟ5$~w;o}~9ݞqZ?/dG\o@hmKKœ<~*^p3=;ٟ.G Qm^@I_0`qb[&(<+ 4_ݣY,0Ƹ]'^ԖP yo#̍1ƭp%&– Bmv4(ycyWiujn ƸfGa.x*)`-HD(l~7:Ƹn1oo@([lXͨX0y /"2oA/QG.q )]7R["9xԫ ck*zs;-gm_sX& J1udF!T cY 1)[St"G'BcdP,Zz|S%Է+BQ#g{acJV.Ʊ}9Uj-|4e7x(龊>w6<R;k̻4C 4G1ų'kɼv#!Eԣ\d~UX1Χ=rZ^eͽ PLz۹>0֋+̻sLeOPc8x3)m2[B[.uvrk{<Ɓ::@v PAG5_@v!?ͼNt*K :mT藗C5q0_bͼ P+GL݋>SK{TLB D^D'FHgwR.wB_:i]]Ip^mpN4z7T1==@" S ;]y 鋑__6l>ɼy9J$!r (T=)lLR}c7U'!#u0_,TT\EP)a9 ;BFD:Xoɬo|P8|Nݑ0/깝+B()/FED4o"|Y'ќLLEC;2֑F?PB(3^o3m^Y@ ߯ι%j:)TGѩ%/uUlM &(BQ)ByT(JXV`Gy:D;'kɖ'<}+'Pswy=t5 `!P?0DL*KYB]A KPA;]_Wo60oXZsUу͟N{~Nww\uT͞`Ȯ.hkQ]':A^~%є/%tEXtdate:create2015-10-24T07:41:44-04:00_N%tEXtdate:modify2015-10-24T07:41:44-04:00.IENDB`CPU-X-4.2.0/data/logos/NSC.png000066400000000000000000000656311403012130000155310ustar00rootroot00000000000000PNG  IHDR:gAMA a cHRMz&u0`:pQ<bKGDjIDATxixUOB! @KB !! " ("( Ⱦ,˼3:3 tխU~Tߺuֹ?        XR!Ó7|48{BAAA*2!r5^wj }סYTx = 1sDAAnJD{WF1{ pPAA2CYl~ѩ8  3 n ׾4:'tAAD\<`\՝zkq mO(|  1i4HRٸg@AA䁫o^wfq8# ?  bC H*jH6˽aHl>AADz\=Ӳ2[OcH>(AAD:S`Hַ'_Z AA&8d}Xp>4AAD%d}0,  b9QIf܏AAA#y`k?8zCFAA,1L"W ppJ C" & V+67A#  6A4zB!`۟1AA\}QםԿqp~e3CUpp‡  9CyKfZ.P-ˣTGAAQ0>e;A.o'L\>|AA߾az[Qםxc| )dY(pTj-Wf#JFOW= ' 2(Q(U>=[oHH/"}D|S61Gdʼn  .#*!pbA`!h9!Y4:׾&rv8AGiV@PTW;8 (8%%ɬ&}[lU.b%t~]_@wfߡr`?@נv|sCs?~7*s4Tװ{PP؋POP-h>I{W1m }ʜ PSx9ŘԠ:IF!9ɶ~Q{Lhﱉ"emcZJ~7iſ{Zh^w A͛zݞ|"NxPGZGX rLr6cv61cr~~*{նXкPcu h\) BP@{T 8nhtNP؋6c~P(Ue;/Ǭ{NؼImb(v͢7$6.KO ֘_9J B `ޣOLl>n޲s^TsWD`<éÎ? ӂ R9!;1Y%ėe27&rVwoJƙ'EG 0ΞRqƢ M֗У 6fbty4DZω$V}Ǭ}\MpA?&=deM} ዅ[$"'v[TscDx&-}=L݂KjYK.niIƣȪLei61qJqt"Lb U_|+W˦ jnʯƇ SucH"acU^Il|1*s1InZAq61<Ϳcѽ-x'5 ID<ճLM󻟢 c43n~T§ ϡ?[ūWrp"jX"qlo BB{'އ^ 96<|"0 K RCnatPJ[%0Q~6fM e{K$4 y4NZ矸(R#~>({iy,#x' @(Z{$ $)GĦʇUmUEQ"ʹtSE6Sйx<ō}̫4s6EGZh=-粓E씴y+6NS(POgPl7&gM 3<4Nl9~73iqa;J:yA@t* 5N6*;r^@Mr?b=Aqx\}DY 2d=ƣPa7PPM_fO},}tҹ A];Y8hu8@048-_2QIf %];,}2s6 uT2|4݃0M #&́RNJmwBs2J!zb БiwTk p7FL!I9qpYAؘ0b(Cv(U fW@X3P|Q3+$2&;uGlzqi+8JM0v߀_Jm[BNPBncP56sdTI=;5s Ϡ0~#x5D$IdhdiyjvqBn'B Kk1i FO_Lqv己&{ FM > ?ֵcTU*ho:<3wFڜhYfy1v13:bCWv37`wdDe΢rCr^jM@on&l J֟ȌB9y1_x2 Fʖ?L_ט9ݲ{=!cpR꾼G@y9-_ܖ-a;BtV)d7>aS܇0#0,> 2;[_jY'zECGe?hk qPp݌^c!8bEYw7mÑ yQi|/ZU% .؏R'>>\s B@N0zz-\bn Z'W[bQ#|̼zn!P2asubk3dW+&P`Jd7YB,`Eoҡ#3`_q[iVPomUVcѮX΄lBVq𵫤 F'ȭZpdJvb5wP{ܴE~;8alDj_:{pxo0;$6j$&?* 'YTϮ3?c cڝ{Vs6PV(`\]BEr!oaK̰ؖ4;^CFO_\%F%\2&JrhO԰vFxx"3 ո_|ƛWՖuVbc1K{Z!Rª2,a"*̓ɧzfI dΊhow }0ZOr^w_ȆbiwG QEy  ߒ6WCb.m\ʻʫUQ V@' :f!L ^r=9a.Z{Lc |st> zo/$.RBv[v#𩿂7j_45j_1Kx1-8Z&Ls29ŸЯpMZC^̈́x3&gufzFDEF*5u|j zsKk]L ʍ{z CbYWxdz&)bs6l'#THBr$[P\/zV;+VIwJ UOB?j~ T ) *Սm1S蠩X8yAO r$o%NW%_/CbKu[ 5aĒjۢ]` gkۢEgz|+--Kl*Fµ +*({"Uq ցxMc9Sj>G?4B_f@s4v HXH 5/B'hG00WRy1ް1i',|꯼7~$Q'j#îj, 2 <e;>I[L*}xe~j}jmdH |f%vqH>-C)_Iy+G'?_=p :{aO|g=t/K:iU$ql4\r]sKC[DAX9YwK)4ÓmY-gX_Lx<<޴v\^G7oh^ .:D3.HhIgRk=]RZ꼖=KI^oZ1)7F l3_j|wя vP{2iOټڑvt+۱QM<D(X}nmRȃ곲 seB:cl&mnd}Ua'7 iVdc;b@h7;$WdKb̴{dIL;[Oc(2}^5-kvhel&4ei' BnjvjiiTz4aӐ4kl;PFRRSP|)[ϖ4Uo@Ch!6 97{y蜨hn-n|{O[t [ȼJ8+ͽiT}ysפ)*ɂ!~\ż Z?~'iasujcKԿ"М :PMI 87֚;^}UL^z[]K9Aqd\՝c-KmC7Λ{fT hTO#yddF)Zc#j 7"VȰk§΃@鯩i$c@vy':E5HM-W. 0MUn~tq6)fɽu] 'ݳ=drlCZ]B$+WO9H,Ĝ^w.p %xG!# ^hdCrzkܿ%a\}Q^M[g9I"!uȖkc*OkO2'f06l"e96 Tf<_?cUc$vF7maXOUlr{4B~˰ Zmw%tX5s6SFvÒ?mEW5zTjϹEd- yڴ2V!HJĎ(wuL{Ij YwZ^{qW)x84RJ6&vd-ihKVw^ 4TQw]w(49Or)Ae/HZK&Kf7vFJ- ح'6JÒ#R[9W,#&>jq 2OXBIEM>˰ Ή.6ŻP "@xIZd>a<w߀>DڒWj _DyTfI'LedPAiϭ.ul+l٤$Zv]G7o%QՓzf ` 1727?/x؀JS_8kA^ ټ>~ ҋ0fN}56 K[\аؼ $>gQJY!t]#nZXtٵ]k6M Kcd5{7`7*MI x`ӡ6Ƭ'A:@/-Ht71z`țJ(}^&/w/G KB_X K[:OtRTf 2HBN!FT 'ufPd.\K^񽧭N:@w{il'^+n굣ty=:{@֗D}ִ&L*ΐXԈ"zlsv{lݢ'rVxM$c0I{j$ml\A/nfw?G1$G̮(ۨ?lLTƇ$**̷6}oHzhI| gp9yS0u]pL7fE?! ]}5S˺̮5O(Nݬ1z|GeUɃ 6dLjv]c#qx1==Wk*VrKa4Nev)U0wӯ~.5E& ?Aū94R]z=?ivT!V3e;ͮ1r_(J?*CLzg$'bRace\4wH=pT5TZ>#s0$??*鿁qac kCgM{*T]bZMFq9Q)I>ZczIe2%P( ScZb(lGcr6:{xZJHгaє'=zn^V'N"HUn(!Mż9񾮣7uUBUhJlyl CIKc3zGeֵ^xFO aYZGCøD}kz^]$#"P(gn6}^--!aY[1 xFwTl5'_g:]#2p 7nKwar5OquTP92&ǣ&J[~o0HGƛ&!SJک݂mfMZ+DUT˜x鐟`B_`8O89sȷP^kezO\RO6bk#v%r/r*A{X0{7dYfsc S)_DX#MYūf'mӬ.BR;80&gZQ+2ktN{p CCqCS~yȩ Wu7[QhD>j 0}2F4-2j#o]eؠT.W!Lon6pt1S#(.pCE\2e:nH,K1csӅ\޾0cRhG.yK ՀLU.yx J-=櫫0,n Fe~g7}h)ֈ 4ɔSe^]xV=S_IZ>WsNVzj16O9CY cȪ`(hd:bFfZI7Li9%4?bim<(>+Ld/7w&Y^׸{wId|ə{̮G0G* $G|ץsFۚO|1c%ȼJ 4 y$MVyͪZ5O0hBW|Ac?62eK sIZM>}'f4:Huc(Gz$k$;f,zc.W}0Gjz)UUKXer2td*L/!b$,_& $LhIi:[U΍弽Ҷ 1>aXD4_2a|lF 7Og9nڙXI(BURr3h7LNs?M⦙"B'IihV(V aA>:2,>uO|U+O|Yu2g)49͏Pm^V8;lc:(zkH\X kc d˾0c3|;FnF eM8m60~#=k1s!~W Y2J 6w>Xep-< 9M!8aE_6f”Pr9(:_Hl$0He'?/  qwjp#i,&? $˂  b7pQ[Mp {El:(|YA<DjVuйx@ceAAdpUA*X;ǩԁ  rQ-g囟a zmZO *_AA~ 5κ.^(WhQl',  .2qI_GUBwu4\mv/  ‚YS:pAB/  5 {B}hJ&oėAptv` %;[+P;PmhJq Ƈ7j 0gS, 1}W(UP("O_ACb!$9J`d^%W+9Mq,+o~=Z`"v|YAdO( pRYf⳨ FH^}eAXGܬ}SW8.%;ìljN7 7|4xF/;ŽB)%pZ yZX5@vِ4o7ǘy8@RSlcJY(B$5l {#P56W FĮ~d3Oc*Cv.^$kbQZEA#ul'tnFWdaM]o)Fm*aܴE_;nj:e]0 bwu},r[s)14a`uP2wJ7Z7'_ 7kiӉ#0ܪCVaT"LvA_ôvC@tdYBECrRjY\xQH4hЛ,-eÇ{urU}BGŒRϠrKhb煟 M>(k{q  +g\{@t d-5x ƆAqh̚%JG,/o{DO,_*5ʯ{dݪ'_y`j;$ZgԔ*3#)ໜʂ'^BY%7 s?@WrK| ^kPU%&qq7F1nT Ns6Io~A-[,:ɜ`K*W`7|h?̾']} !88`n̼9~;G+d{ﺤɴ1qgy 6֐ ɫrIZ9CN#f/u?Ap$u hxC3~m9nYuX;i]G蜠3ɕ _|/κsdX|1TyL0ƨDXOБ7j u9{XF=i+M}镫vK c4R} ŭ&Zk&mɔlu7R:O4iTML+f8{@ټ?_,2lT}w HXI m;m! C#a_1|d.\kv=ڷ2Da޳bk{w BIVHo=$2&KdQDgشA'+q6yūf:yrzDCS&x.^5^770P0}׬8z fdM[xnm~4:FnF qfe\̋<FMÿg4];5ݶ3,xz Gvâoc.cV<8{ɂmfM_o8v4mfV~S͌Պ^G7o5, up26^0k$ 캃2M P|O< % ᣉ˔?4_ <.ι7>K-^ %ܙP{ze@~^|spj>u1z^vtͻSøN b%7b#lQ{ƖZGp s?^iL>-[LbJJd7>lbPN#W G56 J72[̋6TFd=drI2l,/Zg7vӦ Spa 3=Ƭ>bgr"i]*|Kw9S$YӦ IUkaJ瓌#{IV]Zcuߢ'LgӮֲV]x+*zh }ʜep*ߴ{L/"!} ƥ`,Qrҹ6;{HY?LSiu Ct~׬4q_ p\tSC~BA=xKg{p#'u] /6'| BFX镫Auw>WP' bj'\5>:}R%g f8ZC؈8y鋩F;w?e#w;<2{+=0b3l7 6Π)IB4tdR7o?ߛ^eO?&UJ跫Eq ˢ{e7,(*(7%[R\[%ATjOLɫ4*&acSE%Z4_kD?Mnt. Wkio*`dfu]Q\F5VY 5*h!!D![ϖXY_꫞|pRZya5f0ck8ͪX'UBIbJ,j$CPxB#=[a 9?pA 4I$fkS( KG]̨Z#DPx~23HǾf {R/g~m`|9op2ci`.t؈칆cׁJcQ٦n/ZZr?յ V`݄Y!WLq4sVCRgkuh6,GTV[й94OvBBRx/|&'u1  ]}נZqGr?)YIKRUBuTх!VBpab]B/3CZN}J (s}W5 m/ ag:jg{YެWοQ; +Wl*V7b?k4:BT͆@ūHJK)~ߙ}1N Jͫ6ՆiL7QX~M)?ok! ҽL5Qui8cb2- WE F*8[1ƣP];:z/CW5kc]nm}]FwH 4J`oxg[ՓحW;nL9vgbOLWxzT5L<'W v/ r \q#c@}!%u }(fܓZ~캺1g@b%Aʪ;C"@TA]xMo})Tcu߸YԈGY(='46RUo-7{Egp5O Wbݤ1$Q)*7v=s \ڊoxt]ߙ\oTr⚤jҹRm}yFGL0yOIF 3'9./E4bUI7cWd.CX;jJ䇟=/\F))d׿x?9lzl |Kf1L$"z/kX4ZsV[`JZs2? `'cEqXλ"`g8y7La\L'}ס7k4c+ I m >!\X ,( ɴy1\U򰤓$d{߄DZ7%MysHAR4mMhd^X\DxByWh)l86zz-k9yl=qw ,mRQAϠǨ0g&<Bs 1.B".z"oP<\ X*o}!ir2o!iZR"=0 ~G?K*-T3g$KzSȅB$r&Dut!PlE%m TDwH BTpdSZnvCf!ƧLL/:/'>0U3[&FəY@6rpge<c3g8 P0LvZ=>l`- 5C[%NoPzk.ɽL#|%PԌ^5b؅@ID#l[w #zof؏70BTY$DHyŏ*Pչxp,Ѱ'}( o)RzRg$1`؀%$iQ6i*Z,$#ZUp$C5zfZCYNUHl*VrcϧqrNIGĤMk9lqRǚ͸M.nʭ/Aw H\k3שw} nޜ#(YQ La!1MmQ>ka++dYb6}o0+#!颇d-(EO**}R*:J5L\lmH!aGן 4PBR2BOm6ݡ c,G7oh9Ɉf49h՞쉌wH^ KRELB;/*|bߔ*5g"bA+lG]}`lP+`ͯ5 ց5#]( @ Rb@jRQ'd#߰69$ߵO|]}J>/BRndFGLrěL*,'Q;[)ړ>=fRq1eG~+n6 g}g Iʮ8&GwNcXʌ%%4/9<^#(e u2%{iIU(U|sb@ g慏]ޯݿ1b]4mɻ-~By,77HmX֋[(7yX|q|>%X R<,9BwBn¸̲Xݼ9íЍJF= "}:z/ NJY4nMpS Whin~T?X^=0 ڷ%mRZt.UmVP\&1围A-r,?|l|f!:\7;({"g%N> |?6\gr67N:Gb.mBBdH*6e ZUJe/(ZZ9CGw>WoXj:V/Hp&DD@51(Cb!:jCՋ3npxjvJmVb* :Up&>pIl|iɮ~XmgN,~la'$%&8>=ߋ(D߄0T8Se|O<. !'H.n%4Gq{|sA%L$>O 6{䷆V&K%5<|[݇YV0U*Ra=si1}IاT9e+(EveM 5iFrфHR !BArG` e5\q41]Ek ]>EJ,v % Y؋6 \V7Տf2yb]cUm cV6HHЕVv7%|~<7CG<x赾Y$Iޤ-:>*H|ɏ] %CMsETn/*ZN}%xO]ˮ6&yOZ ᄃGAD Qʿ=ɕ}yUЅ׫zcQ0,ʷ2(Ju rS"Q̏s!a!mNK֠8gᦷ2UqR6H-넼ZK|hz}!'_a-b*K=*gs3߂wH,k9 =B#0~G˸ȝOkؘ2xOw )~7H/L~6ƣ0zϛF_t]G,䋃~Bwb].oo/AbӂYMb7xi`XXb~Z)y'~ 0gS?*nށv;Ffr&*!=5=wSE!7J_FxpT/*sMd*ǜŏTQf\9Eͽ,i1k|Ts c vȌBb܍Uj!9`;PVkL.ns!_Ǔio:ʛU_oY=Yy_k|=%Ne)IMG?}+K-kǐu rFG`8|`۠fm*AZ/ZOC:§ëuta͹` m} o@@t*xNG˩2~Ѻ_)fܴNaFn737?o8?-qSkOD$IdsZ3Uj!'@6^LϒFu’p-뵘u'- sJv!3w{zDdF)ޢk}0zur#zwf$)?<= 끋f~Dܟ+*st 3zz-oFO06M_8Fnˢܱ>gx7I))ij:_DzhB~ _h[RtRmoҦDxcOxx5bҜcۢ0:rǵC#g9'K!§ͬ]Ole;˨'t8{CӱOKs;BcL/!: `Ɏq(R15[Za3a믗ÛLN<bH'l{O8--Rk  ?YurHrMfi˄kxIy!&GgZ9MEY<ǐYi:gwX矬B|-*qےyn@ V_sbF&Cu,8¸z`V\%5Y^~'H4i~%t#7kB.H^MsgW N%|:yt]r `;eUثZ*_dզ;Fj J79IՈMIg(,/7XZb|1|͒lQ n.c3 :|m9Bnzi&G7p]gh*CCxk7v@'ui({ nVR}ڊ= !1eK;hXr+ ajTԬ3ߚ[H,v77&"4}/[]0PFMoo7lU-QNXE o)Iz^nk8W}*xYTcZuJUvLʯTϖ$KAAs4{YҪ.>CYfFl@JN5(Id%Zk(*Q5C;LNˣFB.,1L>n+r!79Uխɸ 2|B1QrQ%9mlmT"%v^6UK6LvaR!n&N֙]->8{Fd0h5n~jjG 4y|[_6 jܴE~+۰ygAí>a;l;ɿM"D,. zOH֍Ϣ]1I#Y5Wah(%1BQ5*Ao2}4xyϼG Y88\xFӦ[u^L $DP(ld|BGr++ڷJI 2c|:ӟ{Nnl.Ys7e7E%2w4ƉgPkuѲ('B?{]C3O6/_Hmw X`]&};u:{հZr;=߃{`(sNj FWN:=:rVѫP(!6wsI!1~E&J5ft^,S=o Eο \G Q9 fP I[}aDj҈ [i鯩55:'/XQ#gzJ!(nd֟ʭ/ p ` g)XuLb-_( %̺80n"y㮋W-)4gan-2"S˺3囟$BZstnF`|=f6&_Uv`Kڸe,CvK>8y3~]ܖ-:R>Y<wN.˛W! 20f,d=rdD\ؾgg(X(,4_P'h?<|91NuVI 1' )NpS_ HznB5D;pp2IԏDŽ]^VV/8bUYYacM>Lqlg9)Ƅs?@ڣZ !U ם2=Cvâ_q3H"m-'%:V$'%8-=Ue?= ? &7Y[ÔJ}-h qoSY0peO%t] Ey冣7M \m qzr*r˭VT qpDlhM멌(gwkݼ^fM?EuBfݐ\Y%p_duAڼ>v^ chd^%dT5VUjTA 0*+VAFH*j)Qҹx@i_PP"3 o$"}WY͂T5 UŭE;xmhs!b% D&AFH2gY=G!r5-_ykX)%U~$G`XHUk 6:Y]hT'fè)UXp$jTEOyy,$RʑLZ ghu9AA[[x{HlieGAAyV M$q.7md%ȼ>^JN  ixCD7Z3V/   PM ƇE/W/Яy%AA3f2 G>M+x,/^X'  bNpbM 0r':wi m"Q  gNyڒЀZ+iϠ؋UBAAn*Iղou&   7I[lf(w]yoL]ƣXTAAx sv>!i3uH[%AAςmU f lF}KAA#qf eV-X˰`۟gV]'L‡  Уsee, HFAAf]<,a">XAA:|BGZ+| AAUH;xDAA;$ƮUށ AAmbFr@AA |~0PAAq MlFr/!*  "j=0   "1 ̼9]} aPk!  AsH:ƌ  =Ϳj >AAD>(*u]3(   "_2gAO$|ys  >t^Ip 9~8  }-[̷[=q`AA[dC23|sh$"  rA'@Lv9XbhQ (.ݼqAAAAAAAAAAȾΏ`[Z%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/NexGen.png000066400000000000000000000017331403012130000162630ustar00rootroot00000000000000PNG  IHDRU?K@gAMA a cHRMz&u0`:pQ<bKGD̿ pHYs+tIME*TZIDATHՖ[HAR7]P20 e+"$"b3B2"H*\((.B JBDڅ ,|D#62=iW/=3s~3s qESK+zZ|{:G1%.\j-ʐzA<% H3[ֿ2K:EnbLF%ţ~gE]|H%D"}+%H6~Q1#XN>E" PL|̈}bA=ר|H# 2X fn E?aqע)&ŽBކr E.Ɍϸy,zQPey&^,rZdŐbfJCQmDE+`X=8Kޖ 6&(/ܑ{IJXQ렁! ~ E:Wl(>cR+Ǐ_Fz ']x _mELQCa<j$BJ\ps>|D7 $n'epb˝*V GK_C4QAM@FδFM~,N, WCPa/mwɔTT DPa^+ؠP.V糢2"nexhU$G`ETbaѡaaQ{mv`QJLKWSAK%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/Rise.png000066400000000000000000000013231403012130000157740ustar00rootroot00000000000000PNG  IHDRU%gAMA a cHRMz&u0`:pQ<$PLTE̙̙ff333f3̙̙f3vVtRNS@fbKGD tIME+Sj<IDAT8˥n0 CiJ1@;CAUvgBܪ쾇םh)t?ۉҷ%g[a,ƚB6A@pe.vbUe: 8{u]f[Ŗ'ʸxhjq,=eܰg |VDzЊv$75őֱs I&hC%%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/SiS.png000066400000000000000000000410101403012130000155650ustar00rootroot00000000000000PNG  IHDR1>gAMA a cHRMz&u0`:pQ<PLTEԾ˰yhǫۻϪÙϷʹѹe]K)gĥo\J~7q&eXMF{lVtXa@w#cƩVO=u R6pY}G|4nN.jWɮ`#̥$TtRNS@fbKGDCg btIME28@,IDATx} C:.3eme (-V[uen$BiKzl4[ξ=`!mj|Tݯ~k;ЃaJd/27biqKV⯣L*ӄm9pd~ֱdn_P"jeسBdkn)^_UV#9mY;1c<4Vq,b`ZUۓ-۫r=kE? xڱ/(.sel5keIpoa]ɀ,2L[ h > 7+O$ϩTT-e5znBN岞rnYK_&rʙ 'ܗ5ٿٸ`dmK֎"/33@ܴ-Ez9**鶕߿YYmCmK{dwDҶBaǭꥦ<׈]ROS3a2Ni\jF lp+ORzs[̱fG. #h[a??\O1'_cr4UEI;c >T79{?b\%'⚁#+z7lܒqS{f[i ||fUO>tFzŪN;f9g\MUc/Ðt_tyv[B7J9i&}`~î 3@ywD_* TZ6b?Ա;/Nw?;u_s89m.0ZDM*D&O$eY#Ʋ?\澘S1"jРIBNd5XR(-vE䫆ԔZc&@O>H;FЈܑcEΰt.YkeGj0JEGr#C{5Lt<,Sp'$`){P;%j '5fBC#rG=*GkFTBaAr/g;&ؙ^Y?"tx)l<:dA!绫Leqa($AtN,ug~XboٿHYM@`x8s}L2PШJu JQ;vTdEQv;eqpBodG)K0!il٩񰈕jzZU>v{nVྗx.؝{/,J۾4cǥϊ{].O >NǤӂ[6kl̩_J4/ d&=8+U ?|;4oZN{fb~cڝ!= Lj϶]flf?_eq⬳9M޷8J[6UiX#-56ˤ#C230E$V_'ľӁq^b[1MJ^PaRL ŽmmI4ʇiK%l4?{{=}:S.>~g=~u5HF–ua|y@SRIm`2aQN3 k*oI+ˎ ƋGϷ ب$$Wi w,k%8Qyۺ 2z MΙtOs@$e2v$9%El%޵*5~ݲZ9.yry&bXfʑ 9-ܨL0TىEq*muژ/θ 5f뮺(,QnYgG('I.2g| 1ۈ Β#U5$̝ߖGצOJًeN+gX"gwE:g.;i ίPǞY6;'8C( q.2 5J䌂s> qi}vlx}wOm)M58._  L>ks ;[.Ċ4u eeW,Cq9D>i)[MR\J=1AE/e&!5Q/WJoP &bmQ W941G;R/4۹lSك]#' 6fCXƺ~BKZ3m{5ސo-І 1\" ^yJĈ¯f.R/~gG|JO #2Epc$8T%dϡW[o& n'P= s|.8RCDL<&d-~lg6m׶b{dNwr?h3{Вn^ |M`RCׇwRNW_NS/hH&ΡfoKPKMOz N}ԤF>_IO %@0>S>m;F/*}%kSU%G}Z@_vA}ͥ#LQ4H$ D8P!zV,v2U,7=*$m6yvp_d%\˂v;n<`YoBU,%kyB|r>ٞ1SDf;(>]nЩgݿ#x d]\q(]4* Nz944P硠A M i5ͱ+PWA x`;UbK#X=U",a^Wr&T@͗Oq/6da Lěs|}*="orN~]ŏU\OceQg/T2~rG;d?V7_;OaG$ҳ콋bvg<Vlu=;H|@`9e4rf]3rdrBi+2ȁ_Hb!7^vw%t$aÌٹA::"kCi:\P\;z^.%đ\" .Q}0L(f(R>fR]J\RW9'k%q~'e Uu1[j U9Z?фlېT悖݂:qQlGtqa9XYƝGX@\1wnq(Ɏ9gtp4(A=Iqrhn){7ċ5 0e#=j:..(Jy/wMLg?~&ʧ[v~&<HMEe&ᗷ9lbglj8[CQ[ĄZ!9᪛ ;-'Ø(a>]lJxuVVO;ƭQ @qAbqC).!=N剶|YSv -Q2C|^ Áud.î&=Q;qC]b 6k(;Z~+5szL hReH狫e;r,n$Jr'kŊ|v-Lv+`E tٸ;>ոӂ1w1*di,'6+tqcŕ{7F#E 2] QtfzZCE Hh>(S\G[މ$*SRvM}ȵ6oχ .6ӸFhR,)HʜPwₓK\!;x~w>񞏒E#Os*r,/}>|g8oXlWY ʳF3Cbq5Ǘ*s6XSmꂽA}gc¿~sg>%،9!_kW餧L.Թܶg2$jY19iZuKTx-e:Tg$fth^uOXC,@OtnghYmU2@ 6Xft0 Qc*lgNRȽ?YDc"S Lat*!U~jQye),rxA]ú-vJ707JT=ҢCF$ 2m}إ3 Y5y[-b|΃ŊEQtNɭk`=yVi趝 ͈<}9m߶)-@N]CuTUѹm3nAd+q 44zŁ{`J+°9D?CN8? r rX% /G6K퀰p A% OV!`W=Qª_+~?ўzo%Ϛyqx7"S拥-N  8-!9epV岏8JϷ4Y|rdn0KFu.5eM7$ k#WfMT[J^)VG;uwԛ;Ik X;=*l.{+};*Dw%`x5P_hܐWdҕeϘǶvj<{rKۇ[΍&_J=bdE %~r oa$Wk=: IGvTMc7c~%1b%sS *gEh-,?|pQIu #K~bM̙3̭^qdss%]'7[`(5M/I򮋮 >(w<̣& +29G8xLb$wPD2k# pl#r+,[E?$^vyM YI4$>O7Fz'ESjlZ 5bS CQZ )$] sI"} M@rdӸnZQF3{oACB, e͇5]a ꉱ->DC^T$eS.y0*`9bnߴl)v]cMP[uKfV'eInzrKsQf{i].w?ܿ:=ߝ<^é?/O3ޝDܝS<ܬ߯=]%wOmrɳ/, sU .Ze9˘ yI)F23V'(U>Ma%;ks mu:(ѱnخ=ԓ #V&g]g*MnQnka n21&YS d;fLZ<1qmU"t8,FxFRK6@mŵxYɷn n4,aX>E4fAÊ0C,Hq%rZ ӟSj!ꘀu8~XuM72!2v::vIXv4,|/a#BKֻBbf,e FܒŮ p?7a1q?刁*aǚCo]{ݺ"O +'@L7ca >zyrz1SiX^#Sިҗ5^ͧq9 @ÒDcw6@Vۤf*%''H}ܒJD.7GX, ϰkXr< =W3ѫ3U [^Bu_YzpVаԺ%@p- ѪCM =uZRo=n>eSuQ:(ҕ"sNc[a24,sXM!?O{^o b5r>n61¿PV7#+)/tt#\,T_[/,Ap :R1bOU.ZYb[P[Y& zjX(+Nյ\~Ŭ|n0-CQxΨ nI-JRAXP/m /C61lEL7и%疢*8U{MԔ4o,ob[P ܒaO qF2eLWZX&!-MӸ ,".f6i̓k >^hbK2amCCcԍ6mV>=qu1IGjA_eTlR%KdcalYWD<^%p-" ^al=FGS5.Ҏhd1Շ>")v6naI'zx+*b"S{_$?c`ֈiHU8ߧҮqin)-DZh鞢]ׄ?Y%`喦*PW"{brjl3ǩU*~{fL 3}*er@-,5#x(noZPw-h;EH6 XsK_j&7z2'RGq@.K>083[9|Ba.n۷<PV<W~b % RbIhqjH9RK4`z~$ɷA1{AN_Ӑ[_IXѰ% -e^z:8\3 KPF1󖜱LcyvBPz ˹%!!Cnnj̓2%?-\0B ál^^ oIϧ95pM+jRqg"n9xe !ChLv͏,Y&"n B : P9!^'$/wr.;(1瓋Q5n d `PԈV/U-VA㳘U_sK J&p^Zhn*yF]7v(V|$)N0p(qm41QDse '&U#T ˜&>h9%Fᕏ@Rd9!4 &l\[J/K&pꖢK5TOk\ZqX!- IQ\%a K^b6cu05 m(+>N [ ˧GMh+܅tGL| gFQ 'ԡs(N_, xE$l\.}h-,g -ϱ:KLLsu7H?fzBi*N2=|;hgXץF~OTD%e-q~n" HۺQp) 7^{X4%*qeX*$1 ~կBt|"T3 " `I 1 )$=+KjD/6=- D2)eGppy$WvV~í) -Zc(¾<3~'na%(f{·ga0NhDvc8HqKv&o` ֎ڑ?SuG:<>Ls3 h]߲rrS(h fTB-;AI*BFII>J%e$RRdhb.&N9?R#|14,åg@/|Y+45ߚN}RAs4?Qvh+N&M5.XSK vPhX r~R:$[0=O TLqJT''t!>~0)fD|YE`6eӺ)?`LIEf^a#'';hX^RXfJUB Gf а&ziw֔l˦$@A%KL$;ÚNuy%塚[^0X`S}n0U)~ݴ[?enZV{zۿ}{;9{ WW0 + wI!ë'80'tK|`vH~xXJ_Ϭ$m5tǫj􇦒Y]CLSm;.gGㆥwppB̞y1z#rT"sC OWkt%spe@Wz\-c@^8%%v*bNUG'uei> AtC{X8r FuӢA޲kk!2,W(_nSZmS$Ux*7 HHTXy"\ <*y,-  xBYٛH5J?u~L8͠9d6 ū&ɻƎ*#nm&-/ݞU5Sەp H&e_XX,%uPapBDJF Z jqKXI?xPB%[!!Wn1la,3R4PzH9K 6/,w{ܲDg%{f.<ݽ".$[Dn .[\苿_.˲3!aȸɣ0ˆWI)^t6ȖyC9.ݦ@W7|)9%2 ,Aw{.8#Y%W!qaI&hRE@`S \bjneJhqC CД ҍ(a$aJ>,+{A҃ J$r M%x xbQ%.%> s2D?D1N:JfG10/~%XGJW&"8z=~ }PhtڛA Lf%F7 c%%kl#~V|sЕ([AȕQ[eD1uTMV[=c:ȪY]#M!iF%P5>[vF`w{s|_mQzwqBbtߔAvk}o f)$eR/1Jdڧ[ )#PM8+H%5,/C9J8֜![̀@l#&GG>z.vQZ%Ɠk;2$;-y K.ꑃT! 7!8|EJsL/^'N"eZlCYhdiѸeiz8An4(0GxJV0M /g}dR|jX'F%Jռ,Ӷ#aFMtK@m&؋% 읙Z4Ȉ6Cw4P/$F"xLq ;dsŚCrr7o]of:%AInO{$]̘*RӡLb*,qvQOzV'Q\z~h)y1u !XX)$4?E5i^MϒKY[*o#<-G -d@[^wѳx!rQvR;[7嫈 :g|Z:nJOndv,.X,_Dv~1*޿)d\h>{u'ghϴw 9f[cHQ!m 2N52 W+.FCn -wsa0 zmd&2N 3V>ME]T:BU1çn ?ijNȀ ֻK_b\aۃa%z6gsIuZ:[,U<-Ѻ^bܜ.@°,@#Vsj{ X"pL$&K67-#2EnoVqW,#G H ' 2p/jT,_C[ a@?"|h|ECӀ":FD]l\\g)"CR4XE:ؖKb#B &\i7R;շwnܼT5J@_SA"mJ"(dNOinD,LpuL,Ւ; ʮ&<a)$icoVe 5,yiMx*!>v 2O@ep^R]t17A(mn^[_`旐ߒ?PR~蠵R*@i |ZEB,RyayiuP 7#Dw1<1q 5н,|UF{Zh[mKX,wCBOS'OSc5q-`'*ā%\IsG٠H4 y\c #\Y‘7=6XJ.^PE+9VneDok\L~la޼bڑݰR9 Çq8pkMunu . PV|ƱriokINX;#(Or 'ܓY?thS /)EIf,>g;M + ÔmEfqE kivwww\5si##$h3T ]sjEHDdKXjR)0Dte˧&[ g9Ey:q#-Tgc5 }xg̕y%Y7J''QiZ9bHѺb|el1ZmH\hxxܲ8;VYE7wǎ_m-+fT?ӯyrC/3f͵瘧8 }MCXo嗺 ;tt3YFDyy9NO|)90dṫbBW2dPwPYHᝎZ'ktke4uLuvYqGYA֌#2RY=\m&vꑘpe+t-AuֱMRl~` |*&w-xabeX-Je4P4*zSdfu$3vQ\'_+ZBe6bFwbG쮄Ÿ%[8e>_E^;!bñRHtz?jh_*,"*\^yOk'M|^|4!{N5׺J-sLU4$XE?]|N- }1Q+rzSMIM*X<n5$57c2W:Mssot c WC[G"%4L$>RT,_pԤI&M4iҤI&M4i ?p"h%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/Transmeta.png000066400000000000000000000221531403012130000170340ustar00rootroot00000000000000PNG  IHDR^4]gAMA a cHRMz&u0`:pQ<PLTE̴{{{lll\\\TTTKKKCCC;;;$$$ ,,,444tttccc򱮷໼ĬǶҳЮѹҺԴͻ٤Գڮ9NQ $% 3E -B 2= +<+A5E /J#4yFY_&5D+< 8G-C &;3Nc 6Q.J 5L4J 9M6J1E=E5R:M:M0:% IDATx]#w]=\eL6ǖ-Ev߂%I&[|T˖ZRjE D(SA<P,(x;={&{֝n}/~rWgG>P,+BUdId/*TjFuu^լWĶ :t&źRU P1_put.2Č1.~T@74C]]+h<#\]+f4*+GWoWwXM c`0WG@ aLZoh]ҕmkTDtUQ_Rw|@kԋ@ѬH&?P50jv&ʚ6_d - FkuKA]KyY^_QWZOj P4+oC4|3G ns!^-YZ۳V&ƦݝtQuR 5zF^/ʥzFǹ%u1f]F>g[ŁPky:ѽ!^o}hhH~@C;majhŔVMc0WhF \"~!0C*֣/`UM;[j|;X TQgV)?uɑϺ'j)X6`qKy &7(Ôgʬf[m}`gcC`N C >HAH8m_Fcq85 [mAEc=_[_5(k/(*iTzfd@`u4sYӽ11[-vSwcu_K\X.\è:0c( EiFd]'1./';b'.Q9**6#{͂K@ P )*v3?"иь pfI^ߍ_#\d~sWR!-[qR0 TGTK|t7 _+-*Y/7d|;38ܙ?wjfo,=?;={k;G2@Ψz,H(^SE w5*8 i {nA}"E{IPYb.I6:L]brU2bTQ- -6v{x˘g!ů]QUZJ;)j`颢>$b@oŖCoz=o:䇥G ^=:^r@JAEUzl ~\IOx󙙽g'd39G_[k{}q] uUn B> R(!_ .,9j>W0>`)4fv-줋5A%N#0f#a'N"Yzmo{Kw^go]zmW֋ɟU,yS!rİ܇&1 yˆ h H#fBQ5.<bB_bqVOj #xvz[ v{a_snNx GQ#: {"9P -LyHaF/EB "F+nvev1NrJt"gZ*7u֮{}wLchzq_Թ_ݎV=L?k3wx7;!&K !* P@|g{!4NT683:"k&˜jiۄ]]>]5񅘬?b]Ïxgl{yj.`m޴If@ 325F/gT4t[qMPRΞe &&Ȟ`.ّvֺ$ n;1o[x㹗|z>\'R׀Y&4 iS `U-[Jҵ Q2PV k! :ax:@؅w($Zރd)!Y'':s)gV{moOҲ1R%!)ҋ[E0ɄEY7>E-(\%4d mLnh#HъXȽi/.kKOa!#A*[ߡm#- ,Wqoˣro>lg9Yٛ'i $Gք~B5"Љ.~ h0y&>3vOjcoஓKS-:$co-'f^F{>.*[xvzl5Y$jx!^ŀب"t2D. 2IN7ՅhcV`.QPwVIPb/Zc6xYlF{9?co2Ferx8OI8dVWu -#u8pp_ pIۏJ.曊uP*>omRxpr?pZ>BHz5_=y ȆRjP#iǬb8jͿ.QAmi$Slu̍XU=+3YuUyQAe8YT Ca h& 2ٓ}߂P ;go"cߤGuuA2-"G@jHO*Aftd,&7AT*)u .;c߁Vrشʊx(nP,[<0N3 =fnd=-=6" ]eT,ϐzsE cNWQ-~ꢓ̾7u9ŐCG2j zQQ]^B ƚyO<Z0o$Odh h}d"2e;;ޝsp&7/ak4=jyUײDRHfD`mIށڋd")V^8w)|sU0j+DmcI8썏M 1m{5S_=*s" 2quHy-Ye]d3( Z)7s1Ro n1Ne'{ev oF^doWh3*yzrJl@Kf%ƙ]Wk@?)j27K{;gzmP96u4+:Uh 9PbACoBP˻+VXH)ϊ\-)Sx7ŕ̥rr%"\Jמt컣=vuܶ{w[i}y&哂f=ldPOnl`ѬJca:Dq똚K r?xDL74 0$9M1\8\۞]=Y,糥ڦrt݂OsDid˵{,ܥzooD5dVLx vMuN"Ayo3|az+8Ď˜\M~ȺA5^fQ$hn9$;`Y@# 1ّ:dH. :C&IShow`ä]jKczV^/?w&H21,pkbR@ވ~OEO,[X1C txƹ\j T3rA ޓTmӍ].XcAQ_@]F=h* zd`"hTdjx]x*-Цؐw/ 6/@s dmZHf,v6nnWYV#?0ܞЁH5S;m`Rk!:7YtF8`GD5!֠gMb[7;{v&l:wZ5DQqbF:J®d]c[3=|曏h$Ok5dr5=[Y_S'/Wiw5 YEx$E5\_xO{sH9PHCvAqew5cuN3WmXب3}(7j6sf;ikH g6u@2sm>W;NGF'nIzs,2sRG1WmDjFHa˨%tTT}ftl6j* ێєiN! G=sbB}IWUhL9kTR ˗dD R e%+.tZ @kِшUM"wjjCIZdʸ:\( p6,hxlU%3'V:Gf!fzUfJ,  Y4Sq-r!&+a} T5Hդi=QV߬mU" k`9Uu'͚e^2OW2o{I |}P:zQUVnmb4 @YN~dP:B|Z_Ff͔'~O,vFx j*>Gb"X7u C"`ƿUX}NOY nI%۴Q15@FkOtڻ|E[iYcԁmP.(ZZ08,ID]N(Nx>F A~j]WK<﷜)e¤6 IOS@X^*sa5 a+I 1S 1ؼSE%.SMdl܆'E+Y)?iQ_-w%-ЙU;sy&Z!5  JT: *uē̓?~RC?{؇cssDJ2i+YčpLEuиcϔ㻽vppreGkd~eLK omhZˣtw;7*Hz<04I3 =S},wZ4h&~-_^JA.ٺRh.h3M8q%tlo:Y-UY!Y|ԃ%C/LG+vI̛T:S6Y-*Wt" j߬f)M^G^ ~&e5??w& $%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/UMC.png000066400000000000000000000176711403012130000155330ustar00rootroot00000000000000PNG  IHDRJ_gAMA a cHRMz&u0`:pQ<PLTE᛽ۇxbRK>1w"nd ]WX`g3y;~D[k}ь֣o-u[Kخi3y&pӏWw`jLtIdaǟyx tRNS@fbKGD?>c0utIME1(1FIDATx [<r* m]AUv>nz$iIGE$7s$8Xq=s,*c[{u-p}lkwIZ|X*ʕTR-w37Jhg?H,uzWJSVA7\_"++_uu9脅yoؼU[)kUHܰ3#!VW=^sYߔ{מ LLJv{Ѡ]Xo޽nڱzoOgj"KŎ25G5:T8WZW!"s#PY}U!vɗPC4-CA-9Ttڳ߯?jP,3Pg/dRbقO ,PldZ`r8.23ҿ~vP墬D? J1+&ٴmУKr,eh/ۮ@k. `CjLSWg) 0`Bn׬r!(ȁAPd&(&hg  )Շݴ[XT ‹]DZ(TͧOF%(TβJSK4춦`>esVv,) E& (ǍBfPxw0 `I Ⅰt 5m>q$rUwHP2ʱHjUBV]F+!'`ŕv"EG ՙeGd1OnaxYP7F,/&\O:}ckfҙ i -/d]cFȁYp(}zj )$>#9s3|&8@W烨Q3}OO E|Zظ[&x6DYNNZ %(z $Iݧ ZMtMA2Zז;ME@,x>%G֚O3}ho6=4y"i(;eIIːLES@>$ [W3}bFWi%(ʃ IԴX:o)2C(ddn_HAQH+-K~j@ #\lٸ4D?2RP.qN5&$Q1;bң)YJѧd:ȋOn BAiЍ#oӏ ^ @PC0q| ^CJN/\XxIqA [BqAv"Ll| CSP P_+ތ[jP/uc)މSLf(@QWGؽRzCޫ]etnGH.k(/9*Y_/veqéVʺ{ϭ7+\|s\뼾̷y.5JAWHX E)(h#QLT(D zs`O>_#Biq:QT&SPhEr g΂O(iPqOeL_e'PlV0VKO.;fjR!BZ2UCP~x`Mx҆bxSbfq^ԏBׯSԱ\-򒙳#BƧ'[S59y5j4=/.u+j CQ|QF @6xP"4hT4 HW?jvO OQ B>qfRFI+ q{>Ec$ mp5_R*-Ʌ"(>;)jSdfZZGEǕ+Aq THjM9((m{F;I{p,~σ(F?̻|iJgMEub**712ni sZβD}Y鄚BLDO'xPhtB U/ P_ W @HwSҩѼsgu1FIh|8շm]atԡ֧L$[hoT!& /Eq.7B)n1Iz@!W$SE ,/߳'!YɄy>x0Lpb8"L4 fA  c+[PSDڦ< F#Tg 6:}L(4ǫm K:>* _D~2RB{[ E>_ L&\l`-ej#q|C8&y&ڝw8ť?>O08$ EBO%: O 8 fv% E3E Dy*}k y(iDÈl8S* H;*O^AmSOSL=0g>-wrO.n@<9>)b^`S(+;iKZKj=ԁA CAhAU֑=E!(ͧ"G;]S81Fs'R3~-ŅܥTP8PXH?|ѧma/Xسj)~`hi7fzя(,LƇu pHf#iib]~ b)m~OVS3)wF"VZ$u7@ ?yB_OS@"F,sbXr=vEOdKKS$d KGOfGmZE؄UP3bہ}̐Lyg7L=lA QOղbBm+'WPGUۃu:p 1(yy?T2]z =)c E i;no0|v<: @0dTk)awkk>JTZ` s.#C!PHOԵOS{F]Ax4 ;(a%Eb-DpkX* rGQWpBN\`3 ?aĞ詪hT=,BD9'  pJ.GBXwX;hXEPDw'E[# )@DQP)C4Zr\ږEsҬ)&y:5P+̻"v#'`1(=>b_M 9sΫxS'CC_ P%ɾؤ!bjcp;$?@!FmٗbYT>BcpxZ|* _ ]܈mM˲ZEI{lAJ_d|Zȡj %7{-Dq. ,˲E#.NJQ@򏹉LxaIZ苹G%2eUPl(Ȇ)(BORPN>!<|x6NjHGfR l(Ԫut*HP36p) NWk ^tNV:7ϻ+ ںNG\.(R]}ҏ9I_ W%u%5A@|Z&h;I&3oY~zti':) {FoT2GoO'dRDG"Y64Oq5 J* C:i*%0|x.++8\/UGӷ֤+|iJbq` sBBv? +y(Gi Jê:@A8KI {a$Mjj/ yOF;Ud??0$H1; E@U |Je!c^S΅p,aiՖ;TՌfF)$8So-Ql*6IHFPd9O:4ԫ*)6T1=RH6hџ-cX(xN|(֯;h5(՜s934P߁. d7֏yb^Es䪋jnY@bqSu<Xi4/'|m5 ^d4n.UI4XsPdB4b%NM_S5Mlp>/E~, ~jue^*o*+P8{? "O}Bp- 0/2B Mz4H>)K-3CoGe$x,?;"g`&,b%T5q kdvkhATUC"5  $hpfW_4(R{^Q$pVޫ䫌ofH{AD$ǐݵ@-uD ȻPW `Aҹ_n@=4"M<RzB a?W TgcTV*(O{"- /W˿g-xAȉFdա@8#z be)OE̊h!DOϦ!|&HRSD]8-M]-W/0%w<Ѡer>v.џB䳍E%nznjæbYH&b;N^%R2EX<{CW!>h@yuՎ~}3pZvAGJ1{F._0y3}<\xJUblv 78Rz>zYkT2eyou6ζ.$i~3yv\UOs]*g?o1nv=Yób=,C'ny-ebv~3}k\^ ӻs~6i.O~5rVȠLä9pyqs"bs47l6ے~wKSb~^u:eۛz\ao[L_.h4 Fr-]wNAR%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/logos/Unknown.png000066400000000000000000000443141403012130000165400ustar00rootroot00000000000000PNG  IHDR>agAMA a cHRMz&u0`:pQ<bKGDGIDATxڕieuϽnt@ $DHIQj2EjHI5X%۪T,c)rTJS.%UŠ\eZI$˦Es&%N`A< t{^+?{y;j9{o}[wƗ b&(i NkԇҾl_/}!$@oM'&'ȏP܋_vP}|z4DfO "}{,@a=~<`?=y6 S<݇$B$7>)FfwRv'fsL~>Wemc""E_G?~Ǐw 6pqwW߃@}z2"00!BҺ b>mzB#csa?AܮDwPv(ТR}3Meh^7U#-s@€rc z³< g;53#"dH!:~7=xo!_ʻ>E`"aT!Dr{Z&-R\0= ~y]p)!jO @{8vL"p?P0a-~2~6uEpmw?iϿ >|$9Z@Zc^&͓6̆Jb ^!iWnұF|Csȯ\B7HOE1A̹oK@? DH`ET'd.E2}O5p[4*nv?'tx⯿W3x;_7_HRD<@q9xM7j2h &S^ `;Â#B+(&j*KG@@5| @XQazхz,"XPAAzSwHX'D@2b4" (!28@' Y aI2(Mgs\$NƷW"vpʻ]Ql]\xfFIڹ% !Bq~K;YH 5EjdA[BeD!g8A1> ؤ Fk `dl`} źIsHKBIcpI F!wGR>G4 'W.EPs1[pˍ7bkĀ]@ b$!L1""! zS>@.hd!,E@ L 9A;qMAX/ 9ʳ0"Vzd+!a--IӼFZ(D*ӧ݇C>݋ BhQHT1D:fxЃ65s% ,6[?ކ^r0s ^OI4r~9G[p*d6= 6use`T; qo۹ޥDF"fF BtOD;qI g?O~n|33i#olbm%Q"z<0l]|Kq6c-T)¦PT9`^:~FD)M.9ݩ.BY9 /%i}Lx "XJ,ڍV1"(aB$K;5\џˆ)?CH9 b ySZJ\[( 㐏fS@yEY@ `}A{f* 7pye7I(jȨrRw(( ᷾~Νø^("ˍjn(L\\1c`۴Ԏ9l̆3VKsԲ.tgF}aZ{`QHבz[q?.sN-I= no^z?…0k=K1#9_XMMݔ_nZ==t`PuhvY$A|Gq%@&r٨ԨpL"]$B; q0 BD@ na4b !XˍMy_ɘ#uIE=+;.7z+Rb q#GDD-_sM<(i}~AzLlу A4T=gDE+tT2 J9H)a5p0 irb}[[[xk_zܽOf =;DIZXx㝷w|=l$Rkמ)! ;$5IOICƊ h37E]*/H[]0IR<96K:_dO8.}1qM7ck8hT8zjހO鯱Zg.vjٖn.U kz/lC$U뮿QrBHʨQeʑV4+Kf|TII&irҢX7,B%}FQ~bBTR@"⢈XGiD W ;3OW(,%?y^WS__3n>52i|9Rmn \CP._{z&)%ʕ1FPEF^^vCmTolk4vJfRԊVsz]J;6𚉊-i)%5q#:zgq1\t W]ub ,gm;:d*p >9kq.MJ#81%-/uX"P{1 /yUDBfSsWr?T0'`9XpX,Y z;hJ Z C,H)eH|K^rRZ RI*w6iLmA*9UH4F 1Ga !Z_*85.R/KǙoihb5kǫ0#PMם@58nNs)u [ǰ9&=W og9}NfU7-E,K$ X(3w̹$ĩt.|p./PwL?P(K2 -2W1 cpRb\JjfD>'e J"C4VCDhTW0MvAY+7PȜN-w%hRvRAaBJf!el.ԬZ  T,hMJ:_H!o%¥Ě9ŕɅ9_ʜrĐðh0q3i`Zn E *hhLf )93W߆F?{<4|ɋ)€' ^2j8S`e~VMGF]5OI k"Ea+ BrxDbR}&s%cFaԽ_avf^8yeD%9|rFbZ$IqxRkH+2*:!iE5# ɾڍ#v XUئQb__ϰ]?gTb>:[2E8 t(_͐d2C@'F#w%%E"02Tj<{FVz004=4\IC /uiKY2ԴZ͝D%o&%p{BUJq #+ln,[j zQp!nTm;>+NPD8H^*"ǂ |IJE:vTŠnPp]Mb8U) (.c.JbHCvY4,NQFO]dcJؕP3,'FG_*P›[ГKĈW~(r̚6*9{휩dMl^jTٔG4qpjdRb r*ڎvf PT+ʑ4q,tXRe撶!NNjbPP1%)~ jK'Wʭk;6Puq2yoi $DecDx@FI_$Tf'Ie3\k§Dʂz81Ŗi=h}8bJ\;;-R'/zJJ5L\3?/ dLkKGh/LQ.6MѽS-u b2f1MX,?c8 0S˫O"qFcT*(Jk7?XH5WcVڨ;* {"3e4X摕 z}[t¹VVΦ7,lʢ\-,rFUT#3W]_ѫws.?)p7%5Iu=Ww V?HӶu~a> S/eR (05mUX|1N^}g??zG;P@dB8܀F#qɹjX;j(#ΜV&=LqlCT ^ٔF2]eMW6T0h|sF<.~ɯ;PO8Դ}1HYwcX7+gn,)KVAzc@ s{EM"dXV8V.0؋\/bt|Ua"g+혹uаr=J^pϏ *;|5+Թ(ĥ}>pM-Ͻ6}6 <,ݷ%| 5 RiZE{ Ptə `XĀ}^;9 Ua\ao]|Կ?t,ׯ,q~lҖM6']ܨss퉦>?Oi< }nkQO2JqEPoӋyYEdKb;kwS单tBף{qG~uwsmkCH NWC)On#bhJ{rpcP9+"u% %Irmek HrQ )bgWCR12#$v46 _)E{[[,Q5Q(=WPyw>nv]#*p,ҥ3q_;q1-Z(YFFnc@hQLH^U 7^L [#&Wl?LɤgvרB`7 (AŠUJ'Us>fCu7iӫ]tf/rE2xU.i̥_P+&y `X"}{EdXrːKoȵ|Ϸkwz}N"sXwK' vዯa 8XD6M&x*GS X@XK4玁acjSು`P N$b?iҋA3i4t!&:@2WHvN<ѡ~:VDKl☒:CA(GK)Gjpm,9,_kۚ:Wi"g1..z}9m!( =.ecQKCb{YR OM+k",H("F~N" ^S.5۽lT2TTm{(JiV!ʿmZtYRngJ'W-X-f\Wwۡu.a2ؘF<"ewx˛f+wb^e3 tC~˳&6v\Cn)JK*TT$ l/0Yھ?]M zˊ2U~:j:W+KJqIrC\ Nް>n8VOGە䀠amw&9>E-C-mW"D@V +89FL'! W$UJQ(4їE{>Ydû'N&Q/Ddx29z<ٔRm*y¦Àf4,Z=U50cP]V1iٴ] FZ^sl[ۖUc@Z<${wOe9UF/6*BA+qTbt_5Sdd/G)NXbdb-ܲPͤҭPtҾ)<{ߛt(jØyPІQW4." SFHkVA}4^ l/1) q9,=糃ZͻN-qJ_[L›LMoW̍A[3ZҼtHl5#E&JrF*j H0ft+9yKs@lN[7FO{mS3lGHh~R.w͊;Xڹr>륓N&R鼕"v$҆>9 }oeӆW:ti,5FpY|֍JGr}J3lLb^}#n~`N 4%Ɣvo%+V+R9`2䁊%o90}j`bI5 5c.L[NBZ4Qu`qIeMdFң9\Iw]$g`K<:QP,xՃ? th "&ZBT<@$ZGwI8+Z'kKabhN>onr+x%\i2IW̢阳yeKbo\:X:~h(DP#)Ts~;ޮsp-b(-6o+ Ӊ{"UHuQ{^sPi[BE{rСt鼅\RŨ2P zn,XYd%x8s+pa"4B(YƁ UUJ협܌L:kW""S B)bmyT2Ru63j;Wc3a3-+ оz=J6'1͞ Ě:O27f)N,܁15h"Sq[F4[Px; Bb9u$*"M2VW|W/nh%7ᡜg]gHo^n1 n(1v^i -İwkX eE(Z2Vs9E Ra)8f!oXNוOA BL0VB6YiB'WPy "Oy|ɤ{` 6( d,9zi1liԉ4® )FΦ !T65ibjGRzݹc-o|hr>@9L40096f;r@E#JփpV6R3ðn|1$%Dx+eDo);R( u^+\}N,5=-54DדJ)ށlD>~~˜<<dQP뻔CZ¨a>gf%TF>K@Aw'ټ]@a ͙ZR*W װ_L=y3tYpYNOΞ-[C00Oe]<P80ĥr >L=.]s R&ӏUs*Qz Ot" 1tn^|ϛKd&P2x Ʋ9/nx(65aѨ̬EqM *]z RΞW\PiXC?QҚGR[F \뉌l ]@viܸDiEk7Sd5Y F:);N KL=*BuNC &a̩vbs<,2 znLJIK_EV_D!C#D jɛwT#UHL86& 2$e˹Ѯ]"r6>4zl(c8E/!"Qnm( WLãAN#zBAҌ7LOkҼjY(hnWz҄aɾ8dI1IfXN؄(FN~6{;LaIFÎӣRn$?dVw??!R ~W'T`SHTJEQإ+00EEQe<[j Y ƈ3^pzC]sw눭nXPT #\Pg@Aea@gK#M0&2IiEh&:xL;C:uZg]_C6055C!i(xal?gpjF(bx="mD֥Q>aA&+tV+g7:o2> VЪ0E"g;o{um *F-7Ҍ+d7wC&FM퐮.ί@,VG ;:ʡmP xJQG~ւ"Jّ2LQՌia3fY7-l7b /i?&^k e1OL_7U0(Q:/LRUv1Pw)Z6t@#O:H׉䉔5Ј* E%- hwΠ_Lk+&Aمގr}b 5>`A@ ]Έ/<%,9p' ՒX(`1 SߏwHt8ĞI:7Y,KXݎcdŘuJRG[nGu2 ķ^wS]yde#Bh.!EѴU Ѵ@1|!2eݝx!4\~TI<60Hj":\]m\}ުsmG{|%4HUO@[VLX.]z8l'kfQd0!y4gj[G-܂˷YdՐVmlس@Ia1Ҥ$L(_d>&M77ڂe*4b23PuL$T)▊.zJ][ڦP:e7X;v/mSzAWw(sa:^͜~l agd١k ,W'vGɢmp[MmD}-i79QVf@AbP<lv=l6RTPnwfS+E#",5W{MġT]ˍ݀e?Դm-.V=naڈb1lbΝךHny6JU훫h` 77+8bggw(;*6)kB1G|̳,%#yeK+[S&kM,CXNMDǃ^W}!5y*66}_G]NX*yK!V&Yhy 1bXlrdc=x`V>]9)z& /"gPc in Ws6ͩ$fInBթ%%-5r<< ( HSTYTe1ykW&HՖ(¦3Z0P<>4nu D57eO-ZSἸtw)9Ad[hb1A5(Tz)1)^i\cgƪ&=4 L%3eah[xJz ꬻ:fU\%Eysi ٷ^.ζE̒jT(jR1 dmm2;ʃQdxkBA]\̐rDƑpu7jK X!HNŐ  Jηr(,+d2KsT)L!,Ky#fpޣXdv6f4ԅW/&w$\@Ɂ 3Zģ!t@v_]1 ObWWԋgB+K̈6H3E&tʁAnX\{B2ntI' tb'KPd12r*@Tui+]4X#W__,W+ I;'cEөZѯ\G.\!~ۤwӧz.$rBFThR ̊'%)N G#Pk5O lRq{^^p=۹tP捐u^@DfȉB"*bbncȱ&ڹjBmꠙ!UA"F"dZ7sr^dۻJ S lO˜c3[JCMa'0?f|﫾?No\CbSܘ7J6 e -kΗ֞ LD@Վm7/y?;L@v]g{3S*ZUm2(eFi\AUVWuPC,{MwgO=.WEΖjIXwXr @G })>ͤukTX)t:g"P2c#Xk$ҹ& H>PhZe!RxJc>s%cN57DUldgbv4̵7܄;[G5Lfգ(3ArhSQTb -"'7p$M6툩Uvo-h~~*Lkdr]L ĬZ٦c.y@AAȩ:egDAƱk {A|K_2R2TPlbm0ąl6>Wb),"k E|r-m@fߊj;72+Ij<$v)er20!DhS0Zy9?w+525dZd8}^ Y /x+7[G])JP :fiS?K`v k2n!s@*Ceb\?Y:^}'vU bWr(]QcY5․^!Du™NP-USB- 6nL QJcXǣm_ xv/m_cɐCœmɝycOBQcL#*߬%O4Ri(GwƒgaS%!VQE! $6l̴Z/=Zhv19`R8S!m@< =2^to=C-b*uLV;; $䇆C4{?w~9I[ :MnOP,X;urYHs1Bl@Kg!jM@2FQրcLɓet02${~Ӹ}nxOx- )݆'?$p竗Ms[]ɺiV`DGF:jK8IVrï+YE@(NA!"^BG605 ٩}z&WA̕}3ƢSY#n}kcwǮ q 63M6U0J Xl9(K؊k}Wj"?By.33{#FUe#4ZhQ瑹GTGb_cKb,\g>\8@85ɦ.X[BA&ͅ ͣUڋ^'p[s'2yՋ9YAgq8)T줾ABg6JhI،rPhR8s(;.l1hQ2هG _;x3|\")Wxa!c#;#qh:HE˴IfeX#=p @1 ذ63-c)P,btXA$k4 2sڤeZȍVOF>81n6՞Xo}ᣟs_N* 2:6/bihk+V+ewqr=z!D1]Uw Ճm쌭q_~[`< AEXo-BysҢDKH–uOHHcP[`%̓XpMQ̤nAď <0DX x'!DXڼWXVX )2 Ckq1̚m plN T*c]4NQWZލKTDQ̻bq⒠)Wu m$Ɍ K)Vq;sF?׊.}^\i9jn,Ea ΟCʯ ;{{xi;;ؾt{}} Nc6ӥg:vPX ^%ƩIUCQS@1Vss|s(GaA|@,0͛yVMT\LR=fsH Jڿ]J#4`{niqYoFxc? "tG 3{_WUrL~Xc6% ZtA ͆C@ v"d"B"LMPrX%۱.`яūkDЕY'u@3,@GX9:hí䘠JKF|l=v?4=!F$N0{0n.ޯ~vV\wZ|{MU_`*qX,8qI=v<)0:^̼^H3E[j?Y19 .TQ0Bs<' l`F6"HJx˿񛿁cbf!3:碵"B^qҲp_ak/m8,@q@#UGZa[nM`xE 8̣`5zzU)B0W5.IUfMnq( rvҬY(>gĻoc1,b-1ЄVLFɔtc ǔZmj(78.%aب<|ħqI{" _">sdx6@̀ O%6"?\} t#ȉE:򍌃Hk,#cSBXCvRwG͕`K(cH@NR*뽡x6#Xnnm*d^(HxW=*PHABhG! jr#U 4~/pwF6̈́ZK_uz[a 6oT7L7-A["= ~߃Q+QDW0g^iE8"+3!d NX*;tNF`QNc32 21bow̙D{j3Kb}U'#@dv\a@?gnP\j턭z_G?In<ɗ'{ _% WX ꔬ“Ou7Μ;G\։WjF*RAs-szV ΜџK 5,OSSQ:' " eXS=tY,hvvp񢗼MϿ Ddi0J-_eLkV{p` Ic1^v9|[xwޅ/?>iy8#>ѯc n8^y뭸7kN`XERMJ  r3 XOFv_O>6 U bdr5 H X(Z.mh!$DŽ_7acŦ4 ]d2qB aj sxS7OQvvE7`G?!\ġG_NgpĎ%o5pRDL1ӜA˖Bމ)AR Oڛ_Ǿs7K_$9mfώZIjICR, #x7z'Ǩ?#`EGd' b8=8(OҢ28&b\b}>rwy+cy@4,7cEw=ywdF#6QeTRkT)]P c8)TyyZbEZ+A4`8p58qË bP3Aj"2U_$+E;u<(2ycOVYD;eP'Gݵgtc%$21يP:.uFI5>rAO8+8 zU(K8U p-.Gu!=z5`ExN"xUmLG0Ci@P]+KTٍ^ ,̰Gj.V.Tݨ"N/U)xe?.mI8)^YoП~,7ŭoA' _?/؍'+3/ZߩӵPNS :lyӲ|Ɂ`^݉>;e_՝(uADx/7x-ݎµ/| %O'0G_MQ.~W|=%~SocO<~ gpY[˓)1!:zqB}< X]BǴTS=2fU-Se!"l,5:S{l{ 2=߷O( RZ-<~-8nm;Iϟ= ? <4°g`X,q9lln駞޹g먿{~񖷼D =V@蓂7@ò-RG 9y$?>*ͯ:{ Ї[WONc ^Ti85%tEXtdate:create2020-05-17T22:00:42+00:00ڮK%tEXtdate:modify2020-05-17T22:00:42+00:00IENDB`CPU-X-4.2.0/data/org.cpu-x-daemon.policy.in000066400000000000000000000013551403012130000201570ustar00rootroot00000000000000 cpu-x The CPU-X Project https://x0rg.github.io/CPU-X/ Run CPU-X daemon Authentication is required to run CPU-X daemon. auth_admin auth_admin auth_admin @DAEMON_PATH@ CPU-X-4.2.0/data/org.cpu-x.appdata.xml000066400000000000000000000023051403012130000172170ustar00rootroot00000000000000 org.cpu-x CC0-1.0 GPL-3.0+ CPU-X

Gathers information on CPU, motherboard and more

CPU-X is a Free software that gathers information on CPU, motherboard and more. CPU-X is similar to CPU-Z (Windows), but CPU-X is a Free and Open Source software designed for GNU/Linux; also, it works on *BSD. This software is written in C and built with CMake tool. It can be used in graphical mode by using GTK or in text-based mode by using NCurses. A dump mode is present from command line.

cpu-x.desktop https://x0rg.github.io/CPU-X/ https://github.com/X0rg/CPU-X/issues https://hosted.weblate.org/engage/cpu-x/ https://raw.githubusercontent.com/wiki/X0rg/CPU-X/gallery/screenshots/v4.0.0_CPU_light.png cpu-x.desktop CPU-X-4.2.0/data/org.cpu-x.gschema.xml000066400000000000000000000042141403012130000172150ustar00rootroot00000000000000 1 Refresh time Set custom time between two refreshes 'auto' Theme Change GUI theme color scheme 'cpu' Default tab Set default tab 0 Default CPU core Select CPU core to monitor 0 Default cache test Set custom bandwidth test for CPU caches speed 0 Default active graphic card Select graphic card to monitor false Print CPUID values in decimal Avoid to print CPUID values in hexadecimal false Always start daemon Start and connect to daemon CPU-X-4.2.0/po/000077500000000000000000000000001403012130000127475ustar00rootroot00000000000000CPU-X-4.2.0/po/CMakeLists.txt000066400000000000000000000021351403012130000155100ustar00rootroot00000000000000project(po LANGUAGES NONE ) ### INTERNATIONALIZATION TARGETS # PO files set(pot_file ${CMAKE_PROJECT_NAME}.pot) file(GLOB po_files *.po ) if(GETTEXT_FOUND) set(GETTEXT_FOUND ON PARENT_SCOPE) include(gettext_create_translations) add_custom_target(genpot COMMAND xgettext --language=C --keyword=_ --keyword=N_ --indent --add-comments=TRANSLATORS: --package-name=${CMAKE_PROJECT_NAME} --package-version=${PROJECT_VERSION} --default-domain=${CMAKE_PROJECT_NAME} --msgid-bugs-address=https://github.com/X0rg/CPU-X/issues --copyright-holder=Xorg --output-dir=${CMAKE_CURRENT_SOURCE_DIR} --output=${pot_file} --directory="../src" --from-code="utf-8" "*.c" "cpu-x.h" COMMAND sed --in-place "s/SOME DESCRIPTIVE TITLE./CPU-X translations template/" "${CMAKE_CURRENT_SOURCE_DIR}/${pot_file}" COMMAND sed --in-place "s/\\(C\\) YEAR/© 2014-2021/" "${CMAKE_CURRENT_SOURCE_DIR}/${pot_file}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src ) GETTEXT_CONVERT_TRANSLATIONS(${pot_file} ALL ${po_files}) else(GETTEXT_FOUND) set(GETTEXT_FOUND OFF PARENT_SCOPE) endif(GETTEXT_FOUND) CPU-X-4.2.0/po/ar.po000066400000000000000000000630241403012130000137160ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Hatem Ghouthi , 2019. # Allan Nordhøy , 2019. # mohammadA , 2019. # anonymous , 2020. # Rex_sa , 2020. # Гринько Владимир , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-11-25 18:29+0000\n" "Last-Translator: Гринько Владимир \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 4.4-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "ايجاد معلومات المعالج" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "لا يمكن ايجاد المعالج في قاعدة البيانات ==>%s, model: %i, ext. model: %i, " "ext. family: %i" #: core.c:249 #, fuzzy, c-format #| msgid "%d x %d KB, %d-way" msgid "%d x %d %s, %d-way" msgstr "%d س%d كب ، %d -مسار" #: core.c:250 #, fuzzy, c-format #| msgid "%d MB, %d-way" msgid "%d %s, %d-way" msgstr "%d مب ، %d -مسار" #: core.c:251 #, fuzzy, c-format #| msgid "%s associative, %d-byte line size" msgid "%s associative, %d-%s line size" msgstr "%s ترابطي ،%d-بايت حجم المسار" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "استدعاء libcpuid لاسترجاع البيانات الثابتة" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "تعذر استدعاء libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "استدعاء libcpuid لاسترجاع البيانات الديناميكية" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "استدعاء ليبكبويد لاسترداد قيم ثابتة MSR وحدة المعالجة المركزية" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "استدعاء ليبكبويد لاسترداد قيم ديناميكية MSR وحدة المعالجة المركزية" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "حساب مضاعفات وحدة المعالجة المركزية" #: core.c:521 msgid "Calling dmidecode" msgstr "استدعاء دميديكودي" #: core.c:554 msgid "Calculating CPU usage" msgstr "حساب استخدام وحدة المعالجة المركزية" #: core.c:605 msgid "Calling bandwidth" msgstr "عرض النطاق الترددي الاتصال" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "تعريف وحدة معالجة الرسوميات غير معروف: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "تعريف وحدة معالجة الرسوميات غير معروف: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "تعذر استدعاء libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "العثور على الأجهزة" #: core.c:829 #, fuzzy, c-format #| msgid "Skip devices search (need to be root)" msgid "Skip devices search (wrong permissions on %s device)" msgstr "تخطي البحث عن الأجهزة (تحتاج إلى صلاحيات الروت)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "بائع وحدة معالج البيانات غير معروف: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "لم يعثر على بائع الرقائق والنوع" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "تعذر إيجاد بائع بطاقة الرسوميات ونوعها" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "جارٍ استرداد سرعات GPU" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, fuzzy, c-format #| msgid "Driver for GPU %i doesn't report frequencies" msgid "Driver for GPU %u doesn't report frequencies" msgstr "تعريف وحدة معالجة الرسوميات %i لا يبلغ عن الترددات" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "فشل في استرداد سرعات GPU" #: core.c:1205 msgid "Identifying running system" msgstr "يتعرف على النظام الشغَّال" #: core.c:1208 msgid "failed to identify running system" msgstr "تعذر التعرف على النظام الشغَّال" #: core.c:1249 msgid "Calling libprocps" msgstr "يستدعي libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "يستدعي libstatgrab" #: core.c:1310 #, fuzzy, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i أيام، %i ساعات، %i دقيقة، %i ثانية" #: core.c:1366 msgid "Updating benchmark status" msgstr "تحديث حالة إختبار الأداء" #: core.c:1367 tui_ncurses.c:824 #, fuzzy, c-format msgid "%u mins" msgstr "%u دقيقة" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "غير نَشِط" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "لم يبدأ" #: core.c:1380 msgid "Active" msgstr "نشط" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u ساعة متبقية)" #: core.c:1387 #, fuzzy, c-format msgid "(%u minutes left)" msgstr "(%u دقيقة متبقية)" #: core.c:1389 #, fuzzy, c-format msgid "(%u seconds left)" msgstr "(%u ثانية متبقية)" #: core.c:1394 #, fuzzy, c-format msgid "in %u hours" msgstr "في %u ساعة" #: core.c:1396 #, fuzzy, c-format msgid "in %u minutes" msgstr "في %u دقيقة" #: core.c:1398 #, fuzzy, c-format msgid "in %u seconds" msgstr "في %u ثانية" #: core.c:1414 msgid "Starting benchmark" msgstr "بدء اختبار الأداء" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "حدث خطأ ما أثناء بدء اختبار الأداء" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "لا يمكن ايجاد المعالج في قاعدة البيانات ==>%s, model: %i, ext. model: %i, " "ext. family: %i" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 #, fuzzy #| msgid "Starting GTK GUI..." msgid "Starting GTK GUI…" msgstr "يبدأ الواجهة الرسومية GTK..." #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "تعذَّر استيراد الواجهة الرسومية في GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "النواة %i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "البائع" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "الفولتية" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "العائلة" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "الطراز" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "الحرارة." #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "سرعة النواة" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "سرعة الناقل" #: main.c:78 main.c:155 msgid "Usage" msgstr "الاستخدام" #: main.c:80 msgid "Cache" msgstr "الخبيئة" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "اللوحة الأم" #: main.c:104 msgid "Manufacturer" msgstr "الصانع" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "البيوس" #: main.c:109 msgid "Brand" msgstr "العلامة" #: main.c:110 msgid "Version" msgstr "الإصدار" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "حجم الروم" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "الذاكرة" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "النظام" #: main.c:128 msgid "Operating System" msgstr "نظام التشغيل" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "التوزيعة" #: main.c:131 msgid "Hostname" msgstr "اسم المضيف" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "المصرِّف" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "الإبدال" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "الإصدار" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "درجة الحرارة" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "الفولتية" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "الذاكرة" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "المدة" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s هو برمجية حرَّة تجمع معلومات عن وحدة\n" "المعالجة المركزية واللوحة الأم وغيرها." #: main.c:185 #, c-format msgid "Version %s" msgstr "إصدار %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "المؤلف: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "الموقع: %s" #: main.c:189 msgid "License" msgstr "الرخصة" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "توزع هذه البرمجية وفق بنود %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "لا يأتي هذا البرنامج بأي ضمان مطلقًا" #: main.c:265 #, fuzzy #| msgid "Dumping data..." msgid "Dumping data…" msgstr "يطرح البيانات..." #: main.c:308 msgid "Freeing memory" msgstr "يحرر الذاكرة" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "ابدأ واجهة رسومية (GUI) (المبدئي)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "ابدأ واجهة نصية (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "اطرح كل البيانات في الخرج القياسي واخرج" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "failed to find graphic card driver (%s)" msgid "Select default graphic card (integer)" msgstr "تعذر العثور على تعريف بطاقة الرسومات (%s)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "خرج تشخيصي" #: main.c:348 msgid "Print help and exit" msgstr "اطبع المساعدة واخرج" #: main.c:349 msgid "Print version and exit" msgstr "اطبع النسخة واخرج" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "عطِّل الخرج الملون" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "اطبع البيانات لنسخها في قضية" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "الاستخدام: %s DISPLAY [OPTIONS]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "متغيرات البيئة المؤثرة:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "هذه البرمجية حرة: لك الحق في تغييرها وتوزيعها." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "انظر رخصة%s : <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "تعذر استدعاء libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 #, fuzzy #| msgid "Starting NCurses TUI..." msgid "Starting NCurses TUI…" msgstr "يبدأ NCurses TUI..." #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "اضغط 'h' لرؤية المساعدة.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' key to see this help." msgstr "اضغط 'h' لرؤية المساعدة.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'q' key to exit." msgstr "اضغط 'h' لرؤية المساعدة.\n" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 #, fuzzy #| msgid "Cache" msgid "Caches tab:" msgstr "الخبيئة" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press any key to exit this help." msgstr "اضغط 'h' لرؤية المساعدة.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "لا يمكن تحديد الذاكرة" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "الخروج %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "تجاهل فتح CPU msr (يحتاج روت)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "فشل في فتح وحدة المعالجة المركزية MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "تخطي الدعوة إلى دميديكودي (تحتاج إلى أن يكون الجذر)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "فشل في تخصيص الذاكرة دميديكودي" #~ msgid "failed to call dmidecode" #~ msgstr "فشل استدعاء دميديكودي" #~ msgid "Finding graphic card driver" #~ msgstr "يبحث عن تعريف بطاقة الرسومات" #~ msgid "(%s driver)" #~ msgstr "(تعريف %s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "إسترجاع درجة حرارة المعالج" #~ msgid "Off" #~ msgstr "مُطفأ" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "تعذر جلب درجة حرارة وحدة معالجة الرسوميات" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "تخطي بعض قيم بطاقة الرسوميات (تحتاج إلى صلاحيات الروت)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "فشلت عملية حجز الذاكرة من أجل اختبار الأداء" #~ msgid "Root privileges are required to work properly" #~ msgstr "تحتاج امتيازات الجذر للعمل كما ينبغي" #~ msgid "Some information will not be retrievable" #~ msgstr "قد لا تستطيع جلب بعض المعلومات" #~ msgid "Ignore" #~ msgstr "تجاهل" #~ msgid "Run as root" #~ msgstr "شغَّل بحساب الجذر" #~ msgid "A new version of %s is available!" #~ msgstr "النسخة الجديدة %s متاحة!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "أتريد تحديث %s إلى الإصدارة %s بعد الخروج؟\n" #~ "النسخة الجديدة قد تمحو هذا الملف الثنائي (%s)." #~ msgid "Not now" #~ msgstr "ليس الآن" #~ msgid "Update" #~ msgstr "حدِّث" #~ msgid "Checking on Internet for a new version..." #~ msgstr "يلتمس نسخة جديدة في الشابكة..." #~ msgid "failed to open a Curl session" #~ msgstr "تعذر فتح جلسة Curl" #~ msgid "(version %s is available)" #~ msgstr "(الإصدار %s متاح)" #~ msgid "No new version available" #~ msgstr "لا إصدار جديد متاح" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "حدث خطأ أثناء استخراج الأرشيف %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "النفاذ إلى الشبكة معطل بمتغير بيئة (أسند قيمة موجبة إلى CPUX_NETWORK " #~ "لتفعيله)" #~ msgid "failed to open %s archive for writing" #~ msgstr "تعذر فتح الأرشيف %s للكتابة" #~ msgid "Downloading new version..." #~ msgstr "ينزل الإصدار الجديد..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "تعذر تنزيل الأرشيف %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "يستخرج الإصدار الجديد..." #~ msgid "Applying new version..." #~ msgstr "يطبق الإصدار الجديد..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "حدث خطأ أثناء حذف الملفات وتغيير اسمها" #~ msgid "Update successful!" #~ msgstr "نجح التحديث!" #~ msgid "Temporarily disable network support" #~ msgstr "عطِّل دعم الشبكة مؤقتا" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "مبني على %s، %s (مع %s %s على %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "عذرًا، فلا يمكننا تحديث %s: نسخة 32 بتة المحمولة لم تعد مدعومة." CPU-X-4.2.0/po/ber.po000066400000000000000000000375271403012130000140750ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Hakim Oubouali , 2020. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: ber\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/cpu-x.pot000066400000000000000000000412351403012130000145340ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "Project-Id-Version: cpu-x \n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\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" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "Your CPU is not present in the database ==> %s, model: %i, ext. " "model: %i, ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|" "v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has " "crashed.%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "FATAL ERROR: terminfo database could not be found (try to set " "TERMINFO environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/cs_CZ.po000066400000000000000000000755221403012130000143230ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Pavel Borecki , 2017-2018 # Jiri Tersel , 2019. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-07-11 09:41+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Czech \n" "Language: cs_CZ\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 == 1 && n % 1 == 0) ? 0 : (n >= 2 && n " "<= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;\n" "X-Generator: Weblate 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Zjišťování technologie procesoru" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Váš procesor se nenachází v databázi ==> %s, model: %i, model podrobněji: " "%i, řada podrobněji: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-cestná" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-cestná" #: core.c:251 #, fuzzy, c-format #| msgid "%s associative, %d-byte line size" msgid "%s associative, %d-%s line size" msgstr "%s asociativní, %d-bajtová velikost řádku" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Získávání statických údajů prostřednictvím knihovny libcpuid" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "nepodařilo se zavolat knihovnu libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Získávání dynamických údajů prostřednictvím knihovny libcpuid" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" "Získávání statických hodnot MSR registru procesoru prostřednictvím knihovny " "libcpuid" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" "Získávání dynamických hodnot MSR registru procesoru prostřednictvím knihovny " "libcpuid" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Výpočet násobičů frekvence procesoru" #: core.c:521 msgid "Calling dmidecode" msgstr "Získávání údajů prostřednictvím nástroje dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Výpočet vytížení procesoru" #: core.c:605 msgid "Calling bandwidth" msgstr "Zjišťování údajů prostřednictvím nástroje bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Neznámý ovladač grafického čipu: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Neznámý ovladač grafického čipu: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "nepodařilo se zavolat knihovnu libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "Hledání zařízení" #: core.c:829 #, fuzzy, c-format #| msgid "Skip devices search (need to be root)" msgid "Skip devices search (wrong permissions on %s device)" msgstr "" "Přeskočit vyhledávání zařízení (je třeba mít práva správce systému – root)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Neznámý výrobce grafického čipu: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "nepodařilo se určit výrobce a model čipové sady" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "nepodařilo se určit výrobce a model grafického čipu" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Zjišťování taktů graf. čipu" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, fuzzy, c-format #| msgid "Driver for GPU %i doesn't report frequencies" msgid "Driver for GPU %u doesn't report frequencies" msgstr "Ovladač graf. čipu %i nehlásí takty" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "nepodařilo se zjistit takty grafického čipu" #: core.c:1205 msgid "Identifying running system" msgstr "Rozpoznávání operačního systému, ve kterém je spuštěné" #: core.c:1208 msgid "failed to identify running system" msgstr "nepodařilo se rozpoznat operační systém, ve kterém je spuštěné" #: core.c:1249 msgid "Calling libprocps" msgstr "Zjišťování údajů prostřednictvím knihovny libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Zjišťování údajů prostřednictvím knihovny libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dnů, %i hodin, %i minut, %i sekund" #: core.c:1366 msgid "Updating benchmark status" msgstr "Aktualizace stavu výkonostního testu" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u minut" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Neaktivní" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Není spuštěné" #: core.c:1380 msgid "Active" msgstr "Aktivní" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(zbývá %u hodin)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(zbývá %u minut)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(zbývá %u sekund)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "za %u hodin" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "za %u minut" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "za %u sekund" #: core.c:1414 msgid "Starting benchmark" msgstr "Spouštění výkonnostního testu" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "při spouštění výkonnostního testu se vyskytla chyba" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Typ pouzdra procesoru zjištován v náhradním režimu" #: core.c:1472 #, fuzzy, c-format #| msgid "Your CPU socket does not belong in database ==> %s, codename: %s" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Patice vašeho procesoru se nenachází v databázi ==> %s, krycí název: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Násobiče frekvence procesoru zjišťovány v náhradním režimu" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Informace o základní desce zjišťovány v náhradním režimu" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "nepodařilo se získat informace o základní desce (náhradní režim)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Teplota procesoru zjišťována v náhradním režimu" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "nepodařilo se zjistit teplotu procesoru (náhradní režim)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Provozní napětí procesoru zjišťováno v náhradním režimu" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "nepodařilo se zjistit provozní napětí procesoru (náhradní režim)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Takty graf. čipu zjišťovány v náhradním režimu" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "nepodařilo se zjistit takt procesoru (náhradní režim)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 #, fuzzy #| msgid "Starting GTK GUI..." msgid "Starting GTK GUI…" msgstr "Spouštění GTK grafického uživatelského rozhraní…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" "nepodařilo se importovat definici uživatelské rozhraní ve formátu GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Jádro č. %i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "Nastavování názvů popisek" #: main.c:58 msgid "CPU" msgstr "Procesor" #: main.c:59 msgid "Processor" msgstr "Procesor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Výrobce" #: main.c:61 msgid "Code Name" msgstr "Krycí název" #: main.c:62 msgid "Package" msgstr "Typ pouzdra" #: main.c:63 msgid "Technology" msgstr "Technologie" #: main.c:64 msgid "Voltage" msgstr "Provozní napětí" #: main.c:65 msgid "Specification" msgstr "Specifikace" #: main.c:66 msgid "Family" msgstr "Řada" #: main.c:67 msgid "Ext. Family" msgstr "Řada podrobně" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Model" #: main.c:69 msgid "Ext. Model" msgstr "Model podrobně" #: main.c:70 msgid "Temp." msgstr "Tepl." #: main.c:71 msgid "Stepping" msgstr "Várka" #: main.c:72 msgid "Instructions" msgstr "Výpočetní instrukce" #: main.c:74 msgid "Clocks" msgstr "Takty" #: main.c:75 msgid "Core Speed" msgstr "Rychlost jádra" #: main.c:76 msgid "Multiplier" msgstr "Násobič" #: main.c:77 msgid "Bus Speed" msgstr "Rychlost sběrnice" #: main.c:78 main.c:155 msgid "Usage" msgstr "Využití" #: main.c:80 msgid "Cache" msgstr "Mezipaměť" #: main.c:81 msgid "L1 Data" msgstr "1. úrovně (L1) – datová" #: main.c:82 msgid "L1 Inst." msgstr "1. úrovně (L1) – instrukční" #: main.c:83 msgid "Level 2" msgstr "Druhé úrovně" #: main.c:84 msgid "Level 3" msgstr "Třetí úrovně" #: main.c:86 msgid "Socket(s)" msgstr "Patice" #: main.c:87 msgid "Core(s)" msgstr "Jádra" #: main.c:88 msgid "Thread(s)" msgstr "Vlákna" #: main.c:91 msgid "Caches" msgstr "Mezipaměti" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "mezipaměť %i úrovně" #: main.c:96 msgid "Size" msgstr "Velikost" #: main.c:97 msgid "Speed" msgstr "Rychlost" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Základní deska" #: main.c:104 msgid "Manufacturer" msgstr "Výrobce" #: main.c:106 msgid "Revision" msgstr "Revize" #: main.c:108 msgid "BIOS" msgstr "BIOS/(U)EFI" #: main.c:109 msgid "Brand" msgstr "Značka" #: main.c:110 msgid "Version" msgstr "Verze" #: main.c:111 msgid "Date" msgstr "Datum" #: main.c:112 msgid "ROM Size" msgstr "Velikost ROM" #: main.c:114 msgid "Chipset" msgstr "Čipová sada" #: main.c:119 main.c:135 msgid "Memory" msgstr "Operační paměť" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banka %i" #: main.c:123 msgid "Reference" msgstr "Údaje" #: main.c:127 msgid "System" msgstr "Systém" #: main.c:128 msgid "Operating System" msgstr "Operační systém" #: main.c:129 msgid "Kernel" msgstr "Jádro systému" #: main.c:130 msgid "Distribution" msgstr "Distribuce" #: main.c:131 msgid "Hostname" msgstr "Název stroje" #: main.c:132 msgid "Uptime" msgstr "Doba chodu systému (uptime)" #: main.c:133 msgid "Compiler" msgstr "Kompilátor" #: main.c:136 msgid "Used" msgstr "Využito" #: main.c:137 msgid "Buffers" msgstr "Vyrovnávací paměť" #: main.c:138 msgid "Cached" msgstr "Mezipaměť" #: main.c:139 msgid "Free" msgstr "Volné" #: main.c:140 msgid "Swap" msgstr "Odkládací prostor (swap)" #: main.c:143 msgid "Graphics" msgstr "Grafika" #: main.c:147 #, c-format msgid "Card %i" msgstr "Adaptér %i" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Verze" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Teplota" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Provozní napětí" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "Takt graf. čipu" #: main.c:159 msgid "Memory clock" msgstr "Takt paměti" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Operační paměť" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Adaptér %i" #: main.c:165 msgid "Bench" msgstr "Výkon. test" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Prvočísla (důkladně)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Prvočísla (zběžně)" #: main.c:170 msgid "Score" msgstr "Výsledek" #: main.c:171 msgid "Run" msgstr "Spustit" #: main.c:174 msgid "Parameters" msgstr "Parametry" #: main.c:175 msgid "Duration" msgstr "Doba trvání" #: main.c:176 msgid "Threads" msgstr "Vláken" #: main.c:179 main.c:184 msgid "About" msgstr "O aplikaci" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s je svobodný software který pro vás shromažďuje\n" "o procesoru, základní desce a další." #: main.c:185 #, c-format msgid "Version %s" msgstr "Verze %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Webové stránky: %s" #: main.c:189 msgid "License" msgstr "Licence" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Tento software je šířen za podmínek licence %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Na tuto aplikaci nejsou poskytovány VŮBEC ŽÁDNÉ ZÁRUKY" #: main.c:265 #, fuzzy #| msgid "Dumping data..." msgid "Dumping data…" msgstr "Pořizování výpisu dat…" #: main.c:308 msgid "Freeing memory" msgstr "Uvolňování paměti" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Spustit grafické uživatelské rozhraní (GUI) – výchozí" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Spustit pseudografické uživatelské rozhraní (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Vypsat veškeré údaje na standardní výstup a skončit" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Spustit vestavěný příkaz dmidecode a skončit" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Spustit vestavěný příkaz bandwidth a skončit" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Nastavit vlastní prodlevu mezi dvěma obnoveními (v sekundách)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Nastavit výchozí kartu (celočíselná hodnota)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Vybrat jádro procesoru které monitorovat (celočíselná hodnota)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Nastavit vlastní test propustnosti mezipamětí procesoru (celočíselná hodnota)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Nastavit výchozí kartu (celočíselná hodnota)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "Podrobnější výstup" #: main.c:348 msgid "Print help and exit" msgstr "Vypsat nápovědu a skončit" #: main.c:349 msgid "Print version and exit" msgstr "Vypsat verzi a skončit" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "Vypnout obarvování výstupu" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Vypsat potřebné informace pro přiložení k hlášení problému" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "Vynutit takt sběrnice" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Načíst nezpracovaná CPUID data ze zadaného souboru" #: main.c:369 #, fuzzy #| msgid "Only print a message if CPU does not belong in database" msgid "Only print a message if CPU is not present in the database" msgstr "Pokud procesor není v databázi, pouze vypsat hlášení" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Použití: %s ZOBRAZENÍ [PŘEDVOLBY]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "ZOBRAZENÍ k dispozici:" #: main.c:403 #, fuzzy #| msgid "" #| "\n" #| "Available OPTIONS:" msgid "Available OPTIONS:" msgstr "" "\n" "PŘEDVOLBY k dispozici:" #: main.c:411 #, fuzzy #| msgid "" #| "\n" #| "Influenceable environment variables:" msgid "Influenceable environment variables:" msgstr "" "\n" "Ovlivnitelné proměnné prostředí:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Toto je svobodný software: můžete ho upravovat a šířit dál." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Viz licence %s: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s verze: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "nepodařilo se zavolat knihovnu libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sJejda, něco se pokazilo! %s obdrželo signál %d (%s) a zhavarovalo.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Tento záznam volání funkcí (backtrace) můžete vložit otevřením nového " "hlášení problému zde:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "při nastavování místních a jazykových nastavení došlo k chybě" #: tui_ncurses.c:72 #, fuzzy #| msgid "Starting NCurses TUI..." msgid "Starting NCurses TUI…" msgstr "Spouštění pseudografického (TUI) rozhraní…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Nápovědu zobrazíte stisknutím klávesy „H“.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Vítejte v nápovědě pseudografické (NCurses) varianty %s!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Tato nápověda popisuje použití tohoto textového uživatelského rozhraní.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Všeobecné klávesy:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "" "\tStiskem klávesy „Šipka vlevo“ se přepnete do karty nalevo od stávající.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "" "\tStiskem klávesy „Šipka vpravo“ se přepnete do karty napravo od stávající.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tStiskem klávesy „H“ zobrazíte tuto nápovědu.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tStiskem klávesy „Q“ aplikaci ukončíte.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Na kartě procesor:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tStiskem klávesy „Šipka dolů“ přejdete na monitorování jádra s nižším " "číslem.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tStiskem klávesy „Šipka dolů“ přejdete na monitorování jádra s vyšším " "číslem.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Na kartě mezipaměť:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tStiskem klávesy „Šipka dolů“ přejdete na předchozí test.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "" "\tStiskem klávesy „Šipka dolů“ přejdete na následující test.\n" "\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Na kartě výkonnostní testy:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "" "\tStiskem klávesy „Šipka dolů“ snížíte nastavenou dobu trvání výkonnostního " "testu .\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "" "\tStiskem klávesy „Šipka dolů“ zvýšíte nastavenou dobu trvání výkonnostního " "testu .\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tStiskem klávesy „následující stránka“ snížíte počet vláken, které test " "použije..\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tStiskem klávesy „předchozí stránka“ zvýšíte počet vláken, které test " "použije.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tStiskem klávesy „S“ spustíte/zastavíte výkonnostní test počítání prvočísel " "(důkladnou variantu).\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tStiskem klávesy „F“ spustíte/zastavíte výkonnostní test počítání prvočísel " "(zběžnou variantu).\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafika" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tStiskem klávesy „Šipka dolů“ přejdete na předchozí test.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "" "\tStiskem klávesy „Šipka dolů“ přejdete na následující test.\n" "\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Tuto nápovědu uzavřete stiskem libovolné klávesy.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "došlo k chybě při otevírání souboru „%s“ (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "došlo k chybě při vykonávání příkazu „%s“ (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "nepodařilo se otevřít složku %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "došlo k chybě při sestavování regulárního výrazu" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "nepodařilo se znovupřidělit paměť" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Ukončuje se %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "Přeskočit otevírání MSR registru procesoru (vyžaduje práva správce " #~ "systému)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "nepodařilo se otevřít MSR registr procesoru (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "" #~ "Přeskočit zavolání nástroje dmidecode (vyžaduje práva správce systému)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "nepodařilo se přidělit paměť pro nástroj dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "nepodařilo se zavolat nástroj dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Zjišťování ovladače grafického čipu" #~ msgid "(%s driver)" #~ msgstr "(ovladač %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "nepodařilo se zjistit ovladač grafické karty (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Zjišťování teploty grafického čipu" #~ msgid "Off" #~ msgstr "Vypnuto" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "nepodařilo se zjistit teplotu grafického čipu" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "" #~ "Přeskočit některé hodnoty graf. čipu (vyžaduje práva správce systému)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "nepodařilo se přidělit paměť pro výkonnostní test" #~ msgid "Root privileges are required to work properly" #~ msgstr "Pro správné fungování je třeba oprávnění správce systému" #~ msgid "Some information will not be retrievable" #~ msgstr "Některé informace nebude možné získat" #~ msgid "Ignore" #~ msgstr "Ignorovat" #~ msgid "Run as root" #~ msgstr "Spustit s právy správce systému (root)" #~ msgid "A new version of %s is available!" #~ msgstr "Je k dispozici nová verze %s!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Přejete si (po ukončení) aktualizovat %s na verzi %s?\n" #~ "Tento binární soubor (%s) bude přepsán novou verzí." #~ msgid "Not now" #~ msgstr "Nyní ne" #~ msgid "Update" #~ msgstr "Aktualizovat" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Zjišťování dostupnosti případné nové verze na Internetu…" #~ msgid "failed to open a Curl session" #~ msgstr "Nepodařilo se otevřít relaci nástroje Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "Nepodařilo se provést přenos nástrojem Curl (%s)" #~ msgid "wrong write data" #~ msgstr "chybná data pro zápis" #~ msgid "(version %s is available)" #~ msgstr "(je k dispozici verze %s)" #~ msgid "No new version available" #~ msgstr "Není k dispozici žádná novější verze" #~ msgid "(up-to-date)" #~ msgstr "(už používáte nejnovější dostupnou verzi)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "při vybalování archivu s %s se vyskytla chyba (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Síťový přístup je vypnutý proměnnou prostředí (zapněte nastavením " #~ "CPUX_NETWORK na kladnou hodnotu)" #~ msgid "failed to open %s archive for writing" #~ msgstr "nepodařilo se zapsat do archivu %s" #~ msgid "Downloading new version..." #~ msgstr "Stahování nové verze…" #~ msgid "failed to download %s archive (%s)" #~ msgstr "nepodařilo se stáhnout archiv %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Rozbalování nové verze…" #~ msgid "Applying new version..." #~ msgstr "Nasazování nové verze…" #~ msgid "an error occurred while removing/renaming files" #~ msgstr "při odebírání/přejmenovávání souborů došlo k chybě" #~ msgid "Update successful!" #~ msgstr "Aktualizace úspěšná!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Aktualizovat přenosnou variantu pokud je k dispozici novější verze" #~ msgid "Temporarily disable network support" #~ msgstr "Dočasně vypnout podporu sítě" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Sestaveno %s, %s (pomocí %s %s na %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Omlouváme se, ale %s nemůžete aktualizovat: 32 bitová přenosná verze už " #~ "není podporována." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Pokud chcete zaktualizovat, stiskněte klávesu „U“ – v opačném případě " #~ "přeskočte stisknutím libovolné jiné klávesy.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s bude aktualizováno." CPU-X-4.2.0/po/da.po000066400000000000000000000421201403012130000136720ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Lasse Lykke Jensen , 2020. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-06-24 06:41+0000\n" "Last-Translator: Lasse Lykke Jensen \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 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Finder CPU-teknologi" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Din CPU hører ikke til i databasen ==> %s, model: %i, ext. model: %i, ext. " "familie: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Kalder libcpuid til hentning af statiske data" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "kunne ikke kalde libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Kalder libcpuid til hentning af dynamiske data" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Kalder libcpuid til hentning af statiske CPU-MSR-værdier" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Kalder libcpuid til hentning af dynamiske CPU-MSR-værdier" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Beregner CPU-multiplikatorer" #: core.c:521 msgid "Calling dmidecode" msgstr "Kalder dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Beregner CPU-brug" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, fuzzy, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Ingen kernedriver i brug til grafikkort ved stien %s" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Din GPU-driver er ukendt: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Din GPU-driver er ukendt: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "kunne ikke kalde libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "Finder enheder" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Din CPU hører ikke til i databasen ==> %s, model: %i, ext. model: %i, ext. " "familie: %i" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "kunne ikke kalde libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/de.po000066400000000000000000000715551403012130000137140ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Torge Matthies , 2019, 2020. # Andreas Kleinert , 2019. # CurlingTongs , 2019. # ssantos , 2019. # anonymous , 2020. # Martin Beer , 2020. # nautilusx , 2020. # nautilusx , 2021. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-02-23 09:50+0000\n" "Last-Translator: nautilusx \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 4.5\n" #: core.c:218 msgid "Finding CPU technology" msgstr "CPU-Technologie finden" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Ihre CPU ist nicht in der Datenbank vorhanden ➜ %s, Model: %i, ext. Model: " "%i, ext. Familie: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d × %d %s, %d-fach" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-fach" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s assoziativ, %d-%s Zeilengröße" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Aufruf von libcpuid zum Abrufen statischer Daten" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "Fehler beim Aufruf von libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Aufruf von libcpuid zum Abruf dynamischer Daten" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Aufruf von libcpuid zum Abrufen von statischen CPU-MSR-Werten" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Aufruf von libcpuid zum Abrufen von dynamischer CPU-MSR-Werten" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "CPU-Multiplikatoren berechnen" #: core.c:521 msgid "Calling dmidecode" msgstr "dmidecode aufrufen" #: core.c:554 msgid "Calculating CPU usage" msgstr "CPU-Auslastung wird berechnet" #: core.c:605 msgid "Calling bandwidth" msgstr "Rufe bandwidth auf" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Ihr GPU-Kerneltreiber ist unbekannt: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Ihr GPU-Benutzermodustreiber ist unbekannt: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "GLFW konnte nicht aufgerufen werden (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Suche Geräte" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Suche nach Geräten überspringen (falsche Berechtigungen auf %s Gerät)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Unbekannter GPU-Hersteller: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "Chipsatzhersteller und Modell konnte nicht ermittelt werden" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "Grafikkartenhersteller und Modell konnten nicht ermittelt werden" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "GPU-Taktgeber abrufen" #: core.c:990 msgid "None" msgstr "Keine" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Treiber von GPU %u meldet keine Taktfrequenzen" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "Fehler beim Abrufen von GPU-Takten" #: core.c:1205 msgid "Identifying running system" msgstr "Laufendes System wird identifiziert" #: core.c:1208 msgid "failed to identify running system" msgstr "Fehler beim Identifizieren des laufenden Systems" #: core.c:1249 msgid "Calling libprocps" msgstr "libprocps aufrufen" #: core.c:1275 msgid "Calling libstatgrab" msgstr "libstatgrab aufrufen" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i Tage, %i Stunden, %i Minuten, %i Sekunden" #: core.c:1366 msgid "Updating benchmark status" msgstr "Benchmark-Status wird aktualisiert" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u Minuten" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inaktiv" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Nicht gestartet" #: core.c:1380 msgid "Active" msgstr "Aktiv" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u Stunden verbleibend)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u Minuten verbleibend)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u Sekunden verbleibend)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "in %u Stunden" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "in %u Minuten" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "in %u Sekunden" #: core.c:1414 msgid "Starting benchmark" msgstr "Benchmark starten" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "Beim Starten des Benchmarks ist ein Fehler aufgetreten" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "CPU-Paket wird in alternativem Modus ermittelt" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Ihr CPU-Sockel ist nicht in der Datenbank vorhanden ➜ %s, Codename: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "CPU-Multiplikatoren werden in alternativem Modus ermittelt" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Motherboard-Informationen werden in alternativem Modus abgerufen" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "Fehler beim Abrufen der Motherboard-Informationen (alternativer Modus)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "CPU-Temperatur wird in alternativem Modus abgerufen" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "Fehler beim Abrufen der CPU-Temperatur (alternativer Modus)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "CPU-Spannung wird in alternativem Modus abgerufen" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "Fehler beim Abrufen der CPU-Spannung (alternativer Modus)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "CPU-Frequenz wird in alternativem Modus abgerufen" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "Fehler beim Abrufen der CPU-Frequenz (alternativer Modus)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "GTK-GUI wird gestartet…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "Fehler beim Importieren des UIs in GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Kern %i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Setze Beschriftungsnamen" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Prozessor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Hersteller" #: main.c:61 msgid "Code Name" msgstr "Codename" #: main.c:62 msgid "Package" msgstr "Paket" #: main.c:63 msgid "Technology" msgstr "Technologie" #: main.c:64 msgid "Voltage" msgstr "Spannung" #: main.c:65 msgid "Specification" msgstr "Spezifikation" #: main.c:66 msgid "Family" msgstr "Familie" #: main.c:67 msgid "Ext. Family" msgstr "Erw. Familie" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modell" #: main.c:69 msgid "Ext. Model" msgstr "Erw. Modell" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Stepping" #: main.c:72 msgid "Instructions" msgstr "Instruktionen" #: main.c:74 msgid "Clocks" msgstr "Takte" #: main.c:75 msgid "Core Speed" msgstr "Kerntakt" #: main.c:76 msgid "Multiplier" msgstr "Multiplikator" #: main.c:77 msgid "Bus Speed" msgstr "Bustakt" #: main.c:78 main.c:155 msgid "Usage" msgstr "Auslastung" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "L1 Daten" #: main.c:82 msgid "L1 Inst." msgstr "L1 Inst." #: main.c:83 msgid "Level 2" msgstr "Level 2" #: main.c:84 msgid "Level 3" msgstr "Level 3" #: main.c:86 msgid "Socket(s)" msgstr "Sockel" #: main.c:87 msgid "Core(s)" msgstr "Kern(e)" #: main.c:88 msgid "Thread(s)" msgstr "Thread(s)" #: main.c:91 msgid "Caches" msgstr "Caches" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i Cache" #: main.c:96 msgid "Size" msgstr "Größe" #: main.c:97 msgid "Speed" msgstr "Geschwindigkeit" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Motherboard" #: main.c:104 msgid "Manufacturer" msgstr "Hersteller" #: main.c:106 msgid "Revision" msgstr "Revision" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marke" #: main.c:110 msgid "Version" msgstr "Version" #: main.c:111 msgid "Date" msgstr "Datum" #: main.c:112 msgid "ROM Size" msgstr "ROM-Größe" #: main.c:114 msgid "Chipset" msgstr "Chipsatz" #: main.c:119 main.c:135 msgid "Memory" msgstr "Speicher" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Bank %i" #: main.c:123 msgid "Reference" msgstr "Referenz" #: main.c:127 msgid "System" msgstr "System" #: main.c:128 msgid "Operating System" msgstr "Betriebssystem" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribution" #: main.c:131 msgid "Hostname" msgstr "Hostname" #: main.c:132 msgid "Uptime" msgstr "Betriebszeit" #: main.c:133 msgid "Compiler" msgstr "Compiler" #: main.c:136 msgid "Used" msgstr "Verwendet" #: main.c:137 msgid "Buffers" msgstr "Puffer" #: main.c:138 msgid "Cached" msgstr "Zwischengespeichert" #: main.c:139 msgid "Free" msgstr "Frei" #: main.c:140 msgid "Swap" msgstr "Swap" #: main.c:143 msgid "Graphics" msgstr "Grafik" #: main.c:147 #, c-format msgid "Card %i" msgstr "Karte %i" #: main.c:149 msgid "Driver" msgstr "Treiber" #: main.c:150 msgid "UMD Version" msgstr "UMD-Version" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatur" #: main.c:156 msgid "Core Voltage" msgstr "Kernspannung" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "GPU-Takt" #: main.c:159 msgid "Memory clock" msgstr "Speichertakt" #: main.c:160 msgid "Memory Used" msgstr "Verwendeter Speicher" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Karte %i" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Primzahlen (langsam)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Primzahlen (schnell)" #: main.c:170 msgid "Score" msgstr "Ergebnis" #: main.c:171 msgid "Run" msgstr "Start" #: main.c:174 msgid "Parameters" msgstr "Parameter" #: main.c:175 msgid "Duration" msgstr "Dauer" #: main.c:176 msgid "Threads" msgstr "Threads" #: main.c:179 main.c:184 msgid "About" msgstr "Über" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s ist eine Freie Software die Informationen\n" "über CPU, Motherboard und mehr sammelt." #: main.c:185 #, c-format msgid "Version %s" msgstr "Version %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Seite: %s" #: main.c:189 msgid "License" msgstr "Lizenz" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Diese Software wird unter den Bedingungen der %s verteilt" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Dieses Programm kommt mit ABSOLUT KEINER GARANTIE" #: main.c:265 msgid "Dumping data…" msgstr "Daten werden ausgegeben…" #: main.c:308 msgid "Freeing memory" msgstr "Speicher wird freigegeben" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Grafische Benutzeroberfläche (GUI) starten (Standard)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Text-basierte Benutzeroberfläche (TUI) starten" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Alle Daten in die Standardausgabe schreiben und Anwendung beenden" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Eingebettetes Kommando dmidecode ausführen und Anwendung beenden" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Eingebettete Kommando bandwidth ausführen und Anwendung beenden" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Intervall für die Aktualisierungen festlegen (in Sekunden)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Standard-Tab festlegen (Ganzzahl)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Zu überwachenden CPU-Kern auswählen (Ganzzahl)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Bandbreiten-Test für die CPU-Cache-Geschwindigkeit auswählen (Ganzzahl)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Standard-Tab festlegen (Ganzzahl)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "Ausführliche Ausgabe" #: main.c:348 msgid "Print help and exit" msgstr "Hilfetext ausgeben und Anwendung beenden" #: main.c:349 msgid "Print version and exit" msgstr "Version ausgeben und Anwendung beenden" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "Farbige Ausgabe deaktivieren" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Benötigte Informationen zum Einfügen in einen Problembericht ausgeben" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "Bustaktung erzwingen" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignorieren der von libcpuid gemeldeten CPU-Frequenz" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "CPUID-Rohdaten aus einer gegebenen Datei lesen" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" "Nur eine Nachricht ausgeben, wenn die CPU nicht in der Datenbank vorhanden " "ist" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Aufruf: %s ANZEIGE [OPTIONEN]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Verfügbare ANZEIGE:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Verfügbare OPTIONEN:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Umgebungsvariablen:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Dies ist freie Software: Sie dürfen sie frei verändern und verbreiten." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Siehe %s Lizenz: %s\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s Version: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "Fehler beim Aufruf von libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sEin Fehler ist aufgetreten! %s hat das Signal %d (%s) empfangen und ist " "abgestürzt.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Sie können diese Backtrace einfügen, indem Sie hier einen neuen " "Problembericht öffnen:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "Setzen des Gebietsschemas ist fehlgeschlagen" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "NCurses-TUI wird gestartet…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Fenster ist zu klein!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Taste »H« drücken, um die Hilfe anzuzeigen\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Willkommen in der %s NCurses-Hilfe!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Diese Hilfe beschreibt die Verwendung dieser textbasierten " "Benutzeroberfläche.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Globale Tasten:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tPfeiltaste »Links« drücken, um zum linken Tab zu wechseln.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tPfeiltaste »Rechts« drücken, um zum linken Tab zu wechseln.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tTaste »H« drücken, um diese Hilfe anzuzeigen.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tTaste »Q« drücken, um zu beenden.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "CPU-Tab:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tPfeiltaste »Abwärts« drücken, um die Anzahl der zu überwachenden Kerne zu " "verringern.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tPfeiltaste »Aufwärts« drücken, um die Anzahl der zu überwachenden Kerne zu " "erhöhen.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Caches Tab:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tPfeiltaste »Abwärts« drücken, um zum vorigen Test zu wechseln\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tPfeiltaste »Aufwärts« drücken, um zum nächsten Test zu wechseln\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Bench Tab:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "" "\tTaste »Pfeil abwärts« drücken, um die Dauer des Benchmarks zu verringern.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "" "\tTaste »Pfeil aufwärts« drücken, um die Dauer des Benchmarks zu erhöhen.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tTaste »Bild abwärts« drücken, um die Anzahl der zu verwendeten Threads zu " "verringern.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tTaste »Bild aufwärts« drücken, um die Anzahl der zu verwendeten Threads zu " "erhöhen.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tTaste »S« drücken, um den »Primzahlen (langsam)«-Benchmark zu starten/" "anzuhalten.\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tTaste »F« drücken, um den »Primzahlen (schnell)«-Benchmark zu starten/" "anzuhalten.\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafik" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tPfeiltaste »Abwärts« drücken, um zum vorigen Test zu wechseln\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tPfeiltaste »Aufwärts« drücken, um zum nächsten Test zu wechseln\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Eine beliebige Taste drücken, um diese Hilfe zu beenden.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "Ein Fehler trat auf beim Öffnen der Datei »%s« (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "Ein Fehler trat auf beim Ausführen des Befehls »%s« (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "Ordner »%s« konnte nicht geöffnet werden" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "Beim Kompilieren eines Regulären Ausdrucks trat ein Fehler auf" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "konnte Speicher nicht neu zuweisen" #: cpu-x.h:92 msgid "bytes" msgstr "Bytes" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "%s beenden" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Öffnen eines CPU-MSRs überspringen (Benötigt root-Rechte)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "CPU-MSR konnte nicht geöffnet werden (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Aufruf von dmidecode überspringen (Benötigt root-Rechte)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "Fehler beim Anfordern von Speicher für dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "Fehler beim Aufruf von dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Grafikkartentreiber wird ermittelt" #~ msgid "(%s driver)" #~ msgstr "(%s Treiber)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "Grafikkartentreiber konnte nicht ermittelt werden (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "GPU-Temperatur wird abgerufen" #~ msgid "Off" #~ msgstr "Aus" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "Fehler beim Abrufen der GPU-Temperatur" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Einige GPU-Werte überspringen (Benötigt root-Rechte)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "Speicherzuweisung für Benchmark fehlgeschlagen" #~ msgid "Root privileges are required to work properly" #~ msgstr "Root-Rechte werden benötigt, um richtig zu funktionieren" #~ msgid "Some information will not be retrievable" #~ msgstr "Einige Informationen werden nicht abrufbar sein" #~ msgid "Ignore" #~ msgstr "Ignorieren" #~ msgid "Run as root" #~ msgstr "Als root ausführen" #~ msgid "A new version of %s is available!" #~ msgstr "Eine neue Version von %s ist verfügbar!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Möchten Sie %s auf Version %s aktualisieren?\n" #~ "Dies wird die Binärdatei (%s) mit der neuen Version überschreiben." #~ msgid "Not now" #~ msgstr "Nicht jetzt" #~ msgid "Update" #~ msgstr "Aktualisieren" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Im Internet nach einer neuen Version suchen …" #~ msgid "failed to open a Curl session" #~ msgstr "Öffnen einer Curl-Sitzung fehlgeschlagen" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "Ausführung der Curl-Übertragung fehlgeschlagen (%s)" #~ msgid "wrong write data" #~ msgstr "Falsche Schreibdaten" #~ msgid "(version %s is available)" #~ msgstr "(Version %s ist verfügbar)" #~ msgid "No new version available" #~ msgstr "Keine neue Version verfügbar" #~ msgid "(up-to-date)" #~ msgstr "(neueste Version)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "Beim Entpacken des Archivs %s trat ein Fehler auf (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Netzwerkzugriff ist durch eine Umgebungsvariable deaktiviert " #~ "(CPUX_NETWORK auf einen positiven Wert setzen, um den Netzwerkzugriff zu " #~ "aktivieren)" #~ msgid "failed to open %s archive for writing" #~ msgstr "Archiv %s konnte nicht zum Schreiben geöffnet werden" #~ msgid "Downloading new version..." #~ msgstr "Neue Version wird heruntergeladen …" #~ msgid "failed to download %s archive (%s)" #~ msgstr "Fehler beim Herunterladen des Archivs %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Neue Version wird entpackt …" #~ msgid "Applying new version..." #~ msgstr "Neue Version anwenden …" #~ msgid "an error occurred while removing/renaming files" #~ msgstr "Beim Entfernen/Umbenennen von Dateien trat ein Fehler auf" #~ msgid "Update successful!" #~ msgstr "Erfolgreich aktualisiert!" #~ msgid "Update portable version if a new version is available" #~ msgstr "" #~ "Portable Version aktualisieren, falls eine neue Version verfügbar ist" #~ msgid "Temporarily disable network support" #~ msgstr "Temporär Netzwerkunterstützung deaktivieren" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Kompiliert am %s, %s (mit %s %s auf %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Leider können Sie %s nicht aktualisieren: Die 32-Bit-Portable-Version " #~ "wird nicht mehr unterstützt." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Taste »U« drücken, um zu aktualisieren, oder eine beliebige andere Taste " #~ "zum Überspringen.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s wird aktualisiert." CPU-X-4.2.0/po/el.po000066400000000000000000000402571403012130000137170ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # THANOS SIOURDAKIS , 2019. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2019-06-19 15:01+0000\n" "Last-Translator: THANOS SIOURDAKIS \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 3.7\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Εύρεση τεχνολογίας CPU" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "Δεν ήταν δυνατή η ανακατανομή μνήμης" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Έξοδος από %s" CPU-X-4.2.0/po/es.po000066400000000000000000000703761403012130000137330ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Adolfo Jayme Barrientos , 2019, 2020. # J , 2019, 2020. # Juan Manuel Cantero Diego , 2020. # LocoUnPocoNadaMas , 2020. # Allan Nordhøy , 2020. # H , 2020. # Bruno , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-11-02 22:26+0000\n" "Last-Translator: Bruno \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 4.3.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Encontrando tecnología de la CPU" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Su CPU no pertenece a la base de datos ==> %s, modelo: %i, modelo externo: " "%i, familia externa: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-way" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-way" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s asociativo, %d-%s linea de tamalo" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Llamado a libcpuid para recuperar datos estáticos" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "No se pudo llamar a libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Llamando a libcpuid para recuperar datos dinámicos" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Llamando a libcpuid para recuperar valores estáticos de CPU MSR" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Llamando a libcpuid para recuperar valores dinámicos de CPU MSR" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Calculando multiplicadores de CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Llamando a dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Calculando el uso de la CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Llamando al ancho de banda" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" "No hay controlador kernel en uso para la tarjeta grafica en la ubicación %s" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "El controlador de GPU es desconocido: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "El controlador de GPU es desconocido: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "No se pudo llamar a libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "Búsqueda de dispositivos" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" "Omitir búsqueda de dispositivos (permisos equivocados en dispositivo %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Su proveedor de GPU es desconocido: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "No se encontró el proveedor y el modelo del hipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "no se pudo encontrar el proveedor de la tarjeta gráfica y el modelo" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Recuperando reloj de GPU" #: core.c:990 msgid "None" msgstr "Ninguno" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "El controlador para la GPU %u no informa de las frecuencias" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "fallo al recuperar reloj de GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Identificando el sistema en ejecución" #: core.c:1208 msgid "failed to identify running system" msgstr "fallo al identificar el sistema en ejecución" #: core.c:1249 msgid "Calling libprocps" msgstr "Llamando a libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Llamando a libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i días, %i horas, %i minutos, %i segundos" #: core.c:1366 msgid "Updating benchmark status" msgstr "Actualizando estado del benchmark" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u mins" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inactivo" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Sin iniciar" #: core.c:1380 msgid "Active" msgstr "Activo" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u horas restantes)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minutos restantes)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u segundos restantes)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "en %u horas" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "en %u minutos" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "en %u segundos" #: core.c:1414 msgid "Starting benchmark" msgstr "Iniciando benchmark" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "se produjo un error al iniciar el punto de referencia" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Encontrar paquete de CPU en modo de reserva" #: core.c:1472 #, fuzzy, c-format #| msgid "Your CPU socket does not belong in database ==> %s, codename: %s" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Su zócalo de CPU no pertenece a la base de datos ==> %s, nombre clave: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Calculando multiplicadores de CPU en modo de reserva" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Recuperando información de la placa madre en modo de reserva" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "fallo al recuperar la información de la placa madre (modo de reserva)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "fallo al importar la IU en GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Núcleo #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "Establecer etiquetas de nombre" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Procesador" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Proveedor" #: main.c:61 msgid "Code Name" msgstr "Nombre clave" #: main.c:62 msgid "Package" msgstr "Paquete" #: main.c:63 msgid "Technology" msgstr "Tecnología" #: main.c:64 msgid "Voltage" msgstr "Voltaje" #: main.c:65 msgid "Specification" msgstr "Especificación" #: main.c:66 msgid "Family" msgstr "Familia" #: main.c:67 msgid "Ext. Family" msgstr "Ext. Familiar" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modelo" #: main.c:69 msgid "Ext. Model" msgstr "Ext. Modelo" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "Instrucciones" #: main.c:74 msgid "Clocks" msgstr "Relojes" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "Multiplicador" #: main.c:77 msgid "Bus Speed" msgstr "Velocidad Bus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Uso" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "L1 Datos" #: main.c:82 msgid "L1 Inst." msgstr "L1 Inst." #: main.c:83 msgid "Level 2" msgstr "Nivel 2" #: main.c:84 msgid "Level 3" msgstr "Nivel 3" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "Núcleo(s)" #: main.c:88 msgid "Thread(s)" msgstr "Hilos(s)" #: main.c:91 msgid "Caches" msgstr "Antememorias" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Antememoria L%i" #: main.c:96 msgid "Size" msgstr "Tamaño" #: main.c:97 msgid "Speed" msgstr "Velocidad" #: main.c:99 msgid "Test" msgstr "Prueba" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Placa madre" #: main.c:104 msgid "Manufacturer" msgstr "Fabricante" #: main.c:106 msgid "Revision" msgstr "Revisión" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marca" #: main.c:110 msgid "Version" msgstr "Versión" #: main.c:111 msgid "Date" msgstr "Fecha" #: main.c:112 msgid "ROM Size" msgstr "Tamaño ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memoria" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banco %i" #: main.c:123 msgid "Reference" msgstr "Referencia" #: main.c:127 msgid "System" msgstr "Sistema" #: main.c:128 msgid "Operating System" msgstr "Sistema Operativo" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribución" #: main.c:131 msgid "Hostname" msgstr "Nombre del host" #: main.c:132 msgid "Uptime" msgstr "Tiempo activo" #: main.c:133 msgid "Compiler" msgstr "Compilador" #: main.c:136 msgid "Used" msgstr "Usado" #: main.c:137 msgid "Buffers" msgstr "Buffers" #: main.c:138 msgid "Cached" msgstr "En caché" #: main.c:139 msgid "Free" msgstr "Libre" #: main.c:140 msgid "Swap" msgstr "Intercambio" #: main.c:143 msgid "Graphics" msgstr "Gráfica" #: main.c:147 #, c-format msgid "Card %i" msgstr "Placa %i" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Versión" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatura" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Voltaje" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "Reloj GPU" #: main.c:159 msgid "Memory clock" msgstr "Reloj Memoria" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Memoria" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Placa %i" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Números primos (lento)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Números primos (rápido)" #: main.c:170 msgid "Score" msgstr "Puntuación" #: main.c:171 msgid "Run" msgstr "Ejecutar" #: main.c:174 msgid "Parameters" msgstr "Parámetros" #: main.c:175 msgid "Duration" msgstr "Duración" #: main.c:176 msgid "Threads" msgstr "Hilos" #: main.c:179 main.c:184 msgid "About" msgstr "Acerca de" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s es un software gratuito que recopila información\n" "en CPU, placa madre y más." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versión %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Sitio: %s" #: main.c:189 msgid "License" msgstr "Licencia" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Este software se distribuye bajo los términos de %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Este programa viene ABSOLUTAMENTE SIN GARANTÍA" #: main.c:265 #, fuzzy #| msgid "Dumping data..." msgid "Dumping data…" msgstr "Volcado de datos..." #: main.c:308 msgid "Freeing memory" msgstr "Liberando memoria" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Iniciar la interfaz gráfica de usuario (GUI) (predeterminada)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Iniciar interfaz de usuario basada en texto (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Volcar todos los datos en la salida estándar y salir" #: main.c:339 #, fuzzy msgid "Run embedded command dmidecode and exit" msgstr "Ejecutar el comando incrustado dmidecode y salir" #: main.c:340 #, fuzzy msgid "Run embedded command bandwidth and exit" msgstr "Ejecutar el comando incrustado bandwidth y salir" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Establezca un tiempo personalizado entre dos refrescos (en segundos)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Establecer pestaña predeterminada (entero)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Seleccione el núcleo de CPU a monitorear (entero)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Establecer una prueba de ancho de banda personalizada para la velocidad de " "caché de CPU (entero)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Establecer pestaña predeterminada (entero)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "Salida detallada" #: main.c:348 msgid "Print help and exit" msgstr "Mostrar ayuda y salir" #: main.c:349 msgid "Print version and exit" msgstr "Mostrar versión y salir" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "Deshabilitar salida de color" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "Imponer el reloj del Bus" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Leer datos crudos de CPUID de un archivo determinado" #: main.c:369 #, fuzzy #| msgid "Only print a message if CPU does not belong in database" msgid "Only print a message if CPU is not present in the database" msgstr "Solo imprima un mensaje si la CPU no pertenece a la base de datos" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Uso: %s PANTALLA [OPCIONES]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "PANTALLA disponible:" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPCIONES disponibles:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variables de entorno influibles:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Esto es software libre: usted es libre de cambiarlo y redistribuirlo." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Ver la %s licencia: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s version: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "No se pudo llamar a libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "se produjo un error al ajustar la configuración regional" #: tui_ncurses.c:72 #, fuzzy #| msgid "Starting NCurses TUI..." msgid "Starting NCurses TUI…" msgstr "Iniciando NCurses TUI..." #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Presione 'h' para ver ayuda.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Esta ayuda describe cómo usar esta interfaz de usuario basada en texto.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Teclas globales:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tPresione la tecla 'izquierda' para cambiar a la pestaña izquierda.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tPresione la tecla 'derecha' para cambiar a la pestaña derecha.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tPresione la tecla 'h' para ver esta ayuda.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tPresione la tecla 'q' para salir.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Pestaña CPU:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tPresione la tecla 'abajo' para disminuir el número de núcleo a " "monitorear.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tPresione la tecla 'arriba' para aumentar el número de núcleo a " "monitorear.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Pestaña Cachés:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tPresione la tecla 'abajo' para cambiar a la prueba anterior.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tPresione la tecla 'arriba' para pasar a la siguiente prueba.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Bench tab:" msgstr "" "\n" "Pestaña Cachés:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "" "\tPresione la tecla 'abajo' para disminuir la duración del punto de " "referencia.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "" "\tPresione la tecla 'arriba' para aumentar la duración del punto de " "referencia.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tPresione la tecla 'página siguiente' para disminuir el número de hilos a " "usar.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tPresione la tecla 'página anterior' para incrementar el número de hilos a " "usar.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tOprima la tecla «s» para iniciar/parar el banco de pruebas de números " "primos (lento).\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tOprima la tecla «f» para iniciar/parar el banco de pruebas de números " "primos (rápido).\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Gráfica" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tPresione la tecla 'abajo' para cambiar a la prueba anterior.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tPresione la tecla 'arriba' para pasar a la siguiente prueba.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Oprima cualquier tecla para salir de esta ayuda.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "no se pudo buscar unidad en '%s' cadena en la posición %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "se produjo un error al abrir el archivo '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "se produjo un error al ejecutar el comando '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "fallo al abrir el directorio %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "se produjo un error al compilar regex" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "No se logró reasignar la memoria" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Saliendo de %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Omitir apertura de CPU MSR (necesita ser root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "no se pudo abrir CPU MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Omitir llamada a dmidecode (necesita ser root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "No se pudo asignar memoria para el dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "no se pudo llamar a dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Encontrando el controlador de la tarjeta gráfica" #~ msgid "(%s driver)" #~ msgstr "(controlador %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "No se encontró el controlador de la tarjeta gráfica (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Recuperando temperatura de la GPU" #~ msgid "Off" #~ msgstr "Apagado" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "no se pudo recuperar la temperatura de la GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Omitir algunos valores de la GPU (debe ser root)" #~ msgid "Root privileges are required to work properly" #~ msgstr "" #~ "Se requieren privilegios de superusuario para funcionar correctamente" #~ msgid "Some information will not be retrievable" #~ msgstr "Alguna información no será recuperable" #~ msgid "Ignore" #~ msgstr "Ignorar" #~ msgid "Run as root" #~ msgstr "Ejecutar como superusuario" #~ msgid "A new version of %s is available!" #~ msgstr "¡Una nueva versión de %s está disponible!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "¿Desea actualizar %s a la versión %s después de salir?\n" #~ "Esto borrará el archivo binario (%s) por la nueva versión." #~ msgid "Not now" #~ msgstr "Ahora No" #~ msgid "Update" #~ msgstr "Actualización" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Buscando en Internet una nueva versión..." #~ msgid "wrong write data" #~ msgstr "escritura de datos incorrecta" #~ msgid "(version %s is available)" #~ msgstr "(la versión %s está disponible)" #~ msgid "No new version available" #~ msgstr "Sin nueva versión disponible" #~ msgid "(up-to-date)" #~ msgstr "(a la fecha)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "se produjo un error al extraer %s archivo (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "El acceso a la red está deshabilitado por la variable de entorno " #~ "(configure CPUX_NETWORK con un valor positivo para habilitarlo)" #~ msgid "failed to open %s archive for writing" #~ msgstr "no se pudo abrir el archivo %s para escribir" #~ msgid "Downloading new version..." #~ msgstr "Descargando nueva versión..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "fallo al descargar el archivo %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Extrayendo nueva versión..." #~ msgid "Applying new version..." #~ msgstr "Aplicando nueva versión..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "se produjo un error al eliminar/renombrar archivos" #~ msgid "Update successful!" #~ msgstr "¡Actualización exitosa!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Actualice la versión portátil si hay una nueva versión disponible" #~ msgid "Temporarily disable network support" #~ msgstr "Deshabilitar temporalmente el soporte de red" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Construido en %s, %s (con %s %s en %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Lo sentimos, no puede actualizar %s: la versión portátil de 32-bits ya no " #~ "es compatible." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Si desea actualizar, presione la tecla 'u' o cualquier otra para omitir.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s se actualizará." CPU-X-4.2.0/po/fi.po000066400000000000000000000460031403012130000137100ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Riku Viitanen , 2020. # Jiri Grönroos , 2021. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-07 18:50+0000\n" "Last-Translator: Jiri Grönroos \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 4.5.1\n" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuid:n kutsuminen epäonnistui (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Lasketaan CPU kertoimia" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "Lasketaan prosessorinkäyttö" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Näytönohjaimen kernel-ajuri on tuntematon: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Tuntematon näytönohjaimen ajuri: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "libcpuid:n kutsuminen epäonnistui (%s)" #: core.c:817 msgid "Finding devices" msgstr "Etsitään laitteita" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Tuntematon näytönohjaimen ajuri: %s" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Haetaan GPU kellotaajuuksia" #: core.c:990 msgid "None" msgstr "Ei mitään" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "GPU %u:n ajuri ei raportoi taajuuksia" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "GPU-kellotaajuuksien haku epäonnistui" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "Kutsutaan libprocps:ää" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Kutsutaan libstatgrabia" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i päivää, %i tuntia, %i minuuttia, %i sekuntia" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u minuuttia" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Ei aloitettu" #: core.c:1380 msgid "Active" msgstr "Aktiivinen" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u tuntia jäljellä)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minuuttia jäljellä)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u sekuntia jäljellä)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "%u tunnissa" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "%u minuutissa" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "%u sekunnissa" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Käynnistetään GTK GUI…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Yhdistetty daemoniin" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Käynnistä daemon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Ydin #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "Suoritin" #: main.c:59 msgid "Processor" msgstr "Prosessori" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Tekijä" #: main.c:61 msgid "Code Name" msgstr "Koodinimi" #: main.c:62 msgid "Package" msgstr "Pakkaus" #: main.c:63 msgid "Technology" msgstr "Tekniikka" #: main.c:64 msgid "Voltage" msgstr "Jännite" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "Perhe" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Malli" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "Lämpötila" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "Käskylaajennukset" #: main.c:74 msgid "Clocks" msgstr "Kellotaajuudet" #: main.c:75 msgid "Core Speed" msgstr "Ytimen nopeus" #: main.c:76 msgid "Multiplier" msgstr "Kerroin" #: main.c:77 msgid "Bus Speed" msgstr "Väylänopeus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Käyttö" #: main.c:80 msgid "Cache" msgstr "Välimuisti" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "Taso 2" #: main.c:84 msgid "Level 3" msgstr "Taso 3" #: main.c:86 msgid "Socket(s)" msgstr "Kanta" #: main.c:87 msgid "Core(s)" msgstr "Ytimet" #: main.c:88 msgid "Thread(s)" msgstr "Säikeet" #: main.c:91 msgid "Caches" msgstr "Välimuistit" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i-välimuisti" #: main.c:96 msgid "Size" msgstr "Koko" #: main.c:97 msgid "Speed" msgstr "Nopeus" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Emolevy" #: main.c:104 msgid "Manufacturer" msgstr "Valmistaja" #: main.c:106 msgid "Revision" msgstr "Revisio" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Brändi" #: main.c:110 msgid "Version" msgstr "Versio" #: main.c:111 msgid "Date" msgstr "Päivämäärä" #: main.c:112 msgid "ROM Size" msgstr "ROM:in koko" #: main.c:114 msgid "Chipset" msgstr "Piirisarja" #: main.c:119 main.c:135 msgid "Memory" msgstr "Muisti" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "Järjestelmä" #: main.c:128 msgid "Operating System" msgstr "Käyttöjärjestelmä" #: main.c:129 msgid "Kernel" msgstr "Käyttöjärjestelmäydin" #: main.c:130 msgid "Distribution" msgstr "Jakelu" #: main.c:131 msgid "Hostname" msgstr "Isäntänimi" #: main.c:132 msgid "Uptime" msgstr "Käynnissä" #: main.c:133 msgid "Compiler" msgstr "Kääntäjä" #: main.c:136 msgid "Used" msgstr "Käytetty" #: main.c:137 msgid "Buffers" msgstr "Puskurit" #: main.c:138 msgid "Cached" msgstr "Välimuistissa" #: main.c:139 msgid "Free" msgstr "Vapaana" #: main.c:140 msgid "Swap" msgstr "Sivutus" #: main.c:143 msgid "Graphics" msgstr "Grafiikka" #: main.c:147 #, c-format msgid "Card %i" msgstr "Kortti %i" #: main.c:149 msgid "Driver" msgstr "Ajuri" #: main.c:150 msgid "UMD Version" msgstr "UMD-versio" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Lämpötila" #: main.c:156 msgid "Core Voltage" msgstr "Ytimen jännite" #: main.c:157 msgid "Power Avg" msgstr "Kulutus keskim." #: main.c:158 msgid "GPU clock" msgstr "GPU kellotaajuus" #: main.c:159 msgid "Memory clock" msgstr "Muistin kellotaajuus" #: main.c:160 msgid "Memory Used" msgstr "Käytetty muisti" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Kortti %i" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Alkuluvut (hidas)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Alkuluvut (nopea)" #: main.c:170 msgid "Score" msgstr "Tulos" #: main.c:171 msgid "Run" msgstr "Aja" #: main.c:174 msgid "Parameters" msgstr "Parametrit" #: main.c:175 msgid "Duration" msgstr "Kesto" #: main.c:176 msgid "Threads" msgstr "Säikeet" #: main.c:179 main.c:184 msgid "About" msgstr "Tietoa" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s on vapaa ohjelmisto joka kerää tietoa\n" "suorittimesta, emolevystä ja muusta." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versio %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Kehittäjä: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Sivusto: %s" #: main.c:189 msgid "License" msgstr "Lisenssi" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Tätä ohjelmistoa jaetaan %s -lisenssin mukaisesti" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Tämä ohjelma EI SISÄLLÄ MINKÄÄNLAISTA TAKUUTA" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "Vapautetaan muistia" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Valitse tarkkailtava suoritinydin (numero)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "Select CPU core to monitor (integer)" msgid "Select default graphic card (integer)" msgstr "Valitse tarkkailtava suoritinydin (numero)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "Tulosta ohje ja lopeta" #: main.c:349 msgid "Print version and exit" msgstr "Tulosta versio ja lopeta" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Käyttö: %s DISPLAY [OPTIONS]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Tämä on vapaa ohjelma: voit muokata ja jakaa sitä vapaasti." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Lue lisenssi (%s): <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "libcpuid:n kutsuminen epäonnistui (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Ikkuna on liian pieni!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Paina 'h' nähdäksesi ohjeen.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tPaina 'q' poistuaksesi.\n" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' key to see this help." msgstr "Paina 'h' nähdäksesi ohjeen.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tPaina 'q' poistuaksesi.\n" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 #, fuzzy #| msgid "Caches" msgid "Caches tab:" msgstr "Välimuistit" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tPaina 'q' poistuaksesi.\n" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafiikka" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press any key to exit this help." msgstr "\tPaina 'q' poistuaksesi.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "tiedoston '%s' avaaminen epäonnistui (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "komennon '%s' suoritaminen epäonnistui (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "hakemiston %s avaaminen epäonnistui" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: komentoa ei löytynyt" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: odottamaton virhekoodi" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "tavua" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kt" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "Mt" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "Gt" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "Tt" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "Mt" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "Gt" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "Tt" CPU-X-4.2.0/po/fr.po000066400000000000000000000725531403012130000137320ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Xorg, 2015-2018 # Mattéo Rossillol , 2019. # Xorg , 2019, 2020, 2021. # Mattéo Rossillol‑‑Laruelle , 2020. # Julien Humbert , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-28 13:27+0000\n" "Last-Translator: Xorg \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 4.6-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Recherche la finesse de gravure du processeur" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Votre processeur n'est pas présent dans la base de données ==> %s, modèle : " "%i, modèle ét. : %i, famille ét. : %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d voies" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d voies" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s associatives, %d %s par ligne" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Appel libcpuid pour récupérer les données statiques" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "échec lors de l'appel de libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Appel libcpuid pour récupérer les données dynamiques" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" "Appel de libcpuid pour récupérer les valeurs statiques des MSR du processeur" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" "Appel de libcpuid pour récupérer les valeurs dynamiques des MSR du processeur" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Calcule les multiplicateurs du processeur" #: core.c:521 msgid "Calling dmidecode" msgstr "Appel dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Calcule l'utilisation du processeur" #: core.c:605 msgid "Calling bandwidth" msgstr "Appel bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Aucun pilote noyau n'est utilisé par la carte graphique de chemin %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Le pilote noyau de votre carte-graphique est inconnu : %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Le pilote utilisateur de votre carte-graphique est inconnu : %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "échec lors de l'appel de GLFW (%i) : %s" #: core.c:817 msgid "Finding devices" msgstr "Recherche des périphériques" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" "Saute la recherche des périphériques (mauvaises permissions pour le " "périphérique %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Le fabricant de votre carte-graphique est inconnu : %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "échec lors de la recherche du vendeur et du modèle du chipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" "échec lors de la recherche du vendeur et du modèle de la carte-graphique" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Récupère les fréquences de la carte-graphique" #: core.c:990 msgid "None" msgstr "Aucun" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Le pilote de la carte-graphique %u ne rapporte pas les fréquences" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "Actuel : PCIe Gen%1dx%d / Max : Gen%1dx%d" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "échec lors de la récupération des fréquences de la carte-graphique" #: core.c:1205 msgid "Identifying running system" msgstr "Identifie le système en cours de fonctionnement" #: core.c:1208 msgid "failed to identify running system" msgstr "échec lors de l'identification du système en cours de fonctionnement" #: core.c:1249 msgid "Calling libprocps" msgstr "Appel libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Appel libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i jours, %i heures, %i minutes, %i secondes" #: core.c:1366 msgid "Updating benchmark status" msgstr "Mise à jour du statut du test de performance" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inactif" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Non démarré" #: core.c:1380 msgid "Active" msgstr "Actif" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u heures restantes)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minutes restantes)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u secondes restantes)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "en %u heures" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "en %u minutes" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "en %u secondes" #: core.c:1414 msgid "Starting benchmark" msgstr "Démarrage du test de performance" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "une erreur est survenue lors du démarrage du test de performance" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Recherche du socket du processeur en mode de secours" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Votre socket de processeur n'est pas présent dans la base de données ==> %s, " "nom de code : %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Calcule les multiplicateurs du processeur en mode de secours" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Récupère les informations de la carte-mère en mode de secours" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" "échec lors de la récupération des informations de la carte-mère (mode de " "secours)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Récupère la température du processeur en mode de secours" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" "échec lors de la récupération de la température du processeur (mode de " "secours)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Récupère la tension du processeur en mode de secours" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" "échec lors de la récupération de la tension du processeur (mode de secours)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Récupère la fréquence du processeur en mode de secours" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" "échec lors de la récupération de la fréquence du processeur (mode de secours)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler : le cas %i n'est pas géré" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Démarrage de l'interface graphique GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "échec lors de l'import de l'interface dans GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Connecté au démon" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Aucun agent d'authentification Polkit trouvé" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Demander le mot de passe pour démarrer le démon en arrière-plan" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Démarrer le démon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Cœur #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Configuration du nom des étiquettes" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processeur" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Vendeur" #: main.c:61 msgid "Code Name" msgstr "Nom de code" #: main.c:62 msgid "Package" msgstr "Socket" #: main.c:63 msgid "Technology" msgstr "Technologie" #: main.c:64 msgid "Voltage" msgstr "Tension" #: main.c:65 msgid "Specification" msgstr "Spécification" #: main.c:66 msgid "Family" msgstr "Famille" #: main.c:67 msgid "Ext. Family" msgstr "Famille ét." #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modèle" #: main.c:69 msgid "Ext. Model" msgstr "Modèle ét." #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Révision" #: main.c:72 msgid "Instructions" msgstr "Instructions" #: main.c:74 msgid "Clocks" msgstr "Fréquences" #: main.c:75 msgid "Core Speed" msgstr "Vitesse du cœur" #: main.c:76 msgid "Multiplier" msgstr "Multiplicateur" #: main.c:77 msgid "Bus Speed" msgstr "Vitesse du bus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Utilisation" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "Données L1" #: main.c:82 msgid "L1 Inst." msgstr "Instr. L1" #: main.c:83 msgid "Level 2" msgstr "Niveau L2" #: main.c:84 msgid "Level 3" msgstr "Niveau L3" #: main.c:86 msgid "Socket(s)" msgstr "Socket(s)" #: main.c:87 msgid "Core(s)" msgstr "Cœur(s)" #: main.c:88 msgid "Thread(s)" msgstr "Thread(s)" #: main.c:91 msgid "Caches" msgstr "Caches" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Cache L%i" #: main.c:96 msgid "Size" msgstr "Taille" #: main.c:97 msgid "Speed" msgstr "Vitesse" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Carte-mère" #: main.c:104 msgid "Manufacturer" msgstr "Fabricant" #: main.c:106 msgid "Revision" msgstr "Révision" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marque" #: main.c:110 msgid "Version" msgstr "Version" #: main.c:111 msgid "Date" msgstr "Date" #: main.c:112 msgid "ROM Size" msgstr "Taille de la ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Mémoire" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banc %i" #: main.c:123 msgid "Reference" msgstr "Référence" #: main.c:127 msgid "System" msgstr "Système" #: main.c:128 msgid "Operating System" msgstr "Système d'exploitation" #: main.c:129 msgid "Kernel" msgstr "Noyau" #: main.c:130 msgid "Distribution" msgstr "Distribution" #: main.c:131 msgid "Hostname" msgstr "Nom d'hôte" #: main.c:132 msgid "Uptime" msgstr "Disponibilité" #: main.c:133 msgid "Compiler" msgstr "Compilateur" #: main.c:136 msgid "Used" msgstr "Utilisée" #: main.c:137 msgid "Buffers" msgstr "Tampons" #: main.c:138 msgid "Cached" msgstr "Cachée" #: main.c:139 msgid "Free" msgstr "Libre" #: main.c:140 msgid "Swap" msgstr "Swap" #: main.c:143 msgid "Graphics" msgstr "Graphiques" #: main.c:147 #, c-format msgid "Card %i" msgstr "Carte %i" #: main.c:149 msgid "Driver" msgstr "Pilote" #: main.c:150 msgid "UMD Version" msgstr "Version UMD" #: main.c:152 msgid "DeviceID" msgstr "Identifiant" #: main.c:153 msgid "Interface" msgstr "Interface" #: main.c:154 msgid "Temperature" msgstr "Température" #: main.c:156 msgid "Core Voltage" msgstr "Tension GPU" #: main.c:157 msgid "Power Avg" msgstr "Puissance" #: main.c:158 msgid "GPU clock" msgstr "Fréq. GPU" #: main.c:159 msgid "Memory clock" msgstr "Fréq. mémoire" #: main.c:160 msgid "Memory Used" msgstr "Mémoire utilisée" #: main.c:162 msgid "Cards" msgstr "Cartes" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Nombres premier (lent)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Nombres premier (rapide)" #: main.c:170 msgid "Score" msgstr "Score" #: main.c:171 msgid "Run" msgstr "État" #: main.c:174 msgid "Parameters" msgstr "Paramètres" #: main.c:175 msgid "Duration" msgstr "Durée" #: main.c:176 msgid "Threads" msgstr "Threads" #: main.c:179 main.c:184 msgid "About" msgstr "À propos" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s est un logiciel Libre qui récolte des informations\n" "sur le CPU, la carte-mère et plus." #: main.c:185 #, c-format msgid "Version %s" msgstr "Version %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Auteur : %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Site : %s" #: main.c:189 msgid "License" msgstr "Licence" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Ce logiciel est distribué sous les termes de la %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Ce programme est distribué SANS AUCUNE GARANTIE" #: main.c:265 msgid "Dumping data…" msgstr "Vidage des données…" #: main.c:308 msgid "Freeing memory" msgstr "Libère de la mémoire" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Démarre l’interface graphique utilisateur (GUI) (défaut)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Démarre l'interface en mode texte (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Vide toutes les données sur la sortie standard et quitte" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Lance la commande intégrée dmidecode et quitte" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Lance la commande intégrée bandwidth et quitte" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" "Définit un temps personnalisé entre deux mises à jour de l'interface (en " "secondes)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Définit l'onglet par défaut (entier)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Sélectionne le cœur du processeur à surveiller (entier)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Définit un test personnalisé de bande passante pour la vitesse des caches du " "processeur (entier)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "Définit la carte graphique par défaut (entier)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Démarrer le démon et s'y connecter" #: main.c:347 msgid "Verbose output" msgstr "Sortie bavarde" #: main.c:348 msgid "Print help and exit" msgstr "Affiche l'aide et quitte" #: main.c:349 msgid "Print version and exit" msgstr "Affiche la version et quite" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "Affiche les valeurs CPUID en décimal (en hexadécimal par défaut)" #: main.c:351 msgid "Disable colored output" msgstr "Désactive la sortie colorée" #: main.c:352 msgid "Print information for debugging" msgstr "Affiche les informations pour le débogage" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" "Affiche les informations nécessaires à coller dans un rapport de problèmes" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Définit l'affectation des touches pour le mode NCurses (a[rrows]|e[macs]|" "i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Ajoute les arguments de la ligne de commande par défaut" #: main.c:366 msgid "Enforce the bus clock" msgstr "Impose la fréquence du bus" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignore la fréquence du processeur rapportée par licpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Lis les données CPUID brutes depuis un fichier donné" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" "Affiche uniquement un message si le processeur n'est pas présent dans la " "base de données" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Utilisation : %s AFFICHAGE [OPTIONS]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "AFFICHAGE disponible :" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPTIONS disponibles :" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variables d'environnements influençables :" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Ceci est un logiciel libre ; vous êtes libres de le modifier et de le " "redistribuer." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Voir la licence %s : <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- Version de %-9s : %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "échec lors de l'appel de wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sOups, quelque chose s'est mal passé ! %s a reçu le signal %d (%s) et a " "planté.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Vous pouvez coller la trace d'appels en ouvrant un nouveau rapport de " "problèmes ici :" #: main.c:705 msgid "an error occurred while setting locale" msgstr "une erreur est survenue lors de la définition des locales" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Démarrage de l'interface texte NCurses…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ERREUR FATALE : la base de données terminfo ne peut pas être trouvée " "(essayez de spécifier la variable d'environnement TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "La mise en place du terminal %s a échoué (err=%i) ; retour à %s" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "La fenêtre est trop petite !" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "Appuyer sur 'h' pour voir l'aide." #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Bienvenue dans l'aide pour NCurses de %s !\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "Cette aide décrit comment utiliser cette interface en mode texte." #: tui_ncurses.c:477 msgid "Global keys:" msgstr "Touches globales :" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" "Appuyer sur la touche 'flèche gauche' pour passer dans l'onglet de gauche." #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" "Appuyer sur la touche 'flèche droite' pour passer dans l'onglet de droite." #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "Appuyer sur la touche 'h' pour voir cette aide." #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "Appuyer sur la touche 'q' pour quitter." #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "Onglet processeur :" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" "Appuyer sur la touche 'flèche bas' pour diminuer la valeur du cœur à " "surveiller." #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" "Appuyer sur la touche 'flèche haut' pour augmenter la valeur du cœur à " "surveiller." #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "Onglet caches :" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "Appuyer sur la touche 'flèche bas' pour passer au test précédent." #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "Appuyer sur la touche 'flèche haut' pour passer au test suivant." #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "Onglet Bench :" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" "Appuyer sur la touche 'flèche bas' pour décrémenter la durée du test de " "performance." #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" "Appuyer sur la touche 'flèche haut' pour incrémenter la durée du test de " "performance." #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "Appuyer sur la touche 'page suivante' pour décrémenter le nombre de threads " "à utiliser." #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "Appuyer sur la touche 'page précédente' pour incrémenter le nombre de " "threads à utiliser." #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "Appuyer sur la touche 's' pour démarrer/arrêter le test de performance des " "nombres premier (lent)." #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "Appuyer sur la touche 'f' pour démarrer/arrêter le test de performance des " "nombres premier (rapide)." #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "Onglet graphiques :" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" "Appuyer sur la touche 'flèche bas' pour afficher la carte-graphique " "précédente." #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" "Appuyer sur la touche 'flèche haut' pour afficher la carte-graphique " "suivante." #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "Appuyer sur n'importe quelle touche pour quitter cette aide." #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "impossible de trouver l'unité dans la chaîne « %s » à la position %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "La chaîne '%s' est trop longue, troncage…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "une erreur est survenue lors de l'ouverture du fichier '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "une erreur est survenue lors de l'exécution de la commande '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "échec lors de l'ouverture du répertoire %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" "une erreur est survenue lors de la compilation des expressions régulières" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" "pkexec : l’autorisation ne peut pas être obtenue (la boîte de dialogue a été " "rejetée)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec : l’autorisation ne peut pas être obtenue (non-autorisé)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec : commande introuvable" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec : code d'erreur inattendu" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ERREUR FATALE : n'a pas pu réallouer la mémoire" #: cpu-x.h:92 msgid "bytes" msgstr "octets" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "ko" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "Mo" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "Go" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "To" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "Kio" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "Mio" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "Gio" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "Tio" #~ msgid "Exiting %s" #~ msgstr "Quitte %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "Saute l'ouverture des MSR du processeur (besoin d'être super-utilisateur)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "échec lors de l'ouverture des MSR du processeur (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Saute l'appel de dmidecode (besoin d'être super-utilisateur)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "échec lors de l'allocation de la mémoire pour dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "échec lors de l'appel de dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Recherche le pilote de la carte graphique" #~ msgid "(%s driver)" #~ msgstr "(pilote %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "échec lors de la recherche du pilote de la carte-graphique (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Récupère la température du processeur graphique" #~ msgid "Off" #~ msgstr "Off" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "" #~ "échec lors de la récupération de la température du processeur graphique" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "" #~ "Saute quelques valeurs pour la carte-graphique (besoin d'être super-" #~ "utilisateur)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "" #~ "échec lors de l'allocation de la mémoire pour le test de performance" #~ msgid "Root privileges are required to work properly" #~ msgstr "" #~ "Les privilèges du super-utilisateur sont requis pour fonctionner " #~ "correctement" #~ msgid "Some information will not be retrievable" #~ msgstr "Quelques données ne seront pas récupérables" #~ msgid "Ignore" #~ msgstr "Ignorer" #~ msgid "Run as root" #~ msgstr "Exécuter en tant que super-utilisateur" #~ msgid "A new version of %s is available!" #~ msgstr "Une nouvelle version de %s est disponible !" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Voulez-vous mettre à jour %s à la version %s après la fermeture du " #~ "programme ?\n" #~ "Cela va écraser le fichier binaire (%s) par la nouvelle version." #~ msgid "Not now" #~ msgstr "Pas maintenant" #~ msgid "Update" #~ msgstr "Mettre à jour" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Vérifie l’existence d'une nouvelle version sur Internet..." #~ msgid "failed to open a Curl session" #~ msgstr "échec lors de l'ouverture d'une session Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "échec lors de l'exécution du transfert pour Curl (%s)" #~ msgid "wrong write data" #~ msgstr "donnée en écriture incorrecte" #~ msgid "(version %s is available)" #~ msgstr "(la version %s est disponible)" #~ msgid "No new version available" #~ msgstr "Pas de nouvelle version de disponible" #~ msgid "(up-to-date)" #~ msgstr "(à jour)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "une erreur est survenue lors de l'extraction de l'archive %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "L'accès au réseau est désactivé par une variable d'environnement " #~ "(définissez CPUX_NETWORK avec une valeur positive pour l'activer)" #~ msgid "failed to open %s archive for writing" #~ msgstr "échec lors de l'ouverture en écriture de l'archive %s" #~ msgid "Downloading new version..." #~ msgstr "Téléchargement de la nouvelle version..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "échec lors du téléchargement de l'archive %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Extraction de la nouvelle version..." #~ msgid "Applying new version..." #~ msgstr "Application de la nouvelle version..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "" #~ "une erreur est survenue pendant la suppression/le renommage des fichiers" #~ msgid "Update successful!" #~ msgstr "Mise à jour réussie !" #~ msgid "Update portable version if a new version is available" #~ msgstr "" #~ "Mettre à jour la version portable si une nouvelle version est disponible" #~ msgid "Temporarily disable network support" #~ msgstr "Désactive le support du réseau temporairement" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Compilé le %s à %s (avec %s %s sur %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Désolé, vous ne pouvez pas mettre à jour %s : la version portable 32 bits " #~ "n'est plus supportée." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Si vous voulez mettre à jour, appuyez sur la touche 'u', ou bien " #~ "n'importe quoi d'autre pour passer.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s va être mis à jour." CPU-X-4.2.0/po/hu.po000066400000000000000000000433721403012130000137340ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # PB , 2020. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-09-20 04:39+0000\n" "Last-Translator: PB \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 4.3-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "CPU technológia meghatározása" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s asszociatív, %d-%s vonalméret" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuid hívása sikertelen (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "CPU szorzók kiszámítása" #: core.c:521 msgid "Calling dmidecode" msgstr "dmidecode hívása" #: core.c:554 msgid "Calculating CPU usage" msgstr "CPU használat kiszámítása" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "A %s helyen lévő grafikus kártyához nincs kernel driver betöltve" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Ismeretlen GPU driver: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Ismeretlen GPU driver: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "libcpuid hívása sikertelen (%s)" #: core.c:817 msgid "Finding devices" msgstr "Eszközök keresése" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Ismeretlen GPU gyártó: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "nem sikerült a lapkakészlet gyártójának és modelljének meghatározása" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" "nem sikerült a grafikus kártya gyártójának és modelljének meghatározása" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "Nincs" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i nap, %i óra, %i perc, %i másodperc" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u perc" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inaktív" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Nincs elindítva" #: core.c:1380 msgid "Active" msgstr "Aktív" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u óra van hátra)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u perc van hátra)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u másodperc van hátra)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "%u óra múlva" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "%u perc múlva" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "%u másodperc múlva" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "GTK GUI indítása…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "%i. mag" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processzor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Gyártó" #: main.c:61 msgid "Code Name" msgstr "Kódnév" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "Technológia" #: main.c:64 msgid "Voltage" msgstr "Feszültség" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "Család" #: main.c:67 msgid "Ext. Family" msgstr "Kit. Család" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modell" #: main.c:69 msgid "Ext. Model" msgstr "Kit. Modell" #: main.c:70 msgid "Temp." msgstr "Hőm." #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "Utasítások" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "Mag sebessége" #: main.c:76 msgid "Multiplier" msgstr "Szorzó" #: main.c:77 msgid "Bus Speed" msgstr "Buszsebesség" #: main.c:78 main.c:155 msgid "Usage" msgstr "Kihasználtság" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "L1 adat" #: main.c:82 msgid "L1 Inst." msgstr "L1 utas." #: main.c:83 msgid "Level 2" msgstr "Level 2" #: main.c:84 msgid "Level 3" msgstr "Level 3" #: main.c:86 msgid "Socket(s)" msgstr "Foglalat(ok)" #: main.c:87 msgid "Core(s)" msgstr "Mag(ok)" #: main.c:88 msgid "Thread(s)" msgstr "Szál(ak)" #: main.c:91 msgid "Caches" msgstr "Gyorsítótár" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Alaplap" #: main.c:104 msgid "Manufacturer" msgstr "Gyártó" #: main.c:106 msgid "Revision" msgstr "Revízió" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Márka" #: main.c:110 msgid "Version" msgstr "Verzió" #: main.c:111 msgid "Date" msgstr "Dátum" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "Lapkakészlet" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memória" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "Használt" #: main.c:137 msgid "Buffers" msgstr "Puffer" #: main.c:138 msgid "Cached" msgstr "Gyorsítótárazott" #: main.c:139 msgid "Free" msgstr "Szabad" #: main.c:140 msgid "Swap" msgstr "Cserehely" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Verzió" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Feszültség" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Memória" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "Pontszám" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "Szál" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s egy szabad szoftver, amely a processzorról, alaplapról\n" "és egyéb hardverekről jelenít meg információt." #: main.c:185 #, c-format msgid "Version %s" msgstr "Verzió: %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "Verziószám kiírása és kilépés" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s verzió: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "libcpuid hívása sikertelen (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 #, fuzzy #| msgid "Caches" msgid "Caches tab:" msgstr "Gyorsítótár" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "VÉGZETES HIBA: nem sikerült memóriát foglalni" #: cpu-x.h:92 msgid "bytes" msgstr "bájt" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "MB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "GB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "TB" CPU-X-4.2.0/po/id.po000066400000000000000000000605361403012130000137150ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Aunur Rofik , 2018 # Syahmin Sukhairi , 2019, 2021. # Allan Nordhøy , 2020. # Fredianto , 2020. # william mahagintha , 2020. # Reza Almanda , 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-02-23 09:50+0000\n" "Last-Translator: Reza Almanda \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 4.5\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Menemukan Teknologi CPU" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "CPU Anda tidak ada dalam basis data ==> %s, model: %i, model luar: %i, " "keluarga luar: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d -arah" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d -arah" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s asosiatif, %d-%s ukuran batas byte" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Memanggil libcpuid untuk mengambil data statis" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "gagal memanggil libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Memanggil libcpuid untuk mengambil data dinamis" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Memanggil libcpuid untuk mengambil nilai statik CPU MSR" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Memanggil libcpuid untuk mengambil nilai dinamis MSR CPU" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Menghitung pengali CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Memanggil dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Menghitung penggunaan CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Memanggil bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" "Tidak ada drivel kernel yang digunakan oleh kartu grafis pada alamat %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Driver kernel GPU Anda tidak diketahui: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Driver mode pengguna GPU Anda tidak diketahui: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "gagal memanggil GLFW (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Mencari perangkat" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Lewati pencarian perangkat (kesalahan izin pada perangkat %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Vendor GPU Anda tidak diketahui: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "pencarian model dan vendor chipset gagal" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "pencarian model dan vendor kartu grafis gagal" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Mengambil clocks GPU" #: core.c:990 msgid "None" msgstr "Tidak ada" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Diver GPU %u tidak melaporkan frekuensi" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "gagal mengambil clocks GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Mengidentifikasi sistem yang berjalan" #: core.c:1208 msgid "failed to identify running system" msgstr "Identifikasi sistem yang berjalan telah gagal" #: core.c:1249 msgid "Calling libprocps" msgstr "Memanggil libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Memanggil libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i hari, %i jam, %i menit, %i detik" #: core.c:1366 msgid "Updating benchmark status" msgstr "Memperbarui status benchmark" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u menit" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Tidak aktif" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Belum dimulai" #: core.c:1380 msgid "Active" msgstr "Aktif" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u jam lagi)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u menit lagi)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u detik lagi)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "pada %u jam" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "pada %u menit" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "pada %u detik" #: core.c:1414 msgid "Starting benchmark" msgstr "Memulai benchmark" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "Terjadi galat ketika memulai benchmark" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Mencari paket CPU di mode fallback" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Soket CPU Anda tidak ada dalam database ==> %s, nama kode: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Menghitung pengali CPU di mode fallback" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Mengambil informasi motherboard di mode fallback" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "gagal mengambil informasi motherboard (mode fallback)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Mengambil suhu CPU di mode fallback" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "gagal mengambil suhu CPU (mode fallback)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Mengambil voltase CPU di mode fallback" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "gagal mengambil voltase CPU (mode fallback)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Mengambil frekuensi CPU di mode fallback" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "gagal mengambil frekuensi CPU (mode fallback)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: %i tidak dikendalikan" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Memulai GUI GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "gagal mengimpor UI di GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Terkoneksi dengan daemon" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Agen autentikasi polkit tidak ditemukan" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Meminta password untuk memulai daemon di latar" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Memulai daemon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Core #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Atur nama label" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Prosesor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Vendor" #: main.c:61 msgid "Code Name" msgstr "Code Name" #: main.c:62 msgid "Package" msgstr "Paket" #: main.c:63 msgid "Technology" msgstr "Teknologi" #: main.c:64 msgid "Voltage" msgstr "Voltase" #: main.c:65 msgid "Specification" msgstr "Spesifikasi" #: main.c:66 msgid "Family" msgstr "Keluarga" #: main.c:67 msgid "Ext. Family" msgstr "Ekstensi Keluarga" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Model" #: main.c:69 msgid "Ext. Model" msgstr "Model Ekstensi" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Melangkah" #: main.c:72 msgid "Instructions" msgstr "Instruksi" #: main.c:74 msgid "Clocks" msgstr "Clocks" #: main.c:75 msgid "Core Speed" msgstr "Kecepatan Inti" #: main.c:76 msgid "Multiplier" msgstr "Pengali" #: main.c:77 msgid "Bus Speed" msgstr "Kecepatan Bus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Pengunaan" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "Data L1" #: main.c:82 msgid "L1 Inst." msgstr "L1 Inst." #: main.c:83 msgid "Level 2" msgstr "Tingkat 2" #: main.c:84 msgid "Level 3" msgstr "Tingkat 3" #: main.c:86 msgid "Socket(s)" msgstr "Soket" #: main.c:87 msgid "Core(s)" msgstr "Inti" #: main.c:88 msgid "Thread(s)" msgstr "Thread(s)" #: main.c:91 msgid "Caches" msgstr "Caches" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i Cache" #: main.c:96 msgid "Size" msgstr "Ukuran" #: main.c:97 msgid "Speed" msgstr "Kecepatan" #: main.c:99 msgid "Test" msgstr "Tes" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Papan Induk" #: main.c:104 msgid "Manufacturer" msgstr "Manufaktur" #: main.c:106 msgid "Revision" msgstr "Revisi" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Merek" #: main.c:110 msgid "Version" msgstr "Versi" #: main.c:111 msgid "Date" msgstr "Tanggal" #: main.c:112 msgid "ROM Size" msgstr "Ukuran ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memori" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Bank %i" #: main.c:123 msgid "Reference" msgstr "Referensi" #: main.c:127 msgid "System" msgstr "Sistem" #: main.c:128 msgid "Operating System" msgstr "Sistem Operasi" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribusi" #: main.c:131 msgid "Hostname" msgstr "Hostname" #: main.c:132 msgid "Uptime" msgstr "Uptime" #: main.c:133 msgid "Compiler" msgstr "Penyusun" #: main.c:136 msgid "Used" msgstr "Digunakan" #: main.c:137 msgid "Buffers" msgstr "Buffers" #: main.c:138 msgid "Cached" msgstr "Dalam cache" #: main.c:139 msgid "Free" msgstr "Gratis" #: main.c:140 msgid "Swap" msgstr "Tukar" #: main.c:143 msgid "Graphics" msgstr "Grafis" #: main.c:147 #, c-format msgid "Card %i" msgstr "Kartu %i" #: main.c:149 msgid "Driver" msgstr "Driver" #: main.c:150 msgid "UMD Version" msgstr "Versi UMD" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatur" #: main.c:156 msgid "Core Voltage" msgstr "Voltase Inti" #: main.c:157 msgid "Power Avg" msgstr "Daya Rata-rata" #: main.c:158 msgid "GPU clock" msgstr "GPU clock" #: main.c:159 msgid "Memory clock" msgstr "Memori Clock" #: main.c:160 msgid "Memory Used" msgstr "Memori yang digunakan" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Kartu %i" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Nomor prima (lambat)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Nomor prima (cepat)" #: main.c:170 msgid "Score" msgstr "Skor" #: main.c:171 msgid "Run" msgstr "Jalankan" #: main.c:174 msgid "Parameters" msgstr "Parameter" #: main.c:175 msgid "Duration" msgstr "Durasi" #: main.c:176 msgid "Threads" msgstr "Threads" #: main.c:179 main.c:184 msgid "About" msgstr "Tentang" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s adalah perangkat lunak gratis yang mengumpulkan informasi\n" "CPU, motherboard, dan lainnya." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versi %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Pencipta: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Situs: %s" #: main.c:189 msgid "License" msgstr "Lisensi" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Perangkat lunak ini didistribusikan di bawah aturan %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Program ini hadir dengan TANPA JAMINAN" #: main.c:265 msgid "Dumping data…" msgstr "Membuang data…" #: main.c:308 msgid "Freeing memory" msgstr "Mengosongkan memori" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Mulai antarmuka pengguna grafis (GUI) (default)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Memulai antarmuka pengguna berbasis teks (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Buang semua data pada keluaran standar dan keluar" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Jalankan perintah dmidecode dan keluar" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Jalankan perintah bandwidth dan keluar" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Atur waktu khusus antara dua penyegaran (dalam detik)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Setel tab default (integer)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Pilih inti CPU untuk dipantau (integer)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "Setel pengujian bandwidth khusus untuk kecepatan cache CPU (integer)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Setel tab default (integer)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Mulai dan sambungkan daemon" #: main.c:347 msgid "Verbose output" msgstr "Keluaran verbose" #: main.c:348 msgid "Print help and exit" msgstr "Cetak bantuan dan keluar" #: main.c:349 msgid "Print version and exit" msgstr "Cetak versi dan keluar" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "Cetak nilai desimal CPUID (defaultnya adalah heksadesimal)" #: main.c:351 msgid "Disable colored output" msgstr "Nonaktifkan keluaran berwarna" #: main.c:352 msgid "Print information for debugging" msgstr "Cetak informasi untuk debugging" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Cetak informasi yang diperlukan untuk ditempelkan dalam issue" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Setel pemetaan kunci untuk mode NCurses (a [baris] | e [macs] | i [nverted-" "T] | v [im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Tambahkan argumen baris perintah default" #: main.c:366 msgid "Enforce the bus clock" msgstr "Terapkan jam bus" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Abaikan frekuensi CPU yang dilaporkan oleh libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Baca data mentah CPUID dari file tertentu" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Hanya mencetak pesan jika CPU tidak ada dalam basisdata" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Pengunaan: %s Tampilan [Opsi]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "TAMPILAN yang tersedia:" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPSI yang tersedia:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variabel lingkungan yang dapat dipengaruhi:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Ini adalah perangkat lunak gratis: Anda bebas mengubah dan " "mendistribusikannya kembali." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Lihat %s lisensi: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s versi: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "gagal memanggil wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s Ups, ada yang salah! %s telah menerima sinyal %d (%s) dan jatuh. %s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Anda dapat menempelkan backtrace ini dengan membuka issue baru di sini:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "timbul galat saat menyetel lokal" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Memulai NCurses TUI…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "KESALAHAN FATAL: database terminfo tidak dapat ditemukan (coba atur variabel " "lingkungan TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Gagal menyetel terminal %s (err=%i); kembali ke %s" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Jendela terlalu kecil!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Tekan 'h' untuk melihat bantuan.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Selamat datang di %s bantuan NCurses!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Bantuan ini menjelaskan cara menggunakan Antarmuka Pengguna berbasis Teks.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Kunci global:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tTekan tombol 'kiri' untuk beralih di tab kiri.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tTekan tombol 'kanan' untuk beralih di tab kanan.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tTekan tombol 'h' untuk melihat bantuan ini.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tTekan 'q' untuk keluar.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "tab CPU:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tTekan tombol 'bawah' untuk mengurangi nomor inti yang akan dipantau.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "\tTekan tombol 'atas' untuk menambah nomor inti yang akan dipantau.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Tab cache:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tTekan tombol 'bawah' untuk beralih ke tes sebelumnya.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tTekan tombol 'atas' untuk beralih ke tes berikutnya.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Tab Pengujian:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "\tTekan tombol 'bawah' untuk mengurangi durasi pengujian.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "\tTekan tombol 'atas' untuk menambah durasi pengujian.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tTekan tombol 'next page' untuk mengurangi jumlah thread yang akan " "digunakan.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tTekan tombol 'previous page' untuk menambah jumlah thread yang akan " "digunakan.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tTekan 's untuk memulai / menghentikan benchmark bilangan prima (lambat).\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tTekan tombol 'f' untuk memulai / menghentikan benchmark bilangan prima " "(cepat).\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafis" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tTekan tombol 'bawah' untuk beralih ke tes sebelumnya.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tTekan tombol 'atas' untuk beralih ke tes berikutnya.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Tekan tombol apa saja untuk keluar dari bantuan ini.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "unit string '%s' pada posisi %i tidak ditemukan" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "String '%s' terlalu panjang, mengecilkan…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "kesalahan terjadi saat membuka file '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "galat terjadi saat menjalankan perintah '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "gagal membuka direktori %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "timbul galat saat mengompilasi regex" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: otorisasi tidak dapat diperoleh (dialog ditutup)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: otorisasi tidak dapat diperoleh (tidak diizinkan)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: perintah tidak ditemukan" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: kode kesalahan tak terduga" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "GALAT: tidak bisa mengalokasikan memori" #: cpu-x.h:92 msgid "bytes" msgstr "Bita" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "Keluar %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Lewati pembukaan MSR CPU (harus di-root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "gagal membuka CPU MSR (%s)" CPU-X-4.2.0/po/it.po000066400000000000000000000674641403012130000137440ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Davide Neri , 2019. # Allan Nordhøy , 2020. # Pierfrancesco Passerini , 2020, 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-23 15:29+0000\n" "Last-Translator: Pierfrancesco Passerini \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 4.5.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Ricerca specifiche della CPU" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "La tua CPU non è nel database ==> %s, modello: %i, modello esteso: %i, " "famiglia estesa: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d vie" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d vie" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s associativa, linee da %d-%s byte" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Chiamata a libcpuid per recuperare i dati statici" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "errore nella chiamata a libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Chiamata a libcpuid per recuperare i dati dinamici" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Chiamata a libcpuid per recuperare i valori statici dal MSR della CPU" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Chiamata a libcpuid per recuperare i dati dinamici dal MSR della CPU" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Calcolo dei moltiplicatori della CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Chiamata a dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Calcolo l'utilizzo della CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Chiamata a bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Nessun kernel driver in uso per la scheda grafica in %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Il driver (kernel) della GPU è sconosciuto: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Il driver (user mode) della GPU è sconosciuto: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "impossibile eseguire GLFW (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Ricerca delle periferiche" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" "Ignora la ricerca delle periferiche (autorizzazioni errate sul dispositivo " "%s )" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Il produttore della tua GPU è sconosciuto: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "errore nella ricerca del produttore e del modello del chipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "errore nella ricerca del produttore e del modello della scheda grafica" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Recupero le frequenze della CPU" #: core.c:990 msgid "None" msgstr "Nessuna" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Il driver della GPU %u non restituisce le frequenze" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "impossibile recuperare le frequenze della GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Identificazione del sistema in uso" #: core.c:1208 msgid "failed to identify running system" msgstr "identificazione del sistema in uso non riuscita" #: core.c:1249 msgid "Calling libprocps" msgstr "Chiamata a libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Chiamata a libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i giorni, %i ore, %i minuti, %i secondi" #: core.c:1366 msgid "Updating benchmark status" msgstr "Aggiornano lo stato dei benchmark" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u minuti" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inattivo" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Non iniziato" #: core.c:1380 msgid "Active" msgstr "Attivo" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u ore rimaste)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minuti rimasti)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u secondi rimasti)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "in %u ore" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "in %u minuti" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "in %u secondi" #: core.c:1414 msgid "Starting benchmark" msgstr "Inizio dei benchmark" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "è intervenuto un errore all'avvio del benchmark" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Ricerca del socket della CPU in modalità alternativa" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Il socket della tua CPU non è nel database ==> %s, nome in codice: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Calcolo dei moltiplicatori della CPU in modalità alternativa" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Recupero delle informazioni della scheda madre in modalità alternativa" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" "impossibile recuperare le informazione della scheda madre (modalità " "alternativa)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Recupero della temperatura della CPU in modalità alternativa" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "impossibile recuperare la temperatura della CPU (modalità alternativa)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Recupero del voltaggio della CPU in modalità alternativa" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "impossibile recuperare il voltaggio della CPU (modalità alternativa)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Recupero della frequenza della CPU in modalità alternativa" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "impossibile recuperare la frequenza della CPU (modalità alternativa)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: evento %i non gestito" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Avvio interfaccia GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "importazione dell'interfaccia in GtkBuilder non riuscita" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Connesso al demone" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Non ho trovato nessun agente polkit per l'autenticazione" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Richiedi la password per avviare il demone in background" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Avvia demone" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Core #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Imposto i nomi delle etichette" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processore" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Produttore" #: main.c:61 msgid "Code Name" msgstr "Codice" #: main.c:62 msgid "Package" msgstr "Socket" #: main.c:63 msgid "Technology" msgstr "Tecnologia" #: main.c:64 msgid "Voltage" msgstr "Voltaggio" #: main.c:65 msgid "Specification" msgstr "Specifica" #: main.c:66 msgid "Family" msgstr "Famiglia" #: main.c:67 msgid "Ext. Family" msgstr "Famiglia estesa" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modello" #: main.c:69 msgid "Ext. Model" msgstr "Modello esteso" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Stepping" #: main.c:72 msgid "Instructions" msgstr "Istruzioni" #: main.c:74 msgid "Clocks" msgstr "Frequenze" #: main.c:75 msgid "Core Speed" msgstr "Velocità del core" #: main.c:76 msgid "Multiplier" msgstr "Moltiplicatore" #: main.c:77 msgid "Bus Speed" msgstr "Velocità del bus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Utilizzo" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "Dati L1" #: main.c:82 msgid "L1 Inst." msgstr "Istr. L1" #: main.c:83 msgid "Level 2" msgstr "Livello 2" #: main.c:84 msgid "Level 3" msgstr "Livello 3" #: main.c:86 msgid "Socket(s)" msgstr "Socket" #: main.c:87 msgid "Core(s)" msgstr "Core" #: main.c:88 msgid "Thread(s)" msgstr "Thread" #: main.c:91 msgid "Caches" msgstr "Cache" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Cache L%i" #: main.c:96 msgid "Size" msgstr "Dimensione" #: main.c:97 msgid "Speed" msgstr "Velocità" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Scheda madre" #: main.c:104 msgid "Manufacturer" msgstr "Produttore" #: main.c:106 msgid "Revision" msgstr "Revisione" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marca" #: main.c:110 msgid "Version" msgstr "Versione" #: main.c:111 msgid "Date" msgstr "Data" #: main.c:112 msgid "ROM Size" msgstr "Dimensione ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memoria" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banco %i" #: main.c:123 msgid "Reference" msgstr "Riferimento" #: main.c:127 msgid "System" msgstr "Sistema" #: main.c:128 msgid "Operating System" msgstr "Sistema operativo" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribuzione" #: main.c:131 msgid "Hostname" msgstr "Hostname" #: main.c:132 msgid "Uptime" msgstr "Uptime" #: main.c:133 msgid "Compiler" msgstr "Compilatore" #: main.c:136 msgid "Used" msgstr "Utilizzati" #: main.c:137 msgid "Buffers" msgstr "Buffer" #: main.c:138 msgid "Cached" msgstr "In cache" #: main.c:139 msgid "Free" msgstr "Liberi" #: main.c:140 msgid "Swap" msgstr "Swap" #: main.c:143 msgid "Graphics" msgstr "Grafica" #: main.c:147 #, c-format msgid "Card %i" msgstr "Scheda %i" #: main.c:149 msgid "Driver" msgstr "Driver" #: main.c:150 msgid "UMD Version" msgstr "Versione UMD" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatura" #: main.c:156 msgid "Core Voltage" msgstr "Voltaggio Core" #: main.c:157 msgid "Power Avg" msgstr "Potenza media" #: main.c:158 msgid "GPU clock" msgstr "Frequenza GPU" #: main.c:159 msgid "Memory clock" msgstr "Frequenza della memoria" #: main.c:160 msgid "Memory Used" msgstr "Memoria in uso" #: main.c:162 msgid "Cards" msgstr "Schede %i" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Numeri primi (lento)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Numeri primi (veloce)" #: main.c:170 msgid "Score" msgstr "Punteggio" #: main.c:171 msgid "Run" msgstr "Esegui" #: main.c:174 msgid "Parameters" msgstr "Parametri" #: main.c:175 msgid "Duration" msgstr "Durata" #: main.c:176 msgid "Threads" msgstr "Thread" #: main.c:179 main.c:184 msgid "About" msgstr "Informazioni" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s è software libero che raccoglie informazioni\n" "su CPU, scheda grafica e altre." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versione %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autore: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Sito: %s" #: main.c:189 msgid "License" msgstr "Licenza" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Questo software è distribuito nei termini della %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Questo programma è distribuito SENZA ALCUNA GARANZIA" #: main.c:265 msgid "Dumping data…" msgstr "Salvataggio dei dati…" #: main.c:308 msgid "Freeing memory" msgstr "Libero la memoria" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Avvio dell'interfaccia utente grafica (GUI) (default)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Avvio dell'interfaccia utente testuale (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Scarica tutti i dati sull'output standard ed esci" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Esegui il comando incorporato dmidecode ed esci" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Esegui il comando incorporato bandwidth ed esci" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Imposta intervallo personalizzato tra due aggiornamenti (in secondi)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Imposta scheda di default (intero)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Scegli core CPU da monitorare (intero)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Imposta test della larghezza di banda personalizzato per la velocità della " "cache della CPU (intero)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "Imposta la scheda grafica predefinita (intero)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Avvia e connettiti al demone" #: main.c:347 msgid "Verbose output" msgstr "Output esteso" #: main.c:348 msgid "Print help and exit" msgstr "Stampa la guida ed esci" #: main.c:349 msgid "Print version and exit" msgstr "Stampa il numero di versione ed esci" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" "Stampa i valori CPUID in decimale (esadecimale per impostazione predefinita)" #: main.c:351 msgid "Disable colored output" msgstr "Disattiva l'output colorato" #: main.c:352 msgid "Print information for debugging" msgstr "Stampa le informazioni per il debug" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" "Stampa le informazioni necessarie da incollare in un rapporto di errore" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Imposta la mappatura dei tasti per la modalità NCurses (a[rrows]|e[macs]|" "i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Aggiungi opzioni predefinite per la riga di comando" #: main.c:366 msgid "Enforce the bus clock" msgstr "Forza la frequenza del bus" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignora la frequenza della CPU riportata da libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Leggi i dati grezzi di CPUID da un determinato file" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Stampa un messaggio solo se la CPU non è nel database" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Utilizzo: %s DISPLAY [OPZIONI]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "DISPLAY disponibile:" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPZIONI disponibili:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variabili di ambiente influenzabili:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Questo è un software libero: sei libero/a di modificarlo e ridistribuirlo." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Visualizza la licenza %s: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- versione %-9s: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "impossibile eseguire wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s Ops, qualcosa è andato storto! %s ha ricevuto il segnale %d (%s) e si è " "bloccato.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Puoi incollare questo backtrace aprendo un nuovo rapporto qui:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "è intervenuto un errore mentre si impostava la localizzazione" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Avvia interfaccia testuale NCurses…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ERRORE FATALE: impossibile trovare il database terminfo (provare ad " "impostare la variabile di ambiente TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Impossibile impostare il terminale %s (err=%i); verrà utilizzato %s" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "La finestra è troppo piccola!" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "Premi 'h' per visualizzare la guida." #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Benvenuto/a nella guida Ncurses di %s!\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "Questa guida descrive come usare questa interfaccia testuale." #: tui_ncurses.c:477 msgid "Global keys:" msgstr "Tasti globali:" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "Premi il tasto 'sinistra' per passare alla scheda a sinistra." #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "Premi il tasto 'destra' per passare alla scheda a destra." #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "Premi il tasto 'h' per visualizzare questa guida." #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "Premi il tasto 'q' per uscire." #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "Scheda CPU:" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "Premi 'giù' per diminuire il numero di core da monitorare." #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "Premi 'su' per aumentare il numero di core da monitorare." #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "Scheda cache:" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "Premi il tasto 'giù' per tornare al test precedente." #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "Premi il tasto 'su' per passare al prossimo test." #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "Scheda bench:" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "Premi il tasto 'giù' per diminuire la durata del benchmark." #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "Premi il tasto 'su' per aumentare la durata del benchmark." #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "Premi il tasto 'pagina giù' per diminuire il numero di thread da usare." #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "Premi il tasto 'pagina su' per aumentare il numero di thread da usare." #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "Premi il tasto 's' per avviare/fermare il benchmark dei numeri primi (lento)." #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "Premi il tasto 'f' per avviare/fermare il benchmark dei numeri primi " "(veloce)." #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "Scheda Grafica:" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "Premi il tasto 'giù' per tornare alla precedente scheda grafica." #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "Premi il tasto 'su' per passare alla prossima scheda grafica." #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "Premi qualsiasi tasto per uscire da questa guida." #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "impossibile trovare '%s' nella stringa alla posizione %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "La stringa \"%s\" è troppo lunga, riduzione…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "si è verificato un errore nell'apertura del file '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "si è verificato un errore nell'esecuzione del comando '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "apertura della directory %s fallita" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "è intervenuto un errore alla compilazione delle espressioni regolari" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" "pkexec: non è stato possibile ottenere l'autorizzazione (dialogo respinto)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" "pkexec: non è stato possibile ottenere l'autorizzazione (non autorizzata)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: comando non trovato" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: errore non previsto" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ERRORE FATALE: impossibile allocare memoria" #: cpu-x.h:92 msgid "bytes" msgstr "bytes" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "Uscita %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Ignorando l'apertura del MSR della CPU (richiede accesso root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "Fallimento dell'apertura del MSR della CPU (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Ignorando la chiamata a dmidecode (richiede accesso root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "fallimento ad allocare la memoria per dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "fallimento a chiamare dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Ricerca del driver della scheda grafica" #~ msgid "(%s driver)" #~ msgstr "(driver %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "fallimento della ricerca del driver della scheda grafica (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Recupero della temperatura della GPU" #~ msgid "Off" #~ msgstr "Disattivato" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "fallimento del recupero della temperatura della GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Ignorando alcuni valori della GPU (richiede l'accesso root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "fallimento ad allocare la memoria per il benchmark" #~ msgid "Root privileges are required to work properly" #~ msgstr "Sono necessari i privilegi di root per funzionare correttamente" #~ msgid "Some information will not be retrievable" #~ msgstr "Alcune informazioni non saranno recuperabili" #~ msgid "Ignore" #~ msgstr "Ignora" #~ msgid "Run as root" #~ msgstr "Esegui come root" #~ msgid "A new version of %s is available!" #~ msgstr "È disponibile una nuova versione di %s!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Vuoi aggiornare %s alla versione %s dopo l'uscita?\n" #~ "Questo file binario (%s) sarà cancellato dalla nuova versione." #~ msgid "Not now" #~ msgstr "Non adesso" #~ msgid "Update" #~ msgstr "Aggiornamento" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Cerco su Internet una nuova versione..." #~ msgid "failed to open a Curl session" #~ msgstr "fallimento ad aprire una sessione Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "fallimento ad eseguire un trasferimento (%s)" #~ msgid "wrong write data" #~ msgstr "dati di scrittura sbagliati" #~ msgid "(version %s is available)" #~ msgstr "(la versione %s è disponibile)" #~ msgid "No new version available" #~ msgstr "Nessuna nuova versione disponibile" #~ msgid "(up-to-date)" #~ msgstr "(aggiornato)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "è intervenuto un errore durante l'estrazione dell'archivio %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "L'accesso alla rete è disabilitato da una variabile di ambiente (imposta " #~ "un valore positivo per CPUX_NETWORK per abilitarlo)" #~ msgid "failed to open %s archive for writing" #~ msgstr "fallimento all'apertura dell'archivio %s in scrittura" #~ msgid "Downloading new version..." #~ msgstr "Scaricando la nuova versione..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "fallimento dello scaricamento dell'archivio %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Estraendo la nuova versione..." #~ msgid "Applying new version..." #~ msgstr "Applicando la nuova versione..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "è intervenuto un errore durane la rimozione/rinomina dei file" #~ msgid "Update successful!" #~ msgstr "Aggiornamento riuscito!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Aggiorna la versione portatile se è disponibile una nuova versione" #~ msgid "Temporarily disable network support" #~ msgstr "Disattiva temporaneamente l'accesso alla rete" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Compilato su %s,%s (con %s %s su %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Spiacenti, non puoi aggiornare %s: la versione portatile a 32 bit non è " #~ "più supportata." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Per effettuare l'aggiornamento premi il tasto \"u\", altrimenti qualsiasi " #~ "altro tasto per ignorare.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s sarà aggiornato." CPU-X-4.2.0/po/ja.po000066400000000000000000000610541403012130000137070ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Hayao0819 , 2020, 2021. # Huang Zhiyi , 2020. # Takuro Onoue , 2020. # Umio Yasuno , 2021. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-02-17 08:50+0000\n" "Last-Translator: Umio Yasuno \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 4.5\n" #: core.c:218 msgid "Finding CPU technology" msgstr "CPUテクノロジーを確認中" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "このCPUはデータベースにありませんでした ==> %s、モデル: %i、拡張モデル:%i、" "拡張ファミリー:%i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-way" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-way" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s 連帯, %d-%s 行サイズ" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "静的データを取得するためにlibcpuidを呼び出しています" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuidの呼び出しに失敗しました(%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "動的データを取得するために libcpuid を呼び出しています" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "CPUMSR静的値を取得するために libcpuid を呼び出す" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "動的なCPU MSR値を取得するために libcpuid を呼び出しています" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "クロック倍率を計算しています" #: core.c:521 msgid "Calling dmidecode" msgstr "dmidecode を呼び出す" #: core.c:554 msgid "Calculating CPU usage" msgstr "CPU 使用率の計算" #: core.c:605 msgid "Calling bandwidth" msgstr "帯域幅を呼び出し中" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" "パス %s でグラフィックカードに使用されているカーネルドライバがありません" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "GPUドライバーが不明です: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "GPUドライバーが不明です: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call wordexp (%i)" msgid "failed to call GLFW (%i): %s" msgstr "wordexpの呼び出しに失敗しました(%i)" #: core.c:817 msgid "Finding devices" msgstr "デバイスを探しています" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "デバイス検索をスキップします(デバイス%sの不正なパーミッション)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "不明なベンダー(%s)によるGPUです(0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "チップセットのベンダーとモデルの検索に失敗しました" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "グラフィックカードのベンダーとモデルの検索に失敗しました" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "GPUクロックを取得しています" #: core.c:990 #, fuzzy msgid "None" msgstr "何もありません" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "GPU %u のドライバは温度を報告していません" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "GPUクロックの取得に失敗しました" #: core.c:1205 msgid "Identifying running system" msgstr "実行中のシステムを認識しています" #: core.c:1208 msgid "failed to identify running system" msgstr "実行中のシステムの認識に失敗しました" #: core.c:1249 msgid "Calling libprocps" msgstr "libprocpsを呼び出しています" #: core.c:1275 msgid "Calling libstatgrab" msgstr "libstatgrabを呼び出しています" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i 日 %i 時間 %i 分 %i 秒" #: core.c:1366 msgid "Updating benchmark status" msgstr "ベンチマークの状態を更新しています" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u 分" #: core.c:1369 core.c:1370 #, fuzzy msgid "Inactive" msgstr "停止" #: core.c:1374 core.c:1375 #, fuzzy msgid "Not started" msgstr "開始されていません" #: core.c:1380 #, fuzzy msgid "Active" msgstr "実行" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(残り%u 時間)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(残り%u 分)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(残り%u 秒)" #: core.c:1394 #, fuzzy, c-format msgid "in %u hours" msgstr "%u 時間" #: core.c:1396 #, fuzzy, c-format msgid "in %u minutes" msgstr "%u 分" #: core.c:1398 #, fuzzy, c-format msgid "in %u seconds" msgstr "%u 秒" #: core.c:1414 msgid "Starting benchmark" msgstr "ベンチマークを開始しています" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "ベンチマークの開始中にエラーが発生しました" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "fallbackモードでCPUパッケージの検索中" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "このCPUソケットはデータベースにありませんでした ==> %s、コードネーム: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "fallbackモードでCPU倍率を計算しています" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "fallbackモードでマザーボードの情報を取得しています" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "マザーボードの情報の取得に失敗しました(fallbackモード)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "fallbackモードでCPUの温度を取得しています" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "CPUの温度の取得に失敗しました(fallbackモード)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "fallbackモードでCPUの電圧を取得しています" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "CPUの電圧の取得に失敗しました(fallbackモード)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "fallbackモードでCPUのクロック倍率を取得しています" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "CPUのクロック倍率の取得に失敗しました(fallbackモード)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "要求されたハンドラー: %iは処理されません" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "GTK GUIを開始しています…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "GtkBuilderからのUIのインポートに失敗しました" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "デーモンに接続しました" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Polkit 認証エージェントが見つかりませんでした" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "バックグラウンドでデーモンを起動するためにパスワードが必要です" #: gui_gtk.c:556 msgid "Start daemon" msgstr "デーモンを開始する" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "コア #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "ラベル名を設定" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "プロセッサー" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "ベンダー" #: main.c:61 msgid "Code Name" msgstr "コードネーム" #: main.c:62 msgid "Package" msgstr "パッケージ" #: main.c:63 msgid "Technology" msgstr "テクノロジー" #: main.c:64 msgid "Voltage" msgstr "電圧" #: main.c:65 msgid "Specification" msgstr "仕様" #: main.c:66 msgid "Family" msgstr "ファミリー" #: main.c:67 msgid "Ext. Family" msgstr "拡張ファミリー" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "モデル" #: main.c:69 msgid "Ext. Model" msgstr "拡張モデル" #: main.c:70 msgid "Temp." msgstr "温度" #: main.c:71 msgid "Stepping" msgstr "ステッピング" #: main.c:72 msgid "Instructions" msgstr "命令" #: main.c:74 msgid "Clocks" msgstr "クロック" #: main.c:75 msgid "Core Speed" msgstr "1コアの速度" #: main.c:76 msgid "Multiplier" msgstr "周波数" #: main.c:77 msgid "Bus Speed" msgstr "バススピード" #: main.c:78 main.c:155 msgid "Usage" msgstr "使用量" #: main.c:80 msgid "Cache" msgstr "キャッシュ" #: main.c:81 msgid "L1 Data" msgstr "L1 データ" #: main.c:82 msgid "L1 Inst." msgstr "L1 命令" #: main.c:83 msgid "Level 2" msgstr "レベル2" #: main.c:84 msgid "Level 3" msgstr "レベル3" #: main.c:86 msgid "Socket(s)" msgstr "ソケット" #: main.c:87 msgid "Core(s)" msgstr "コア" #: main.c:88 msgid "Thread(s)" msgstr "スレッド" #: main.c:91 msgid "Caches" msgstr "キャッシュ" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%iキャッシュ" #: main.c:96 msgid "Size" msgstr "サイズ" #: main.c:97 msgid "Speed" msgstr "スピード" #: main.c:99 msgid "Test" msgstr "テスト" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "マザーボード" #: main.c:104 msgid "Manufacturer" msgstr "メーカー" #: main.c:106 msgid "Revision" msgstr "リビジョン" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "ブランド" #: main.c:110 msgid "Version" msgstr "バージョン" #: main.c:111 msgid "Date" msgstr "日付" #: main.c:112 msgid "ROM Size" msgstr "ROMサイズ" #: main.c:114 msgid "Chipset" msgstr "チップセット" #: main.c:119 main.c:135 msgid "Memory" msgstr "メモリー" #: main.c:122 #, c-format msgid "Bank %i" msgstr "バンク %i" #: main.c:123 msgid "Reference" msgstr "リファレンス" #: main.c:127 msgid "System" msgstr "システム" #: main.c:128 msgid "Operating System" msgstr "オペレーティングシステム" #: main.c:129 msgid "Kernel" msgstr "カーネル" #: main.c:130 msgid "Distribution" msgstr "ディストリビューション" #: main.c:131 msgid "Hostname" msgstr "ホスト名" #: main.c:132 msgid "Uptime" msgstr "連続稼働時間" #: main.c:133 msgid "Compiler" msgstr "コンパイラー" #: main.c:136 msgid "Used" msgstr "使用済み" #: main.c:137 msgid "Buffers" msgstr "バッファ" #: main.c:138 msgid "Cached" msgstr "キャッシュ済み" #: main.c:139 msgid "Free" msgstr "フリー" #: main.c:140 msgid "Swap" msgstr "スワップ" #: main.c:143 msgid "Graphics" msgstr "グラフィック" #: main.c:147 #, c-format msgid "Card %i" msgstr "カード %i" #: main.c:149 msgid "Driver" msgstr "ドライバー" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "バージョン" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "温度" #: main.c:156 msgid "Core Voltage" msgstr "コア電圧" #: main.c:157 msgid "Power Avg" msgstr "平均電力" #: main.c:158 msgid "GPU clock" msgstr "GPU クロック" #: main.c:159 msgid "Memory clock" msgstr "メモリークロック" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "メモリー" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "カード %i" #: main.c:165 msgid "Bench" msgstr "ベンチマーク" #: main.c:166 msgid "Prime numbers (slow)" msgstr "素数(スロー)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "素数(ファースト)" #: main.c:170 msgid "Score" msgstr "スコア" #: main.c:171 msgid "Run" msgstr "実行" #: main.c:174 msgid "Parameters" msgstr "パラメータ" #: main.c:175 msgid "Duration" msgstr "デュレーション" #: main.c:176 msgid "Threads" msgstr "スレッド" #: main.c:179 main.c:184 msgid "About" msgstr "CPU-Xについて" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s はCPUやマザーボードなどの情報を\n" "収集する無料のソフトウェアです。" #: main.c:185 #, c-format msgid "Version %s" msgstr "バージョン %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "作者: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "サイト: %s" #: main.c:189 msgid "License" msgstr "ライセンス" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "このソフトウェアは%sのもとで配布されています" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "このプログラムは全て自己責任で使用してください" #: main.c:265 msgid "Dumping data…" msgstr "\"データをダンプしています…" #: main.c:308 msgid "Freeing memory" msgstr "フリーなメモリ" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "グラフィカルユーザインタフェース(GUI)を開始する(デフォルト)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "テキストユーザインタフェース(TUI)を開始する" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "全てのデータを取得し、標準出力して終了します" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "埋め込みコマンド dmidecode を実行して終了します" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "埋め込みコマンド bandwidth を実行して終了します" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "更新の間隔を設定します(秒)" #: main.c:342 msgid "Set default tab (integer)" msgstr "デフォルトのタブを設定します(整数)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "モニタリングするCPUコアを選択します(整数)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "CPUキャッシュ速度の帯域幅テストを設定します(整数)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "デフォルトのタブを設定します(整数)" #: main.c:346 msgid "Start and connect to daemon" msgstr "デーモンを開始、接続します" #: main.c:347 msgid "Verbose output" msgstr "詳細な出力を有効化します" #: main.c:348 msgid "Print help and exit" msgstr "ヘルプメッセージを表示して終了します" #: main.c:349 msgid "Print version and exit" msgstr "バージョンを表示して終了します" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "CPUIDの値を10進数で表示します (デフォルトでは16進数です)" #: main.c:351 msgid "Disable colored output" msgstr "色のついた出力を無効化します" #: main.c:352 msgid "Print information for debugging" msgstr "デバッグのための情報を表示します" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Issueに貼り付けるために必要な情報を表示します" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "NCursesモードのキーマッピングを設定します(a[rrows]|e[macs]|i[nverted-T]|" "v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "デフォルトのコマンドライン引数を追加します" #: main.c:366 msgid "Enforce the bus clock" msgstr "バスクロックを適用する" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "libcpuidから取得したCPUクロックを無視します" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "生のCPUIDデータを与えられたファイルから読み込みます" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "CPUがデータベースに存在しない場合のみメッセージを出力します" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "使い方: %s 表示(オプション)\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "利用可能な表示方法:" #: main.c:403 msgid "Available OPTIONS:" msgstr "利用可能なオプション:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "影響力のある環境変数:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "これはフリーソフトウェアです: 自由に変更して再配布することができます。" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "%s ライセンスを見てください: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s バージョン: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "wordexpの呼び出しに失敗しました(%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s何かが間違っています! %s はシグナル %d (%s)を受け取ってクラッシュしまし" "た。%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "ここで新しいIssueを開いてバックトレースを貼り付けることができます。" #: main.c:705 msgid "an error occurred while setting locale" msgstr "ロケールの設定中にエラーが発生しました" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "NCurses TUI を開始しています…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "致命的なエラー: terminfoデータベースが見つかりませんでした(TERMINFO環境変数" "を設定してください)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" "ターミナル %s のセットアップに失敗しました(エラー%i); %sにFalbackします" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "ウィンドウが小さすぎます\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "ヘルプを見るには「h」キーを押してください。\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "%sのNCursesヘルプへようこそ\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "グローバルキー:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tqを押して終了します。\n" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' key to see this help." msgstr "ヘルプを見るには「h」キーを押してください。\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tqを押して終了します。\n" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 #, fuzzy #| msgid "Caches" msgid "Caches tab:" msgstr "キャッシュ" #: tui_ncurses.c:488 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press 'down' key to switch to previous test." msgstr "" "\n" "終了するには何かキを押してください\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tqを押して終了します。\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "Bench" msgid "Bench tab:" msgstr "ベンチマーク" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "グラフィック" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "終了するには何かキを押してください\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "「%s」文字列が%iのにユニットが見つかりません" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "ディレクトリ %s を開けませんでした" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: 認証を取得できませんでした(認証されていません)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: コマンドが見つかりませんでした" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: 予期しないエラーコード" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "bytes" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "MB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "GB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "TB" CPU-X-4.2.0/po/ko.po000066400000000000000000000400331403012130000137200ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # bluepencil , 2019. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2019-07-16 16:25+0000\n" "Last-Translator: bluepencil \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 3.8-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "메모리를 재할당할 수 없습니다" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/lv.po000066400000000000000000000464511403012130000137420ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Anton Kochubey , 2020. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-07-11 09:41+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Latvian \n" "Language: lv\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 == 0 || n % 100 >= 11 && n % 100 <= " "19) ? 0 : ((n % 10 == 1 && n % 100 != 11) ? 1 : 2);\n" "X-Generator: Weblate 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Procesora tehnoloģijas noteikšana" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Jūsu procesors nav atrasts datubāzē ==> %s, modelis: %i, papl. modelis: %i, " "papl. ģimene: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-direkcionāls" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-direkcionāls" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Izsaucu libcpuid statisko datu saņemšanai" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuid izsaukšana neveiksmīga (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Izsaucu libcpuid dinamisko datu saņemšanai" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Izsaucu libcpuid procesora MSR statisko vērtību nolasīšanai" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Izsaucu libcpuid procesora MSR dinamisko vērtību nolasīšanai" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Izrēķinu CPU frekvences reizinātākus" #: core.c:521 msgid "Calling dmidecode" msgstr "Izsaucu dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Izrēķinu procesora pielietojumu" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Jūsu GPU draiveris nav zināms: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Jūsu GPU draiveris nav zināms: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "libcpuid izsaukšana neveiksmīga (%s)" #: core.c:817 msgid "Finding devices" msgstr "Ierīču meklēšana" #: core.c:829 #, fuzzy, c-format #| msgid "Skip devices search (need to be root)" msgid "Skip devices search (wrong permissions on %s device)" msgstr "Ierīču meklēšana tiek izlaista (nepieciešamas root tiesības)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Jūsu GPU ražōtājs ir nezināms: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "nav iespējams noteikt mikroshēmojuma ražotāju un modeli" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "nav iespējams noteikt grafiskā akseleratora ražotāju un modeli" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "GPU frekvences nolasīšana" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "GPU %u draiveris neatbalsta frekvenču nolasīšanu" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "GPU frekvenču nolasīšana neveiksmīga" #: core.c:1205 msgid "Identifying running system" msgstr "Darbojošās sistēmas noteikšana" #: core.c:1208 msgid "failed to identify running system" msgstr "Nav iespējams noteikt darbojošo sistēmu" #: core.c:1249 msgid "Calling libprocps" msgstr "Izsauc libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Izsauc libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dienas, %i stundas, %i minūtes, %i sekundes" #: core.c:1366 msgid "Updating benchmark status" msgstr "Atjauno darbspējas mērījuma statusu" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u minūtes" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Nav aktīvs" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Nav palaists" #: core.c:1380 msgid "Active" msgstr "Aktīvs" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(palika %u stundas)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(palika %u minūtes)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(palika %u sekundes)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "pēc %u stundām" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "pēc %u minūtēm" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "pēc %u sekundēm" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Jūsu procesors nav atrasts datubāzē ==> %s, modelis: %i, papl. modelis: %i, " "papl. ģimene: %i" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "failed to find graphic card driver (%s)" msgid "Select default graphic card (integer)" msgstr "nav atrasts grafiskā akseleratora draiveris (%s)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "libcpuid izsaukšana neveiksmīga (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "nav iespējams izdalīt atmiņu" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Iziešana no %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "Tiek izlaista procesora MSR nolasīšana (nepieciešamas root tiesības)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "Nav iespējams nolasīt procesora MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Tiek izlaista dmidecode izsaukšana (nepieciešamas root tiesības)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "Nav iespējams izdalīt atmiņu priekš dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "Nav iespējams izsaukt dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Grafikas akseleratora draivera meklēšana" #~ msgid "(%s driver)" #~ msgstr "(%s draiveris)" #~ msgid "Retrieving GPU temperature" #~ msgstr "GPU temperatūras nolasīšana" #~ msgid "Off" #~ msgstr "Izslēgts" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "GPU temperatūras noteikšana neveiksmīga" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Izlaist dažus GPU parametrus (nepieciešamas root tiesības)" CPU-X-4.2.0/po/mr.po000066400000000000000000001152031403012130000137270ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Prachi Joshi , 2019, 2020. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-11-20 19:28+0000\n" "Last-Translator: Prachi Joshi \n" "Language-Team: Marathi \n" "Language: mr\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 4.4-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "CPU तंत्रज्ञान शोधत आहे" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "आपला सीपीयू डेटाबेसमध्ये उपस्थित नाही==>%s,मॉडेल: %i, ext. मॉडेल: %i, ext. परिवार: " "%i मध्ये नाही" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-way" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s,%d-वे" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s सहकारी,%d-%s लाइन आकार" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "स्थिर डेटा पुनर्प्राप्त करण्यासाठी libcpuid वर कॉल करीत आहे" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuid (%s) वर कॉल करण्यात अयशस्वी" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "डायनॅमिक डेटा पुनर्प्राप्त करण्यासाठी libcpuid वर कॉल करीत आहे" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "सीपीयू एमएसआर स्थिर मूल्ये प्राप्त करण्यासाठी लिबकप्यूईडवर कॉल करीत आहे" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "सीपीयू एमएसआर डायनॅमिक मूल्ये पुनर्प्राप्त करण्यासाठी लिबकप्यूईड कॉल करीत आहे" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "सीपीयू गुणकांची गणना करत आहे" #: core.c:521 msgid "Calling dmidecode" msgstr "डीमिडेकोडला कॉल करीत आहे" #: core.c:554 msgid "Calculating CPU usage" msgstr "सीपीयू वापराची गणना करत आहे" #: core.c:605 msgid "Calling bandwidth" msgstr "कॉलिंग बँडविड्थ" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "पथ %s वर ग्राफिक कार्ड करीता कर्नल ड्राइव्हर वापरात नाही" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "आपला GPU ड्राइव्हर अज्ञात आहे: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "आपला GPU ड्राइव्हर अज्ञात आहे: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "libcpuid (%s) वर कॉल करण्यात अयशस्वी" #: core.c:817 msgid "Finding devices" msgstr "उपकरणे शोधत आहे" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "डिव्हाइस शोध वगळा (%s डिव्हाइसवर चुकीच्या परवानग्या)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "आपला GPU विक्रेता अज्ञात आहे: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "चिपसेट विक्रेता आणि मॉडेल शोधण्यात अयशस्वी" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "ग्राफिक कार्ड विक्रेता आणि मॉडेल शोधण्यात अयशस्वी" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "GPU घड्याळे प्राप्त करीत आहे" #: core.c:990 msgid "None" msgstr "काहीही नाही" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "GPU %u साठी ड्राइव्हर वारंवारिता नोंदवत नाही" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "GPU घड्याळे प्राप्त करण्यात अयशस्वी" #: core.c:1205 msgid "Identifying running system" msgstr "कार्यरत प्रणाली ओळखत आहे" #: core.c:1208 msgid "failed to identify running system" msgstr "चालू प्रणाली ओळखण्यात अयशस्वी" #: core.c:1249 msgid "Calling libprocps" msgstr "libprocps ला कॉल करीत आहे" #: core.c:1275 msgid "Calling libstatgrab" msgstr "libstatgrab ला कॉल करीत आहे" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i दिवस, %i तास, %i मिनिटे, %i सेकंद" #: core.c:1366 msgid "Updating benchmark status" msgstr "बेंचमार्क स्थिती अद्यतनित करीत आहे" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u मि" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "निष्क्रीय" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "सुरू झाले नाही" #: core.c:1380 msgid "Active" msgstr "सक्रीय" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u तास बाकी)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u मिनिटे बाकी)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u सेकंद शिल्लक)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "%u तासात" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "%u मिनिटात" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "%u सेकंदात" #: core.c:1414 msgid "Starting benchmark" msgstr "बेंचमार्क सुरू करीत आहे" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "बेंचमार्क सुरू करताना एक त्रुटी आली" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "फॉलबॅक मोडमध्ये सीपीयू पॅकेज शोधत आहे" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "आपला सीपीयू सॉकेट डेटाबेसमध्ये उपस्थित नाही==>%s, कोडनाव:%s मध्ये संबंधित नाही" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "फॉलबॅक मोडमध्ये सीपीयू मल्टिप्लायर्सची गणना करत आहे" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "फॉलबॅक मोडमध्ये मदरबोर्ड माहिती पुनर्प्राप्त करीत आहे" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "मदरबोर्ड माहिती पुनर्प्राप्त करण्यात अयशस्वी (फॉलबॅक मोड)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "फॉलबॅक मोडमध्ये सीपीयू तापमान प्राप्त करत आहे" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "सीपीयू तापमान (फॉलबॅक मोड) पुनर्प्राप्त करण्यात अयशस्वी" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "फॉलबॅक मोडमध्ये सीपीयू व्होल्टेज पुनर्प्राप्त करीत आहे" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "सीपीयू व्होल्टेज (फॉलबॅक मोड) पुनर्प्राप्त करण्यात अयशस्वी" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "फॉलबॅक मोडमध्ये सीपीयू वारंवारता पुनर्प्राप्त करीत आहे" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "सीपीयू वारंवारता पुनर्प्राप्त करण्यात अयशस्वी (फॉलबॅक मोड)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "विनंती_हांडलर: केस %i हाताळले नाही" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "जीटीके जीयूआय प्रारंभ करीत आहे …" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "GtkBuilder मध्ये UI आयात करण्यात अयशस्वी" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "डिमनशी कनेक्ट केले" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "कोणताही पोलकिट ऑथेंटिकेशन एजंट सापडला नाही" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "पार्श्वभूमीवर डिमन सुरू करण्यासाठी संकेतशब्द विचारा" #: gui_gtk.c:556 msgid "Start daemon" msgstr "डिमन प्रारंभ करा" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "कोर #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "लेबल नावे सेट करत आहे" #: main.c:58 msgid "CPU" msgstr "सीपीयू" #: main.c:59 msgid "Processor" msgstr "प्रोसेसर" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "विक्रेता" #: main.c:61 msgid "Code Name" msgstr "सांकेतिक नाव" #: main.c:62 msgid "Package" msgstr "पॅकेज" #: main.c:63 msgid "Technology" msgstr "तंत्रज्ञान" #: main.c:64 msgid "Voltage" msgstr "विद्युतदाब" #: main.c:65 msgid "Specification" msgstr "तपशील" #: main.c:66 msgid "Family" msgstr "परिवार" #: main.c:67 msgid "Ext. Family" msgstr "Ext. परिवार" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "मॉडेल" #: main.c:69 msgid "Ext. Model" msgstr "Ext. मॉडेल" #: main.c:70 msgid "Temp." msgstr "टेम्प." #: main.c:71 msgid "Stepping" msgstr "पायरी" #: main.c:72 msgid "Instructions" msgstr "सूचना" #: main.c:74 msgid "Clocks" msgstr "घड्याळे" #: main.c:75 msgid "Core Speed" msgstr "कोर गती" #: main.c:76 msgid "Multiplier" msgstr "गुणक" #: main.c:77 msgid "Bus Speed" msgstr "बस गती" #: main.c:78 main.c:155 msgid "Usage" msgstr "वापर" #: main.c:80 msgid "Cache" msgstr "कॅशे" #: main.c:81 msgid "L1 Data" msgstr "एल 1 डेटा" #: main.c:82 msgid "L1 Inst." msgstr "एल 1 इन्स्ट." #: main.c:83 msgid "Level 2" msgstr "पातळी 2" #: main.c:84 msgid "Level 3" msgstr "पातळी 3" #: main.c:86 msgid "Socket(s)" msgstr "सॉकेट" #: main.c:87 msgid "Core(s)" msgstr "कोअर" #: main.c:88 msgid "Thread(s)" msgstr "थ्रेड" #: main.c:91 msgid "Caches" msgstr "कॅशे" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i कॅशे" #: main.c:96 msgid "Size" msgstr "आकार" #: main.c:97 msgid "Speed" msgstr "वेग" #: main.c:99 msgid "Test" msgstr "चाचणी" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "मदरबोर्ड" #: main.c:104 msgid "Manufacturer" msgstr "निर्माता" #: main.c:106 msgid "Revision" msgstr "पुनरावृत्ती" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "ब्रँड" #: main.c:110 msgid "Version" msgstr "आवृत्ती" #: main.c:111 msgid "Date" msgstr "तारीख" #: main.c:112 msgid "ROM Size" msgstr "रॉम आकार" #: main.c:114 msgid "Chipset" msgstr "चिपसेट" #: main.c:119 main.c:135 msgid "Memory" msgstr "स्मृती" #: main.c:122 #, c-format msgid "Bank %i" msgstr "बँक %i" #: main.c:123 msgid "Reference" msgstr "संदर्भ" #: main.c:127 msgid "System" msgstr "प्रणाली" #: main.c:128 msgid "Operating System" msgstr "ऑपरेटिंग सिस्टम" #: main.c:129 msgid "Kernel" msgstr "कर्नल" #: main.c:130 msgid "Distribution" msgstr "वितरण" #: main.c:131 msgid "Hostname" msgstr "होस्टनाव" #: main.c:132 msgid "Uptime" msgstr "अपटाइम" #: main.c:133 msgid "Compiler" msgstr "संकलक" #: main.c:136 msgid "Used" msgstr "वापरलेले" #: main.c:137 msgid "Buffers" msgstr "बफर" #: main.c:138 msgid "Cached" msgstr "कॅश" #: main.c:139 msgid "Free" msgstr "मॊकळी" #: main.c:140 msgid "Swap" msgstr "स्वॅप" #: main.c:143 msgid "Graphics" msgstr "ग्राफिक्स" #: main.c:147 #, c-format msgid "Card %i" msgstr "कार्ड %i" #: main.c:149 msgid "Driver" msgstr "ड्रायव्हर" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "आवृत्ती" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "तापमान" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "विद्युतदाब" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "GPU घड्याळ" #: main.c:159 msgid "Memory clock" msgstr "स्मृती घड्याळ" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "स्मृती" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "कार्ड %i" #: main.c:165 msgid "Bench" msgstr "बेन्च" #: main.c:166 msgid "Prime numbers (slow)" msgstr "मूळ संख्या(हळु)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "मूळ संख्या (जलद)" #: main.c:170 msgid "Score" msgstr "गुण" #: main.c:171 msgid "Run" msgstr "चालवा" #: main.c:174 msgid "Parameters" msgstr "घटक" #: main.c:175 msgid "Duration" msgstr "कालावधी" #: main.c:176 msgid "Threads" msgstr "थ्रेड" #: main.c:179 main.c:184 msgid "About" msgstr "बद्दल" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s हे एक विनामूल्य सॉफ्टवेअर आहे जे\n" "सीपीयू, मदरबोर्ड आणि बरेच काहीची माहिती एकत्रित करते." #: main.c:185 #, c-format msgid "Version %s" msgstr "आवृत्ती %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "लेखक: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "साइट: %s" #: main.c:189 msgid "License" msgstr "परवाना" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "हे सॉफ्टवेअर %s च्या अटी अंतर्गत वितरीत केले गेले आहे" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "हा प्रोग्राम पूर्णपणे कोणतीही हमी देत नाही" #: main.c:265 msgid "Dumping data…" msgstr "डम्पिंग डेटा…" #: main.c:308 msgid "Freeing memory" msgstr "मेमरी रिकामी करीत आहे" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "ग्राफिकल यूजर इंटरफेस (जीयूआय) प्रारंभ करा (डीफॉल्ट)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "मजकूर-आधारित वापरकर्ता इंटरफेस (TUI) प्रारंभ करा" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "मानक आउटपुटवरील सर्व डेटा काढून टाका आणि बाहेर पडा" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "एम्बेडेड कमांड dmidecode चालवा आणि बाहेर पडा" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "एम्बेडेड कमांड बँडविड्थ चालवा आणि बाहेर पडा" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "दोन रीफ्रेश दरम्यान सानुकूल वेळ सेट करा (सेकंदात)" #: main.c:342 msgid "Set default tab (integer)" msgstr "डीफॉल्ट टॅब सेट करा (पूर्णांक)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "निरीक्षण करण्यासाठी सीपीयू कोर निवडा (पूर्णांक)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "सीपीयू कॅशे वेग (पूर्णांक) साठी सानुकूल बँडविड्थ चाचणी सेट करा" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "डीफॉल्ट टॅब सेट करा (पूर्णांक)" #: main.c:346 msgid "Start and connect to daemon" msgstr "डिमन प्रारंभ करा आणि कनेक्ट करा" #: main.c:347 msgid "Verbose output" msgstr "व्हर्बोज आउटपुट" #: main.c:348 msgid "Print help and exit" msgstr "मदत प्रिंट करा आणि बाहेर पडा" #: main.c:349 msgid "Print version and exit" msgstr "आवृत्ती मुद्रित करा आणि बाहेर पडा" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "रंगीत आउटपुट अक्षम करा" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "समस्येमध्ये पेस्ट करण्यासाठी आवश्यक माहिती मुद्रित करा" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "बस घड्याळ लागू करा" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "दिलेल्या फाईलमधून CPUIDचा कच्चा डेटा वाचा" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "डेटाबेसमध्ये सीपीयू नसल्यास केवळ संदेश मुद्रित करा" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "वापर: %s प्रदर्शन [पर्याय]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "उपलब्ध प्रदर्शन:" #: main.c:403 msgid "Available OPTIONS:" msgstr "उपलब्ध पर्याय:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "प्रभावशाली वातावरण बदल:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "हे विनामूल्य सॉफ्टवेअर आहे: आपण ते बदलून पुन्हा वितरित करण्यास मोकळे आहात." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "%s परवाना पहा: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "--%-9s चे आवृत्ती: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "libcpuid (%s) वर कॉल करण्यात अयशस्वी" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s अरेरे, काहीतरी चूक झाली! %s ला सिग्नल %d (%s) प्राप्त झाला आहे आणि क्रॅश झाला आहे.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "आपण येथे नवीन समस्या उघडून हा बॅकट्रॅस पेस्ट करू शकता:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "लोकॅल सेट करताना एक त्रुटी आली" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "एनकर्स टीयूआय प्रारंभ करीत आहे…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "FATAL ERROR: टर्मिनफो डेटाबेस सापडू शकला नाही (TERMINFO पर्यावरण व्हेरिएबल सेट " "करण्याचा प्रयत्न करा)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "%s टर्मिनल स्थापित करण्यात अपयशी (err=%i); %s मागे पडतोय" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "विंडो खूपच लहान आहे!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "मदत पाहण्यासाठी 'h' दाबा.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "%s एनसीर्स मदत मध्ये आपले स्वागत आहे!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "हा मजकूर-आधारित वापरकर्ता इंटरफेस कसे वापरावे याचे वर्णन करते.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "ग्लोबल की:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tडाव्या टॅबमध्ये स्विच करण्यासाठी 'डावी' की दाबा.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tउजव्या टॅबवर स्विच करण्यासाठी 'उजवी' की दाबा.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tही मदत पाहण्यासाठी 'h' की दाबा.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tबाहेर पडण्यासाठी 'q' की दाबा.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "सीपीयू टॅब:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "\tमॉनिटर करण्यासाठी कोर नंबर कमी करण्यासाठी 'डाउन' की दाबा.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "\tदेखरेखीसाठी कोअर नंबर वाढविण्यासाठी 'अप' की दाबा.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "कॅशे टॅब:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tमागील चाचणीवर स्विच करण्यासाठी 'डाउन' की दाबा.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tपुढील चाचणीवर स्विच करण्यासाठी 'अप' की दाबा.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "खंडपीठ टॅब:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "\tघटलेल्या बेंचमार्क कालावधीसाठी 'डाउन' की दाबा.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "\tवाढीव बेंचमार्क कालावधीसाठी 'अप' की दाबा.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "\tवापरण्यासाठी थ्रेडची संख्या कमी करण्यासाठी 'पुढचे पान' कि दाबा.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "\tवापरण्यासाठी थ्रेडच्या वाढीव संख्येसाठी 'मागील पृष्ठ' की दाबा.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "\tप्राइम नंबर (स्लो) बेंचमार्क सुरू करण्यासाठी /थांबवण्यासाठी 's' कि दाबा.\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "\tप्राइम नंबर (स्लो) बेंचमार्क सुरू करण्यासाठी /थांबवण्यासाठी 's' कि दाबा.\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "ग्राफिक्स" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tमागील चाचणीवर स्विच करण्यासाठी 'डाउन' की दाबा.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tपुढील चाचणीवर स्विच करण्यासाठी 'अप' की दाबा.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "या मदतीमधून बाहेर पडण्यासाठी कोणतीही की दाबा.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "'%s' स्ट्रिंगमध्ये %i स्थानावर युनिट शोधू शकत नाही" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "फाइल '%s' (%s) उघडताना त्रुटी आली" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "'%s' (%s) कमांड चालू करताना त्रुटी आली" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "%s निर्देशिका उघडण्यात अयशस्वी" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "regex कंपाईल करताना त्रुटी आली" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: अधिकृतता प्राप्त होऊ शकली नाही (संवाद फेटाळला)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: अधिकृतता मिळू शकली नाही (अधिकृत नाही)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: कमांड आढळली नाही" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: अनपेक्षित त्रुटी कोड" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "FATAL ERROR: मेमरी वाटप करू शकलो नाही" #: cpu-x.h:92 msgid "bytes" msgstr "बाईट्स" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "एमबी" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "जीबी" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "टीबी" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "एमबी" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "जीबी" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "टीबी" #~ msgid "Exiting %s" #~ msgstr "%s बाहेर पडत आहे" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "सीपीयू एमएसआर उघडणे वगळा (मूळ असणे आवश्यक आहे)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "सीपीयू एमएसआर (%s) उघडण्यात अयशस्वी" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "डीमिडेकोडवर कॉल वगळा (रूट असणे आवश्यक आहे)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "डीमिडेकोडसाठी मेमरी वाटप करण्यात अयशस्वी" #~ msgid "failed to call dmidecode" #~ msgstr "dmidecode वर कॉल करण्यात अयशस्वी" #~ msgid "Finding graphic card driver" #~ msgstr "ग्राफिक कार्ड ड्रायव्हर शोधत आहे" #~ msgid "(%s driver)" #~ msgstr "(%s ड्राइव्हर)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "ग्राफिक कार्ड ड्राइव्हर (%s) शोधण्यात अयशस्वी" #~ msgid "Retrieving GPU temperature" #~ msgstr "GPU तापमान मिळवत आहे" #~ msgid "Off" #~ msgstr "बंद" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "GPU तापमान प्राप्त करण्यात अयशस्वी" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "काही GPU मूल्ये वगळा (रूट असणे आवश्यक आहे)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "बेंचमार्कसाठी मेमरी वाटप करण्यात अयशस्वी" #~ msgid "Some information will not be retrievable" #~ msgstr "काही माहिती पुनर्प्राप्त करण्यायोग्य होणार नाही" #~ msgid "Ignore" #~ msgstr "दुर्लक्ष करा" #~ msgid "Run as root" #~ msgstr "रूट म्हणून चालवा" #~ msgid "A new version of %s is available!" #~ msgstr "%s ची नवीन आवृत्ती उपलब्ध आहे!" #~ msgid "Not now" #~ msgstr "आता नाही" #~ msgid "Update" #~ msgstr "अद्यतनित करा" #~ msgid "Checking on Internet for a new version..." #~ msgstr "नवीन आवृत्तीसाठी इंटरनेटवर तपासत आहे ..." #~ msgid "failed to open a Curl session" #~ msgstr "कर्ल सत्र उघडण्यात अयशस्वी" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "कर्ल हस्तांतरण (%s) करण्यात अयशस्वी" #~ msgid "wrong write data" #~ msgstr "चुकीचे डेटा लेखन" #~ msgid "(version %s is available)" #~ msgstr "(आवृत्ती %s उपलब्ध आहे)" #~ msgid "No new version available" #~ msgstr "कोणतीही नवीन आवृत्ती उपलब्ध नाही" #~ msgid "(up-to-date)" #~ msgstr "(अद्ययावत)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "%s संग्रहण (%s) काढताना त्रुटी आली" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "पर्यावरण प्रवेशाद्वारे नेटवर्क प्रवेश अक्षम केला आहे (ते सक्षम करण्यासाठी सकारात्मक " #~ "मूल्यासह CPUX_NETWORK सेट करा)" #~ msgid "failed to open %s archive for writing" #~ msgstr "लेखनासाठी %s संग्रह उघडण्यात अयशस्वी" #~ msgid "Downloading new version..." #~ msgstr "नवीन आवृत्ती डाउनलोड करीत आहे ..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "%s संग्रहण (%s) डाउनलोड करण्यात अयशस्वी" #~ msgid "Extracting new version..." #~ msgstr "नवीन आवृत्ती काढत आहे ..." #~ msgid "Applying new version..." #~ msgstr "नवीन आवृत्ती लागू करत आहे ..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "फायली काढताना / पुनर्नामित करताना त्रुटी आली" #~ msgid "Update successful!" #~ msgstr "अद्यतन यशस्वी!" #~ msgid "Update portable version if a new version is available" #~ msgstr "नवीन आवृत्ती उपलब्ध असल्यास पोर्टेबल आवृत्ती अद्यतनित करा" #~ msgid "Temporarily disable network support" #~ msgstr "नेटवर्क समर्थन तात्पुरते अक्षम करा" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "%s,%s (%s वर %s %s सह) वर निर्मित." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "क्षमस्व, आपण%s अद्यतनित करू शकत नाही: 32-बिट पोर्टेबल आवृत्ती यापुढे समर्थित नाही." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "आपण अद्यतनित करू इच्छित असल्यास, 'u' की किंवा वगळण्यासाठी काहीही दाबा.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s अद्यतनित केले जाईल." CPU-X-4.2.0/po/ms.po000066400000000000000000000511421403012130000137310ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # abuyop , 2020. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-07-11 09:41+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Malay \n" "Language: ms\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 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Mencari teknologi CPU" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "CPU anda tiada dalam pangkalan data ==> %s, model: %i, model ext.: %i, " "keluarga ext.: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-way" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-way" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Memanggil libcpuid untuk mendapatkan semula data statik" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "gagal memanggil libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Memanggil libcpuid untuk mendapatkan semula data dinamik" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Memanggil libcpuid untuk mendapatkan semula nilai statik MSR CPU" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Memanggil libcpuid untuk mendapatkan semula nilai dinamik MSR CPU" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Mengira pengganda CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Memanggil dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Mengira penggunaan CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Memanggil jalur lebar" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Pemacu GPU anda tidak diketahui: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Pemacu GPU anda tidak diketahui: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "gagal memanggil libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "Mencari peranti" #: core.c:829 #, fuzzy, c-format #| msgid "Skip devices search (need to be root)" msgid "Skip devices search (wrong permissions on %s device)" msgstr "Langkau gelintar peranti (perlu dalam root)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Vendor GPU anda tidak diketahui: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "gagal mencari vendor dan model cipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "gagal mencari vendor dan model kad grafik" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Mendapatkan semula jam GPU" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Pemacu untuk GPU %u tidak melaporkan frekuensi" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "gagal mendapatkan semula jam GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Mengenal pasti sistem yang berjalan" #: core.c:1208 msgid "failed to identify running system" msgstr "gagal mengenal pasti sistem yang berjalan" #: core.c:1249 msgid "Calling libprocps" msgstr "Memanggil libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Memanggil libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i hari, %i jam, %i minit, %i saat" #: core.c:1366 msgid "Updating benchmark status" msgstr "Mengemas kini status tanda aras" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Tidak aktif" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Belum mula" #: core.c:1380 msgid "Active" msgstr "Aktif" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u jam berbaki)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minit berbaki)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u saat berbaki)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "dalam tempoh %u jam" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "dalam tempoh %u minit" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "dalam tempoh %u saat" #: core.c:1414 msgid "Starting benchmark" msgstr "Memulakan tanda aras" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "satu ralat berlaku ketika memulakan tanda aras" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Mencari pakej CPU dalam mod jatuh-balik" #: core.c:1472 #, fuzzy, c-format #| msgid "Your CPU socket does not belong in database ==> %s, codename: %s" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Soket CPU anda tiada dalam pangkalan data ==> %s, nama kod: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Mengira pengganda CPU dalam mod jatuh-balik" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Mendapatkan semula maklumat papan induk dalam mod jatuh balik" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "gagal mendapatkan semula maklumat papan induk (mod jatuh-balik)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Mendapatkan semula suhu CPU dalam mod jatuh-balik" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "gagal mendapatkan semula suhu CPU (mod jatuh-balik)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Mendapatkan semula voltan CPU dalam mod jatuh-balik" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "gagal mendapatkan semula voltan CPU (mod jatuh-balik)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Mendapatkan semula frekuensi CPU dalam mod jatuh-balik" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "gagal mendapatkan semula frekuensi CPU (mod jatuh-balik)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 #, fuzzy #| msgid "Starting GTK GUI..." msgid "Starting GTK GUI…" msgstr "Memulakan GUI GTK..." #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "gagal mengimport UI dalam GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Teras #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "Menetapkan nama label" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Pemproses" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Vendor" #: main.c:61 msgid "Code Name" msgstr "Nama Kod" #: main.c:62 msgid "Package" msgstr "Pakej" #: main.c:63 msgid "Technology" msgstr "Teknologi" #: main.c:64 msgid "Voltage" msgstr "Voltan" #: main.c:65 msgid "Specification" msgstr "Spesifikasi" #: main.c:66 msgid "Family" msgstr "Keluarga" #: main.c:67 msgid "Ext. Family" msgstr "Keluarga Ext" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Model" #: main.c:69 msgid "Ext. Model" msgstr "Model Ext" #: main.c:70 msgid "Temp." msgstr "Suhu." #: main.c:71 msgid "Stepping" msgstr "Langkah" #: main.c:72 msgid "Instructions" msgstr "Arahan" #: main.c:74 msgid "Clocks" msgstr "Jam" #: main.c:75 msgid "Core Speed" msgstr "Kelajuan Teras" #: main.c:76 msgid "Multiplier" msgstr "Pengganda" #: main.c:77 msgid "Bus Speed" msgstr "Kelajuan Bas" #: main.c:78 main.c:155 msgid "Usage" msgstr "Penggunaan" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Voltan" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "failed to find graphic card driver (%s)" msgid "Select default graphic card (integer)" msgstr "gagal mencari pemacu kad grafik (%s)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "gagal memanggil libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 #, fuzzy #| msgid "Cache" msgid "Caches tab:" msgstr "Cache" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "tidak dapat memperuntuk semula ingatan" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Keluar dari %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Langkau pembukaan MSR CPU (perlu dalam root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "gagal membuka MSR CPU (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Langkau panggilan ke dmidecode (perlu dalam root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "gagal memperuntukkan ingatan untuk dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "gagal memanggil dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Mencari pemacu kad grafik" #~ msgid "(%s driver)" #~ msgstr "(pemacu %s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Mendapatkan semula suhu GPU" #~ msgid "Off" #~ msgstr "Mati" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "gagal mendapatkan semula suhu GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Langkau beberapa nilai GPU (perlu dalam root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "gagal memperuntuk ingatan untuk tanda aras" #~ msgid "Root privileges are required to work properly" #~ msgstr "Kelayakan root diperlukan untuk berfungsi dengan baik" #~ msgid "Some information will not be retrievable" #~ msgstr "Beberapa maklumat tidak boleh diperoleh" #~ msgid "Ignore" #~ msgstr "Abai" #~ msgid "Run as root" #~ msgstr "Jalan sebagai root" #~ msgid "A new version of %s is available!" #~ msgstr "Satu versi baharu %s sudah tersedia!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Anda mahu mengemas kini %s ke versi %s selepas keluar?\n" #~ "Ia akan memadam fail perduaan ini (%s) dengan versi baharu." #~ msgid "Not now" #~ msgstr "Bukan sekarang" #~ msgid "Update" #~ msgstr "Kemas kini" CPU-X-4.2.0/po/nb_NO.po000066400000000000000000000707531403012130000143160ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Allan Nordhøy , 2019, 2020, 2021. # Michal Čihař , 2019. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-23 15:29+0000\n" "Last-Translator: Allan Nordhøy \n" "Language-Team: Norwegian Bokmål \n" "Language: nb_NO\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 4.5.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Finner prosessor-teknologi" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Prosessoren din finnes ikke i databasen → %s, modell: %i, ekst. modell: %i, " "ekst. familie: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-veis" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-veis" #: core.c:251 #, fuzzy, c-format msgid "%s associative, %d-%s line size" msgstr "%s-tilknytning, %d-%s-bytelinjestørrelse" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Kaller libcpuid for innhenting av statisk data" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "Klarte ikke å kalle libcpuid (%s)" #: core.c:427 #, fuzzy msgid "Calling libcpuid for retrieving dynamic data" msgstr "Kaller libcpuid for innhenting av dynamisk data …" #: core.c:440 #, fuzzy msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Kaller libcpuid for mottak av statiske CPU MSR-verdier …" #: core.c:465 #, fuzzy msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Kaller libcpuid for mottak av dynamiske CPU MSR-verdier …" #: core.c:488 #, fuzzy msgid "Calculating CPU multipliers" msgstr "Regner ut prosessor-multiplikatorer …" #: core.c:521 msgid "Calling dmidecode" msgstr "Kaller dmidecode" #: core.c:554 #, fuzzy msgid "Calculating CPU usage" msgstr "Regner ut prosessor-bruk …" #: core.c:605 msgid "Calling bandwidth" msgstr "Kaller båndbredde" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Ingen kjernedriver i bruk for grafikkort på stien %s" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Ukjent sjermkortdriver: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Ukjent sjermkortdriver: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call wordexp (%i)" msgid "failed to call GLFW (%i): %s" msgstr "Klarte ikke å kalle wordexp (%i)" #: core.c:817 msgid "Finding devices" msgstr "Finner enheter" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Hopp over søk etter enheter (feil tilganger på %s-enhet)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Din GPU-tilvirker er ukjent: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "klarte ikke å finne brikkesetttilverker eller modell" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "klarte ikke å finne grafikkorttilvirker eller modell" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Henter GPU-klokker" #: core.c:990 msgid "None" msgstr "Ingen" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Driver for GPU %u rapporterer ikke frekvenser" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "klarte ikke å hente GPU-klokker" #: core.c:1205 msgid "Identifying running system" msgstr "Identifiserer kjørende system" #: core.c:1208 msgid "failed to identify running system" msgstr "klarte ikke å identifisere kjørende system" #: core.c:1249 msgid "Calling libprocps" msgstr "Kaller libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Kaller libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dager, %i timer, %i minutter, %i sekunder" #: core.c:1366 msgid "Updating benchmark status" msgstr "Oppdaterer ytelsesteststatus" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u minutter" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inaktiv" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Ikke startet" #: core.c:1380 msgid "Active" msgstr "Aktiv" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u timer gjenstår)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minutter gjenstår)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u sekunder gjenstår)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "om %u timer" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "in %u minutter" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "om %u sekunder" #: core.c:1414 msgid "Starting benchmark" msgstr "Starter ytelsestest" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "En feil inntraff under oppstart av ytelsestest" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Finner prosessor-pakke i tilbakefallsmodus" #: core.c:1472 #, fuzzy, c-format #| msgid "Your CPU socket does not belong in database ==> %s, codename: %s" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Din prosessor-sokkel finnes ikke i databasen ➜ %s, kodenavn: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Regner ut prosessor-multiplikatorer i tilbakefallsmodus" #: core.c:1518 #, fuzzy msgid "Retrieving motherboard information in fallback mode" msgstr "Henter hovedkortinformasjon i tilbakefallsmodus" #: core.c:1527 #, fuzzy msgid "failed to retrieve motherboard information (fallback mode)" msgstr "Klarte ikke å hente hovedkortinformasjon (tilbakefallsmodus)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Henter prosessor-temperatur i tilbakefallsmodus" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "Klarte ikke å hente prosessor-temperatur (tilbakefallsmodus)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Henter prosessor-spenning i tilbakefallsmodus" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "Klarte ikke å hente prosessor-spenning (tilbakefallsmodus)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Henter prosessor-frekvens i tilbakefallsmodus" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "Klarte ikke å hente prosessor-frekvens (tilbakefallsmodus)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "forespørselshåndterer: Tilfelle %i ikke håndtert" #: gui_gtk.c:62 #, fuzzy msgid "Starting GTK GUI…" msgstr "Starter grafisk GTK-brukergrensesnitt…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "Klarte ikke å importere grensesnitt i GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Tilkoblet nisse" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Fant ingen polkit-identitetsbekreftelsesagent" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Forespør passord for å starte nisse i bakgrunnen" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Start nisse" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Kjerne #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Setter etikettnavn" #: main.c:58 msgid "CPU" msgstr "Prosessor" #: main.c:59 msgid "Processor" msgstr "Prosessor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Leverandør" #: main.c:61 msgid "Code Name" msgstr "Kodenavn" #: main.c:62 msgid "Package" msgstr "Pakke" #: main.c:63 msgid "Technology" msgstr "Teknologi" #: main.c:64 msgid "Voltage" msgstr "Spenning" #: main.c:65 msgid "Specification" msgstr "Spesifikasjon" #: main.c:66 msgid "Family" msgstr "Familie" #: main.c:67 #, fuzzy msgid "Ext. Family" msgstr "Ekst. familie" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modell" #: main.c:69 #, fuzzy msgid "Ext. Model" msgstr "Ekst. modell" #: main.c:70 #, fuzzy msgid "Temp." msgstr "Temp." #: main.c:71 #, fuzzy msgid "Stepping" msgstr "Stepping" #: main.c:72 msgid "Instructions" msgstr "Instruksjoner" #: main.c:74 msgid "Clocks" msgstr "Klokker" #: main.c:75 msgid "Core Speed" msgstr "Kjernehastighet" #: main.c:76 msgid "Multiplier" msgstr "Multiplikator" #: main.c:77 msgid "Bus Speed" msgstr "Busshastighet" #: main.c:78 main.c:155 msgid "Usage" msgstr "Bruk" #: main.c:80 msgid "Cache" msgstr "Hurtiglager" #: main.c:81 msgid "L1 Data" msgstr "L1-data" #: main.c:82 msgid "L1 Inst." msgstr "L1-instr." #: main.c:83 msgid "Level 2" msgstr "Nivå 2" #: main.c:84 msgid "Level 3" msgstr "Nivå 3" #: main.c:86 msgid "Socket(s)" msgstr "Sokkel" #: main.c:87 msgid "Core(s)" msgstr "Kjerne(r)" #: main.c:88 msgid "Thread(s)" msgstr "Tråd(er)" #: main.c:91 msgid "Caches" msgstr "Hurtiglagre" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i-hurtiglager" #: main.c:96 msgid "Size" msgstr "Størrelse" #: main.c:97 msgid "Speed" msgstr "Hastighet" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Hovedkort" #: main.c:104 msgid "Manufacturer" msgstr "Fabrikant" #: main.c:106 msgid "Revision" msgstr "Revisjon" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Merke" #: main.c:110 msgid "Version" msgstr "Versjon" #: main.c:111 msgid "Date" msgstr "Dato" #: main.c:112 msgid "ROM Size" msgstr "ROM-størrelse" #: main.c:114 msgid "Chipset" msgstr "Brikkesett" #: main.c:119 main.c:135 msgid "Memory" msgstr "Minne" #: main.c:122 #, fuzzy, c-format msgid "Bank %i" msgstr "Bank %i" #: main.c:123 msgid "Reference" msgstr "Referanse" #: main.c:127 msgid "System" msgstr "System" #: main.c:128 msgid "Operating System" msgstr "Operativsystem" #: main.c:129 msgid "Kernel" msgstr "Kjerne" #: main.c:130 msgid "Distribution" msgstr "Distro" #: main.c:131 msgid "Hostname" msgstr "Vertsnavn" #: main.c:132 msgid "Uptime" msgstr "Oppetid" #: main.c:133 msgid "Compiler" msgstr "Kompilator" #: main.c:136 msgid "Used" msgstr "Brukt" #: main.c:137 msgid "Buffers" msgstr "Mellomlagre" #: main.c:138 msgid "Cached" msgstr "Mellomlagret" #: main.c:139 msgid "Free" msgstr "Ledig" #: main.c:140 msgid "Swap" msgstr "Sidevekslingsfil" #: main.c:143 msgid "Graphics" msgstr "Grafikk" #: main.c:147 #, c-format msgid "Card %i" msgstr "Kort %i" #: main.c:149 msgid "Driver" msgstr "Driver" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Versjon" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatur" #: main.c:156 msgid "Core Voltage" msgstr "Kjernespenning" #: main.c:157 msgid "Power Avg" msgstr "Effektgjennomsnitt" #: main.c:158 msgid "GPU clock" msgstr "prosessor-klokke" #: main.c:159 #, fuzzy msgid "Memory clock" msgstr "Minne-klokke" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Minne" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Kort %i" #: main.c:165 msgid "Bench" msgstr "Ytelsestest" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Primtall (tregt)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Primtall (raskt)" #: main.c:170 msgid "Score" msgstr "Poengsum" #: main.c:171 msgid "Run" msgstr "Kjør" #: main.c:174 msgid "Parameters" msgstr "Parameter" #: main.c:175 msgid "Duration" msgstr "Varighet" #: main.c:176 msgid "Threads" msgstr "Tråder" #: main.c:179 main.c:184 msgid "About" msgstr "Om" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s er fri programvare som henter info om\n" "prosessor, hovedkort, med mer." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versjon %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Utvikler: %s" #: main.c:187 #, fuzzy, c-format msgid "Site: %s" msgstr "Nettside: %s" #: main.c:189 #, fuzzy msgid "License" msgstr "Lisens" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Denne programvaren utgis i henhold til vilkårene i %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Dette programmet kommer deg i hende UTEN NOEN FORM FOR GARANTI" #: main.c:265 #, fuzzy msgid "Dumping data…" msgstr "Dumper data …" #: main.c:308 msgid "Freeing memory" msgstr "Frigjør minne" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Start grafisk brukergrensesnitt (GUI) (forvalg)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Start tekstbasert brukergrensesnitt (TUI)" #: main.c:338 #, fuzzy msgid "Dump all data on standard output and exit" msgstr "Dump all data til forvalgt utdata og avslutt" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Kjør den innebygde kommandoen dmidecode og avslutt" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Kjør den innebygde kommandoen bandwidth og avslutt" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Sett egendefinert tid mellom to oppdateringer (i sekunder)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Sett forvalgt fane (heltall)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Velg prosessor-kjerne å overvåke (heltall)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Sett egendefinert båndbreddetest for hastigheter for prosessor-hurtiglagre " "(heltall)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Sett forvalgt fane (heltall)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Start og koble til nisse" #: main.c:347 msgid "Verbose output" msgstr "Ordrik utdata" #: main.c:348 msgid "Print help and exit" msgstr "Skriv ut hjelp og avslutt" #: main.c:349 msgid "Print version and exit" msgstr "Skriv ut versjon og avslutt" #: main.c:350 #, fuzzy msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "Skriv ut CPUID-verdier i desimalform (forvalget er heksadesimaler)" #: main.c:351 msgid "Disable colored output" msgstr "Skru av fargelagt utdata" #: main.c:352 msgid "Print information for debugging" msgstr "Skriv ut info for avlusing" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Skriv ut påkrevd informasjon å lime inn i en feilrapport" #: main.c:354 #, fuzzy msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Sett tastetildeling for NCurses-modus (a[rrows]|e[macs]|i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Sett forvalgte kommandolinjeargumenter" #: main.c:366 msgid "Enforce the bus clock" msgstr "Påtving bussklokkefrekvens" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignorer prosessorfrekvens rapportert av libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Les CPUID-rådata fra en gitt fil" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Kun skriv ut en melding hvis prosessoren ikke finnes i databasen" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Bruk: %s SKJERM {VALG]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Tilgjengelig SKJERM:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Tilgjengelige VALG:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Påvirkelige miljøvariabler:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Dette er fri programvare: Du står fritt til å endre og redistribuere den." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Vis %s-linsensen: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s versjon: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "Klarte ikke å kalle wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s! %s has received signal %d (%s) and has crashed.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Du kan lime inn denne tilbakesporingen ved å åpne en ny feilrapport her:" #: main.c:705 #, fuzzy msgid "an error occurred while setting locale" msgstr "Kunne ikke sette lokalitet" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Starter NCurses-TUI …" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "FATAL FEIL: Fant ikke terminfo-database. (Prøv å sette TERMINFO-" "miljøvariabel.)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Klarte ikke å sette opp %s-terminal (err=%i); faller tilbake til %s" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Vinduet er for lite!\n" #: tui_ncurses.c:318 #, fuzzy msgid "Press 'h' to see help." msgstr "Trykk \"h\" for å vise hjelp.\n" #: tui_ncurses.c:474 #, fuzzy, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Velkommen til %s-ncurseshjelpen!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Denne hjelpen beskrives bruken av dette tekstbaserte brukergrensesnittet.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Programvide hurtigtaster:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tTrykk \"venstre piltast\" for å veksle i venstre fane.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tTrykk \"høyre piltast\" for å veksle i høyre fane.\n" #: tui_ncurses.c:480 #, fuzzy msgid "Press 'h' key to see this help." msgstr "\tTrykk \"h\"-tasten for å se denne hjelpen.\n" #: tui_ncurses.c:481 #, fuzzy msgid "Press 'q' key to exit." msgstr "\tTrykk \"q\"-tast for å avslutte.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Prosessor-fane:\n" #: tui_ncurses.c:484 #, fuzzy msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tTrykk \"nedover-piltast\" ↓ for å senke kjerneantall å holde oppsikt med.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tTrykk \"oppover-piltast\" ↑ for å øke kjerneantallet å holde oppsyn med.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Fane for hurtiglagre:\n" #: tui_ncurses.c:488 #, fuzzy msgid "Press 'down' key to switch to previous test." msgstr "\tTrykk \"nedovertast\" ↓ for å bytte til forrige test.\n" #: tui_ncurses.c:489 #, fuzzy msgid "Press 'up' key' to switch to next test." msgstr "\tTrykk \"nedovertast\" ↑ for å bytte til neste test.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Ytelsestestfane:\n" #: tui_ncurses.c:492 #, fuzzy msgid "Press 'down' key to decrement benchmark duration." msgstr "\tTrykk \"nedover-piltast\" ↓ for å senke ytelsestestens varighet.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "\tTrykk \"oppovertast\" ↑ for å endre ytelsestestens varighet.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "\tTrykk \"neste side-tast\" for å senke antall tråder i bruk.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "\tTrykk \"forrige side-tast\" for å øke antall tråder i bruk.\n" #: tui_ncurses.c:496 #, fuzzy msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "\tTrykk \"s\"-tast for å starte/stoppe primtall (treg) ytelsestest.\n" #: tui_ncurses.c:497 #, fuzzy msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "\tTrykk \"f\"-tast for å starte/stoppe primtall (rask) ytelsestest.\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafikk" #: tui_ncurses.c:500 #, fuzzy msgid "Press 'down' key to switch to previous graphic card." msgstr "\tTrykk \"nedovertast\" ↓ for å bytte til forrige test.\n" #: tui_ncurses.c:501 #, fuzzy msgid "Press 'up' key to switch to next graphic card." msgstr "\tTrykk \"nedovertast\" ↑ for å bytte til neste test.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Trykk vilkårlig tast for å avslutte denne hjelpen.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "finner ikke enheten «%s»-streng i posisjon %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "Strengen «%s» er for lang, forkorter …" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "Kunne ikke åpne fil \"%s\" (%s)" #: util.c:317 #, fuzzy, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "Kunne ikke kjøre kommandoen \"%s\" (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "Klarte ikke ikke å åpne %s-mappe" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "Feil under kompilering av regulære uttrykk" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: Kunne ikke utføre identitetsbekreftelse (dialogvindu avvist)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: Kunne ikke utføre dentitetsbekreftelse (fant ikke)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: Fant ikke kommandoen" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: Uventet feilkode" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "Fatal feil: Kunne ikke tildele minne" #: cpu-x.h:92 msgid "bytes" msgstr "byte" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "MB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "GB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "TB" #~ msgid "Exiting %s" #~ msgstr "Avslutter %s" #, fuzzy #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Hopp over CPU MSR-åpning (superbrukerrettigheter påkrevd)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "Klarete ikke å åpne CPU MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Hopp over kall til dmidecode (root-rettigheter behøves)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "klarte ikke å tildele minne til dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "kall til dmidecode mislyktes" #~ msgid "Finding graphic card driver" #~ msgstr "Finner grafikkortdriver" #~ msgid "(%s driver)" #~ msgstr "(%s-driver)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "klarte ikke å finne grafikkortdriver (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Henter GPU-temperatur" #~ msgid "Off" #~ msgstr "Av" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "Klarte ikke å hente GPU-temperatur" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Hopp over noen GPU-verdier (root-tilgang behøves)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "Klarte ikke å tildele minne for ytelsestest" #, fuzzy #~ msgid "Root privileges are required to work properly" #~ msgstr "Superbrukerprivilegier kreves for at ting skal virke" #~ msgid "Some information will not be retrievable" #~ msgstr "Noe info kunne ikke innhentes" #~ msgid "Ignore" #~ msgstr "Ignorer" #~ msgid "Run as root" #~ msgstr "Kjør som superbruker" #~ msgid "A new version of %s is available!" #~ msgstr "Ny versjon av %s tilgjengelig." #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Ønsker du å oppgradere %s til versjon %s etter avslutning?\n" #~ "Det vil slette den kjørbare filen (%s) og erstatte den med den nye " #~ "versjonen." #~ msgid "Not now" #~ msgstr "Ikke nå" #~ msgid "Update" #~ msgstr "Oppgrader" #, fuzzy #~ msgid "Checking on Internet for a new version..." #~ msgstr "Ser etter ny versjon…" #, fuzzy #~ msgid "failed to open a Curl session" #~ msgstr "Klarte ikke å åpne Curl-økt" #, fuzzy #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "Klarte ikke å utføre Curl-overføring (%s)" #~ msgid "wrong write data" #~ msgstr "Feil data forsøkt skrevet" #~ msgid "(version %s is available)" #~ msgstr "(versjon %s er tilgjengelig)" #~ msgid "No new version available" #~ msgstr "Ingen ny versjon tilgjengelig" #~ msgid "(up-to-date)" #~ msgstr "(nyeste versjon)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "Feil under utpakking %s-arkiv (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Nettverkstilgang er avskrudd av miljøvariabel (sett CPUX_NETWORK med " #~ "positiv verdi for å skru den på)" #, fuzzy #~ msgid "failed to open %s archive for writing" #~ msgstr "Klarte ikke å åpne %s-arkiv for skriving" #~ msgid "Downloading new version..." #~ msgstr "Laster ned ny versjon…" #, fuzzy #~ msgid "failed to download %s archive (%s)" #~ msgstr "Kunne ikke laste ned %s-arkiv (%s)" #~ msgid "Extracting new version..." #~ msgstr "Pakker ut ny versjon…" #, fuzzy #~ msgid "Applying new version..." #~ msgstr "Iverksetter ny versjon…" #~ msgid "an error occurred while removing/renaming files" #~ msgstr "En feil inntraff under flytting/endring av filnavn" #~ msgid "Update successful!" #~ msgstr "Oppgradert." #~ msgid "Update portable version if a new version is available" #~ msgstr "Oppgrader portabel versjon hvis en ny versjon er tilgjengelig" #~ msgid "Temporarily disable network support" #~ msgstr "Skru av nettverksstøtte midlertidig" #, fuzzy #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Bygd på %s, %s (med %s %s på %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Du kan ikke oppgradere %s: 32-biters portabel versjon støttes ikke lenger." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Hvis du vil oppgradere, trykk \"u\"-tasten, eller vilkårlig annen tast " #~ "for å hoppe over.\n" #, fuzzy #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s vil bli oppgradert." CPU-X-4.2.0/po/pa.po000066400000000000000000000400751403012130000137150ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Aman ALam , 2020. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-07-05 01:41+0000\n" "Last-Translator: Aman ALam \n" "Language-Team: Punjabi \n" "Language: pa\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 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "CPU ਤਕਨਾਲੋਜੀ ਲੱਭੀ ਜਾ ਰਹੀ ਹੈ" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-ਵੇਅ" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/pl.po000066400000000000000000000740611403012130000137320ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Michał Głowienka , 2016 # WaldiS , 2019, 2020. # Mr Talon63 , 2019. # kakiremora , 2020. # Michal Biesiada , 2020. # WaldiS , 2020, 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-02-23 09:50+0000\n" "Last-Translator: WaldiS \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=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n" "%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n" "%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" "X-Generator: Weblate 4.5\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Wyszukiwanie technologi procesora" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Twój CPU nie jest obecny w bazie danych ==> %s, model: %i, ext. model: %i, " "ext. family: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-sposób" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-sposób" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s przemienne, %d-%s rozmiar linii" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Wywołanie libcpuid w celu pobierania danych statycznych" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "nie udało się wywołać libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Wywołanie libcpuid w celu pobierania danych dynamicznych" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Wywołanie libcpuid w celu pobrania statycznych danych z CPU MSR" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Wywołanie libcpuid w celu pobrania dynamicznych danych z CPU MSR" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Obliczanie mnożnika CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Wywołanie dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Obliczanie użycia procesora" #: core.c:605 msgid "Calling bandwidth" msgstr "Wywołanie bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Brak sterownika jądra dla karty graficznej przy ścieżce %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Nieznany sterownik jądra GPU: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Nieznany sterownik trybu użytkownika Twojego układu GPU: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "nie udało się wywołać GLFW (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Wyszukiwanie urządzeń" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Pomiń wyszukiwanie urządzeń (brak uprawnień do urządzenia %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Dostawca procesora GPU jest nieznany: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "nie udało się znaleźć producenta i modelu chipsetu" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "nie udało się znaleźć producenta i modelu GPU" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Pobieranie zegarów GPU" #: core.c:990 msgid "None" msgstr "Żaden" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Sterownik procesora graficznego %u nie raportuje częstotliwości" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "nie udało się znaleźć zegarów GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Identyfikacja uruchomionego systemu" #: core.c:1208 msgid "failed to identify running system" msgstr "nie udało się zidentyfikować uruchomionego systemu" #: core.c:1249 msgid "Calling libprocps" msgstr "Wywołanie libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Wywołanie libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dni, %i godzin, %i minut, %i sekund" #: core.c:1366 msgid "Updating benchmark status" msgstr "Aktualizacja statusu benchmarku" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Nieaktywny" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Nie uruchomiono" #: core.c:1380 msgid "Active" msgstr "Aktywny" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u godzin pozostało)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minut pozostało)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(pozostało %u sekund)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "w %u godzinach" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "w %u minutach" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "w %u sekundach" #: core.c:1414 msgid "Starting benchmark" msgstr "Uruchamianie benchmarku" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "wystąpił błąd podczas uruchamiania benchmarku" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Wyszukiwanie rodzaju układu CPU w trybie awaryjnym" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Twojego gniazda CPU nie ma w bazie ==> %s, codename: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Obliczanie mnożnika CPU w trybie awaryjnym" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Pozyskiwanie informacji o płycie głównej w trybie awaryjnym" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "nie udało się pobrać informacji o płycie głównej (tryb awaryjny)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Pozyskiwanie informacji o temperaturze CPU w trybie awaryjnym" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "nie udało się pobrać temperatury CPU (tryb awaryjny)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Pozyskiwanie napięcia CPU w trybie awaryjnym" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "nie udało się pozyskać napięcia CPU (tryb awaryjny)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Pobieranie częstotliwości procesora w trybie awaryjnym" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "nie udało się pobrać częstotliwości procesora (tryb awaryjny)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "moduł obsługi żądań: przypadek %i nie obsługiwany" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Uruchamianie GTK GUI…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "nie udało się zaimportować interfejsu z GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Połączony z demonem" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Nie znaleziono agenta uwierzytelniającego polkit" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Pytaj o hasło, aby uruchomić demona w tle" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Uruchom demon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Rdzeń #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Ustawianie nazw etykiet" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Producent" #: main.c:61 msgid "Code Name" msgstr "Nazwa kodowa" #: main.c:62 msgid "Package" msgstr "Rodzaj Układu" #: main.c:63 msgid "Technology" msgstr "Technologia" #: main.c:64 msgid "Voltage" msgstr "Napięcie" #: main.c:65 msgid "Specification" msgstr "Specyfikacja" #: main.c:66 msgid "Family" msgstr "Rodzina" #: main.c:67 msgid "Ext. Family" msgstr "Zewnętrzna Rodzina" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Model" #: main.c:69 msgid "Ext. Model" msgstr "Zewnętrzny Model" #: main.c:70 msgid "Temp." msgstr "Temperatura." #: main.c:71 msgid "Stepping" msgstr "Krok" #: main.c:72 msgid "Instructions" msgstr "Instrukcje" #: main.c:74 msgid "Clocks" msgstr "Zegary" #: main.c:75 msgid "Core Speed" msgstr "Częstotliwość rdzenia" #: main.c:76 msgid "Multiplier" msgstr "Mnożnik" #: main.c:77 msgid "Bus Speed" msgstr "Częstotliwość Szyny" #: main.c:78 main.c:155 msgid "Usage" msgstr "Użycie" #: main.c:80 msgid "Cache" msgstr "Pamięć podręczna" #: main.c:81 msgid "L1 Data" msgstr "L1 Dane" #: main.c:82 msgid "L1 Inst." msgstr "L1 Instrukcja." #: main.c:83 msgid "Level 2" msgstr "Poziom 2" #: main.c:84 msgid "Level 3" msgstr "Poziom 3" #: main.c:86 msgid "Socket(s)" msgstr "Gniazda" #: main.c:87 msgid "Core(s)" msgstr "Rdzenie" #: main.c:88 msgid "Thread(s)" msgstr "Wątki" #: main.c:91 msgid "Caches" msgstr "Pamięci Podręczne" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Pamięć podręczna L%i" #: main.c:96 msgid "Size" msgstr "Rozmiar" #: main.c:97 msgid "Speed" msgstr "Prędkość" #: main.c:99 msgid "Test" msgstr "Testy" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Płyta główna" #: main.c:104 msgid "Manufacturer" msgstr "Producent" #: main.c:106 msgid "Revision" msgstr "Rewizja" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marka" #: main.c:110 msgid "Version" msgstr "Wersja" #: main.c:111 msgid "Date" msgstr "Data" #: main.c:112 msgid "ROM Size" msgstr "ROM Rozmiar" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Pamięć" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Slot %i" #: main.c:123 msgid "Reference" msgstr "Referencja" #: main.c:127 msgid "System" msgstr "System" #: main.c:128 msgid "Operating System" msgstr "System operacyjny" #: main.c:129 msgid "Kernel" msgstr "Jądro" #: main.c:130 msgid "Distribution" msgstr "Dystrybucja" #: main.c:131 msgid "Hostname" msgstr "Nazwa hosta" #: main.c:132 msgid "Uptime" msgstr "Czas pracy" #: main.c:133 msgid "Compiler" msgstr "Kompilator" #: main.c:136 msgid "Used" msgstr "Używana" #: main.c:137 msgid "Buffers" msgstr "Buforowana" #: main.c:138 msgid "Cached" msgstr "Podręczna" #: main.c:139 msgid "Free" msgstr "Wolna" #: main.c:140 msgid "Swap" msgstr "Wymiany" #: main.c:143 msgid "Graphics" msgstr "Grafika" #: main.c:147 #, c-format msgid "Card %i" msgstr "Karta %i" #: main.c:149 msgid "Driver" msgstr "Sterownik" #: main.c:150 msgid "UMD Version" msgstr "Wersja UMD" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatura" #: main.c:156 msgid "Core Voltage" msgstr "Napięcie rdzenia" #: main.c:157 msgid "Power Avg" msgstr "Moc śr" #: main.c:158 msgid "GPU clock" msgstr "Zegar GPU" #: main.c:159 msgid "Memory clock" msgstr "Zegar pamięci" #: main.c:160 msgid "Memory Used" msgstr "Używana pamięć" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Karta %i" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Liczby pierwsze (wolno)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Liczby pierwsze (szybko)" #: main.c:170 msgid "Score" msgstr "Wynik" #: main.c:171 msgid "Run" msgstr "Uruchom" #: main.c:174 msgid "Parameters" msgstr "Parametry" #: main.c:175 msgid "Duration" msgstr "Czas trwania" #: main.c:176 msgid "Threads" msgstr "Wątki" #: main.c:179 main.c:184 msgid "About" msgstr "O Programie" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s jest darmowym programem który gromadzi informacje\n" "o CPU, płycie głównej i wiele więcej." #: main.c:185 #, c-format msgid "Version %s" msgstr "Wersja %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Strona domowa: %s" #: main.c:189 msgid "License" msgstr "Licencja" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "To oprogramowanie jest rozpowszechniane na warunkach %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "To oprogramowanie jest dostarczane bez ŻADNEJ GWARANCJI" #: main.c:265 msgid "Dumping data…" msgstr "Przesyłanie danych…" #: main.c:308 msgid "Freeing memory" msgstr "Zwalnianie pamięci" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Uruchom graficzny interfejs użytkownika (GUI) (domyślnie)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Uruchom tekstowy interfejs użytkownika (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Zrzuć wszystkie dane na standardowe wyjście i wyjdź" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Uruchom wbudowane polecenie dmidecode i wyjdź" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Uruchom wbudowane pasmo poleceń i zakończ" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Ustaw niestandardowy czas między dwoma odświeżeniami (w sekundach)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Ustaw domyślną kartę (liczba całkowita)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Wybierz rdzeń procesora do monitorowania (liczba całkowita)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Ustaw niestandardowy test przepustowości dla szybkości pamięci podręcznej " "procesora (liczba całkowita)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Ustaw domyślną kartę (liczba całkowita)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Uruchamianie i łączenie się z demonem" #: main.c:347 msgid "Verbose output" msgstr "Pełne dane wyjściowe" #: main.c:348 msgid "Print help and exit" msgstr "Drukuj pomoc i wyjdź" #: main.c:349 msgid "Print version and exit" msgstr "Wydrukuj wersję i wyjdź" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" "Wydrukuj wartości CPUID w systemie dziesiętnym (domyślnie szesnastkowo)" #: main.c:351 msgid "Disable colored output" msgstr "Wyłącz kolorowe wyjście" #: main.c:352 msgid "Print information for debugging" msgstr "Wydrukuj informacje do debugowania" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Wydrukuj wymagane informacje do wklejenia w śledzeniu problemów" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Ustaw mapowanie klawiszy dla trybu NCurses (a [rrows] | e [macs] | i " "[nverted-T] | v [im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Dodaj domyślne argumenty wiersza poleceń" #: main.c:366 msgid "Enforce the bus clock" msgstr "Wymuszanie zegara magistrali" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignoruj częstotliwość procesora zgłaszaną przez libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Odczyt danych nieprzetworzonych CPUID z danego pliku" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Wydrukuj komunikat tylko wtedy, gdy CPU nie ma w bazie danych" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Użycie: %s WYŚWIETL [OPCJE]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Dostępny WYŚWIETLACZ:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Dostępne OPCJE:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Zmienne środowiskowe, na które można wpłynąć:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "To jest wolne oprogramowanie: możesz je zmieniać i rozpowszechniać." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Zobacz licencje %s: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s wersja: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "nie udało się wywołać wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s Oops, coś było nie tak! %s otrzymał sygnał %d (%s) i się zawiesił.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Możesz wkleić to śledzenie, otwierając nowy problem tutaj:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "wystąpił błąd podczas ustawiania ustawień regionalnych" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Uruchamianie NCurses TUI…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "Błąd krytyczny: nie można było znaleźć bazy danych terminfo (spróbuj ustawić " "zmienną środowiskową TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Nie można skonfigurować terminala %s (err=%i); powrót do %s" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Okno jest za małe!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Naciśnij 'h' żeby zobaczyć pomoc\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Witamy w pomocy %s NCurses!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "W tej pomocy opisano sposób korzystania z tekstowego interfejsu " "użytkownika.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Klawisze globalne:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tNaciśnij klawisz „w lewo”, aby przełączyć się na lewą kartę.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tNaciśnij klawisz „w prawo”, aby przełączyć na prawą kartę.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tNaciśnij klawisz 'h', aby zobaczyć tę pomoc.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tNacisnąć klawisz \"q\", aby wyjść.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Zakładka CPU:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tNaciśnij przycisk \"w dół\", aby zmniejszyć liczbę rdzeni do " "monitorowania.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tNaciśnij klawisz „w górę”, aby zwiększyć liczbę rdzeni do monitorowania.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Karta Pamięć Podręczna:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tNaciśnij klawisz „w dół”, aby wrócić do poprzedniego testu.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tNaciśnij klawisz „w górę”, aby przejść do następnego testu.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Karta testy wydajności:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "" "\tNaciśnij klawisz „w dół”, aby zmniejszyć czas trwania testu " "porównawczego.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "" "\tNaciśnij klawisz „w górę”, aby zwiększyć czas trwania testu " "porównawczego.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tNaciśnij przycisk „następna strona”, aby zmniejszyć liczbę używanych " "wątków.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tNaciśnij przycisk „poprzednia strona”, aby zwiększyć liczbę używanych " "wątków.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tNaciśnij klawisz 's', aby rozpocząć/zatrzymać test wydajności liczenia " "liczb pierwszych (powoli).\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tNaciśnij klawisz 'f', aby uruchomić/zatrzymać test wydajności zliczania " "liczb pierwszych (szybko).\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Grafika" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tNaciśnij klawisz „w dół”, aby wrócić do poprzedniego testu.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tNaciśnij klawisz „w górę”, aby przejść do następnego testu.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Naciśnij dowolny klawisz, aby zamknąć tę pomoc.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "nie można odnaleźć jednostki w ciągu '%s' w pozycji %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "Ciąg '%s' jest za długi, obcinanie…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "wystąpił błąd podczas otwierania pliku '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "wystąpił błąd podczas uruchamiania polecenia '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "Nie udało się otworzyć pliku %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "wystąpił błąd podczas kompilacji wyrażenia regularnego" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" "pkexec: nie można uzyskać autoryzacji (okno dialogowe zostało odrzucone)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: nie można było uzyskać autoryzacji (nie autoryzowano)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: nie znaleziono polecenia" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: nieoczekiwany kod błędu" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "Błąd krytyczny: nie można przydzielić pamięci" #: cpu-x.h:92 msgid "bytes" msgstr "bajtów" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "Wychodzące %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Pomijam otwarcie CPU MSR (musisz być użytkownikiem root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "nie udało się otworzyć CPU MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Pomijam wykonanie dmidecode (musisz być użytkownikiem root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "nie udało się przydzielić pamięci dla dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "nie udało się wywołać dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Szukam sterownika karty graficznej" #~ msgid "(%s driver)" #~ msgstr "(sterownik %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "nie udało się znaleźć sterownika karty graficznej (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Pobieranie temperatury GPU" #~ msgid "Off" #~ msgstr "Wyłączone" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "nie udało się pobrać temperatury GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "" #~ "Pomijanie kilku wartości o procesorze graficznym (musisz mieć uprawnienia " #~ "root'a)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "nie udało się przydzielić pamięci dla benchmarku" #~ msgid "Root privileges are required to work properly" #~ msgstr "Do prawidłowego działania wymagane są prawa użytkownika root" #~ msgid "Some information will not be retrievable" #~ msgstr "Niektóre informacje nie mogą być pozyskane" #~ msgid "Ignore" #~ msgstr "Ignoruj" #~ msgid "Run as root" #~ msgstr "Uruchom jako root" #~ msgid "A new version of %s is available!" #~ msgstr "Nowa wersja programu %s jest dostępna!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Czy chcesz zaktualizować %s do wersji %s przed zamknięciem?\n" #~ "Spowoduje to nadpisanie pliku binarnego (%s) przez nową wersję." #~ msgid "Not now" #~ msgstr "Nie teraz" #~ msgid "Update" #~ msgstr "Zaktualizuj" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Sprawdzanie dostępności nowej wersji..." #~ msgid "failed to open a Curl session" #~ msgstr "Nie udało się otworzyć sesji Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "Nie udało się przesłać Curl'em (%s)" #~ msgid "wrong write data" #~ msgstr "nieprawidłowy zapis danych" #~ msgid "(version %s is available)" #~ msgstr "(wersja %s jest dostępna)" #~ msgid "No new version available" #~ msgstr "Nie ma nowej wersji" #~ msgid "(up-to-date)" #~ msgstr "(zaktualizowane)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "wystąpił błąd podczas wyodrębniania %s archiwum (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Dostęp do sieci jest wyłączany przez zmienną środowiskową (ustaw wartość " #~ "CPUX_NETWORK na wartość dodatnią, aby ją włączyć)" #~ msgid "failed to open %s archive for writing" #~ msgstr "nie można otworzyć archiwum %s do zapisu" #~ msgid "Downloading new version..." #~ msgstr "Pobieranie nowej wersji..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "nie można wczytać %s archiwum (%s)" #~ msgid "Extracting new version..." #~ msgstr "Rozpakowywanie nowej wersji..." #~ msgid "Applying new version..." #~ msgstr "Stosowanie nowej wersji..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "podczas usuwania/zmiany nazwy plików wystąpił błąd" #~ msgid "Update successful!" #~ msgstr "Aktualizacja zakończona powodzeniem!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Zaktualizuj wersję przenośną, jeśli dostępna jest nowa wersja" #~ msgid "Temporarily disable network support" #~ msgstr "Tymczasowo wyłącz obsługę sieci" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Zbudowane na %s i %s (z użyciem %s%s na %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Niestety nie możesz zaktualizować %s: 32-bitowa wersja przenośna nie jest " #~ "już obsługiwana." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Jeśli chcesz zaktualizować, naciśnij klawisz 'u', lub cokolwiek innego " #~ "aby pominąć.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s zostaną zaktualizowane." CPU-X-4.2.0/po/pt.po000066400000000000000000000734341403012130000137450ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Rui Mendes , 2019. # ssantos , 2019, 2020. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-10-05 12:12+0000\n" "Last-Translator: ssantos \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 4.3-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "A encontrar tecnologias da CPU" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "A sua CPU não existe na base de dados ==> %s, modelo: %i, ext. modelo: %i, " "ext. família: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-via" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-via" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s associativa, %d-%s tamanho da linha" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "A chamar libcpuid para recuperar dados estáticos" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "falhou a chamada de libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "A chamar o libcpuid para recuperar dados dinâmicos" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" "A chamar libcpuid para recuperar valores estáticos do MSR (registo de modelo " "específico) da CPU" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" "A chamar libcpuid para recuperar valores dinâmicos do MSR (registo de modelo " "específico) da CPU" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "A calcular multiplicadores da CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "A chamar dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "A calcular a utilização da CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "A chamar bandwidth (largura de banda)" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "Nenhum driver do kernel em uso para a placa de vídeo no caminho %s" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "O controlador da sua GPU é desconhecido: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "O controlador da sua GPU é desconhecido: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "falhou a chamada de libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "A procurar dispositivos" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Saltar a busca de aparelhos (permissões erradas no aparelho %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "O fabricante da GPU é desconhecido: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "não foi possível encontrar o fabricante e o modelo do chipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "não foi possível encontrar o fabricante e o modelo da placa gráfica" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "A obter as velocidades da GPU" #: core.c:990 msgid "None" msgstr "Nenhum" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "O driver para a GPU %u não reporta frequências" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "não foi possível obter as velocidades da GPU" #: core.c:1205 msgid "Identifying running system" msgstr "A identificar o sistema operativo em execução" #: core.c:1208 msgid "failed to identify running system" msgstr "não foi possível identificar o sistema operativo em execução" #: core.c:1249 msgid "Calling libprocps" msgstr "A chamar libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "A chamar libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dias, %i horas, %i minutos, %i segundos" #: core.c:1366 msgid "Updating benchmark status" msgstr "A atualizar o estado do benchmark" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inativo" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Não iniciado" #: core.c:1380 msgid "Active" msgstr "Ativo" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u horas restantes)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minutos restantes)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u segundos restantes)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "em %u horas" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "em %u minutos" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "em %u segundos" #: core.c:1414 msgid "Starting benchmark" msgstr "Iniciando benchmark" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "um erro ocorreu enquanto iniciava o benchmark" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Encontrando o pacote da CPU em modo fallback" #: core.c:1472 #, fuzzy, c-format #| msgid "Your CPU socket does not belong in database ==> %s, codename: %s" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Seu socket de CPU não existe no banco de dados ==> %s, codinome: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Calculando multiplicadores da CPU em modo fallback" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Recuperando informações da placa-mãe em modo fallback" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "falhou ao recuperar informações da placa-mãe (modo fallback)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Recuperando a temperatura da CPU em modo fallback" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "falhou ao recuperar a temperatura da CPU (modo fallback)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Recuperando a voltagem da CPU em modo fallback" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "falhou ao recuperar a voltagem da CPU (modo fallback)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Recuperando a frequência da CPU em modo fallback" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "falhou ao recuperar a frequência da CPU (modo fallback)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: caso %i não tratado" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Iniciando a interface gráfica GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "Falhou ao importar UI no GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Conectado ao daemon" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Nenhum agente de autenticação polkit foi encontrado" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Pedir palavra-passe para iniciar o daemon em segundo plano" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Iniciar daemon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Núcleo #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Configurando nome dos rótulos" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processador" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Fabricante" #: main.c:61 msgid "Code Name" msgstr "Nome de código" #: main.c:62 msgid "Package" msgstr "Pacote" #: main.c:63 msgid "Technology" msgstr "Tecnologia" #: main.c:64 msgid "Voltage" msgstr "Voltagem" #: main.c:65 msgid "Specification" msgstr "Especificação" #: main.c:66 msgid "Family" msgstr "Família" #: main.c:67 msgid "Ext. Family" msgstr "Ext. Família" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modelo" #: main.c:69 msgid "Ext. Model" msgstr "Ext. Modelo" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Stepping" #: main.c:72 msgid "Instructions" msgstr "Instruções" #: main.c:74 msgid "Clocks" msgstr "Frequências" #: main.c:75 msgid "Core Speed" msgstr "Velocidade do núcleo" #: main.c:76 msgid "Multiplier" msgstr "Multiplicador" #: main.c:77 msgid "Bus Speed" msgstr "Velocidade do bus" #: main.c:78 main.c:155 msgid "Usage" msgstr "Utilização" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "L1 Data" #: main.c:82 msgid "L1 Inst." msgstr "L1 Instruções" #: main.c:83 msgid "Level 2" msgstr "Nível 2" #: main.c:84 msgid "Level 3" msgstr "Nível 3" #: main.c:86 msgid "Socket(s)" msgstr "Socket(s)" #: main.c:87 msgid "Core(s)" msgstr "Núcleo(s)" #: main.c:88 msgid "Thread(s)" msgstr "Thread(s)" #: main.c:91 msgid "Caches" msgstr "Caches" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Cache L%i" #: main.c:96 msgid "Size" msgstr "Tamanho" #: main.c:97 msgid "Speed" msgstr "Velocidade" #: main.c:99 msgid "Test" msgstr "Testar" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Placa-mãe" #: main.c:104 msgid "Manufacturer" msgstr "Fabricante" #: main.c:106 msgid "Revision" msgstr "Revisão" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marca" #: main.c:110 msgid "Version" msgstr "Versão" #: main.c:111 msgid "Date" msgstr "Data" #: main.c:112 msgid "ROM Size" msgstr "Tamanho da ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memória" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banco %i" #: main.c:123 msgid "Reference" msgstr "Referência" #: main.c:127 msgid "System" msgstr "Sistema" #: main.c:128 msgid "Operating System" msgstr "Sistema operativo" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribuição" #: main.c:131 msgid "Hostname" msgstr "Nome do host" #: main.c:132 msgid "Uptime" msgstr "Tempo ligado" #: main.c:133 msgid "Compiler" msgstr "Compilador" #: main.c:136 msgid "Used" msgstr "Utilizado" #: main.c:137 msgid "Buffers" msgstr "Buffers" #: main.c:138 msgid "Cached" msgstr "Em cache" #: main.c:139 msgid "Free" msgstr "Livre" #: main.c:140 msgid "Swap" msgstr "Swap" #: main.c:143 msgid "Graphics" msgstr "Gráficos" #: main.c:147 #, c-format msgid "Card %i" msgstr "Placa %i" #: main.c:149 msgid "Driver" msgstr "Driver" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Versão" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Temperatura" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Voltagem" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "Velocidade da GPU" #: main.c:159 msgid "Memory clock" msgstr "Velocidade da memória" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Memória" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Placa %i" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Números primos (lento)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Números primos (rápido)" #: main.c:170 msgid "Score" msgstr "Pontuação" #: main.c:171 msgid "Run" msgstr "Executar" #: main.c:174 msgid "Parameters" msgstr "Parâmetros" #: main.c:175 msgid "Duration" msgstr "Duração" #: main.c:176 msgid "Threads" msgstr "Threads" #: main.c:179 main.c:184 msgid "About" msgstr "Sobre" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s é um programa de código livre que recolhe\n" "informações sobre o processador, a placa-mãe e mais." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versão %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Site: %s" #: main.c:189 msgid "License" msgstr "Licença" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Este programa é distribuído nos termos da licença %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Este programa é fornecido ABSOLUTAMENTE SEM NENHUMA GARANTIA" #: main.c:265 msgid "Dumping data…" msgstr "A despejar dados (dumping)…" #: main.c:308 msgid "Freeing memory" msgstr "A libertar memória" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Iniciar a interface de utilizador em modo gráfico (GUI) (padrão)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Iniciar a interface de utilizador em modo de texto (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Despejar todos os dados na saída padrão e sair" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Executa o comando dmidecode embutido e sai" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Executa o comando bandwidth embutido e sai" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" "Definir um intervalo personalizado entre duas atualizações (em segundos)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Define a aba padrão (inteiro)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Selecione um núcleo de CPU para monitorar (inteiro)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Definir um teste de bandwidth personalizado para a velocidade de cache da " "CPU (inteiro)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Define a aba padrão (inteiro)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Iniciar e conectar ao daemon" #: main.c:347 msgid "Verbose output" msgstr "Saída verbosa" #: main.c:348 msgid "Print help and exit" msgstr "Imprime a ajuda e sai" #: main.c:349 msgid "Print version and exit" msgstr "Imprime a versão e sai" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "Desativar saída a cores" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Imprimir informações necessárias para colar em uma questão" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "Forçar o bus clock" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Ler dados crus do CPUID de um determinado ficheiro" #: main.c:369 #, fuzzy #| msgid "Only print a message if CPU does not belong in database" msgid "Only print a message if CPU is not present in the database" msgstr "Somente mostrar uma mensagem se a CPU não estiver no banco de dados" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Uso: %s TELA [OPÇÕES]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Tela disponível:" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPÇÕES disponíveis:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variáveis de ambiente influenciáveis:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Isto é um programa livre: tem a liberdade de o alterar e redistribuí-lo." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Veja a licença %s em: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s versão: %s" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "falhou a chamada de libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sOops, alguma coisa está errada! %s recebeu o sinal %d (%s) e saiu.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Você pode colar esse backtrace abrindo uma nova issue aqui:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "um erro ocorreu enquanto definia a localização" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Iniciando a interface de texto NCurses…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ERRO FATAL: não foi possível encontrar o banco de dados terminfo (tente " "definir a variável de ambiente TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Falha ao configurar o terminal %s (err=%i); voltando para %s" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "A janela é pequena demais!\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Pressione 'h' para ver a ajuda.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Bem vindo a ajuda do %s Ncurses!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "" "Essa ajuda descreve como usar a interface de utilizador baseada em texto.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Chaves globais:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\tPressione a tecla 'esquerda' para alternar a aba esquerda.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\tPressione a tecla 'direita' para alternar a aba direita.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\tPressione 'h' para ver essa ajuda.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\tPressione a tecla 'q' para sair.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Separador da CPU:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "" "\tPressione a tecla 'abaixo' para diminutir o número de núcleos à " "monitorar.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "\tPressione a tecla 'acima' para aumentar o número de núcleos à monitorar.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Separador das Caches:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\tPressione a tecla 'abaixo' para alternar para o teste anterior.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\tPressione a tecla 'acima' para alternar para o próximo teste.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Aba Bench:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "" "\tPressione a tecla 'abaixo' para decrementar a duração do benchmark.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "\tPressione a tecla 'acima' para incrementar a duração do benchmark.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "\tPressione a tecla 'próxima página' para decrementar o número de threads\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "\tPressione a tecla 'página anterior' para incrementar o número de threads\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "\tPressione a tecla 's' para iniciar/parar o benchmark de números primos " "(lento).\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "\tPressione a tecla 'f' para iniciar/parar o benchmark de números primos " "(rápido).\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Gráficos" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\tPressione a tecla 'abaixo' para alternar para o teste anterior.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\tPressione a tecla 'acima' para alternar para o próximo teste.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Pressione qualquer tecla para sair desta ajuda.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "não é possível encontrar a unidade na cadeia '%s' na posição %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "um erro ocorreu enquanto abria o ficheiro '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "um erro ocorreu enquanto rodava o comando '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "falhou ao abrir o diretório %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "um erro ocorreu enquanto compilava o regex" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" "pkexec: não foi possível obter a autorização (caixa de diálogo ignorada)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: não foi possível obter a autorização (não autorizado)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: comando não encontrado" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: código de erro inesperado" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ERRO FATAL: não foi possível alocar a memória" #: cpu-x.h:92 msgid "bytes" msgstr "bytes" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "MB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "GB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "TB" #~ msgid "Exiting %s" #~ msgstr "A sair do %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "A ignorar a abertura do MSR (registo de modelo específico) da CPU (tem de " #~ "ser root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "" #~ "Não foi possível abrir o MSR (registo de modelo específico) da CPU (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "A ignorar a chamada ao dmidecode (tem de ser root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "falhou a alocação de memória para o dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "falhou a chamada de dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "A procurar o controlador da placa gráfica" #~ msgid "(%s driver)" #~ msgstr "(%s controlador)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "não foi possível encontrar o controlador da placa gráfica (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "A obter a temperatura da GPU" #~ msgid "Off" #~ msgstr "Desligado" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "não foi possível obter a temperatura da GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Ignorar alguns valores da GPU (tem de ser root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "falhou ao alocar memória para o benchmark" #~ msgid "Root privileges are required to work properly" #~ msgstr "É necessário privilégios de root para funcionar corretamente" #~ msgid "Some information will not be retrievable" #~ msgstr "Algumas informações não serão recuperáveis" #~ msgid "Ignore" #~ msgstr "Ignorar" #~ msgid "Run as root" #~ msgstr "Executar como root" #~ msgid "A new version of %s is available!" #~ msgstr "Está disponível uma nova versão do %s!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Quer atualizar o %s para a versão %s depois de sair?\n" #~ "Isso vai substituir o ficheiro binário (%s) pela nova versão." #~ msgid "Not now" #~ msgstr "Agora não" #~ msgid "Update" #~ msgstr "Atualizar" #~ msgid "Checking on Internet for a new version..." #~ msgstr "A verificar se existe uma nova versão na Internet..." #~ msgid "failed to open a Curl session" #~ msgstr "não foi possível abrir uma sessão do Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "falhou ao realizar a transferência Curl (%s)" #~ msgid "wrong write data" #~ msgstr "dados de escrita incorretos" #~ msgid "(version %s is available)" #~ msgstr "(está disponível a versão %s)" #~ msgid "No new version available" #~ msgstr "Não há nova versão disponível" #~ msgid "(up-to-date)" #~ msgstr "(atualizado)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "ocorreu um erro ao extrair o arquivo %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "O acesso à rede está desativado por uma variável de ambiente (defina " #~ "CPUX_NETWORK com um valor positivo para ativar)" #~ msgid "failed to open %s archive for writing" #~ msgstr "falhou ao abrir o arquivo %s para escrita" #~ msgid "Downloading new version..." #~ msgstr "A descarregar a nova versão..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "não foi possível descarregar o arquivo %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "A extrair a nova versão..." #~ msgid "Applying new version..." #~ msgstr "A aplicar a nova versão..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "ocorreu um erro ocorreu ao eliminar/alterar o nome dos ficheiros" #~ msgid "Update successful!" #~ msgstr "Atualização bem sucedida!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Atualizar a versão portátil se uma nova versão estiver disponível" #~ msgid "Temporarily disable network support" #~ msgstr "Desabilitar temporariamente o suporte à rede" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Compilado em %s, %s (com %s %s em %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Desculpe, você não pode atualizar %s: a versão portátil de 32 bits não é " #~ "mais suportada." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "se você quiser atualizar, pressione a tecla 'u', ou qualquer outra para " #~ "pular.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s vai ser atualizado." CPU-X-4.2.0/po/pt_BR.po000066400000000000000000000705651403012130000143320ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # Lara Maia , 2015-2016,2018 # Rui Mendes , 2019. # Seila Oxe , 2019. # DanielDevBR , 2020. # Celio Alves , 2020, 2021. # Samuel Carvalho de Araújo , 2020. # André Marcelo Alvarenga , 2020. # LL Magical , 2020. # Wellington Terumi Uemura , 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-28 13:27+0000\n" "Last-Translator: Wellington Terumi Uemura \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 4.6-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Localizando a tecnologia da CPU" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "A sua CPU não consta do banco de dados ==> %s, modelo: %i, ext. modelo: %i, " "ext. família: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-via(s)" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-via(s)" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s associativa, tam. linha %d-%s" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Invocando o libcpuid para recuperar os dados estáticos" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "Falha ao invocar o libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Invocando o libcpuid para recuperar os dados dinâmicos" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Invocando o libcpuid para recuperar os valores estáticos da CPU MSR" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Invocando o libcpuid para recuperar os valores dinâmicos da CPU MSR" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Calculando os multiplicadores da CPU" #: core.c:521 msgid "Calling dmidecode" msgstr "Invocando o dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Calculando a utilização da CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Invocando a largura de banda" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" "Não há um driver do kernel sendo utilizado para a placa de vídeo no caminho " "%s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "O driver da sua GPU é desconhecido: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "O driver modo de usuário da sua GPU é desconhecido: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "Houve uma falha ao invocar o GLFW (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Localizando os dispositivos" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" "Ignore a pesquisa dos dispositivos (permissões erradas no dispositivo %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "A fabricante da GPU é desconhecido: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" "houve uma falha durante a localização do fabricante e do modelo do chipset" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" "houve uma falha durante a localização do fabricante e do modelo da placa de " "vídeo" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Obtendo a frequência da GPU" #: core.c:990 msgid "None" msgstr "Nenhum" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "O driver para a GPU %u não informa quaisquer frequências" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "Atual: PCIe Gen%1dx%d / Max: Gen%1dx%d" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "Houve uma falha durante a obtenção da frequência da GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Identificando o sistema atual" #: core.c:1208 msgid "failed to identify running system" msgstr "houve uma falha durante a identificação do sistema atual" #: core.c:1249 msgid "Calling libprocps" msgstr "Invocando o libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Invocando o libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dias, %i horas, %i minutos, %i segundos" #: core.c:1366 msgid "Updating benchmark status" msgstr "Atualizando o status do benchmark" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inativo" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Não iniciado" #: core.c:1380 msgid "Active" msgstr "Ativo" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u horas restantes)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minutos restantes)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u segundos restantes)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "em %u horas" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "em %u minutos" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "em %u segundos" #: core.c:1414 msgid "Starting benchmark" msgstr "Iniciando o benchmark" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "ocorreu um erro durante a inicialização do benchmark" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Localizando o pacote da CPU no modo fallback" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "O soquete da sua CPU não consta no banco de dados ==> %s, codinome: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Calculando os multiplicadores da CPU no modo fallback" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Recuperando as informações da placa-mãe no modo fallback" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" "houve uma falha durante a recuperação das informações da placa-mãe (modo " "fallback)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Recuperando a temperatura da CPU em modo fallback" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" "houve uma falha durante a recuperação da temperatura da CPU (modo fallback)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Recuperando a tensão da CPU no modo fallback" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "houve uma falha durante a recuperação da tensão da CPU (modo fallback)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Recuperando a frequência da CPU em modo fallback" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" "houve uma falha durante a recuperação da frequência da CPU (modo fallback)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: caso %i não tratado" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Iniciando a interface gráfica GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "Houve uma falha ao importar a IU no GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Conectado ao daemon" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Não foi encontrado nenhum agente de autenticação polkit" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Peça pela senha para iniciar o daemon em segundo plano" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Iniciar o daemon" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Núcleo #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Configurando o nome das etiquetas" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processador" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Fornecedor" #: main.c:61 msgid "Code Name" msgstr "Codinome" #: main.c:62 msgid "Package" msgstr "Pacote" #: main.c:63 msgid "Technology" msgstr "Tecnologia" #: main.c:64 msgid "Voltage" msgstr "Tensão" #: main.c:65 msgid "Specification" msgstr "Especificação" #: main.c:66 msgid "Family" msgstr "Família" #: main.c:67 msgid "Ext. Family" msgstr "Ext. Família" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modelo" #: main.c:69 msgid "Ext. Model" msgstr "Ext. Modelo" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Passo" #: main.c:72 msgid "Instructions" msgstr "Instruções" #: main.c:74 msgid "Clocks" msgstr "Frequências" #: main.c:75 msgid "Core Speed" msgstr "Velocidade do Núcleo" #: main.c:76 msgid "Multiplier" msgstr "Multiplicador" #: main.c:77 msgid "Bus Speed" msgstr "Velocidade do Barramento" #: main.c:78 main.c:155 msgid "Usage" msgstr "Uso" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "L1 Data" #: main.c:82 msgid "L1 Inst." msgstr "L1 Inst." #: main.c:83 msgid "Level 2" msgstr "Level 2" #: main.c:84 msgid "Level 3" msgstr "Level 3" #: main.c:86 msgid "Socket(s)" msgstr "Socket(s)" #: main.c:87 msgid "Core(s)" msgstr "Núcleo(s)" #: main.c:88 msgid "Thread(s)" msgstr "Thread(s)" #: main.c:91 msgid "Caches" msgstr "Caches" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Cache L%i" #: main.c:96 msgid "Size" msgstr "Tamanho" #: main.c:97 msgid "Speed" msgstr "Velocidade" #: main.c:99 msgid "Test" msgstr "Teste" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Placa-mãe" #: main.c:104 msgid "Manufacturer" msgstr "Fabricante" #: main.c:106 msgid "Revision" msgstr "Revisão" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marca" #: main.c:110 msgid "Version" msgstr "Versão" #: main.c:111 msgid "Date" msgstr "Data" #: main.c:112 msgid "ROM Size" msgstr "Tamanho da ROM" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Memória" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Banco %i" #: main.c:123 msgid "Reference" msgstr "Referência" #: main.c:127 msgid "System" msgstr "Sistema" #: main.c:128 msgid "Operating System" msgstr "Sistema Operacional" #: main.c:129 msgid "Kernel" msgstr "Kernel" #: main.c:130 msgid "Distribution" msgstr "Distribuição" #: main.c:131 msgid "Hostname" msgstr "Nome do Host" #: main.c:132 msgid "Uptime" msgstr "Tempo de operação" #: main.c:133 msgid "Compiler" msgstr "Compilador" #: main.c:136 msgid "Used" msgstr "Utilizado" #: main.c:137 msgid "Buffers" msgstr "Buffers" #: main.c:138 msgid "Cached" msgstr "Em Cache" #: main.c:139 msgid "Free" msgstr "Disponível" #: main.c:140 msgid "Swap" msgstr "Swap" #: main.c:143 msgid "Graphics" msgstr "Gráficos" #: main.c:147 #, c-format msgid "Card %i" msgstr "Placa %i" #: main.c:149 msgid "Driver" msgstr "Controladora" #: main.c:150 msgid "UMD Version" msgstr "Versão UMD" #: main.c:152 msgid "DeviceID" msgstr "ID do dispositivo" #: main.c:153 msgid "Interface" msgstr "Interface" #: main.c:154 msgid "Temperature" msgstr "Temperatura" #: main.c:156 msgid "Core Voltage" msgstr "Tensão Principal" #: main.c:157 msgid "Power Avg" msgstr "Média da Alimentação" #: main.c:158 msgid "GPU clock" msgstr "Frequência da GPU" #: main.c:159 msgid "Memory clock" msgstr "Frequência da memória" #: main.c:160 msgid "Memory Used" msgstr "Utilização da Memória" #: main.c:162 msgid "Cards" msgstr "Placas" #: main.c:165 msgid "Bench" msgstr "Bench" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Números primos (lento)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Números primos (rápido)" #: main.c:170 msgid "Score" msgstr "Nota" #: main.c:171 msgid "Run" msgstr "Executar" #: main.c:174 msgid "Parameters" msgstr "Parâmetros" #: main.c:175 msgid "Duration" msgstr "Duração" #: main.c:176 msgid "Threads" msgstr "Threads" #: main.c:179 main.c:184 msgid "About" msgstr "Sobre" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s é um software Livre que coleta informações sobre\n" "a sua CPU, placa-mãe e mais." #: main.c:185 #, c-format msgid "Version %s" msgstr "Versão %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Autor: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Site: %s" #: main.c:189 msgid "License" msgstr "Licença" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Este programa é distribuído sob os termos da %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Este programa vem com ABSOLUTAMENTE NENHUMA GARANTIA" #: main.c:265 msgid "Dumping data…" msgstr "Despejando dados…" #: main.c:308 msgid "Freeing memory" msgstr "Liberando a memória" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Inicie a interface do usuário em modo gráfico (GUI) (padrão)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Inicie a interface de usuário em modo texto (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Despeje todos os dados na saída padrão e encerre" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Execute o comando integrado dmidecode e encerre" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Execute o comando integrado bandwidth e encerre" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" "Defina um intervalo personalizado entre as duas atualizações (em segundos)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Defina a aba padrão (valor inteiro)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Selecione um núcleo da CPU para monitorar (inteiro)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Defina um teste de bandwidth personalizado para a velocidade da cache da CPU " "(valor inteiro)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "Defina a placa gráfica padrão (valor inteiro)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Inicie e conecte ao daemon" #: main.c:347 msgid "Verbose output" msgstr "Saída detalhada" #: main.c:348 msgid "Print help and exit" msgstr "Imprima a ajuda e encerre" #: main.c:349 msgid "Print version and exit" msgstr "Imprima a versão e encerre" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "Imprima os valores do CPUID em decimal (o padrão é hexadeximal)" #: main.c:351 msgid "Disable colored output" msgstr "Desabilite a saída colorida" #: main.c:352 msgid "Print information for debugging" msgstr "Imprima as informações para a depuração" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Imprima as informações necessárias para colar em um assunto" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Definir o mapeamento das chaves para o modo NCurses (a[rrows]|e[macs]|" "i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Adicione as opções padrão na linha de comando" #: main.c:366 msgid "Enforce the bus clock" msgstr "Imponha a frequência do barramento" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignore a frequência da CPU informada pelo libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Leia os dados brutos do CPUID a partir de um determinado arquivo" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Exiba somente uma mensagem caso a CPU não exista no banco de dados" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Uso: %s TELA [OPÇÕES]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Tela disponível:" #: main.c:403 msgid "Available OPTIONS:" msgstr "OPÇÕES disponíveis:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Variáveis importantes do ambiente:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Este é um programa livre: você é livre para modificá-lo e para redistribuí-" "lo." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Consulte a %s licença: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s versão: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "Houve uma falha ao invocar o wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sOops, alguma coisa está errada! %s recebeu o sinal %d (%s) e encerrou.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Você pode colar esse backtrace abrindo uma nova issue aqui:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "ocorreu um erro enquanto a localização estava sendo definida" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Iniciando a interface de texto NCurses…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ERRO FATAL: não foi possível encontrar o banco de dados terminfo (tente " "definir a variável de ambiente TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" "Houve uma falha ao configurar o terminal %s (err=%i); retornando para %s" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "A janela é muito pequena!" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "Pressione 'h' para ver a ajuda." #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Bem vindo a ajuda do %s Ncurses!\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" "Essa ajuda descreve como usar a interface do usuário com base em texto." #: tui_ncurses.c:477 msgid "Global keys:" msgstr "Chaves globais:" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "Pressione a tecla 'esquerda' para alternar para a aba esquerda." #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "Pressione a tecla 'direita' para alternar para a aba direita." #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "Pressione 'h' para ver esta ajuda." #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "Pressione a tecla 'q' para encerrar." #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "Aba da CPU:" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" "Pressione a tecla 'abaixo' para reduzir a quantidade dos núcleos que serão " "monitorados." #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" "Pressione a tecla 'acima' para aumentar a quantidade dos núcleos que serão " "monitorados." #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "Aba Caches:" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "Pressione a tecla 'abaixo' para alternar para o teste anterior." #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "Pressione a tecla 'acima' para alternar para o próximo teste." #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "Aba Bench:" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "Pressione a tecla 'abaixo' para reduzir a duração do benchmark." #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "Pressione a tecla 'acima' para aumentar a duração do benchmark." #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "Pressione a tecla 'próxima página' para reduzir a quantidade de threads." #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "Pressione a tecla 'página anterior' para aumentar a quantidade das threads." #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "Pressione a tecla 's' para iniciar/parar o benchmark dos números primos " "(lento)." #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "Pressione a tecla 'f' para iniciar/parar o benchmark dos números primos " "(rápido)." #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "Aba gráficos:" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" "Pressione a tecla 'abaixo' para alternar para a placa gráfica anterior." #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "Pressione a tecla 'acima' para alternar para a próxima placa gráfica." #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "Pressione qualquer tecla para encerrar esta ajuda." #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "não é possível encontrar a unidade na string '%s' na posição %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "A string '%s' é muito grande, cortando…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "ocorreu um erro enquanto abria o arquivo '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "ocorreu um erro enquanto executava o comando '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "houve uma falha ao abrir o diretório %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "ocorreu um erro enquanto compilava o regex" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" "pkexec: não foi possível obter a autorização (caixa de diálogo ignorada)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: não foi possível obter a autorização (não autorizado)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: o comando não foi encontrado" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: código de erro inesperado" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ERRO FATAL: não foi possível alocar a memória" #: cpu-x.h:92 msgid "bytes" msgstr "bytes" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "Saindo %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "Pular abertura do CPU MSR (precisa estar em root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "Falha ao abrir CPU MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Pular chamada ao dmidecode (precisa estar em root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "falhou ao alocar memória para o dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "falhou ao chamar o dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Encontrando driver da placa de vídeo" #~ msgid "(%s driver)" #~ msgstr "(%s driver)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "Falha ao encontrar o driver da placa de vídeo (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Obtendo temperatura da GPU" #~ msgid "Off" #~ msgstr "Desativado" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "falha ao obter a temperatura da GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Ignorar alguns valores da GPU (precisa ser root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "falhou ao alocar memória para o benchmark" #~ msgid "Root privileges are required to work properly" #~ msgstr "É necessário privilégios de root para funcionar corretamente" #~ msgid "Some information will not be retrievable" #~ msgstr "Algumas informações não serão recuperáveis" #~ msgid "Ignore" #~ msgstr "Ignorar" #~ msgid "Run as root" #~ msgstr "Executar como root" #~ msgid "A new version of %s is available!" #~ msgstr "Uma nova versão do %s está disponível!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Você quer atualizar %s para a versão %s depois de sair?\n" #~ "Isso vai substituir o arquivo binário (%s) com a nova versão." #~ msgid "Not now" #~ msgstr "Não agora" #~ msgid "Update" #~ msgstr "Atualizar" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Checando na internet por uma nova versão..." #~ msgid "failed to open a Curl session" #~ msgstr "falhou ao abrir uma sessão do Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "falhou ao realizar a transferência Curl (%s)" #~ msgid "wrong write data" #~ msgstr "dados de escrita incorretos" #~ msgid "(version %s is available)" #~ msgstr "(versão %s está disponível)" #~ msgid "No new version available" #~ msgstr "Nenhuma nova versão disponível" #~ msgid "(up-to-date)" #~ msgstr "(atualizado)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "um erro ocorreu enquanto extraía o arquivo %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "O acesso a rede está desabilitado por uma variável de ambiente (defina " #~ "CPUX_NETWORK com um valor positivo para habilitar)" #~ msgid "failed to open %s archive for writing" #~ msgstr "falhou ao abrir o arquivo %s para escrita" #~ msgid "Downloading new version..." #~ msgstr "Baixando nova versão..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "falhou ao baixar o arquivo %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Extraindo nova versão..." #~ msgid "Applying new version..." #~ msgstr "Aplicando nova versão..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "um erro ocorreu enquanto deletava/renomeava arquivos" #~ msgid "Update successful!" #~ msgstr "Atualização bem sucedida!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Atualizar a versão portátil se uma nova versão estiver disponível" #~ msgid "Temporarily disable network support" #~ msgstr "Desabilitar temporariamente o suporte à rede" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Compilado em %s, %s (com %s %s em %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Desculpe, você não pode atualizar %s: a versão portátil de 32 bits não é " #~ "mais suportada." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "se você quiser atualizar, pressione a tecla 'u', ou qualquer outra para " #~ "pular.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s vai ser atualizado." CPU-X-4.2.0/po/ru.po000066400000000000000000001067141403012130000137460ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # TotalCaesar659 , 2016,2018 # Xorg , 2019. # Andrei Stepanov , 2020. # Artem , 2020. # Alex , 2020. # Виктор Ерухин , 2021. # Andrey F. , 2021. # vadimkozhin , 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-05 22:50+0000\n" "Last-Translator: vadimkozhin \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=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" "X-Generator: Weblate 4.5.1\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Обнаружение технологии ЦП" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Ваш ЦП отсутствует в базе данных ==> %s, модель: %i, доп. модель: %i, доп. " "семейство: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-канальный" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-канальный" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s ассоциативный, %d-%s размер кэш-линии" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Вызов libcpuid для получения статических данных" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "не удалось вызвать libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Вызов libcpuid для получения динамических данных" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" "Вызов libcpuid для получения статических значений моделезависимых регистров " "ЦП" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" "Вызов libcpuid для получения динамических значений моделезависимых регистров " "ЦП" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Подсчет множителей ЦП" #: core.c:521 msgid "Calling dmidecode" msgstr "Вызов dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Подсчет использования ЦП" #: core.c:605 msgid "Calling bandwidth" msgstr "Вызов пропускной способности" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "В ядре нет драйвера для видео карты по адресу %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Неизвестный драйвер ядра ГП: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Неизвестный драйвер ГП: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call wordexp (%i)" msgid "failed to call GLFW (%i): %s" msgstr "не удалось вызвать wordexp (%i)" #: core.c:817 msgid "Finding devices" msgstr "Поиск устройств" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Пропустить поиск устройств (некорректные права на устройстве %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Неизвестный производитель ГП: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "не удалось найти производителя и модель чипсета" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "не удалось найти производителя и модель видеокарты" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Получение частоты ГП" #: core.c:990 msgid "None" msgstr "Отсутствует" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Драйвер ГП %u не отдает значения частоты" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "не удалось получить частоту ГП" #: core.c:1205 msgid "Identifying running system" msgstr "Определение запущенной системы" #: core.c:1208 msgid "failed to identify running system" msgstr "не удалось определить запущенную систему" #: core.c:1249 msgid "Calling libprocps" msgstr "Вызов libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Вызов libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i дней, %i часов, %i минут, %i секунд" #: core.c:1366 msgid "Updating benchmark status" msgstr "Обновление состояния бенчмарка" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u минут" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Неактивен" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Не запускался" #: core.c:1380 msgid "Active" msgstr "Активен" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(осталось %u часов)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(осталось %u минут)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(осталось %u секунд)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "за %u часов" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "за %u минут" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "за %u секунд" #: core.c:1414 msgid "Starting benchmark" msgstr "Запуск бенчмарка" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "ошибка при запуске бенчмарка" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Поиск корпусировки ЦП в fallback-режиме" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Ваш сокет ЦП отсутствует в базе данных ==> %s, кодовое название: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Подсчет множителей ЦП в fallback-режиме" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Получение информации о материнской плате в fallback-режиме" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "не удалось получить информацию о материнской плате (fallback-режим)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Получение температуры ЦП в fallback-режиме" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "не удалось получить температуру ЦП (fallback-режим)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Получение напряжения ЦП в fallback-режиме" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "не удалось получить напряжение ЦП (fallback-режим)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Получение частоты ЦП в fallback-режиме" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "не удалось получить частоту ЦП (fallback-режим)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: %i не обрабатывается" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Запуск графического интерфейса GTK…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "не удалось импортировать интерфейс в GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Подключение к демону" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Не найдена аутентификация агента polkit" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Требуется пароль для запуска демона в фоновом режиме" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Запустить демона" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Ядро #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Установка названий меток" #: main.c:58 msgid "CPU" msgstr "ЦП" #: main.c:59 msgid "Processor" msgstr "Процессор" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Производитель" #: main.c:61 msgid "Code Name" msgstr "Кодовое название" #: main.c:62 msgid "Package" msgstr "Сокет" #: main.c:63 msgid "Technology" msgstr "Технология" #: main.c:64 msgid "Voltage" msgstr "Напряжение" #: main.c:65 msgid "Specification" msgstr "Спецификация" #: main.c:66 msgid "Family" msgstr "Семейство" #: main.c:67 msgid "Ext. Family" msgstr "Доп. семейство" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Модель" #: main.c:69 msgid "Ext. Model" msgstr "Доп. модель" #: main.c:70 msgid "Temp." msgstr "Темп." #: main.c:71 msgid "Stepping" msgstr "Степпинг" #: main.c:72 msgid "Instructions" msgstr "Инструкции" #: main.c:74 msgid "Clocks" msgstr "Частоты" #: main.c:75 msgid "Core Speed" msgstr "Тактовая частота ядра" #: main.c:76 msgid "Multiplier" msgstr "Множитель" #: main.c:77 msgid "Bus Speed" msgstr "Скорость шины" #: main.c:78 main.c:155 msgid "Usage" msgstr "Использование" #: main.c:80 msgid "Cache" msgstr "Кэш" #: main.c:81 msgid "L1 Data" msgstr "Уровень 1 (данные)" #: main.c:82 msgid "L1 Inst." msgstr "1 уровень инструкц." #: main.c:83 msgid "Level 2" msgstr "Уровень 2" #: main.c:84 msgid "Level 3" msgstr "Уровень 3" #: main.c:86 msgid "Socket(s)" msgstr "Сокет(-ы)" #: main.c:87 msgid "Core(s)" msgstr "Ядро(-а)" #: main.c:88 msgid "Thread(s)" msgstr "Поток(-и)" #: main.c:91 msgid "Caches" msgstr "Кэши" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "Кэш L%i" #: main.c:96 msgid "Size" msgstr "Размер" #: main.c:97 msgid "Speed" msgstr "Скорость" #: main.c:99 msgid "Test" msgstr "Тест" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Материнская плата" #: main.c:104 msgid "Manufacturer" msgstr "Производитель" #: main.c:106 msgid "Revision" msgstr "Ревизия" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Марка" #: main.c:110 msgid "Version" msgstr "Версия" #: main.c:111 msgid "Date" msgstr "Дата" #: main.c:112 msgid "ROM Size" msgstr "Размер ROM" #: main.c:114 msgid "Chipset" msgstr "Чипсет" #: main.c:119 main.c:135 msgid "Memory" msgstr "Оперативная память" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Модуль %i" #: main.c:123 msgid "Reference" msgstr "Описание" #: main.c:127 msgid "System" msgstr "Система" #: main.c:128 msgid "Operating System" msgstr "Операционная система" #: main.c:129 msgid "Kernel" msgstr "Ядро" #: main.c:130 msgid "Distribution" msgstr "Дистрибутив" #: main.c:131 msgid "Hostname" msgstr "Имя хоста" #: main.c:132 msgid "Uptime" msgstr "Время работы" #: main.c:133 msgid "Compiler" msgstr "Компилятор" #: main.c:136 msgid "Used" msgstr "Используется" #: main.c:137 msgid "Buffers" msgstr "Буферы" #: main.c:138 msgid "Cached" msgstr "Кэш" #: main.c:139 msgid "Free" msgstr "Свободно" #: main.c:140 msgid "Swap" msgstr "Подкачка" #: main.c:143 msgid "Graphics" msgstr "Графическая подсистема" #: main.c:147 #, c-format msgid "Card %i" msgstr "Карта %i" #: main.c:149 msgid "Driver" msgstr "Драйвер" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Версия" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Температура" #: main.c:156 msgid "Core Voltage" msgstr "Напряжение ядра" #: main.c:157 msgid "Power Avg" msgstr "Среднее напряжение" #: main.c:158 msgid "GPU clock" msgstr "Частота ГП" #: main.c:159 msgid "Memory clock" msgstr "Частота памяти" #: main.c:160 msgid "Memory Used" msgstr "Используемая память" #: main.c:162 #, fuzzy #| msgid "Card %i" msgid "Cards" msgstr "Карта %i" #: main.c:165 msgid "Bench" msgstr "Бенчмарк" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Простые числа (медленно)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Простые числа (быстро)" #: main.c:170 msgid "Score" msgstr "Счет" #: main.c:171 msgid "Run" msgstr "Запуск" #: main.c:174 msgid "Parameters" msgstr "Параметры" #: main.c:175 msgid "Duration" msgstr "Продолжительность" #: main.c:176 msgid "Threads" msgstr "Потоки" #: main.c:179 main.c:184 msgid "About" msgstr "О программе" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s это свободное программное обеспечение\n" "для сбора информации о процессоре, видеокарте и др." #: main.c:185 #, c-format msgid "Version %s" msgstr "Версия %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Автор: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Сайт: %s" #: main.c:189 msgid "License" msgstr "Лицензия" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Данное программное обеспечение распространяется на условиях %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Данное программное обеспечение предоставляется БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ" #: main.c:265 msgid "Dumping data…" msgstr "Получение дампа данных…" #: main.c:308 msgid "Freeing memory" msgstr "Освобождение памяти" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Запустить графический интерфейс (GUI) (по умолчанию)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Запустить текстовый интерфейс (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Собрать все данные стандартного вывода и выйти" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Запустить расширенную команду dmidecode и выйти" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Запустить расширенную команду bandwidth и выйти" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Установить время между обновлениями (в секундах)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Установить вкладку по умолчанию (целое число)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Установить ядро ЦП для мониторинга (целое число)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" "Установить тест пропускной способности для скорости кэша ЦП (целое число)" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "Установить вкладку по умолчанию (целое число)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Старт и подключение к демону" #: main.c:347 msgid "Verbose output" msgstr "Текстовый вывод" #: main.c:348 msgid "Print help and exit" msgstr "Показать помощь и выйти" #: main.c:349 msgid "Print version and exit" msgstr "Показать версию и выйти" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "Отключить цветной вывод" #: main.c:352 msgid "Print information for debugging" msgstr "Вывод информации для отладки" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Вывести требуемую информацию для вставки в отчет об ошибке" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Установить сопоставление клавиш для режима NCurses (a[rrows]|e[macs]|" "i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Добавить аргументы командной строки по умолчанию" #: main.c:366 msgid "Enforce the bus clock" msgstr "Принудительно установить тактовую частоту шины" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Игнорировать частоту ЦП, сообщаемую libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Прочитать сырые данные CPUID из заданного файла" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Распечатать сообщение, только если ЦП отсутствует в базе данных" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Использование: %s ДИСПЛЕЙ [ОПЦИИ]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Доступный ДИСПЛЕЙ:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Доступные ОПЦИИ:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Затрагиваемые переменные окружения:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" "Это свободное программное обеспечение. Вы можете изменять и распространять " "его." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Посмотреть лицензию %s: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s версия: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "не удалось вызвать wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sОй, что-то пошло не так! %s получил сигнал %d (%s) и прекратил работу.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Вы можете открыть новую тему и вставить в нее вывод ошибки:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "ошибка при установке локализации" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Запуск текстового интерфейса NCurses…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "FATAL ERROR: база данных terminfo не найдена (попробуйте установить " "переменную окружения TERMINFO)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Ошибка установки %s (err=%i); откат к %s" #: tui_ncurses.c:310 #, fuzzy #| msgid "Window is too small!\n" msgid "Window is too small!" msgstr "Окно слишком маленькое.\n" #: tui_ncurses.c:318 #, fuzzy #| msgid "Press 'h' to see help.\n" msgid "Press 'h' to see help." msgstr "Нажмите \"H\" для получения помощи.\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Добро пожаловать в %s помощь NCurses!\n" #: tui_ncurses.c:475 #, fuzzy #| msgid "This help describes how to use this Text-based User Interface.\n" msgid "This help describes how to use this Text-based User Interface." msgstr "Здесь описано, как использовать текстовый интерфейс.\n" #: tui_ncurses.c:477 #, fuzzy #| msgid "" #| "\n" #| "Global keys:\n" msgid "Global keys:" msgstr "" "\n" "Глобальные клавиши:\n" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "Нажмите клавишу \"влево\", чтобы перейти на вкладку слева.\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "Нажмите клавишу \"вправо\", чтобы перейти на вкладку справа.\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "Нажмите клавишу \"H\" для вызова помощи.\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "Нажмите \"Q\" для выхода.\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "Вкладка \"ЦП\":\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "Нажмите клавишу \"вниз\" для уменьшения номера ядра для мониторинга.\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "" "Нажмите клавишу \"вверх\" для увеличения номера ядра для мониторинга.\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "Вкладка \"Кэши\":\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "Нажмите клавишу \"вниз\" для перехода к предыдущему тесту.\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "Нажмите клавишу \"вверх\" для перехода к следующему тесту.\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "Вкладка \"Бенчмарк\":\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "Нажмите клавишу \"вниз\" для уменьшения длительности бенчмарка.\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "Нажмите клавишу \"вверх\" для увеличения длительности бенчмарка.\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "Нажмите клавишу \"предыдущая страница\" для уменьшения числа используемых " "потоков.\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "Нажмите клавишу \"следующая страница\" для увеличения числа используемых " "потоков.\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 's' key to start/stop prime numbers (slow) benchmark.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "Нажмите клавишу \"S\" для запуска/остановки бенчмарка \"простые числа " "(медленно)\".\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'f' key to start/stop prime numbers (fast) benchmark.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "Нажмите клавишу \"F\" для запуска/остановки бенчмарка \"простые числа " "(быстро)\".\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "Graphics" msgid "Graphics tab:" msgstr "Графическая подсистема" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "Нажмите клавишу \"вниз\" для перехода к предыдущему тесту.\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "Нажмите клавишу \"вверх\" для перехода к следующему тесту.\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "Нажмите любую клавишу для выхода из помощи.\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "не удается найти элемент в '%s' строке на позиции %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "Строка '%s' слишком длинная, обрезается…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "ошибка при открытии файла '%s' (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "ошибка при выполнении команды '%s' (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "не удалось открыть папку %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "ошибка при компиляции регулярных выражений" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: не удается получить авторизацию (диалог отключен)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: не удается получить авторизацию (нет авторизации)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: команда не найдена" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: непредвиденный код ошибки" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "FATAL ERROR: Не удалось распределить память" #: cpu-x.h:92 msgid "bytes" msgstr "байты" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "кб" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "мб" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "гб" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "тб" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "КиБ" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "МиБ" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "ГиБ" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "ТиБ" #~ msgid "Exiting %s" #~ msgstr "Выход из %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "Пропустить открытие моделезависимых регистров ЦП (требуются права " #~ "администратора)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "не удалось открыть моделезависимые регистры ЦП (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Пропустить вызов dmidecode (требуются права администратора)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "не удалось переназначить память для dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "не удалось вызвать dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Поиск драйвера видеокарты" #~ msgid "(%s driver)" #~ msgstr "(драйвер %s)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "не удалось найти драйвер видеокарты (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Получение температуры ГП" #~ msgid "Off" #~ msgstr "Выкл" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "не удалось получить температуру ГП" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Пропускать некоторые значения ГП (требуются права администратора)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "не удалось переназначить память для бенчмарка" #~ msgid "Root privileges are required to work properly" #~ msgstr "Для корректной работы требуются права администратора" #~ msgid "Some information will not be retrievable" #~ msgstr "Невозможно получить некоторые данные" #~ msgid "Ignore" #~ msgstr "Пропустить" #~ msgid "Run as root" #~ msgstr "Запустить с правами администратора" #~ msgid "A new version of %s is available!" #~ msgstr "Доступна новая версия %s!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Вы хотите обновить %s до версии %s после выхода?\n" #~ "Бинарный файл (%s) будет заменен новой версией." #~ msgid "Not now" #~ msgstr "Не сейчас" #~ msgid "Update" #~ msgstr "Обновить" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Проверка обновлений через интернет..." #~ msgid "failed to open a Curl session" #~ msgstr "не удалось открыть сессию Curl" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "не удалось выполнить перенос Curl (%s)" #~ msgid "wrong write data" #~ msgstr "неверные данные записи" #~ msgid "(version %s is available)" #~ msgstr "(доступна версия %s)" #~ msgid "No new version available" #~ msgstr "Обновлений нет" #~ msgid "(up-to-date)" #~ msgstr "(последняя версия)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "ошибка при извлечении архива %s (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Доступ к сети отключен переменной окружения (для его включения установите " #~ "положительное значение CPUX_NETWORK)" #~ msgid "failed to open %s archive for writing" #~ msgstr "не удалось открыть архив %s для записи" #~ msgid "Downloading new version..." #~ msgstr "Загрузка новой версии..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "не удалось загрузить архив %s (%s)" #~ msgid "Extracting new version..." #~ msgstr "Извлечение обновлений..." #~ msgid "Applying new version..." #~ msgstr "Применение обновлений..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "ошибка при удалении/переименовании файлов" #~ msgid "Update successful!" #~ msgstr "Обновление завершено!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Обновить переносную версию (при доступности обновлений)" #~ msgid "Temporarily disable network support" #~ msgstr "Временно отключить поддержку сети" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "Скомпилировано на %s, %s (с помощью %s %s на %s)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Извините, вы не можете обновить %s: 32-битная портативная версия больше " #~ "не поддерживается." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Нажмите клавишу \"U\" для обновления или любую другую для пропуска.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s будет обновлен." CPU-X-4.2.0/po/si.po000066400000000000000000000400051403012130000137210ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # HelaBasa , 2021. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-02-23 09:50+0000\n" "Last-Translator: HelaBasa \n" "Language-Team: Sinhala \n" "Language: si\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 4.5\n" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "උපාංග සොයමින්" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/sv.po000066400000000000000000000545211403012130000137460ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Åke Engelbrektson , 2021. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-27 20:52+0000\n" "Last-Translator: Åke Engelbrektson \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 4.6-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Söker CPU-teknologi" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Din CPU finns inte i databasen ==> %s, modell: %i, ext. model: %i, ext. " "family: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-way" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-way" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s associativa, %d-%s radstorlek" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Anropar libcpuid för hämtning av statisk data" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "kunde inte anropa libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Anropar libcpuid för hämtning av dynamisk data" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "Anropar libcpuid för hämtning av CPU MSR statisk data" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "Anropar libcpuid för hämtning av CPU MSR dynamisk data" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Beräknar CPU-multiplikatorer" #: core.c:521 msgid "Calling dmidecode" msgstr "Anropar dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Beräknar CPU-användning" #: core.c:605 msgid "Calling bandwidth" msgstr "Anropar bandbredd" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" "Ingen drivrutin för kärnan som används, för grafikkortet på sökvägen %s" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "Din GPU-kärndrivrutin är okänd: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "Din drivrutin för GPU-användarläge är okänd: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "kunde inte anropa GLFW (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Söker enheter" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Hoppa över enhetssök (fel behörigheter på %s)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Din GPU-leverantör är okänd: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "kunde inte hitta chipset-leverantör och modell" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "kunde inte hitta grafikkortsleverantör och modell" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Hämtar GPU-frekvenser" #: core.c:990 msgid "None" msgstr "Inga" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Drivrutinen för GPU %u rapporterar inte frekvenser" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "Aktuellt: PCIe Gen%1dx%d / Max: Gen%1dx%d" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "kunde inte hämta GPU-frekvenser" #: core.c:1205 msgid "Identifying running system" msgstr "Identifierar aktuellt system" #: core.c:1208 msgid "failed to identify running system" msgstr "kunde inte identifiera aktuellt system" #: core.c:1249 msgid "Calling libprocps" msgstr "Anropar libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Anropar libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i dagar, %i timmar, %i minuter, %i sekunder" #: core.c:1366 msgid "Updating benchmark status" msgstr "Uppdaterar prestandateststatus" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u min." #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Inaktiv" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Inte startad" #: core.c:1380 msgid "Active" msgstr "Aktiv" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u timmar kvar)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u minuter kvar)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u sekunder kvar)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "om %u timmar" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "om %u minuter" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "om %u sekunder" #: core.c:1414 msgid "Starting benchmark" msgstr "Startar prestandtest" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "ett fel inträffade under start av prestandatest" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Söker CPU-paket i nödfallsläge" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Din CPU-sockel finns inte databasen ==> %s, kodnamn: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Beräknar CPU-multiplikatorer i nödfallsläge" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Hämtar moderkortsinformation i nödfallsläge" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "kunde inte hämta moderkortsinformation (nödfallsläge)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Hämtar CPU-temperatur i nödfallsläge" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "kunde inte hämta CPU-temperatur (nödfallsläge)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Hämtar CPU-spänning i nödfallsläge" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "kunde inte hämta CPU-spänning (nödfallsläge)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Hämtar CPU-frekvens i nödfallsläge" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "kunde inte hämta CPU-frekvens (nödfallsläge)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: Fall %i hanterades inte" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "Startar GTK-gui…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "kunde inte importera UI i GtkBuilder" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Ansluten till tjänsten" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Ingen polkit-autentiseringsagent hittades" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Be om lösenord för att starta tjänsten i bakgrunden" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Starta tjänsten" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Kärna #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Anger etikettnamn" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "Processor" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Producent" #: main.c:61 msgid "Code Name" msgstr "Kodnamn" #: main.c:62 msgid "Package" msgstr "Paket" #: main.c:63 msgid "Technology" msgstr "Teknologi" #: main.c:64 msgid "Voltage" msgstr "Spänning" #: main.c:65 msgid "Specification" msgstr "Specifikation" #: main.c:66 msgid "Family" msgstr "Familj" #: main.c:67 msgid "Ext. Family" msgstr "Ext. familj" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Modell" #: main.c:69 msgid "Ext. Model" msgstr "Ext. modell" #: main.c:70 msgid "Temp." msgstr "Temp." #: main.c:71 msgid "Stepping" msgstr "Stepping" #: main.c:72 msgid "Instructions" msgstr "Instruktioner" #: main.c:74 msgid "Clocks" msgstr "Frekvenser" #: main.c:75 msgid "Core Speed" msgstr "Kärnhastighet" #: main.c:76 msgid "Multiplier" msgstr "Multiplikator" #: main.c:77 msgid "Bus Speed" msgstr "Busshastighet" #: main.c:78 main.c:155 msgid "Usage" msgstr "Användning" #: main.c:80 msgid "Cache" msgstr "Cache" #: main.c:81 msgid "L1 Data" msgstr "L1-Data" #: main.c:82 msgid "L1 Inst." msgstr "L1-Inst." #: main.c:83 msgid "Level 2" msgstr "Nivå 2" #: main.c:84 msgid "Level 3" msgstr "Nivå 3" #: main.c:86 msgid "Socket(s)" msgstr "Socklar" #: main.c:87 msgid "Core(s)" msgstr "Kärnor" #: main.c:88 msgid "Thread(s)" msgstr "Trådar" #: main.c:91 msgid "Caches" msgstr "Cache" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i Cache" #: main.c:96 msgid "Size" msgstr "Storlek" #: main.c:97 msgid "Speed" msgstr "Hastighet" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Moderkort" #: main.c:104 msgid "Manufacturer" msgstr "Tillverkare" #: main.c:106 msgid "Revision" msgstr "Revision" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Varumärke" #: main.c:110 msgid "Version" msgstr "Version" #: main.c:111 msgid "Date" msgstr "Datum" #: main.c:112 msgid "ROM Size" msgstr "ROM-storlek" #: main.c:114 msgid "Chipset" msgstr "Chipset" #: main.c:119 main.c:135 msgid "Memory" msgstr "Minne" #: main.c:122 #, c-format msgid "Bank %i" msgstr "Bank %i" #: main.c:123 msgid "Reference" msgstr "Referens" #: main.c:127 msgid "System" msgstr "System" #: main.c:128 msgid "Operating System" msgstr "Operativsystem" #: main.c:129 msgid "Kernel" msgstr "Kärna" #: main.c:130 msgid "Distribution" msgstr "Distribution" #: main.c:131 msgid "Hostname" msgstr "Värdnamn" #: main.c:132 msgid "Uptime" msgstr "Upptid" #: main.c:133 msgid "Compiler" msgstr "Kompilator" #: main.c:136 msgid "Used" msgstr "Använt" #: main.c:137 msgid "Buffers" msgstr "Buffertar" #: main.c:138 msgid "Cached" msgstr "Cache-lagrat" #: main.c:139 msgid "Free" msgstr "Ledigt" #: main.c:140 msgid "Swap" msgstr "Växlingsutrymme" #: main.c:143 msgid "Graphics" msgstr "Grafik" #: main.c:147 #, c-format msgid "Card %i" msgstr "Kort %i" #: main.c:149 msgid "Driver" msgstr "Drivrutin" #: main.c:150 msgid "UMD Version" msgstr "UMD-version" #: main.c:152 msgid "DeviceID" msgstr "Enhets-ID" #: main.c:153 msgid "Interface" msgstr "Gränssnitt" #: main.c:154 msgid "Temperature" msgstr "Temperatur" #: main.c:156 msgid "Core Voltage" msgstr "Kärnspänning" #: main.c:157 msgid "Power Avg" msgstr "Effekt Genomsnitt" #: main.c:158 msgid "GPU clock" msgstr "GPU-frekvens" #: main.c:159 msgid "Memory clock" msgstr "Minnesfrekvens" #: main.c:160 msgid "Memory Used" msgstr "Använt minne" #: main.c:162 msgid "Cards" msgstr "Kort" #: main.c:165 msgid "Bench" msgstr "Testbänk" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Primtal (långsam)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Primtal (snabb)" #: main.c:170 msgid "Score" msgstr "Poäng" #: main.c:171 msgid "Run" msgstr "Kör" #: main.c:174 msgid "Parameters" msgstr "Parametrar" #: main.c:175 msgid "Duration" msgstr "Varaktighet" #: main.c:176 msgid "Threads" msgstr "Trådar" #: main.c:179 main.c:184 msgid "About" msgstr "Om" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s är fri mjukvara som samlar in information\n" "om CPU, moderkort och mer." #: main.c:185 #, c-format msgid "Version %s" msgstr "Version %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Utvecklare: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Sajt: %s" #: main.c:189 msgid "License" msgstr "Licens" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Denna mjukvara distribueras under villkoren för %s" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Detta program levereras UTAN NÅGRA SOM HELST GARANTIER" #: main.c:265 msgid "Dumping data…" msgstr "Dumpar data…" #: main.c:308 msgid "Freeing memory" msgstr "Frigör minne" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Starta grafiskt användargränssnitt (GUI) (standard)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Starta textbaserat användargränssnitt (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Dumpa all data till standard utdata och avsluta" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Kör inbäddad kommando-dmidecode och avsluta" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Kör inbäddad kommandobandbredd och avsluta" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "Ange anpassad tid mellan två uppdateringar (i sekunder)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Ange standardflik (heltal)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "Välj CPU-kärna att övervaka (heltal)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "Ange anpassad bandbreddstest för CPU-cachehastighet (heltal)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "Välj standardgrafikkort (heltal)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Starta och anslut till tjänsten" #: main.c:347 msgid "Verbose output" msgstr "Utförlig utdata" #: main.c:348 msgid "Print help and exit" msgstr "Skriv ut hjälp och avsluta" #: main.c:349 msgid "Print version and exit" msgstr "Skriv ut version och avsluta" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "Skriv ut CPUID-värden decimalt (standard är hexadeximalt)" #: main.c:351 msgid "Disable colored output" msgstr "Inaktivera färgad utdata" #: main.c:352 msgid "Print information for debugging" msgstr "Skriv ut information för felsökning" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Skriv ut önskad information att klistra in i ett ärende" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "Ange tangentmappning för NCurses-läge (a[rrows]|e[macs]|i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Lägg till standardargument för kommandorad" #: main.c:366 msgid "Enforce the bus clock" msgstr "Framtvinga bussfrekvens" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "Ignorera CPU-frekvens rapporterad a libcpuid" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Läs CPUID-rådata från en given fil" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Skriv bara ut ett meddelande om CPU:n inte finns med i databasen" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Användning: %s DISPLAY [OPTIONS]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Tillgänglig SKÄRM:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Tillgängliga ALTERNATIV:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Påverkbara miljövariabler:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Detta är fri mjukvara: Du får ändra och återdistribuera den." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "Se %s-licensen: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s version: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "kunde inte anropa wordexp (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sHoppsan, något gick snett! %s har mottagit signal %d (%s) och har kraschat." "%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" "Du kan klistra in denna bakåtspårning genom att öppna ett nytt ärende här:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "ett fel uppstod vid inställning av språk" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "Startar NCurses TUI…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ALLVARLIGT FEL: terminfo-databasen kunde inte hittas (försök ange TERMINFO " "miljövariabel)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "Det gick inte att starta %s terminal (fel=%i); Faller tillbaka på %s" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "Fönstret är för litet!" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "Tryck \"h\" för att se hjälpen." #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "Välkommen till %s NCurses hjälp!\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" "Denna hjälp beskriver hur man använder detta textbaserade användargränssnitt." #: tui_ncurses.c:477 msgid "Global keys:" msgstr "Systemövergripande tangenter:" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "Tryck \"vänster\" för att växla till vänster flik." #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "Tryck \"höger\" för att växla till höger flik." #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "Tryck \"h\" för att se den här hjälpen." #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "Tryck \"q\" för att avsluta." #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "CPU-flik:" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "Tryck \"ner\" för att minska antalet kärnor att övervaka." #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "Tryck \"upp\" för att öka antalet kärnor att övervaka." #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "Cache-flik:" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "Tryck \"ner\" för att växla till föregående test." #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "Tryck \"upp\" för att växla till nästa test." #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "Testflik:" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "Tryck \"ner\" för att minska varaktigheten för prestandatestet." #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "Tryck \"upp\" för att öka varaktigheten för prestandatestet." #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "Tryck \"nästa sida\" för att minska antalet trådar som används." #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "Tryck \"föregående sida\" för att öka anatalet trådar som används." #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "Tryck \"s\" för att starta/stoppa primtalstest (långsam)." #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "Tryck \"f\" för att starta/stoppa primtalstest (snabbt)." #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "Grafikflik:" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "Tryck \"ner\" för att växla till föregående grafikkort." #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "Tryck \"upp\" för att växla till nästa grafikkort." #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "Tryck valfri tangent för avsluta denna hjälp." #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "kan inte hitta enhet i strängen \"%s\" på position %i" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "Strängen \"%s\" är för lång, trunkerar…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "ett fel inträffade vid öppning av filen \"%s\" (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "ett fel inträffade vid körning av kommandot \"%s\" (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "kunde inte öppna mappen %s" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "ett fel inträffade vid regex-kompilering" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: Auktorisering kunde inte erhållas (dialog avfärdas)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: Auktorisation kunde inte erhållas (ej auktoriserad)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: Kommandot hittades inte" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: Oväntad felkod" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ALLVARLIGT FEL: Kunde inte allokera minne" #: cpu-x.h:92 msgid "bytes" msgstr "byte" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" CPU-X-4.2.0/po/tr.po000066400000000000000000000676001403012130000137450ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Brsn , 2019. # Mesut Akcan , 2019. # illaki , 2019. # Ömer Çakmak , 2019. # Ferit Etem , 2019. # Ali A. , 2019. # mahmut özcan , 2019, 2020. # Burak , 2019. # Sabri Ünal , 2020. # Çalgan Aygün , 2020. # Adnan1091 , 2020. # Yaşar Çiv , 2020. # Anonymous , 2020. # Oğuz Ersen , 2020, 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-23 15:29+0000\n" "Last-Translator: Oğuz Ersen \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 4.5.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "İşlemci teknolojisi bulunuyor" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Veri tabanında CPU'nuz yok ==> %s, model: %i, genişletilmiş model: %i, " "genişletilmiş aile: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-yol" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-yol" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s ilişkilendirilebilir, %d-%s satır boyutu" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Statik veri almak için libcpuid çağrılıyor" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "libcpuid çağrılamadı (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Dinamik veri almak için libcpuid çağrılıyor" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "CPU MSR statik değerlerini almak için libcpuid çağrılıyor" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "CPU MSR dinamik değerlerini almak için libcpuid çağrılıyor" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "CPU çarpanları hesaplanıyor" #: core.c:521 msgid "Calling dmidecode" msgstr "dmidecode çağrılıyor" #: core.c:554 msgid "Calculating CPU usage" msgstr "CPU kullanımı hesaplanıyor" #: core.c:605 msgid "Calling bandwidth" msgstr "Bant genişliği çağırılıyor" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "%s yolundaki grafik kartı için kullanılan çekirdek sürücüsü yok" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "GPU çekirdek sürücünüz bilinmiyor: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "GPU kullanıcı modu sürücünüz bilinmiyor: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "GLFW çağrılamadı (%i): %s" #: core.c:817 msgid "Finding devices" msgstr "Aygıtlar bulunuyor" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "Aygıt aramayı atla (%s aygıtında yanlış izinler)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "GPU satıcınız bilinmiyor: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "yonga seti satıcısı ve model bulunamadı" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "ekran kartı marka ve modeli bulunamadı" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "GPU saatleri alınıyor" #: core.c:990 msgid "None" msgstr "Hiçbiri" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "%u GPU sürücüsü frekansları bildirmiyor" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "GPU saatleri alınamadı" #: core.c:1205 msgid "Identifying running system" msgstr "İşletim sistemi tanımlanıyor" #: core.c:1208 msgid "failed to identify running system" msgstr "işletim sistemi tanımlanamadı" #: core.c:1249 msgid "Calling libprocps" msgstr "libprocps çağrılıyor" #: core.c:1275 msgid "Calling libstatgrab" msgstr "libstatgrab çağrılıyor" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i gün, %i saat, %i dakika, %i saniye" #: core.c:1366 msgid "Updating benchmark status" msgstr "Karşılaştırma durumu güncelleniyor" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u dakika" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Etkin değil" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Başlatılmadı" #: core.c:1380 msgid "Active" msgstr "Etkin" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u saat kaldı)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u dakika kaldı)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u saniye kaldı)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "%u saat içinde" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "%u dakika içinde" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "%u saniye içinde" #: core.c:1414 msgid "Starting benchmark" msgstr "Karşılaştırma başlatılıyor" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "karşılaştırma başlatılırken hata oluştu" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "Yedek modda CPU paketi bulunuyor" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "Veri tabanında CPU soketiniz yok ==> %s, kod adı: %s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "Yedek modda CPU çarpanları hesaplanıyor" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "Yedek modda anakart bilgisi alınıyor" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "anakart bilgisi alınamadı (yedek modu)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "Yedek modda CPU sıcaklığı alınıyor" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "CPU sıcaklığı alınamadı (yedek mod)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "Yedek modda CPU gerilimi alınıyor" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "CPU gerilimi alınamadı (yedek mod)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "Yedek modda CPU frekansı alınıyor" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "CPU frekansı alınamadı (yedek mod)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: %i durumu işlemedi" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "GTK GUI başlatılıyor…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "GtkBuilder'da kullanıcı arayüzü içe aktarılamadı" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "Arka plan programına bağlandı" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "Hiçbir polkit kimlik doğrulama aracısı bulunamadı" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "Arka plan programı başlatmak için parola sor" #: gui_gtk.c:556 msgid "Start daemon" msgstr "Arka plan programını başlat" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Çekirdek #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "Etiket adları ayarlanıyor" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "İşlemci" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "Satıcı" #: main.c:61 msgid "Code Name" msgstr "Kod Adı" #: main.c:62 msgid "Package" msgstr "Paket" #: main.c:63 msgid "Technology" msgstr "Teknoloji" #: main.c:64 msgid "Voltage" msgstr "Gerilim" #: main.c:65 msgid "Specification" msgstr "Tanımlama" #: main.c:66 msgid "Family" msgstr "Aile" #: main.c:67 msgid "Ext. Family" msgstr "Genişletilmiş Aile" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Model" #: main.c:69 msgid "Ext. Model" msgstr "Genişletilmiş Model" #: main.c:70 msgid "Temp." msgstr "Sıcaklık" #: main.c:71 msgid "Stepping" msgstr "Basamak Seviyesi" #: main.c:72 msgid "Instructions" msgstr "Talimatlar" #: main.c:74 msgid "Clocks" msgstr "Saatler" #: main.c:75 msgid "Core Speed" msgstr "Çekirdek Hızı" #: main.c:76 msgid "Multiplier" msgstr "Katsayı" #: main.c:77 msgid "Bus Speed" msgstr "Veri Yolu Hızı" #: main.c:78 main.c:155 msgid "Usage" msgstr "Kullanım" #: main.c:80 msgid "Cache" msgstr "Önbellek" #: main.c:81 msgid "L1 Data" msgstr "L1 Verileri" #: main.c:82 msgid "L1 Inst." msgstr "L1 Talimat." #: main.c:83 msgid "Level 2" msgstr "Seviye 2" #: main.c:84 msgid "Level 3" msgstr "Seviye 3" #: main.c:86 msgid "Socket(s)" msgstr "Soket(ler)" #: main.c:87 msgid "Core(s)" msgstr "Çekirdek(ler)" #: main.c:88 msgid "Thread(s)" msgstr "İş Parçacık(lar)ı" #: main.c:91 msgid "Caches" msgstr "Önbellek" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i Önbelleği" #: main.c:96 msgid "Size" msgstr "Boyut" #: main.c:97 msgid "Speed" msgstr "Hız" #: main.c:99 msgid "Test" msgstr "Test" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Anakart" #: main.c:104 msgid "Manufacturer" msgstr "Üretici" #: main.c:106 msgid "Revision" msgstr "Düzeltme" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "Marka" #: main.c:110 msgid "Version" msgstr "Sürüm" #: main.c:111 msgid "Date" msgstr "Tarih" #: main.c:112 msgid "ROM Size" msgstr "ROM Boyutu" #: main.c:114 msgid "Chipset" msgstr "Yonga seti" #: main.c:119 main.c:135 msgid "Memory" msgstr "Bellek" #: main.c:122 #, c-format msgid "Bank %i" msgstr "%i Bankası" #: main.c:123 msgid "Reference" msgstr "Kaynak" #: main.c:127 msgid "System" msgstr "Sistem" #: main.c:128 msgid "Operating System" msgstr "İşletim Sistemi" #: main.c:129 msgid "Kernel" msgstr "Çekirdek" #: main.c:130 msgid "Distribution" msgstr "Dağıtım" #: main.c:131 msgid "Hostname" msgstr "Ana Makine Adı" #: main.c:132 msgid "Uptime" msgstr "Çalışma Zamanı" #: main.c:133 msgid "Compiler" msgstr "Derleyici" #: main.c:136 msgid "Used" msgstr "Kullanılmış" #: main.c:137 msgid "Buffers" msgstr "Arabellek" #: main.c:138 msgid "Cached" msgstr "Önbelleğe alınmış" #: main.c:139 msgid "Free" msgstr "Boş" #: main.c:140 msgid "Swap" msgstr "Takas" #: main.c:143 msgid "Graphics" msgstr "Grafikler" #: main.c:147 #, c-format msgid "Card %i" msgstr "Kart %i" #: main.c:149 msgid "Driver" msgstr "Sürücü" #: main.c:150 msgid "UMD Version" msgstr "UMD Sürümü" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "Sıcaklık" #: main.c:156 msgid "Core Voltage" msgstr "Çekirdek Gerilimi" #: main.c:157 msgid "Power Avg" msgstr "Güç Ortalaması" #: main.c:158 msgid "GPU clock" msgstr "GPU saati" #: main.c:159 msgid "Memory clock" msgstr "Bellek saati" #: main.c:160 msgid "Memory Used" msgstr "Kullanılan Bellek" #: main.c:162 msgid "Cards" msgstr "Kartlar" #: main.c:165 msgid "Bench" msgstr "Karşılaştırma" #: main.c:166 msgid "Prime numbers (slow)" msgstr "Asal sayılar (yavaş)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "Asal sayılar (hızlı)" #: main.c:170 msgid "Score" msgstr "Puan" #: main.c:171 msgid "Run" msgstr "Çalıştır" #: main.c:174 msgid "Parameters" msgstr "Parametreler" #: main.c:175 msgid "Duration" msgstr "Süre" #: main.c:176 msgid "Threads" msgstr "İş Parçacıkları" #: main.c:179 main.c:184 msgid "About" msgstr "Hakkında" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s CPU, anakart ve daha fazlası hakkında bilgi\n" "toplayan özgür bir yazılımdır." #: main.c:185 #, c-format msgid "Version %s" msgstr "Sürüm %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "Yazar: %s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Site: %s" #: main.c:189 msgid "License" msgstr "Lisans" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "Bu yazılım %s koşulları altında dağıtılmıştır" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "Bu programın KESİNLİKLE HİÇBİR GARANTİSİ yoktur" #: main.c:265 msgid "Dumping data…" msgstr "Veriler dökülüyor…" #: main.c:308 msgid "Freeing memory" msgstr "Bellek boşaltılıyor" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "Grafiksel kullanıcı arayüzünü (GUI) başlat (öntanımlı)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "Metin tabanlı kullanıcı arayüzünü (TUI) başlat" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "Tüm verileri standart çıktıya dök ve çık" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "Gömülü dmidecode komutunu çalıştır ve çık" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "Gömülü bandwidth komutunu çalıştır ve çık" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "İki yenileme arasında özel süre ayarla (saniye cinsinden)" #: main.c:342 msgid "Set default tab (integer)" msgstr "Öntanımlı sekmeyi ayarla (tam sayı)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "İzlenecek işlemci çekirdeğini seç (tam sayı)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "İşlemci önbellek hızı için özel bant genişliği ayarla (tam sayı)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "Öntanımlı grafik kartını seç (tam sayı)" #: main.c:346 msgid "Start and connect to daemon" msgstr "Arka plan programını başlat ve bağlan" #: main.c:347 msgid "Verbose output" msgstr "Ayrıntılı çıktı" #: main.c:348 msgid "Print help and exit" msgstr "Yardımı yazdır ve çık" #: main.c:349 msgid "Print version and exit" msgstr "Sürümü yazdır ve çık" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" "CPUID değerlerini ondalık olarak yazdır (öntanımlı olarak onaltılıktır)" #: main.c:351 msgid "Disable colored output" msgstr "Renkli çıktıyı devre dışı bırak" #: main.c:352 msgid "Print information for debugging" msgstr "Hata ayıklama bilgilerini yazdır" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "Bir soruna yapıştırmak için gerekli bilgileri yazdır" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" "NCurses modu için tuş atamasını ayarla (a[rrows]|e[macs]|i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "Öntanımlı komut satırı argümanlarını ekle" #: main.c:366 msgid "Enforce the bus clock" msgstr "Veri yolu saatini zorla" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "libcpuid tarafından bildirilen CPU frekansını yok say" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "Belirtilen bir dosyadan CPUID ham verilerini oku" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "Yalnızca veri tabanında CPU yoksa bir mesaj yazdır" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "Kullanım: %s EKRAN [SEÇENEKLER]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "Kullanılabilir EKRAN:" #: main.c:403 msgid "Available OPTIONS:" msgstr "Kullanılabilir SEÇENEKLER:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "Etkilenebilir ortam değişkenleri:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "Bu bir özgür yazılımdır: değiştirmek ve yeniden dağıtmakta özgürsünüz." #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "%s lisansına bakın: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s sürümü: %s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "wordexp çağrılamadı (%i)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%sHay aksi, birşeyler yanlış gitti! %s, %d (%s) sinyali aldı ve çöktü.%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "Bu geri izlemeyi buraya yeni bir konu açarak yapıştırabilirsiniz:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "yerel ayar yapılırken bir hata oluştu" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "NCurses metin tabanlı arayüzü başlatılıyor…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" "ÖNEMLİ HATA: terminfo veri tabanı bulunamadı (TERMINFO ortam değişkenini " "ayarlamayı deneyin)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "%s terminali ayarlanamadı (err=%i); yedek olarak %s kullanılıyor" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "Pencere çok küçük!" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "Yardımı görmek için 'h' tuşuna basın." #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "%s NCurses yardımına hoş geldiniz!\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" "Bu yardım, metin tabanlı kullanıcı arayüzünün nasıl kullanılacağını açıklar." #: tui_ncurses.c:477 msgid "Global keys:" msgstr "Genel tuşlar:" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "Sol sekmeye geçmek için 'sol' tuşuna basın." #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "Sağ sekmeye geçmek için 'sağ' tuşuna basın." #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "Bu yardımı görmek için 'h' tuşuna basın." #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "Çıkmak için 'q' tuşuna basın." #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "CPU sekmesi:" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "İzlenecek çekirdek sayısını azaltmak için 'aşağı' tuşuna basın." #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "İzlenecek çekirdek sayısını artırmak için 'yukarı' tuşuna basın." #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "Önbellek sekmesi:" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "Önceki teste geçmek için 'aşağı' tuşuna basın." #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "Sonraki teste geçmek için 'yukarı' tuşuna basın." #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "Karşılaştırma sekmesi:" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "Karşılaştırma süresini azaltmak için 'aşağı' tuşuna basın." #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "Karşılaştırma süresini artırmak için 'yukarı' tuşuna basın." #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" "Kullanılacak iş parçacığı sayısını azaltmak için 'sonraki sayfa' tuşuna " "basın." #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" "Kullanılacak iş parçacığı sayısını artırmak için 'önceki sayfa' tuşuna basın." #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" "Asal sayıları (yavaş) karşılaştırmayı başlatmak/durdurmak için 's' tuşuna " "basın." #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" "Asal sayıları (hızlı) karşılaştırmayı başlatmak/durdurmak için 'f' tuşuna " "basın." #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "Grafikler sekmesi:" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "Önceki grafik kartına geçmek için 'aşağı' tuşuna basın." #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "Sonraki grafik kartına geçmek için 'yukarı' tuşuna basın." #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "Yardımdan çıkmak için herhangi bir tuşa basın." #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "'%s' dizgesinde %i konumundaki birim bulunamıyor" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "'%s' dizgesi çok uzun, kesiliyor…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "'%s' dosyası açılırken bir hata oluştu (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "'%s' komutu çalıştırılırken bir hata oluştu (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "%s dizini açılamadı" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "düzenli ifade derlenirken bir hata oluştu" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec: yetkilendirme alınamadı (iletişim kutusu kapatıldı)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec: yetkilendirme alınamadı (yetkilendirilmedi)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec: komut bulunamadı" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec: beklenmedik hata kodu" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "ÖNEMLİ HATA: bellek ayrılamadı" #: cpu-x.h:92 msgid "bytes" msgstr "bayt" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "%s çıkışı yapılıyor" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "CPU MSR açılışını atla (rootlu olması gerek)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "CPU MSR açılamadı (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "dmidecall çağrılmasını es geç (root olmalı)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "dmidecode için hafıza tahsis edilemedi" #~ msgid "failed to call dmidecode" #~ msgstr "dmidecode çağırılamadı" #~ msgid "Finding graphic card driver" #~ msgstr "Grafik kartı sürücüsü aranıyor" #~ msgid "(%s driver)" #~ msgstr "(%s sürücüsü)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "grafik kartı sürücüsü bulunamadı (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "GPU sıcaklığı alınıyor" #~ msgid "Off" #~ msgstr "Kapalı" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "GPU sıcaklığı alınamadı" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Bazı GPU değerlerini atla (Root izni gerek)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "Karşılaştırma için bellek ayrılamadı" #~ msgid "Root privileges are required to work properly" #~ msgstr "Düzgün çalışması için Root (kök) yetki gerekiyor" #~ msgid "Some information will not be retrievable" #~ msgstr "Bazı bilgiler geri alınamayacak" #~ msgid "Ignore" #~ msgstr "Yok say" #~ msgid "Run as root" #~ msgstr "Root (kök) olarak çalıştır" #~ msgid "A new version of %s is available!" #~ msgstr "%s için yeni bir sürüm mevcut!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "Çıktıktan sonra %s sürümünü, %s sürümüne yükseltmek ister misiniz?\n" #~ "Bu işlem ikili dosyayı (%s) yenisiyle değiştirecektir." #~ msgid "Not now" #~ msgstr "Şu anda değil" #~ msgid "Update" #~ msgstr "Güncelle" #~ msgid "Checking on Internet for a new version..." #~ msgstr "Yeni sürüm internetten denetleniyor..." #~ msgid "failed to open a Curl session" #~ msgstr "Curl oturumu açılamadı" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "Curl aktarımı gerçekleştirilemedi (%s)" #~ msgid "wrong write data" #~ msgstr "hatalı yazma verisi" #~ msgid "(version %s is available)" #~ msgstr "(sürüm %s mevcut)" #~ msgid "No new version available" #~ msgstr "Yeni bir sürüm yok" #~ msgid "(up-to-date)" #~ msgstr "(güncel)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "%s arşivi dışarı çıkarılırken bir hatayla karşılaşıldı (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "" #~ "Ağ erişimi ortam değişkeni tarafından devre dışı bırakıldı " #~ "(aktifleştirmek için CPUX_NETWORK değişkenine pozitif bir değer atayın)" #~ msgid "failed to open %s archive for writing" #~ msgstr "%s arşivi yazmak için açılamadı" #~ msgid "Downloading new version..." #~ msgstr "Yeni sürüm indiriliyor..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "%s arşivi indirilemedi (%s)" #~ msgid "Extracting new version..." #~ msgstr "Yeni sürüm çıkarılıyor..." #~ msgid "Applying new version..." #~ msgstr "Yeni sürüm uygulanıyor..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "dosyalar kaldırılırken/yeniden adlandırılırken bir hata oluştu" #~ msgid "Update successful!" #~ msgstr "Güncelleme başarılı!" #~ msgid "Update portable version if a new version is available" #~ msgstr "Yeni bir sürüm varsa taşınabilir sürümü güncelle" #~ msgid "Temporarily disable network support" #~ msgstr "Ağ desteğini geçici olarak devre dışı bırak" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "%s üzerinde oluşturuldu, %s (%s ile %s %s üzerinde)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "" #~ "Maalesef, %s güncelleyemezsiniz: 32 bit taşınabilir sürüm artık " #~ "desteklenmiyor." #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "" #~ "Güncellemek isterseniz, 'u' tuşuna veya atlamak için başka bir şeye " #~ "basın.\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s güncellenecek." CPU-X-4.2.0/po/tzm.po000066400000000000000000000407111403012130000141240ustar00rootroot00000000000000# CPU-X translations template # Copyright © 2014-2021 Xorg # This file is distributed under the same license as the cpu-x package. # Hakim Oubouali , 2020. msgid "" msgstr "" "Project-Id-Version: cpu-x\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-10-19 21:26+0000\n" "Last-Translator: Hakim Oubouali \n" "Language-Team: Central Atlas Tamazight \n" "Language: tzm\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 >= 2 && (n < 11 || n > 99);\n" "X-Generator: Weblate 4.3.1-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d%s, %d-aɣaras" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d%s, %d-aɣaras" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s amsmun, %d-%s s wadur" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "Asiḍen n asemres n CPU" #: core.c:605 msgid "Calling bandwidth" msgstr "Aɣuri n bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "" #: core.c:817 msgid "Finding devices" msgstr "" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "" #: core.c:990 msgid "None" msgstr "Walu" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u sdin" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "" #: core.c:1380 msgid "Active" msgstr "" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "g %u tsragin" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "Ul #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "Tatikenulujit" #: main.c:64 msgid "Voltage" msgstr "Asevolt" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "Tawacunt" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "Azurt" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "Asemres" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "Ul(awn)" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "Tiɣzi" #: main.c:97 msgid "Speed" msgstr "Tazzla" #: main.c:99 msgid "Test" msgstr "Turimt" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "Taflut taymmat" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "Azzeray" #: main.c:108 msgid "BIOS" msgstr "ABIYUS" #: main.c:109 msgid "Brand" msgstr "Tamatart" #: main.c:110 msgid "Version" msgstr "Taleqqimt" #: main.c:111 msgid "Date" msgstr "Asakud" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "Tiktit" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "Tasaɣult" #: main.c:127 msgid "System" msgstr "Anegraw" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "Tuẓemt" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "Baṭel" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "Taleqqimt" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "Asevolt" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "Tiktit" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "Γef" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "Taleqqimt %s" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "Asit: %s" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" CPU-X-4.2.0/po/uk.po000066400000000000000000000513721403012130000137360ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Tymofij Lytvynenko , 2019, 2020. # Oleksii Melnychenko , 2020. # Allan Nordhøy , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-07-11 09:41+0000\n" "Last-Translator: Allan Nordhøy \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 4.2-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "Пошук технології процесора" #: core.c:237 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "" "Ваш процесор відсутній у базі даних ==> %s, модель: %i, дод. модель: %i, " "дод. сімейство: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-канальний" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-канальний" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s асоціативний, %d-%s розмір кеш-смуги" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "Виклик libcpuid для отримання статичних даних" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "не вдалося викликати libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "Виклик libcpuid для отримання динамічних даних" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "" "Виклик libcpuid для отримання статичних значень моделезалежних реєстрів " "процесора" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "" "Виклик libcpuid для отримання динамічних значень моделезалежних реєстрів " "процесора" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "Розрахунок множників процесора" #: core.c:521 msgid "Calling dmidecode" msgstr "Виклик dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "Розрахунок завантаження процесора" #: core.c:605 msgid "Calling bandwidth" msgstr "Виклик пропускної спроможності" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "Невідомий драйвер GPU: %s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "Невідомий драйвер GPU: %s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "не вдалося викликати libcpuid (%s)" #: core.c:817 msgid "Finding devices" msgstr "Пошук пристроїв" #: core.c:829 #, fuzzy, c-format #| msgid "Skip devices search (need to be root)" msgid "Skip devices search (wrong permissions on %s device)" msgstr "Пропустити пошук пристроїв (потрібно мати root)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "Постачальник графічного процесора невідомий: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "не вдалося знайти постачальника чи модель чіпсету" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "не вдалося знайти постачальника та модель графічної карти" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "Отримання частоти GPU" #: core.c:990 msgid "None" msgstr "" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "Драйвер для GPU %u не звітує частоти" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "не вдалося отримати частоту GPU" #: core.c:1205 msgid "Identifying running system" msgstr "Виявлення запущеної системи" #: core.c:1208 msgid "failed to identify running system" msgstr "не вдалося визначити запущену систему" #: core.c:1249 msgid "Calling libprocps" msgstr "Виклик libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "Виклик libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i днів, %i годин, %i хвилин, %i секунд" #: core.c:1366 msgid "Updating benchmark status" msgstr "Оновлення стану тестів" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u хв." #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "Неактивний" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "Не запущено" #: core.c:1380 msgid "Active" msgstr "Активний" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(%u годин лишилось)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(%u хвилин лишилось)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(%u секунд лишилося)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "за %u годин" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "за %u хвилин" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "за %u секунд" #: core.c:1414 msgid "Starting benchmark" msgstr "Запустити тестування" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, fuzzy, c-format #| msgid "" #| "Your CPU does not belong in database ==> %s, model: %i, ext. model: %i, " #| "ext. family: %i" msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "" "Ваш процесор відсутній у базі даних ==> %s, модель: %i, дод. модель: %i, " "дод. сімейство: %i" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "" #: main.c:59 msgid "Processor" msgstr "" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "" #: main.c:61 msgid "Code Name" msgstr "" #: main.c:62 msgid "Package" msgstr "" #: main.c:63 msgid "Technology" msgstr "" #: main.c:64 msgid "Voltage" msgstr "" #: main.c:65 msgid "Specification" msgstr "" #: main.c:66 msgid "Family" msgstr "" #: main.c:67 msgid "Ext. Family" msgstr "" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "" #: main.c:69 msgid "Ext. Model" msgstr "" #: main.c:70 msgid "Temp." msgstr "" #: main.c:71 msgid "Stepping" msgstr "" #: main.c:72 msgid "Instructions" msgstr "" #: main.c:74 msgid "Clocks" msgstr "" #: main.c:75 msgid "Core Speed" msgstr "" #: main.c:76 msgid "Multiplier" msgstr "" #: main.c:77 msgid "Bus Speed" msgstr "" #: main.c:78 main.c:155 msgid "Usage" msgstr "" #: main.c:80 msgid "Cache" msgstr "" #: main.c:81 msgid "L1 Data" msgstr "" #: main.c:82 msgid "L1 Inst." msgstr "" #: main.c:83 msgid "Level 2" msgstr "" #: main.c:84 msgid "Level 3" msgstr "" #: main.c:86 msgid "Socket(s)" msgstr "" #: main.c:87 msgid "Core(s)" msgstr "" #: main.c:88 msgid "Thread(s)" msgstr "" #: main.c:91 msgid "Caches" msgstr "" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "" #: main.c:104 msgid "Manufacturer" msgstr "" #: main.c:106 msgid "Revision" msgstr "" #: main.c:108 msgid "BIOS" msgstr "" #: main.c:109 msgid "Brand" msgstr "" #: main.c:110 msgid "Version" msgstr "" #: main.c:111 msgid "Date" msgstr "" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "" #: main.c:119 main.c:135 msgid "Memory" msgstr "" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "" #: main.c:129 msgid "Kernel" msgstr "" #: main.c:130 msgid "Distribution" msgstr "" #: main.c:131 msgid "Hostname" msgstr "" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "" #: main.c:150 msgid "UMD Version" msgstr "" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "" #: main.c:156 msgid "Core Voltage" msgstr "" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "" #: main.c:159 msgid "Memory clock" msgstr "" #: main.c:160 msgid "Memory Used" msgstr "" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "" #: main.c:171 msgid "Run" msgstr "" #: main.c:174 msgid "Parameters" msgstr "" #: main.c:175 msgid "Duration" msgstr "" #: main.c:176 msgid "Threads" msgstr "" #: main.c:179 main.c:184 msgid "About" msgstr "" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" #: main.c:185 #, c-format msgid "Version %s" msgstr "" #: main.c:186 #, c-format msgid "Author: %s" msgstr "" #: main.c:187 #, c-format msgid "Site: %s" msgstr "" #: main.c:189 msgid "License" msgstr "" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "failed to find graphic card driver (%s)" msgid "Select default graphic card (integer)" msgstr "не вдалося знайти драйвер графічної карти (%s)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "не вдалося викликати libcpuid (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 #, fuzzy #| msgid "could not reallocate memory" msgid "FATAL ERROR: could not allocate memory" msgstr "Не вдалося перерозподілити пам'ять" #: cpu-x.h:92 msgid "bytes" msgstr "" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "" #~ msgid "Exiting %s" #~ msgstr "Вихід з %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "" #~ "Пропустити відкриття моделезалежного реєстру процесора (потрібно мати " #~ "root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "не вдалося відкрити моделезалежні реєстри процесора (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "Пропустити виклик до dmidecode (потрібно мати root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "не вдалося виділити пам'ять для dmidecode" #~ msgid "failed to call dmidecode" #~ msgstr "не вдалося викликати dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "Пошук драйвера графічної карти" #~ msgid "(%s driver)" #~ msgstr "(драйвер %s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "Отримання температури GPU" #~ msgid "Off" #~ msgstr "Вимк." #~ msgid "failed to retrieve GPU temperature" #~ msgstr "не вдалося отримати температуру GPU" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "Пропустіть деякі значення GPU (потрібно мати root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "не вдалося виділити пам'ять для тестів" CPU-X-4.2.0/po/zh.po000066400000000000000000000631121403012130000137330ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Translators: # 高垚鑫, 2017-2018 # Huang Zhiyi , 2019. # chakhee <931489141@qq.com>, 2019. # Azurak , 2019. # wdggg , 2020. # Forbidden <10278743+f0rb1d@users.noreply.github.com>, 2020. # Eric , 2021. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2021-03-28 13:27+0000\n" "Last-Translator: Eric \n" "Language-Team: Chinese (Simplified) \n" "Language: zh\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 4.6-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "正在查找 CPU 工艺" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "数据库中没有您的 CPU ==> %s,型号: %i,扩展型号: %i,扩展系列: %i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d-路" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d-路" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s 关联, %d-%s 最小缓存单元大小" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "正在调用 libcpuid 以检索静态数据" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "无法调用 libcpuid (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "正在调用 libcpuid 以检索动态数据" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "正在调用 libcpuid 以检索 CPU MSR 静态值" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "正在调用 libcpuid 以检索 CPU MSR 动态值" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "正在计算 CPU 倍频" #: core.c:521 msgid "Calling dmidecode" msgstr "正在调用 dmidecode" #: core.c:554 msgid "Calculating CPU usage" msgstr "正在计算 CPU 使用率" #: core.c:605 msgid "Calling bandwidth" msgstr "正在调用 bandwidth" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "路径%s中没有驱动图形卡的内核驱动程序" #: core.c:717 #, c-format msgid "Your GPU kernel driver is unknown: %s" msgstr "你的 GPU 内核驱动未知: %s" #: core.c:790 #, c-format msgid "Your GPU user mode driver is unknown: %s" msgstr "你的 GPU 用户模式驱动未知: %s" #: core.c:794 #, c-format msgid "failed to call GLFW (%i): %s" msgstr "调用 GLFW (%i) 失败: %s" #: core.c:817 msgid "Finding devices" msgstr "正在搜索设备" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "跳过设备搜索 (%s设备上的权限错误)" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "您的 GPU 供应商未知: %s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "未找到芯片组供应商和型号" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "未找到显卡供应商和型号" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "正在检索 GPU 时钟" #: core.c:990 msgid "None" msgstr "无" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "GPU 驱动 %u 无法报告频率" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "当前: PCIe Gen%1dx%d / 最高: Gen%1dx%d" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "无法检索 GPU 时钟" #: core.c:1205 msgid "Identifying running system" msgstr "正在识别本系统" #: core.c:1208 msgid "failed to identify running system" msgstr "未识别本系统" #: core.c:1249 msgid "Calling libprocps" msgstr "正在调用 libprocps" #: core.c:1275 msgid "Calling libstatgrab" msgstr "正在调用 libstatgrab" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "%i 天,%i 小时,%i 分钟,%i 秒" #: core.c:1366 msgid "Updating benchmark status" msgstr "正在更新基准测试状态" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u 分钟" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "待用" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "未启动" #: core.c:1380 msgid "Active" msgstr "启用" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(剩余 %u 小时)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(剩余 %u 分钟)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "(剩余 %u 秒)" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "%u 小时后" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "%u 分钟后" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "%u 秒后" #: core.c:1414 msgid "Starting benchmark" msgstr "正在启动基准测试" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "启动基准测试时出错" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "正在故障预置模式下查找 CPU 封装" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "数据库中没有您的 CPU 插槽 ==> %s,架构:%s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "正在应急模式下计算 CPU 倍频" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "正在应急模式下检索主板信息" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "无法检索主板信息 (应急模式)" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "正在应急模式下检索 CPU 温度" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "未能检索 CPU 温度 (应急模式)" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "正在应急模式下检索 CPU 电压" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "未能检索 CPU 电压 (应急模式)" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "正在应急模式下检索 CPU 频率" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "未能检索 CPU 频率 (应急模式)" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "request_handler: 事件 %i 未处理" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "正在启动 GTK 图形用户界面…" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "无法在 GtkBuilder 中导入用户界面" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "连接到守护程序" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "找不到polkit身份验证代理" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "询问密码以在后台启动守护进程" #: gui_gtk.c:556 msgid "Start daemon" msgstr "启动守护进程" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "核心 #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "正在设置标签名称" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "处理器" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "制造商" #: main.c:61 msgid "Code Name" msgstr "架构" #: main.c:62 msgid "Package" msgstr "接口" #: main.c:63 msgid "Technology" msgstr "工艺" #: main.c:64 msgid "Voltage" msgstr "电压" #: main.c:65 msgid "Specification" msgstr "规格" #: main.c:66 msgid "Family" msgstr "系列" #: main.c:67 msgid "Ext. Family" msgstr "扩展系列" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "型号" #: main.c:69 msgid "Ext. Model" msgstr "扩展型号" #: main.c:70 msgid "Temp." msgstr "温度." #: main.c:71 msgid "Stepping" msgstr "步进" #: main.c:72 msgid "Instructions" msgstr "指令集" #: main.c:74 msgid "Clocks" msgstr "时钟" #: main.c:75 msgid "Core Speed" msgstr "核心速度" #: main.c:76 msgid "Multiplier" msgstr "倍频" #: main.c:77 msgid "Bus Speed" msgstr "总线速度" #: main.c:78 main.c:155 msgid "Usage" msgstr "使用率" #: main.c:80 msgid "Cache" msgstr "缓存" #: main.c:81 msgid "L1 Data" msgstr "一级数据缓存" #: main.c:82 msgid "L1 Inst." msgstr "一级指令缓存." #: main.c:83 msgid "Level 2" msgstr "二级缓存" #: main.c:84 msgid "Level 3" msgstr "三级缓存" #: main.c:86 msgid "Socket(s)" msgstr "插槽" #: main.c:87 msgid "Core(s)" msgstr "核心" #: main.c:88 msgid "Thread(s)" msgstr "线程" #: main.c:91 msgid "Caches" msgstr "缓存" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "%i级缓存" #: main.c:96 msgid "Size" msgstr "大小" #: main.c:97 msgid "Speed" msgstr "速度" #: main.c:99 msgid "Test" msgstr "测试" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "主板" #: main.c:104 msgid "Manufacturer" msgstr "制造商" #: main.c:106 msgid "Revision" msgstr "版本修订" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "品牌" #: main.c:110 msgid "Version" msgstr "版本" #: main.c:111 msgid "Date" msgstr "日期" #: main.c:112 msgid "ROM Size" msgstr "ROM 大小" #: main.c:114 msgid "Chipset" msgstr "芯片组" #: main.c:119 main.c:135 msgid "Memory" msgstr "内存" #: main.c:122 #, c-format msgid "Bank %i" msgstr "插槽 %i" #: main.c:123 msgid "Reference" msgstr "引用" #: main.c:127 msgid "System" msgstr "系统" #: main.c:128 msgid "Operating System" msgstr "操作系统" #: main.c:129 msgid "Kernel" msgstr "内核" #: main.c:130 msgid "Distribution" msgstr "发行版" #: main.c:131 msgid "Hostname" msgstr "主机名" #: main.c:132 msgid "Uptime" msgstr "运行时间" #: main.c:133 msgid "Compiler" msgstr "编译器" #: main.c:136 msgid "Used" msgstr "已用" #: main.c:137 msgid "Buffers" msgstr "缓冲" #: main.c:138 msgid "Cached" msgstr "缓存" #: main.c:139 msgid "Free" msgstr "可用" #: main.c:140 msgid "Swap" msgstr "交换" #: main.c:143 msgid "Graphics" msgstr "显卡" #: main.c:147 #, c-format msgid "Card %i" msgstr "卡 %i" #: main.c:149 msgid "Driver" msgstr "驱动" #: main.c:150 msgid "UMD Version" msgstr "UMD 版本" #: main.c:152 msgid "DeviceID" msgstr "设备ID" #: main.c:153 msgid "Interface" msgstr "界面" #: main.c:154 msgid "Temperature" msgstr "温度" #: main.c:156 msgid "Core Voltage" msgstr "核心电压" #: main.c:157 msgid "Power Avg" msgstr "平均功率" #: main.c:158 msgid "GPU clock" msgstr "GPU 时钟" #: main.c:159 msgid "Memory clock" msgstr "内存时钟" #: main.c:160 msgid "Memory Used" msgstr "所用内存" #: main.c:162 msgid "Cards" msgstr "卡" #: main.c:165 msgid "Bench" msgstr "基准测试" #: main.c:166 msgid "Prime numbers (slow)" msgstr "素数 (慢速)" #: main.c:167 msgid "Prime numbers (fast)" msgstr "素数 (快速)" #: main.c:170 msgid "Score" msgstr "分数" #: main.c:171 msgid "Run" msgstr "运行" #: main.c:174 msgid "Parameters" msgstr "参数" #: main.c:175 msgid "Duration" msgstr "持续时间" #: main.c:176 msgid "Threads" msgstr "线程" #: main.c:179 main.c:184 msgid "About" msgstr "关于" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s 是一个自由软件,收集有关\n" " CPU 和主板等的信息。" #: main.c:185 #, c-format msgid "Version %s" msgstr "%s 版" #: main.c:186 #, c-format msgid "Author: %s" msgstr "作者:%s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "网站:%s" #: main.c:189 msgid "License" msgstr "许可证" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "本软件依照 %s 条款分发" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "本软件不作任何保修" #: main.c:265 msgid "Dumping data…" msgstr "正在转储数据…" #: main.c:308 msgid "Freeing memory" msgstr "正在释放内存" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "启动图形用户界面 (GUI) (默认)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "启动文本用户界面 (TUI)" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "将所有数据转储到标准输出并退出" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "运行嵌入式命令 dmidecode 并退出" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "运行嵌入的命令 bandwidth 并退出" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "设置两次刷新之间的自定义时间 (以秒为单位)" #: main.c:342 msgid "Set default tab (integer)" msgstr "设置默认选项卡 (整型)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "选择要监视的 CPU 核心 (整型)" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "为 CPU 缓存速度设置自定义 bandwidth 测试 (整型)" #: main.c:345 msgid "Select default graphic card (integer)" msgstr "选择默认显卡 (整型)" #: main.c:346 msgid "Start and connect to daemon" msgstr "启动并连接到守护进程" #: main.c:347 msgid "Verbose output" msgstr "详细输出" #: main.c:348 msgid "Print help and exit" msgstr "打印帮助并退出" #: main.c:349 msgid "Print version and exit" msgstr "打印版本并退出" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "以十进制打印 CPUID 值(默认是十六进制)" #: main.c:351 msgid "Disable colored output" msgstr "禁用彩色输出" #: main.c:352 msgid "Print information for debugging" msgstr "打印信息用于调试" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "输出粘贴在问题反馈中的所需信息" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "设置 NCurses 模式的键位映射 (a[rrows]|e[macs]|i[nverted-T]|v[im])" #: main.c:365 msgid "Add default command line arguments" msgstr "添加默认的命令行参数" #: main.c:366 msgid "Enforce the bus clock" msgstr "强制执行总线计时器" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "忽略 libcpuid 报告的 CPU 频率" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "从指定文件中读取 CPUID 源数据" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "仅在 CPU 不存在于数据库时打印消息" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "用法: %s 显示 [选项]\n" #: main.c:394 msgid "Available DISPLAY:" msgstr "可用显示:" #: main.c:403 msgid "Available OPTIONS:" msgstr "可用选项:" #: main.c:411 msgid "Influenceable environment variables:" msgstr "可影响的环境变量:" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "这是一个自由软件:您可以自由更改和重新分发。" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "查看 %s 许可协议: <%s>\n" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "-- %-9s 版本:%s" #: main.c:467 #, c-format msgid "failed to call wordexp (%i)" msgstr "调用 wordexp (%i) 失败" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" "\n" "%s遇到了错误! %s 获得信号 %d (%s) 并崩溃。%s" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "您可以在这里打开一个新的问题来粘贴该回馈:" #: main.c:705 msgid "an error occurred while setting locale" msgstr "本地化设置时出错" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "正在启动 NCurses TU…" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "严重错误:找不到terminfo数据库(请尝试将TERMINFO设置为环境变量)" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "无法设置%s终端(err = %i);退回至%s" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "窗口太小了!" #: tui_ncurses.c:318 msgid "Press 'h' to see help." msgstr "按 'h' 键查看帮助。" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "欢迎来到 %s NCurses 帮助!\n" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "此帮助介绍如何使用该基于文本的用户界面。" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "全局按键:" #: tui_ncurses.c:478 msgid "Press 'left' key to switch in left tab." msgstr "按“left”键切换到左侧选项卡。" #: tui_ncurses.c:479 msgid "Press 'right' key to switch in right tab." msgstr "按“右”键切换到右选项卡。" #: tui_ncurses.c:480 msgid "Press 'h' key to see this help." msgstr "按 'h' 键查看此帮助。" #: tui_ncurses.c:481 msgid "Press 'q' key to exit." msgstr "按 'q' 键退出。" #: tui_ncurses.c:483 msgid "CPU tab:" msgstr "CPU 选项卡:" #: tui_ncurses.c:484 msgid "Press 'down' key to decrease core number to monitor." msgstr "按 'down' 键减小要监视的核心数值。" #: tui_ncurses.c:485 msgid "Press 'up' key to increase core number to monitor." msgstr "按 'up' 键增加要监视的核心数值。" #: tui_ncurses.c:487 msgid "Caches tab:" msgstr "缓存选项卡:" #: tui_ncurses.c:488 msgid "Press 'down' key to switch to previous test." msgstr "按 'down' 键切换至上一项测试。" #: tui_ncurses.c:489 msgid "Press 'up' key' to switch to next test." msgstr "按 'up' 键切换至下一项测试。" #: tui_ncurses.c:491 msgid "Bench tab:" msgstr "基准测试选项卡:" #: tui_ncurses.c:492 msgid "Press 'down' key to decrement benchmark duration." msgstr "按 'down' 键减少基准测试持续时间。" #: tui_ncurses.c:493 msgid "Press 'up' key to increment benchmark duration." msgstr "按 'up' 键增加基准测试持续时间。" #: tui_ncurses.c:494 msgid "Press 'next page' key to decrement number of threads to use." msgstr "按 'next page' 键减少要使用的线程数。" #: tui_ncurses.c:495 msgid "Press 'previous page' key to increment number of threads to use." msgstr "按 'previous page' 键增加要使用的线程数。" #: tui_ncurses.c:496 msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "按 's' 键开始/停止素数 (慢速) 基准测试。" #: tui_ncurses.c:497 msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "按 'f' 键开始/停止素数 (快速) 基准测试。" #: tui_ncurses.c:499 msgid "Graphics tab:" msgstr "显卡选项卡:" #: tui_ncurses.c:500 msgid "Press 'down' key to switch to previous graphic card." msgstr "按 'down' 键切换至上一张显卡。" #: tui_ncurses.c:501 msgid "Press 'up' key to switch to next graphic card." msgstr "按 'up' 键切换至下一张显卡。" #: tui_ncurses.c:503 msgid "Press any key to exit this help." msgstr "按任意键退出帮助。" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "在字符串 '%s' 的位置%i找不到单元" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "字符串 '%s' 太长,截断中…" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "打开文件 '%s' 时发生错误 (%s)" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "运行命令 '%s' 时发生错误 (%s)" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "无法打开 %s 目录" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "编译正则表达式时出错" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "pkexec:无法获得授权(对话框被关闭)" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "pkexec:无法获得授权(未被授权)" #: util.c:580 msgid "pkexec: command not found" msgstr "pkexec:找不到命令" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "pkexec:意外的错误代码" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "严重错误:无法分配内存" #: cpu-x.h:92 msgid "bytes" msgstr "字节" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "KiB" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 msgid "MiB" msgstr "MiB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 msgid "GiB" msgstr "GiB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 msgid "TiB" msgstr "TiB" #~ msgid "Exiting %s" #~ msgstr "正在退出 %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "跳过启用 CPU MSR (需要 root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "无法启用 CPU MSR (%s)" #~ msgid "Skip call to dmidecode (need to be root)" #~ msgstr "跳过调用 dmidecode (需要 root)" #~ msgid "failed to allocate memory for dmidecode" #~ msgstr "无法为 dmidecode 分配内存" #~ msgid "failed to call dmidecode" #~ msgstr "无法调用 dmidecode" #~ msgid "Finding graphic card driver" #~ msgstr "正在查找显卡驱动程序" #~ msgid "(%s driver)" #~ msgstr "(%s 驱动)" #~ msgid "failed to find graphic card driver (%s)" #~ msgstr "未找到显卡驱动程序 (%s)" #~ msgid "Retrieving GPU temperature" #~ msgstr "正在检索 GPU 温度" #~ msgid "Off" #~ msgstr "关" #~ msgid "failed to retrieve GPU temperature" #~ msgstr "无法检索 GPU 温度" #~ msgid "Skip some GPU values (need to be root)" #~ msgstr "跳过某些 GPU 值 (需要 root)" #~ msgid "failed to allocate memory for benchmark" #~ msgstr "无法为基准测试分配内存" #~ msgid "Root privileges are required to work properly" #~ msgstr "需要 root 权限以正常工作" #~ msgid "Some information will not be retrievable" #~ msgstr "某些信息无法检索" #~ msgid "Ignore" #~ msgstr "忽略" #~ msgid "Run as root" #~ msgstr "以 root 权限运行" #~ msgid "A new version of %s is available!" #~ msgstr "新版本 %s 可用!" #~ msgid "" #~ "Do you want to update %s to version %s after exit?\n" #~ "It will erase this binary file (%s) by the new version." #~ msgstr "" #~ "您想在退出后将版本 %s 更新至版本 %s 吗?\n" #~ "将会用新版本替换该二进制文件 (%s) 。" #~ msgid "Not now" #~ msgstr "现在不要" #~ msgid "Update" #~ msgstr "更新" #~ msgid "Checking on Internet for a new version..." #~ msgstr "正在联网检查新版本..." #~ msgid "failed to open a Curl session" #~ msgstr "无法启用 Curl 模块" #~ msgid "failed to perform the Curl transfer (%s)" #~ msgstr "无法执行 Curl 传输 (%s)" #~ msgid "wrong write data" #~ msgstr "写入数据出错" #~ msgid "(version %s is available)" #~ msgstr "(%s 版目前可用)" #~ msgid "No new version available" #~ msgstr "没有新版本可用" #~ msgid "(up-to-date)" #~ msgstr "(最新)" #~ msgid "an error occurred while extracting %s archive (%s)" #~ msgstr "提取 %s 存档时出错 (%s)" #~ msgid "" #~ "Network access is disabled by environment variable (set CPUX_NETWORK with " #~ "a positive value to enable it)" #~ msgstr "网络访问被环境变量禁用 (将 CPUX_NETWORK 设置为正值以启用)" #~ msgid "failed to open %s archive for writing" #~ msgstr "无法写入 %s 存档" #~ msgid "Downloading new version..." #~ msgstr "正在下载新版本..." #~ msgid "failed to download %s archive (%s)" #~ msgstr "无法下载 %s 存档 (%s)" #~ msgid "Extracting new version..." #~ msgstr "正在提取新版本..." #~ msgid "Applying new version..." #~ msgstr "正在应用新版本..." #~ msgid "an error occurred while removing/renaming files" #~ msgstr "移动/重命名文件时出错" #~ msgid "Update successful!" #~ msgstr "更新成功!" #~ msgid "Update portable version if a new version is available" #~ msgstr "新版本可用时,更新便携式版本" #~ msgid "Temporarily disable network support" #~ msgstr "暂时禁用网络支持" #~ msgid "Built on %s, %s (with %s %s on %s)." #~ msgstr "基于 %s,%s (使用 %s %s 在 %s 上)." #~ msgid "" #~ "Sorry, you cannot update %s: 32-bit portable version is no more supported." #~ msgstr "很抱歉,无法更新 %s :不再支持32位可移植版本。" #~ msgid "If you want to update, press 'u' key, or anything else to skip.\n" #~ msgstr "如果您想要更新,请按 'u' 键,否则请按其他按键跳过更新。\n" #~ msgid "" #~ "\n" #~ "\n" #~ "%s will be updated." #~ msgstr "" #~ "\n" #~ "\n" #~ "%s 将会被更新。" CPU-X-4.2.0/po/zh_Hant.po000066400000000000000000000515051403012130000147100ustar00rootroot00000000000000# Copyright © 2014-2021 Xorg # This file is distributed under the same license as the CPU-X package. # Louies , 2019. # byStarTW , 2019. # Jeff Huang , 2019. # mingjieWu , 2020. # Hung, Chi-Heng , 2020. # crlambda , 2020. msgid "" msgstr "" "Project-Id-Version: CPU-X\n" "Report-Msgid-Bugs-To: https://github.com/X0rg/CPU-X/issues\n" "POT-Creation-Date: 2021-03-28 13:26+0000\n" "PO-Revision-Date: 2020-12-26 08:29+0000\n" "Last-Translator: crlambda \n" "Language-Team: Chinese (Traditional) \n" "Language: zh_Hant\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 4.4.1-dev\n" #: core.c:218 msgid "Finding CPU technology" msgstr "正在尋找 CPU 技術" #: core.c:237 #, c-format msgid "" "Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, " "ext. family: %i" msgstr "您的 CPU 不在資料庫中 ==>> %s,型號:%i,延伸型號:%i,擴充系列:%i" #: core.c:249 #, c-format msgid "%d x %d %s, %d-way" msgstr "%d x %d %s, %d 路" #: core.c:250 #, c-format msgid "%d %s, %d-way" msgstr "%d %s, %d 路" #: core.c:251 #, c-format msgid "%s associative, %d-%s line size" msgstr "%s 組合,%d-%s 行大小" #: core.c:256 msgid "Calling libcpuid for retrieving static data" msgstr "正在呼叫 libcpuid 以取得靜態資料" #: core.c:268 #, c-format msgid "failed to call libcpuid (%s)" msgstr "呼叫 libcpuid 失敗 (%s)" #: core.c:427 msgid "Calling libcpuid for retrieving dynamic data" msgstr "正在呼叫 libcpuid 以取得動態資料" #: core.c:440 msgid "Calling libcpuid for retrieving CPU MSR static values" msgstr "正在呼叫 libcpuid 以取得 CPU MSR 靜態值" #: core.c:465 msgid "Calling libcpuid for retrieving CPU MSR dynamic values" msgstr "正在呼叫 libcpuid 以取得 CPU MSR 動態值" #: core.c:488 msgid "Calculating CPU multipliers" msgstr "正在計算 CPU 倍頻" #: core.c:521 msgid "Calling dmidecode" msgstr "" #: core.c:554 msgid "Calculating CPU usage" msgstr "正在計算 CPU 使用率" #: core.c:605 msgid "Calling bandwidth" msgstr "" #: core.c:686 #, c-format msgid "No kernel driver in use for graphic card at path %s" msgstr "" #: core.c:717 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU kernel driver is unknown: %s" msgstr "無法得知您的 GPU 驅動程式:%s" #: core.c:790 #, fuzzy, c-format #| msgid "Your GPU driver is unknown: %s" msgid "Your GPU user mode driver is unknown: %s" msgstr "無法得知您的 GPU 驅動程式:%s" #: core.c:794 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call GLFW (%i): %s" msgstr "呼叫 libcpuid 失敗 (%s)" #: core.c:817 msgid "Finding devices" msgstr "正在尋找裝置" #: core.c:829 #, c-format msgid "Skip devices search (wrong permissions on %s device)" msgstr "" #: core.c:858 #, c-format msgid "Your GPU vendor is unknown: %s (0x%X)" msgstr "無法得知您的 GPU 供應商:%s (0x%X)" #: core.c:877 msgid "failed to find chipset vendor and model" msgstr "找不到晶片組供應商及型號" #: core.c:879 msgid "failed to find graphic card vendor and model" msgstr "找不到顯示卡供應商及型號" #: core.c:956 msgid "Retrieving GPU clocks" msgstr "正在取得 GPU 時脈" #: core.c:990 msgid "None" msgstr "無" #: core.c:1123 #, c-format msgid "Driver for GPU %u doesn't report frequencies" msgstr "" #: core.c:1166 #, c-format msgid "Current: PCIe Gen%1dx%d / Max: Gen%1dx%d" msgstr "" #: core.c:1188 msgid "failed to retrieve GPU clocks" msgstr "" #: core.c:1205 msgid "Identifying running system" msgstr "" #: core.c:1208 msgid "failed to identify running system" msgstr "" #: core.c:1249 msgid "Calling libprocps" msgstr "" #: core.c:1275 msgid "Calling libstatgrab" msgstr "" #: core.c:1310 #, c-format msgid "%i days, %i hours, %i minutes, %i seconds" msgstr "" #: core.c:1366 msgid "Updating benchmark status" msgstr "更新benchmark狀態" #: core.c:1367 tui_ncurses.c:824 #, c-format msgid "%u mins" msgstr "%u 分鐘" #: core.c:1369 core.c:1370 msgid "Inactive" msgstr "未啟動" #: core.c:1374 core.c:1375 msgid "Not started" msgstr "未開始" #: core.c:1380 msgid "Active" msgstr "活動中" #: core.c:1385 #, c-format msgid "(%u hours left)" msgstr "(剩下 %u 小時)" #: core.c:1387 #, c-format msgid "(%u minutes left)" msgstr "(剩下 %u 分鐘)" #: core.c:1389 #, c-format msgid "(%u seconds left)" msgstr "" #: core.c:1394 #, c-format msgid "in %u hours" msgstr "" #: core.c:1396 #, c-format msgid "in %u minutes" msgstr "" #: core.c:1398 #, c-format msgid "in %u seconds" msgstr "" #: core.c:1414 msgid "Starting benchmark" msgstr "正在開始效能測試" #: core.c:1433 msgid "an error occurred while starting benchmark" msgstr "" #: core.c:1450 msgid "Finding CPU package in fallback mode" msgstr "" #: core.c:1472 #, c-format msgid "Your CPU socket is not present in the database ==> %s, codename: %s" msgstr "您的 CPU 不在資料庫中 ==>> %s,型號:%i,延伸型號:%i,擴充系列:%s" #: core.c:1491 msgid "Calculating CPU multipliers in fallback mode" msgstr "" #: core.c:1518 msgid "Retrieving motherboard information in fallback mode" msgstr "" #: core.c:1527 msgid "failed to retrieve motherboard information (fallback mode)" msgstr "" #: core.c:1566 msgid "Retrieving CPU temperature in fallback mode" msgstr "" #: core.c:1611 msgid "failed to retrieve CPU temperature (fallback mode)" msgstr "" #: core.c:1624 msgid "Retrieving CPU voltage in fallback mode" msgstr "" #: core.c:1637 msgid "failed to retrieve CPU voltage (fallback mode)" msgstr "" #: core.c:1652 msgid "Retrieving CPU frequency in fallback mode" msgstr "" #: core.c:1660 msgid "failed to retrieve CPU frequency (fallback mode)" msgstr "" #: daemon.c:254 #, c-format msgid "request_handler: case %i not handled" msgstr "" #: gui_gtk.c:62 msgid "Starting GTK GUI…" msgstr "" #: gui_gtk.c:70 msgid "failed to import UI in GtkBuilder" msgstr "" #: gui_gtk.c:544 msgid "Connected to daemon" msgstr "" #: gui_gtk.c:546 msgid "No polkit authentication agent found" msgstr "" #: gui_gtk.c:550 msgid "Ask password to start daemon in background" msgstr "" #: gui_gtk.c:556 msgid "Start daemon" msgstr "" #: gui_gtk.c:565 gui_gtk.c:650 tui_ncurses.c:550 #, c-format msgid "Core #%i" msgstr "核心 #%i" #: gui_gtk.c:647 #, c-format msgid "%s" msgstr "%s" #: main.c:56 msgid "Setting label names" msgstr "" #: main.c:58 msgid "CPU" msgstr "CPU" #: main.c:59 msgid "Processor" msgstr "處理器" #: main.c:60 main.c:115 main.c:148 msgid "Vendor" msgstr "供應商" #: main.c:61 msgid "Code Name" msgstr "代號" #: main.c:62 msgid "Package" msgstr "封裝" #: main.c:63 msgid "Technology" msgstr "製程" #: main.c:64 msgid "Voltage" msgstr "電壓" #: main.c:65 msgid "Specification" msgstr "規格" #: main.c:66 msgid "Family" msgstr "系列" #: main.c:67 msgid "Ext. Family" msgstr "延伸系列" #: main.c:68 main.c:105 main.c:116 main.c:151 msgid "Model" msgstr "型號" #: main.c:69 msgid "Ext. Model" msgstr "延伸型號" #: main.c:70 msgid "Temp." msgstr "溫度" #: main.c:71 msgid "Stepping" msgstr "步進" #: main.c:72 msgid "Instructions" msgstr "指令集" #: main.c:74 msgid "Clocks" msgstr "時脈" #: main.c:75 msgid "Core Speed" msgstr "核心速度" #: main.c:76 msgid "Multiplier" msgstr "倍頻" #: main.c:77 msgid "Bus Speed" msgstr "匯流排速度" #: main.c:78 main.c:155 msgid "Usage" msgstr "用量" #: main.c:80 msgid "Cache" msgstr "快取" #: main.c:81 msgid "L1 Data" msgstr "L1 資料" #: main.c:82 msgid "L1 Inst." msgstr "L1 指令" #: main.c:83 msgid "Level 2" msgstr "L2 快取" #: main.c:84 msgid "Level 3" msgstr "L3 快取" #: main.c:86 msgid "Socket(s)" msgstr "插槽" #: main.c:87 msgid "Core(s)" msgstr "核心" #: main.c:88 msgid "Thread(s)" msgstr "線程" #: main.c:91 msgid "Caches" msgstr "快取" #: main.c:95 #, c-format msgid "L%i Cache" msgstr "L%i 快取" #: main.c:96 msgid "Size" msgstr "" #: main.c:97 msgid "Speed" msgstr "速度" #: main.c:99 msgid "Test" msgstr "" #: main.c:102 main.c:103 msgid "Motherboard" msgstr "主機板" #: main.c:104 msgid "Manufacturer" msgstr "製造商" #: main.c:106 msgid "Revision" msgstr "修訂" #: main.c:108 msgid "BIOS" msgstr "BIOS" #: main.c:109 msgid "Brand" msgstr "廠牌" #: main.c:110 msgid "Version" msgstr "版本" #: main.c:111 msgid "Date" msgstr "日期" #: main.c:112 msgid "ROM Size" msgstr "" #: main.c:114 msgid "Chipset" msgstr "晶片組" #: main.c:119 main.c:135 msgid "Memory" msgstr "記憶體" #: main.c:122 #, c-format msgid "Bank %i" msgstr "" #: main.c:123 msgid "Reference" msgstr "" #: main.c:127 msgid "System" msgstr "" #: main.c:128 msgid "Operating System" msgstr "作業系統" #: main.c:129 msgid "Kernel" msgstr "核心" #: main.c:130 msgid "Distribution" msgstr "發行版" #: main.c:131 msgid "Hostname" msgstr "主機名稱" #: main.c:132 msgid "Uptime" msgstr "" #: main.c:133 msgid "Compiler" msgstr "編譯器" #: main.c:136 msgid "Used" msgstr "" #: main.c:137 msgid "Buffers" msgstr "" #: main.c:138 msgid "Cached" msgstr "" #: main.c:139 msgid "Free" msgstr "" #: main.c:140 msgid "Swap" msgstr "" #: main.c:143 msgid "Graphics" msgstr "" #: main.c:147 #, c-format msgid "Card %i" msgstr "" #: main.c:149 msgid "Driver" msgstr "驅動程式" #: main.c:150 #, fuzzy #| msgid "Version" msgid "UMD Version" msgstr "版本" #: main.c:152 msgid "DeviceID" msgstr "" #: main.c:153 msgid "Interface" msgstr "" #: main.c:154 msgid "Temperature" msgstr "溫度" #: main.c:156 #, fuzzy #| msgid "Voltage" msgid "Core Voltage" msgstr "電壓" #: main.c:157 msgid "Power Avg" msgstr "" #: main.c:158 msgid "GPU clock" msgstr "GPU 時脈" #: main.c:159 msgid "Memory clock" msgstr "記憶體時脈" #: main.c:160 #, fuzzy #| msgid "Memory" msgid "Memory Used" msgstr "記憶體" #: main.c:162 msgid "Cards" msgstr "" #: main.c:165 msgid "Bench" msgstr "效能測試" #: main.c:166 msgid "Prime numbers (slow)" msgstr "" #: main.c:167 msgid "Prime numbers (fast)" msgstr "" #: main.c:170 msgid "Score" msgstr "分數" #: main.c:171 msgid "Run" msgstr "執行" #: main.c:174 msgid "Parameters" msgstr "參數" #: main.c:175 msgid "Duration" msgstr "持續時間" #: main.c:176 msgid "Threads" msgstr "線程" #: main.c:179 main.c:184 msgid "About" msgstr "關於" #: main.c:181 #, c-format msgid "" "%s is a Free software that gathers information\n" "on CPU, motherboard and more." msgstr "" "%s 是一款蒐集CPU、主機板等資訊\n" "的自由軟體。" #: main.c:185 #, c-format msgid "Version %s" msgstr "%s 版" #: main.c:186 #, c-format msgid "Author: %s" msgstr "作者:%s" #: main.c:187 #, c-format msgid "Site: %s" msgstr "網站:%s" #: main.c:189 msgid "License" msgstr "授權條款" #: main.c:192 #, c-format msgid "This software is distributed under the terms of %s" msgstr "" #: main.c:194 main.c:443 msgid "This program comes with ABSOLUTELY NO WARRANTY" msgstr "" #: main.c:265 msgid "Dumping data…" msgstr "" #: main.c:308 msgid "Freeing memory" msgstr "" #: main.c:336 msgid "Start graphical user interface (GUI) (default)" msgstr "開啓圖形使用者界面(預設)" #: main.c:337 msgid "Start text-based user interface (TUI)" msgstr "開啓文字使用者介面" #: main.c:338 msgid "Dump all data on standard output and exit" msgstr "" #: main.c:339 msgid "Run embedded command dmidecode and exit" msgstr "" #: main.c:340 msgid "Run embedded command bandwidth and exit" msgstr "" #: main.c:341 msgid "Set custom time between two refreshes (in seconds)" msgstr "" #: main.c:342 msgid "Set default tab (integer)" msgstr "設定預設分頁(整數)" #: main.c:343 msgid "Select CPU core to monitor (integer)" msgstr "" #: main.c:344 msgid "Set custom bandwidth test for CPU caches speed (integer)" msgstr "" #: main.c:345 #, fuzzy #| msgid "Set default tab (integer)" msgid "Select default graphic card (integer)" msgstr "設定預設分頁(整數)" #: main.c:346 msgid "Start and connect to daemon" msgstr "" #: main.c:347 msgid "Verbose output" msgstr "" #: main.c:348 msgid "Print help and exit" msgstr "" #: main.c:349 msgid "Print version and exit" msgstr "" #: main.c:350 msgid "Print CPUID values in decimal (default is hexadeximal)" msgstr "" #: main.c:351 msgid "Disable colored output" msgstr "" #: main.c:352 msgid "Print information for debugging" msgstr "" #: main.c:353 msgid "Print required information to paste in an issue" msgstr "" #: main.c:354 msgid "Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])" msgstr "" #: main.c:365 msgid "Add default command line arguments" msgstr "" #: main.c:366 msgid "Enforce the bus clock" msgstr "" #: main.c:367 msgid "Ignore CPU frequency reported by libcpuid" msgstr "" #: main.c:368 msgid "Read CPUID raw data from a given file" msgstr "" #: main.c:369 msgid "Only print a message if CPU is not present in the database" msgstr "" #: main.c:393 #, c-format msgid "Usage: %s DISPLAY [OPTIONS]\n" msgstr "" #: main.c:394 msgid "Available DISPLAY:" msgstr "" #: main.c:403 msgid "Available OPTIONS:" msgstr "" #: main.c:411 msgid "Influenceable environment variables:" msgstr "" #: main.c:442 msgid "This is free software: you are free to change and redistribute it." msgstr "" #: main.c:444 #, c-format msgid "See the %s license: <%s>\n" msgstr "" #: main.c:451 #, c-format msgid "-- %-9s version: %s" msgstr "" #: main.c:467 #, fuzzy, c-format #| msgid "failed to call libcpuid (%s)" msgid "failed to call wordexp (%i)" msgstr "呼叫 libcpuid 失敗 (%s)" #: main.c:662 #, c-format msgid "" "\n" "%sOops, something was wrong! %s has received signal %d (%s) and has crashed." "%s" msgstr "" #: main.c:677 msgid "You can paste this backtrace by opening a new issue here:" msgstr "" #: main.c:705 msgid "an error occurred while setting locale" msgstr "" #: tui_ncurses.c:72 msgid "Starting NCurses TUI…" msgstr "" #: tui_ncurses.c:80 msgid "" "FATAL ERROR: terminfo database could not be found (try to set TERMINFO " "environment variable)" msgstr "" #: tui_ncurses.c:85 #, c-format msgid "Failed to set up %s terminal (err=%i); falling back to %s" msgstr "" #: tui_ncurses.c:310 msgid "Window is too small!" msgstr "" #: tui_ncurses.c:318 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' to see help." msgstr "\t按「h」鍵查看此幫助。\n" #: tui_ncurses.c:474 #, c-format msgid "Welcome in %s NCurses help!\n" msgstr "" #: tui_ncurses.c:475 msgid "This help describes how to use this Text-based User Interface." msgstr "" #: tui_ncurses.c:477 msgid "Global keys:" msgstr "" #: tui_ncurses.c:478 #, fuzzy #| msgid "\tPress 'left' key to switch in left tab.\n" msgid "Press 'left' key to switch in left tab." msgstr "\t按「左」鍵切換至左邊的分頁。\n" #: tui_ncurses.c:479 #, fuzzy #| msgid "\tPress 'right' key to switch in right tab.\n" msgid "Press 'right' key to switch in right tab." msgstr "\t按「右」鍵切換至右邊的分頁。\n" #: tui_ncurses.c:480 #, fuzzy #| msgid "\tPress 'h' key to see this help.\n" msgid "Press 'h' key to see this help." msgstr "\t按「h」鍵查看此幫助。\n" #: tui_ncurses.c:481 #, fuzzy #| msgid "\tPress 'q' key to exit.\n" msgid "Press 'q' key to exit." msgstr "\t按「q」鍵退出。\n" #: tui_ncurses.c:483 #, fuzzy #| msgid "" #| "\n" #| "CPU tab:\n" msgid "CPU tab:" msgstr "" "\n" "CPU分頁:\n" #: tui_ncurses.c:484 #, fuzzy #| msgid "\tPress 'down' key to decrease core number to monitor.\n" msgid "Press 'down' key to decrease core number to monitor." msgstr "\t按「下」鍵減少要監視的核心數。\n" #: tui_ncurses.c:485 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'up' key to increase core number to monitor." msgstr "\t按「上」鍵增加要監視的核心數。\n" #: tui_ncurses.c:487 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Caches tab:" msgstr "" "\n" "快取分頁:\n" #: tui_ncurses.c:488 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous test." msgstr "\t按「下」鍵切換至上一項測試。\n" #: tui_ncurses.c:489 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key' to switch to next test." msgstr "\t按「上」鍵切換至下一項測試。\n" #: tui_ncurses.c:491 #, fuzzy #| msgid "" #| "\n" #| "Bench tab:\n" msgid "Bench tab:" msgstr "" "\n" "效能測試分頁:\n" #: tui_ncurses.c:492 #, fuzzy #| msgid "\tPress 'down' key to decrement benchmark duration.\n" msgid "Press 'down' key to decrement benchmark duration." msgstr "\t按「下」鍵減少效能測試持續的時間。\n" #: tui_ncurses.c:493 #, fuzzy #| msgid "\tPress 'up' key to increment benchmark duration.\n" msgid "Press 'up' key to increment benchmark duration." msgstr "\t按「上」鍵增加效能測試持續的時間。\n" #: tui_ncurses.c:494 #, fuzzy #| msgid "\tPress 'next page' key to decrement number of threads to use.\n" msgid "Press 'next page' key to decrement number of threads to use." msgstr "\t按「下一頁」鍵減少要使用的線程數。\n" #: tui_ncurses.c:495 #, fuzzy #| msgid "\tPress 'previous page' key to increment number of threads to use.\n" msgid "Press 'previous page' key to increment number of threads to use." msgstr "\t按「上一頁」鍵增加要使用的線程數。\n" #: tui_ncurses.c:496 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 's' key to start/stop prime numbers (slow) benchmark." msgstr "\t按「上」鍵增加要監視的核心數。\n" #: tui_ncurses.c:497 #, fuzzy #| msgid "\tPress 'up' key to increase core number to monitor.\n" msgid "Press 'f' key to start/stop prime numbers (fast) benchmark." msgstr "\t按「上」鍵增加要監視的核心數。\n" #: tui_ncurses.c:499 #, fuzzy #| msgid "" #| "\n" #| "Caches tab:\n" msgid "Graphics tab:" msgstr "" "\n" "快取分頁:\n" #: tui_ncurses.c:500 #, fuzzy #| msgid "\tPress 'down' key to switch to previous test.\n" msgid "Press 'down' key to switch to previous graphic card." msgstr "\t按「下」鍵切換至上一項測試。\n" #: tui_ncurses.c:501 #, fuzzy #| msgid "\tPress 'up' key' to switch to next test.\n" msgid "Press 'up' key to switch to next graphic card." msgstr "\t按「上」鍵切換至下一項測試。\n" #: tui_ncurses.c:503 #, fuzzy #| msgid "" #| "\n" #| "Press any key to exit this help.\n" msgid "Press any key to exit this help." msgstr "" "\n" "按任意鍵退出幫助。\n" #: util.c:198 #, c-format msgid "cannot find unit in '%s' string at position %i" msgstr "" #: util.c:210 #, c-format msgid "String '%s' is too long, truncating…" msgstr "" #: util.c:287 #, c-format msgid "an error occurred while opening file '%s' (%s)" msgstr "" #: util.c:317 #, c-format msgid "an error occurred while running command '%s' (%s)" msgstr "" #: util.c:375 util.c:435 #, c-format msgid "failed to open %s directory" msgstr "" #: util.c:448 msgid "an error occurred while compiling regex" msgstr "編譯正則表達式時出錯" #: util.c:574 msgid "pkexec: authorization could not be obtained (dialog dismissed)" msgstr "" #: util.c:577 msgid "pkexec: authorization could not be obtained (not authorized)" msgstr "" #: util.c:580 msgid "pkexec: command not found" msgstr "" #: util.c:583 msgid "pkexec: unexpected error code" msgstr "" #: cpu-x.h:53 msgid "FATAL ERROR: could not allocate memory" msgstr "致命錯誤:無法配置記憶體" #: cpu-x.h:92 msgid "bytes" msgstr "位元組" #. TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #: cpu-x.h:95 msgid "kB" msgstr "kB" #. TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #: cpu-x.h:97 msgid "MB" msgstr "MB" #. TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #: cpu-x.h:99 msgid "GB" msgstr "GB" #. TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #: cpu-x.h:101 msgid "TB" msgstr "TB" #. TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #: cpu-x.h:104 msgid "KiB" msgstr "" #. TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #: cpu-x.h:106 #, fuzzy #| msgid "MB" msgid "MiB" msgstr "MB" #. TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #: cpu-x.h:108 #, fuzzy #| msgid "GB" msgid "GiB" msgstr "GB" #. TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #: cpu-x.h:110 #, fuzzy #| msgid "TB" msgid "TiB" msgstr "TB" #~ msgid "Exiting %s" #~ msgstr "退出 %s" #~ msgid "Skip CPU MSR opening (need to be root)" #~ msgstr "跳過 CPU MSR 開啟(必須為 root)" #~ msgid "failed to open CPU MSR (%s)" #~ msgstr "開啟 CPU MSR 失敗 (%s)" #~ msgid "(%s driver)" #~ msgstr "(%s 驅動)" CPU-X-4.2.0/scripts/000077500000000000000000000000001403012130000140205ustar00rootroot00000000000000CPU-X-4.2.0/scripts/build_appimage.sh000077500000000000000000000034441403012130000173260ustar00rootroot00000000000000#!/bin/bash set -eo pipefail # Functions die() { echo "[FATAL] $*" exit 1 } runCmd() { if ! "$@"; then die "command failed: '$*'" fi } # Constant variables if [[ $# -lt 2 ]]; then echo "$0: WORKSPACE APPDIR" exit 1 fi WORKSPACE="$1" APPDIR="$2" # Reset arguments set -- # Download linuxdeploy and plugins BUNDLER="$WORKSPACE/linuxdeploy.AppImage" runCmd wget --no-verbose "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" --output-document="$BUNDLER" \ && set -- "$@" --output appimage runCmd wget --no-verbose "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/libpangoft2/linuxdeploy-plugin-gtk.sh" \ && set -- "$@" --plugin gtk runCmd wget --no-verbose "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-ncurses/master/linuxdeploy-plugin-ncurses.sh" \ && set -- "$@" --plugin ncurses runCmd wget --no-verbose "https://raw.githubusercontent.com/linuxdeploy/misc-plugins/master/gettext/linuxdeploy-plugin-gettext.sh" \ && set -- "$@" --plugin gettext if [[ -z "$VERSION" ]]; then export LINUXDEPLOY_PLUGIN_GDB_SRC="$WORKSPACE/src" runCmd wget --no-verbose "https://raw.githubusercontent.com/linuxdeploy/misc-plugins/master/gdb/linuxdeploy-plugin-gdb.sh" \ && set -- "$@" --plugin gdb fi runCmd chmod --verbose a+x ./*.AppImage ./*.sh # Set useful variables for linuxdeploy export ARCH=x86_64 export UPDATE_INFORMATION="gh-releases-zsync|${GITHUB_REPOSITORY//\//|}|${VERSION:-"continuous"}|CPU-X-*$ARCH.AppImage.zsync" export VERBOSE=1 #export DEBUG=1 export DISABLE_COPYRIGHT_FILES_DEPLOYMENT=1 # Run linuxdeploy runCmd mkdir --parents --verbose "$WORKSPACE/AppImage" && runCmd cd "$_" runCmd "$BUNDLER" \ --appdir="$APPDIR" \ --desktop-file="$APPDIR/usr/share/applications/cpu-x.desktop" \ --verbosity=1 \ "$@" CPU-X-4.2.0/scripts/build_ubuntu.sh000077500000000000000000000033411403012130000170610ustar00rootroot00000000000000#!/bin/bash set -euo pipefail source /etc/os-release if [[ $# -lt 2 ]]; then echo "$0: BUILD_TYPE SOURCE_DIRECTORY [INSTALL_DIRECTORY]" exit 1 fi if [[ "$ID" != "ubuntu" ]]; then echo "$0: this script must be run on a Ubuntu system" exit 1 fi BUILD_TYPE="$1" SRC_DIR="$2" if [[ $# -ge 3 ]]; then DST_DIR="$3" APPIMAGE=1 else DST_DIR="" APPIMAGE=0 fi case "$VERSION_ID" in "16.04") PACKAGES=('libncursesw5-dev' 'libncursesw5' 'libcpuid15-git' 'libpci3' 'libglfw3-dev' 'libglfw3' 'libprocps4');; "18.04") PACKAGES=('libncursesw5-dev' 'libncursesw5' 'libcpuid15-git' 'libpci3' 'libglfw3-dev' 'libglfw3' 'libprocps6');; "20.04") PACKAGES=('libncurses-dev' 'libncursesw6' 'libcpuid15-git' 'libpci3' 'libglfw3-dev' 'libglfw3' 'libprocps8');; *) echo "Unsupported Ubuntu version: $VERSION_ID" ; exit 1;; esac echo "Add OBS repository" echo "deb http://download.opensuse.org/repositories/home:/Xorg/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/home:Xorg.list curl -sSL "https://download.opensuse.org/repositories/home:Xorg/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add - sudo apt-get update -qq echo "Install packages" sudo apt-get install -y -qq \ cmake \ ninja-build \ nasm \ gettext \ adwaita-icon-theme \ "${PACKAGES[@]}" \ libgtk-3-0 \ libgtk-3-dev \ libcpuid-dev-git \ libpci-dev \ libprocps-dev echo "Run CMake" cmake -S "$SRC_DIR" \ -B build \ -GNinja \ -DCMAKE_BUILD_TYPE="$BUILD_TYPE" \ -DCMAKE_INSTALL_PREFIX=/usr \ -DCMAKE_INSTALL_LIBEXECDIR=/usr/bin \ -DAPPIMAGE=$APPIMAGE echo "Build CPU-X" cmake --build build if [[ -z "$DST_DIR" ]]; then echo "Install CPU-X on system" sudo ninja -C build install else echo "Install CPU-X in AppDir" DESTDIR="$DST_DIR" ninja -C build install fi CPU-X-4.2.0/scripts/check_new_strings.sh000077500000000000000000000013041403012130000200540ustar00rootroot00000000000000#!/bin/bash # This script is used to check if there are new strings in source files set -euo pipefail GIT_DIR="$(git rev-parse --show-toplevel)" SHA=${GITHUB_SHA:-HEAD~0} cd "$GIT_DIR" || exit 1 if [[ "$(git show -s --format='%ce' "$SHA")" == "hosted@weblate.org" ]]; then echo "Commit by Weblate, nothing to do." > /dev/stderr echo "NO_CHANGE" exit 0 fi for file in $(git show --pretty="" --name-only "$SHA"); do if [[ "$file" == *.c ]] || [[ "$file" == *.h ]]; then if git show "$SHA" "$file" | egrep '^(\+|\-)' | egrep -qw '_\(|N_\('; then git show "$SHA" "$file" > /dev/stderr echo "REGEN" exit 0 fi fi done echo "No commit with translation change." > /dev/stderr echo "NO_CHANGE" CPU-X-4.2.0/scripts/make_builds.sh000077500000000000000000000040571403012130000166440ustar00rootroot00000000000000#!/bin/bash # This script is used to create archives for releases set -euo pipefail GIT_DIR="$(git rev-parse --show-toplevel)" VER=$(git describe --tags --exclude continuous | cut -d- -f1) ######################################################### # FUNCTIONS # ######################################################### help() { echo -e "Usage: $0 OPTION" echo -e "Options:" echo -e "\t-p, --package\tMake tarballs which contain packages" echo -e "\t --local\tBuild packages locally (with --package)" echo -e "\t-h, --help\tDisplay this help and exit" } ######################################################### # MAIN # ######################################################### if [[ $# < 1 ]]; then help exit 1 fi case "$1" in -p|--package) choice="package";; -h|--help) help; exit 0;; - |--) help; exit 1;; *) help; exit 1;; esac case "$choice" in package) REPO_URL="https://download.opensuse.org/repositories/home:/Xorg/" OBS_DIR="$(realpath "$GIT_DIR/../OBS")" PKGS_DIR="$OBS_DIR/pkgs" ARCHIVES_DIR="$GIT_DIR/packages" COMPRESS="tar -zcvf" if [[ "$2" == "--local" ]] && [[ ! -d "$PKGS_DIR" ]]; then "$GIT_DIR/scripts/osc_build.sh" "$OBS_DIR" "libcpuid" "$GIT_DIR/scripts/osc_build.sh" "$OBS_DIR" "cpu-x" cd "$PKGS_DIR" else mkdir -p "$PKGS_DIR" && cd "$_" wget --no-parent --no-host-directories --cut-dirs=3 --quiet --show-progress --continue \ --accept "*.pkg.tar.zst","*.rpm","*.deb" \ --reject "*.src.rpm","*git*" \ --recursive "$REPO_URL" fi find "$PKGS_DIR" -type f -not -name '*.deb' -and -not -name '*.rpm' -and -not -name '*.pkg.tar.*' -delete find "$PKGS_DIR" -type d -empty -delete mkdir -p "$ARCHIVES_DIR" $COMPRESS "$ARCHIVES_DIR/CPU-X_${VER}_ArchLinux.tar.gz" Arch* $COMPRESS "$ARCHIVES_DIR/CPU-X_${VER}_Debian.tar.gz" Debian* $COMPRESS "$ARCHIVES_DIR/CPU-X_${VER}_openSUSE.tar.gz" openSUSE* $COMPRESS "$ARCHIVES_DIR/CPU-X_${VER}_Ubuntu.tar.gz" xUbuntu* ;; esac CPU-X-4.2.0/scripts/osc_build.sh000077500000000000000000000025601403012130000163250ustar00rootroot00000000000000#!/bin/bash set -euo pipefail die() { echo "Error: $*" exit 1 } detach() { local distro="$1" local arch="$2" local descr="$3" local pkgs="$4" local logfile="$5" echo -e "\n\033[1m==> Build for $distro $arch\033[0m" if time nohup osc build "$distro" "$arch" "$descr" \ --trust-all-projects --clean --ccache --local-package \ --keep-pkgs="$pkgs" --prefer-pkgs="$pkgs" \ --no-debug-packages --jobs=2 > "$logfile" then color="\033[1;32m" else color="\033[1;31m" fi echo -e "\n$color==> End of $distro $arch\033[0m\n$(tail -n10 "$logfile")" } if [[ $# -lt 2 ]]; then echo "$0: OBS_DIR PACKAGE_NAME" exit 1 fi OLD_IFS="$IFS" OBS_DIR="$1" PACKAGE="$2" PKGS_DIR="$(realpath $OBS_DIR/pkgs)" cd "$OBS_DIR/$PACKAGE" || die "failed to change directory to '$PACKAGE'" mkdir -pv "$PKGS_DIR" IFS=$'\n' repos="${REPOS:-"$(osc repos)"}" for repo in $repos; do IFS="$OLD_IFS" array=($repo) distro="${array[0]}" arch="${array[1]}" pkgs="$PKGS_DIR/$distro" logfile=".osc/_buildlog-$distro.$arch.log" case "$distro" in Debian*|xUbuntu_*) descr="$PACKAGE.dsc";; Fedora*|openSUSE*) descr="$PACKAGE.spec";; Arch) descr="PKGBUILD";; esac detach "$distro" "$arch" "$descr" "$pkgs" "$logfile" & sleep 3 # Workaround to avoid issues with _service files done echo -e "\n\033[1m==> Wait for processes:\033[0m" jobs -p wait echo -e "\n\033[1mAll done!\033[0m" CPU-X-4.2.0/scripts/patch_dmidecode.sh000077500000000000000000000017321403012130000174560ustar00rootroot00000000000000#!/bin/bash set -euo pipefail CPUX_DIR="$(git rev-parse --show-toplevel)/src/dmidecode" DMIDECODE_DIR="/tmp/dmidecode" HASH_FILE="$CPUX_DIR/.hash" OLD_HASH=$(cat "$HASH_FILE") OLD_HASH_SHORT=${OLD_HASH:0:7} # Get dmidecode source code git clone https://git.savannah.gnu.org/git/dmidecode.git "$DMIDECODE_DIR" cd "$DMIDECODE_DIR" || exit 255 # Retrieve informations about repo VER=$(git describe --abbrev=0 | sed 's/^dmidecode-//;s/-/./') DATE=$(git show -s --format=%cd --date=format:%Y%m%d) NEW_HASH=$(git rev-parse HEAD) NEW_HASH_SHORT=$(git rev-parse --short HEAD) git diff "$OLD_HASH" master > "dmidecode.patch" # Patch to the new version cd "$CPUX_DIR" || exit 255 echo "$NEW_HASH" > "$HASH_FILE" sed -i "s/$OLD_HASH/$NEW_HASH/" "README.md" sed -i "s/$OLD_HASH_SHORT/$NEW_HASH_SHORT/" "README.md" sed -i "s/VERSION \"[^ ]*\"/VERSION \"$VER.$DATE\"/" "CMakeLists.txt" patch --batch --no-backup-if-mismatch --input="$DMIDECODE_DIR/dmidecode.patch" CPU-X-4.2.0/scripts/run_libcpuid_tests.sh000077500000000000000000000023671403012130000202700ustar00rootroot00000000000000#!/bin/bash # This script is used to test the CPU Technology database set -euo pipefail CR="\033[0m" # Color reset CB="\033[1m" # Color bold CBR="\033[1;31m" # Color bold red CBG="\033[1;32m" # Color bold green if [[ $# -lt 1 ]]; then echo "$0: you must provide the libcpuid 'tests' directory." exit 1 else TESTS_DIR="$1" fi count=0 while IFS= read -r -d '' file; do if [[ ! "$file" =~ "amd" ]] && [[ ! "$file" =~ "intel" ]]; then # Only AMD and Intel CPUs are supported continue fi # Cut test file after delimiter (dash line) tmp_file="/tmp/$(basename "$file")" while read -r line; do echo "$line" | grep -q "\-\-\-\-\-\-\-\-\-\-\-\-" && break echo "$line" >> "$tmp_file" done < "$file" # Run with CPU-X and display test status printf "Test file ${CB}%-32s${CR}: " "$(basename "$file")" if output=$(LC_ALL=C CPUX_CPUID_RAW="$tmp_file" CPUX_DEBUG_DATABASE=1 cpu-x --dump --nocolor); then echo -en "${CBG}OK${CR}\n" else echo -en "${CBR}${output#*"==> "}${CR}\n" ((count++)) fi rm "$tmp_file" done < <(find "$TESTS_DIR" -name '*.test' -print0) echo -en "\nDone: " if [[ $count -eq 0 ]]; then echo -e "${CBG}all test files passed with success!${CR}" else echo -e "${CBR}$count test files failed to pass.${CR}" fi exit "$count" CPU-X-4.2.0/src/000077500000000000000000000000001403012130000131205ustar00rootroot00000000000000CPU-X-4.2.0/src/CMakeLists.txt000066400000000000000000000142031403012130000156600ustar00rootroot00000000000000### FIND NEEDED LIBRAIRIES # GTK3+ if(WITH_GTK) set(MINIMUM_GTK_VERSION 3.12.0) pkg_check_modules(GTK3 gtk+-3.0>=${MINIMUM_GTK_VERSION}) if(GTK3_FOUND) include_directories(${GTK3_INCLUDE_DIRS}) link_directories(${GTK3_LIBRARY_DIRS}) add_definitions(${GTK3_CFLAGS_OTHER}) add_library(gui_gtk STATIC gui_gtk.c gui_gtk.h gui_gtk_id.h ${GRESOURCES} ) set(GTK3_LIBRARIES "gui_gtk" ${GTK3_LIBRARIES}) else(GTK3_FOUND) message("${BoldYellow}GTK3+ GUI will not be build:${ColourReset} ${Yellow}GTK ${MINIMUM_GTK_VERSION} or higher is needed.${ColourReset}") message("${Yellow}Set ${BoldYellow}PKG_CONFIG_PATH${ColourReset}${Yellow} environment variable if development files are installed.${ColourReset}") endif(GTK3_FOUND) endif(WITH_GTK) # NCurses if(WITH_NCURSES) pkg_check_modules(NCURSES ncursesw) if(NCURSES_FOUND) include_directories(${NCURSES_INCLUDE_DIRS}) link_directories(${NCURSES_LIBRARY_DIRS}) add_library(tui_ncurses STATIC tui_ncurses.c tui_ncurses.h ) set(NCURSES_LIBRARIES "tui_ncurses" ${NCURSES_LIBRARIES}) endif(NCURSES_FOUND) endif(WITH_NCURSES) # Gettext if(Intl_FOUND) include_directories(${CMAKE_BINARY_DIR}/po) endif(Intl_FOUND) # Libcpuid if(WITH_LIBCPUID) pkg_check_modules(LIBCPUID libcpuid>=0.5.0) if(LIBCPUID_FOUND) include_directories(${LIBCPUID_INCLUDE_DIRS}) link_directories(${LIBCPUID_LIBRARY_DIRS}) add_definitions(${LIBCPUID_CFLAGS_OTHER}) set(CMAKE_REQUIRED_LIBRARIES ${LIBCPUID_LIBRARIES}) endif(LIBCPUID_FOUND) endif(WITH_LIBCPUID) # Libpci if(WITH_LIBPCI) pkg_check_modules(LIBPCI libpci) if(LIBPCI_FOUND) include_directories(${LIBPCI_INCLUDE_DIRS}) link_directories(${LIBPCI_LIBRARY_DIRS}) add_definitions(${LIBPCI_CFLAGS_OTHER}) endif(LIBPCI_FOUND) endif(WITH_LIBPCI) # Libglfw if(WITH_LIBGLFW) pkg_check_modules(LIBGL gl) pkg_check_modules(LIBGLFW glfw3>=3.3) if(LIBGL_FOUND AND LIBGLFW_FOUND) include_directories(${LIBGL_INCLUDE_DIRS} ${LIBGLFW_INCLUDE_DIRS}) link_directories(${LIBGL_LIBRARY_DIRS} ${LIBGLFW_LIBRARY_DIRS}) add_definitions(${LIBGL_CFLAGS_OTHER} ${LIBGLFW_CFLAGS_OTHER}) endif(LIBGL_FOUND AND LIBGLFW_FOUND) endif(WITH_LIBGLFW) # Libprocps set(LIBSYSTEM 0) if(WITH_LIBPROCPS AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT FORCE_LIBSTATGRAB) pkg_check_modules(LIBPROCPS libprocps) if(LIBPROCPS_FOUND) include_directories(${LIBPROCPS_INCLUDE_DIRS}) link_directories(${LIBPROCPS_LIBRARY_DIRS}) add_definitions(${LIBPROCPS_CFLAGS_OTHER}) set(LIBSYSTEM 1) endif(LIBPROCPS_FOUND) endif(WITH_LIBPROCPS AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT FORCE_LIBSTATGRAB) # Libstatgrab if(WITH_LIBSTATGRAB AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR FORCE_LIBSTATGRAB)) pkg_check_modules(LIBSTATGRAB libstatgrab) if(LIBSTATGRAB_FOUND) include_directories(${LIBSTATGRAB_INCLUDE_DIRS}) link_directories(${LIBSTATGRAB_LIBRARY_DIRS}) add_definitions(${LIBSTATGRAB_CFLAGS_OTHER}) set(LIBSYSTEM 2) endif(LIBSTATGRAB_FOUND) endif(WITH_LIBSTATGRAB AND (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR FORCE_LIBSTATGRAB)) # Dmidecode if(WITH_DMIDECODE) add_subdirectory(dmidecode) include_directories(dmidecode) set(DMIDECODE_LIBRARIES "dmidecode") endif(WITH_DMIDECODE) # Bandwidth if(WITH_BANDWIDTH) add_subdirectory(bandwidth) if(BANDWIDTH_FOUND) include_directories(bandwidth) set(BANDWIDTH_LIBRARIES "bandwidth") endif(BANDWIDTH_FOUND) endif(WITH_BANDWIDTH) ### FINAL CONFIG message("${BoldCyan}** ${CMAKE_PROJECT_NAME} ${PROJECT_VERSION} configuration **${ColourReset}") # UI libraries print_config("GTK" "${GTK3_VERSION}" GTK3_FOUND WITH_GTK) print_config("NCURSES" "${NCURSES_VERSION}" NCURSES_FOUND WITH_NCURSES) # Other libraries print_config("GETTEXT" 0 GETTEXT_FOUND WITH_GETTEXT) print_config("LIBCPUID" "${LIBCPUID_VERSION}" LIBCPUID_FOUND WITH_LIBCPUID) print_config("LIBPCI" "${LIBPCI_VERSION}" LIBPCI_FOUND WITH_LIBPCI) print_config("LIBGLFW" "${LIBGLFW_VERSION}" LIBGLFW_FOUND WITH_LIBGLFW) if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" AND NOT FORCE_LIBSTATGRAB) print_config("LIBPROCPS" "${LIBPROCPS_VERSION}" LIBPROCPS_FOUND WITH_LIBPROCPS) else() print_config("LIBSTATGRAB" "${LIBSTATGRAB_VERSION}" LIBSTATGRAB_FOUND WITH_LIBSTATGRAB) endif() # Subprojects print_config("DMIDECODE" "${DMIDECODE_VERSION}" 1 WITH_DMIDECODE) print_config("BANDWIDTH" "${BANDWIDTH_VERSION}" BANDWIDTH_FOUND WITH_BANDWIDTH) ### MAIN BINARY # Executable add_executable(${APP_EXEC} main.c util.c cpu-x.h core.c core.h ipc.h ) add_executable(${DAEMON_EXEC} daemon.c daemon.h ipc.h cpu-x.h ) # Libsystem extra-definitions if(${LIBSYSTEM} EQUAL 0 OR ${LIBSYSTEM} EQUAL 1) add_definitions(-DHAS_LIBSTATGRAB=0 -DLIBSTATGRAB_VERSION=NULL) endif() if(${LIBSYSTEM} EQUAL 0 OR ${LIBSYSTEM} EQUAL 2) add_definitions(-DHAS_LIBPROCPS=0 -DLIBPROCPS_VERSION=NULL) endif() # Various definitions add_definitions(-DPRGVER="${PROJECT_VERSION}" -DGITREV="${GIT_REVISION}" -DSYSTEM_NAME="${CMAKE_SYSTEM_NAME}" -DSYSTEM_PROCESSOR="${CMAKE_SYSTEM_PROCESSOR}" -DC_COMPILER_ID="${CMAKE_C_COMPILER_ID}" -DHAS_LIBSYSTEM=${LIBSYSTEM} -DGETTEXT_PACKAGE="${CMAKE_PROJECT_NAME}" -DLOCALEDIR="${CMAKE_INSTALL_FULL_LOCALEDIR}" -DTERMINFODIR="/lib/terminfo" -DDAEMON_EXEC="${DAEMON_EXEC}" -DDAEMON_PATH="${DAEMON_PATH}" ) if(APPIMAGE) set(DAEMON_FLAGS "-static") set(LIBCPUID_LIBRARIES "-l:libcpuid.a") endif(APPIMAGE) # Link libraries target_link_libraries(${APP_EXEC} m ${Intl_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${Backtrace_LIBRARIES} ${GTK3_LIBRARIES} ${NCURSES_LIBRARIES} ${LIBCPUID_LIBRARIES} ${LIBPCI_LIBRARIES} ${LIBGL_LIBRARIES} ${LIBGLFW_LIBRARIES} ${LIBPROCPS_LIBRARIES} ${LIBSTATGRAB_LIBRARIES} ${DMIDECODE_LIBRARIES} ${BANDWIDTH_LIBRARIES} ${OTHER_LIBRARIES} ) target_link_libraries(${DAEMON_EXEC} ${DAEMON_FLAGS} ${Intl_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${LIBCPUID_LIBRARIES} ${DMIDECODE_LIBRARIES} ) ### INSTALLATION install(TARGETS ${APP_EXEC} DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}/) install(TARGETS ${DAEMON_EXEC} DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}/) CPU-X-4.2.0/src/bandwidth/000077500000000000000000000000001403012130000150645ustar00rootroot00000000000000CPU-X-4.2.0/src/bandwidth/BMP.c000066400000000000000000000362751403012130000156630ustar00rootroot00000000000000 /*============================================================================= bmplib, a simple library to create, modify, and write BMP image files. Copyright (C) 2009-2014 by Zack T Smith. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *============================================================================*/ //-------------------------------------------------- // Change Log // 0.8 ZS Added larger font of my own design. // 0.9 ZS Removed attempt at anti-aliasing. //-------------------------------------------------- #include #include #include #include "BMP.h" #include "font.h" #include "minifont.h" // Narrowest possible numbers. static char* narrow_nums [] = { " # ", "# #", "# #", "# #", "# #", "# #", " # ", " #", "##", " #", " #", " #", " #", " #", " # ", "# #", " #", " ##", "# ", "# ", "###", "###", " #", " # ", "## ", " #", "# #", " # ", "# #", "# #", "# #", "###", " #", " #", " #", "###", "# ", "## ", " #", " #", "# #", " # ", " # ", "# ", "# ", "## ", "# #", "# #", " # ", "###", " #", " #", " # ", " # ", " # ", " # ", " # ", "# #", "# #", " # ", "# #", "# #", " # ", " # ", "# #", "# #", " ##", " #", " # ", "# ", " ", "", "", " ", "", "", "#", }; /*--------------------------------------------------------------------------- * Name: BMP_new * Purpose: Creates new image. *-------------------------------------------------------------------------*/ BMP* BMP_new (int w, int h) { unsigned long size; BMP* nu; if (w<1 || h<1) return NULL; //---------- if (w & 3) w += 4 - (w & 3); if (h & 3) h += 4 - (h & 3); nu = (BMP*) malloc (sizeof (BMP)); if (!nu) return NULL; memset (nu, 0, sizeof (BMP)); nu->width = w; nu->height = h; size = w * h * sizeof (long); nu->pixels = (RGB*) malloc (size); if (!nu->pixels) { free (nu); return NULL; } memset (nu->pixels, 0, size); return nu; } /*--------------------------------------------------------------------------- * Name: BMP_destroy * Purpose: Deallocates image. *-------------------------------------------------------------------------*/ void BMP_destroy (BMP* bmp) { if (!bmp) return; //---------- if (bmp->pixels) free (bmp->pixels); free (bmp); } /*--------------------------------------------------------------------------- * Name: BMP_point * Purpose: Writes pixel into image. *-------------------------------------------------------------------------*/ void BMP_point (BMP *bmp, int x, int y, RGB rgb) { if (!bmp || x<0 || y<0) return; if (x >= bmp->width || y >= bmp->height) return; if (!bmp->pixels) return; //---------- bmp->pixels[y*bmp->width + x] = rgb; } /*--------------------------------------------------------------------------- * Name: BMP_line_core * Purpose: Draws a line in a BMP image. *-------------------------------------------------------------------------*/ void BMP_line_core (BMP *bmp, int x0, int y0, int x1, int y1, RGB rgb, int dashed) { if ((rgb >> 24) == 0xff) return; int dot_counter = 0; if (!dashed && x0 == x1 && y0 == y1) BMP_point (bmp, x0, y0, rgb); else if (!dashed && x0 == x1) BMP_vline (bmp, x0, y0, y1, rgb); else if (!dashed && y0 == y1) BMP_hline (bmp, x0, x1, y0, rgb); else { int j, x, y, dx, dy, e, xchange, s1, s2; // DDA, copied from my FramebufferUI project. x = x0; y = y0; s1 = 1; s2 = 1; dx = x1 - x0; if (dx < 0) { dx = -dx; s1 = -1; } dy = y1 - y0; if (dy < 0) { dy = -dy; s2 = -1; } xchange = 0; if (dy > dx) { int tmp = dx; dx = dy; dy = tmp; xchange = 1; } e = (dy<<1) - dx; j = 0; while (j <= dx) { j++; int draw = 1; if (dashed && (1 & (dot_counter >> 2))) draw = 0; if (draw) BMP_point (bmp, x, y, rgb); dot_counter++; if (e >= 0) { if (xchange) x += s1; else y += s2; e -= (dx << 1); } if (xchange) y += s2; else x += s1; e += (dy << 1); } } } /*--------------------------------------------------------------------------- * Name: BMP_line * Purpose: Draws a line in a BMP image. *-------------------------------------------------------------------------*/ void BMP_line (BMP *bmp, int x0, int y0, int x1, int y1, RGB rgb) { BMP_line_core (bmp, x0, y0, x1, y1, rgb, 0); } /*--------------------------------------------------------------------------- * Name: BMP_line_dashed * Purpose: Draws a dashed line in a BMP image. *-------------------------------------------------------------------------*/ void BMP_line_dashed (BMP *bmp, int x0, int y0, int x1, int y1, RGB rgb) { BMP_line_core (bmp, x0, y0, x1, y1, rgb, 1); } /*--------------------------------------------------------------------------- * Name: BMP_rect * Purpose: Fills a rectangle with a color. *-------------------------------------------------------------------------*/ void BMP_rect (BMP *bmp, int x, int y, int w, int h, RGB rgb) { BMP_hline (bmp, x, x+w-1, y, rgb); BMP_hline (bmp, x, x+w-1, y+h-1, rgb); BMP_vline (bmp, x, y, y+h-1, rgb); BMP_vline (bmp, x+w-1, y, y+h-1, rgb); } /*--------------------------------------------------------------------------- * Name: BMP_fillrect * Purpose: Fills a rectangle with a color. *-------------------------------------------------------------------------*/ void BMP_fillrect (BMP *bmp, int x, int y, int w, int h, RGB rgb) { while (h > 0) { BMP_hline (bmp, x, x+w-1, y, rgb); h--; y++; } } /*--------------------------------------------------------------------------- * Name: BMP_clear * Purpose: Sets all pixels to specified color. *-------------------------------------------------------------------------*/ void BMP_clear (BMP *bmp, RGB rgb) { BMP_fillrect (bmp, 0, 0, bmp->width, bmp->height, rgb); } /*--------------------------------------------------------------------------- * Name: BMP_hline * Purpose: Draws horizontal line. *-------------------------------------------------------------------------*/ void BMP_hline (BMP *bmp, int x0, int x1, int y, RGB rgb) { if (x0 > x1) { int tmp=x1; x1=x0; x0=tmp; } while (x0 <= x1) { BMP_point (bmp, x0++, y, rgb); } } /*--------------------------------------------------------------------------- * Name: BMP_vline * Purpose: Draws vertical line. *-------------------------------------------------------------------------*/ void BMP_vline (BMP *bmp, int x, int y0, int y1, RGB rgb) { if (y0 > y1) { int tmp=y1; y1=y0; y0=tmp; } while (y0 <= y1) { BMP_point (bmp, x, y0++, rgb); } } /*--------------------------------------------------------------------------- * Name: BMP_draw_string * Purpose: Draws ature 5x8 characters into the image. *-------------------------------------------------------------------------*/ int BMP_draw_string (BMP *bmp, const char *string, int x, int y, RGB color) { char ch; const char *s; if (!bmp || !string) return 0; if (x >= bmp->width || y >= bmp->height || !*string) return 0; //---------- #if 0 RGB r,g,b; RGB light; RGB dark; r = 0xff & (color >> 16); g = 0xff & (color >> 8); b = 0xff & color; r += 3*0xff; b += 3*0xff; g += 3*0xff; r /= 4; g /= 4; b /= 4; light = b | (g << 8) | (r << 16); r = 0xff & (color >> 16); g = 0xff & (color >> 8); b = 0xff & color; r += 0xff; b += 0xff; g += 0xff; r /= 2; g /= 2; b /= 2; dark = b | (g << 8) | (r << 16); #endif const char **chars = get_font_chars (); s = string; while ((ch = *s++)) { int ix = -1; if (ch == ' ') { x += 10; continue; } if (ch > 'z') continue; if (ch > ' ' && ch <= 'z') ix = FONT_HEIGHT * (ch - 33); if (ix >= 0) { int i; int width = 0; for (i=0; i 'z') continue; if (ch > ' ' && ch <= 'z') ix = FONT_HEIGHT * (ch - 33); if (ix >= 0) { int j; int max_w = 0; for (j = 0; j < FONT_HEIGHT; j++) { const char *ptr = _chars [j+ix]; int w = ptr ? strlen (ptr) : 0; if (max_w < w) max_w = w; } width += max_w + 2/* kerning */; } } return width; } /*--------------------------------------------------------------------------- * Name: BMP_draw_mini_string * Purpose: Draws miniature 5x8 characters into the image. *-------------------------------------------------------------------------*/ int BMP_draw_mini_string (BMP *bmp, const char *string, int x, int y, RGB color) { char ch; const char *s; if (!bmp || !string) return 0; if (x >= bmp->width || y >= bmp->height || !*string) return 0; //---------- #if 0 unsigned long r,g,b; unsigned long light, dark; r = 0xff & (color >> 16); g = 0xff & (color >> 8); b = 0xff & color; r += 3*0xff; b += 3*0xff; g += 3*0xff; r /= 4; g /= 4; b /= 4; light = b | (g << 8) | (r << 16); r = 0xff & (color >> 16); g = 0xff & (color >> 8); b = 0xff & color; r += 0xff; b += 0xff; g += 0xff; r /= 2; g /= 2; b /= 2; dark = b | (g << 8) | (r << 16); #endif const char **mini_chars = get_minifont_chars (); #define MINI_HEIGHT (8) s = string; while ((ch = *s++)) { int ix = -1; if (ch == ' ') { x += 5; continue; } if (ch > 'z') continue; if (ch > ' ' && ch <= 'z') ix = MINI_HEIGHT * (ch - 33); if (ix >= 0) { int i; int width = 0; for (i=0; i 'z') continue; if (ch > ' ' && ch <= 'z') ix = MINI_HEIGHT * (ch - 33); if (ix >= 0) { int max_w = 0; int j; for (j = 0; j < MINI_HEIGHT; j++) { const char *ptr = mini_chars [j+ix]; int w = ptr ? strlen (ptr) : 0; if (max_w < w) max_w = w; } width += max_w + 1/*kerning*/; } } return width; } /*--------------------------------------------------------------------------- * Name: BMP_narrow_numbers * Purpose: Draws miniature 4x7 characters into the image. *-------------------------------------------------------------------------*/ int BMP_draw_narrow_numbers (BMP *bmp, const char *string, int x, int y, RGB color) { char ch; const char *s; if (!bmp || !string) return 0; if (x >= bmp->width || y >= bmp->height || !*string) return 0; //---------- #define NARROW_HEIGHT (7) s = string; while ((ch = *s++)) { int ix = -1; if (ch == ' ') { x += 3; continue; } if (ch >= '0' && ch <= '9') ix = ch - '0'; else if (ch == '.') ix = 10; ix *= NARROW_HEIGHT; if (ix >= 0) { int i; int width = strlen (narrow_nums [ix]); for (i=0; i= bmp->width || y >= bmp->height) return 0; if (!bmp->pixels) return 0; //---------- return bmp->pixels[y*bmp->width + x]; } /*--------------------------------------------------------------------------- * Name: BMP_write * Purpose: Writes image to BMP file. *-------------------------------------------------------------------------*/ int BMP_write (const BMP* bmp, const char *path) { FILE *f; #define HDRLEN (54) unsigned char h[HDRLEN]; unsigned long len; int i, j; if (!bmp || !path) return -1; //---------- memset (h, 0, HDRLEN); //-------------------- // Create the file. // f = fopen (path, "wb"); if (!f) return 0; //-------------------- // Prepare header // len = HDRLEN + 3 * bmp->width * bmp->height; h[0] = 'B'; h[1] = 'M'; h[2] = len & 0xff; h[3] = (len >> 8) & 0xff; h[4] = (len >> 16) & 0xff; h[5] = (len >> 24) & 0xff; h[10] = HDRLEN; h[14] = 40; h[18] = bmp->width & 0xff; h[19] = (bmp->width >> 8) & 0xff; h[20] = (bmp->width >> 16) & 0xff; h[22] = bmp->height & 0xff; h[23] = (bmp->height >> 8) & 0xff; h[24] = (bmp->height >> 16) & 0xff; h[26] = 1; h[28] = 24; h[34] = 16; h[36] = 0x13; // 2835 pixels/meter h[37] = 0x0b; h[42] = 0x13; // 2835 pixels/meter h[43] = 0x0b; //-------------------- // Write header. // if (HDRLEN != fwrite (h, 1, HDRLEN, f)) { fclose (f); return 0; } //---------------------------------------- // Write pixels. // Note that BMP has lower rows first. // for (j=bmp->height-1; j >= 0; j--) { for (i=0; i < bmp->width; i++) { unsigned char rgb[3]; int ix = i + j * bmp->width; unsigned long pixel = bmp->pixels[ix]; rgb[0] = pixel & 0xff; rgb[1] = (pixel >> 8) & 0xff; rgb[2] = (pixel >> 16) & 0xff; if (3 != fwrite (rgb, 1, 3, f)) { fclose (f); return 0; } } } fclose (f); return 1; } CPU-X-4.2.0/src/bandwidth/BMP.h000066400000000000000000000062321403012130000156560ustar00rootroot00000000000000 /*============================================================================= bmplib, a simple library to create, modify, and write BMP image files. Copyright (C) 2009-2014 by Zack T Smith. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *============================================================================*/ #ifndef _BMP_H #define _BMP_H #include #define BMPLIB_RELEASE "0.9" #define BMPLIB_RELEASE_MAJOR 0 #define BMPLIB_RELEASE_MINOR 9 typedef uint32_t RGB; typedef uint32_t RGBA; typedef struct { int width, height; RGB *pixels; } BMP; #define FONT_HEIGHT (17) #define MINIFONT_HEIGHT (8) extern BMP* BMP_new (int, int); extern void BMP_destroy (BMP*); extern void BMP_clear (BMP*, RGB); extern int BMP_write (const BMP*, const char *path); extern void BMP_point (BMP*, int, int, RGB); extern void BMP_line (BMP *, int x0, int y0, int x1, int y1, RGB); extern void BMP_line_dashed (BMP *, int x0, int y0, int x1, int y1, RGB); extern void BMP_hline (BMP *, int x0, int x1, int y, RGB); extern void BMP_vline (BMP *, int x, int y0, int y1, RGB); extern void BMP_rect (BMP *, int x, int y, int w, int h, RGB); extern void BMP_fillrect (BMP *, int x, int y, int w, int h, RGB); extern RGB BMP_getpixel (BMP*, int, int); extern int BMP_draw_string (BMP *, const char *, int x, int y, RGB); extern int BMP_string_width (const char *); extern int BMP_draw_mini_string (BMP *, const char *, int x, int y, RGB); extern int BMP_mini_string_width (const char *); #define RGB_BLACK (0) #define RGB_BLUE (0xff) #define RGB_BRASS (0xc3a368) #define RGB_BROWN (0x8b4513) #define RGB_CADETBLUE (0x5f9ea0) #define RGB_CHARTREUSE (0x7fff00) #define RGB_CORAL (0xff7f50) #define RGB_CYAN (0xffff) #define RGB_DARKGREEN (0x6400) #define RGB_DARKKHAKI (0xbdb76b) #define RGB_DARKOLIVEGREEN (0x556b2f) #define RGB_DARKORANGE (0xff8c00) #define RGB_DODGERBLUE (0x1e90ff) #define RGB_GOLDENROD (0xdaa520) #define RGB_GRAY (0xc0c0c0) #define RGB_GREEN (0xff00) #define RGB_KHAKI (0xf0e68c) #define RGB_LEMONYELLOW (0xfde910) #define RGB_MAGENTA (0xff00ff) #define RGB_MAROON (0x800000) #define RGB_NAVYBLUE (0x80) #define RGB_ORANGE (0xffa500) #define RGB_PINK (0xf77fbe) #define RGB_PURPLE (0xa020f0) #define RGB_RED (0xff0000) #define RGB_ROYALBLUE (0x4169e1) #define RGB_SALMON (0xfa8072) #define RGB_TURQUOISE (0x40e0d0) #define RGB_VIOLET (0xee82ee) #define RGB_WHITE (0xffffff) #define RGB_YELLOW (0xffff00) #define RGB_GRAY6 (0x606060) #define RGB_GRAY8 (0x808080) #define RGB_GRAY10 (0xa0a0a0) #define RGB_GRAY12 (0xc0c0c0) #define RGB_GRAY14 (0xe0e0e0) #endif CPU-X-4.2.0/src/bandwidth/BMPGraphing.c000066400000000000000000000307211403012130000173310ustar00rootroot00000000000000/*============================================================================ BMPGraphing, a library for graphing. Copyright (C) 2005-2017 by Zack T Smith. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *===========================================================================*/ #include #include #include #include #include "BMP.h" #include "BMPGraphing.h" //---------------------------------------------------------------------------- // Name: BMPGraphing_draw_labels_log2 // Purpose: Draw the labels and ticks. //---------------------------------------------------------------------------- void BMPGraphing_draw_labels_log2 (BMPGraph* graph) { if (!graph || !graph->image) return; //---------------------------------------- // Horizontal // // Establish min & max x values. // int i = 0; Value min_x = 0x4000000000000000; Value max_x = 0; for (i = 0; i < graph->data_index; i += 2) { Value type = graph->data[i]; Value value = graph->data[i+1]; if (type == DATUM_X) { if (value < min_x) min_x = value; if (value > max_x) max_x = value; } } graph->min_x = (long long) log2 (min_x); graph->max_x = (long long) ceil (log2 (max_x)); for (i = graph->min_x; i <= graph->max_x; i++) { char str [200]; int x = graph->left_margin + ((i-graph->min_x) * graph->x_span) / (graph->max_x - graph->min_x); int y = graph->height - graph->margin + 10; unsigned long y2 = 1 << i; if (y2 < 1536) snprintf (str, 199, "%ld B", y2); else if (y2 < (1<<20)) { snprintf (str, 199, "%ld kB", y2 >> 10); } else { Value j = y2 >> 20; switch ((y2 >> 18) & 3) { case 0: snprintf (str, 199, "%lld MB", (unsigned long long) j); break; case 1: snprintf (str, 199, "%lld.25 MB", (unsigned long long) j); break; case 2: snprintf (str, 199, "%lld.5 MB", (unsigned long long) j); break; case 3: snprintf (str, 199, "%lld.75 MB", (unsigned long long) j); break; } } BMP_vline (graph->image, x, y, y - 10, RGB_BLACK); BMP_draw_mini_string (graph->image, str, x - 10, y + 8, RGB_BLACK); } //---------------------------------------- // Vertical // // Establish min & max y values. // Value min_y = 0x4000000000000000; Value max_y = 0; for (i = 0; i < graph->data_index; i += 2) { Value type = graph->data[i]; Value value = graph->data[i+1]; if (type == DATUM_Y) { if (value < min_y) min_y = value; if (value > max_y) max_y = value; } } graph->min_y = min_y; graph->max_y = max_y; int font_height = 10; int available_height = graph->y_span; int max_labels = available_height / font_height; int preferred_n_labels = graph->max_y/10000; int actual_n_labels; float multiplier = 1; if (preferred_n_labels < max_labels) { actual_n_labels = preferred_n_labels; } else { actual_n_labels = max_labels; multiplier = preferred_n_labels / (float) actual_n_labels; } for (i = 0; i <= actual_n_labels; i++) { char str [200]; int x = graph->left_margin - 10; int y = graph->height - graph->margin - (i * graph->y_span) / (float)actual_n_labels; BMP_hline (graph->image, x, x+10, y, RGB_BLACK); int value = (int) (i * multiplier); snprintf (str, 199, "%d GB/s", value); BMP_draw_mini_string (graph->image, str, x - 40, y - MINIFONT_HEIGHT/2, RGB_BLACK); } } BMPGraph * BMPGraphing_new (int w, int h, int x_axis_mode) { if (x_axis_mode != MODE_X_AXIS_LINEAR && x_axis_mode != MODE_X_AXIS_LOG2) return NULL; BMPGraph *graph = (BMPGraph*) malloc (sizeof(BMPGraph)); if (!graph) return NULL; bzero (graph, sizeof(BMPGraph)); graph->x_axis_mode = x_axis_mode; if (w <= 0 || h <= 0) { w = 1920; h = 1080; } graph->width = w; graph->height = h; graph->image = BMP_new (w, h); graph->margin = 40; graph->left_margin = 80; BMP_clear (graph->image, RGB_WHITE); BMP_hline (graph->image, graph->left_margin, graph->width - graph->margin, graph->height - graph->margin, RGB_BLACK); BMP_vline (graph->image, graph->left_margin, graph->margin, graph->height - graph->margin, RGB_BLACK); graph->x_span = graph->width - (graph->margin + graph->left_margin); graph->y_span = graph->height - 2 * graph->margin; graph->legend_y = graph->margin; return graph; } void BMPGraphing_set_title (BMPGraph* graph, const char *title) { if (!graph || !title) return; if (graph->title) free (graph->title); graph->title = strdup (title); BMP_draw_string (graph->image, graph->title, graph->left_margin, graph->margin/2, RGB_BLACK); } void BMPGraphing_new_line (BMPGraph *graph, const char *str, RGB color) { if (!graph || !graph->image) return; BMP_draw_string (graph->image, str, graph->width - graph->margin - 370, graph->legend_y, 0xffffff & color); graph->legend_y += 17; graph->fg = 0; graph->last_x = graph->last_y = -1; if (graph->data_index >= MAX_GRAPH_DATA-2) return; // error ("Too many graph data."); graph->data [graph->data_index++] = DATUM_COLOR; graph->data [graph->data_index++] = color; } //---------------------------------------------------------------------------- // Name: BMPGraphing_add_point // Purpose: Adds a point to this list to be drawn. //---------------------------------------------------------------------------- void BMPGraphing_add_point (BMPGraph *graph, Value x, Value y) { if (!graph || !graph->image) return; if (graph->data_index >= MAX_GRAPH_DATA-4) return; // error ("Too many graph data."); graph->data [graph->data_index++] = DATUM_X; graph->data [graph->data_index++] = x; graph->data [graph->data_index++] = DATUM_Y; graph->data [graph->data_index++] = y; } //---------------------------------------------------------------------------- // Name: BMPGraphing_plot_log2 // Purpose: Plots a point on the current graph. //---------------------------------------------------------------------------- void BMPGraphing_plot_log2 (BMPGraph *graph, Value x, Value y) { if (!graph || !graph->image) return; //---------------------------------------- // Plot the point. The x axis is // logarithmic, base 2. // double tmp = log2 (x); tmp -= (double) graph->min_x; tmp *= (double) graph->x_span; tmp /= (double) (graph->max_x - graph->min_x); int x2 = graph->left_margin + (int) tmp; int y2 = graph->height - graph->margin - (y * graph->y_span) / graph->max_y; if (graph->last_x != -1 && graph->last_y != -1) { if (graph->fg & DASHED) BMP_line_dashed (graph->image, graph->last_x, graph->last_y, x2, y2, graph->fg & 0xffffff); else BMP_line (graph->image, graph->last_x, graph->last_y, x2, y2, graph->fg); } graph->last_x = x2; graph->last_y = y2; } //---------------------------------------------------------------------------- // Name: BMPGraphing_plot_linear // Purpose: Plots a point on the current graph. //---------------------------------------------------------------------------- void BMPGraphing_plot_linear (BMPGraph *graph, Value x, Value y, Value max_y) { if (!graph || !graph->image) return; //---------------------------------------- // Plot the point. The x axis is // logarithmic, base 2. The units of the // y value is kB. // double tmp = 10. + log2 (x); tmp -= (double) XVALUE_MIN; tmp *= (double) graph->x_span; tmp /= (double) (XVALUE_MAX - XVALUE_MIN); int x2 = graph->left_margin + (int) tmp; int y2 = graph->height - graph->margin - (y * graph->y_span) / max_y; //printf ("\tx=%d, y=%d\n",x,y); fflush(stdout); if (graph->last_x != -1 && graph->last_y != -1) { if (graph->fg & DASHED) BMP_line_dashed (graph->image, graph->last_x, graph->last_y, x2, y2, graph->fg & 0xffffff); else BMP_line (graph->image, graph->last_x, graph->last_y, x2, y2, graph->fg); } graph->last_x = x2; graph->last_y = y2; } //---------------------------------------------------------------------------- // Name: BMPGraphing_make_log2 // Purpose: Plots all lines. //---------------------------------------------------------------------------- static void BMPGraphing_make_log2 (BMPGraph *graph) { if (!graph || !graph->image) return; BMPGraphing_draw_labels_log2 (graph); //---------------------------------------- // OK, now draw the lines. // int i; int x = -1, y = -1; for (i = 0; i < graph->data_index; i += 2) { Value type = graph->data[i]; Value value = graph->data[i+1]; switch (type) { case DATUM_Y: y = value; break; case DATUM_X: x = value; break; case DATUM_COLOR: graph->fg = (unsigned long) value; graph->last_x = -1; graph->last_y = -1; break; } if (x != -1 && y != -1) { BMPGraphing_plot_log2 (graph, x, y); x = y = -1; } } } //---------------------------------------------------------------------------- // Name: BMPGraphing_make_linear // Purpose: Plots all lines for the network test graph. //---------------------------------------------------------------------------- static void BMPGraphing_make_linear (BMPGraph *graph) { if (!graph || !graph->image) return; int i; // No data if (!graph->data_index) return; //---------------------------------------- // Get the maximum bandwidth in order to // properly scale the graph vertically. // int max_y = 0; for (i = 0; i < graph->data_index; i += 2) { if (graph->data[i] == DATUM_Y) { int y = graph->data [i+1]; if (y > max_y) max_y = y; } } int range = max_y > 10000 ? 2 : (max_y > 1000 ? 1 : 0); int y_spacing = 1; switch (range) { case 2: // Round up to the next 100.00 MB/sec. (=10000). y_spacing = 10000; break; case 1: // Round up to the next 10.00 MB/sec. y_spacing = 1000; break; case 0: // Round up to the next 1.00 MB/sec. y_spacing = 100; break; } max_y /= y_spacing; max_y *= y_spacing; max_y += y_spacing; //---------------------------------------- // Draw the axes, ticks & labels. // // X axis: if (XVALUE_MIN < 10) return; // error ("Minimum y is too small."); for (i = XVALUE_MIN; i <= XVALUE_MAX; i++) { char str[200]; unsigned long y2 = 1 << (i-10); // XX XVALUE_MIN>=10 if (y2 < 1024) snprintf (str, 199, "%u kB", (unsigned int) y2); else snprintf (str, 199, "%lu MB", (unsigned long) (y2 >> 10)); int x = graph->left_margin + ((i - XVALUE_MIN) * graph->x_span) / (XVALUE_MAX - XVALUE_MIN); int y = graph->height - graph->margin + 10; BMP_vline (graph->image, x, y, y-10, RGB_BLACK); BMP_draw_mini_string (graph->image, str, x - 10, y+8, RGB_BLACK); } //---------- // Y axis: // Decide what the tick spacing will be. for (i = 0; i <= max_y; i += y_spacing) { char str[200]; unsigned long whole = i / 100; unsigned long frac = i % 100; snprintf (str, 199, "%lu.%02lu MB/s", whole, frac); int x = graph->left_margin - 10; int y = graph->height - graph->margin - (i * graph->y_span) / max_y; BMP_hline (graph->image, x, x+10, y, RGB_BLACK); BMP_draw_mini_string (graph->image, str, x - 60, y - MINIFONT_HEIGHT/2, RGB_BLACK); } //---------------------------------------- // Draw the data lines. // int x = -1, y = -1; graph->last_x = -1; graph->last_y = -1; for (i = 0; i < graph->data_index; i += 2) { int type = graph->data[i]; long value = graph->data[i+1]; switch (type) { case DATUM_Y: y = value; break; case DATUM_X: x = value; break; case DATUM_COLOR: graph->fg = (unsigned long) value; graph->last_x = -1; graph->last_y = -1; break; } if (x != -1 && y != -1) { BMPGraphing_plot_linear (graph, x, y, max_y); x = y = -1; } } } void BMPGraphing_make (BMPGraph *graph) { if (!graph) return; // XX silent error switch (graph->x_axis_mode) { case MODE_X_AXIS_LOG2: BMPGraphing_make_log2 (graph); break; case MODE_X_AXIS_LINEAR: BMPGraphing_make_linear (graph); break; default: fprintf (stderr, "Invalid graph mode %d.\n", graph->x_axis_mode); break; } } void BMPGraphing_destroy (BMPGraph *graph) { if (!graph) return; if (graph->title) { free (graph->title); graph->title = NULL; } if (graph->image) { BMP_destroy (graph->image); graph->image = NULL; } free (graph); } CPU-X-4.2.0/src/bandwidth/BMPGraphing.h000066400000000000000000000047221403012130000173400ustar00rootroot00000000000000/*============================================================================ BMPGraphing, a library for graphing. Copyright (C) 2005-2017 by Zack T Smith. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *===========================================================================*/ #ifndef _BMPGRAPHING_H #define _BMPGRAPHING_H #ifdef __WIN32__ typedef char bool; enum { true=1, false=0 }; #else #include #endif #include #define BMPGRAPHING_RELEASE "0.3" #define XVALUE_MIN (15) #define XVALUE_MAX (28) enum { DATUM_X=0, DATUM_Y=1, DATUM_COLOR=2, }; typedef uint32_t Coordinate; typedef uint64_t Value; enum { MODE_X_AXIS_LINEAR = 0, MODE_X_AXIS_LOG2 = 1, }; //--------------- // Graphing data. // typedef struct { BMP *image; char *title; unsigned char x_axis_mode; Coordinate width; Coordinate height; Coordinate left_margin; Coordinate margin; Coordinate last_x; Coordinate last_y; Coordinate x_span; Coordinate y_span; Coordinate legend_y; RGB fg; #define MAX_GRAPH_DATA 50000 Value data [MAX_GRAPH_DATA]; int data_index; #define DASHED 0x1000000 // dashed line flag Value max_y; Value min_y; Value min_x; Value max_x; } BMPGraph; extern void BMPGraphing_set_title (BMPGraph*, const char *); extern void BMPGraphing_draw_labels_log2 (BMPGraph*); extern BMPGraph *BMPGraphing_new (int w, int h, int x_axis_mode); extern void BMPGraphing_new_line (BMPGraph *, const char *str, RGB color); extern void BMPGraphing_add_point (BMPGraph *, Value x, Value y); extern void BMPGraphing_plot_log2 (BMPGraph *, Value x, Value y); extern void BMPGraphing_plot_linear (BMPGraph *, Value x, Value y, Value max_amt); extern void BMPGraphing_make (BMPGraph*); extern BMP *BMPGraphing_get_graph (BMPGraph*); extern void BMPGraphing_destroy (BMPGraph*); #endif CPU-X-4.2.0/src/bandwidth/CMakeLists.txt000066400000000000000000000033771403012130000176360ustar00rootroot00000000000000project(bandwidth VERSION "1.5.1" LANGUAGES C ) # Config (bandwidth) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wno-strict-prototypes -Wno-sign-compare") find_program(NASM_FOUND nasm) if(NASM_FOUND) enable_language(ASM_NASM) endif(NASM_FOUND) if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") set(NASM_FLAGS_DEBUG "-gdwarf") endif(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") # Build (bandwidth) if(CMAKE_ASM_NASM_INFOMATION_LOADED) set(BANDWIDTH_FOUND ON PARENT_SCOPE) message(STATUS "Using built-in ${PROJECT_NAME}, version ${PROJECT_VERSION}") if(BITNESS EQUAL 32) set(ROUTINES "routines-x86-32bit") add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ROUTINES}.o COMMAND ${CMAKE_ASM_NASM_COMPILER} ${NASM_FLAGS_DEBUG} -f elf ${ROUTINES}.asm -o ${CMAKE_CURRENT_BINARY_DIR}/${ROUTINES}.o WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) elseif(BITNESS EQUAL 64) set(ROUTINES "routines-x86-64bit") add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${ROUTINES}.o COMMAND ${CMAKE_ASM_NASM_COMPILER} ${NASM_FLAGS_DEBUG} -f elf64 ${ROUTINES}.asm -o ${CMAKE_CURRENT_BINARY_DIR}/${ROUTINES}.o WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) endif() if(LIBCPUID_FOUND AND WITH_LIBCPUID) add_definitions(-DHAS_LIBCPUID=1) else(LIBCPUID_FOUND AND WITH_LIBCPUID) add_definitions(-DHAS_LIBCPUID=0) endif(LIBCPUID_FOUND AND WITH_LIBCPUID) add_library(bandwidth STATIC BMP.c BMPGraphing.c font.c main.c minifont.c libbandwidth.h ${ROUTINES}.o ) target_link_libraries(bandwidth) set(BANDWIDTH_VERSION ${PROJECT_VERSION} PARENT_SCOPE) else(CMAKE_ASM_NASM_INFOMATION_LOADED) set(BANDWIDTH_FOUND OFF PARENT_SCOPE) endif(CMAKE_ASM_NASM_INFOMATION_LOADED) CPU-X-4.2.0/src/bandwidth/COPYING.txt000066400000000000000000000431331403012130000167410ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, 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 Library 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 St, 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 Library General Public License instead of this License. CPU-X-4.2.0/src/bandwidth/README.md000066400000000000000000000013321403012130000163420ustar00rootroot00000000000000# Bandwidth: a memory bandwidth benchmark Distributed under the terms of the [GNU GPL v2](https://raw.githubusercontent.com/X0rg/CPU-X/master/src/bandwidth/COPYING.txt). ### CPU-X NOTE This sofware has been patched to be used within CPU-X. You can find the official web page of this project here: https://zsmith.co/bandwidth.html This is based on bandwidth [1.5.1](https://zsmith.co/archives/bandwidth-1.5.1.tar.gz). This software is used to retrieve following data: * Caches tab * L1 cache speed * L2 cache speed * L3 cache speed * L4 cache speed You can reproduce the output of `bandwidth` command by using `cpu-x --bandwidth`. It will produce a graph named `bandwidth.bmp` in the current working directory. CPU-X-4.2.0/src/bandwidth/README.txt000066400000000000000000000127561403012130000165750ustar00rootroot00000000000000 This is the README file for my program, "bandwidth". Bandwidth is a benchmark that attempts to measure memory bandwidth. In December 2010 (and as of release 0.24), I extended 'bandwidth' to measure network bandwidth as well. Bandwidth is useful because both memory bandwidth and network bandwidth need to be measured to give you a clear idea of what your computer(s) can do. Merely relying on specs does not give a full picture and indeed specs can be misleading. -------------------------------------------------- MEMORY BANDWIDTH My program bandwidth performs sequential and random reads and writes of varying sizes. This permits you to infer from the graph how each type of memory is performing. So for instance when bandwidth writes a 256-byte chunk, you know that because caches are normally write-back, this chunk will reside entirely in the L1 cache. Whereas a 512 kB chunk will mainly reside in L2. You could run a non-artificial benchmark and observe that a general performance number is lower on one machine or higher on anotehr, but that may conceal the cause. So the purpose of this program is to help you pinpoint the cause of a performance problem, or to affirm a general impression about a memory- intensive program. It also tells you the best-case scenario e.g. the maximum bandwidth achieved using sequential, 128-bit memory accesses. Release 1.5: - Fixed AVX bug. Added --nice mode and CPU temperature monitoring (OS/X only). Release 1.4: - Added randomized 256-bit AVX reader & writer tests (Intel64 only). Release 1.3: - Added CSV output. Updated ARM code for Raspberry π 3. Release 1.2: - Added ARM code back in. Release 1.1: - Added larger font. Release 1.0: - Moved graphing into BMPGraphing module. - Finally added LODS benchmarking, which proves how badly lodsb/lodsw/lodsd/lodsq perform. - Added switches --faster and --fastest. Release 0.32: - Improved AVX support. Release 0.31: - Adds cache detection for Intel 32-bit CPUs - Adds a little AVX support. - Fixes vector-to/from-main transfer bugs. Release 0.30 adds cache detection for Intel 64-bit CPUs. Release 0.29 improved graph granularity with more 128-byte tests and removes ARM support. Release 0.28 added a proper test of CPU features e.g. SSE 4.1. Release 0.27 added finer-granularity 128-byte tests. Release 0.26 fixed an issue with AMD processors. Release 0.25 maked network bandwidth bidirectional. Release 0.24 added network bandwidth testing. Release 0.23 added: - Mac OS/X 64-bit support. - Vector-to-vector register transfer test. - Main register to/from vector register transfer test. - Main register byte/word/dword/qword to/from vector register test (pinsr*, pextr* instructions). - Memory copy test using SSE2. - Automatic checks under Linux for SSE2 & SSE4. Release 0.22 added: - Register-to-register transfer test. - Register-to/from-stack transfer tests. Release 0.21 added: - Standardized memory chunks to always be a multiple of 256-byte mini-chunks. - Random memory accesses, in which each 256-byte mini-chunk accessed is accessed in a random order, but also, inside each mini-chunk the 32/64/128 data are accessed pseudo-randomly as well. - Now 'bandwidth' includes chunk sizes that are not powers of 2, which increases data points around the key chunk sizes corresponding to common L1 and L2 cache sizes. - Command-line options: --fast for 0.25 seconds per test. --slow for 20 seconds per test. --title for adding a graph title. Release 0.20 added graphing, with the graph stored in a BMP image file. It also adds the --slow option for more precise runs. Release 0.19 added a second 128-bit SSE writer routine that bypasses the caches, in addition to the one that doesn't. Release 0.18 was my Grand Unified bandwidth benchmark that brought together support for four operating systems: - Linux - Windows Mobile - 32-bit Windows - Mac OS/X 64-bit and two processor architectures: - x86 - Intel64 I've written custom assembly routines for each architecture. Total run time for the default speed, which has 5 seconds per test, is about 35 minutes. -------------------------------------------------- NETWORK BANDWIDTH (beginning with release 0.24) [Update: This feature may no longer be working.] In mid-December 2010, I extended bandwidth to measure network bandwidth, which is useful for testing your home or workplace network setup, and in theory could be used to test machines across the Internet. Release 0.25 adds: - Bidirectional network bandwidth testing. - Specifiable port# (default is 49000). In the graph: - Sent data appears as a solid line. - Received data appears as a dashed line. The network test is pretty simple. It sends chunks of data of varying sizes to whatever computers (nodes) that you specify. Each of those must be running 'bandwidth' in transponder mode. The chunks of data range of 32 kB up to 32 MB. These are actually send as a stream of 1 or more 32 kB sub-chunks. Sample output: output/Network-Linux2.6-Celeron-2.8GHz-32bit-loopback.bmp output/Network-MacOSX32-Corei5-2.4GHz-64bit-loopback.bmp output/Network-Mac64-Linux32.bmp How to start a transponder: ./bandwidth-mac64 --transponder Example invocation of the test leader: ./bandwidth64 --network 192.168.1.104 I've tested network mode on: Linux 32-bit Mac OS/X 32- and 64-bit Win/Cygwin 32-bit. -------------------------------------------------- This program is provided without any warranty and AS-IS. See the file COPYING for details. Zack Smith 1@zsmith.co March 2013 CPU-X-4.2.0/src/bandwidth/defs.h000066400000000000000000000160541403012130000161640ustar00rootroot00000000000000/*============================================================================ bandwidth, a benchmark to estimate memory transfer bandwidth. Copyright (C) 2005-2017 by Zack T Smith. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *===========================================================================*/ //--------------------------------------------------------------------------- // Change log // 0.18 Grand unified version supports x86/intel64/arm, linux/win32/winmo. // 0.19 Now have 128-bit writer that goes to cache AND one that bypasses. // 0.20 Added my bmplib and graphing of output. Also added --slow option. // 0.21 Adds random testing. Min chunk size = 256 B. Allows non-2^n chunks. // 0.22 Adds register-to-register and register-to/from-stack transfers. // 0.23 Adds vector-to-vector and register-to-vector transfers, & Mac support. // 0.24 Adds network bandwidth tests from this PC to specified others. // 0.25 Made network tests bidirectional to test asymmetric networks. // 0.26 Fixes to prevent certain vector instructions being used w/AMD chips. // 0.27 Added 128-byte tests for greater precision. // 0.28 Added use of CPUID. // 0.29 Added more 128-byte tests. // 0.30 Adds cache identification for Intel CPUs in 64-bit mode. // 0.31 Adds cache identification for Intel CPUs in 32-bit mode. // 0.32 Added AVX support. // 1.0 Moved graphing logic into BMPGraphing. Added LODS support. // 1.1 Switched to larger font in graphing module. // 1.2 Re-added ARM 32 support. // 1.3 Added CSV output support. Added 32-bit Raspberry π 3 support. // 1.4 Added 256-bit routines RandomReaderAVX, RandomWriterAVX. // 1.4.1 Added --limit parameter. // 1.4.2 Fixed compiler warnings. // 1.5 Fixed AVX writer bug that gave inaccurate results. Added nice mode. // 1.5.1 Fixed crashing bug. //--------------------------------------------------------------------------- #ifndef _DEFS_H #define _DEFS_H #define RELEASE "1.5.1" #ifdef __WIN32__ typedef char bool; enum { true=1, false=0 }; #else #include #endif #define NETWORK_DEFAULT_PORTNUM (49000) #define NETSIZE_MIN (15) #define NETSIZE_MAX (28) #define NETWORK_CHUNK_SIZE (1< #include "BMP.h" // Mini characters, 8 pixels high. static const char *font_chars_ [] = { "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", " ", " ", "##", "##", "", "", "", "## ##", "## ##", "## ##", " # #", "", "", "", "", "", "", "", "", "", "", "", "", "", " ## ## ", " ## ## ", " ## ## ", " ## ## ", " ##########", " ##########", " ## ## ", " ## ## ", " ##########", " ##########", " ## ## ", " ## ## ", " ## ## ", " ## ## ", "", "", "", " ## ", " ## ", " ########", "## ##", "## ## ", "## ## ", " ###### ", " ## ##", " ## ##", " ## ##", " ## ##", "########", " ## ", " ## ", "", "", "", " ## ##", " # # ##", " ## ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "## ## ", "## # #", "## ## ", "", "", "", " #####", "## ##", "## ##", "## ##", "## ##", "## ## ", " ## ## ##", " #### ##", "## ## ##", "## ####", "## ##", "## ##", " ## ## ##", " ##### ##", "", "", "", "###", "###", " ##", " #", " #", "", "", "", "", "", "", "", "", "", "", "", "", " ##", " ##", " ##", " ##", " ##", "##", "##", "##", "##", "##", "##", " ##", " ##", " ##", " ##", " ##", "", "## ", " ## ", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "##", "", " ", "", "", " ##", "## ## ##", " ## ## ##", " ######", " ####", " ######", " ## ## ##", "## ## ##", " ##", "", "", "", "", "", "", "", "", " ##", " ##", " ##", " ##", "##########", " ##", " ##", " ##", " ##", "", "", "", "", "", " ", " ", "", "", "", "", "", "", "", "", "", "", "###", "###", " ##", " #", " #", " ", "", "", "", "", "", "", "#######", "", "", "", "", "", "", "", "", "", " ", " ", "", "", "", "", "", "", "", "", "", "", "###", "###", "", "", "", " ", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "##", "##", "", "", "", " ##### ", " ## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " ##### ", "", "", "", " ##", " ##", " ###", "#####", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ## ", "", "", "", " #### ", " ## ##", "## ##", " ##", " ##", " ##", " ##", " ##", " ##", " ## ", "## ", "## ", "## ", "########", "", "", "", "########", " ##", " ##", " ##", " ## ", " ## ", " #### ", " ##", " ##", " ##", " ##", "## ##", " ## ##", " #### ", "", "", "", " ##", " ###", " ####", " ## ##", " ## ##", "## ##", "#########", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", "########", "## ", "## ", "## ", "## ", "###", " ######", " ##", " ##", " ##", " ##", "## ##", " ## ##", " #### ", "", "", "", " ##### ", " ## #", "##", "##", "##", "##", "#######", "## ## ", "## ##", "## ##", "## ##", "## ##", " ## ##", " ##### ", "", "", "", "########", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", " ##### ", " ## ##", "## ##", "## ##", "## ##", " ## ##", " ##### ", " ## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " ##### ", "", "", "", " ##### ", " ## ##", "## ##", "## ##", "## ##", " ## ##", " #######", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", " ", " ", "", "", "", "###", "###", "", "", "", "", "###", "###", "", "", "", "", " ", "", "", "", "", "###", "###", "", "", "", "", "###", "###", " ##", " ##", "#", "", " ##", " ##", " ##", " ##", " ##", " ##", "##", "##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", " ", "", "", "", "", "", "############", "############", " ", " ", "############", "############", "", "", "", "", "", "##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "##", "", "", "", " ###### ", " ## ##", "## ##", "## ##", " ##", " ##", " ### ", " ##", " ##", " ##", "", "", " ##", " ##", "", "", "", " ###### ", " ## ##", "## ##", "## ##", "## ####", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ####", "## ", "## ", " ## ##", " #######", "", "", "", " ##", " ####", " ####", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ########", " ## ##", " ## ##", "## ##", "## ##", "## ##", "", "", "", "#######", "## ##", "## ##", "## ##", "## ##", "## ##", "#######", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "#######", "", "", "", " ###### ", " ## ##", "## ##", "## ##", "## ", "## ", "## ", "## ", "## ", "## ", "## ##", "## ##", " ## ##", " ######", "", "", "", "########", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ## ", "########", "", "", "", "##########", "##", "##", "##", "##", "##", "########", "##", "##", "##", "##", "##", "##", "##########", "", "", "", "##########", "##", "##", "##", "##", "##", "########", "##", "##", "##", "##", "##", "##", "##", "", "", "", " ###### ", " ## ##", "## ##", "## ##", "## ", "## ", "## ####", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ###", " ###### #", "", "", "", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "##########", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", " ## ", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "## ##", "## ##", " ## ##", " ####", "", "", "", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "####", "####", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "########", "", "", "", "## ##", "### ###", "#### ####", "## ## ## ##", "## ## ## ##", "## ### ##", "## # ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", "## ##", "### ##", "#### ##", "#### ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ####", "## ####", "## ###", "## ##", "", "", "", " ###### ", " ## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " ######", "", "", "", "########", "## ##", "## ##", "## ##", "## ##", "## ##", "########", "##", "##", "##", "##", "##", "##", "##", "", "", "", " ######", " ## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ## ##", "## ## ##", "## ## ##", "## ###", " ## ##", " ##### ##", "", "", "", "########", "## ##", "## ##", "## ##", "## ##", "## ##", "########", "####", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", " ######", " ## ##", "## ##", "## ##", "##", " ###", " #####", " ##", " ##", " ##", "## ##", "## ##", " ## ##", " ######", "", "", "", "##########", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " ######", "", "", "", "## ##", "## ##", " ## ##", " ## ##", " ## ##", " ## ## ", " ## ## ", " ## ## ", " ## ## ", " ## ## ", " ## ## ", " ### ", " ### ", " # ", "", "", "", "## ## ##", "## ## ##", "## ## ##", " ## #### ##", " ## #### ##", " ## ## ## ##", " ## ## ## ##", " ## ## ## ##", " ## ## ## ##", " ## ## ## ##", " ## ## ## ##", " # # # #", " ### ###", " ### ###", "", "", "", "## ##", "## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ##", " ##", " ## ##", " ## ##", " ## ##", " ## ##", "## ##", "## ##", "", "", "", "## ##", "## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ####", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", "#########", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "#########", "", "", "", "#####", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "#####", "", "##", "##", "##", "##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "", "", "", "#####", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "#####", "", " ##", " ####", " ## ##", " ## ##", "## ##", "## ##", "", "", "", "", "", "", "", "", "", "", "", " ", "", "", "", "", "", "", "", "", "", "", "", "", "########", "", "", "", "####", "####", "##", " ##", " #", "", "", "", "", "", "", "", "", "", "", "", "", " ", "", "", "", " ######", " ## ##", " ##", " ##", " ######", " ## ##", "## ##", "## ##", " ## ##", " ##### ##", "", "", "", "##", "##", "##", "##", "## ####", "### ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "### ##", "## ####", "", "", "", " ", "", "", "", " #####", " ## ##", "## ", "## ", "## ", "## ", "## ", "## ", " ## ##", " #####", "", "", "", " ##", " ##", " ##", " ##", " #### ##", " ## ###", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ###", " #### ##", "", "", "", " ", "", "", "", " #####", " ## ##", "## ##", "## ##", "#########", "##", "##", "##", " ## ##", " ######", "", "", "", " #####", " ##", " ## ", " ## ", "#####", " ## ", " ## ", " ## ", " ## ", " ## ", " ## ", " ## ", " ## ", " ## ", "", "", "", " ", "", "", "", " ##### #", " ## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " #######", " ##", "## ##", " ######", "##", "##", "##", "##", "## ####", "### ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", "##", "##", "", "", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "", "", "", " ##", " ##", " ", " ", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", "###", "##", "##", "##", "##", "## ##", "## ##", "## ## ", "## ## ", "#### ", "#### ", "## ## ", "## ## ", "## ##", "## ##", "", "", "", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "##", "", "", "", " ", "", "", "", "## ### ####", "### ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "## ## ##", "", "", "", " ", "", "", "", "## ####", "### ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "", "", "", " ", "", "", "", " #####", " ## ## ", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ## ", " ##### ", "", "", "", " ", "", "", "", "## ####", "### ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "#######", "##", "##", "##", " ", "", "", "", " #### ##", " ## ###", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " #######", " ##", " ##", " ##", " ", "", "", "", "## ####", "#### ##", "###", "##", "##", "##", "##", "##", "##", "##", "", "", "", " ", "", "", "", " ######", "## ##", "##", "##", " ###", " ###", " ##", " ##", "## ##", " ######", "", "", "", " ##", " ##", " ##", " ##", "######", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ##", " ####", "", "", "", " ", "", "", "", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", "## ##", " ## ##", " ##### #", "", "", "", " ", "", "", "", "## ##", "## ##", "## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " #####", " ###", "", "", "", " ", "", "", "", "## ## ##", "## ## ##", "## ## ##", " ## #### ##", " ## #### ##", " ## #### ##", " ## ## ## ##", " ## ## ## ##", " ##### #####", " ### ###", "", "", "", " ", "", "", "", "## ##", "## ##", " ## ##", " ## ##", " ##", " ##", " ## ##", " ## ##", "## ##", "## ##", "", "", "", " ", "", "", "", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ## ##", " ####", " ###", " ##", " ##", "###", " ", "", "", "", "#########", " ##", " ##", " ##", " ##", " ##", " ## ", " ## ", "## ", "#########", "", "", "", }; const char **get_font_chars () { return font_chars_; } CPU-X-4.2.0/src/bandwidth/font.h000066400000000000000000000020261403012130000162030ustar00rootroot00000000000000 /*============================================================================= bmplib, a simple library to create, modify, and write BMP image files. Copyright (C) 2009-2014 by Zack T Smith. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *============================================================================*/ #ifndef _FONT_H #define _FONT_H extern const char **get_font_chars (void); #endif CPU-X-4.2.0/src/bandwidth/libbandwidth.h000066400000000000000000000033121403012130000176670ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE libbandwidth.h */ #ifndef _LIBBANDWIDTH_H_ #define _LIBBANDWIDTH_H_ #define BANDWIDTH_MODE (opts->output_type == OUT_BANDWIDTH) enum EnTests { SEQ_128_R, SEQ_256_R, RAND_128_R, SEQ_128_CACHE_W, SEQ_256_CACHE_W, RAND_128_CACHE_W, SEQ_128_BYPASS_R, RAND_128_BYPASS_R, SEQ_128_BYPASS_W, SEQ_256_BYPASS_W, RAND_128_BYPASS_W, SEQ_128_C, SEQ_256_C, SEQ_32_LR, SEQ_16_LR, SEQ_8_LR, #ifdef __x86_64__ SEQ_64_R, RAND_64_R, SEQ_64_W, RAND_64_W, SEQ_64_LR, RAND_256_R, RAND_256_W, #else SEQ_32_R, RAND_32_R, SEQ_32_W, RAND_32_W, #endif LASTTEST }; struct Tests { enum EnTests test; char *name; uint32_t color; bool need_flag; bool need_mask; int (*func_ptr)(unsigned long, int, bool); int mode; bool random; }; int bandwidth_main(int argc, char **argv); int bandwidth_cpux(void *p_data); #endif CPU-X-4.2.0/src/bandwidth/main.c000066400000000000000000002230421403012130000161570ustar00rootroot00000000000000/*============================================================================ bandwidth, a benchmark to estimate memory transfer bandwidth. Copyright (C) 2005-2018 by Zack T Smith. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *===========================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include // gethostbyname #include #include #include #define GRAPH_WIDTH 1440 #define GRAPH_HEIGHT 900 #include "defs.h" #include "BMP.h" #include "BMPGraphing.h" #define VREGISTER_COUNT 3333 #ifndef __arm__ #define x86 #endif #define TITLE_MEMORY_NET "Network benchmark results from bandwidth " RELEASE " by Zack Smith, http://zsmith.co" #define TITLE_MEMORY_GRAPH "Memory benchmark results from bandwidth " RELEASE " by Zack Smith, http://zsmith.co" #ifdef __WIN32__ // #include #endif #ifdef __linux__ #include #include #include #endif /* Needed by CPU-X */ #include "../cpu-x.h" #include "libbandwidth.h" #if HAS_LIBCPUID # include #endif #ifdef __x86_64__ #define IS_64BIT #endif static enum { OUTPUT_MODE_GRAPH=1, OUTPUT_MODE_CSV=2, } outputMode; // Mode to be nice and to keep CPU temperature low. static bool nice_mode = false; #define NICE_DURATION (2) #define MAX_CPU_TEMP (50) static int network_port = NETWORK_DEFAULT_PORTNUM; enum { NO_SSE2, // x86 SSE2, SSE2_BYPASS, AVX, AVX_BYPASS, LODSQ, LODSD, LODSW, LODSB, // ARM NEON_64BIT, NEON_128BIT, }; static BMPGraph *graph = NULL; #ifndef __arm__ static bool use_sse2 = true; static bool use_sse4 = true; #else static bool use_sse2 = false; static bool use_sse4 = false; #endif static bool is_intel = false; static bool is_amd = false; static bool limit_below_100MB = false; static FILE *csv_output_file = NULL; static char *csv_file_path = NULL; static uint32_t cpu_has_mmx = 0; static uint32_t cpu_has_sse = 0; static uint32_t cpu_has_sse2 = 0; static uint32_t cpu_has_sse3 = 0; static uint32_t cpu_has_ssse3 = 0; static uint32_t cpu_has_sse4a = 0; static uint32_t cpu_has_sse41 = 0; static uint32_t cpu_has_sse42 = 0; static uint32_t cpu_has_aes = 0; static uint32_t cpu_has_avx = 0; static uint32_t cpu_has_avx2 = 0; static uint32_t cpu_has_64bit = 0; static uint32_t cpu_has_xd = 0; //---------------------------------------- // Parameters for the tests. // static long usec_per_test = 5000000; // 5 seconds per memory test. static int chunk_sizes[] = { #ifdef x86 128, #endif 256, #ifdef x86 384, #endif 512, #ifdef x86 640, #endif 768, #ifdef x86 896, #endif 1024, 1280, 2048, 3072, 4096, 6144, 8192, // Some processors' L1 data caches are only 8kB. 12288, 16384, 20480, 24576, 28672, 32768, // Common L1 data cache size. 34*1024, 36*1024, 40960, 49152, 65536, 131072, // Old L2 cache size. 192 * 1024, 256 * 1024, // Old L2 cache size. 320 * 1024, 384 * 1024, 512 * 1024, // Old L2 cache size. 768 * 1024, 1 << 20, // 1 MB = common L2 cache size. (1024 + 256) * 1024, // 1.25 (1024 + 512) * 1024, // 1.5 (1024 + 768) * 1024, // 1.75 1 << 21, // 2 MB = common L2 cache size. (2048 + 256) * 1024, // 2.25 (2048 + 512) * 1024, // 2.5 (2048 + 768) * 1024, // 2.75 3072 * 1024, // 3 MB = common L2 cache size. 3407872, // 3.25 MB 3 * 1024 * 1024 + 1024 * 512, // 3.5 MB 1 << 22, // 4 MB 5242880, // 5 megs 6291456, // 6 megs (common L2 cache size) 7 * 1024 * 1024, 8 * 1024 * 1024, // Xeon E3's often has 8MB L3 #ifndef __arm__ 9 * 1024 * 1024, 10 * 1024 * 1024, // Xeon E5-2609 has 10MB L3 12 * 1024 * 1024, 14 * 1024 * 1024, 15 * 1024 * 1024, // Xeon E6-2630 has 15MB L3 16 * 1024 * 1024, 20 * 1024 * 1024, // Xeon E5-2690 has 20MB L3 21 * 1024 * 1024, 32 * 1024 * 1024, 48 * 1024 * 1024, 64 * 1024 * 1024, 72 * 1024 * 1024, 96 * 1024 * 1024, 128 * 1024 * 1024, #define TEST_L4 #ifdef TEST_L4 160 * 1024 * 1024, 192 * 1024 * 1024, 224 * 1024 * 1024, 256 * 1024 * 1024, 320 * 1024 * 1024, 512 * 1024 * 1024, #endif #endif 0 }; static double chunk_sizes_log2 [sizeof(chunk_sizes)/sizeof(int)]; //---------------------------------------------------------------------------- // Name: internal // Purpose: Complain and exit. //---------------------------------------------------------------------------- void internal (char *s) { fprintf (stderr, "Internal error: %s\n", s); exit (2); } //---------------------------------------------------------------------------- // Name: error // Purpose: Complain and exit. //---------------------------------------------------------------------------- void error (char *s) { #ifndef __WIN32__ fprintf (stderr, "Error: %s\n", s); exit (1); #else wchar_t tmp [200]; int i; for (i = 0; s[i]; i++) tmp[i] = s[i]; tmp[i] = 0; MessageBoxW (0, tmp, L"Error", 0); ExitProcess (0); #endif } //============================================================================ // Output multiplexor. //============================================================================ void dataBegins (char *title) { if (!outputMode) { internal ("Bad output mode."); } //========== if (outputMode & OUTPUT_MODE_GRAPH) { if (graph) internal ("Graphing already initialized."); graph = BMPGraphing_new (GRAPH_WIDTH, GRAPH_HEIGHT, MODE_X_AXIS_LOG2); BMPGraphing_set_title (graph, title? title : TITLE_MEMORY_GRAPH); } if (outputMode & OUTPUT_MODE_CSV) { if (csv_output_file) internal ("CSV file already initialized."); csv_output_file = fopen (csv_file_path, "wb"); if (!csv_output_file) { error ("Cannot open CSV output file."); } if (title) fprintf (csv_output_file, "%s\n", title); } } void dataBeginSection (const char *name, uint32_t parameter) { if (!outputMode) { internal ("Bad output mode."); } if (!name) { internal ("dataBeginSection: NULL name."); } //========== if (nice_mode) { sleep (NICE_DURATION); #ifdef __APPLE__ #define POPEN_BUFSIZE (256) // Keep CPU temperature below 50 C. // int cpu_temperature = 0; bool done = true; do { FILE *f = popen ("sysctl machdep.xcpm.cpu_thermal_level | sed '\''s/machdep.xcpm.cpu_thermal_level/CPU temperature/'\''", "r"); if (f) { char buffer [POPEN_BUFSIZE] = {0}; if (0 < fread (buffer, 1, POPEN_BUFSIZE-1, f)) { int i; for (i=0; i < POPEN_BUFSIZE && buffer[i]; i++) { if (isdigit (buffer[i])) break; } if (i < POPEN_BUFSIZE) { cpu_temperature = atoi (buffer + i); printf ("CPU temperature is %d C.\n", cpu_temperature); } else { break; } } pclose (f); } else { break; } done = (cpu_temperature < MAX_CPU_TEMP); if (!done) sleep (10); } while (!done); #endif } if (outputMode & OUTPUT_MODE_GRAPH) { if (!graph) internal ("Graphing not initialized."); BMPGraphing_new_line (graph, name, parameter); } if (outputMode & OUTPUT_MODE_CSV) { if (!csv_output_file) internal ("CSV output not initialized."); fprintf (csv_output_file, "%s\n", name); } } void dataEnds (const char *parameter) { if (!outputMode) { internal ("Bad output mode."); } //========== if (outputMode & OUTPUT_MODE_GRAPH) { if (!graph) internal ("Graphing not initialized."); if (!parameter) internal ("dataEnds: NULL name."); BMPGraphing_make (graph); BMP_write (graph->image, parameter); BMPGraphing_destroy (graph); graph= NULL; puts ("Wrote graph to: bandwidth.bmp"); } if (outputMode & OUTPUT_MODE_CSV) { if (!csv_output_file) internal ("CSV output not initialized."); fclose (csv_output_file); printf ("Wrote %s.\n", csv_file_path); } } void dataAddDatum (Value x, Value y) { if (!outputMode) { internal ("Bad output mode."); } //========== if (outputMode & OUTPUT_MODE_GRAPH) { if (!graph) internal ("Graphing not initialized."); BMPGraphing_add_point (graph, x, y); } if (outputMode & OUTPUT_MODE_CSV) { if (!csv_output_file) internal ("CSV output not initialized."); fprintf (csv_output_file, "%lld, %.1Lf\n", (long long)x, (long double)y/10.); fflush (csv_output_file); } } //============================================================================ // Output buffer logic. //============================================================================ void print (const char *s) { if(BANDWIDTH_MODE) printf ("%s",s); } void newline () { if(BANDWIDTH_MODE) puts (""); } void println (char *s) { print (s); newline (); } void print_int (int d) { if(BANDWIDTH_MODE) printf ("%d", d); } void print_uint (unsigned long d) { if(BANDWIDTH_MODE) printf ("%lu", d); } void println_int (int d) { print_int (d); newline (); } void print_result (long double result) { if(BANDWIDTH_MODE) printf ("%.1Lf MB/s", result); } void flush () { fflush (stdout); } void print_size (unsigned long size) { if (size < 1536) { print_int (size); print (" B"); } else if (size < (1<<20)) { print_int (size >> 10); print (" kB"); } else { print_int (size >> 20); switch ((size >> 18) & 3) { case 1: print (".25"); break; case 2: print (".5"); break; case 3: print (".75"); break; } print (" MB"); } } //============================================================================ // Timing logic. //============================================================================ //---------------------------------------------------------------------------- // Name: mytime // Purpose: Reports time in microseconds. //---------------------------------------------------------------------------- unsigned long mytime () { #ifndef __WIN32__ struct timeval tv; struct timezone tz; memset (&tz, 0, sizeof(struct timezone)); gettimeofday (&tv, &tz); return 1000000 * tv.tv_sec + tv.tv_usec; #else return 1000 * GetTickCount (); // accurate enough. #endif } //---------------------------------------------------------------------------- // Name: calculate_result // Purpose: Calculates and prints a result. // Returns: 10 times the number of megabytes per second. //---------------------------------------------------------------------------- int calculate_result (unsigned long chunk_size, long long total_loops, long diff) { if (!diff) error ("Zero time difference."); // printf ("\nIn calculate_result, chunk_size=%ld, total_loops=%lld, diff=%ld\n", chunk_size, total_loops, diff); long double result = (long double) chunk_size; result *= (long double) total_loops; result *= 1000000.; // Convert to microseconds. result /= 1048576.; result /= (long double) diff; print_result (result); return (long) (10.0 * result); } //============================================================================ // Tests. //============================================================================ //---------------------------------------------------------------------------- // Name: do_write // Purpose: Performs write on chunk of memory of specified size. //---------------------------------------------------------------------------- int do_write (unsigned long size, int mode, bool random) { unsigned char *chunk; unsigned char *chunk0; unsigned long loops; unsigned long long total_count=0; #ifdef IS_64BIT unsigned long value = 0x1234567689abcdef; #else unsigned long value = 0x12345678; #endif unsigned long diff=0, t0; unsigned long tmp; unsigned long **chunk_ptrs = NULL; #ifdef x86 if (size & 127) error ("do_write(): chunk size is not multiple of 128."); #else if (size & 255) error ("do_write(): chunk size is not multiple of 256."); #endif //------------------------------------------------- chunk0 = malloc (size+64); chunk = chunk0; if (!chunk) error ("Out of memory"); tmp = (unsigned long) chunk; if (tmp & 31) { tmp -= (tmp & 31); tmp += 32; chunk = (unsigned char*) tmp; } //---------------------------------------- // Set up random pointers to chunks. // if (random) { tmp = size/256; chunk_ptrs = (unsigned long**) malloc (sizeof (unsigned long*) * tmp); if (!chunk_ptrs) error ("Out of memory."); //---------------------------------------- // Store pointers to all chunks into array. // int i; for (i = 0; i < tmp; i++) { chunk_ptrs [i] = (unsigned long*) (chunk + 256 * i); } //---------------------------------------- // Randomize the array of chunk pointers. // int k = 200; while (k--) { for (i = 0; i < tmp; i++) { int j = rand() % tmp; if (i != j) { unsigned long *ptr = chunk_ptrs [i]; chunk_ptrs [i] = chunk_ptrs [j]; chunk_ptrs [j] = ptr; } } } } //------------------------------------------------- if (random) print ("Random write "); else print ("Sequential write "); switch (mode) { case NEON_64BIT: print ("(64-bit), size = "); break; case NEON_128BIT: print ("(128-bit), size = "); break; case SSE2: print ("(128-bit), size = "); break; case AVX: print ("(256-bit), size = "); break; case AVX_BYPASS: print ("bypassing cache (256-bit), size = "); break; case SSE2_BYPASS: print ("bypassing cache (128-bit), size = "); break; default: #ifdef IS_64BIT print ("(64-bit), size = "); #else print ("(32-bit), size = "); #endif } print_size (size); print (", "); loops = (1 << 26) / size;// XX need to adjust for CPU MHz if (loops < 1) loops = 1; t0 = mytime (); while (diff < usec_per_test) { total_count += loops; switch (mode) { #ifdef __arm__ case NEON_64BIT: if (random) RandomWriterVector (chunk_ptrs, size/256, loops, value); break; case NEON_128BIT: if (!random) WriterVector (chunk, size, loops, value); break; #endif #ifdef x86 case SSE2: if (random) RandomWriterSSE2 (chunk_ptrs, size/256, loops, value); else { if (size & 128) WriterSSE2_128bytes (chunk, size, loops, value); else WriterSSE2 (chunk, size, loops, value); } break; case SSE2_BYPASS: if (random) RandomWriterSSE2_bypass (chunk_ptrs, size/256, loops, value); else { if (size & 128) WriterSSE2_128bytes_bypass (chunk, size, loops, value); else WriterSSE2_bypass (chunk, size, loops, value); } break; case AVX: if (!random) { WriterAVX (chunk, size, loops, value); } else { #ifdef IS_64BIT RandomWriterAVX (chunk_ptrs, size/256, loops, value); #endif } break; case AVX_BYPASS: if (!random) { WriterAVX_bypass (chunk, size, loops, value); } break; #endif default: if (random) RandomWriter (chunk_ptrs, size/256, loops, value); else { #ifdef x86 if (size & 128) Writer_128bytes (chunk, size, loops, value); else #endif Writer (chunk, size, loops, value); } } diff = mytime () - t0; } print ("loops = "); print_uint (total_count); print (", "); flush (); int result = calculate_result (size, total_count, diff); newline (); flush (); free ((void*)chunk0); if (chunk_ptrs) free (chunk_ptrs); return result; } //---------------------------------------------------------------------------- // Name: do_read // Purpose: Performs sequential read on chunk of memory of specified size. //---------------------------------------------------------------------------- int do_read (unsigned long size, int mode, bool random) { unsigned long loops; unsigned long long total_count = 0; unsigned long t0, diff=0; unsigned char *chunk; unsigned char *chunk0; unsigned long tmp; unsigned long **chunk_ptrs = NULL; if (size & 127) error ("do_read(): chunk size is not multiple of 128."); //------------------------------------------------- chunk0 = chunk = malloc (size+64); if (!chunk) error ("Out of memory"); memset (chunk, 0, size); tmp = (unsigned long) chunk; if (tmp & 31) { tmp -= (tmp & 31); tmp += 32; chunk = (unsigned char*) tmp; } //---------------------------------------- // Set up random pointers to chunks. // if (random) { int tmp = size/256; chunk_ptrs = (unsigned long**) malloc (sizeof (unsigned long*) * tmp); if (!chunk_ptrs) error ("Out of memory."); //---------------------------------------- // Store pointers to all chunks into array. // int i; for (i = 0; i < tmp; i++) { chunk_ptrs [i] = (unsigned long*) (chunk + 256 * i); } //---------------------------------------- // Randomize the array of chunk pointers. // int k = 200; while (k--) { for (i = 0; i < tmp; i++) { int j = rand() % tmp; if (i != j) { unsigned long *ptr = chunk_ptrs [i]; chunk_ptrs [i] = chunk_ptrs [j]; chunk_ptrs [j] = ptr; } } } } //------------------------------------------------- if (random) print ("Random read "); else print ("Sequential read "); switch (mode) { #ifdef __arm__ case NEON_64BIT: print ("(64-bit), size = "); break; case NEON_128BIT: print ("(128-bit), size = "); break; #endif #ifdef x86 case SSE2: print ("(128-bit), size = "); break; case LODSB: print ("(8-bit LODSB), size = "); break; case LODSW: print ("(16-bit LODSW), size = "); break; case LODSD: print ("(32-bit LODSD), size = "); break; case LODSQ: print ("(64-bit LODSQ), size = "); break; case AVX: print ("(256-bit), size = "); break; case AVX_BYPASS: print ("bypassing cache (256-bit), size = "); break; case SSE2_BYPASS: print ("bypassing cache (128-bit), size = "); break; #endif default: #ifdef IS_64BIT print ("(64-bit), size = "); #else print ("(32-bit), size = "); #endif } print_size (size); print (", "); flush (); loops = (1 << 26) / size; // XX need to adjust for CPU MHz if (loops < 1) loops = 1; t0 = mytime (); while (diff < usec_per_test) { total_count += loops; switch (mode) { #ifdef __arm__ case NEON_64BIT: if (random) RandomReaderVector (chunk_ptrs, size/256, loops); break; case NEON_128BIT: if (!random) ReaderVector (chunk, size, loops); break; #endif #ifdef x86 case SSE2: if (random) RandomReaderSSE2 (chunk_ptrs, size/256, loops); else { if (size & 128) ReaderSSE2_128bytes (chunk, size, loops); else ReaderSSE2 (chunk, size, loops); } break; case SSE2_BYPASS: // No random reader for bypass. // if (random) RandomReaderSSE2_bypass (chunk_ptrs, size/256, loops); else { if (size & 128) ReaderSSE2_128bytes_bypass (chunk, size, loops); else ReaderSSE2_bypass (chunk, size, loops); } break; case AVX: if (!random) { ReaderAVX (chunk, size, loops); } else { #ifdef IS_64BIT RandomReaderAVX (chunk_ptrs, size/256, loops); #endif } break; case LODSB: if (!random) { ReaderLODSB (chunk, size, loops); } break; case LODSW: if (!random) { ReaderLODSW (chunk, size, loops); } break; case LODSD: if (!random) { ReaderLODSD (chunk, size, loops); } break; case LODSQ: if (!random) { ReaderLODSQ (chunk, size, loops); } break; #endif default: if (random) { RandomReader (chunk_ptrs, size/256, loops); } else { #ifdef x86 if (size & 128) Reader_128bytes (chunk, size, loops); else #endif Reader (chunk, size, loops); } } diff = mytime () - t0; } print ("loops = "); print_uint (total_count); print (", "); int result = calculate_result (size, total_count, diff); newline (); flush (); free (chunk0); if (chunk_ptrs) free (chunk_ptrs); return result; } //---------------------------------------------------------------------------- // Name: do_copy // Purpose: Performs sequential memory copy. //---------------------------------------------------------------------------- int do_copy (unsigned long size, int mode) { #ifdef x86 unsigned long loops; unsigned long long total_count = 0; unsigned long t0, diff=0; unsigned char *chunk_src; unsigned char *chunk_dest; unsigned char *chunk_src0; unsigned char *chunk_dest0; unsigned long tmp; if (size & 127) error ("do_copy(): chunk size is not multiple of 128."); //------------------------------------------------- chunk_src0 = chunk_src = malloc (size+64); if (!chunk_src) error ("Out of memory"); chunk_dest0 = chunk_dest = malloc (size+64); if (!chunk_dest) error ("Out of memory"); memset (chunk_src, 100, size); memset (chunk_dest, 200, size); tmp = (unsigned long) chunk_src; if (tmp & 31) { tmp -= (tmp & 31); tmp += 32; chunk_src = (unsigned char*) tmp; } tmp = (unsigned long) chunk_dest; if (tmp & 31) { tmp -= (tmp & 31); tmp += 32; chunk_dest = (unsigned char*) tmp; } //------------------------------------------------- print ("Sequential copy "); if (mode == SSE2) { print ("(128-bit), size = "); } else if (mode == AVX) { print ("(256-bit), size = "); } else { #ifdef IS_64BIT print ("(64-bit), size = "); #else print ("(32-bit), size = "); #endif } print_size (size); print (", "); flush (); loops = (1 << 26) / size; // XX need to adjust for CPU MHz if (loops < 1) loops = 1; t0 = mytime (); while (diff < usec_per_test) { total_count += loops; if (mode == SSE2) { #ifdef IS_64BIT if (size & 128) CopySSE_128bytes (chunk_dest, chunk_src, size, loops); else CopySSE (chunk_dest, chunk_src, size, loops); #else CopySSE (chunk_dest, chunk_src, size, loops); #endif } else if (mode == AVX) { if (!(size & 128)) CopyAVX (chunk_dest, chunk_src, size, loops); } diff = mytime () - t0; } print ("loops = "); print_uint (total_count); print (", "); int result = calculate_result (size, total_count, diff); newline (); flush (); free (chunk_src0); free (chunk_dest0); return result; #else return 0; #endif } int do_copy2 (unsigned long size, int mode, bool unused __attribute__((unused))) { return do_copy(size, mode); } //---------------------------------------------------------------------------- // Name: fb_readwrite // Purpose: Performs sequential read & write tests on framebuffer memory. //---------------------------------------------------------------------------- #if defined(__linux__) && defined(FBIOGET_FSCREENINFO) void fb_readwrite (bool use_sse2) { unsigned long total_count; unsigned long length; unsigned long diff, t0; static struct fb_fix_screeninfo fi; static struct fb_var_screeninfo vi; unsigned long *fb = NULL; int fd; #ifdef IS_64BIT unsigned long value = 0x1234567689abcdef; #else unsigned long value = 0x12345678; #endif //------------------------------------------------- fd = open ("/dev/fb0", O_RDWR); if (fd < 0) fd = open ("/dev/fb/0", O_RDWR); if (fd < 0) { println ("Cannot open framebuffer device."); return; } if (ioctl (fd, FBIOGET_FSCREENINFO, &fi)) { close (fd); println ("Cannot get framebuffer info"); return; } else if (ioctl (fd, FBIOGET_VSCREENINFO, &vi)) { close (fd); println ("Cannot get framebuffer info"); return; } else { if (fi.visual != FB_VISUAL_TRUECOLOR && fi.visual != FB_VISUAL_DIRECTCOLOR ) { close (fd); println ("Need direct/truecolor framebuffer device."); return; } else { unsigned long fblen; print ("Framebuffer resolution: "); print_int (vi.xres); print ("x"); print_int (vi.yres); print (", "); print_int (vi.bits_per_pixel); println (" bpp\n"); fb = (unsigned long*) fi.smem_start; fblen = fi.smem_len; fb = mmap (fb, fblen, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0); if (fb == MAP_FAILED) { close (fd); println ("Cannot access framebuffer memory."); return; } } } //------------------- // Use only the upper half of the display. // length = FB_SIZE; //------------------- // READ // print ("Framebuffer memory sequential read "); flush (); t0 = mytime (); total_count = FBLOOPS_R; #ifdef x86 if (use_sse2) ReaderSSE2 (fb, length, FBLOOPS_R); else #endif Reader (fb, length, FBLOOPS_R); diff = mytime () - t0; calculate_result (length, total_count, diff); newline (); //------------------- // WRITE // print ("Framebuffer memory sequential write "); flush (); t0 = mytime (); total_count = FBLOOPS_W; #ifdef x86 if (use_sse2) WriterSSE2_bypass (fb, length, FBLOOPS_W, value); else #endif Writer (fb, length, FBLOOPS_W, value); diff = mytime () - t0; calculate_result (length, total_count, diff); newline (); } #endif //---------------------------------------------------------------------------- // Name: register_test // Purpose: Determines bandwidth of register-to-register transfers. //---------------------------------------------------------------------------- void register_test () { long long total_count = 0; unsigned long t0; unsigned long diff = 0; //-------------------------------------- #ifdef IS_64BIT print ("Main register to main register transfers (64-bit) "); #else print ("Main register to main register transfers (32-bit) "); #endif flush (); #define REGISTER_COUNT 10000 t0 = mytime (); while (diff < usec_per_test) { RegisterToRegister (REGISTER_COUNT); total_count += REGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); //-------------------------------------- #ifdef x86 #ifdef IS_64BIT print ("Main register to vector register transfers (64-bit) "); #else print ("Main register to vector register transfers (32-bit) "); #endif flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { RegisterToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); //-------------------------------------- #ifdef IS_64BIT print ("Vector register to main register transfers (64-bit) "); #else print ("Vector register to main register transfers (32-bit) "); #endif flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { VectorToRegister (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); #endif //-------------------------------------- print ("Vector register to vector register transfers (128-bit) "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { VectorToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); #ifdef x86 //-------------------------------------- if (cpu_has_avx) { print ("Vector register to vector register transfers (256-bit) "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { VectorToVectorAVX (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } //-------------------------------------- if (use_sse4) { print ("Vector 8-bit datum to main register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Vector8ToRegister (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (64, total_count, diff); newline (); flush (); } //-------------------------------------- print ("Vector 16-bit datum to main register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Vector16ToRegister (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (128, total_count, diff); newline (); flush (); //-------------------------------------- if (use_sse4) { print ("Vector 32-bit datum to main register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Vector32ToRegister (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } //-------------------------------------- if (use_sse4) { print ("Vector 64-bit datum to main register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Vector64ToRegister (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } //-------------------------------------- if (use_sse4) { print ("Main register 8-bit datum to vector register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Register8ToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (64, total_count, diff); newline (); flush (); } //-------------------------------------- print ("Main register 16-bit datum to vector register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Register16ToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (128, total_count, diff); newline (); flush (); //-------------------------------------- if (use_sse4) { print ("Main register 32-bit datum to vector register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Register32ToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } //-------------------------------------- if (use_sse4) { print ("Main register 64-bit datum to vector register transfers "); flush (); t0 = mytime (); diff = 0; total_count = 0; while (diff < usec_per_test) { Register64ToVector (VREGISTER_COUNT); total_count += VREGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } #endif } //---------------------------------------------------------------------------- // Name: stack_test // Purpose: Determines bandwidth of stack-to/from-register transfers. //---------------------------------------------------------------------------- void stack_test () { long long total_count = 0; unsigned long t0; unsigned long diff = 0; #ifdef IS_64BIT print ("Stack-to-register transfers (64-bit) "); #else print ("Stack-to-register transfers (32-bit) "); #endif flush (); //-------------------------------------- diff = 0; total_count = 0; t0 = mytime (); while (diff < usec_per_test) { StackReader (REGISTER_COUNT); total_count += REGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); #ifdef IS_64BIT print ("Register-to-stack transfers (64-bit) "); #else print ("Register-to-stack transfers (32-bit) "); #endif flush (); //-------------------------------------- diff = 0; total_count = 0; t0 = mytime (); while (diff < usec_per_test) { StackWriter (REGISTER_COUNT); total_count += REGISTER_COUNT; diff = mytime () - t0; } calculate_result (256, total_count, diff); newline (); flush (); } //---------------------------------------------------------------------------- // Name: library_test // Purpose: Performs C library tests (memset, memcpy). //---------------------------------------------------------------------------- void library_test () { char *a1, *a2; unsigned long t, t0; int i; #define NT_SIZE (64*1024*1024) #define NT_SIZE2 (100) a1 = malloc (NT_SIZE); if (!a1) error ("Out of memory"); a2 = malloc (NT_SIZE); if (!a2) error ("Out of memory"); //-------------------------------------- t0 = mytime (); for (i=0; ih_addr_list); int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(host_ip); addr.sin_port = htons(network_port); if (connect (sock, (struct sockaddr*) &addr, sizeof (struct sockaddr))) { // perror ("connect"); close (sock); return false; } //------------------------------------ // Start stopwatch just before the send. // It will be stopped on receipt of // the response. // unsigned long t0 = mytime (); //------------------------------------ // Put # of chunks in the chunk. // Send all of our data. // sprintf (chunk, "%lu\n", n_chunks); int i; for (i = 0; i < n_chunks; i++) send (sock, chunk, chunk_size, 0); #if 0 //------------------------------------ // Set nonblocking mode. // int opt = 1; ioctl (sock, FIONBIO, &opt); #endif unsigned long t1 = mytime (); //------------------------------------ // Read the response. // int amount = recv (sock, chunk, chunk_size, 0); if (amount < 16) { close (sock); return false; } unsigned long duration_send = mytime() - t0; //------------------------------------ // Validate the response, which // contains the transponder's // perceived read duration. This value // may be as little as half our number. // unsigned long duration2 = -1; if (strncmp ("OK: ", chunk, 4)) { close (sock); return false; } if (1 != sscanf (4+chunk, "%lu", &duration2)) { close (sock); return false; } unsigned long remaining = chunk_size * n_chunks - amount; while (remaining > 0) { int amount = recv (sock, chunk, chunk_size, 0); if (amount <= 0) { perror ("recv"); close (sock); return false; } remaining -= amount; } unsigned long duration_recv = mytime () - t1; *duration_send_return = duration_send; *duration_recv_return = duration_recv; close (sock); return true; } //---------------------------------------------------------------------------- // Name: ip_to_str //---------------------------------------------------------------------------- void ip_to_str (unsigned long addr, char *str) { if (!str) return; unsigned short a = 0xff & addr; unsigned short b = 0xff & (addr >> 8); unsigned short c = 0xff & (addr >> 16); unsigned short d = 0xff & (addr >> 24); sprintf (str, "%u.%u.%u.%u", a,b,c,d); } //---------------------------------------------------------------------------- // Name: network_transponder // Purpose: Act as a transponder, receiving chunks of data and sending // back an acknowledgement once the enture chunk is read. // Returns: False if a problem occurs setting up the network socket. //---------------------------------------------------------------------------- bool network_transponder () { struct sockaddr_in sin, from; //------------------------------ // Get listening socket for port. // Then listen on given port#. // sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(network_port); int listensock; if ((listensock = socket (AF_INET, SOCK_STREAM, 0)) < 0) { perror ("socket"); return false; } if (bind (listensock, (struct sockaddr*) &sin, sizeof(sin)) < 0) { perror ("bind"); close (listensock); return false; } if (listen (listensock, 500) < 0) { perror ("listen"); close (listensock); return false; } bool done = false; while (!done) { //---------------------------------------- // Wait for a client to contact us. // socklen_t len = sizeof (struct sockaddr); int sock = accept (listensock, (struct sockaddr*) &from, &len); if (sock < 0) { perror ("accept"); close (listensock); return false; } //---------------------------------------- // Clockwatch starts when we accept the // connection. // unsigned long t0 = mytime (); if (len != sizeof (struct sockaddr_in)) { close (sock); close (listensock); return false; } #if 0 unsigned long ipaddr = from.sin_addr.s_addr; char ipstring[30]; ip_to_str (ipaddr, ipstring); fprintf (stderr, "Incoming connection from %s\n", ipstring); #endif //---------------------------------------- // Read the first chunk only, in order to // get the # of bytes that will be sent. // char chunk [NETWORK_CHUNK_SIZE+1]; long n_chunks = 0; int amount_read = read (sock, chunk, NETWORK_CHUNK_SIZE); chunk [amount_read] = 0; if (1 != sscanf (chunk, "%ld", &n_chunks)) { close (sock); close (listensock); return false; } //---------------------------------------- // If the leader sends us a chunk count of // -99, this indicates that we should exit. // if (n_chunks == -99) { close (sock); close (listensock); return true; } // printf ("Reading %lu chunks of %d bytes...\n", n_chunks, NETWORK_CHUNK_SIZE); unsigned long long remaining = n_chunks; remaining *= NETWORK_CHUNK_SIZE; // printf ("remaining="); dump_hex64(remaining); puts(""); remaining -= amount_read; while (remaining > 0) { amount_read = read (sock, chunk, NETWORK_CHUNK_SIZE); remaining -= amount_read; if (amount_read < 0) { perror ("read"); break; } else if (!amount_read) break; } unsigned long duration = mytime() - t0; //------------------------------------ // Send response of same size. // sprintf (chunk, "OK: %lu\n", duration); chunk[14] = '\n'; //------------------------------------ // Send all of our data. // int i; for (i = 0; i < n_chunks; i++) send (sock, chunk, NETWORK_CHUNK_SIZE, 0); close (sock); } return true; } //---------------------------------------------------------------------------- // Name: network_test //---------------------------------------------------------------------------- bool network_test (char **destinations, int n_destinations) { int i; //---------------------------------------- // The memory chunk starts with a 12-byte // length of the overall send size. // The memory chunk will have a list of // the destinations in it. // In future, there will be a mechanism // for testing bandwidth between all nodes, // not just the leader & each of the // transponders. // char chunk [NETWORK_CHUNK_SIZE]; memset (chunk, 0, NETWORK_CHUNK_SIZE); sprintf (chunk, "000000000000\n%d\n", n_destinations); for (i = 0; i < n_destinations; i++) { char *s = destinations [i]; int chunk_len = strlen (chunk); int len = strlen (s); if (len + chunk_len < NETWORK_CHUNK_SIZE-1) { //---------------------------------------- // "transp" indicates that the given node // has not yet been a leader. // In future, "done" will indicate it has. // sprintf (chunk + chunk_len, "%s %s\n", s, "transp"); } } static unsigned long colors [] = { RGB_RED, RGB_GREEN, RGB_BLUE, RGB_ORANGE, RGB_PURPLE, RGB_BLACK, RGB_CORAL, RGB_CYAN, RGB_NAVYBLUE, RGB_BRASS, RGB_DARKORANGE, RGB_DARKGREEN, RGB_SALMON, RGB_MAGENTA, RGB_LEMONYELLOW, RGB_ROYALBLUE, RGB_DODGERBLUE, RGB_TURQUOISE, RGB_CADETBLUE, RGB_CHARTREUSE, RGB_DARKOLIVEGREEN, RGB_VIOLET, RGB_KHAKI, RGB_DARKKHAKI, RGB_GOLDENROD }; #define NCOLORS (sizeof(colors)/sizeof(unsigned long)) //---------------------------------------- // For each destination, run the test. // for (i = 0; i < n_destinations; i++) { bool problem = false; char *hostname = destinations[i]; printf ("Bandwidth sending to %s:\n", hostname); char title [PATH_MAX]; sprintf (title, "%s send (solid)", hostname); BMPGraphing_new_line (graph, title, i < NCOLORS? colors[i] : RGB_GRAY); //---------------------------------------- // Cache the receive durations for later. // unsigned long recv_rates [NETSIZE_MAX]; int recv_ix = 0; //---------------------------------------- // Send data of increasing sizes. // int j = NETSIZE_MIN; int n_runs = 64; while (!problem && j <= NETSIZE_MAX) { unsigned long chunk_count = 1 << (j-NETSIZE_MIN); unsigned long long amt_to_send = chunk_count; amt_to_send *= NETWORK_CHUNK_SIZE; if (!amt_to_send) // unlikely break; //---------------------------------------- // Send the data; do this n_runs times. // unsigned long long total_duration_send = 0; unsigned long long total_duration_recv = 0; int k = n_runs; while (k--) { long duration_send, duration_recv; if (! network_test_core (hostname, chunk, NETWORK_CHUNK_SIZE, chunk_count, &duration_send, &duration_recv)) { problem = true; fprintf (stderr, "\nCan't connect to %s\n", hostname); break; } total_duration_send += duration_send; total_duration_recv += duration_recv; } if (problem) break; total_duration_send += n_runs/2; // Round up total_duration_send /= n_runs; // Get average long duration = (long) total_duration_send; total_duration_recv += n_runs/2; // Round up total_duration_recv /= n_runs; // Get average unsigned long amt_in_kb = amt_to_send / 1024; unsigned long amt_in_mb = amt_to_send / 1048576; if (!amt_in_mb) { printf ("\r\tChunk %lu kB x %d: \t", amt_in_kb, n_runs); } else { printf ("\r\tChunk %lu MB x %d: \t", amt_in_mb, n_runs); } //------------------------------ // Calculate send rate in MB/sec. // // Get total # bytes. unsigned long long tmp = NETWORK_CHUNK_SIZE; tmp *= chunk_count; // Get total bytes per second. tmp *= 1000000; tmp /= duration; // Bytes to megabytes. tmp /= 1000; tmp /= 10; unsigned long whole = tmp / 100; unsigned long frac = tmp % 100; printf ("%lu.%02lu MB/s (sent)\t", whole, frac); fflush (stdout); dataAddDatum (amt_in_kb, tmp); //------------------------------ // Calculate recv rate in MB/sec. // // Get total # bytes. tmp = NETWORK_CHUNK_SIZE; tmp *= chunk_count; // Get total bytes per second. tmp *= 1000000; tmp /= total_duration_recv; // Bytes to megabytes. tmp /= 1000; tmp /= 10; whole = tmp / 100; frac = tmp % 100; printf ("%lu.%02lu MB/s (received)\n", whole, frac); recv_rates [recv_ix++] = tmp; j++; n_runs >>= 1; if (!n_runs) n_runs = 1; } //---------------------------------------- // Now add the line for the receive rates. // sprintf (title, "%s receive (dashed)", hostname); BMPGraphing_new_line (graph, title, DASHED | (i < NCOLORS? colors[i] : RGB_GRAY)); for (j = NETSIZE_MIN; j <= NETSIZE_MAX; j++) { unsigned long chunk_count = 1 << (j-NETSIZE_MIN); unsigned long long amt_to_send = chunk_count; amt_to_send *= NETWORK_CHUNK_SIZE; unsigned long amt_in_kb = amt_to_send / 1024; // printf ("amt_in_kb=%ld\n",amt_in_kb); dataAddDatum (amt_in_kb, recv_rates[j-NETSIZE_MIN]); } newline (); } return true; } //---------------------------------------------------------------------------- // Name: usage //---------------------------------------------------------------------------- void usage () { printf ("Usage: bandwidth [--slow] [--fast] [--faster] [--fastest] [--limit] [--title string] [--csv file] [--nice]\n"); //printf ("Usage for starting network tests: bandwidth --network []\n"); //printf ("Usage for receiving network tests: bandwidth --transponder [--port ]\n"); exit (0); } //---------------------------------------------------------------------------- // Name: main //---------------------------------------------------------------------------- int bandwidth_main (int argc, char **argv) { int i, chunk_size; outputMode = OUTPUT_MODE_GRAPH; --argc; ++argv; bool network_mode = false; bool network_leader = false; // false => transponder // int network_destinations_size = 0; int n_network_destinations = 0; char **network_destinations = NULL; char graph_title [512] = {0}; i = 0; while (i < argc) { char *s = argv [i++]; #if NETWORK_MODE // unsure if it still works if (!strcmp ("--network", s)) { network_mode = true; network_leader = true; network_destinations_size = 20; network_destinations = (char**) malloc (network_destinations_size * sizeof (char*)); } else if (!strcmp ("--transponder", s)) { network_mode = true; } else if (!strcmp ("--port", s)) { if (i != argc) network_port = atoi (argv[i++]); } else #endif if (!strcmp ("--nice", s)) { nice_mode = true; } else if (!strcmp ("--slow", s)) { usec_per_test=20000000; // 20 seconds per test. } else if (!strcmp ("--limit", s)) { limit_below_100MB= true; } else if (!strcmp ("--fast", s)) { usec_per_test = 500000; // 0.5 seconds per test. } else if (!strcmp ("--faster", s)) { usec_per_test = 50000; // 0.05 seconds per test. } else if (!strcmp ("--fastest", s)) { usec_per_test = 5000; // 0.005 seconds per test. } else if (!strcmp ("--nosse2", s)) { use_sse2 = false; use_sse4 = false; } else if (!strcmp ("--nosse4", s)) { use_sse4 = false; } else if (!strcmp ("--help", s)) { usage (); } else if (!strcmp ("--nograph", s)) { outputMode &= ~OUTPUT_MODE_GRAPH; } else if (!strcmp ("--csv", s) && i != argc) { outputMode |= OUTPUT_MODE_CSV; if (i < argc) csv_file_path = strdup (argv[i++]); else usage (); } else if (!strcmp ("--title", s) && i != argc) { snprintf (graph_title, 511, "%s", argv[i++]); } else { if ('-' == *s) usage (); } } for (i = 0; chunk_sizes[i] && i < sizeof(chunk_sizes)/sizeof(int); i++) { chunk_sizes_log2[i] = log2 (chunk_sizes[i]); } printf ("This is bandwidth version %s.\n", RELEASE); printf ("Copyright (C) 2005-2017 by Zack T Smith.\n\n"); printf ("This software is covered by the GNU General Public License.\n"); printf ("It is provided AS-IS, use at your own risk.\n"); printf ("See the file COPYING for more information.\n\n"); fflush (stdout); //---------------------------------------- // If network mode selected, enter it now. // Currently cannot combine memory tests // & network tests. // if (network_mode) { if (network_leader) { graph = BMPGraphing_new (GRAPH_WIDTH, GRAPH_HEIGHT, MODE_X_AXIS_LINEAR); strcpy (graph_title, TITLE_MEMORY_NET); BMPGraphing_set_title (graph, graph_title); network_test (network_destinations, n_network_destinations); BMPGraphing_make (graph); BMP_write (graph->image, "network_bandwidth.bmp"); #if defined(__linux__) || defined(__CYGWIN__) || defined(__APPLE__) puts ("Wrote graph to network_bandwidth.bmp."); newline (); puts ("Done."); #endif BMPGraphing_destroy (graph); } else { network_transponder (); } return 0; } #ifdef x86 uint32_t ecx = get_cpuid1_ecx (); uint32_t edx = get_cpuid1_edx (); cpu_has_mmx = edx & CPUID_EDX_MMX; cpu_has_sse = edx & CPUID_EDX_SSE; cpu_has_sse2 = edx & CPUID_EDX_SSE2; cpu_has_sse3 = ecx & CPUID_ECX_SSE3; cpu_has_ssse3 = ecx & CPUID_ECX_SSSE3; cpu_has_sse41 = ecx & CPUID_ECX_SSE41; cpu_has_sse42 = ecx & CPUID_ECX_SSE42; cpu_has_aes = ecx & CPUID_ECX_AES; cpu_has_avx = ecx & CPUID_ECX_AVX; cpu_has_avx2 = 0; if (cpu_has_avx) { cpu_has_avx2 = get_cpuid7_ebx (); cpu_has_avx2 &= CPUID_EBX_AVX2; } use_sse2 = true; use_sse4 = true; cpu_has_sse4a = 0; cpu_has_64bit = 0; cpu_has_xd = 0; static char family [17]; get_cpuid_family (family); family [16] = 0; printf ("CPU family: %s\n", family); uint32_t ecx2 = get_cpuid_80000001_ecx (); uint32_t edx2 = get_cpuid_80000001_edx (); if (!strcmp ("AuthenticAMD", family)) { is_amd = true; cpu_has_sse4a = ecx2 & CPUID_ECX_SSE4A; } else if (!strcmp ("GenuineIntel", family)) { is_intel = true; } cpu_has_xd = edx2 & CPUID_EDX_XD; cpu_has_64bit = edx2 & CPUID_EDX_INTEL64; printf ("CPU features: "); if (cpu_has_mmx) printf ("MMX "); if (cpu_has_sse) printf ("SSE "); if (cpu_has_sse2) printf ("SSE2 "); if (cpu_has_sse3) printf ("SSE3 "); if (cpu_has_ssse3) printf ("SSSE3 "); if (cpu_has_sse4a) printf ("SSE4A "); if (cpu_has_sse41) printf ("SSE4.1 "); if (cpu_has_sse42) printf ("SSE4.2 "); if (cpu_has_aes) printf ("AES "); if (cpu_has_avx) printf ("AVX "); if (cpu_has_avx2) printf ("AVX2 "); if (cpu_has_xd) printf ("XD "); if (cpu_has_64bit) { if (!is_amd) printf ("Intel64 "); else printf ("LongMode "); } puts ("\n"); if (is_intel) { uint32_t cache_info[4]; i = 0; while (1) { get_cpuid_cache_info (cache_info, i); if (!(cache_info[0] & 31)) break; #if 0 printf ("Cache info %d = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", i, cache_info [0], cache_info [1], cache_info [2], cache_info [3]); #endif printf ("Cache %d: ", i); switch ((cache_info[0] >> 5) & 7) { case 1: printf ("L1 "); break; case 2: printf ("L2 "); break; case 3: printf ("L3 "); break; } switch (cache_info[0] & 31) { case 1: printf ("data cache, "); break; case 2: printf ("instruction cache, "); break; case 3: printf ("unified cache, "); break; } uint32_t n_ways = 1 + (cache_info[1] >> 22); uint32_t line_size = 1 + (cache_info[1] & 2047); uint32_t n_sets = 1 + cache_info[2]; printf ("line size %d, ", line_size); printf ("%2d-way%s, ", n_ways, n_ways>1 ? "s" : ""); printf ("%5d sets, ", n_sets); unsigned size = (n_ways * line_size * n_sets) >> 10; printf ("size %dk ", size); newline (); i++; } } if (!cpu_has_sse41) use_sse4 = false; if (!cpu_has_sse2) use_sse2 = false; newline (); #endif println ("Notation: B = byte, kB = 1024 B, MB = 1048576 B."); flush (); //------------------------------------------------------------ // Attempt to obtain information about the CPU. // #ifdef __linux__ struct stat st; if (!stat ("/proc/cpuinfo", &st)) { #define TMPFILE "/tmp/bandw_tmp" unlink (TMPFILE); if (-1 == system ("grep MHz /proc/cpuinfo | uniq | sed \"s/[\\t\\n: a-zA-Z]//g\" > "TMPFILE)) perror ("system"); FILE *f = fopen (TMPFILE, "r"); if (f) { float cpu_speed = 0.0; if (1 == fscanf (f, "%g", &cpu_speed)) { newline (); printf ("CPU speed is %g MHz.\n", cpu_speed); } fclose (f); } } else { printf ("CPU information is not available (/proc/cpuinfo).\n"); } fflush (stdout); #endif unsigned long chunk_limit = limit_below_100MB ? 100 << 20 : 1<<31; dataBegins (graph_title); //------------------------------------------------------------ // Sequential non-vector reads. // newline (); #ifdef IS_64BIT dataBeginSection ( "Sequential 64-bit reads", RGB_BLUE); #else dataBeginSection ( "Sequential 32-bit reads", RGB_BLUE); #endif i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, NO_SSE2, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // Random non-vector reads. // newline (); #ifdef IS_64BIT dataBeginSection ( "Random 64-bit reads", RGB_CYAN); #else dataBeginSection ( "Random 32-bit reads", RGB_CYAN); #endif srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_read (chunk_size, NO_SSE2, true); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // Sequential non-vector writes. // #ifdef IS_64BIT dataBeginSection ( "Sequential 64-bit writes", RGB_DARKGREEN); #else dataBeginSection ( "Sequential 32-bit writes", RGB_DARKGREEN); #endif newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_write (chunk_size, NO_SSE2, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // Random non-vector writes. // #ifdef IS_64BIT dataBeginSection ( "Random 64-bit writes", RGB_GREEN); #else dataBeginSection ( "Random 32-bit writes", RGB_GREEN); #endif newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, NO_SSE2, true); dataAddDatum (chunk_size, amount); } } #ifdef __arm__ //------------------------------------------------------------ // NEON 128 bit sequential reads. // dataBeginSection ("Sequential 128-bit reads", RGB_RED); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, NEON_128BIT, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // NEON 128 bit sequential writes. // dataBeginSection ("Sequential 128-bit writes", 0xA04040); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_write (chunk_size, NEON_128BIT, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // NEON 64bit random writes. // dataBeginSection ( "Random 64-bit writes", RGB_NAVYBLUE); newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_write (chunk_size, NEON_64BIT, true); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // NEON 64bit random reads. // dataBeginSection ( "Random 64-bit reads", RGB_MAROON); newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, NEON_64BIT, true); dataAddDatum (chunk_size, amount); } #endif #ifdef x86 //------------------------------------------------------------ // SSE2 sequential reads. // if (use_sse2) { dataBeginSection ("Sequential 128-bit reads", RGB_RED); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, SSE2, false); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // AVX sequential reads. // if (cpu_has_avx) { dataBeginSection ( "Sequential 256-bit reads", RGB_TURQUOISE); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_read (chunk_size, AVX, false); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // AVX random reads. // #ifdef IS_64BIT if (cpu_has_avx) { dataBeginSection ( "Random 256-bit reads", RGB_BROWN ); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_read (chunk_size, AVX, true); dataAddDatum (chunk_size, amount); } } } #endif //------------------------------------------------------------ // SSE2 random reads. // if (use_sse2) { dataBeginSection ( "Random 128-bit reads", RGB_MAROON); newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_read (chunk_size, SSE2, true); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // SSE2 sequential writes that do not bypass the caches. // if (use_sse2) { dataBeginSection ( "Sequential 128-bit cache writes", RGB_PURPLE); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_write (chunk_size, SSE2, false); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // AVX sequential writes that do not bypass the caches. // if (cpu_has_avx) { dataBeginSection ( "Sequential 256-bit cache writes", RGB_PINK); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, AVX, false); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // AVX randomized writes that do not bypass the caches. // #ifdef IS_64BIT if (cpu_has_avx) { dataBeginSection ( "Random 256-bit cache writes", RGB_RED); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, AVX, true); dataAddDatum (chunk_size, amount); } } } #endif //------------------------------------------------------------ // SSE2 random writes that do not bypass the caches. // if (use_sse2) { dataBeginSection ( "Random 128-bit cache writes", RGB_NAVYBLUE); newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, SSE2, true); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // SSE4 sequential reads that do bypass the caches. // if (use_sse4) { dataBeginSection ( "Sequential 128-bit non-temporal reads", 0xA04040); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, SSE2_BYPASS, false); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // SSE4 random reads that do bypass the caches. // if (use_sse4) { dataBeginSection ( "Random 128-bit non-temporal reads", 0x301934 /* dark purple */); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_read (chunk_size, SSE2_BYPASS, true); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // SSE4 sequential writes that do bypass the caches. // if (use_sse4) { dataBeginSection ( "Sequential 128-bit non-temporal writes", RGB_DARKORANGE); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_write (chunk_size, SSE2_BYPASS, false); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // AVX sequential writes that do bypass the caches. // if (cpu_has_avx) { dataBeginSection ( "Sequential 256-bit non-temporal writes", RGB_DARKOLIVEGREEN); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, AVX_BYPASS, false); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // SSE4 random writes that bypass the caches. // if (use_sse4) { dataBeginSection ( "Random 128-bit non-temporal writes", RGB_LEMONYELLOW); newline (); srand (time (NULL)); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_write (chunk_size, SSE2_BYPASS, true); dataAddDatum (chunk_size, amount); } } } //------------------------------------------------------------ // SSE2 sequential copy. // if (use_sse2) { dataBeginSection ( "Sequential 128-bit copy", 0x8f8844); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_copy (chunk_size, SSE2); dataAddDatum (chunk_size, amount); } } //------------------------------------------------------------ // AVX sequential copy. // if (cpu_has_avx) { dataBeginSection ( "Sequential 256-bit copy", RGB_CHARTREUSE); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { if (!(chunk_size & 128)) { int amount = do_copy (chunk_size, AVX); dataAddDatum (chunk_size, amount); } } } #ifdef DOING_LODS #ifdef IS_64BIT //------------------------------------------------------------ // LODSQ 64-bit sequential reads. // dataBeginSection ( "Sequential 64-bit LODSQ reads", RGB_GRAY6); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, LODSQ, false); dataAddDatum (chunk_size, amount); } #endif //------------------------------------------------------------ // LODSD 32-bit sequential reads. // dataBeginSection ( "Sequential 32-bit LODSD reads", RGB_GRAY8); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, LODSD, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // LODSW 16-bit sequential reads. // dataBeginSection ( "Sequential 16-bit LODSW reads", RGB_GRAY10); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, LODSW, false); dataAddDatum (chunk_size, amount); } //------------------------------------------------------------ // LODSB 64-bit sequential reads. // dataBeginSection ( "Sequential 8-bit LODSB reads", RGB_GRAY12); newline (); i = 0; while ((chunk_size = chunk_sizes [i++]) && chunk_size < chunk_limit) { int amount = do_read (chunk_size, LODSB, false); dataAddDatum (chunk_size, amount); } #endif // lods #endif // x86 //------------------------------------------------------------ // Register to register. // newline (); register_test (); //------------------------------------------------------------ // Stack to/from register. // newline (); stack_test (); #ifndef __arm__ //------------------------------------------------------------ // Register vs stack. // newline (); time_t t0 = mytime (); #ifdef IS_64BIT #define N_INC_OUTER_LOOPS 65537L #define N_INC_INNER_LOOPS 32767L #else #define N_INC_OUTER_LOOPS 9997L #define N_INC_INNER_LOOPS 3337L #endif for (i=0; i 0) { long double d = N_INC_OUTER_LOOPS * 32; d *= N_INC_INNER_LOOPS; d /= diff; d *= 1000000; // usec->sec d /= 1000000000; // billions/sec #ifdef IS_64BIT printf ("64-bit register increments per second: %.2Lf billion\n", d); #else printf ("32-bit register increments per second: %.2Lf billion\n", d); #endif } t0 = mytime (); for (i=0; i < N_INC_INNER_LOOPS; i++) { IncrementStack (N_INC_INNER_LOOPS); } diff = mytime () - t0; if (diff > 0) { long double d = N_INC_OUTER_LOOPS * 32; d *= N_INC_INNER_LOOPS; d /= diff; d *= 1000000; // usec->sec d /= 1000000000; // billions/sec #ifdef IS_64BIT printf ("64-bit stack value increments per second: %.2Lf billion\n", d); #else printf ("32-bit stack value increments per second: %.2Lf billion\n", d); #endif } #endif //------------------------------------------------------------ // C library performance. // newline (); library_test (); //------------------------------------------------------------ // Framebuffer read & write. // #if defined(__linux__) && defined(FBIOGET_FSCREENINFO) newline (); fb_readwrite (true); #endif flush (); newline (); dataEnds ("bandwidth.bmp"); newline (); puts ("Done."); return 0; } int bandwidth_cpux(void *p_data) { int i, chunk_size; outputMode = OUTPUT_MODE_GRAPH; usec_per_test = 5000; char graph_title [512] = {0}; /* Needed by CPU-X */ int count = 0; uint8_t cache_level = 0; double total_amount = 0; Labels *data = p_data; BandwidthData *w_data = data->w_data; for (i = 0; chunk_sizes[i] && i < sizeof(chunk_sizes)/sizeof(int); i++) { chunk_sizes_log2[i] = log2 (chunk_sizes[i]); } uint32_t ecx = get_cpuid1_ecx (); uint32_t edx = get_cpuid1_edx (); uint32_t ecx2 = get_cpuid_80000001_ecx (); uint32_t edx2 = get_cpuid_80000001_edx (); cpu_has_mmx = edx & CPUID_EDX_MMX; cpu_has_sse = edx & CPUID_EDX_SSE; cpu_has_sse2 = edx & CPUID_EDX_SSE2; cpu_has_sse3 = ecx & CPUID_ECX_SSE3; cpu_has_ssse3 = ecx & CPUID_ECX_SSSE3; cpu_has_sse41 = ecx & CPUID_ECX_SSE41; cpu_has_sse42 = ecx & CPUID_ECX_SSE42; cpu_has_aes = ecx & CPUID_ECX_AES; cpu_has_avx = ecx & CPUID_ECX_AVX; cpu_has_avx2 = 0; cpu_has_xd = edx2 & CPUID_EDX_XD; cpu_has_64bit = edx2 & CPUID_EDX_INTEL64; cpu_has_sse4a = 0; if (cpu_has_avx) { cpu_has_avx2 = get_cpuid7_ebx (); cpu_has_avx2 &= CPUID_EBX_AVX2; } /* Needed by CPU-X */ if (!cpu_has_sse41) use_sse4 = false; if (!cpu_has_sse2) use_sse2 = false; const struct Tests tests[] = { /* Test Name Color Flag Mask Func Mode Rand */ { SEQ_128_R, "Sequential 128-bit reads", RGB_RED, use_sse2, false, do_read, SSE2, false }, { SEQ_256_R, "Sequential 256-bit reads", RGB_TURQUOISE, cpu_has_avx, true, do_read, AVX, false }, { RAND_128_R, "Random 128-bit reads", RGB_MAROON, use_sse2, true, do_read, SSE2, true }, { SEQ_128_CACHE_W, "Sequential 128-bit cache writes", RGB_PURPLE, use_sse2, false, do_write, SSE2, false }, { SEQ_256_CACHE_W, "Sequential 256-bit cache writes", RGB_PINK, cpu_has_avx, true, do_write, AVX, false }, { RAND_128_CACHE_W, "Random 128-bit cache writes", RGB_NAVYBLUE, use_sse2, true, do_write, SSE2, true }, { SEQ_128_BYPASS_R, "Sequential 128-bit non-temporal reads", 0xA04040, use_sse4, false, do_read, SSE2_BYPASS, false }, { RAND_128_BYPASS_R, "Random 128-bit non-temporal reads", 0x301934, use_sse4, true, do_read, SSE2_BYPASS, true }, { SEQ_128_BYPASS_W, "Sequential 128-bit non-temporal writes", RGB_DARKORANGE, use_sse4, false, do_write, SSE2_BYPASS, false }, { SEQ_256_BYPASS_W, "Sequential 256-bit non-temporal writes", RGB_DARKOLIVEGREEN, cpu_has_avx, true, do_write, AVX_BYPASS, false }, { RAND_128_BYPASS_W, "Random 128-bit non-temporal writes", RGB_LEMONYELLOW, use_sse4, true, do_write, SSE2_BYPASS, true }, { SEQ_128_C, "Sequential 128-bit copy", 0x8f8844, use_sse2, false, do_copy2, SSE2, false }, { SEQ_256_C, "Sequential 256-bit copy", RGB_CHARTREUSE, cpu_has_avx, true, do_copy2, AVX, false }, { SEQ_32_LR, "Sequential 32-bit LODSD reads", RGB_GRAY8, true, false, do_read, LODSD, false }, { SEQ_16_LR, "Sequential 16-bit LODSW reads", RGB_GRAY10, true, false, do_read, LODSW, false }, { SEQ_8_LR, "Sequential 8-bit LODSB reads", RGB_GRAY12, true, false, do_read, LODSB, false }, #ifdef __x86_64__ { SEQ_64_LR, "Sequential 64-bit LODSQ reads", RGB_GRAY6, true, false, do_read, LODSQ, false }, { SEQ_64_R, "Sequential 64-bit reads", RGB_BLUE, true, false, do_read, NO_SSE2, false }, { RAND_64_R, "Random 64-bit reads", RGB_CYAN, true, true, do_read, NO_SSE2, true }, { SEQ_64_W, "Sequential 64-bit writes", RGB_DARKGREEN, true, false, do_write, NO_SSE2, false }, { RAND_64_W, "Random 64-bit writes", RGB_GREEN, true, true, do_write, NO_SSE2, true }, { RAND_256_R, "Random 256-bit reads", RGB_BROWN, cpu_has_avx, true, do_read, AVX, true }, { RAND_256_W, "Random 256-bit cache writes", RGB_RED, cpu_has_avx, true, do_write, AVX, true }, #else { SEQ_32_R, "Sequential 32-bit reads", RGB_BLUE, true, false, do_read, NO_SSE2, false }, { RAND_32_R, "Random 32-bit reads", RGB_CYAN, true, true, do_read, NO_SSE2, true }, { SEQ_32_W, "Sequential 32-bit writes", RGB_DARKGREEN, true, false, do_write, NO_SSE2, false }, { RAND_32_W, "Random 32-bit writes", RGB_GREEN, true, true, do_write, NO_SSE2, true }, #endif { -1, NULL, 0x0, false, false, NULL, 0, false } }; #if HAS_LIBCPUID /* Fast initialization by using libcpuid */ switch(data->l_data->cpu_vendor_id) { case VENDOR_INTEL: is_intel = true; goto end_initialization; case VENDOR_AMD: is_amd = true; cpu_has_sse4a = ecx2 & CPUID_ECX_SSE4A; goto end_initialization; default: break; } #endif /* HAS_LIBCPUID */ static char family [17]; get_cpuid_family (family); family [16] = 0; printf ("CPU family: %s\n", family); if (!strcmp ("AuthenticAMD", family)) { is_amd = true; cpu_has_sse4a = ecx2 & CPUID_ECX_SSE4A; } else if (!strcmp ("GenuineIntel", family)) { is_intel = true; } printf ("CPU features: "); if (cpu_has_mmx) printf ("MMX "); if (cpu_has_sse) printf ("SSE "); if (cpu_has_sse2) printf ("SSE2 "); if (cpu_has_sse3) printf ("SSE3 "); if (cpu_has_ssse3) printf ("SSSE3 "); if (cpu_has_sse4a) printf ("SSE4A "); if (cpu_has_sse41) printf ("SSE4.1 "); if (cpu_has_sse42) printf ("SSE4.2 "); if (cpu_has_aes) printf ("AES "); if (cpu_has_avx) printf ("AVX "); if (cpu_has_avx2) printf ("AVX2 "); if (cpu_has_xd) printf ("XD "); if (cpu_has_64bit) { if (!is_amd) printf ("Intel64 "); else printf ("LongMode "); } puts ("\n"); if (is_intel) { uint32_t cache_info[4]; i = 0; while (1) { get_cpuid_cache_info (cache_info, i); if (!(cache_info[0] & 31)) break; #if 0 printf ("Cache info %d = 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", i, cache_info [0], cache_info [1], cache_info [2], cache_info [3]); #endif printf ("Cache %d: ", i); switch ((cache_info[0] >> 5) & 7) { case 1: printf ("L1 "); break; case 2: printf ("L2 "); break; case 3: printf ("L3 "); break; } switch (cache_info[0] & 31) { case 1: printf ("data cache, "); break; case 2: printf ("instruction cache, "); break; case 3: printf ("unified cache, "); break; } uint32_t n_ways = 1 + (cache_info[1] >> 22); uint32_t line_size = 1 + (cache_info[1] & 2047); uint32_t n_sets = 1 + cache_info[2]; printf ("line size %d, ", line_size); printf ("%2d-way%s, ", n_ways, n_ways>1 ? "s" : ""); printf ("%5d sets, ", n_sets); unsigned size = (n_ways * line_size * n_sets) >> 10; printf ("size %dk ", size); newline (); i++; } } newline (); println ("Notation: B = byte, kB = 1024 B, MB = 1048576 B."); flush (); //------------------------------------------------------------ // Attempt to obtain information about the CPU. // #ifdef __linux__ struct stat st; if (!stat ("/proc/cpuinfo", &st)) { #define TMPFILE "/tmp/bandw_tmp" unlink (TMPFILE); if (-1 == system ("grep MHz /proc/cpuinfo | uniq | sed \"s/[\\t\\n: a-zA-Z]//g\" > "TMPFILE)) perror ("system"); FILE *f = fopen (TMPFILE, "r"); if (f) { float cpu_speed = 0.0; if (1 == fscanf (f, "%g", &cpu_speed)) { newline (); printf ("CPU speed is %g MHz.\n", cpu_speed); } fclose (f); } } else { printf ("CPU information is not available (/proc/cpuinfo).\n"); } fflush (stdout); #endif dataBegins (graph_title); #if HAS_LIBCPUID end_initialization: #endif /* HAS_LIBCPUID */ /* Check if selectionned test is valid */ if(opts->bw_test >= LASTTEST) opts->bw_test = 0; /* Set test names */ if(w_data->test_count == 0) { w_data->test_name = malloc(LASTTEST * sizeof(char *)); w_data->test_count = (w_data->test_name == NULL) ? 0 : LASTTEST; for(i = 0; i < w_data->test_count; i++) { w_data->test_name[i] = NULL; casprintf(&w_data->test_name[i], false, "#%2i: %s", i, tests[i].name); } } if(tests[opts->bw_test].need_flag) { if(tests[opts->bw_test].random) srand(time (NULL)); i = 0; while((chunk_size = chunk_sizes [i++])) { if(!tests[opts->bw_test].need_mask || (tests[opts->bw_test].need_mask && !(chunk_size & 128))) { if(chunk_size > w_data->size[cache_level] * 1024) { w_data->speed[cache_level] = total_amount / count; count = 0; total_amount = 0; cache_level++; if(cache_level >= data->cache_count || w_data->size[cache_level] < 1) return 0; } int amount = (*tests[opts->bw_test].func_ptr)(chunk_size, tests[opts->bw_test].mode, tests[opts->bw_test].random); total_amount += amount; count++; } } } else { for(i = 0; i < LASTCACHES / CACHEFIELDS; i++) w_data->speed[i] = 0; return 1; } return 0; } CPU-X-4.2.0/src/bandwidth/minifont.c000066400000000000000000000155561403012130000170670ustar00rootroot00000000000000 /*============================================================================= bmplib, a simple library to create, modify, and write BMP image files. Copyright (C) 2009-2014 by Zack T Smith. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *============================================================================*/ #include #include "BMP.h" // Mini characters, 8 pixels high. static const char *mini_chars_ [] = { "#", "#", "#", "#", "#", " ", "#", "", "## ##", " # #", "# #", " ", " ", " ", " ", "", " # # ", " # # ", "#####", " # # ", "#####", " # # ", " # # ", "", " # ", " ####", "# # ", " ### ", " # #", "####", " # ", "", "## #", " #", " #", " #", " #", "#", "# ##", "", " # ", "# # ", "## ", " ## #", "# ## ", "# # ", " ## #", "", "##", " #", "#", "", "", "", "", "", " #", "#", "#", "#", "#", "#", "#", " #", "# ", " #", " #", " #", " #", " #", " #", "#", " ", "# # #", " ###", " #", " ###", "# # #", "", "", " ", " #", " #", "#####", " #", " #", "", "", " ", "", "", "", "", "##", " #", "#", " ", "", "", "#####", "", "", "", "", " ", "", "", "", "", "", "#", "", " #", " #", " #", " #", " #", "#", "#", "", " ## ", "# #", "# #", "# #", "# #", "# #", " ## ", "", " #", "##", " #", " #", " #", " #", " #", "", " ## ", "# #", " #", " ###", "# ", "# ", "####", "", "####", " #", " # ", " ## ", " #", "# #", " ## ", "", "# # ", "# #", "# #", "####", " #", " #", " #", "", "####", "# ", "### ", " #", " #", "# #", " ## ", "", " ## ", "# ", "# ", "### ", "# #", "# #", " ## ", "", "####", " #", " #", " # ", " # ", " # ", " # ", "", " ## ", "# #", "# #", " ## ", "# #", "# #", " ## ", "", " ## ", "# #", "# #", " ###", " #", " # ", " # ", "", " ", "", "", "#", "", "#", "", "", " ", "", " ", "##", " ", "##", " #", "#", " #", " #", " #", "#", " #", " #", " #", "", " ", "", "", "#####", " ", "#####", "", "", "# ", " #", " #", " #", " #", " #", "#", "", " ### ", "# #", " #", " ## ", " #", "", " #", "", " ### ", "# #", "# ##", "# # #", "# ##", "# ", " ###", "", " # ", " # # ", "# #", "# #", "#####", "# #", "# #", "", "### ", "# #", "# #", "### ", "# #", "# #", "###", "", " ### ", "# #", "# ", "# ", "# ", "# #", " ###", "", "#### ", "# #", "# #", "# #", "# #", "# #", "####", "", "#####", "#", "#", "###", "#", "#", "#####", "", "#####", "# ", "# ", "###", "# ", "# ", "#", "", " ### ", "# #", "# ", "# ##", "# #", "# #", " ####", "", "# #", "# #", "# #", "#####", "# #", "# #", "# #", "", "###", " #", " #", " #", " #", " #", "###", "", " ###", " #", " #", " #", " #", "# #", " ##", "", "# #", "# #", "# #", "##", "# #", "# #", "# #", "", "# ", "#", "#", "#", "#", "#", "#####", "", "# #", "## ##", "# # #", "# #", "# #", "# #", "# #", "", "# #", "## #", "# # #", "# ##", "# #", "# #", "# #", "", " ### ", "# #", "# #", "# #", "# #", "# #", " ###", "", "#### ", "# #", "# #", "#### ", "# ", "# ", "# ", "", " ### ", "# #", "# #", "# #", "# # #", "# # ", " ## #", "", "#### ", "# #", "# #", "#### ", "# # ", "# # ", "# #", "", " ### ", "# #", "# ", " ### ", " #", "# #", " ###", "", "#####", " #", " #", " #", " #", " #", " #", "", "# #", "# #", "# #", "# #", "# #", "# #", " ###", "", "# #", "# #", "# #", "# #", "# #", " # # ", " #", "", "# #", "# #", "# #", "# # #", "# # #", "## ##", "# #", "", "# #", "# #", " # #", " #", " # #", "# #", "# #", "", "# #", "# #", "# #", " # #", " #", " #", " #", "", "#####", " #", " #", " #", " #", "#", "#####", "", "##", "#", "#", "#", "#", "#", "#", "##", "#", "#", " #", " #", " #", " #", " #", "", "##", " #", " #", " #", " #", " #", " #", "##", " # ", " # #", "# #", "", "", "", "", "", " ", "", "", "", "", "", "", "####", "##", "#", " #", "", "", "", "", "", " ", " ", " ## ", " #", " ###", "# #", " ###", "", "# ", "# ", "### ", "# #", "# #", "# #", "### ", "", " ", " ", " ###", "# ", "# ", "# ", " ###", "", " #", " #", " ###", "# #", "# #", "# #", " ###", "", " ", " ", " ## ", "# #", "####", "# ", " ###", "", " ##", " # ", "### ", " # ", " # ", " # ", "### ", "", " ", " ", " ###", "# #", "# #", " ###", " #", "### ", "# ", "# ", "### ", "# #", "# #", "# #", "# #", "", " # ", " ", "## ", " # ", " # ", " # ", "###", "", " #", " ", " ##", " #", " #", " #", " #", "## ", "# ", "# ", "# #", "# # ", "## ", "# # ", "# #", "", "## ", " # ", " # ", " # ", " # ", " # ", "###", "", " ", "", "####", "# # #", "# # #", "# # #", "# # #", "", " ", " ", "###", "# #", "# #", "# #", "# #", "", " ", " ", " ## ", "# #", "# #", "# #", " ## ", "", " ", "", "###", "# #", "# #", "###", "#", "#", " ", "", " ###", "# #", "# #", " ###", " #", " # ", " ", " ", "# ##", "## ", "# ", "# ", "# ", "", " ", " ", " ###", "# ", " ##", " #", "### ", "", " # ", " #", "###", " #", " #", " #", " ##", "", " ", "", "# #", "# #", "# #", "# #", " ###", "", " ", "", "# #", "# #", "# #", " # #", " #", "", " ", "", "# # #", "# # #", "# # #", "# # #", " # #", "", " ", "", "# #", " # #", " #", " # #", "# #", "", " ", " ", "# #", "# #", "# #", " ###", " #", "### ", " ", "", "#####", " #", " #", " # ", "#####", "", }; const char **get_minifont_chars () { return mini_chars_; } CPU-X-4.2.0/src/bandwidth/minifont.h000066400000000000000000000020421403012130000170560ustar00rootroot00000000000000 /*============================================================================= bmplib, a simple library to create, modify, and write BMP image files. Copyright (C) 2009-2014 by Zack T Smith. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. 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 St, Fifth Floor, Boston, MA 02110-1301 USA The author may be reached at 1@zsmith.co. *============================================================================*/ #ifndef _MINIFONT_H #define _MINIFONT_H extern const char **get_minifont_chars (void); #endif CPU-X-4.2.0/src/bandwidth/routines-x86-32bit.asm000066400000000000000000001654511403012130000210160ustar00rootroot00000000000000;============================================================================ ; bandwidth, a benchmark to estimate memory transfer bandwidth. ; Copyright (C) 2005-2015 by Zack T Smith. ; ; 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 St, Fifth Floor, Boston, MA 02110-1301 USA ; ; The author may be reached at veritas@comcast.net. ;============================================================================= bits 32 cpu ia64 global IncrementRegisters global _IncrementRegisters global IncrementStack global _IncrementStack global ReaderLODSQ global _ReaderLODSQ global ReaderLODSD global _ReaderLODSD global ReaderLODSW global _ReaderLODSW global ReaderLODSB global _ReaderLODSB ; Cygwin requires the underbar-prefixed symbols. global _WriterSSE2 global WriterSSE2 global _WriterAVX global WriterAVX global _WriterSSE2_128bytes global WriterSSE2_128bytes global _ReaderAVX global ReaderAVX global _ReaderSSE2 global ReaderSSE2 global ReaderSSE2_bypass global _ReaderSSE2_bypass global _ReaderSSE2_128bytes global ReaderSSE2_128bytes global ReaderSSE2_128bytes_bypass global _ReaderSSE2_128bytes_bypass global _RandomReaderSSE2 global RandomReaderSSE2 global _RandomReaderSSE2_bypass global RandomReaderSSE2_bypass global WriterAVX_bypass global _WriterAVX_bypass global _WriterSSE2_bypass global WriterSSE2_bypass global _WriterSSE2_128bytes_bypass global WriterSSE2_128bytes_bypass global _RandomWriterSSE2_bypass global RandomWriterSSE2_bypass global Reader global _Reader global Writer global _Writer global Reader_128bytes global _Reader_128bytes global Writer_128bytes global _Writer_128bytes global RandomReader global _RandomReader global RandomWriter global _RandomWriter global RandomWriterSSE2 global _RandomWriterSSE2 global get_cpuid_family global _get_cpuid_family global get_cpuid_cache_info global _get_cpuid_cache_info global get_cpuid1_ecx global _get_cpuid1_ecx global get_cpuid1_edx global _get_cpuid1_edx global get_cpuid7_ebx global _get_cpuid7_ebx global get_cpuid_80000001_ecx global _get_cpuid_80000001_ecx global get_cpuid_80000001_edx global _get_cpuid_80000001_edx global CopySSE global _CopySSE global CopyAVX global _CopyAVX global CopySSE_128bytes global _CopySSE_128bytes global RegisterToRegister global _RegisterToRegister global VectorToVector global _VectorToVector global VectorToVectorAVX global _VectorToVectorAVX global RegisterToVector global _RegisterToVector global VectorToRegister global _VectorToRegister global Register8ToVector global Register16ToVector global Register32ToVector global Register64ToVector global Vector8ToRegister global Vector16ToRegister global Vector32ToRegister global Vector64ToRegister global _Register8ToVector global _Register16ToVector global _Register32ToVector global _Register64ToVector global _Vector8ToRegister global _Vector16ToRegister global _Vector32ToRegister global _Vector64ToRegister global StackReader global _StackReader global StackWriter global _StackWriter section .text ;------------------------------------------------------------------------------ ; Name: ReaderLODSQ ; Purpose: Reads 64-bit values sequentially from an area of memory ; using LODSQ instruction. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSQ: _ReaderLODSQ: ; N/A ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSD ; Purpose: Reads 32-bit values sequentially from an area of memory ; using LODSD instruction. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSD: _ReaderLODSD: shr dword [esp+8], 2 ; length in double words rounded down. push ebx push ecx ; REP counter push edx mov edx, [esp+12+12] .L1: mov esi, [esp+4+12] mov ecx, [esp+8+12] rep lodsd dec edx jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSW ; Purpose: Reads 16-bit values sequentially from an area of memory ; using LODSW instruction. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSW: _ReaderLODSW: shr dword [esp+8], 1 ; length in words rounded down. push ebx push ecx ; REP counter push edx mov edx, [esp+12+12] .L1: mov esi, [esp+4+12] mov ecx, [esp+8+12] rep lodsw dec edx jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSB ; Purpose: Reads 8-bit values sequentially from an area of memory ; using LODSB instruction. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSB: _ReaderLODSB: push ebx push ecx ; REP counter push edx mov edx, [esp+12+12] .L1: mov esi, [esp+4+12] mov ecx, [esp+8+12] rep lodsb dec edx jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: Reader ; Purpose: Reads 32-bit values sequentially from an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 Reader: _Reader: push ebx push ecx push edx mov ecx, [esp+12+12] ; loops to do. mov edx, [esp+4+12] ; ptr to memory chunk. mov ebx, edx ; ebx = limit in memory add ebx, [esp+8+12] .L1: mov edx, [esp+4+12] .L2: mov eax, [edx] mov eax, [4+edx] mov eax, [8+edx] mov eax, [12+edx] mov eax, [16+edx] mov eax, [20+edx] mov eax, [24+edx] mov eax, [28+edx] mov eax, [32+edx] mov eax, [36+edx] mov eax, [40+edx] mov eax, [44+edx] mov eax, [48+edx] mov eax, [52+edx] mov eax, [56+edx] mov eax, [60+edx] mov eax, [64+edx] mov eax, [68+edx] mov eax, [72+edx] mov eax, [76+edx] mov eax, [80+edx] mov eax, [84+edx] mov eax, [88+edx] mov eax, [92+edx] mov eax, [96+edx] mov eax, [100+edx] mov eax, [104+edx] mov eax, [108+edx] mov eax, [112+edx] mov eax, [116+edx] mov eax, [120+edx] mov eax, [124+edx] mov eax, [edx+128] mov eax, [edx+132] mov eax, [edx+136] mov eax, [edx+140] mov eax, [edx+144] mov eax, [edx+148] mov eax, [edx+152] mov eax, [edx+156] mov eax, [edx+160] mov eax, [edx+164] mov eax, [edx+168] mov eax, [edx+172] mov eax, [edx+176] mov eax, [edx+180] mov eax, [edx+184] mov eax, [edx+188] mov eax, [edx+192] mov eax, [edx+196] mov eax, [edx+200] mov eax, [edx+204] mov eax, [edx+208] mov eax, [edx+212] mov eax, [edx+216] mov eax, [edx+220] mov eax, [edx+224] mov eax, [edx+228] mov eax, [edx+232] mov eax, [edx+236] mov eax, [edx+240] mov eax, [edx+244] mov eax, [edx+248] mov eax, [edx+252] add edx, 256 cmp edx, ebx jb .L2 sub ecx, 1 jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: Writer ; Purpose: Writes 32-bit value sequentially to an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = long to write ;------------------------------------------------------------------------------ align 64 Writer: _Writer: push ebx push ecx push edx mov ecx, [esp+12+12] mov eax, [esp+16+12] mov edx, [esp+4+12] ; edx = ptr to chunk mov ebx, edx add ebx, [esp+8+12] ; ebx = limit in memory .L1: mov edx, [esp+4+12] .L2: mov [edx], eax mov [4+edx], eax mov [8+edx], eax mov [12+edx], eax mov [16+edx], eax mov [20+edx], eax mov [24+edx], eax mov [28+edx], eax mov [32+edx], eax mov [36+edx], eax mov [40+edx], eax mov [44+edx], eax mov [48+edx], eax mov [52+edx], eax mov [56+edx], eax mov [60+edx], eax mov [64+edx], eax mov [68+edx], eax mov [72+edx], eax mov [76+edx], eax mov [80+edx], eax mov [84+edx], eax mov [88+edx], eax mov [92+edx], eax mov [96+edx], eax mov [100+edx], eax mov [104+edx], eax mov [108+edx], eax mov [112+edx], eax mov [116+edx], eax mov [120+edx], eax mov [124+edx], eax mov [edx+128], eax mov [edx+132], eax mov [edx+136], eax mov [edx+140], eax mov [edx+144], eax mov [edx+148], eax mov [edx+152], eax mov [edx+156], eax mov [edx+160], eax mov [edx+164], eax mov [edx+168], eax mov [edx+172], eax mov [edx+176], eax mov [edx+180], eax mov [edx+184], eax mov [edx+188], eax mov [edx+192], eax mov [edx+196], eax mov [edx+200], eax mov [edx+204], eax mov [edx+208], eax mov [edx+212], eax mov [edx+216], eax mov [edx+220], eax mov [edx+224], eax mov [edx+228], eax mov [edx+232], eax mov [edx+236], eax mov [edx+240], eax mov [edx+244], eax mov [edx+248], eax mov [edx+252], eax add edx, 256 cmp edx, ebx jb .L2 sub ecx, 1 jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: Reader_128bytes ; Purpose: Reads 32-bit values sequentially from an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 Reader_128bytes: _Reader_128bytes: push ebx push ecx push edx mov ecx, [esp+12+12] ; loops to do. mov edx, [esp+4+12] ; ptr to memory chunk. mov ebx, edx ; ebx = limit in memory add ebx, [esp+8+12] .L1: mov edx, [esp+4+12] .L2: mov eax, [edx] mov eax, [4+edx] mov eax, [8+edx] mov eax, [12+edx] mov eax, [16+edx] mov eax, [20+edx] mov eax, [24+edx] mov eax, [28+edx] mov eax, [32+edx] mov eax, [36+edx] mov eax, [40+edx] mov eax, [44+edx] mov eax, [48+edx] mov eax, [52+edx] mov eax, [56+edx] mov eax, [60+edx] mov eax, [64+edx] mov eax, [68+edx] mov eax, [72+edx] mov eax, [76+edx] mov eax, [80+edx] mov eax, [84+edx] mov eax, [88+edx] mov eax, [92+edx] mov eax, [96+edx] mov eax, [100+edx] mov eax, [104+edx] mov eax, [108+edx] mov eax, [112+edx] mov eax, [116+edx] mov eax, [120+edx] mov eax, [124+edx] add edx, 128 cmp edx, ebx jb .L2 sub ecx, 1 jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: Writer_128bytes ; Purpose: Writes 32-bit value sequentially to an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = long to write ;------------------------------------------------------------------------------ align 64 Writer_128bytes: _Writer_128bytes: push ebx push ecx push edx mov ecx, [esp+12+12] mov eax, [esp+16+12] mov edx, [esp+4+12] ; edx = ptr to chunk mov ebx, edx add ebx, [esp+8+12] ; ebx = limit in memory .L1: mov edx, [esp+4+12] .L2: mov [edx], eax mov [4+edx], eax mov [8+edx], eax mov [12+edx], eax mov [16+edx], eax mov [20+edx], eax mov [24+edx], eax mov [28+edx], eax mov [32+edx], eax mov [36+edx], eax mov [40+edx], eax mov [44+edx], eax mov [48+edx], eax mov [52+edx], eax mov [56+edx], eax mov [60+edx], eax mov [64+edx], eax mov [68+edx], eax mov [72+edx], eax mov [76+edx], eax mov [80+edx], eax mov [84+edx], eax mov [88+edx], eax mov [92+edx], eax mov [96+edx], eax mov [100+edx], eax mov [104+edx], eax mov [108+edx], eax mov [112+edx], eax mov [116+edx], eax mov [120+edx], eax mov [124+edx], eax add edx, 128 cmp edx, ebx jb .L2 sub ecx, 1 jnz .L1 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_cache_info ; get_cpuid_cache_info: _get_cpuid_cache_info: push ebp push ebx push ecx push edx mov eax, 4 mov ecx, [esp + 16 + 4 + 4] cpuid mov ebp, eax mov eax, [esp + 16 + 4] mov [eax], ebp mov [eax+4], ebx mov [eax+8], ecx mov [eax+12], edx pop edx pop ecx pop ebx pop ebp ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_family ; get_cpuid_family: _get_cpuid_family: push ebx push ecx push edx xor eax, eax cpuid mov eax, [esp + 12 + 4] mov [eax], ebx mov [eax+4], edx mov [eax+8], ecx mov byte [eax+12], 0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid1_ecx ; get_cpuid1_ecx: _get_cpuid1_ecx: push ebx push ecx push edx mov eax, 1 cpuid mov eax, ecx pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid7_ebx ; get_cpuid7_ebx: _get_cpuid7_ebx: push ebx push ecx push edx mov eax, 7 xor ecx, ecx cpuid mov eax, ebx pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_80000001_ecx ; get_cpuid_80000001_ecx: _get_cpuid_80000001_ecx: push ebx push ecx push edx mov eax, 0x80000001 cpuid mov eax, ecx pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_80000001_edx ; get_cpuid_80000001_edx: _get_cpuid_80000001_edx: push ebx push ecx push edx mov eax, 0x80000001 cpuid mov eax, edx pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid1_edx ; get_cpuid1_edx: _get_cpuid1_edx: push ebx push ecx push edx mov eax, 1 cpuid mov eax, edx pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderAVX ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 ReaderAVX: _ReaderAVX: vzeroupper push ebx push ecx mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: vmovdqa ymm0, [eax] ; Read aligned @ 16-byte boundary. vmovdqa ymm0, [32+eax] vmovdqa ymm0, [64+eax] vmovdqa ymm0, [96+eax] vmovdqa ymm0, [128+eax] vmovdqa ymm0, [160+eax] vmovdqa ymm0, [192+eax] vmovdqa ymm0, [224+eax] add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2 ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2: _ReaderSSE2: push ebx push ecx mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movdqa xmm0, [eax] ; Read aligned @ 16-byte boundary. movdqa xmm0, [16+eax] movdqa xmm0, [32+eax] movdqa xmm0, [48+eax] movdqa xmm0, [64+eax] movdqa xmm0, [80+eax] movdqa xmm0, [96+eax] movdqa xmm0, [112+eax] movdqa xmm0, [128+eax] movdqa xmm0, [144+eax] movdqa xmm0, [160+eax] movdqa xmm0, [176+eax] movdqa xmm0, [192+eax] movdqa xmm0, [208+eax] movdqa xmm0, [224+eax] movdqa xmm0, [240+eax] add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_bypass ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_bypass: _ReaderSSE2_bypass: push ebx push ecx mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: prefetchnta [eax] movntdqa xmm0, [eax] ; Read aligned @ 16-byte boundary. movntdqa xmm0, [16+eax] movntdqa xmm0, [32+eax] movntdqa xmm0, [48+eax] prefetchnta [eax+64] movntdqa xmm0, [64+eax] movntdqa xmm0, [80+eax] movntdqa xmm0, [96+eax] movntdqa xmm0, [112+eax] prefetchnta [eax+128] movntdqa xmm0, [128+eax] movntdqa xmm0, [144+eax] movntdqa xmm0, [160+eax] movntdqa xmm0, [176+eax] prefetchnta [eax+192] movntdqa xmm0, [192+eax] movntdqa xmm0, [208+eax] movntdqa xmm0, [224+eax] movntdqa xmm0, [240+eax] add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_128bytes_bypass ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_128bytes_bypass: _ReaderSSE2_128bytes_bypass: push ebx push ecx mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: prefetchnta [eax] movntdqa xmm0, [eax] ; Read aligned @ 16-byte boundary. movntdqa xmm0, [16+eax] movntdqa xmm0, [32+eax] movntdqa xmm0, [48+eax] prefetchnta [eax+64] movntdqa xmm0, [64+eax] movntdqa xmm0, [80+eax] movntdqa xmm0, [96+eax] movntdqa xmm0, [112+eax] add eax, 128 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_128bytes ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_128bytes: _ReaderSSE2_128bytes: push ebx push ecx mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movdqa xmm0, [eax] ; Read aligned @ 16-byte boundary. movdqa xmm0, [16+eax] movdqa xmm0, [32+eax] movdqa xmm0, [48+eax] movdqa xmm0, [64+eax] movdqa xmm0, [80+eax] movdqa xmm0, [96+eax] movdqa xmm0, [112+eax] add eax, 128 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterAVX ; Purpose: Write 256-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterAVX: _WriterAVX: vzeroupper push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: vmovdqa [eax], ymm0 vmovdqa [32+eax], ymm0 vmovdqa [64+eax], ymm0 vmovdqa [96+eax], ymm0 vmovdqa [128+eax], ymm0 vmovdqa [160+eax], ymm0 vmovdqa [192+eax], ymm0 vmovdqa [224+eax], ymm0 add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2 ; Purpose: Write 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterSSE2: _WriterSSE2: push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movdqa [eax], xmm0 movdqa [16+eax], xmm0 movdqa [32+eax], xmm0 movdqa [48+eax], xmm0 movdqa [64+eax], xmm0 movdqa [80+eax], xmm0 movdqa [96+eax], xmm0 movdqa [112+eax], xmm0 movdqa [128+eax], xmm0 movdqa [144+eax], xmm0 movdqa [160+eax], xmm0 movdqa [176+eax], xmm0 movdqa [192+eax], xmm0 movdqa [208+eax], xmm0 movdqa [224+eax], xmm0 movdqa [240+eax], xmm0 add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2 ; Purpose: Write 128-bit values sequentially from an area of memory. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterSSE2_128bytes: _WriterSSE2_128bytes: push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movdqa [eax], xmm0 movdqa [16+eax], xmm0 movdqa [32+eax], xmm0 movdqa [48+eax], xmm0 movdqa [64+eax], xmm0 movdqa [80+eax], xmm0 movdqa [96+eax], xmm0 movdqa [112+eax], xmm0 add eax, 128 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterAVX_bypass ; Purpose: Write 256-bit values sequentially from an area of memory, ; bypassing the cache. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterAVX_bypass: _WriterAVX_bypass: vzeroupper push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: vmovntdq [eax], ymm0 ; Write bypassing cache. vmovntdq [32+eax], ymm0 vmovntdq [64+eax], ymm0 vmovntdq [96+eax], ymm0 vmovntdq [128+eax], ymm0 vmovntdq [160+eax], ymm0 vmovntdq [192+eax], ymm0 vmovntdq [224+eax], ymm0 add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2_bypass ; Purpose: Write 128-bit values sequentially from an area of memory, ; bypassing the cache. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterSSE2_bypass: _WriterSSE2_bypass: push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movntdq [eax], xmm0 ; Write bypassing cache. movntdq [16+eax], xmm0 movntdq [32+eax], xmm0 movntdq [48+eax], xmm0 movntdq [64+eax], xmm0 movntdq [80+eax], xmm0 movntdq [96+eax], xmm0 movntdq [112+eax], xmm0 movntdq [128+eax], xmm0 movntdq [144+eax], xmm0 movntdq [160+eax], xmm0 movntdq [176+eax], xmm0 movntdq [192+eax], xmm0 movntdq [208+eax], xmm0 movntdq [224+eax], xmm0 movntdq [240+eax], xmm0 add eax, 256 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2_128bytes_bypass ; Purpose: Write 128-bit values sequentially from an area of memory, ; bypassing the cache. ; Params: [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = value (ignored) ;------------------------------------------------------------------------------ align 64 WriterSSE2_128bytes_bypass: _WriterSSE2_128bytes_bypass: push ebx push ecx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+8] mov eax, [esp+4+8] mov ebx, eax add ebx, [esp+8+8] ; ebx points to end. .L1: mov eax, [esp+4+8] .L2: movntdq [eax], xmm0 ; Write bypassing cache. movntdq [16+eax], xmm0 movntdq [32+eax], xmm0 movntdq [48+eax], xmm0 movntdq [64+eax], xmm0 movntdq [80+eax], xmm0 movntdq [96+eax], xmm0 movntdq [112+eax], xmm0 add eax, 128 cmp eax, ebx jb .L2 sub ecx, 1 jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomReader ; Purpose: Reads 32-bit values randomly from an area of memory. ; Params: ; [esp+4] = ptr to array of chunk pointers ; [esp+8] = # of 128-byte chunks ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 RandomReader: _RandomReader: push ebx push ecx push edx mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] mov eax, [edx+160] mov eax, [edx+232] mov eax, [edx+224] mov eax, [96+edx] mov eax, [edx+164] mov eax, [76+edx] mov eax, [100+edx] mov eax, [edx+220] mov eax, [edx+248] mov eax, [104+edx] mov eax, [4+edx] mov eax, [edx+136] mov eax, [112+edx] mov eax, [edx+200] mov eax, [12+edx] mov eax, [edx+128] mov eax, [edx+148] mov eax, [edx+196] mov eax, [edx+216] mov eax, [edx] mov eax, [84+edx] mov eax, [edx+140] mov eax, [edx+204] mov eax, [edx+184] mov eax, [124+edx] mov eax, [48+edx] mov eax, [64+edx] mov eax, [edx+212] mov eax, [edx+240] mov eax, [edx+236] mov eax, [24+edx] mov eax, [edx+252] mov eax, [68+edx] mov eax, [20+edx] mov eax, [72+edx] mov eax, [32+edx] mov eax, [28+edx] mov eax, [52+edx] mov eax, [edx+244] mov eax, [edx+180] mov eax, [80+edx] mov eax, [60+edx] mov eax, [8+edx] mov eax, [56+edx] mov eax, [edx+208] mov eax, [edx+228] mov eax, [40+edx] mov eax, [edx+172] mov eax, [120+edx] mov eax, [edx+176] mov eax, [108+edx] mov eax, [edx+132] mov eax, [16+edx] mov eax, [44+edx] mov eax, [92+edx] mov eax, [edx+168] mov eax, [edx+152] mov eax, [edx+156] mov eax, [edx+188] mov eax, [36+edx] mov eax, [88+edx] mov eax, [116+edx] mov eax, [edx+192] mov eax, [edx+144] jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomReaderSSE2 ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: ; [esp+4] = ptr to array of chunk pointers ; [esp+8] = # of 128-byte chunks ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 RandomReaderSSE2: _RandomReaderSSE2: push ebx push ecx push edx mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] ; Read aligned @ 16-byte boundary. movdqa xmm0, [240+edx] movdqa xmm0, [128+edx] movdqa xmm0, [64+edx] movdqa xmm0, [208+edx] movdqa xmm0, [112+edx] movdqa xmm0, [176+edx] movdqa xmm0, [144+edx] movdqa xmm0, [edx] movdqa xmm0, [96+edx] movdqa xmm0, [16+edx] movdqa xmm0, [192+edx] movdqa xmm0, [160+edx] movdqa xmm0, [32+edx] movdqa xmm0, [48+edx] movdqa xmm0, [224+edx] movdqa xmm0, [80+edx] jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomReaderSSE2_bypass ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: ; [esp+4] = ptr to array of chunk pointers ; [esp+8] = # of 128-byte chunks ; [esp+12] = loops ;------------------------------------------------------------------------------ align 64 RandomReaderSSE2_bypass: _RandomReaderSSE2_bypass: push ebx push ecx push edx mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] ; Read aligned @ 16-byte boundary. prefetchnta [edx+192] movntdqa xmm0, [240+edx] prefetchnta [edx] movntdqa xmm0, [edx] prefetchnta [edx+128] movntdqa xmm0, [128+edx] prefetchnta [edx+64] movntdqa xmm0, [64+edx] movntdqa xmm0, [208+edx] movntdqa xmm0, [112+edx] movntdqa xmm0, [32+edx] movntdqa xmm0, [176+edx] movntdqa xmm0, [144+edx] movntdqa xmm0, [96+edx] movntdqa xmm0, [16+edx] movntdqa xmm0, [160+edx] movntdqa xmm0, [192+edx] movntdqa xmm0, [48+edx] movntdqa xmm0, [224+edx] movntdqa xmm0, [80+edx] jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomWriter ; Purpose: Writes 32-bit value sequentially to an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = long to write ;------------------------------------------------------------------------------ align 64 RandomWriter: _RandomWriter: push ebx push ecx push edx mov eax, [esp+16+12] ; get datum. mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] mov [edx+212], eax mov [edx+156], eax mov [edx+132], eax mov [20+edx], eax mov [edx+172], eax mov [edx+196], eax mov [edx+248], eax mov [edx], eax mov [edx+136], eax mov [edx+228], eax mov [edx+160], eax mov [80+edx], eax mov [76+edx], eax mov [32+edx], eax mov [64+edx], eax mov [68+edx], eax mov [120+edx], eax mov [edx+216], eax mov [124+edx], eax mov [28+edx], eax mov [edx+152], eax mov [36+edx], eax mov [edx+220], eax mov [edx+188], eax mov [48+edx], eax mov [104+edx], eax mov [72+edx], eax mov [96+edx], eax mov [edx+184], eax mov [112+edx], eax mov [edx+236], eax mov [edx+224], eax mov [edx+252], eax mov [88+edx], eax mov [edx+180], eax mov [60+edx], eax mov [24+edx], eax mov [edx+192], eax mov [edx+164], eax mov [edx+204], eax mov [44+edx], eax mov [edx+168], eax mov [92+edx], eax mov [edx+208], eax mov [8+edx], eax mov [edx+144], eax mov [edx+148], eax mov [edx+128], eax mov [52+edx], eax mov [4+edx], eax mov [108+edx], eax mov [12+edx], eax mov [56+edx], eax mov [edx+200], eax mov [edx+232], eax mov [16+edx], eax mov [edx+244], eax mov [40+edx], eax mov [edx+140], eax mov [84+edx], eax mov [100+edx], eax mov [116+edx], eax mov [edx+176], eax mov [edx+240], eax jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomWriterSSE2 ; Purpose: Writes 128-bit value randomly to an area of memory. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = long to write ;------------------------------------------------------------------------------ align 64 RandomWriterSSE2: _RandomWriterSSE2: push ebx push ecx push edx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] movdqa [64+edx], xmm0 movdqa [208+edx], xmm0 movdqa [128+edx], xmm0 movdqa [112+edx], xmm0 movdqa [176+edx], xmm0 movdqa [144+edx], xmm0 movdqa [edx], xmm0 movdqa [96+edx], xmm0 movdqa [48+edx], xmm0 movdqa [16+edx], xmm0 movdqa [192+edx], xmm0 movdqa [160+edx], xmm0 movdqa [32+edx], xmm0 movdqa [240+edx], xmm0 movdqa [224+edx], xmm0 movdqa [80+edx], xmm0 jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RandomWriterSSE2_bypass ; Purpose: Writes 128-bit value randomly into memory, bypassing caches. ; Params: ; [esp+4] = ptr to memory area ; [esp+8] = length in bytes ; [esp+12] = loops ; [esp+16] = long to write ;------------------------------------------------------------------------------ align 64 RandomWriterSSE2_bypass: _RandomWriterSSE2_bypass: push ebx push ecx push edx mov eax, [esp+16+8] movd xmm0, eax ; Create a 128-bit replication of the 32-bit movd xmm1, eax ; value that was provided. movd xmm2, eax movd xmm3, eax pslldq xmm1, 32 pslldq xmm2, 64 pslldq xmm3, 96 por xmm0, xmm1 por xmm0, xmm2 por xmm0, xmm3 mov ecx, [esp+12+12] ; loops to do. .L0: mov ebx, [esp+8+12] ; # chunks to do .L1: sub ebx, 1 jc .L2 mov edx, [esp+4+12] ; get ptr to memory chunk. mov edx, [edx + 4*ebx] movntdq [128+edx], xmm0 movntdq [240+edx], xmm0 movntdq [112+edx], xmm0 movntdq [64+edx], xmm0 movntdq [176+edx], xmm0 movntdq [144+edx], xmm0 movntdq [edx], xmm0 movntdq [208+edx], xmm0 movntdq [80+edx], xmm0 movntdq [96+edx], xmm0 movntdq [48+edx], xmm0 movntdq [16+edx], xmm0 movntdq [192+edx], xmm0 movntdq [160+edx], xmm0 movntdq [224+edx], xmm0 movntdq [32+edx], xmm0 jmp .L1 .L2: sub ecx, 1 jnz .L0 pop edx pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: RegisterToRegister ; Purpose: Reads/writes 32-bit values between registers of ; the main register set. ; Params: ; dword [esp+4] = loops ;------------------------------------------------------------------------------ align 64 RegisterToRegister: _RegisterToRegister: push ebx push ecx mov ecx, [esp+4+8] ; loops to do. .L1: mov eax, ebx ; 64 transfers by 4 bytes = 256 bytes mov eax, ecx mov eax, edx mov eax, esi mov eax, edi mov eax, ebp mov eax, esp mov eax, ebx mov eax, ebx mov eax, ecx mov eax, edx mov eax, esi mov eax, edi mov eax, ebp mov eax, esp mov eax, ebx mov eax, ebx mov eax, ecx mov eax, edx mov eax, esi mov eax, edi mov eax, ebp mov eax, esp mov eax, ebx mov eax, ebx mov eax, ecx mov eax, edx mov eax, esi mov eax, edi mov eax, ebp mov eax, esp mov eax, ebx mov ebx, eax mov ebx, ecx mov ebx, edx mov ebx, esi mov ebx, edi mov ebx, ebp mov ebx, esp mov ebx, eax mov ebx, eax mov ebx, ecx mov ebx, edx mov ebx, esi mov ebx, edi mov ebx, ebp mov ebx, esp mov ebx, eax mov ebx, eax mov ebx, ecx mov ebx, edx mov ebx, esi mov ebx, edi mov ebx, ebp mov ebx, esp mov ebx, eax mov ebx, eax mov ebx, ecx mov ebx, edx mov ebx, esi mov ebx, edi mov ebx, ebp mov ebx, esp mov ebx, eax dec ecx jnz .L1 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: VectorToVectorAVX ; Purpose: Reads/writes 256-bit values between registers of ; the vector register set, in this case YMM. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 VectorToVectorAVX: _VectorToVectorAVX: vzeroupper mov eax, [esp + 4] .L1: vmovdqa ymm0, ymm1 ; Each move moves 32 bytes, so we need 8 vmovdqa ymm0, ymm2 ; moves to transfer a 256 byte chunk. vmovdqa ymm0, ymm3 vmovdqa ymm2, ymm0 vmovdqa ymm1, ymm2 vmovdqa ymm2, ymm1 vmovdqa ymm0, ymm3 vmovdqa ymm3, ymm1 dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: VectorToVector ; Purpose: Reads/writes 128-bit values between registers of ; the vector register set, in this case XMM. ; Params: dword [esp + 4] = count. ;------------------------------------------------------------------------------ align 64 VectorToVector: _VectorToVector: mov eax, [esp + 4] .L1: movdqa xmm0, xmm1 movdqa xmm0, xmm2 movdqa xmm0, xmm3 movdqa xmm2, xmm0 movdqa xmm1, xmm2 movdqa xmm2, xmm1 movdqa xmm0, xmm3 movdqa xmm3, xmm1 movdqa xmm3, xmm2 movdqa xmm1, xmm3 movdqa xmm2, xmm1 movdqa xmm0, xmm1 movdqa xmm1, xmm2 movdqa xmm0, xmm1 movdqa xmm0, xmm3 movdqa xmm3, xmm0 dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: RegisterToVector ; Purpose: Writes 32-bit main register values into 128-bit vector register ; clearing the upper unused bits. ; Params: dword [esp + 4] = count. ;------------------------------------------------------------------------------ align 64 RegisterToVector: _RegisterToVector: mov eax, [esp + 4] add eax, eax ; Double # of loops. .L1: movd xmm1, eax ; 32 transfers of 4 bytes = 128 bytes movd xmm2, eax movd xmm3, eax movd xmm0, eax movd xmm1, eax movd xmm2, eax movd xmm3, eax movd xmm0, eax movd xmm1, eax movd xmm3, eax movd xmm2, eax movd xmm0, eax movd xmm1, eax movd xmm2, eax movd xmm3, eax movd xmm0, eax movd xmm0, eax movd xmm2, eax movd xmm0, eax movd xmm3, eax movd xmm1, eax movd xmm3, eax movd xmm2, eax movd xmm0, eax movd xmm0, eax movd xmm3, eax movd xmm1, eax movd xmm2, eax movd xmm0, eax movd xmm2, eax movd xmm3, eax movd xmm0, eax dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: VectorToRegister ; Purpose: Writes lowest 32 bits of vector registers into 32-bit main ; register. ; Params: dword [esp + 4] = count. ;------------------------------------------------------------------------------ align 64 VectorToRegister: _VectorToRegister: mov eax, [esp + 4] add eax, eax ; Double # of loops. push ebx .L1: movd ebx, xmm1 ; 4 bytes per transfer therefore need 64 movd ebx, xmm2 ; to transfer 256 bytes. movd ebx, xmm3 movd ebx, xmm0 movd ebx, xmm1 movd ebx, xmm2 movd ebx, xmm3 movd ebx, xmm0 movd ebx, xmm1 movd ebx, xmm3 movd ebx, xmm2 movd ebx, xmm0 movd ebx, xmm1 movd ebx, xmm2 movd ebx, xmm3 movd ebx, xmm0 movd ebx, xmm0 movd ebx, xmm2 movd ebx, xmm0 movd ebx, xmm3 movd ebx, xmm1 movd ebx, xmm3 movd ebx, xmm2 movd ebx, xmm0 movd ebx, xmm0 movd ebx, xmm3 movd ebx, xmm1 movd ebx, xmm2 movd ebx, xmm0 movd ebx, xmm2 movd ebx, xmm3 movd ebx, xmm0 dec eax jnz .L1 pop ebx ret ;------------------------------------------------------------------------------ ; Name: StackReader ; Purpose: Reads 32-bit values off the stack into registers of ; the main register set, effectively testing L1 cache access ; *and* effective-address calculation speed. ; Params: ; dword [esp+4] = loops ;------------------------------------------------------------------------------ align 64 StackReader: _StackReader: push ebx push ecx mov ecx, [esp+4+8] ; loops to do. push dword 7000 ; [esp+24] push dword 6000 ; [esp+20] push dword 5000 ; [esp+16] push dword 4000 ; [esp+12] push dword 3000 ; [esp+8] push dword 2000 ; [esp+4] push dword 1000 ; [esp] .L1: mov eax, [esp] mov eax, [esp+8] mov eax, [esp+12] mov eax, [esp+16] mov eax, [esp+20] mov eax, [esp+4] mov eax, [esp+24] mov eax, [esp] mov eax, [esp] mov eax, [esp+8] mov eax, [esp+12] mov eax, [esp+16] mov eax, [esp+20] mov eax, [esp+4] mov eax, [esp+24] mov eax, [esp] mov eax, [esp] mov eax, [esp+8] mov eax, [esp+12] mov eax, [esp+16] mov eax, [esp+20] mov eax, [esp+4] mov eax, [esp+24] mov eax, [esp+4] mov eax, [esp+4] mov eax, [esp+8] mov eax, [esp+12] mov eax, [esp+16] mov eax, [esp+20] mov eax, [esp+4] mov eax, [esp+24] mov eax, [esp+4] mov ebx, [esp] mov ebx, [esp+8] mov ebx, [esp+12] mov ebx, [esp+16] mov ebx, [esp+20] mov ebx, [esp+4] mov ebx, [esp+24] mov ebx, [esp] mov ebx, [esp] mov ebx, [esp+8] mov ebx, [esp+12] mov ebx, [esp+16] mov ebx, [esp+20] mov ebx, [esp+4] mov ebx, [esp+24] mov ebx, [esp] mov ebx, [esp] mov ebx, [esp+8] mov ebx, [esp+12] mov ebx, [esp+16] mov ebx, [esp+20] mov ebx, [esp+4] mov ebx, [esp+24] mov ebx, [esp+4] mov ebx, [esp+4] mov ebx, [esp+8] mov ebx, [esp+12] mov ebx, [esp+16] mov ebx, [esp+20] mov ebx, [esp+4] mov ebx, [esp+24] mov ebx, [esp+4] dec ecx jnz .L1 add esp, 28 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: StackWriter ; Purpose: Writes 32-bit values into the stack from registers of ; the main register set, effectively testing L1 cache access ; *and* effective-address calculation speed. ; Params: ; dword [esp+4] = loops ;------------------------------------------------------------------------------ align 64 StackWriter: _StackWriter: push ebx push ecx mov ecx, [esp+4+8] ; loops to do. push dword 7000 ; [esp+24] push dword 6000 ; [esp+20] push dword 5000 ; [esp+16] push dword 4000 ; [esp+12] push dword 3000 ; [esp+8] push dword 2000 ; [esp+4] push dword 1000 ; [esp] xor eax, eax mov ebx, 0xffffffff .L1: mov [esp], eax mov [esp+8], eax mov [esp+12], eax mov [esp+16], eax mov [esp+20], eax mov [esp+4], eax mov [esp+24], eax mov [esp], eax mov [esp], eax mov [esp+8], eax mov [esp+12], eax mov [esp+16], eax mov [esp+20], eax mov [esp+4], eax mov [esp+24], eax mov [esp], eax mov [esp], eax mov [esp+8], eax mov [esp+12], eax mov [esp+16], eax mov [esp+20], eax mov [esp+4], eax mov [esp+24], eax mov [esp+4], eax mov [esp+4], eax mov [esp+8], eax mov [esp+12], eax mov [esp+16], eax mov [esp+20], eax mov [esp+4], eax mov [esp+24], eax mov [esp+4], eax mov [esp], ebx mov [esp+8], ebx mov [esp+12], ebx mov [esp+16], ebx mov [esp+20], ebx mov [esp+4], ebx mov [esp+24], ebx mov [esp], ebx mov [esp], ebx mov [esp+8], ebx mov [esp+12], ebx mov [esp+16], ebx mov [esp+20], ebx mov [esp+4], ebx mov [esp+24], ebx mov [esp], ebx mov [esp], ebx mov [esp+8], ebx mov [esp+12], ebx mov [esp+16], ebx mov [esp+20], ebx mov [esp+4], ebx mov [esp+24], ebx mov [esp+4], ebx mov [esp+4], ebx mov [esp+8], ebx mov [esp+12], ebx mov [esp+16], ebx mov [esp+20], ebx mov [esp+4], ebx mov [esp+24], ebx mov [esp+4], ebx sub ecx, 1 jnz .L1 add esp, 28 pop ecx pop ebx ret ;------------------------------------------------------------------------------ ; Name: Register8ToVector ; Purpose: Writes 8-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: dword [esp + 4] ;------------------------------------------------------------------------------ align 64 Register8ToVector: _Register8ToVector: mov eax, [esp + 4] sal eax, 4 ; Force some repetition. .L1: pinsrb xmm1, al, 0 ; 64 transfers x 1 byte = 64 bytes pinsrb xmm2, bl, 1 pinsrb xmm3, cl, 2 pinsrb xmm1, dl, 3 pinsrb xmm2, sil, 4 pinsrb xmm3, dil, 5 pinsrb xmm0, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm0, al, 0 pinsrb xmm1, bl, 1 pinsrb xmm2, cl, 2 pinsrb xmm3, dl, 3 pinsrb xmm3, al, 4 pinsrb xmm2, bl, 5 pinsrb xmm1, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm1, al, 0 pinsrb xmm2, al, 1 pinsrb xmm3, al, 2 pinsrb xmm1, al, 3 pinsrb xmm2, al, 4 pinsrb xmm3, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm0, al, 0 pinsrb xmm0, al, 1 pinsrb xmm0, al, 2 pinsrb xmm0, al, 3 pinsrb xmm0, al, 4 pinsrb xmm0, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm1, al, 0 pinsrb xmm2, bl, 1 pinsrb xmm3, cl, 2 pinsrb xmm1, dl, 3 pinsrb xmm2, sil, 4 pinsrb xmm3, dil, 5 pinsrb xmm0, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm0, al, 10 pinsrb xmm1, bl, 11 pinsrb xmm2, cl, 12 pinsrb xmm3, dl, 13 pinsrb xmm3, dil, 14 pinsrb xmm2, cl, 15 pinsrb xmm1, al, 6 pinsrb xmm0, bpl, 7 pinsrb xmm1, al, 10 pinsrb xmm2, al, 11 pinsrb xmm3, al, 12 pinsrb xmm1, al, 13 pinsrb xmm2, al, 14 pinsrb xmm3, al, 15 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm0, al, 9 pinsrb xmm0, al, 8 pinsrb xmm0, al, 11 pinsrb xmm0, al, 3 pinsrb xmm0, al, 4 pinsrb xmm0, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register16ToVector ; Purpose: Writes 16-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register16ToVector: _Register16ToVector: mov eax, [esp + 4] sal eax, 3 ; Force some repetition. .L1: pinsrw xmm1, ax, 0 ; 64 transfers x 2 bytes = 128 bytes pinsrw xmm2, bx, 1 pinsrw xmm3, cx, 2 pinsrw xmm1, dx, 3 pinsrw xmm2, si, 4 pinsrw xmm3, di, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm0, ax, 0 pinsrw xmm1, bx, 1 pinsrw xmm2, cx, 2 pinsrw xmm3, dx, 3 pinsrw xmm3, si, 4 pinsrw xmm2, di, 5 pinsrw xmm1, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm1, ax, 0 pinsrw xmm2, ax, 1 pinsrw xmm3, ax, 2 pinsrw xmm1, ax, 3 pinsrw xmm2, ax, 4 pinsrw xmm3, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm0, ax, 0 pinsrw xmm0, ax, 1 pinsrw xmm0, ax, 2 pinsrw xmm0, ax, 3 pinsrw xmm0, ax, 4 pinsrw xmm0, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm1, ax, 0 pinsrw xmm2, bx, 1 pinsrw xmm3, cx, 2 pinsrw xmm1, dx, 3 pinsrw xmm2, si, 4 pinsrw xmm3, di, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm0, ax, 0 pinsrw xmm1, bx, 1 pinsrw xmm2, cx, 2 pinsrw xmm3, dx, 3 pinsrw xmm3, si, 4 pinsrw xmm2, di, 5 pinsrw xmm1, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm1, ax, 0 pinsrw xmm2, ax, 1 pinsrw xmm3, ax, 2 pinsrw xmm1, ax, 3 pinsrw xmm2, ax, 4 pinsrw xmm3, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm0, ax, 0 pinsrw xmm0, ax, 1 pinsrw xmm0, ax, 2 pinsrw xmm0, ax, 3 pinsrw xmm0, ax, 4 pinsrw xmm0, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register32ToVector ; Purpose: Writes 32-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register32ToVector: _Register32ToVector: mov eax, [esp + 4] sal eax, 2 ; Force some repetition. .L1: pinsrd xmm1, eax, 0 ; Each xfer moves 4 bytes so to move 256 bytes pinsrd xmm2, ebx, 1 ; we need 64 transfers. pinsrd xmm3, ecx, 2 pinsrd xmm1, edx, 3 pinsrd xmm2, esi, 0 pinsrd xmm3, edi, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, esp, 3 pinsrd xmm0, eax, 0 pinsrd xmm1, ebx, 1 pinsrd xmm2, ecx, 2 pinsrd xmm3, edx, 3 pinsrd xmm3, esi, 3 pinsrd xmm2, edi, 2 pinsrd xmm1, ebp, 1 pinsrd xmm0, esp, 0 pinsrd xmm1, eax, 0 pinsrd xmm2, eax, 1 pinsrd xmm3, eax, 2 pinsrd xmm1, eax, 3 pinsrd xmm2, eax, 0 pinsrd xmm3, eax, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, ebx, 3 pinsrd xmm0, eax, 0 pinsrd xmm0, eax, 1 pinsrd xmm0, eax, 2 pinsrd xmm0, eax, 3 pinsrd xmm0, eax, 0 pinsrd xmm0, eax, 0 pinsrd xmm0, ebp, 0 pinsrd xmm0, ebx, 0 pinsrd xmm1, eax, 0 pinsrd xmm2, ebx, 1 pinsrd xmm3, ecx, 2 pinsrd xmm1, edx, 3 pinsrd xmm2, esi, 0 pinsrd xmm3, edi, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, esp, 3 pinsrd xmm0, eax, 0 pinsrd xmm1, ebx, 1 pinsrd xmm2, ecx, 2 pinsrd xmm3, edx, 3 pinsrd xmm3, esi, 3 pinsrd xmm2, edi, 2 pinsrd xmm1, ebp, 1 pinsrd xmm0, esp, 0 pinsrd xmm1, eax, 0 pinsrd xmm2, eax, 1 pinsrd xmm3, eax, 2 pinsrd xmm1, eax, 3 pinsrd xmm2, eax, 0 pinsrd xmm3, eax, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, ebx, 3 pinsrd xmm0, eax, 0 pinsrd xmm0, eax, 1 pinsrd xmm0, eax, 2 pinsrd xmm0, eax, 3 pinsrd xmm0, eax, 0 pinsrd xmm0, eax, 0 pinsrd xmm0, ebp, 0 pinsrd xmm0, ebx, 0 pinsrd xmm0, esp, 0 dec eax jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register64ToVector ; Purpose: Writes 64-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ Register64ToVector: _Register64ToVector: ret ;------------------------------------------------------------------------------ ; Name: Vector8ToRegister ; Purpose: Writes 8-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector8ToRegister: _Vector8ToRegister: mov eax, [esp + 4] sal eax, 4 ; Force some repetition. push ebx .L1: pextrb ebx, xmm1, 0 pextrb ebx, xmm2, 1 pextrb ebx, xmm3, 2 pextrb ebx, xmm1, 3 pextrb ebx, xmm2, 4 pextrb ebx, xmm3, 5 pextrb ebx, xmm0, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm0, 0 pextrb ebx, xmm1, 1 pextrb ebx, xmm2, 2 pextrb ebx, xmm3, 3 pextrb ebx, xmm3, 4 pextrb ebx, xmm2, 15 pextrb ebx, xmm1, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm1, 0 pextrb ebx, xmm2, 1 pextrb ebx, xmm3, 2 pextrb ebx, xmm1, 3 pextrb ebx, xmm2, 4 pextrb ebx, xmm3, 5 pextrb ebx, xmm0, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm0, 0 pextrb ebx, xmm1, 1 pextrb ebx, xmm2, 2 pextrb ebx, xmm3, 3 pextrb ebx, xmm3, 4 pextrb ebx, xmm2, 5 pextrb ebx, xmm1, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm1, 0 pextrb ebx, xmm2, 1 pextrb ebx, xmm3, 2 pextrb ebx, xmm1, 13 pextrb ebx, xmm2, 14 pextrb ebx, xmm3, 15 pextrb ebx, xmm0, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm0, 10 pextrb ebx, xmm1, 11 pextrb ebx, xmm2, 12 pextrb ebx, xmm3, 13 pextrb ebx, xmm3, 14 pextrb ebx, xmm2, 15 pextrb ebx, xmm1, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm1, 0 pextrb ebx, xmm2, 1 pextrb ebx, xmm3, 2 pextrb ebx, xmm1, 3 pextrb ebx, xmm2, 4 pextrb ebx, xmm3, 5 pextrb ebx, xmm0, 6 pextrb ebx, xmm0, 7 pextrb ebx, xmm0, 0 pextrb ebx, xmm1, 1 pextrb ebx, xmm2, 2 pextrb ebx, xmm3, 3 pextrb ebx, xmm3, 4 pextrb ebx, xmm2, 5 pextrb ebx, xmm1, 6 pextrb ebx, xmm0, 7 dec eax jnz .L1 pop ebx ret ;------------------------------------------------------------------------------ ; Name: Vector16ToRegister ; Purpose: Writes 16-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector16ToRegister: _Vector16ToRegister: mov eax, [esp + 4] sal eax, 3 ; Force some repetition. push ebx .L1: pextrw ebx, xmm1, 0 pextrw ebx, xmm2, 1 pextrw ebx, xmm3, 2 pextrw ebx, xmm1, 3 pextrw ebx, xmm2, 4 pextrw ebx, xmm3, 5 pextrw ebx, xmm0, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm0, 0 pextrw ebx, xmm1, 1 pextrw ebx, xmm2, 2 pextrw ebx, xmm3, 3 pextrw ebx, xmm3, 4 pextrw ebx, xmm2, 5 pextrw ebx, xmm1, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm1, 0 pextrw ebx, xmm2, 1 pextrw ebx, xmm3, 2 pextrw ebx, xmm1, 3 pextrw ebx, xmm2, 4 pextrw ebx, xmm3, 5 pextrw ebx, xmm0, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm0, 0 pextrw ebx, xmm1, 1 pextrw ebx, xmm2, 2 pextrw ebx, xmm3, 3 pextrw ebx, xmm3, 4 pextrw ebx, xmm2, 5 pextrw ebx, xmm1, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm1, 0 pextrw ebx, xmm2, 1 pextrw ebx, xmm3, 2 pextrw ebx, xmm1, 3 pextrw ebx, xmm2, 4 pextrw ebx, xmm3, 5 pextrw ebx, xmm0, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm0, 0 pextrw ebx, xmm1, 1 pextrw ebx, xmm2, 2 pextrw ebx, xmm3, 3 pextrw ebx, xmm3, 4 pextrw ebx, xmm2, 5 pextrw ebx, xmm1, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm1, 0 pextrw ebx, xmm2, 1 pextrw ebx, xmm3, 2 pextrw ebx, xmm1, 3 pextrw ebx, xmm2, 4 pextrw ebx, xmm3, 5 pextrw ebx, xmm0, 6 pextrw ebx, xmm0, 7 pextrw ebx, xmm0, 0 pextrw ebx, xmm1, 1 pextrw ebx, xmm2, 2 pextrw ebx, xmm3, 3 pextrw ebx, xmm3, 4 pextrw ebx, xmm2, 5 pextrw ebx, xmm1, 6 pextrw ebx, xmm0, 7 dec eax jnz .L1 pop ebx ret ;------------------------------------------------------------------------------ ; Name: Vector32ToRegister ; Purpose: Writes 32-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector32ToRegister: _Vector32ToRegister: mov eax, [esp + 4] sal eax, 2 ; Force some repetition. push ebx .L1: pextrd ebx, xmm1, 0 pextrd ebx, xmm2, 1 pextrd ebx, xmm3, 2 pextrd ebx, xmm1, 3 pextrd ebx, xmm2, 0 pextrd ebx, xmm3, 1 pextrd ebx, xmm0, 2 pextrd ebx, xmm0, 3 pextrd ebx, xmm0, 0 pextrd ebx, xmm1, 1 pextrd ebx, xmm2, 2 pextrd ebx, xmm3, 3 pextrd ebx, xmm3, 3 pextrd ebx, xmm2, 2 pextrd ebx, xmm1, 1 pextrd ebx, xmm0, 0 pextrd ebx, xmm1, 0 pextrd ebx, xmm2, 1 pextrd ebx, xmm3, 2 pextrd ebx, xmm1, 3 pextrd ebx, xmm2, 0 pextrd ebx, xmm3, 1 pextrd ebx, xmm0, 2 pextrd ebx, xmm0, 3 pextrd ebx, xmm0, 0 pextrd ebx, xmm1, 1 pextrd ebx, xmm2, 2 pextrd ebx, xmm3, 3 pextrd ebx, xmm3, 3 pextrd ebx, xmm2, 2 pextrd ebx, xmm1, 1 pextrd ebx, xmm0, 0 dec eax jnz .L1 pop ebx ret ;------------------------------------------------------------------------------ ; Name: Vector64ToRegister ; Purpose: Writes 64-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ Vector64ToRegister: _Vector64ToRegister: ret ;------------------------------------------------------------------------------ ; Name: CopyAVX ; Purpose: Copies memory chunks that are 32-byte aligned. ; Params: [esp + 4] = ptr to destination memory area ; [esp + 8] = ptr to source memory area ; [esp + 12] = length in bytes ; [esp + 16] = loops ;------------------------------------------------------------------------------ align 64 CopyAVX: _CopyAVX: vzeroupper ; Register usage: ; esi = source ; edi = dest ; ecx = loops ; edx = length push esi push edi push ecx push edx mov edi, [esp + 4 + 16] mov esi, [esp + 8 + 16] mov edx, [esp + 12 + 16] mov ecx, [esp + 16 + 16] shr edx, 8 ; Ensure length is multiple of 256. shl edx, 8 .L1: mov eax, edx .L2: vmovdqa ymm0, [esi] vmovdqa ymm1, [32+esi] vmovdqa ymm2, [64+esi] vmovdqa ymm3, [96+esi] vmovdqa [edi], ymm0 vmovdqa [32+edi], ymm1 vmovdqa [64+edi], ymm2 vmovdqa [96+edi], ymm3 vmovdqa ymm0, [128+esi] vmovdqa ymm1, [128+32+esi] vmovdqa ymm2, [128+64+esi] vmovdqa ymm3, [128+96+esi] vmovdqa [128+edi], ymm0 vmovdqa [128+32+edi], ymm1 vmovdqa [128+64+edi], ymm2 vmovdqa [128+96+edi], ymm3 add esi, 256 add edi, 256 sub eax, 256 jnz .L2 sub esi, edx ; rsi now points to start. sub edi, edx ; rdi now points to start. dec ecx jnz .L1 pop edx pop ecx pop edi pop esi ret ;------------------------------------------------------------------------------ ; Name: CopySSE ; Purpose: Copies memory chunks that are 16-byte aligned. ; Params: [esp + 4] = ptr to destination memory area ; [esp + 8] = ptr to source memory area ; [esp + 12] = length in bytes ; [esp + 16] = loops ;------------------------------------------------------------------------------ align 64 CopySSE: _CopySSE: ; Register usage: ; esi = source ; edi = dest ; ecx = loops ; edx = length push esi push edi push ecx push edx mov edi, [esp + 4 + 16] mov esi, [esp + 8 + 16] mov edx, [esp + 12 + 16] mov ecx, [esp + 16 + 16] shr edx, 7 ; Ensure length is multiple of 128. shl edx, 7 ; Save our non-parameter XMM registers. sub esp, 64 movdqu [esp], xmm4 movdqu [16+esp], xmm5 movdqu [32+esp], xmm6 movdqu [48+esp], xmm7 .L1: mov eax, edx .L2: movdqa xmm0, [esi] movdqa xmm1, [16+esi] movdqa xmm2, [32+esi] movdqa xmm3, [48+esi] movdqa xmm4, [64+esi] movdqa xmm5, [80+esi] movdqa xmm6, [96+esi] movdqa xmm7, [112+esi] ; 32-bit lacks xmm8 - xmm15. movdqa [edi], xmm0 movdqa [16+edi], xmm1 movdqa [32+edi], xmm2 movdqa [48+edi], xmm3 movdqa [64+edi], xmm4 movdqa [80+edi], xmm5 movdqa [96+edi], xmm6 movdqa [112+edi], xmm7 add esi, 128 add edi, 128 sub eax, 128 jnz .L2 sub esi, edx ; rsi now points to start. sub edi, edx ; rdi now points to start. dec ecx jnz .L1 movdqu xmm4, [0+esp] movdqu xmm5, [16+esp] movdqu xmm6, [32+esp] movdqu xmm7, [48+esp] add esp, 64 pop edx pop ecx pop edi pop esi ret ;------------------------------------------------------------------------------ ; Name: CopySSE_128bytes ; Purpose: Copies memory chunks that are 16-byte aligned. ; Params: [esp + 4] = ptr to destination memory area ; [esp + 8] = ptr to source memory area ; [esp + 12] = length in bytes ; [esp + 16] = loops ;------------------------------------------------------------------------------ align 64 CopySSE_128bytes: _CopySSE_128bytes: jmp CopySSE ;------------------------------------------------------------------------------ ; Name: IncrementRegisters ; Purpose: Increments 32-bit values in registers. ; Params: [esp + 4] = loops ;------------------------------------------------------------------------------ align 64 IncrementRegisters: _IncrementRegisters: push ebp mov ebp, [esp+4] .L1: inc eax inc ebx inc ecx inc edx inc esi inc edi inc ebp inc esp dec eax dec ebx dec ecx dec edx dec esi dec edi dec ebp dec esp inc eax inc ebx inc ecx inc edx inc esi inc edi inc ebp inc esp dec eax dec ebx dec ecx dec edx dec esi dec edi dec ebp dec esp dec ebp jnz .L1 pop ebp ret ;------------------------------------------------------------------------------ ; Name: IncrementStack ; Purpose: Increments 32-bit values on stack. ; Params: [esp + 4] = loops ;------------------------------------------------------------------------------ align 64 IncrementStack: _IncrementStack: push ebp mov ebp, [esp+4] sub esp, 64 .L1: inc dword [esp] inc dword [esp+4] inc dword [esp+8] inc dword [esp+12] inc dword [esp+16] inc dword [esp+20] inc dword [esp+24] inc dword [esp+28] inc dword [esp+32] inc dword [esp+36] inc dword [esp+40] inc dword [esp+44] inc dword [esp+48] inc dword [esp+52] inc dword [esp+56] inc dword [esp+60] inc dword [esp] inc dword [esp+4] inc dword [esp+8] inc dword [esp+12] inc dword [esp+16] inc dword [esp+20] inc dword [esp+24] inc dword [esp+28] inc dword [esp+32] inc dword [esp+36] inc dword [esp+40] inc dword [esp+44] inc dword [esp+48] inc dword [esp+52] inc dword [esp+56] inc dword [esp+60] dec ebp jnz .L1 add esp, 64 pop ebp ret CPU-X-4.2.0/src/bandwidth/routines-x86-64bit.asm000066400000000000000000001555121403012130000210200ustar00rootroot00000000000000;============================================================================ ; bandwidth, a benchmark to estimate memory transfer bandwidth. ; Copyright (C) 2005-2017 by Zack T Smith. ; ; 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 St, Fifth Floor, Boston, MA 02110-1301 USA ; ; The author may be reached at veritas@comcast.net. ;============================================================================= bits 64 cpu ia64 global CopySSE global CopySSE_128bytes global CopyAVX global _CopyAVX global ReaderLODSQ global _ReaderLODSQ global ReaderLODSD global _ReaderLODSD global ReaderLODSW global _ReaderLODSW global ReaderLODSB global _ReaderLODSB global IncrementRegisters global _IncrementRegisters global IncrementStack global _IncrementStack global RandomReader global RandomReaderSSE2 global RandomReaderSSE2_bypass global RandomWriter global RandomWriterSSE2 global RandomWriterSSE2_bypass global Reader global Reader_128bytes global ReaderAVX global RandomReaderAVX global ReaderSSE2 global ReaderSSE2_128bytes global ReaderSSE2_bypass global ReaderSSE2_128bytes_bypass global Register16ToVector global Register32ToVector global Register64ToVector global Register8ToVector global RegisterToRegister global RegisterToVector global StackReader global StackWriter global Vector16ToRegister global Vector32ToRegister global Vector64ToRegister global Vector8ToRegister global VectorToRegister global VectorToVector global VectorToVectorAVX global Writer global Writer_128bytes global WriterAVX global RandomWriterAVX global WriterSSE2 global WriterSSE2_128bytes global WriterSSE2_bypass global WriterSSE2_128bytes_bypass global WriterAVX_bypass global _WriterAVX_bypass global _CopySSE global _CopySSE_128bytes global _RandomReader global _RandomReaderSSE2 global _RandomReaderSSE2_bypass global _RandomWriter global _RandomWriterSSE2 global _RandomWriterSSE2_bypass global _Reader global _ReaderAVX global _RandomReaderAVX global _Reader_128bytes global _ReaderSSE2 global _ReaderSSE2_bypass global _ReaderSSE2_128bytes global _ReaderSSE2_128bytes_bypass global _Register16ToVector global _Register32ToVector global _Register64ToVector global _Register8ToVector global _RegisterToRegister global _RegisterToVector global _StackReader global _StackWriter global _Vector16ToRegister global _Vector32ToRegister global _Vector64ToRegister global _Vector8ToRegister global _VectorToRegister global _VectorToVector global _VectorToVectorAVX global _Writer global _Writer_128bytes global _WriterSSE2 global _WriterAVX global _RandomWriterAVX global _WriterSSE2_128bytes global _WriterSSE2_bypass global _WriterSSE2_128bytes_bypass global get_cpuid_cache_info global _get_cpuid_cache_info global get_cpuid_family global _get_cpuid_family global get_cpuid1_ecx global _get_cpuid1_ecx global get_cpuid1_edx global _get_cpuid1_edx global get_cpuid7_ebx global _get_cpuid7_ebx global get_cpuid_80000001_ecx global _get_cpuid_80000001_ecx global get_cpuid_80000001_edx global _get_cpuid_80000001_edx ; Note: ; Unix ABI says integer param are put in these registers in this order: ; rdi, rsi, rdx, rcx, r8, r9 section .text ;------------------------------------------------------------------------------ ; Name: get_cpuid_cache_info ; get_cpuid_cache_info: _get_cpuid_cache_info: push rbx push rcx push rdx mov rax, 4 mov rcx, rsi cpuid mov [rdi], eax mov [rdi+4], ebx mov [rdi+8], ecx mov [rdi+12], edx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_family ; get_cpuid_family: _get_cpuid_family: push rbx push rcx push rdx xor rax, rax cpuid mov [rdi], ebx mov [rdi+4], edx mov [rdi+8], ecx mov byte [rdi+12], 0 pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid1_ecx ; get_cpuid1_ecx: _get_cpuid1_ecx: push rbx push rcx push rdx mov rax, 1 cpuid mov rax, rcx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid7_ebx ; get_cpuid7_ebx: _get_cpuid7_ebx: push rbx push rcx push rdx mov rax, 7 xor rcx, rcx cpuid mov rax, rbx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid1_edx ; get_cpuid1_edx: _get_cpuid1_edx: push rbx push rcx push rdx mov rax, 1 cpuid mov rax, rdx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_80000001_ecx ; get_cpuid_80000001_ecx: _get_cpuid_80000001_ecx: push rbx push rcx push rdx mov rax, 0x80000001 cpuid mov rax, rcx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: get_cpuid_80000001_edx ; get_cpuid_80000001_edx: _get_cpuid_80000001_edx: push rbx push rcx push rdx mov rax, 0x80000001 cpuid mov rax, rdx pop rdx pop rcx pop rbx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSQ ; Purpose: Reads 64-bit values sequentially from an area of memory ; using LODSQ instruction. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSQ: _ReaderLODSQ: push rcx ; REP counter push r10 push r11 mov r10, rdi mov r11, rsi shr r11, 3 ; length in quadwords rounded down. .L1: mov rsi, r10 ; buffer start mov rcx, r11 ; # of quadwords rep lodsq dec rdx jnz .L1 pop r11 pop r10 pop rcx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSD ; Purpose: Reads 32-bit values sequentially from an area of memory ; using LODSD instruction. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSD: _ReaderLODSD: push rcx ; REP counter push r10 push r11 mov r10, rdi mov r11, rsi shr r11, 2 ; length in double words rounded down. .L1: mov rsi, r10 ; buffer start mov rcx, r11 ; # of double words rep lodsd dec rdx jnz .L1 pop r11 pop r10 pop rcx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSW ; Purpose: Reads 16-bit values sequentially from an area of memory ; using LODSW instruction. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSW: _ReaderLODSW: push rcx ; REP counter push r10 push r11 mov r10, rdi mov r11, rsi shr r11, 1 ; length in words rounded down. .L1: mov rsi, r10 ; buffer start mov rcx, r11 ; # of words rep lodsw dec rdx jnz .L1 pop r11 pop r10 pop rcx ret ;------------------------------------------------------------------------------ ; Name: ReaderLODSB ; Purpose: Reads 8-bit values sequentially from an area of memory ; using LODSB instruction. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 32 ReaderLODSB: _ReaderLODSB: push rcx ; REP counter push r10 push r11 mov r10, rdi mov r11, rsi .L1: mov rsi, r10 ; buffer start mov rcx, r11 ; # of bytes rep lodsb dec rdx jnz .L1 pop r11 pop r10 pop rcx ret ;------------------------------------------------------------------------------ ; Name: Reader ; Purpose: Reads 64-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 Reader: _Reader: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: mov rax, [r10] mov rax, [8+r10] mov rax, [16+r10] mov rax, [24+r10] mov rax, [32+r10] mov rax, [40+r10] mov rax, [48+r10] mov rax, [56+r10] mov rax, [64+r10] mov rax, [72+r10] mov rax, [80+r10] mov rax, [88+r10] mov rax, [96+r10] mov rax, [104+r10] mov rax, [112+r10] mov rax, [120+r10] mov rax, [128+r10] mov rax, [136+r10] mov rax, [144+r10] mov rax, [152+r10] mov rax, [160+r10] mov rax, [168+r10] mov rax, [176+r10] mov rax, [184+r10] mov rax, [192+r10] mov rax, [200+r10] mov rax, [208+r10] mov rax, [216+r10] mov rax, [224+r10] mov rax, [232+r10] mov rax, [240+r10] mov rax, [248+r10] add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: Reader_128bytes ; Purpose: Reads 64-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 Reader_128bytes: _Reader_128bytes: push r10 add rsi, rdi ; rdi now points to end. .L1: mov r10, rdi .L2: mov rax, [r10] mov rax, [8+r10] mov rax, [16+r10] mov rax, [24+r10] mov rax, [32+r10] mov rax, [40+r10] mov rax, [48+r10] mov rax, [56+r10] mov rax, [64+r10] mov rax, [72+r10] mov rax, [80+r10] mov rax, [88+r10] mov rax, [96+r10] mov rax, [104+r10] mov rax, [112+r10] mov rax, [120+r10] add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomReader ; Purpose: Reads 64-bit values randomly from an area of memory. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ;------------------------------------------------------------------------------ align 64 RandomReader: _RandomReader: push r10 push r11 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Note, 64-bit pointers. mov rax, [96+r10] mov rax, [r10] mov rax, [120+r10] mov rax, [184+r10] mov rax, [160+r10] mov rax, [176+r10] mov rax, [112+r10] mov rax, [80+r10] mov rax, [32+r10] mov rax, [128+r10] mov rax, [88+r10] mov rax, [40+r10] mov rax, [48+r10] mov rax, [72+r10] mov rax, [200+r10] mov rax, [24+r10] mov rax, [152+r10] mov rax, [16+r10] mov rax, [248+r10] mov rax, [56+r10] mov rax, [240+r10] mov rax, [208+r10] mov rax, [104+r10] mov rax, [216+r10] mov rax, [136+r10] mov rax, [232+r10] mov rax, [64+r10] mov rax, [224+r10] mov rax, [144+r10] mov rax, [192+r10] mov rax, [8+r10] mov rax, [168+r10] inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomReaderSSE2 ; Purpose: Reads 128-bit values randomly from an area of memory. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ;------------------------------------------------------------------------------ align 64 RandomReaderSSE2: _RandomReaderSSE2: push r10 push r11 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] movdqa xmm0, [240+r10] movdqa xmm0, [128+r10] movdqa xmm0, [64+r10] movdqa xmm0, [208+r10] movdqa xmm0, [112+r10] movdqa xmm0, [176+r10] movdqa xmm0, [144+r10] movdqa xmm0, [r10] movdqa xmm0, [96+r10] movdqa xmm0, [16+r10] movdqa xmm0, [192+r10] movdqa xmm0, [160+r10] movdqa xmm0, [32+r10] movdqa xmm0, [48+r10] movdqa xmm0, [224+r10] movdqa xmm0, [80+r10] inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomReaderSSE2_bypass ; Purpose: Reads 128-bit values randomly from an area of memory. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ;------------------------------------------------------------------------------ align 64 RandomReaderSSE2_bypass: _RandomReaderSSE2_bypass: push r10 push r11 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; SSE 4.1 required prefetchnta [r10+192] movntdqa xmm0, [240+r10] prefetchnta [r10] movntdqa xmm0, [r10] prefetchnta [r10+128] movntdqa xmm0, [128+r10] prefetchnta [r10+64] movntdqa xmm0, [64+r10] movntdqa xmm0, [208+r10] movntdqa xmm0, [112+r10] movntdqa xmm0, [48+r10] movntdqa xmm0, [176+r10] movntdqa xmm0, [144+r10] movntdqa xmm0, [96+r10] movntdqa xmm0, [16+r10] movntdqa xmm0, [160+r10] movntdqa xmm0, [32+r10] movntdqa xmm0, [224+r10] movntdqa xmm0, [80+r10] movntdqa xmm0, [192+r10] inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomWriter ; Purpose: Writes 64-bit values randomly to an area of memory. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ; rcx = datum to write ;------------------------------------------------------------------------------ align 64 RandomWriter: _RandomWriter: push r10 push r11 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Note, 64-bit pointers. mov [96+r10], rcx mov [r10], rcx mov [120+r10], rcx mov [184+r10], rcx mov [160+r10], rcx mov [176+r10], rcx mov [112+r10], rcx mov [80+r10], rcx mov [32+r10], rcx mov [128+r10], rcx mov [88+r10], rcx mov [40+r10], rcx mov [48+r10], rcx mov [72+r10], rcx mov [200+r10], rcx mov [24+r10], rcx mov [152+r10], rcx mov [16+r10], rcx mov [248+r10], rcx mov [56+r10], rcx mov [240+r10], rcx mov [208+r10], rcx mov [104+r10], rcx mov [216+r10], rcx mov [136+r10], rcx mov [232+r10], rcx mov [64+r10], rcx mov [224+r10], rcx mov [144+r10], rcx mov [192+r10], rcx mov [8+r10], rcx mov [168+r10], rcx inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomWriterSSE2 ; Purpose: Writes 128-bit values randomly to an area of memory. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ; rcx = datum to write ;------------------------------------------------------------------------------ align 64 RandomWriterSSE2: _RandomWriterSSE2: push r10 push r11 movq xmm0, rcx ; Create duplicated 128-bit datum movq xmm1, rcx pslldq xmm1, 64 por xmm0, xmm1 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Note, 64-bit pointers. movdqa [240+r10], xmm0 movdqa [128+r10], xmm0 movdqa [208+r10], xmm0 movdqa [112+r10], xmm0 movdqa [64+r10], xmm0 movdqa [176+r10], xmm0 movdqa [144+r10], xmm0 movdqa [r10], xmm0 movdqa [96+r10], xmm0 movdqa [16+r10], xmm0 movdqa [192+r10], xmm0 movdqa [160+r10], xmm0 movdqa [32+r10], xmm0 movdqa [48+r10], xmm0 movdqa [224+r10], xmm0 movdqa [80+r10], xmm0 inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: RandomWriterSSE2_bypass ; Purpose: Writes 128-bit values randomly into memory, bypassing caches. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ; rcx = datum to write ;------------------------------------------------------------------------------ align 64 RandomWriterSSE2_bypass: _RandomWriterSSE2_bypass: push r10 push r11 movq xmm0, rcx ; Create duplicated 128-bit datum movq xmm1, rcx pslldq xmm1, 64 por xmm0, xmm1 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Note, 64-bit pointers. movntdq [240+r10], xmm0 movntdq [128+r10], xmm0 movntdq [208+r10], xmm0 movntdq [112+r10], xmm0 movntdq [64+r10], xmm0 movntdq [176+r10], xmm0 movntdq [144+r10], xmm0 movntdq [r10], xmm0 movntdq [96+r10], xmm0 movntdq [16+r10], xmm0 movntdq [192+r10], xmm0 movntdq [160+r10], xmm0 movntdq [32+r10], xmm0 movntdq [48+r10], xmm0 movntdq [224+r10], xmm0 movntdq [80+r10], xmm0 inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_128bytes ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_128bytes: _ReaderSSE2_128bytes: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: movdqa xmm0, [r10] ; Read aligned to 16-byte boundary. movdqa xmm0, [16+r10] movdqa xmm0, [32+r10] movdqa xmm0, [48+r10] movdqa xmm0, [64+r10] movdqa xmm0, [80+r10] movdqa xmm0, [96+r10] movdqa xmm0, [112+r10] add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2 ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2: _ReaderSSE2: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: movdqa xmm0, [r10] ; Read aligned to 16-byte boundary. movdqa xmm0, [16+r10] movdqa xmm0, [32+r10] movdqa xmm0, [48+r10] movdqa xmm0, [64+r10] movdqa xmm0, [80+r10] movdqa xmm0, [96+r10] movdqa xmm0, [112+r10] movdqa xmm0, [128+r10] movdqa xmm0, [144+r10] movdqa xmm0, [160+r10] movdqa xmm0, [176+r10] movdqa xmm0, [192+r10] movdqa xmm0, [208+r10] movdqa xmm0, [224+r10] movdqa xmm0, [240+r10] add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: ReaderAVX ; Purpose: Reads 256-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 ReaderAVX: _ReaderAVX: ; vzeroupper sub rsp, 32 vmovdqu [rsp], ymm0 sub rsp, 32 vmovdqu [rsp], ymm1 sub rsp, 32 vmovdqu [rsp], ymm2 sub rsp, 32 vmovdqu [rsp], ymm3 push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: vmovdqa ymm0, [r10] ; Read aligned to 32-byte boundary. vmovdqa ymm1, [32+r10] vmovdqa ymm2, [64+r10] vmovdqa ymm3, [96+r10] vmovdqa ymm0, [128+r10] vmovdqa ymm1, [160+r10] vmovdqa ymm2, [192+r10] vmovdqa ymm3, [224+r10] add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 vmovdqu ymm3, [rsp] add rsp, 32 vmovdqu ymm2, [rsp] add rsp, 32 vmovdqu ymm1, [rsp] add rsp, 32 vmovdqu ymm0, [rsp] add rsp, 32 ret ;------------------------------------------------------------------------------ ; Name: RandomReaderAVX ; Purpose: Reads 256-bit values in somewhat random order from RAM. ; Params: rdi = ptr to chunk pointers ; rsi = # chunks ; rdx = loops ;------------------------------------------------------------------------------ align 64 RandomReaderAVX: _RandomReaderAVX: sub rsp, 32 vmovdqu [rsp], ymm0 sub rsp, 32 vmovdqu [rsp], ymm1 sub rsp, 32 vmovdqu [rsp], ymm2 sub rsp, 32 vmovdqu [rsp], ymm3 push r10 push r11 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Read aligned to 32-byte boundary. vmovdqa ymm0, [96+r10] vmovdqa ymm1, [192+r10] vmovdqa ymm2, [64+r10] vmovdqa ymm3, [224+r10] vmovdqa ymm0, [r10] vmovdqa ymm1, [160+r10] vmovdqa ymm2, [128+r10] vmovdqa ymm3, [32+r10] inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 vmovdqu ymm3, [rsp] add rsp, 32 vmovdqu ymm2, [rsp] add rsp, 32 vmovdqu ymm1, [rsp] add rsp, 32 vmovdqu ymm0, [rsp] add rsp, 32 ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_bypass ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_bypass: _ReaderSSE2_bypass: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: prefetchnta [r10] prefetchnta [r10+64] movntdqa xmm0, [r10] ; Read aligned to 16-byte boundary. movntdqa xmm0, [16+r10] movntdqa xmm0, [32+r10] movntdqa xmm0, [48+r10] movntdqa xmm0, [64+r10] movntdqa xmm0, [80+r10] movntdqa xmm0, [96+r10] movntdqa xmm0, [112+r10] prefetchnta [r10+128] prefetchnta [r10+192] movntdqa xmm0, [128+r10] movntdqa xmm0, [144+r10] movntdqa xmm0, [160+r10] movntdqa xmm0, [176+r10] movntdqa xmm0, [192+r10] movntdqa xmm0, [208+r10] movntdqa xmm0, [224+r10] movntdqa xmm0, [240+r10] add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: ReaderSSE2_128bytes_bypass ; Purpose: Reads 128-bit values sequentially from an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ;------------------------------------------------------------------------------ align 64 ReaderSSE2_128bytes_bypass: _ReaderSSE2_128bytes_bypass: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: prefetchnta [r10] movntdqa xmm0, [r10] ; Read aligned to 16-byte boundary. movntdqa xmm0, [16+r10] movntdqa xmm0, [32+r10] movntdqa xmm0, [48+r10] prefetchnta [r10+64] movntdqa xmm0, [64+r10] movntdqa xmm0, [80+r10] movntdqa xmm0, [96+r10] movntdqa xmm0, [112+r10] add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: Writer ; Purpose: Writes 64-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 Writer: _Writer: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: mov [r10], rcx mov [8+r10], rcx mov [16+r10], rcx mov [24+r10], rcx mov [32+r10], rcx mov [40+r10], rcx mov [48+r10], rcx mov [56+r10], rcx mov [64+r10], rcx mov [72+r10], rcx mov [80+r10], rcx mov [88+r10], rcx mov [96+r10], rcx mov [104+r10], rcx mov [112+r10], rcx mov [120+r10], rcx mov [128+r10], rcx mov [136+r10], rcx mov [144+r10], rcx mov [152+r10], rcx mov [160+r10], rcx mov [168+r10], rcx mov [176+r10], rcx mov [184+r10], rcx mov [192+r10], rcx mov [200+r10], rcx mov [208+r10], rcx mov [216+r10], rcx mov [224+r10], rcx mov [232+r10], rcx mov [240+r10], rcx mov [248+r10], rcx add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: Writer_128bytes ; Purpose: Writes 64-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 Writer_128bytes: _Writer_128bytes: push r10 add rsi, rdi ; rsi now points to end. .L1: mov r10, rdi .L2: mov [r10], rcx mov [8+r10], rcx mov [16+r10], rcx mov [24+r10], rcx mov [32+r10], rcx mov [40+r10], rcx mov [48+r10], rcx mov [56+r10], rcx mov [64+r10], rcx mov [72+r10], rcx mov [80+r10], rcx mov [88+r10], rcx mov [96+r10], rcx mov [104+r10], rcx mov [112+r10], rcx mov [120+r10], rcx add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2 ; Purpose: Writes 128-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterSSE2: _WriterSSE2: push r10 add rsi, rdi ; rsi now points to end. movq xmm0, rcx .L1: mov r10, rdi .L2: movdqa [r10], xmm0 movdqa [16+r10], xmm0 movdqa [32+r10], xmm0 movdqa [48+r10], xmm0 movdqa [64+r10], xmm0 movdqa [80+r10], xmm0 movdqa [96+r10], xmm0 movdqa [112+r10], xmm0 movdqa [128+r10], xmm0 movdqa [144+r10], xmm0 movdqa [160+r10], xmm0 movdqa [176+r10], xmm0 movdqa [192+r10], xmm0 movdqa [208+r10], xmm0 movdqa [224+r10], xmm0 movdqa [240+r10], xmm0 add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: WriterAVX ; Purpose: Writes 256-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterAVX: _WriterAVX: vzeroupper push r10 add rsi, rdi ; rsi now points to end. pinsrq xmm0, rcx, 0 pinsrq xmm0, rcx, 1 .L1: mov r10, rdi .L2: vmovdqa [r10], ymm0 vmovdqa [32+r10], ymm0 vmovdqa [64+r10], ymm0 vmovdqa [96+r10], ymm0 vmovdqa [128+r10], ymm0 vmovdqa [160+r10], ymm0 vmovdqa [192+r10], ymm0 vmovdqa [224+r10], ymm0 add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 vzeroall ret ;------------------------------------------------------------------------------ ; Name: RandomWriterAVX ; Purpose: Writes 256-bit value in somewhat random order to RAM. ; Params: rdi = ptr to array of chunk pointers ; rsi = # of chunks ; rdx = loops ; rcx = datum to write ;------------------------------------------------------------------------------ align 64 RandomWriterAVX: _RandomWriterAVX: push r10 push r11 sub rsp, 32 mov [rsp], rcx mov [rsp+8], rcx mov [rsp+16], rcx mov [rsp+24], rcx vmovdqu ymm0, [rsp] add rsp, 32 .L1: xor r11, r11 .L2: mov r10, [rdi + 8*r11] ; Note, 64-bit pointers. vmovdqa [192+r10], ymm0 vmovdqa [224+r10], ymm0 vmovdqa [64+r10], ymm0 vmovdqa [128+r10], ymm0 vmovdqa [r10], ymm0 vmovdqa [96+r10], ymm0 vmovdqa [160+r10], ymm0 vmovdqa [32+r10], ymm0 inc r11 cmp r11, rsi jb .L2 dec rdx jnz .L1 pop r11 pop r10 vzeroall ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2_128bytes ; Purpose: Writes 128-bit value sequentially to an area of memory, ; chunks are 128 bytes rather than 256. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterSSE2_128bytes: _WriterSSE2_128bytes: push r10 add rsi, rdi ; rsi now points to end. movq xmm0, rcx .L1: mov r10, rdi .L2: movdqa [r10], xmm0 movdqa [16+r10], xmm0 movdqa [32+r10], xmm0 movdqa [48+r10], xmm0 movdqa [64+r10], xmm0 movdqa [80+r10], xmm0 movdqa [96+r10], xmm0 movdqa [112+r10], xmm0 add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2_bypass ; Purpose: Writes 128-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterSSE2_bypass: _WriterSSE2_bypass: push r10 add rsi, rdi ; rsi now points to end. movq xmm0, rcx .L1: mov r10, rdi .L2: movntdq [r10], xmm0 ; Write bypassing cache. movntdq [16+r10], xmm0 movntdq [32+r10], xmm0 movntdq [48+r10], xmm0 movntdq [64+r10], xmm0 movntdq [80+r10], xmm0 movntdq [96+r10], xmm0 movntdq [112+r10], xmm0 movntdq [128+r10], xmm0 movntdq [144+r10], xmm0 movntdq [160+r10], xmm0 movntdq [176+r10], xmm0 movntdq [192+r10], xmm0 movntdq [208+r10], xmm0 movntdq [224+r10], xmm0 movntdq [240+r10], xmm0 add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: WriterAVX_bypass ; Purpose: Writes 256-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterAVX_bypass: _WriterAVX_bypass: vzeroupper push r10 add rsi, rdi ; rsi now points to end. movq xmm0, rcx .L1: mov r10, rdi .L2: vmovntdq [r10], ymm0 ; Write bypassing cache. vmovntdq [32+r10], ymm0 vmovntdq [64+r10], ymm0 vmovntdq [96+r10], ymm0 vmovntdq [128+r10], ymm0 vmovntdq [160+r10], ymm0 vmovntdq [192+r10], ymm0 vmovntdq [224+r10], ymm0 add r10, 256 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 vzeroall ret ;------------------------------------------------------------------------------ ; Name: WriterSSE2_128bytes_bypass ; Purpose: Writes 128-bit value sequentially to an area of memory. ; Params: rdi = ptr to memory area ; rsi = length in bytes ; rdx = loops ; rcx = quad to write ;------------------------------------------------------------------------------ align 64 WriterSSE2_128bytes_bypass: _WriterSSE2_128bytes_bypass: push r10 add rsi, rdi ; rsi now points to end. movq xmm0, rcx .L1: mov r10, rdi .L2: movntdq [r10], xmm0 ; Write bypassing cache. movntdq [16+r10], xmm0 movntdq [32+r10], xmm0 movntdq [48+r10], xmm0 movntdq [64+r10], xmm0 movntdq [80+r10], xmm0 movntdq [96+r10], xmm0 movntdq [112+r10], xmm0 add r10, 128 cmp r10, rsi jb .L2 dec rdx jnz .L1 pop r10 ret ;------------------------------------------------------------------------------ ; Name: StackReader ; Purpose: Reads 64-bit values off the stack into registers of ; the main register set, effectively testing L1 cache access ; *and* effective-address calculation speed. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 StackReader: _StackReader: push qword 7000 ; [rsp+48] push qword 6000 ; [rsp+40] push qword 5000 ; [rsp+32] push qword 4000 ; [rsp+24] push qword 3000 ; [rsp+16] push qword 2000 ; [rsp+8] push qword 1000 ; [rsp] .L1: mov rax, [rsp] mov rax, [rsp+16] mov rax, [rsp+24] mov rax, [rsp+32] mov rax, [rsp+40] mov rax, [rsp+8] mov rax, [rsp+48] mov rax, [rsp] mov rax, [rsp] mov rax, [rsp+16] mov rax, [rsp+24] mov rax, [rsp+32] mov rax, [rsp+40] mov rax, [rsp+8] mov rax, [rsp+48] mov rax, [rsp] mov rax, [rsp] mov rax, [rsp+16] mov rax, [rsp+24] mov rax, [rsp+32] mov rax, [rsp+40] mov rax, [rsp+8] mov rax, [rsp+48] mov rax, [rsp+8] mov rax, [rsp+8] mov rax, [rsp+16] mov rax, [rsp+24] mov rax, [rsp+32] mov rax, [rsp+40] mov rax, [rsp+8] mov rax, [rsp+48] mov rax, [rsp+8] sub rdi, 1 jnz .L1 add rsp, 56 ret ;------------------------------------------------------------------------------ ; Name: StackWriter ; Purpose: Writes 64-bit values into the stack from registers of ; the main register set, effectively testing L1 cache access ; *and* effective-address calculation speed. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 StackWriter: _StackWriter: push qword 7000 ; [rsp+48] push qword 6000 ; [rsp+40] push qword 5000 ; [rsp+32] push qword 4000 ; [rsp+24] push qword 3000 ; [rsp+16] push qword 2000 ; [rsp+8] push qword 1000 ; [rsp] xor rax, rax .L1: mov [rsp], rax mov [rsp+16], rax mov [rsp+24], rax mov [rsp+32], rax mov [rsp+40], rax mov [rsp+8], rax mov [rsp+48], rax mov [rsp], rax mov [rsp], rax mov [rsp+16], rax mov [rsp+24], rax mov [rsp+32], rax mov [rsp+40], rax mov [rsp+8], rax mov [rsp+48], rax mov [rsp], rax mov [rsp], rax mov [rsp+16], rax mov [rsp+24], rax mov [rsp+32], rax mov [rsp+40], rax mov [rsp+8], rax mov [rsp+48], rax mov [rsp+8], rax mov [rsp+8], rax mov [rsp+16], rax mov [rsp+24], rax mov [rsp+32], rax mov [rsp+40], rax mov [rsp+8], rax mov [rsp+48], rax mov [rsp+8], rax sub rdi, 1 jnz .L1 add rsp, 56 ret ;------------------------------------------------------------------------------ ; Name: RegisterToRegister ; Purpose: Reads/writes 64-bit values between registers of ; the main register set. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 RegisterToRegister: _RegisterToRegister: .L1: mov rax, rbx mov rax, rcx mov rax, rdx mov rax, rsi mov rax, rdi mov rax, rbp mov rax, rsp mov rax, rbx mov rax, rbx mov rax, rcx mov rax, rdx mov rax, rsi mov rax, rdi mov rax, rbp mov rax, rsp mov rax, rbx mov rax, rbx mov rax, rcx mov rax, rdx mov rax, rsi mov rax, rdi mov rax, rbp mov rax, rsp mov rax, rbx mov rax, rbx mov rax, rcx mov rax, rdx mov rax, rsi mov rax, rdi mov rax, rbp mov rax, rsp mov rax, rbx sub rdi, 1 jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: VectorToVector ; Purpose: Reads/writes 128-bit values between registers of ; the vector register set, in this case XMM. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 VectorToVector: _VectorToVector: .L1: movq xmm0, xmm1 ; Each move moves 16 bytes, so we need 16 movq xmm14, xmm2 ; moves to transfer a 256 byte chunk. movq xmm0, xmm4 movq xmm9, xmm0 movq xmm1, xmm12 movq xmm7, xmm1 movq xmm8, xmm3 movq xmm3, xmm1 movq xmm13, xmm2 movq xmm11, xmm3 movq xmm2, xmm10 movq xmm6, xmm1 movq xmm1, xmm2 movq xmm15, xmm1 movq xmm0, xmm3 movq xmm3, xmm14 sub rdi, 1 jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: VectorToVectorAVX ; Purpose: Reads/writes 256-bit values between registers of ; the vector register set, in this case YMM. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 VectorToVectorAVX: _VectorToVectorAVX: vzeroupper .L1: vmovdqa ymm0, ymm1 ; Each move moves 32 bytes, so we need 8 vmovdqa ymm0, ymm2 ; moves to transfer a 256 byte chunk. vmovdqa ymm0, ymm3 vmovdqa ymm2, ymm0 vmovdqa ymm1, ymm2 vmovdqa ymm2, ymm1 vmovdqa ymm0, ymm3 vmovdqa ymm3, ymm1 sub rdi, 1 jnz .L1 vzeroall ret ;------------------------------------------------------------------------------ ; Name: RegisterToVector ; Purpose: Writes 64-bit main register values into 128-bit vector register ; clearing the upper unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 RegisterToVector: _RegisterToVector: .L1: movq xmm1, rax ; Each movq transfers 8 bytes, so we need movq xmm2, rsi ; 32 transfers to move a 256-byte chunk. movq xmm3, rbx movq xmm1, rcx movq xmm2, rsi movq xmm3, rsp movq xmm0, rdi movq xmm0, rdx movq xmm0, rax movq xmm1, rsi movq xmm2, rbx movq xmm3, rcx movq xmm0, rsi movq xmm3, rsp movq xmm2, rdi movq xmm1, rdx movq xmm0, rax movq xmm1, rsi movq xmm2, rbx movq xmm3, rcx movq xmm0, rsi movq xmm3, rsp movq xmm2, rdi movq xmm1, rdx movq xmm0, rax movq xmm1, rsi movq xmm2, rbx movq xmm3, rcx movq xmm0, rsi movq xmm3, rsp movq xmm2, rdi movq xmm1, rdx dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: VectorToRegister ; Purpose: Writes lower 64 bits of vector register into 64-bit main ; register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 VectorToRegister: _VectorToRegister: .L1: movq rax, xmm1 movq rax, xmm2 movq rax, xmm3 movq rax, xmm1 movq rax, xmm2 movq rax, xmm3 movq rax, xmm0 movq rax, xmm0 movq rax, xmm0 movq rax, xmm1 movq rax, xmm2 movq rax, xmm3 movq rax, xmm0 movq rax, xmm3 movq rax, xmm2 movq rax, xmm1 movq rax, xmm0 movq rax, xmm1 movq rax, xmm2 movq rax, xmm3 movq rax, xmm0 movq rax, xmm3 movq rax, xmm2 movq rax, xmm1 movq rax, xmm0 movq rax, xmm1 movq rax, xmm2 movq rax, xmm3 movq rax, xmm0 movq rax, xmm3 movq rax, xmm2 movq rax, xmm1 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register8ToVector ; Purpose: Writes 8-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register8ToVector: _Register8ToVector: sal rdi, 2 ; Force some repetition. .L1: pinsrb xmm1, al, 0 ; 64 transfers x 1 byte = 64 bytes pinsrb xmm2, bl, 1 pinsrb xmm3, cl, 2 pinsrb xmm1, dl, 3 pinsrb xmm2, sil, 4 pinsrb xmm3, dil, 5 pinsrb xmm0, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm0, al, 0 pinsrb xmm1, bl, 1 pinsrb xmm2, cl, 2 pinsrb xmm3, dl, 3 pinsrb xmm3, al, 4 pinsrb xmm2, bl, 5 pinsrb xmm1, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm1, r8b, 0 pinsrb xmm2, r9b, 1 pinsrb xmm3, r10b, 2 pinsrb xmm1, r11b, 3 pinsrb xmm2, r12b, 4 pinsrb xmm3, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm0, r8b, 0 pinsrb xmm0, r9b, 1 pinsrb xmm0, r10b, 2 pinsrb xmm0, r11b, 3 pinsrb xmm0, r12b, 4 pinsrb xmm0, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm1, al, 0 pinsrb xmm2, bl, 1 pinsrb xmm3, cl, 2 pinsrb xmm1, dl, 3 pinsrb xmm2, sil, 4 pinsrb xmm3, dil, 5 pinsrb xmm0, bpl, 6 pinsrb xmm0, spl, 7 pinsrb xmm0, al, 10 pinsrb xmm1, bl, 11 pinsrb xmm2, cl, 12 pinsrb xmm3, dl, 13 pinsrb xmm3, dil, 14 pinsrb xmm2, cl, 15 pinsrb xmm1, al, 6 pinsrb xmm0, bpl, 7 pinsrb xmm1, r8b, 10 pinsrb xmm2, r9b, 11 pinsrb xmm3, r10b, 12 pinsrb xmm1, r11b, 13 pinsrb xmm2, r12b, 14 pinsrb xmm3, al, 15 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 pinsrb xmm0, r8b, 9 pinsrb xmm0, r9b, 8 pinsrb xmm0, r10b, 11 pinsrb xmm0, r11b, 3 pinsrb xmm0, r12b, 4 pinsrb xmm0, al, 5 pinsrb xmm0, cl, 6 pinsrb xmm0, bl, 7 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register16ToVector ; Purpose: Writes 16-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register16ToVector: _Register16ToVector: sal rdi, 1 ; Force some repetition. .L1: pinsrw xmm1, ax, 0 ; 64 transfers x 2 bytes = 128 bytes pinsrw xmm2, bx, 1 pinsrw xmm3, cx, 2 pinsrw xmm1, dx, 3 pinsrw xmm2, si, 4 pinsrw xmm3, di, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm0, ax, 0 pinsrw xmm1, bx, 1 pinsrw xmm2, cx, 2 pinsrw xmm3, dx, 3 pinsrw xmm3, si, 4 pinsrw xmm2, di, 5 pinsrw xmm1, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm1, r8w, 0 pinsrw xmm2, r9w, 1 pinsrw xmm3, r10w, 2 pinsrw xmm1, r11w, 3 pinsrw xmm2, r12w, 4 pinsrw xmm3, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm0, r8w, 0 pinsrw xmm0, r9w, 1 pinsrw xmm0, r10w, 2 pinsrw xmm0, r11w, 3 pinsrw xmm0, r12w, 4 pinsrw xmm0, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm1, ax, 0 pinsrw xmm2, bx, 1 pinsrw xmm3, cx, 2 pinsrw xmm1, dx, 3 pinsrw xmm2, si, 4 pinsrw xmm3, di, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm0, ax, 0 pinsrw xmm1, bx, 1 pinsrw xmm2, cx, 2 pinsrw xmm3, dx, 3 pinsrw xmm3, si, 4 pinsrw xmm2, di, 5 pinsrw xmm1, bp, 6 pinsrw xmm0, sp, 7 pinsrw xmm1, r8w, 0 pinsrw xmm2, r9w, 1 pinsrw xmm3, r10w, 2 pinsrw xmm1, r11w, 3 pinsrw xmm2, r12w, 4 pinsrw xmm3, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 pinsrw xmm0, r8w, 0 pinsrw xmm0, r9w, 1 pinsrw xmm0, r10w, 2 pinsrw xmm0, r11w, 3 pinsrw xmm0, r12w, 4 pinsrw xmm0, ax, 5 pinsrw xmm0, bp, 6 pinsrw xmm0, bx, 7 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register32ToVector ; Purpose: Writes 32-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register32ToVector: _Register32ToVector: .L1: pinsrd xmm1, eax, 0 ; Each xfer moves 4 bytes so to move 256 bytes pinsrd xmm2, ebx, 1 ; we need 64 transfers. pinsrd xmm3, ecx, 2 pinsrd xmm1, edx, 3 pinsrd xmm2, esi, 0 pinsrd xmm3, edi, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, esp, 3 pinsrd xmm0, eax, 0 pinsrd xmm1, ebx, 1 pinsrd xmm2, ecx, 2 pinsrd xmm3, edx, 3 pinsrd xmm3, esi, 3 pinsrd xmm2, edi, 2 pinsrd xmm1, ebp, 1 pinsrd xmm0, esp, 0 pinsrd xmm1, r8d, 0 pinsrd xmm2, r9d, 1 pinsrd xmm3, r10d, 2 pinsrd xmm1, r11d, 3 pinsrd xmm2, r12d, 0 pinsrd xmm3, eax, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, ebx, 3 pinsrd xmm0, r8d, 0 pinsrd xmm0, r9d, 1 pinsrd xmm0, r10d, 2 pinsrd xmm0, r11d, 3 pinsrd xmm0, r12d, 0 pinsrd xmm0, eax, 0 pinsrd xmm0, ebp, 0 pinsrd xmm0, ebx, 0 pinsrd xmm1, eax, 0 pinsrd xmm2, ebx, 1 pinsrd xmm3, ecx, 2 pinsrd xmm1, edx, 3 pinsrd xmm2, esi, 0 pinsrd xmm3, edi, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, esp, 3 pinsrd xmm0, eax, 0 pinsrd xmm1, ebx, 1 pinsrd xmm2, ecx, 2 pinsrd xmm3, edx, 3 pinsrd xmm3, esi, 3 pinsrd xmm2, edi, 2 pinsrd xmm1, ebp, 1 pinsrd xmm0, esp, 0 pinsrd xmm1, r8d, 0 pinsrd xmm2, r9d, 1 pinsrd xmm3, r10d, 2 pinsrd xmm1, r11d, 3 pinsrd xmm2, r12d, 0 pinsrd xmm3, eax, 1 pinsrd xmm0, ebp, 2 pinsrd xmm0, ebx, 3 pinsrd xmm0, r8d, 0 pinsrd xmm0, r9d, 1 pinsrd xmm0, r10d, 2 pinsrd xmm0, r11d, 3 pinsrd xmm0, r12d, 0 pinsrd xmm0, eax, 0 pinsrd xmm0, ebp, 0 pinsrd xmm0, ebx, 0 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Register64ToVector ; Purpose: Writes 64-bit main register values into 128-bit vector register ; without clearing the unused bits. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Register64ToVector: _Register64ToVector: add rdi, rdi .L1: pinsrq xmm1, r8, 0 ; Each xfer moves 8 bytes, therefore to do pinsrq xmm2, r9, 1 ; 256 bytes we need 32 transfers. pinsrq xmm3, r10, 0 pinsrq xmm1, r11, 1 pinsrq xmm2, r12, 0 pinsrq xmm3, rax, 1 pinsrq xmm0, rbp, 0 pinsrq xmm0, rbx, 1 pinsrq xmm0, r8, 0 pinsrq xmm0, r9, 1 pinsrq xmm0, r10, 1 pinsrq xmm0, r11, 1 pinsrq xmm0, r12, 0 pinsrq xmm0, rax, 0 pinsrq xmm0, rbp, 0 pinsrq xmm0, rbx, 0 pinsrq xmm0, r8, 0 pinsrq xmm0, r9, 1 pinsrq xmm0, r10, 1 pinsrq xmm0, r11, 1 pinsrq xmm0, r12, 0 pinsrq xmm0, rax, 0 pinsrq xmm0, rbp, 0 pinsrq xmm0, rbx, 0 pinsrq xmm0, r8, 0 pinsrq xmm0, r9, 1 pinsrq xmm0, r10, 1 pinsrq xmm0, r11, 1 pinsrq xmm0, r12, 0 pinsrq xmm0, rax, 0 pinsrq xmm0, rbp, 0 pinsrq xmm0, rbx, 0 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Vector8ToRegister ; Purpose: Writes 8-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector8ToRegister: _Vector8ToRegister: sal rdi, 3 ; Force some repetition. .L1: pextrb eax, xmm1, 0 ; 64 transfers x 1 bytes = 64 bytes pextrb eax, xmm2, 1 pextrb eax, xmm3, 2 pextrb eax, xmm1, 3 pextrb eax, xmm2, 4 pextrb eax, xmm3, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 pextrb eax, xmm0, 0 pextrb eax, xmm1, 1 pextrb eax, xmm2, 2 pextrb eax, xmm3, 3 pextrb eax, xmm3, 4 pextrb eax, xmm2, 5 pextrb eax, xmm1, 6 pextrb eax, xmm0, 7 pextrb eax, xmm1, 0 pextrb eax, xmm2, 1 pextrb eax, xmm3, 2 pextrb eax, xmm1, 3 pextrb eax, xmm2, 4 pextrb eax, xmm3, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 pextrb eax, xmm0, 0 pextrb eax, xmm0, 1 pextrb eax, xmm0, 2 pextrb eax, xmm0, 3 pextrb eax, xmm0, 4 pextrb eax, xmm0, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 pextrb eax, xmm1, 0 pextrb eax, xmm2, 1 pextrb eax, xmm3, 2 pextrb eax, xmm1, 3 pextrb eax, xmm2, 4 pextrb eax, xmm3, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 pextrb eax, xmm0, 0 pextrb eax, xmm1, 1 pextrb eax, xmm2, 2 pextrb eax, xmm3, 3 pextrb eax, xmm3, 4 pextrb eax, xmm2, 5 pextrb eax, xmm1, 6 pextrb eax, xmm0, 7 pextrb eax, xmm1, 0 pextrb eax, xmm2, 1 pextrb eax, xmm3, 2 pextrb eax, xmm1, 3 pextrb eax, xmm2, 4 pextrb eax, xmm3, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 pextrb eax, xmm0, 0 pextrb eax, xmm0, 1 pextrb eax, xmm0, 2 pextrb eax, xmm0, 3 pextrb eax, xmm0, 4 pextrb eax, xmm0, 5 pextrb eax, xmm0, 6 pextrb eax, xmm0, 7 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Vector16ToRegister ; Purpose: Writes 16-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector16ToRegister: _Vector16ToRegister: sal rdi, 2 ; Force some repetition. .L1: pextrw eax, xmm1, 0 ; 64 transfers x 2 bytes = 128 bytes pextrw eax, xmm2, 1 pextrw eax, xmm3, 2 pextrw eax, xmm1, 3 pextrw eax, xmm2, 4 pextrw eax, xmm3, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 pextrw eax, xmm0, 0 pextrw eax, xmm1, 1 pextrw eax, xmm2, 2 pextrw eax, xmm3, 3 pextrw eax, xmm3, 4 pextrw eax, xmm2, 5 pextrw eax, xmm1, 6 pextrw eax, xmm0, 7 pextrw eax, xmm1, 0 pextrw eax, xmm2, 1 pextrw eax, xmm3, 2 pextrw eax, xmm1, 3 pextrw eax, xmm2, 4 pextrw eax, xmm3, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 pextrw eax, xmm0, 0 pextrw eax, xmm0, 1 pextrw eax, xmm0, 2 pextrw eax, xmm0, 3 pextrw eax, xmm0, 4 pextrw eax, xmm0, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 pextrw eax, xmm1, 0 pextrw eax, xmm2, 1 pextrw eax, xmm3, 2 pextrw eax, xmm1, 3 pextrw eax, xmm2, 4 pextrw eax, xmm3, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 pextrw eax, xmm0, 0 pextrw eax, xmm1, 1 pextrw eax, xmm2, 2 pextrw eax, xmm3, 3 pextrw eax, xmm3, 4 pextrw eax, xmm2, 5 pextrw eax, xmm1, 6 pextrw eax, xmm0, 7 pextrw eax, xmm1, 0 pextrw eax, xmm2, 1 pextrw eax, xmm3, 2 pextrw eax, xmm1, 3 pextrw eax, xmm2, 4 pextrw eax, xmm3, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 pextrw eax, xmm0, 0 pextrw eax, xmm0, 1 pextrw eax, xmm0, 2 pextrw eax, xmm0, 3 pextrw eax, xmm0, 4 pextrw eax, xmm0, 5 pextrw eax, xmm0, 6 pextrw eax, xmm0, 7 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Vector32ToRegister ; Purpose: Writes 32-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector32ToRegister: _Vector32ToRegister: add rdi, rdi .L1: pextrd eax, xmm1, 0 ; 64 xfers x 4 bytes = 256 bytes pextrd eax, xmm2, 1 pextrd eax, xmm3, 2 pextrd eax, xmm1, 3 pextrd eax, xmm2, 0 pextrd eax, xmm3, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm1, 1 pextrd eax, xmm2, 2 pextrd eax, xmm3, 3 pextrd eax, xmm3, 3 pextrd eax, xmm2, 2 pextrd eax, xmm1, 1 pextrd eax, xmm0, 0 pextrd eax, xmm1, 0 pextrd eax, xmm2, 1 pextrd eax, xmm3, 2 pextrd eax, xmm1, 3 pextrd eax, xmm2, 0 pextrd eax, xmm3, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm0, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm0, 0 pextrd eax, xmm0, 0 pextrd eax, xmm0, 0 pextrd eax, xmm1, 0 pextrd eax, xmm2, 1 pextrd eax, xmm3, 2 pextrd eax, xmm1, 3 pextrd eax, xmm2, 0 pextrd eax, xmm3, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm1, 1 pextrd eax, xmm2, 2 pextrd eax, xmm3, 3 pextrd eax, xmm3, 3 pextrd eax, xmm2, 2 pextrd eax, xmm1, 1 pextrd eax, xmm0, 0 pextrd eax, xmm1, 0 pextrd eax, xmm2, 1 pextrd eax, xmm3, 2 pextrd eax, xmm1, 3 pextrd eax, xmm2, 0 pextrd eax, xmm3, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm0, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 pextrd eax, xmm0, 0 pextrd eax, xmm0, 1 pextrd eax, xmm0, 2 pextrd eax, xmm0, 3 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: Vector64ToRegister ; Purpose: Writes 64-bit vector register values into main register. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 Vector64ToRegister: _Vector64ToRegister: add rdi, rdi .L1: pextrq rax, xmm1, 0 ; 32 transfers by 8 bytes = 256 bytes pextrq rax, xmm2, 1 pextrq rax, xmm3, 0 pextrq rax, xmm1, 1 pextrq rax, xmm2, 0 pextrq rax, xmm3, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm1, 0 pextrq rax, xmm2, 1 pextrq rax, xmm3, 0 pextrq rax, xmm1, 1 pextrq rax, xmm2, 0 pextrq rax, xmm3, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 pextrq rax, xmm0, 0 pextrq rax, xmm0, 1 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: CopyAVX ; Purpose: Copies memory chunks that are 32-byte aligned. ; Params: rdi = ptr to destination memory area ; rsi = ptr to source memory area ; rdx = length in bytes ; rcx = loops ;------------------------------------------------------------------------------ align 64 CopyAVX: _CopyAVX: vzeroupper push r10 shr rdx, 8 ; Ensure length is multiple of 256. shl rdx, 8 prefetcht0 [rsi] .L1: mov r10, rdx .L2: vmovdqa ymm0, [rsi] vmovdqa ymm1, [32+rsi] vmovdqa ymm2, [64+rsi] vmovdqa ymm3, [96+rsi] vmovdqa [rdi], ymm0 vmovdqa [32+rdi], ymm1 vmovdqa [64+rdi], ymm2 vmovdqa [96+rdi], ymm3 vmovdqa ymm0, [128+rsi] vmovdqa ymm1, [128+32+rsi] vmovdqa ymm2, [128+64+rsi] vmovdqa ymm3, [128+96+rsi] vmovdqa [128+rdi], ymm0 vmovdqa [128+32+rdi], ymm1 vmovdqa [128+64+rdi], ymm2 vmovdqa [128+96+rdi], ymm3 add rsi, 256 add rdi, 256 sub r10, 256 jnz .L2 sub rsi, rdx ; rsi now points to start. sub rdi, rdx ; rdi now points to start. dec rcx jnz .L1 pop r10 vzeroall ret ;------------------------------------------------------------------------------ ; Name: CopySSE ; Purpose: Copies memory chunks that are 16-byte aligned. ; Params: rdi = ptr to destination memory area ; rsi = ptr to source memory area ; rdx = length in bytes ; rcx = loops ;------------------------------------------------------------------------------ align 64 CopySSE: _CopySSE: push r10 shr rdx, 8 ; Ensure length is multiple of 256. shl rdx, 8 prefetcht0 [rsi] ; Save our non-parameter XMM registers. sub rsp, 192 movdqu [rsp], xmm4 movdqu [16+rsp], xmm5 movdqu [32+rsp], xmm6 movdqu [48+rsp], xmm7 movdqu [64+rsp], xmm8 movdqu [80+rsp], xmm9 movdqu [96+rsp], xmm10 movdqu [112+rsp], xmm11 movdqu [128+rsp], xmm12 movdqu [144+rsp], xmm13 movdqu [160+rsp], xmm14 movdqu [176+rsp], xmm15 .L1: mov r10, rdx .L2: movdqa xmm0, [rsi] movdqa xmm1, [16+rsi] movdqa xmm2, [32+rsi] movdqa xmm3, [48+rsi] movdqa [rdi], xmm0 movdqa [16+rdi], xmm1 movdqa [32+rdi], xmm2 movdqa [48+rdi], xmm3 movdqa xmm4, [64+rsi] movdqa xmm5, [80+rsi] movdqa xmm6, [96+rsi] movdqa xmm7, [112+rsi] movdqa [64+rdi], xmm4 movdqa [80+rdi], xmm5 movdqa [96+rdi], xmm6 movdqa [112+rdi], xmm7 movdqa xmm8, [128+rsi] movdqa xmm9, [144+rsi] movdqa xmm10, [160+rsi] movdqa xmm11, [176+rsi] movdqa [128+rdi], xmm8 movdqa [144+rdi], xmm9 movdqa [160+rdi], xmm10 movdqa [176+rdi], xmm11 movdqa xmm12, [192+rsi] movdqa xmm13, [208+rsi] movdqa xmm14, [224+rsi] movdqa xmm15, [240+rsi] movdqa [192+rdi], xmm12 movdqa [208+rdi], xmm13 movdqa [224+rdi], xmm14 movdqa [240+rdi], xmm15 add rsi, 256 add rdi, 256 sub r10, 256 jnz .L2 sub rsi, rdx ; rsi now points to start. sub rdi, rdx ; rdi now points to start. dec rcx jnz .L1 movdqu xmm4, [rsp] movdqu xmm5, [16+rsp] movdqu xmm6, [32+rsp] movdqu xmm7, [48+rsp] movdqu xmm8, [64+rsp] movdqu xmm9, [80+rsp] movdqu xmm10, [96+rsp] movdqu xmm11, [112+rsp] movdqu xmm12, [128+rsp] movdqu xmm13, [144+rsp] movdqu xmm14, [160+rsp] movdqu xmm15, [176+rsp] add rsp, 192 pop r10 ret ;------------------------------------------------------------------------------ ; Name: CopySSE_128bytes ; Purpose: Copies memory chunks that are 16-byte aligned. ; Params: rdi = ptr to destination memory area ; rsi = ptr to source memory area ; rdx = length in bytes ; rcx = loops ;------------------------------------------------------------------------------ align 64 CopySSE_128bytes: _CopySSE_128bytes: push r10 shr rdx, 7 ; Ensure length is multiple of 128. shl rdx, 7 prefetcht0 [rsi] ; Save our non-parameter XMM registers. sub rsp, 64 movdqu [rsp], xmm4 movdqu [16+rsp], xmm5 movdqu [32+rsp], xmm6 movdqu [48+rsp], xmm7 .L1: mov r10, rdx .L2: movdqa xmm0, [rsi] movdqa xmm1, [16+rsi] movdqa xmm2, [32+rsi] movdqa xmm3, [48+rsi] movdqa [rdi], xmm0 movdqa [16+rdi], xmm1 movdqa [32+rdi], xmm2 movdqa [48+rdi], xmm3 movdqa xmm4, [64+rsi] movdqa xmm5, [80+rsi] movdqa xmm6, [96+rsi] movdqa xmm7, [112+rsi] movdqa [64+rdi], xmm4 movdqa [80+rdi], xmm5 movdqa [96+rdi], xmm6 movdqa [112+rdi], xmm7 add rsi, 128 add rdi, 128 sub r10, 128 jnz .L2 sub rsi, rdx ; rsi now points to start. sub rdi, rdx ; rdi now points to start. dec rcx jnz .L1 movdqu xmm4, [rsp] movdqu xmm5, [16+rsp] movdqu xmm6, [32+rsp] movdqu xmm7, [48+rsp] add rsp, 64 pop r10 ret ;------------------------------------------------------------------------------ ; Name: IncrementRegisters ; Purpose: Increments 64-bit values in registers. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 IncrementRegisters: _IncrementRegisters: .L1: inc rax inc rbx inc rcx inc rdx inc rsi inc rdi inc rbp inc rsp inc r8 inc r9 inc r10 inc r11 inc r12 inc r13 inc r14 inc r15 dec rax dec rbx dec rcx dec rdx dec rsi dec rdi dec rbp dec rsp dec r8 dec r9 dec r10 dec r11 dec r12 dec r13 dec r14 dec r15 dec rdi jnz .L1 ret ;------------------------------------------------------------------------------ ; Name: IncrementStack ; Purpose: Increments 64-bit values on stack. ; Params: rdi = loops ;------------------------------------------------------------------------------ align 64 IncrementStack: _IncrementStack: sub rsp, 128 .L1: inc qword [rsp] inc qword [rsp+8] inc qword [rsp+16] inc qword [rsp+24] inc qword [rsp+32] inc qword [rsp+40] inc qword [rsp+48] inc qword [rsp+56] inc qword [rsp+64] inc qword [rsp+72] inc qword [rsp+80] inc qword [rsp+88] inc qword [rsp+96] inc qword [rsp+104] inc qword [rsp+112] inc qword [rsp+120] dec qword [rsp] dec qword [rsp+8] dec qword [rsp+16] dec qword [rsp+24] dec qword [rsp+32] dec qword [rsp+40] dec qword [rsp+48] dec qword [rsp+56] dec qword [rsp+64] dec qword [rsp+72] dec qword [rsp+80] dec qword [rsp+88] dec qword [rsp+96] dec qword [rsp+104] dec qword [rsp+112] dec qword [rsp+120] dec rdi jnz .L1 add rsp, 128 ret CPU-X-4.2.0/src/core.c000066400000000000000000001571251403012130000142270ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE core.c */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" #include "cpu-x.h" #include "ipc.h" #ifndef __linux__ # include #endif #if HAS_GETTEXT # include #endif #if HAS_LIBCPUID # include # include "databases.h" #endif #if HAS_BANDWIDTH # include "bandwidth/libbandwidth.h" #endif #if HAS_LIBPCI # include #endif #if HAS_LIBPROCPS # include #endif #if HAS_LIBGLFW # include # include #endif #if HAS_LIBSTATGRAB # include #endif /************************* Public functions *************************/ /* Fill labels by calling below functions */ int fill_labels(Labels *data) { int i, err = 0; const uint8_t selected_page = opts->selected_page; #if HAS_LIBCPUID err += call_libcpuid_static(data); if(DAEMON_UP) err += call_libcpuid_msr_static(data); #endif #if HAS_DMIDECODE if(DAEMON_UP) err += call_dmidecode(data); #endif #if HAS_LIBPCI err += find_devices(data); #endif casprintf(&data->tab_cpu[VALUE][BUSSPEED], true, "%.2f MHz", data->bus_freq); err += system_static (data); err += fallback_mode_static(data); /* Call do_refresh() once to get dynamic values */ for(i = NO_CPU; i < NO_ABOUT; i++) { opts->selected_page = i; err += do_refresh(data); } opts->selected_page = selected_page; return err; } /* Refresh some labels */ int do_refresh(Labels *data) { int err = 0; switch(opts->selected_page) { case NO_CPU: #if HAS_LIBCPUID err += err_func(call_libcpuid_dynamic, data); if(DAEMON_UP) err += err_func(call_libcpuid_msr_dynamic, data); #endif /* HAS_LIBCPUID */ err += err_func(cpu_usage, data); err += fallback_mode_dynamic(data); err += err_func(cputab_fill_multipliers, data); break; case NO_CACHES: #if HAS_BANDWIDTH err += err_func(call_bandwidth, data); #endif /* HAS_BANDWIDTH */ break; case NO_SYSTEM: #if HAS_LIBSYSTEM err += err_func(system_dynamic, data); #endif /* HAS_LIBSYSTEM */ break; case NO_GRAPHICS: #if HAS_LIBPCI err += err_func(gpu_monitoring, data); #endif /* HAS_LIBPCI */ break; case NO_BENCH: err += err_func(benchmark_status, data); break; } return err; } int connect_to_daemon(Labels *data) { int socket_fd = -1; char error_str[MAXSTR]; struct sockaddr_un addr; /* Create local socket */ if((socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) GOTO_ERROR("socket"); /* Connect socket to socket address */ memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); if(connect(socket_fd, (const struct sockaddr*) &addr, sizeof(struct sockaddr_un)) < 0) GOTO_ERROR("connect"); data->socket_fd = socket_fd; return 0; error: MSG_ERRNO("failed to connect to daemon: %s", error_str); if(socket_fd >= 0) close(socket_fd); return 1; } /************************* Private functions *************************/ /* Avoid to re-run a function if an error was occurred in previous call */ static int err_func(int (*func)(Labels *), Labels *data) { unsigned i = 0; static unsigned last = 0; struct Functions { void *func; int skip_func; } *tmp = NULL; static struct Functions *registered = NULL; for(i = 0; (i < last) && (func != registered[i].func); i++); if(i == last) { tmp = realloc(registered, sizeof(struct Functions) * (i + 1)); ALLOC_CHECK(tmp); registered = tmp; registered[last].func = func; registered[last].skip_func = 0; last++; } if(!registered[i].skip_func) registered[i].skip_func = func(data); return registered[i].skip_func; } #if HAS_LIBCPUID #define RETURN_OR_EXIT(e) { if(opts->debug_database) exit(e); else return e; } /* Get CPU technology, in nanometre (nm) */ static int cpu_technology(Labels *data) { int i = -1; const Technology_DB *db; LibcpuidData *l_data = data->l_data; if(l_data->cpu_vendor_id < 0 || l_data->cpu_model < 0 || l_data->cpu_ext_model < 0 || l_data->cpu_ext_family < 0) RETURN_OR_EXIT(1); MSG_VERBOSE("%s", _("Finding CPU technology")); if(l_data->cpu_vendor_id == VENDOR_INTEL) db = technology_intel; else if(l_data->cpu_vendor_id == VENDOR_AMD) db = technology_amd; else db = technology_unknown; while(db[++i].cpu_model != -2) { if(((db[i].cpu_model < 0) || (db[i].cpu_model == l_data->cpu_model)) && ((db[i].cpu_ext_model < 0) || (db[i].cpu_ext_model == l_data->cpu_ext_model)) && ((db[i].cpu_ext_family < 0) || (db[i].cpu_ext_family == l_data->cpu_ext_family))) { casprintf(&data->tab_cpu[VALUE][TECHNOLOGY], false, "%i nm", db[i].process); RETURN_OR_EXIT(0); } } MSG_WARNING(_("Your CPU is not present in the database ==> %s, model: %i, ext. model: %i, ext. family: %i"), data->tab_cpu[VALUE][SPECIFICATION], l_data->cpu_model, l_data->cpu_ext_model, l_data->cpu_ext_family); RETURN_OR_EXIT(2); } #undef RETURN_OR_EXIT /* Static elements provided by libcpuid */ static int call_libcpuid_static(Labels *data) { int err, i, j = 0; char tmp[MAXSTR * 2] = ""; const char *fmt_cpuid = opts->cpuid_decimal ? "%i" : "0x%X"; const char *fmt_cache_kb = _("%d x %d %s, %d-way"); const char *fmt_cache_mb = _("%d %s, %d-way"); const char *fmt_lines = _("%s associative, %d-%s line size"); struct cpu_raw_data_t raw; struct cpu_id_t datanr; /* Call libcpuid */ MSG_VERBOSE("%s", _("Calling libcpuid for retrieving static data")); if(opts->issue) cpuid_set_verbosiness_level(2); if(data->l_data->cpuid_raw_file == NULL) err = cpuid_get_raw_data(&raw); else err = cpuid_deserialize_raw_data(&raw, data->l_data->cpuid_raw_file); if(opts->issue) cpuid_serialize_raw_data(&raw, ""); if(err || cpu_identify(&raw, &datanr)) { MSG_ERROR(_("failed to call libcpuid (%s)"), cpuid_error()); return 1; } /* Some prerequisites */ data->cpu_count = datanr.num_logical_cpus; data->l_data->cpu_model = datanr.model; data->l_data->cpu_ext_model = datanr.ext_model; data->l_data->cpu_ext_family = datanr.ext_family; if(opts->selected_core >= data->cpu_count) opts->selected_core = 0; /* Basically fill CPU tab */ casprintf(&data->tab_cpu[VALUE][CODENAME], false, "%s", datanr.cpu_codename); casprintf(&data->tab_cpu[VALUE][SPECIFICATION], false, "%s", datanr.brand_str); casprintf(&data->tab_cpu[VALUE][FAMILY], false, fmt_cpuid, datanr.family); casprintf(&data->tab_cpu[VALUE][EXTFAMILY], false, fmt_cpuid, datanr.ext_family); casprintf(&data->tab_cpu[VALUE][MODEL], false, fmt_cpuid, datanr.model); casprintf(&data->tab_cpu[VALUE][EXTMODEL], false, fmt_cpuid, datanr.ext_model); casprintf(&data->tab_cpu[VALUE][STEPPING], false, "%d", datanr.stepping); casprintf(&data->tab_cpu[VALUE][CORES], true, "%d", datanr.num_cores); casprintf(&data->tab_cpu[VALUE][THREADS], true, "%d", datanr.num_logical_cpus); /* Improve the CPU Vendor label */ const struct CpuVendor { char *standard; char *improved; cpu_vendor_t id; } cpuvendors[] = { { "GenuineIntel", "Intel", VENDOR_INTEL }, { "AuthenticAMD", "AMD", VENDOR_AMD }, { "CyrixInstead", "Cyrix", VENDOR_CYRIX }, { "NexGenDriven", "NexGen", VENDOR_NEXGEN }, { "GenuineTMx86", "Transmeta", VENDOR_TRANSMETA }, { "UMC UMC UMC ", "UMC", VENDOR_UMC }, { "CentaurHauls", "Centaur", VENDOR_CENTAUR }, { "RiseRiseRise", "Rise", VENDOR_RISE }, { "SiS SiS SiS ", "SiS", VENDOR_SIS }, { "Geode by NSC", "National Semiconductor", VENDOR_NSC }, { datanr.vendor_str, datanr.vendor_str, VENDOR_UNKNOWN } }; for(i = 0; strcmp(cpuvendors[i].standard, datanr.vendor_str); i++); casprintf(&data->tab_cpu[VALUE][VENDOR], false, cpuvendors[i].improved); data->l_data->cpu_vendor_id = cpuvendors[i].id; /* Search in DB for CPU technology (depends on data->l_data->cpu_vendor_id) */ err = cpu_technology(data); /* Remove training spaces in Specification label */ for(i = 1; datanr.brand_str[i] != '\0'; i++) { if(!(isspace(datanr.brand_str[i]) && isspace(datanr.brand_str[i - 1]))) data->tab_cpu[VALUE][SPECIFICATION][++j] = datanr.brand_str[i]; } data->tab_cpu[VALUE][SPECIFICATION][++j] = '\0'; /* Cache level 1 (instruction) */ if(datanr.l1_instruction_cache > 0) casprintf(&data->tab_cpu[VALUE][LEVEL1I], true, fmt_cache_kb, datanr.num_cores, datanr.l1_instruction_cache, UNIT_KB, datanr.l1_instruction_assoc); /* Cache level 1 (data) */ if(datanr.l1_data_cache > 0) { data->cache_count++; data->w_data->size[0] = datanr.l1_data_cache; casprintf(&data->tab_cpu[VALUE][LEVEL1D], true, fmt_cache_kb, datanr.num_cores, datanr.l1_data_cache, UNIT_KB, datanr.l1_data_assoc); casprintf(&data->tab_caches[VALUE][L1SIZE], true, fmt_lines, data->tab_cpu[VALUE][LEVEL1D], datanr.l1_data_cacheline, UNIT_B); } /* Cache level 2 */ if(datanr.l2_cache > 0) { data->cache_count++; data->w_data->size[1] = datanr.l2_cache; casprintf(&data->tab_cpu[VALUE][LEVEL2], true, fmt_cache_kb, datanr.num_cores, datanr.l2_cache, UNIT_KB, datanr.l2_assoc); casprintf(&data->tab_caches[VALUE][L2SIZE], true, fmt_lines, data->tab_cpu[VALUE][LEVEL2], datanr.l2_cacheline, UNIT_B); } /* Cache level 3 */ if(datanr.l3_cache > 0) { data->cache_count++; data->w_data->size[2] = datanr.l3_cache; casprintf(&data->tab_cpu[VALUE][LEVEL3], true, fmt_cache_mb, datanr.l3_cache >> 10, UNIT_MB, datanr.l3_assoc); casprintf(&data->tab_caches[VALUE][L3SIZE], true, fmt_lines, data->tab_cpu[VALUE][LEVEL3], datanr.l3_cacheline, UNIT_B); } /* Cache level 4 */ if(datanr.l4_cache > 0) { data->cache_count++; data->w_data->size[3] = datanr.l4_cache; snprintf(tmp, MAXSTR, fmt_cache_mb, datanr.l4_cache >> 10, UNIT_MB, datanr.l4_assoc); casprintf(&data->tab_caches[VALUE][L4SIZE], true, fmt_lines, tmp, datanr.l4_cacheline, UNIT_B); memset(tmp, 0, MAXSTR); } if(datanr.total_logical_cpus < datanr.num_logical_cpus) casprintf(&data->tab_cpu[VALUE][SOCKETS], true, "%d", 1); else if(datanr.num_logical_cpus > 0) /* Avoid divide by 0 */ casprintf(&data->tab_cpu[VALUE][SOCKETS], true, "%d", datanr.total_logical_cpus / datanr.num_logical_cpus); /* Add string "HT" in CPU Intructions label (if enabled) */ if(datanr.num_cores < datanr.num_logical_cpus) strncat(tmp, (data->l_data->cpu_vendor_id == VENDOR_INTEL) ? "HT" : "SMT", MAXSTR * 2 - strlen(tmp)); /* Fill CPU Intructions label */ const struct { const cpu_feature_t flag; const char *str; } cpu_flags[] = { /* SIMD x86 */ { CPU_FEATURE_MMX, "MMX" }, { CPU_FEATURE_MMXEXT, "(+)" }, { CPU_FEATURE_3DNOW, "3DNOW!" }, { CPU_FEATURE_3DNOWEXT, "(+)" }, { CPU_FEATURE_SSE, "SSE(1" }, { CPU_FEATURE_SSE2, "2" }, { CPU_FEATURE_PNI, "3" }, { CPU_FEATURE_SSSE3, "3S" }, { CPU_FEATURE_SSE4_1, "4.1" }, { CPU_FEATURE_SSE4_2, "4.2" }, { CPU_FEATURE_SSE4A, "4A" }, { CPU_FEATURE_SSE, ")" }, { CPU_FEATURE_XOP, "XOP" }, { CPU_FEATURE_AVX, "AVX(1" }, { CPU_FEATURE_AVX2, "2" }, { CPU_FEATURE_AVX512F, "512" }, { CPU_FEATURE_AVX, ")" }, { CPU_FEATURE_FMA3, "FMA(3" }, { CPU_FEATURE_FMA4, "4" }, { CPU_FEATURE_FMA3, ")" }, /* Security and Cryptography */ { CPU_FEATURE_AES, "AES" }, { CPU_FEATURE_PCLMUL, "CLMUL" }, { CPU_FEATURE_RDRAND, "RdRand" }, { CPU_FEATURE_SHA_NI, "SHA" }, { CPU_FEATURE_SGX, "SGX" }, /* Virtualization */ { CPU_FEATURE_VMX, "VT-x" }, { CPU_FEATURE_SVM, "AMD-V" }, /* Other */ { CPU_FEATURE_LM, "x86-64" }, { NUM_CPU_FEATURES, NULL } }; for(i = 0; cpu_flags[i].flag != NUM_CPU_FEATURES; i++) { if(!datanr.flags[cpu_flags[i].flag]) continue; j = strlen(tmp); if((j > 0) && (cpu_flags[i].str[0] != '(') && (cpu_flags[i].str[0] != ')')) strncat(tmp, ", ", MAXSTR * 2 - j); strncat(tmp, cpu_flags[i].str, MAXSTR * 2 - j); } casprintf(&data->tab_cpu[VALUE][INSTRUCTIONS], false, tmp); return err; } /* Dynamic elements provided by libcpuid */ static int call_libcpuid_dynamic(Labels *data) { /* CPU frequency */ MSG_VERBOSE("%s", _("Calling libcpuid for retrieving dynamic data")); data->cpu_freq = cpu_clock(); casprintf(&data->tab_cpu[VALUE][CORESPEED], true, "%d MHz", data->cpu_freq); return (data->cpu_freq <= 0); } /* MSRs static values provided by libcpuid */ static int call_libcpuid_msr_static(Labels *data) { const DaemonCommand cmd = LIBCPUID_MSR_STATIC; MsrStaticData msg; MSG_VERBOSE("%s", _("Calling libcpuid for retrieving CPU MSR static values")); SEND_DATA(&data->socket_fd, &cmd, sizeof(DaemonCommand)); SEND_DATA(&data->socket_fd, &opts->selected_core, sizeof(uint8_t)); RECEIVE_DATA(&data->socket_fd, &msg, sizeof(MsrStaticData)); /* CPU Multipliers (minimum & maximum) */ if(msg.min_mult != CPU_INVALID_VALUE && msg.max_mult != CPU_INVALID_VALUE) { data->cpu_min_mult = (double) msg.min_mult / 100; data->cpu_max_mult = (double) msg.max_mult / 100; } /* Base clock */ if(msg.bclk != CPU_INVALID_VALUE && data->bus_freq == 0.0) data->bus_freq = (double) msg.bclk / 100; return 0; } /* MSRs dynamic values provided by libcpuid */ static int call_libcpuid_msr_dynamic(Labels *data) { const DaemonCommand cmd = LIBCPUID_MSR_DYNAMIC; MsrDynamicData msg; MSG_VERBOSE("%s", _("Calling libcpuid for retrieving CPU MSR dynamic values")); SEND_DATA(&data->socket_fd, &cmd, sizeof(DaemonCommand)); SEND_DATA(&data->socket_fd, &opts->selected_core, sizeof(unsigned)); RECEIVE_DATA(&data->socket_fd, &msg, sizeof(MsrDynamicData)); /* CPU Voltage */ if(msg.voltage != CPU_INVALID_VALUE) casprintf(&data->tab_cpu[VALUE][VOLTAGE], true, "%.3f V", (double) msg.voltage / 100); /* CPU Temperature */ if(msg.temp != CPU_INVALID_VALUE) casprintf(&data->tab_cpu[VALUE][TEMPERATURE], true, "%i°C", msg.temp); return 0; } #endif /* HAS_LIBCPUID */ /* Fill the Multiplier label with the most appropriate format */ static int cputab_fill_multipliers(Labels *data) { if(data->cpu_freq <= 0 || data->bus_freq <= 0.0) return 1; MSG_VERBOSE("%s", _("Calculating CPU multipliers")); const int fmt = (data->cpu_max_mult < 10) ? 1 : 0; const double cur_mult = (double) data->cpu_freq / data->bus_freq; if(data->cpu_min_mult <= 0.0 && data->cpu_max_mult <= 0.0) casprintf(&data->tab_cpu[VALUE][MULTIPLIER], false, "x %.2f", cur_mult); else if(data->cpu_min_mult <= 0.0 && data->cpu_max_mult > 0.0) casprintf(&data->tab_cpu[VALUE][MULTIPLIER], false, "x%.1f (?-%.*f)", cur_mult, fmt, data->cpu_max_mult); else if(data->cpu_min_mult > 0.0 && data->cpu_max_mult <= 0.0) casprintf(&data->tab_cpu[VALUE][MULTIPLIER], false, "x%.1f (%.*f-?)", cur_mult, fmt, data->cpu_min_mult); else casprintf(&data->tab_cpu[VALUE][MULTIPLIER], false, "x%.1f (%.*f-%.*f)", cur_mult, fmt, data->cpu_min_mult, fmt, data->cpu_max_mult); return 0; } #if HAS_DMIDECODE /* Call Dmidecode through CPU-X but do nothing else */ int run_dmidecode(void) { return dmidecode(!opts->verbose, NULL); } /* Elements provided by dmidecode */ static int call_dmidecode(Labels *data) { int i; const DaemonCommand cmd = DMIDECODE; DmidecodeData msg; MSG_VERBOSE("%s", _("Calling dmidecode")); SEND_DATA(&data->socket_fd, &cmd, sizeof(DaemonCommand)); RECEIVE_DATA(&data->socket_fd, &msg, sizeof(DmidecodeData)); if(msg.ret) return 1; /* Tab CPU */ data->tab_cpu[VALUE][PACKAGE] = strdup(msg.cpu_package); if(data->bus_freq == 0.0) data->bus_freq = msg.bus_freq; /* Tab Motherboard */ for(i = MANUFACTURER; i < CHIPVENDOR; i++) data->tab_motherboard[VALUE][i] = strdup_and_set_unit(msg.motherboard[i]); /* Tab RAM */ data->dimm_count = msg.dimm_count; for(i = BANK0; i < (int) data->dimm_count; i++) data->tab_memory[VALUE][i] = strdup_and_set_unit(msg.memory[i]); return 0; } #endif /* HAS_DMIDECODE */ /* Calculate total CPU usage */ static int cpu_usage(Labels *data) { static long *pre = NULL; long *new = NULL; double loadavg; enum StatType { USER, NICE, SYSTEM, INTR, IDLE, LASTSTAT }; MSG_VERBOSE("%s", _("Calculating CPU usage")); if(pre == NULL) { pre = calloc(LASTSTAT, sizeof(long)); ALLOC_CHECK(pre); } new = calloc(LASTSTAT, sizeof(long)); ALLOC_CHECK(new); #ifdef __linux__ FILE *fp; fp = fopen("/proc/stat","r"); fscanf(fp,"%*s %li %li %li %li %*s %*s %*s %*s %*s %*s", &new[USER], &new[NICE], &new[SYSTEM], &new[IDLE]); fclose(fp); #else /* __linux__ */ size_t len = sizeof(new) * LASTSTAT; if(sysctlbyname("kern.cp_time", new, &len, NULL, 0)) return 1; #endif /* __linux__ */ loadavg = (double)((new[USER] + new[NICE] + new[SYSTEM] + new[INTR]) - (pre[USER] + pre[NICE] + pre[SYSTEM] + pre[INTR])) / ((new[USER] + new[NICE] + new[SYSTEM] + new[INTR] + new[IDLE]) - (pre[USER] + pre[NICE] + pre[SYSTEM] + pre[INTR] + pre[IDLE])); casprintf(&data->tab_cpu[VALUE][USAGE], false, "%6.2f %%", loadavg * 100); memcpy(pre, new, LASTSTAT * sizeof(long)); free(new); return 0; } #if HAS_BANDWIDTH /* Call Bandwidth through CPU-X but do nothing else */ int run_bandwidth(void) { char *argv[] = { NULL, "--fastest", NULL }; return bandwidth_main(2, argv); } /* Compute CPU cache speed */ static int call_bandwidth(Labels *data) { static bool first = true; int i, err; pthread_t tid; if(data->w_data->size[0] < 1) return 1; MSG_VERBOSE("%s", _("Calling bandwidth")); /* Run bandwidth in a separated thread */ err = pthread_create(&tid, NULL, (void *)bandwidth_cpux, data); if(first) { err += pthread_join(tid, NULL); first = false; } else err += pthread_detach(tid); /* Speed labels */ for(i = 0; i < LASTCACHES / CACHEFIELDS; i++) casprintf(&data->tab_caches[VALUE][i * CACHEFIELDS + L1SPEED], true, "%.2f %s/s", (double) data->w_data->speed[i] / 10, UNIT_MB); return err; } #endif /* HAS_BANDWIDTH */ #if HAS_LIBPCI /* Check is GPU is enabled */ static bool gpu_is_on(char *device_path) { #ifdef __linux__ return !access(format("%s/driver", device_path), F_OK); #else /* __linux__ */ UNUSED(device_path); return true; #endif /* __linux__ */ } /* Find driver name for a device */ static int find_gpu_device_path(struct pci_dev *dev, char **device_path) { int err = 0; #ifdef __linux__ /* Adapted from http://git.kernel.org/cgit/utils/pciutils/pciutils.git/tree/ls-kernel.c */ char *base = NULL; if(dev->access->method != PCI_ACCESS_SYS_BUS_PCI) { MSG_ERROR("dev->access->method=%u", dev->access->method); return 1; } if((base = pci_get_param(dev->access, "sysfs.path")) == NULL) { MSG_ERROR("%s", "pci_get_param (sysfs.path)"); return 1; } casprintf(device_path, false, "%s/devices/%04x:%02x:%02x.%d", base, dev->domain, dev->bus, dev->dev, dev->func); #else /* __linux__ */ err = popen_to_str(device_path, "sysctl hw.dri | grep busid | grep %04x:%02x:%02x.%d | cut -d. -f1-3", dev->domain, dev->bus, dev->dev, dev->func); #endif /* __linux__ */ MSG_DEBUG("find_gpu_device_path: device_path=%s", *device_path); return err; } static int find_gpu_kernel_driver(char *device_path, char *driver_name, enum EnGpuDrv *gpu_driver) { int i; char *drv = NULL, *cmd = NULL; *gpu_driver = GPUDRV_UNKNOWN; const struct { const char *str; const enum EnGpuDrv val; } gpu_drivers[] = { { "fglrx", GPUDRV_FGLRX }, { "radeon", GPUDRV_RADEON }, { "amdgpu", GPUDRV_AMDGPU }, { "i915", GPUDRV_INTEL }, { "nvidia", GPUDRV_NVIDIA }, { "nouveau", GPUDRV_NOUVEAU }, { "vfio-pci", GPUDRV_VFIO }, { "", GPUDRV_UNKNOWN } }; /* Check GPU state */ if(!gpu_is_on(device_path)) { MSG_WARNING(_("No kernel driver in use for graphic card at path %s"), device_path); return 1; } #ifdef __linux__ ssize_t n; char buff[MAXSTR] = ""; /* Get driver name (as string) */ if((n = readlink(format("%s/driver", device_path), buff, MAXSTR)) < 0) { MSG_ERRNO("readlink(%s)", device_path); return 1; } buff[n] = '\0'; drv = strrchr(buff, '/'); strncpy(driver_name, (drv == NULL) ? buff : drv + 1, MAXSTR); #else /* __linux__ */ size_t len = MAXSTR; if(!sysctlbyname(format("%s.name", device_path), driver_name, &len, NULL, 0)) { if((drv = strchr(driver_name, ' ')) != NULL) drv[0] = '\0'; } #endif /* __linux__ */ /* Find driver type */ for(i = 0; (i != GPUDRV_UNKNOWN - 1) && (strstr(gpu_drivers[i].str, driver_name) == NULL); i++); *gpu_driver = gpu_drivers[i].val; if(*gpu_driver == GPUDRV_UNKNOWN) { MSG_WARNING(_("Your GPU kernel driver is unknown: %s"), driver_name); return 1; } /* Check for discrete GPU */ switch(*gpu_driver) { case GPUDRV_NVIDIA: case GPUDRV_NOUVEAU: if(command_exists("optirun") && !popen_to_str(&cmd, "optirun --status") && (strstr(cmd, "Bumblebee status: Ready") != NULL)) *gpu_driver = (*gpu_driver) == GPUDRV_NVIDIA ? GPUDRV_NVIDIA_BUMBLEBEE : GPUDRV_NOUVEAU_BUMBLEBEE; break; default: break; } free(cmd); return 0; } static int find_gpu_user_mode_driver(enum EnGpuDrv gpu_driver, char *user_mode_driver) { int err = 0; #if HAS_LIBGLFW const char *description, *gl_ver = NULL, *umd_ver = NULL; GLFWwindow *win = NULL; if(glfwInit() == GLFW_FALSE) { err = glfwGetError(&description); goto clean; } glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); if((err = glfwGetError(&description)) != GLFW_NO_ERROR) goto clean; win = glfwCreateWindow(640, 480, "", NULL, NULL); if((err = glfwGetError(&description)) != GLFW_NO_ERROR) goto clean; glfwMakeContextCurrent(win); if((err = glfwGetError(&description)) != GLFW_NO_ERROR) goto clean; gl_ver = (const char*) glGetString(GL_VERSION); if(gl_ver == NULL) { err = glGetError() == GL_NO_ERROR ? -1 : (int) glGetError(); description = "glGetString"; goto clean; } switch(gpu_driver) { case GPUDRV_AMDGPU: case GPUDRV_INTEL: case GPUDRV_RADEON: case GPUDRV_NOUVEAU: case GPUDRV_NOUVEAU_BUMBLEBEE: umd_ver = strstr(gl_ver, "Mesa"); break; case GPUDRV_NVIDIA: umd_ver = strstr(gl_ver, "NVIDIA"); break; default: break; } if(umd_ver != NULL) snprintf(user_mode_driver, MAXSTR, "%s", umd_ver); else MSG_WARNING(_("Your GPU user mode driver is unknown: %s"), gl_ver); clean: if(err) MSG_ERROR(_("failed to call GLFW (%i): %s"), err, description); if(win != NULL) glfwDestroyWindow(win); #else UNUSED(gpu_driver); UNUSED(user_mode_driver); #endif /* HAS_LIBGLFW */ return err; } #define DEVICE_VENDOR_STR(d) pci_lookup_name(pacc, buff, MAXSTR, PCI_LOOKUP_VENDOR, d->vendor_id, d->device_id) #define DEVICE_PRODUCT_STR(d) pci_lookup_name(pacc, buff, MAXSTR, PCI_LOOKUP_DEVICE, d->vendor_id, d->device_id) /* Find some PCI devices, like chipset and GPU */ static int find_devices(Labels *data) { /* Adapted from http://git.kernel.org/cgit/utils/pciutils/pciutils.git/tree/example.c */ bool chipset_found = false; char *gpu_vendor = NULL; char gpu_driver[MAXSTR] = "", gpu_umd[MAXSTR] = "", buff[MAXSTR] = ""; struct pci_access *pacc; struct pci_dev *dev; MSG_VERBOSE("%s", _("Finding devices")); pacc = pci_alloc(); /* Get the pci_access structure */ #ifdef __FreeBSD__ int ret = -1; const DaemonCommand cmd = ACCESS_DEV_PCI; if(DAEMON_UP && access(DEV_PCI, W_OK)) { SEND_DATA(&data->socket_fd, &cmd, sizeof(DaemonCommand)); RECEIVE_DATA(&data->socket_fd, &ret, sizeof(int)); } if(ret && access(DEV_PCI, W_OK)) { MSG_WARNING(_("Skip devices search (wrong permissions on %s device)"), DEV_PCI); return 1; } #endif /* __FreeBSD__ */ pci_init(pacc); /* Initialize the PCI library */ pci_scan_bus(pacc); /* We want to get the list of devices */ /* Iterate over all devices */ for(dev = pacc->devices; dev != NULL; dev = dev->next) { pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Looking for chipset */ if(!chipset_found && (dev->device_class == PCI_CLASS_BRIDGE_ISA)) { casprintf(&data->tab_motherboard[VALUE][CHIPVENDOR], false, DEVICE_VENDOR_STR(dev)); casprintf(&data->tab_motherboard[VALUE][CHIPMODEL], false, DEVICE_PRODUCT_STR(dev)); chipset_found = true; } /* Looking for GPU */ if((data->gpu_count < LASTGRAPHICS / GPUFIELDS) && ((dev->device_class >> 8) == PCI_BASE_CLASS_DISPLAY)) { switch(dev->vendor_id) { case 0x1002: gpu_vendor = "AMD"; break; case 0x8086: gpu_vendor = "Intel"; break; case 0x10DE: gpu_vendor = "NVIDIA"; break; default: gpu_vendor = DEVICE_VENDOR_STR(dev); MSG_WARNING(_("Your GPU vendor is unknown: %s (0x%X)"), gpu_vendor, dev->vendor_id); } memset(gpu_driver, 0, MAXSTR); memset(buff, 0, MAXSTR); find_gpu_device_path(dev, &data->g_data->device_path[data->gpu_count]); find_gpu_kernel_driver(data->g_data->device_path[data->gpu_count], gpu_driver, &data->g_data->gpu_driver[data->gpu_count]); find_gpu_user_mode_driver(data->g_data->gpu_driver[data->gpu_count], gpu_umd); casprintf(&data->tab_graphics[VALUE][GPU1VENDOR + data->gpu_count * GPUFIELDS], false, "%s", gpu_vendor); casprintf(&data->tab_graphics[VALUE][GPU1DRIVER + data->gpu_count * GPUFIELDS], false, "%s", gpu_driver); casprintf(&data->tab_graphics[VALUE][GPU1UMD + data->gpu_count * GPUFIELDS], false, "%s", gpu_umd); casprintf(&data->tab_graphics[VALUE][GPU1MODEL + data->gpu_count * GPUFIELDS], false, "%s", DEVICE_PRODUCT_STR(dev)); casprintf(&data->tab_graphics[VALUE][GPU1DIDRID + data->gpu_count * GPUFIELDS], false, "0x%04X:0x%02X", dev->device_id, pci_read_byte(dev, PCI_REVISION_ID)); data->gpu_count++; } } pci_cleanup(pacc); if(!chipset_found) MSG_ERROR("%s", _("failed to find chipset vendor and model")); if(!data->gpu_count) MSG_ERROR("%s", _("failed to find graphic card vendor and model")); #if 0 while(data->gpu_count < LASTGRAPHICS / GPUFIELDS) { casprintf(&data->tab_graphics[VALUE][GPU1VENDOR + data->gpu_count * GPUFIELDS], false, "Vendor %u", data->gpu_count); casprintf(&data->tab_graphics[VALUE][GPU1DRIVER + data->gpu_count * GPUFIELDS], false, "Driver %u", data->gpu_count); casprintf(&data->tab_graphics[VALUE][GPU1UMD + data->gpu_count * GPUFIELDS], false, "UMD %u", data->gpu_count); casprintf(&data->tab_graphics[VALUE][GPU1MODEL + data->gpu_count * GPUFIELDS], false, "Model %u", data->gpu_count); data->gpu_count++; } #endif if(opts->selected_gpu >= data->gpu_count) opts->selected_gpu = 0; return !chipset_found + !data->gpu_count; } #undef DEVICE_VENDOR_STR #undef DEVICE_PRODUCT_STR #ifdef __linux__ static bool can_access_sys_debug_dri(Labels *data) { static int ret = 1; const DaemonCommand cmd = ACCESS_SYS_DEBUG; if(ret == 1) { if(!access(SYS_DEBUG_DRI, X_OK)) ret = 0; else if(DAEMON_UP) { SEND_DATA(&data->socket_fd, &cmd, sizeof(DaemonCommand)); RECEIVE_DATA(&data->socket_fd, &ret, sizeof(int)); } else ret = -2; } MSG_DEBUG("can_access_sys_debug_dri() ==> %i", ret); return !ret; } static int convert_pcie_speed_to_gen(char *pcie_speed, uint8_t *pcie_gen) { if (!strcmp(pcie_speed, "2.5 GT/s PCIe")) *pcie_gen = 1; else if (!strcmp(pcie_speed, "5.0 GT/s PCIe")) *pcie_gen = 2; else if (!strcmp(pcie_speed, "8.0 GT/s PCIe")) *pcie_gen = 3; else if (!strcmp(pcie_speed, "16.0 GT/s PCIe")) *pcie_gen = 4; else if (!strcmp(pcie_speed, "32.0 GT/s PCIe")) *pcie_gen = 5; else if (!strcmp(pcie_speed, "64.0 GT/s PCIe")) *pcie_gen = 6; else *pcie_gen = 0; return 0; } #endif /* __linux__ */ /* Retrieve GPU temperature and clocks */ static int gpu_monitoring(Labels *data) { #ifdef __linux__ bool gpu_ok; int ret_drm, ret_hwmon, ret_temp, ret_load, ret_gclk, ret_mclk, ret_vram_used, ret_vram_total, ret_gvolt, ret_gpwr, ret_pcie_max_speed, ret_pcie_max_width, ret_pcie_sta_speed, ret_pcie_sta_width; uint8_t i, card_number, failed_count = 0, fglrx_count = 0, nvidia_count = 0, pcie_max_gen = 0, pcie_sta_gen = 0; long double divisor_temp, divisor_gclk, divisor_mclk, divisor_vram, divisor_gvolt, divisor_gpwr; char *temp = NULL, *gclk = NULL, *mclk = NULL, *load = NULL, *vram_used = NULL, *vram_total = NULL, *gvolt = NULL, *gpwr = NULL, *pcie_max_speed = NULL, *pcie_max_width = NULL, *pcie_sta_speed = NULL, *pcie_sta_width = NULL; static bool once_error = true; static char *cached_paths_drm[LASTGRAPHICS / GPUFIELDS] = { NULL }; static char *cached_paths_hwmon[LASTGRAPHICS / GPUFIELDS] = { NULL }; MSG_VERBOSE("%s", _("Retrieving GPU clocks")); for(i = 0; i < data->gpu_count; i++) { gpu_ok = gpu_is_on(data->g_data->device_path[i]); ret_drm = 0; ret_hwmon = 0; ret_temp = -1; ret_load = -1; ret_gclk = -1; ret_mclk = -1; ret_vram_used = -1; ret_vram_total = -1; ret_gvolt = -1; ret_gpwr = -1; ret_pcie_max_speed = -1; ret_pcie_max_width = -1; ret_pcie_sta_speed = -1; ret_pcie_sta_width = -1; divisor_temp = 1.0; divisor_gclk = 1.0; divisor_mclk = 1.0; divisor_vram = 1.0; divisor_gvolt = 1.0; divisor_gpwr = 1.0; if(gpu_ok && (data->g_data->gpu_driver[i] == GPUDRV_UNKNOWN)) { char gpu_driver[MAXSTR] = ""; find_gpu_kernel_driver(data->g_data->device_path[i], gpu_driver, &data->g_data->gpu_driver[i]); casprintf(&data->tab_graphics[VALUE][GPU1DRIVER + i * GPUFIELDS], false, "%s", gpu_driver); } else if(!gpu_ok) { data->g_data->gpu_driver[i] = GPUDRV_UNKNOWN; casprintf(&data->tab_graphics[VALUE][GPU1DRIVER + i * GPUFIELDS], false, _("None")); casprintf(&data->tab_graphics[VALUE][GPU1TEMPERATURE + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1PCIE + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1DIDRID + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1USAGE + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1MEMUSED + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1CORECLOCK + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1MEMCLOCK + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1VOLTAGE + i * GPUFIELDS], false, "---"); casprintf(&data->tab_graphics[VALUE][GPU1POWERAVG + i * GPUFIELDS], false, "---"); continue; } switch(data->g_data->gpu_driver[i]) { case GPUDRV_AMDGPU: case GPUDRV_INTEL: case GPUDRV_RADEON: case GPUDRV_NOUVEAU: case GPUDRV_NOUVEAU_BUMBLEBEE: /* HWmon */ divisor_temp = 1e3; if((cached_paths_hwmon[i] == NULL) && (data->g_data->gpu_driver[i] != GPUDRV_INTEL)) ret_hwmon = request_sensor_path(format("%s/hwmon", data->g_data->device_path[i]), &cached_paths_hwmon[i], RQT_GPU_HWMON); if(!ret_hwmon && (cached_paths_hwmon[i] != NULL)) ret_temp = fopen_to_str(&temp, "%s/temp1_input", cached_paths_hwmon[i]); /* DRM */ if(cached_paths_drm[i] == NULL) ret_drm = request_sensor_path(format("%s/drm", data->g_data->device_path[i]), &cached_paths_drm[i], RQT_GPU_DRM); if(ret_drm || (cached_paths_drm[i] == NULL) || (sscanf(cached_paths_drm[i], "/sys/bus/pci/devices/%*x:%*x:%*x.%*d/drm/card%hhu", &card_number) != 1)) goto skip_clocks; break; default: break; } switch(data->g_data->gpu_driver[i]) { case GPUDRV_AMDGPU: { const char *amdgpu_gpu_busy_file = format("%s/device/gpu_busy_percent", cached_paths_drm[i]); MSG_DEBUG("gpu_monitoring: amdgpu: amdgpu_gpu_busy_file=%s", amdgpu_gpu_busy_file); // ret_temp obtained above if(!access(amdgpu_gpu_busy_file, F_OK)) // Linux 4.19+ ret_load = fopen_to_str(&load, "%s", amdgpu_gpu_busy_file); else if(can_access_sys_debug_dri(data)) ret_load = popen_to_str(&load, "awk '/GPU Load/ { print $3 }' %s/%u/amdgpu_pm_info", SYS_DEBUG_DRI, card_number); ret_gclk = fopen_to_str(&gclk, "%s/freq1_input", cached_paths_hwmon[i]); ret_mclk = fopen_to_str(&mclk, "%s/freq2_input", cached_paths_hwmon[i]); ret_vram_used = fopen_to_str(&vram_used, "%s/device/mem_info_vram_used", cached_paths_drm[i]); ret_vram_total = fopen_to_str(&vram_total, "%s/device/mem_info_vram_total", cached_paths_drm[i]); ret_gvolt = fopen_to_str(&gvolt, "%s/in0_input", cached_paths_hwmon[i]); ret_gpwr = fopen_to_str(&gpwr, "%s/power1_average", cached_paths_hwmon[i]); divisor_gclk = 1e6; divisor_mclk = 1e6; divisor_vram = 1 << 20; divisor_gvolt = 1e3; divisor_gpwr = 1e6; break; } case GPUDRV_FGLRX: ret_temp = popen_to_str(&temp, "aticonfig --adapter=%1u --odgt | awk '/Sensor/ { print $5 }'", fglrx_count); ret_load = popen_to_str(&load, "aticonfig --adapter=%1u --odgc | awk '/GPU load/ { sub(\"%\",\"\",$4); print $4 }'", fglrx_count); ret_gclk = popen_to_str(&gclk, "aticonfig --adapter=%1u --odgc | awk '/Current Clocks/ { print $4 }'", fglrx_count); ret_mclk = popen_to_str(&mclk, "aticonfig --adapter=%1u --odgc | awk '/Current Clocks/ { print $5 }'", fglrx_count); ret_vram_used = -1; ret_vram_total = -1; ret_gvolt = -1; ret_gpwr = -1; fglrx_count++; break; case GPUDRV_INTEL: ret_temp = -1; ret_load = -1; ret_gclk = fopen_to_str(&gclk, "%s/gt_cur_freq_mhz", cached_paths_drm[i]); ret_mclk = -1; ret_vram_used = -1; ret_vram_total = -1; ret_gvolt = -1; ret_gpwr = -1; break; case GPUDRV_RADEON: // ret_temp obtained above ret_load = -1; ret_gclk = can_access_sys_debug_dri(data) ? popen_to_str(&gclk, "awk -F '(sclk: | mclk:)' 'NR==2 { print $2 }' %s/%u/radeon_pm_info", SYS_DEBUG_DRI, card_number) : -1; ret_mclk = can_access_sys_debug_dri(data) ? popen_to_str(&mclk, "awk -F '(mclk: | vddc:)' 'NR==2 { print $2 }' %s/%u/radeon_pm_info", SYS_DEBUG_DRI, card_number) : -1; ret_vram_used = -1; ret_vram_total = -1; ret_gvolt = can_access_sys_debug_dri(data) ? popen_to_str(&gvolt, "awk -F '(vddc: | vddci:)' 'NR==2 { print $2 }' %s/%u/radeon_pm_info", SYS_DEBUG_DRI, card_number) : -1; ret_gpwr = -1; divisor_gclk = 100.0; divisor_mclk = 100.0; break; case GPUDRV_NVIDIA: case GPUDRV_NVIDIA_BUMBLEBEE: { /* Doc: https://nvidia.custhelp.com/app/answers/detail/a_id/3751/~/useful-nvidia-smi-queries https://briot-jerome.developpez.com/fichiers/blog/nvidia-smi/list.txt */ const char *nvidia_cmd_base = (data->g_data->gpu_driver[i] == GPUDRV_NVIDIA_BUMBLEBEE) ? "optirun -b none nvidia-smi -c :8" : "nvidia-smi"; const char *nvidia_cmd_args = format("%s --format=csv,noheader,nounits --id=%1u", nvidia_cmd_base, nvidia_count); MSG_DEBUG("gpu_monitoring: nvidia: nvidia_cmd_args=%s", nvidia_cmd_args); ret_temp = popen_to_str(&temp, "%s --query-gpu=temperature.gpu", nvidia_cmd_args); ret_load = popen_to_str(&load, "%s --query-gpu=utilization.gpu", nvidia_cmd_args); ret_gclk = popen_to_str(&gclk, "%s --query-gpu=clocks.gr", nvidia_cmd_args); ret_mclk = popen_to_str(&mclk, "%s --query-gpu=clocks.mem", nvidia_cmd_args); ret_vram_used = popen_to_str(&vram_used, "%s --query-gpu=memory.used", nvidia_cmd_args); ret_vram_total = popen_to_str(&vram_total, "%s --query-gpu=memory.total", nvidia_cmd_args); ret_gvolt = -1; ret_gpwr = popen_to_str(&gpwr, "%s --query-gpu=power.draw", nvidia_cmd_args);; nvidia_count++; break; } case GPUDRV_NOUVEAU: case GPUDRV_NOUVEAU_BUMBLEBEE: { char *pstate = NULL; int ret_pstate = popen_to_str(&pstate, "grep '*' %1$s/%2$u/pstate || sed -n 1p %1$s/%2$u/pstate ", SYS_DEBUG_DRI, card_number); MSG_DEBUG("gpu_monitoring: nouveau: pstate=%s", pstate); // ret_temp obtained above ret_load = -1; ret_gclk = !ret_pstate && can_access_sys_debug_dri(data) ? popen_to_str(&gclk, "echo %s | grep -oP '(?<=core )[^ ]*' | cut -d- -f2", pstate) : -1; ret_mclk = !ret_pstate && can_access_sys_debug_dri(data) ? popen_to_str(&mclk, "echo %s | grep -oP '(?<=memory )[^ ]*'", pstate) : -1; ret_vram_used = -1; ret_vram_total = -1; ret_gvolt = -1; ret_gpwr = -1; FREE(pstate); break; } default: if(once_error) MSG_WARNING(_("Driver for GPU %u doesn't report frequencies"), i); continue; } // Linux 4.13+ const char *max_speed_file = format("%s/device/max_link_speed", cached_paths_drm[i]); const char *max_width_file = format("%s/device/max_link_width", cached_paths_drm[i]); const char *sta_speed_file = format("%s/device/current_link_speed", cached_paths_drm[i]); const char *sta_width_file = format("%s/device/current_link_width", cached_paths_drm[i]); if(!access(max_speed_file, F_OK) && !access(max_width_file, F_OK) && !access(sta_width_file, F_OK) && !access(sta_speed_file, F_OK)) { ret_pcie_max_speed = fopen_to_str(&pcie_max_speed, "%s", max_speed_file); ret_pcie_max_width = fopen_to_str(&pcie_max_width, "%s", max_width_file); ret_pcie_sta_speed = fopen_to_str(&pcie_sta_speed, "%s", sta_speed_file); ret_pcie_sta_width = fopen_to_str(&pcie_sta_width, "%s", sta_width_file); if(!ret_pcie_max_speed) convert_pcie_speed_to_gen(pcie_max_speed, &pcie_max_gen); if(!ret_pcie_sta_speed) convert_pcie_speed_to_gen(pcie_sta_speed, &pcie_sta_gen); } if(!ret_load) casprintf(&data->tab_graphics[VALUE][GPU1USAGE + i * GPUFIELDS], false, "%s%%", load); if(!ret_gclk) casprintf(&data->tab_graphics[VALUE][GPU1CORECLOCK + i * GPUFIELDS], true, "%.0Lf MHz", strtoull(gclk, NULL, 10) / divisor_gclk); if(!ret_mclk) casprintf(&data->tab_graphics[VALUE][GPU1MEMCLOCK + i * GPUFIELDS], true, "%.0Lf MHz", strtoull(mclk, NULL, 10) / divisor_mclk); if(!ret_vram_used && !ret_vram_total) casprintf(&data->tab_graphics[VALUE][GPU1MEMUSED + i * GPUFIELDS], true, "%.0Lf %s / %.0Lf %s", strtoull(vram_used, NULL, 10) / divisor_vram, UNIT_MIB, strtoull(vram_total, NULL, 10) / divisor_vram, UNIT_MIB); if(!ret_gvolt) casprintf(&data->tab_graphics[VALUE][GPU1VOLTAGE + i * GPUFIELDS], true, "%.2Lf V", strtoull(gvolt, NULL, 10) / divisor_gvolt); if(!ret_gpwr) casprintf(&data->tab_graphics[VALUE][GPU1POWERAVG + i * GPUFIELDS], true, "%.2Lf W", strtoull(gpwr, NULL, 10) / divisor_gpwr); skip_clocks: if(!ret_temp) casprintf(&data->tab_graphics[VALUE][GPU1TEMPERATURE + i * GPUFIELDS], true, "%.2Lf°C", strtoull(temp, NULL, 10) / divisor_temp); if(!ret_pcie_max_width && !ret_pcie_sta_width && pcie_sta_gen && pcie_max_gen) casprintf(&data->tab_graphics[VALUE][GPU1PCIE + i * GPUFIELDS], false, _("Current: PCIe Gen%1dx%d / Max: Gen%1dx%d"), pcie_sta_gen, atoi(pcie_sta_width), pcie_max_gen, atoi(pcie_max_width)); if(ret_temp && ret_load && ret_gclk && ret_mclk && ret_vram_used && ret_vram_total && ret_gvolt && ret_gpwr && ret_pcie_max_speed && ret_pcie_max_width && ret_pcie_sta_speed && ret_pcie_sta_width) failed_count++; FREE(temp); FREE(load); FREE(gclk); FREE(mclk); FREE(vram_used); FREE(vram_total); FREE(gvolt); FREE(gpwr); FREE(pcie_max_speed); FREE(pcie_max_width); FREE(pcie_sta_speed); FREE(pcie_sta_width); } if(once_error && failed_count) MSG_ERROR("%s", _("failed to retrieve GPU clocks")); once_error = false; return (failed_count == data->gpu_count); #else /* __linux__ */ UNUSED(data); return 0; #endif /* __linux__ */ } #endif /* HAS_LIBPCI */ /* Satic elements for System tab, OS specific */ static int system_static(Labels *data) { int err = 0; struct utsname name; MSG_VERBOSE("%s", _("Identifying running system")); err = uname(&name); if(err) MSG_ERRNO("%s", _("failed to identify running system")); else { casprintf(&data->tab_system[VALUE][KERNEL], false, "%s %s", name.sysname, name.release); /* Kernel label */ casprintf(&data->tab_system[VALUE][HOSTNAME], false, "%s", name.nodename); /* Hostname label */ } /* Compiler label */ err += popen_to_str(&data->tab_system[VALUE][COMPILER], "cc --version"); #ifdef __linux__ /* Distribution label */ err += popen_to_str(&data->tab_system[VALUE][DISTRIBUTION], ". /etc/os-release && echo $PRETTY_NAME"); #else /* __linux__ */ char tmp[MAXSTR]; size_t len = sizeof(tmp); /* Overwrite Kernel label */ err += sysctlbyname("kern.osrelease", &tmp, &len, NULL, 0); casprintf(&data->tab_system[VALUE][KERNEL], false, tmp); /* Distribution label */ err += sysctlbyname("kern.ostype", &tmp, &len, NULL, 0); casprintf(&data->tab_system[VALUE][DISTRIBUTION], false, tmp); #endif /* __linux__ */ return err; } #if HAS_LIBSYSTEM /* Dynamic elements for System tab, provided by libprocps/libstatgrab */ static int system_dynamic(Labels *data) { int err = 0, i, j = 0; time_t uptime_s = 0; struct tm *tm; MemoryData *m_data = data->m_data; static PrefixUnit pu_mem = { .init = false }, pu_swap = { .init = false }; #if HAS_LIBPROCPS MSG_VERBOSE("%s", _("Calling libprocps")); /* System uptime */ uptime_s = (time_t) uptime(NULL, NULL); /* Memory variables */ meminfo(); if(!pu_mem.init || !pu_swap.init) { find_best_prefix(kb_main_total, MULT_K, false, &pu_mem); find_best_prefix(kb_swap_total, MULT_K, false, &pu_swap); } m_data->mem_usage[BARUSED] = kb_main_used / (long double) pu_mem.divisor; m_data->mem_usage[BARBUFFERS] = kb_main_buffers / (long double) pu_mem.divisor; m_data->mem_usage[BARCACHED] = kb_main_cached / (long double) pu_mem.divisor; m_data->mem_usage[BARFREE] = kb_main_free / (long double) pu_mem.divisor; m_data->mem_usage[BARSWAP] = kb_swap_used / (long double) pu_swap.divisor; m_data->mem_total = kb_main_total / (long double) pu_mem.divisor; m_data->swap_total = kb_swap_total / (long double) pu_swap.divisor; #endif /* HAS_LIBPROCPS */ #if HAS_LIBSTATGRAB static bool called = false; sg_mem_stats *mem; /* Memory labels */ sg_swap_stats *swap; sg_host_info *info; MSG_VERBOSE("%s", _("Calling libstatgrab")); /* Libstatgrab initialization */ if(!called) { err += sg_init(0); called = true; } mem = sg_get_mem_stats(NULL); swap = sg_get_swap_stats(NULL); info = sg_get_host_info(NULL); /* System uptime */ uptime_s = info->uptime; /* Memory variables */ if(!pu_mem.init || !pu_swap.init) { find_best_prefix(mem->total, MULT_NONE, false, &pu_mem); find_best_prefix(swap->total, MULT_NONE, false, &pu_swap); } m_data->mem_usage[BARUSED] = mem->used / (long double) pu_mem.divisor; m_data->mem_usage[BARBUFFERS] = 0; m_data->mem_usage[BARCACHED] = mem->cache / (long double) pu_mem.divisor; m_data->mem_usage[BARFREE] = mem->free / (long double) pu_mem.divisor; m_data->mem_usage[BARSWAP] = swap->used / (long double) pu_swap.divisor; m_data->mem_total = mem->total / (long double) pu_mem.divisor; m_data->swap_total = swap->total / (long double) pu_swap.divisor; #endif /* HAS_LIBSTATGRAB */ /* Memory labels */ for(i = USED; i < SWAP; i++) casprintf(&data->tab_system[VALUE][i], false, "%3.2Lf %s / %3.2Lf %s", m_data->mem_usage[j++], pu_mem.prefix, m_data->mem_total, pu_mem.prefix); casprintf(&data->tab_system[VALUE][SWAP], false, "%3.2Lf %s / %3.2Lf %s", m_data->mem_usage[j], pu_swap.prefix, m_data->swap_total, pu_swap.prefix); /* Uptime label */ tm = gmtime(&uptime_s); casprintf(&data->tab_system[VALUE][UPTIME], false, _("%i days, %i hours, %i minutes, %i seconds"), tm->tm_yday, tm->tm_hour, tm->tm_min, tm->tm_sec); return err; } #endif /* HAS_LIBSYSTEM */ /* Compute all prime numbers in 'duration' seconds */ static void *primes_bench(void *p_data) { uint64_t i, num, sup; Labels *data = p_data; BenchData *b_data = data->b_data; while(b_data->elapsed < b_data->duration * 60 && b_data->run) { /* b_data->num is shared by all threads */ pthread_mutex_lock(&b_data->mutex_num); b_data->num++; num = b_data->num; pthread_mutex_unlock(&b_data->mutex_num); /* Slow mode: loop from i to num, prime if num == i Fast mode: loop from i to sqrt(num), prime if num mod i != 0 */ sup = b_data->fast_mode ? sqrt(num) : num; for(i = 2; (i < sup) && (num % i != 0); i++); if((b_data->fast_mode && num % i) || (!b_data->fast_mode && num == i)) { pthread_mutex_lock(&b_data->mutex_primes); b_data->primes++; pthread_mutex_unlock(&b_data->mutex_primes); } /* Only the first thread compute elapsed time */ if(b_data->first_thread == pthread_self()) b_data->elapsed = (clock() - b_data->start) / CLOCKS_PER_SEC / b_data->threads; } if(b_data->first_thread == pthread_self()) { b_data->run = false; pthread_mutex_destroy(&b_data->mutex_num); pthread_mutex_destroy(&b_data->mutex_primes); } return NULL; } /* Report score of benchmarks */ static int benchmark_status(Labels *data) { char *buff = NULL; BenchData *b_data = data->b_data; enum EnTabBench ind = b_data->fast_mode ? PRIMEFASTSCORE : PRIMESLOWSCORE; MSG_VERBOSE("%s", _("Updating benchmark status")); asprintf(&data->tab_bench[VALUE][PARAMDURATION], _("%u mins"), data->b_data->duration); asprintf(&data->tab_bench[VALUE][PARAMTHREADS], "%u", data->b_data->threads); asprintf(&data->tab_bench[VALUE][PRIMESLOWRUN], _("Inactive")); asprintf(&data->tab_bench[VALUE][PRIMEFASTRUN], _("Inactive")); if(b_data->primes == 0) { asprintf(&data->tab_bench[VALUE][PRIMESLOWSCORE], _("Not started")); asprintf(&data->tab_bench[VALUE][PRIMEFASTSCORE], _("Not started")); return 0; } if(b_data->run) asprintf(&data->tab_bench[VALUE][ind + 1], _("Active")); if(b_data->run) { if(b_data->duration * 60 - b_data->elapsed > 60 * 59) asprintf(&buff, _("(%u hours left)"), (b_data->duration - b_data->elapsed / 60) / 60); else if(b_data->duration * 60 - b_data->elapsed >= 60) asprintf(&buff, _("(%u minutes left)"), b_data->duration - b_data->elapsed / 60); else asprintf(&buff, _("(%u seconds left)"), b_data->duration * 60 - b_data->elapsed); } else { if(b_data->elapsed >= 60 * 60) asprintf(&buff, _("in %u hours"), b_data->elapsed / 60 / 60); else if(b_data->elapsed >= 60) asprintf(&buff, _("in %u minutes"), b_data->elapsed / 60); else asprintf(&buff, _("in %u seconds"), b_data->elapsed); } asprintf(&data->tab_bench[VALUE][ind], "%'u %s", b_data->primes, buff); free(buff); return 0; } /* Perform a multithreaded benchmark (compute prime numbers) */ void start_benchmarks(Labels *data) { int err = 0; unsigned i; pthread_t *t_id = NULL; BenchData *b_data = data->b_data; MSG_VERBOSE("%s", _("Starting benchmark")); b_data->run = true; b_data->elapsed = 0; b_data->num = 2; b_data->primes = 1; b_data->start = clock(); t_id = malloc(sizeof(pthread_t) * b_data->threads); ALLOC_CHECK(t_id); err += pthread_mutex_init(&b_data->mutex_num, NULL); err += pthread_mutex_init(&b_data->mutex_primes, NULL); for(i = 0; i < b_data->threads; i++) err += pthread_create(&t_id[i], NULL, primes_bench, data); b_data->first_thread = t_id[0]; free(t_id); if(err) MSG_ERROR("%s", _("an error occurred while starting benchmark")); } /************************* Fallback functions (static) *************************/ #if HAS_LIBCPUID /* If dmidecode fails to find CPU package, check in database */ static int cputab_package_fallback(Labels *data) { int i = -1; const Package_DB *db; LibcpuidData *l_data = data->l_data; if(l_data->cpu_vendor_id < 0 || data->tab_cpu[VALUE][CODENAME] == NULL || data->tab_cpu[VALUE][SPECIFICATION] == NULL) return 1; MSG_VERBOSE("%s", _("Finding CPU package in fallback mode")); if(l_data->cpu_vendor_id == VENDOR_INTEL) db = package_intel; else if(l_data->cpu_vendor_id == VENDOR_AMD) db = package_amd; else db = package_unknown; while(db[++i].socket != NULL) { const bool codename_defined = (db[i].codename != NULL); const bool model_defined = (db[i].model != NULL); const bool codename_matchs = codename_defined && (strstr(data->tab_cpu[VALUE][CODENAME], db[i].codename) != NULL); const bool model_matchs = model_defined && (strstr(data->tab_cpu[VALUE][SPECIFICATION], db[i].model) != NULL); if((codename_matchs && model_matchs) || (codename_matchs && !model_defined) || (!codename_defined && model_matchs)) { casprintf(&data->tab_cpu[VALUE][PACKAGE], false, db[i].socket); return 0; } } MSG_WARNING(_("Your CPU socket is not present in the database ==> %s, codename: %s"), data->tab_cpu[VALUE][SPECIFICATION], data->tab_cpu[VALUE][CODENAME]); data->tab_cpu[VALUE][PACKAGE][0] = '\0'; return 2; } #endif /* HAS_LIBCPUID */ /* Get minimum and maximum CPU multipliers */ static int cputab_multipliers_fallback(Labels *data) { int err = 0; if(data->bus_freq <= 0) return 1; #ifdef __linux__ char *min_freq_str = NULL; char *max_freq_str = NULL; MSG_VERBOSE("%s", _("Calculating CPU multipliers in fallback mode")); /* Minimum multiplier */ if(!(err = fopen_to_str(&min_freq_str, "%s%i/cpufreq/cpuinfo_min_freq", SYS_CPU, opts->selected_core))) { data->cpu_min_mult = round((strtod(min_freq_str, NULL) / 1e3) / data->bus_freq); free(min_freq_str); } /* Maximum multiplier */ if(!(err = fopen_to_str(&max_freq_str, "%s%i/cpufreq/cpuinfo_max_freq", SYS_CPU, opts->selected_core))) { data->cpu_max_mult = round((strtod(max_freq_str, NULL) / 1e3) / data->bus_freq); free(max_freq_str); } #endif /* __linux__ */ return err; } /* Retrieve missing Motherboard data if run as regular user */ static int motherboardtab_fallback(Labels *data) { int err = 0; #ifdef __linux__ int i; const char *id[] = { "board_vendor", "board_name", "board_version", "bios_vendor", "bios_version", "bios_date", NULL }; MSG_VERBOSE("%s", _("Retrieving motherboard information in fallback mode")); /* Tab Motherboard */ for(i = 0; id[i] != NULL; i++) err += fopen_to_str(&data->tab_motherboard[VALUE][i], "%s/%s", SYS_DMI, id[i]); #else /* __linux__ */ UNUSED(data); #endif /* __linux__ */ if(err) MSG_ERROR("%s", _("failed to retrieve motherboard information (fallback mode)")); return err; } /* Retrieve static data if other functions failed */ static int fallback_mode_static(Labels *data) { int err = 0; #if HAS_LIBCPUID if(string_is_empty(data->tab_cpu[VALUE][PACKAGE]) || strstr(data->tab_cpu[VALUE][PACKAGE], "CPU") != NULL || strstr(data->tab_cpu[VALUE][PACKAGE], "Microprocessor") != NULL) err += cputab_package_fallback(data); #endif /* HAS_LIBCPUID */ if(data->cpu_min_mult <= 0.0 || data->cpu_max_mult <= 0.0) err += cputab_multipliers_fallback(data); if(string_is_empty(data->tab_motherboard[VALUE][MANUFACTURER]) || string_is_empty(data->tab_motherboard[VALUE][MBMODEL]) || string_is_empty(data->tab_motherboard[VALUE][REVISION]) || string_is_empty(data->tab_motherboard[VALUE][BRAND]) || string_is_empty(data->tab_motherboard[VALUE][BIOSVERSION]) || string_is_empty(data->tab_motherboard[VALUE][DATE])) err += motherboardtab_fallback(data); return err; } /************************* Fallback functions (dynamic) *************************/ /* Retrieve CPU temperature if run as regular user */ static int cputab_temp_fallback(Labels *data) { int err = 0; MSG_VERBOSE("%s", _("Retrieving CPU temperature in fallback mode")); #ifdef __linux__ char *temp; static char **cached_paths = NULL; # if HAS_LIBCPUID static bool module_loaded = false; /* Load kernel modules */ if(!module_loaded && (data->l_data->cpu_vendor_id == VENDOR_INTEL)) module_loaded = !load_module("coretemp", &data->socket_fd); else if(!module_loaded && (data->l_data->cpu_vendor_id == VENDOR_AMD) && (data->l_data->cpu_ext_family <= 0x8)) module_loaded = !load_module("k8temp", &data->socket_fd); else if(!module_loaded && (data->l_data->cpu_vendor_id == VENDOR_AMD) && (data->l_data->cpu_ext_family >= 0x10)) module_loaded = !load_module("k10temp", &data->socket_fd); # endif /* HAS_LIBCPUID */ /* Filenames are cached */ if(cached_paths == NULL) { cached_paths = calloc(data->cpu_count, sizeof(char *)); ALLOC_CHECK(cached_paths); } if(!cached_paths[opts->selected_core]) if((err = request_sensor_path(SYS_HWMON, &cached_paths[opts->selected_core], RQT_CPU_TEMPERATURE))) err = request_sensor_path(SYS_HWMON, &cached_paths[opts->selected_core], RQT_CPU_TEMPERATURE_OTHERS); if(!err && cached_paths[opts->selected_core]) { if(!(err = fopen_to_str(&temp, cached_paths[opts->selected_core]))) { casprintf(&data->tab_cpu[VALUE][TEMPERATURE], true, "%.2f°C", atof(temp) / 1e3); free(temp); } } #else /* __linux__ */ /* Tested on FreeBSD 12: https://github.com/X0rg/CPU-X/issues/121#issuecomment-575985765 */ char temp[MAXSTR]; size_t len = sizeof(temp); if(!(err = sysctlbyname(format("dev.cpu.%i.temperature", opts->selected_core), temp, &len, NULL, 0))) casprintf(&data->tab_cpu[VALUE][TEMPERATURE], true, "%s", temp); #endif /* __linux__ */ if(err) MSG_ERROR("%s", _("failed to retrieve CPU temperature (fallback mode)")); return err; } /* Retrieve CPU voltage if run as regular user */ static int cputab_volt_fallback(Labels *data) { int err = 0; #ifdef __linux__ char *voltage; static char *cached_path = NULL; MSG_VERBOSE("%s", _("Retrieving CPU voltage in fallback mode")); if(cached_path == NULL) err = request_sensor_path(SYS_HWMON, &cached_path, RQT_CPU_VOLTAGE); if(!err && (cached_path != NULL)) { if(!(err = fopen_to_str(&voltage, cached_path))) { casprintf(&data->tab_cpu[VALUE][VOLTAGE], true, "%.3f V", atof(voltage) / 1e3); free(voltage); } } else MSG_ERROR("%s", _("failed to retrieve CPU voltage (fallback mode)")); #else /* __linux__ */ UNUSED(data); #endif /* __linux__ */ return err; } /* Retrieve CPU frequency if Libcpuid is missing */ static int cputab_freq_fallback(Labels *data) { int err = 0; #ifdef __linux__ char *freq; MSG_VERBOSE("%s", _("Retrieving CPU frequency in fallback mode")); if(!(err = fopen_to_str(&freq, "%s%i/cpufreq/scaling_cur_freq", SYS_CPU, opts->selected_core))) { data->cpu_freq = (int) round(strtod(freq, NULL) / 1e3); casprintf(&data->tab_cpu[VALUE][CORESPEED], true, "%d MHz", data->cpu_freq); free(freq); } else MSG_ERROR("%s", _("failed to retrieve CPU frequency (fallback mode)")); #else /* __linux__ */ UNUSED(data); #endif /* __linux__ */ return err; } /* Retrieve dynamic data if other functions failed */ static int fallback_mode_dynamic(Labels *data) { enum FallbackDynamic { TEMP, VOLT, FREQ, LASTFALLBACK }; static bool use_fallback[LASTFALLBACK] = { false }; int err = 0; if(string_is_empty(data->tab_cpu[VALUE][TEMPERATURE]) || use_fallback[TEMP]) { use_fallback[TEMP] = true; err += err_func(cputab_temp_fallback, data); } if(string_is_empty(data->tab_cpu[VALUE][VOLTAGE]) || use_fallback[VOLT]) { use_fallback[VOLT] = true; err += err_func(cputab_volt_fallback, data); } if(string_is_empty(data->tab_cpu[VALUE][CORESPEED]) || use_fallback[FREQ] || opts->freq_fallback) { use_fallback[FREQ] = true; err += err_func(cputab_freq_fallback, data); } return err; } CPU-X-4.2.0/src/core.h000066400000000000000000000062551403012130000142310ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE core.h */ #ifndef _CORE_H_ #define _CORE_H_ #include "cpu-x.h" #if HAS_LIBPCI # include "pci/pci.h" #endif /* HAS_LIBPCI */ /* Avoid to re-run a function if an error was occurred in previous call */ static int err_func(int (*func)(Labels *), Labels *data); #if HAS_LIBCPUID /* Static elements provided by libcpuid */ static int call_libcpuid_static(Labels *data); /* Required: HAS_LIBCPUID */ /* Dynamic elements provided by libcpuid */ static int call_libcpuid_dynamic(Labels *data); /* Required: HAS_LIBCPUID */ /* MSRs static values provided by libcpuid */ static int call_libcpuid_msr_static(Labels *data); /* Required: HAS_LIBCPUID && DAEMON_UP */ /* MSRs dynamic values provided by libcpuid */ static int call_libcpuid_msr_dynamic(Labels *data); /* Required: HAS_LIBCPUID && DAEMON_UP */ #endif /* HAS_LIBCPUID */ /* Fill the Multiplier label with the most appropriate format */ static int cputab_fill_multipliers(Labels *data); /* Required: none Both normal and fallback mode provide CPU multipliers, need to be call after */ #if HAS_DMIDECODE /* Elements provided by dmidecode */ static int call_dmidecode(Labels *data); /* Required: HAS_DMIDECODE && DAEMON_UP */ #endif /* HAS_DMIDECODE */ #if HAS_BANDWIDTH /* Compute CPU cache speed */ static int call_bandwidth(Labels *data); /* Required: HAS_BANDWIDTH */ #endif /* HAS_BANDWIDTH */ /* Calculate total CPU usage */ static int cpu_usage(Labels *data); /* Required: none */ #if HAS_LIBPCI /* Find some PCI devices, like chipset and GPU */ static int find_devices(Labels *data); /* Required: HAS_LIBPCI */ /* Retrieve GPU temperature and clocks */ static int gpu_monitoring(Labels *data); /* Required: HAS_LIBPCI */ #endif /* HAS_LIBPCI */ /* Satic elements for System tab, OS specific */ static int system_static(Labels *data); /* Required: none */ #if (HAS_LIBSYSTEM) /* Dynamic elements for System tab, provided by libprocps/libstatgrab */ static int system_dynamic(Labels *data); /* Required: HAS_LIBPROCPS || HAS_LIBSTATGRAB */ #endif /* HAS_LIBSYSTEM */ /* Report score of benchmarks */ static int benchmark_status(Labels *data); /* Required: none */ /* Retrieve static data if other functions failed */ static int fallback_mode_static(Labels *data); /* Retrieve dynamic data if other functions failed */ static int fallback_mode_dynamic(Labels *data); #endif /* _CORE_H_ */ CPU-X-4.2.0/src/cpu-x.h000066400000000000000000000332221403012130000143270ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE core.h */ #ifndef _CPUX_H_ #define _CPUX_H_ #include #include #include #include #include /* Software definition */ #define PRGNAME "CPU-X" #define PRGNAME_LOW "cpu-x" #define PRGAUTH "X0rg" #define PRGURL "https://"PRGAUTH".github.io/"PRGNAME #define PRGCPRGHT "Copyright © 2014-2021 Xorg" #define PRGLCNS "GNU GPL v3" #define LCNSURL "https://www.gnu.org/licenses/gpl.txt" /* Colors definition */ #define DEFAULT "\x1b[0m" #define BOLD_RED "\x1b[1;31m" #define BOLD_GREEN "\x1b[1;32m" #define BOLD_YELLOW "\x1b[1;33m" #define BOLD_BLUE "\x1b[1;34m" #define BOLD_MAGENTA "\x1b[1;35m" /* Utilities macro */ #define LOCATION PRGNAME, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__), __LINE__ #define GOTO_ERROR(str) { snprintf(error_str, MAXSTR, str); goto error; } #define ALLOC_CHECK(ptr) if(ptr == NULL) { MSG_ERRNO("%s", _("FATAL ERROR: could not allocate memory")); exit(255); } #define FREE(ptr) { free(ptr); ptr = NULL; } #define IS_ROOT (getuid() == 0) #define PRGINFO(out) fprintf(out, "%s %s%s (%s %s, %s %s, %s %s)\n", PRGNAME, PRGVER, GITREV, __DATE__, __TIME__, SYSTEM_NAME, SYSTEM_PROCESSOR, C_COMPILER_ID, __VERSION__) #define UNUSED(x) (void)(x) /* Formatted messages definition */ #define MSG_BUFF_LEN 128 #define MSG_STDOUT(fmt, ...) fprintf(stdout, colorized_msg(DEFAULT, "%s", fmt), ##__VA_ARGS__) #define MSG_STDERR(fmt, ...) fprintf(stderr, colorized_msg(DEFAULT, "%s", fmt), ##__VA_ARGS__) #define MSG_VERBOSE(fmt, ...) opts->verbose ? fprintf(stdout, colorized_msg(BOLD_GREEN, "%s", fmt), ##__VA_ARGS__) : 0 #define MSG_DEBUG(fmt, ...) opts->debug ? fprintf(stdout, colorized_msg(BOLD_MAGENTA, "%s", fmt), ##__VA_ARGS__) : 0 #define MSG_WARNING(fmt, ...) fprintf(stdout, colorized_msg(BOLD_YELLOW, "%s", fmt), ##__VA_ARGS__) #define MSG_ERROR(fmt, ...) fprintf(stderr, colorized_msg(BOLD_RED, "%s:%s:%i: %s", LOCATION, fmt), ##__VA_ARGS__) #define MSG_ERRNO(fmt, ...) fprintf(stderr, colorized_msg(BOLD_RED, "%s:%s:%i: %s (%s)", LOCATION, fmt, strerror(errno)), ##__VA_ARGS__) #if HAS_GETTEXT # define _(msg) gettext(msg) #else # define _(msg) msg #endif /* HAS_GETTEXT */ #define N_(msg) msg /* Options definition */ #define OUT_GTK (1 << 0) #define OUT_NCURSES (1 << 1) #define OUT_DUMP (1 << 2) #define OUT_NO_CPUX (1 << 10) #define OUT_DMIDECODE (1 << 11) #define OUT_BANDWIDTH (1 << 12) /* Arrays definition */ #define NAME 0 #define VALUE 1 #define MAXSTR 80 /* Max string */ #define CACHEFIELDS 2 /* Nb of fields by cache frame */ #define RAMFIELDS 2 /* Nb of fields by bank */ #define GPUFIELDS 13 /* Nb of fields by GPU frame */ #define BENCHFIELDS 2 /* Nb of fields by bench frame */ #define UNIT_B _("bytes") /* SI unit prefixes */ // TRANSLATORS: initials for kilobyte (10³): please put initials (keep it short) #define UNIT_KB _("kB") // TRANSLATORS: initials for megabyte (10⁶): please put initials (keep it short) #define UNIT_MB _("MB") // TRANSLATORS: initials for gigabyte (10⁹): please put initials (keep it short) #define UNIT_GB _("GB") // TRANSLATORS: initials for terabyte (10¹²): please put initials (keep it short) #define UNIT_TB _("TB") /* Binary unit prefixes */ // TRANSLATORS: initials for kibibyte (2¹⁰): please put initials (keep it short) #define UNIT_KIB _("KiB") // TRANSLATORS: initials for mebibyte (2²⁰): please put initials (keep it short) #define UNIT_MIB _("MiB") // TRANSLATORS: initials for gibibyte (2³⁰): please put initials (keep it short) #define UNIT_GIB _("GiB") // TRANSLATORS: initials for tebibyte (2⁴⁰): please put initials (keep it short) #define UNIT_TIB _("TiB") /* Linux-specific paths definition */ #define SYS_DMI "/sys/devices/virtual/dmi/id" #define SYS_CPU "/sys/devices/system/cpu/cpu" #define SYS_DRM "/sys/class/drm/card" #define SYS_HWMON "/sys/class/hwmon" #define SYS_DEBUG "/sys/kernel/debug" #define SYS_DEBUG_DRI SYS_DEBUG"/dri" /* FreeBSD-specific paths definition */ #define DEV_PCI "/dev/pci" enum EnTabNumber { NO_CPU, NO_CACHES, NO_MOTHERBOARD, NO_MEMORY, NO_SYSTEM, NO_GRAPHICS, NO_BENCH, NO_ABOUT }; enum EnObjects { TABCPU, TABCACHES, TABMOTHERBOARD, TABMEMORY, TABSYSTEM, TABGRAPHICS, TABBENCH, TABABOUT, FRAMPROCESSOR, FRAMCLOCKS, FRAMCACHE, FRAML1CACHE, FRAML2CACHE, FRAML3CACHE, FRAML4CACHE, FRAMTEST, FRAMMOTHERBOARD, FRAMBIOS, FRAMCHIPSET, FRAMBANK0, FRAMBANK1, FRAMBANK2, FRAMBANK3, FRAMBANK4, FRAMBANK5, FRAMBANK6, FRAMBANK7, FRAMOPERATINGSYSTEM, FRAMMEMORY, FRAMGPU1, FRAMGPU2, FRAMGPU3, FRAMGPU4, FRAMGPU5, FRAMGPU6, FRAMGPU7, FRAMGPU8, FRAMCARDS, FRAMPRIMESLOW, FRAMPRIMEFAST, FRAMPARAM, FRAMABOUT, FRAMLICENSE, LASTOBJ }; enum EnTabCpu { VENDOR, CODENAME, PACKAGE, TECHNOLOGY, VOLTAGE, SPECIFICATION, FAMILY, EXTFAMILY, MODEL, EXTMODEL, TEMPERATURE, STEPPING, INSTRUCTIONS, CORESPEED, MULTIPLIER, BUSSPEED, USAGE, LEVEL1D, LEVEL1I, LEVEL2, LEVEL3, SOCKETS, CORES, THREADS, LASTCPU }; enum EnTabCaches { L1SIZE, L1SPEED, L2SIZE, L2SPEED, L3SIZE, L3SPEED, L4SIZE, L4SPEED, LASTCACHES }; enum EnTabMotherboard { MANUFACTURER, MBMODEL, REVISION, BRAND, BIOSVERSION, DATE, ROMSIZE, CHIPVENDOR, CHIPMODEL, LASTMOTHERBOARD }; enum EnTabMemory { BANK0, BANK1, BANK2, BANK3, BANK4, BANK5, BANK6, BANK7, LASTMEMORY }; enum EnTabSystem { KERNEL, DISTRIBUTION, HOSTNAME, UPTIME, COMPILER, USED, BUFFERS, CACHED, FREE, SWAP, LASTSYSTEM }; enum EnTabSystemExtra { BARUSED, BARBUFFERS, BARCACHED, BARFREE, BARSWAP, LASTBAR }; enum EnTabGraphics { GPU1VENDOR, GPU1DRIVER, GPU1UMD, GPU1MODEL, GPU1DIDRID, GPU1PCIE, GPU1TEMPERATURE, GPU1USAGE, GPU1VOLTAGE, GPU1POWERAVG, GPU1CORECLOCK, GPU1MEMCLOCK, GPU1MEMUSED, GPU2VENDOR, GPU2DRIVER, GPU2UMD, GPU2MODEL, GPU2DIDRID, GPU2PCIE, GPU2TEMPERATURE, GPU2USAGE, GPU2VOLTAGE, GPU2POWERAVG, GPU2CORECLOCK, GPU2MEMCLOCK, GPU2MEMUSED, GPU3VENDOR, GPU3DRIVER, GPU3UMD, GPU3MODEL, GPU3DIDRID, GPU3PCIE, GPU3TEMPERATURE, GPU3USAGE, GPU3VOLTAGE, GPU3POWERAVG, GPU3CORECLOCK, GPU3MEMCLOCK, GPU3MEMUSED, GPU4VENDOR, GPU4DRIVER, GPU4UMD, GPU4MODEL, GPU4DIDRID, GPU4PCIE, GPU4TEMPERATURE, GPU4USAGE, GPU4VOLTAGE, GPU4POWERAVG, GPU4CORECLOCK, GPU4MEMCLOCK, GPU4MEMUSED, GPU5VENDOR, GPU5DRIVER, GPU5UMD, GPU5MODEL, GPU5DIDRID, GPU5PCIE, GPU5TEMPERATURE, GPU5USAGE, GPU5VOLTAGE, GPU5POWERAVG, GPU5CORECLOCK, GPU5MEMCLOCK, GPU5MEMUSED, GPU6VENDOR, GPU6DRIVER, GPU6UMD, GPU6MODEL, GPU6DIDRID, GPU6PCIE, GPU6TEMPERATURE, GPU6USAGE, GPU6VOLTAGE, GPU6POWERAVG, GPU6CORECLOCK, GPU6MEMCLOCK, GPU6MEMUSED, GPU7VENDOR, GPU7DRIVER, GPU7UMD, GPU7MODEL, GPU7DIDRID, GPU7PCIE, GPU7TEMPERATURE, GPU7USAGE, GPU7VOLTAGE, GPU7POWERAVG, GPU7CORECLOCK, GPU7MEMCLOCK, GPU7MEMUSED, GPU8VENDOR, GPU8DRIVER, GPU8UMD, GPU8MODEL, GPU8DIDRID, GPU8PCIE, GPU8TEMPERATURE, GPU8USAGE, GPU8VOLTAGE, GPU8POWERAVG, GPU8CORECLOCK, GPU8MEMCLOCK, GPU8MEMUSED, LASTGRAPHICS }; enum EnGpuDrv { GPUDRV_FGLRX, GPUDRV_AMDGPU, GPUDRV_RADEON, // AMD GPUDRV_INTEL, // Intel GPUDRV_NVIDIA, GPUDRV_NVIDIA_BUMBLEBEE, GPUDRV_NOUVEAU, GPUDRV_NOUVEAU_BUMBLEBEE, // NVIDIA GPUDRV_VFIO, GPUDRV_UNKNOWN }; enum EnTabBench { PRIMESLOWSCORE, PRIMESLOWRUN, PRIMEFASTSCORE, PRIMEFASTRUN, PARAMDURATION, PARAMTHREADS, LASTBENCH }; enum EnTabAbout { DESCRIPTION, VERSIONSTR, AUTHOR, SITE, COPYRIGHT, LICENSE, NOWARRANTY, LASTABOUT }; enum EnOptKeymap { ARROWS, EMACS, INVERTED_T, VIM, LASTKEYMAP }; enum EnMultipliers { MULT_NONE, MULT_K, MULT_M, MULT_G, MULT_T }; typedef struct { int8_t cpu_vendor_id; int32_t cpu_model, cpu_ext_model, cpu_ext_family; char *cpuid_raw_file; } LibcpuidData; typedef struct { uint8_t test_count; uint32_t size[LASTCACHES / CACHEFIELDS]; uint32_t speed[LASTCACHES / CACHEFIELDS]; char **test_name; } BandwidthData; typedef struct { long double mem_usage[SWAP - USED + 1]; long double mem_total; long double swap_total; } MemoryData; typedef struct { enum EnGpuDrv gpu_driver[LASTGRAPHICS / GPUFIELDS]; char *device_path[LASTGRAPHICS / GPUFIELDS]; } GraphicsData; typedef struct { bool run, fast_mode; unsigned duration, threads; uint32_t primes, start, elapsed; uint64_t num; pthread_t first_thread; pthread_mutex_t mutex_num, mutex_primes; } BenchData; typedef struct { char *objects[LASTOBJ]; char *tab_cpu[2][LASTCPU]; char *tab_caches[2][LASTCACHES]; char *tab_motherboard[2][LASTMOTHERBOARD]; char *tab_memory[2][LASTMEMORY]; char *tab_system[2][LASTSYSTEM]; char *tab_graphics[2][LASTGRAPHICS]; char *tab_bench[2][LASTBENCH]; char *tab_about[LASTABOUT]; int cpu_freq, socket_fd; uint8_t cpu_count, cache_count, dimm_count, gpu_count; double bus_freq, cpu_min_mult, cpu_max_mult; bool reload; LibcpuidData *l_data; BandwidthData *w_data; MemoryData *m_data; GraphicsData *g_data; BenchData *b_data; } Labels; typedef struct { bool cpuid_decimal, color, verbose, debug, issue, with_daemon, debug_database, freq_fallback; uint8_t selected_page, selected_core, bw_test, selected_gpu; uint16_t output_type, refr_time; enum EnOptKeymap keymap; } Options; typedef struct { char **dim_names; char **dim_values; int last; } Arrays; typedef struct { bool init; char *prefix; uint64_t divisor; } PrefixUnit; extern Options *opts; /***************************** Defined in main.c *****************************/ /* Free memory after display labels */ void labels_free(Labels *data); /***************************** Defined in util.c *****************************/ /* An asprintf-like function, but which can clean some parts of 'str' if 'clean_str' is true * - It calls vasprintf if 'fmt' is a valid string * - If 'clean_str' is true, it removes "unvalid args" from 'str' until next "valid arg" E.g.: casprintf(&str, false, "%i nm", 0): str = "0 nm" casprintf(&str, true, "%i nm", 0): str = "" casprintf(&str, true, "%i nm", 32): str = "32 nm" casprintf(&str, true, "%i KB %i-way", -1, 12): str = "12-way" */ int casprintf(char **str, bool clean_str, const char *fmt, ...); /* Return a formatted string */ char *format(char *str, ...); /* Divide a number (in bytes) with the appropriate prefix */ void find_best_prefix(uint64_t value, enum EnMultipliers multiplier, bool use_si_prefixes, PrefixUnit *pu); /* Duplicate a string and set unit */ char *strdup_and_set_unit(char *str); /* Check is string is empty (e.g. contains only non printable characters) */ bool string_is_empty(char *str); /* Similar to format(), but string can be colorized */ char *colorized_msg(const char *color, const char *str, ...); /* Open a file and put its content in a variable ('str' accept printf-like format) */ int fopen_to_str(char **buffer, char *str, ...); /* Run a command and put output in a variable ('str' accept printf-like format) */ int popen_to_str(char **buffer, char *str, ...); /* Check if a command exists */ bool command_exists(char *cmd); /* Load a kernel module (return 0 on success) */ int load_module(char *module, int *fd); /* Get a filename located in a directory corresponding to given request */ enum RequestSensor { RQT_CPU_TEMPERATURE, RQT_CPU_TEMPERATURE_OTHERS, RQT_CPU_VOLTAGE, RQT_GPU_TEMPERATURE, RQT_GPU_DRM, RQT_GPU_HWMON }; int request_sensor_path(char *base_dir, char **cached_path, enum RequestSensor which); /* Start daemon in background */ const char *start_daemon(bool graphical); /* Check if daemon is running */ bool daemon_is_alive(void); /***************************** External headers *****************************/ /* Fill labels by calling core functions */ int fill_labels(Labels *data); /* Refresh some labels */ int do_refresh(Labels *data); /* Establish connection to daemon */ int connect_to_daemon(Labels *data); /* Dmidecode main function */ int dmidecode(int quiet, void *cpux_pdata); /* Call Dmidecode through CPU-X but do nothing else */ int run_dmidecode(void); /* Call Bandwidth through CPU-X but do nothing else */ int run_bandwidth(void); /* Perform a multithreaded benchmark (compute prime numbers) */ void start_benchmarks(Labels *data); /* Load and apply settings from GSettings */ void load_settings(void); /* Start CPU-X in GTK mode */ void start_gui_gtk(int *argc, char **argv[], Labels *data); /* Start CPU-X in NCurses mode */ void start_tui_ncurses(Labels *data); #endif /* _CPUX_H_ */ CPU-X-4.2.0/src/daemon.c000066400000000000000000000223441403012130000145340ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE daemon.c */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "cpu-x.h" #include "daemon.h" #include "ipc.h" #ifdef __linux__ # include #endif #if HAS_LIBCPUID # include #endif static bool quit_loop = false; static ThreadsInfo *ti = &(ThreadsInfo) { .count = 0, .allocated = 1, .thread = NULL, }; char *colorized_msg(const char *__color, const char *str, ...) { UNUSED(__color); char fmt[MSG_BUFF_LEN]; static char buff[MSG_BUFF_LEN]; va_list aptr; va_start(aptr, str); snprintf(fmt, MSG_BUFF_LEN, "%s\n", str); vsnprintf(buff, MSG_BUFF_LEN, fmt, aptr); va_end(aptr); return buff; } #if HAS_LIBCPUID static void libcpuid_msr_serialize(void) { struct msr_driver_t *msr = cpu_msr_driver_open_core(0); if(msr != NULL) { MSG_STDOUT("libcpuid version %s", cpuid_lib_version()); msr_serialize_raw_data(msr, NULL); cpu_msr_driver_close(msr); } } /* Try to open a CPU MSR */ static int libcpuid_init_msr(int fd, struct msr_driver_t **msr) { unsigned selected_core = 0; read(fd, &selected_core, sizeof(uint8_t)); // Core 0 on failure if((*msr = cpu_msr_driver_open_core(selected_core)) == NULL) { MSG_ERROR("cpu_msr_driver_open_core(%u) (%s)", selected_core, cpuid_error()); return 2; } return 0; } static int __call_libcpuid_msr_static(int *fd) { struct msr_driver_t *msr = NULL; MsrStaticData msg = { CPU_INVALID_VALUE, CPU_INVALID_VALUE, CPU_INVALID_VALUE }; if(!libcpuid_init_msr(*fd, &msr)) { msg.min_mult = cpu_msrinfo(msr, INFO_MIN_MULTIPLIER); msg.max_mult = cpu_msrinfo(msr, INFO_MAX_MULTIPLIER); msg.bclk = cpu_msrinfo(msr, INFO_BCLK); cpu_msr_driver_close(msr); } SEND_DATA(fd, &msg, sizeof(MsrStaticData)); return 0; } static int __call_libcpuid_msr_dynamic(int *fd) { struct msr_driver_t *msr = NULL; MsrDynamicData msg = { CPU_INVALID_VALUE, CPU_INVALID_VALUE }; if(!libcpuid_init_msr(*fd, &msr)) { msg.voltage = cpu_msrinfo(msr, INFO_VOLTAGE); msg.temp = cpu_msrinfo(msr, INFO_TEMPERATURE); cpu_msr_driver_close(msr); } SEND_DATA(fd, &msg, sizeof(MsrDynamicData)); return 0; } #endif /* HAS_LIBCPUID */ #if HAS_DMIDECODE static int __call_dmidecode(int *fd) { DmidecodeData msg = { .ret = -1, .dimm_count = 0, .bus_freq = 0.0 }; msg.ret = dmidecode(1, &msg); SEND_DATA(fd, &msg, sizeof(DmidecodeData)); return msg.ret; } #endif /* HAS_DMIDECODE */ #if HAS_LIBPCI static int __find_devices(int *fd) { int ret = -1; #ifdef __FreeBSD__ ret = chmod(DEV_PCI, DEFFILEMODE); // 0666 #endif /* __FreeBSD__ */ SEND_DATA(fd, &ret, sizeof(int)); return ret; } #endif /* HAS_LIBPCI */ static int __can_access_sys_debug_dri(int *fd) { int ret = -1; #ifdef __linux__ if(access(SYS_DEBUG_DRI, R_OK)) { mkdir(SYS_DEBUG, S_IRWXU|S_IXGRP|S_IXOTH); mount("none", SYS_DEBUG, "debugfs", MS_NOSUID|MS_NODEV|MS_NOEXEC, ""); } ret = chmod(SYS_DEBUG, S_IRWXU|S_IXGRP|S_IXOTH); // 0711 #endif /* __linux__ */ SEND_DATA(fd, &ret, sizeof(int)); return ret; } /* Load a kernel module */ static int __load_module(int *fd) { int ret = -1; ssize_t len; char *module = NULL, *load_cmd = NULL; RECEIVE_DATA(fd, &len, sizeof(ssize_t)); if((module = malloc(len)) == NULL) { MSG_ERRNO("%s", "malloc"); close(*fd); *fd = -1; return 1; } RECEIVE_DATA(fd, module, len); #if defined (__linux__) asprintf(&load_cmd, "modprobe %s 2> /dev/null", module); #elif defined (__DragonFly__) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) asprintf(&load_cmd, "kldload -n %s 2> /dev/null", module); #else # error "Unsupported operating system" #endif ret = system(load_cmd); free(module); free(load_cmd); SEND_DATA(fd, &ret, sizeof(int)); return 0; } static void cleanup_thread(void *p_data) { Thread *td = (Thread*) p_data; pthread_mutex_lock(&ti->mutex); ti->count--; close(td->fd); td->fd = -1; pthread_mutex_unlock(&ti->mutex); } static void *request_handler(void *p_data) { DaemonCommand cmd; Thread *td = (Thread*) p_data; pthread_cleanup_push(cleanup_thread, p_data); while(42) { if(read(td->fd, &cmd, sizeof(DaemonCommand)) != sizeof(DaemonCommand)) break; switch(cmd) { #if HAS_LIBCPUID case LIBCPUID_MSR_STATIC: __call_libcpuid_msr_static(&td->fd); break; case LIBCPUID_MSR_DYNAMIC: __call_libcpuid_msr_dynamic(&td->fd); break; #endif /* HAS_LIBCPUID */ #if HAS_DMIDECODE case DMIDECODE: __call_dmidecode(&td->fd); break; #endif /* HAS_DMIDECODE */ #if HAS_LIBPCI case ACCESS_DEV_PCI: __find_devices(&td->fd); break; #endif /* HAS_LIBPCI */ case ACCESS_SYS_DEBUG: __can_access_sys_debug_dri(&td->fd); break; case LOAD_MODULE: __load_module(&td->fd); break; default: MSG_WARNING(_("request_handler: case %i not handled"), cmd); } } pthread_cleanup_pop(1); return NULL; } static void create_thread(int fd) { uint8_t i, j; Thread *tmp; /* Search available index */ if(pthread_mutex_lock(&ti->mutex) < 0) { MSG_ERRNO("%s", "pthread_mutex_lock"); close(fd); } for(i = 0; i < ti->allocated; i++) if(ti->thread[i].fd < 0) goto found; /* Extend array if no available index */ if((tmp = realloc(ti->thread, (ti->allocated * 2) * sizeof(Thread))) == NULL) { MSG_ERRNO("%s", "realloc"); close(fd); pthread_mutex_unlock(&ti->mutex); return; } ti->allocated *= 2; ti->thread = tmp; for(j = i; j < ti->allocated; j++) ti->thread[j].fd = -1; found: /* Add file descriptor in array */ ti->count++; ti->thread[i].fd = fd; pthread_mutex_unlock(&ti->mutex); /* Start a new thread */ pthread_create(&ti->thread[i].id, NULL, request_handler, &ti->thread[i]); pthread_detach(ti->thread[i].id); } static void sighandler(int __signum) { UNUSED(__signum); quit_loop = true; } int main(void) { int listen_socket, data_socket, ret, err = EXIT_SUCCESS; uint8_t i; pid_t pid; char error_str[MAXSTR] = "unknown"; struct sockaddr_un name; struct pollfd fds[NFDS]; /* Pre-initialization */ umask(0); unlink(SOCKET_NAME); signal(SIGINT, sighandler); signal(SIGTERM, sighandler); /* Logs */ unlink(LOG_FILE); freopen(LOG_FILE, "a", stdout); setvbuf(stdout, NULL, _IONBF, 0); dup2(STDOUT_FILENO, STDERR_FILENO); PRGINFO(stdout); #if HAS_LIBCPUID if(getenv("CPUX_DAEMON_DEBUG")) libcpuid_msr_serialize(); #endif /* HAS_LIBCPUID */ /* Initialize mutex */ if(pthread_mutex_init(&ti->mutex, NULL) < 0) { MSG_ERRNO("%s", "pthread_mutex_init"); return EXIT_FAILURE; } /* Initialize threads array */ if((ti->thread = malloc(ti->allocated * sizeof(Thread))) == NULL) { MSG_ERRNO("%s", "malloc"); pthread_mutex_destroy(&ti->mutex); return EXIT_FAILURE; } for(i = 0; i < ti->allocated; i++) ti->thread[i].fd = -1; /* Create local socket. */ if((listen_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0)) < 0) GOTO_ERROR("socket"); /* Bind socket to socket name. */ memset(&name, 0, sizeof(struct sockaddr_un)); name.sun_family = AF_UNIX; strncpy(name.sun_path, SOCKET_NAME, sizeof(name.sun_path) - 1); if(bind(listen_socket, (const struct sockaddr*) &name, sizeof(struct sockaddr_un)) < 0) GOTO_ERROR("bind"); /* Prepare for accepting connections. */ if(listen(listen_socket, SOMAXCONN) < 0) GOTO_ERROR("listen"); /* Initialize pollfd */ memset(fds, 0 , sizeof(fds)); fds[0].fd = listen_socket; fds[0].events = POLLIN; /* Fork daemon in background */ pid = fork(); if(pid > 0) return 0; else if(pid < 0) GOTO_ERROR("fork"); /* This is the main loop for handling connections */ while(!quit_loop) { /* Wait for incoming connection */ ret = poll(fds, NFDS, POLL_TIMEOUT); if(ret < 0) MSG_ERRNO("%s", "poll"); else if(ret == 0) // Timeout quit_loop = ti->count == 0; else if(fds[0].revents & POLLIN) { if((data_socket = accept(listen_socket, NULL, NULL)) < 0) MSG_ERRNO("%s", "accept"); else create_thread(data_socket); } } goto clean; error: MSG_ERRNO("%s", error_str); err = EXIT_FAILURE; clean: for(i = 0; i < ti->count; i++) pthread_join(ti->thread[i].id, NULL); fclose(stdout); unlink(SOCKET_NAME); close(listen_socket); free(ti->thread); pthread_mutex_destroy(&ti->mutex); if(getenv("APPDIR") != NULL) remove("/tmp/"DAEMON_EXEC); return err; } CPU-X-4.2.0/src/daemon.h000066400000000000000000000023321403012130000145340ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE daemon.h */ #ifndef _DAEMON_H_ #define _DAEMON_H_ #define POLL_TIMEOUT (5 * 1000) // 5 seconds #define NFDS 1 #define LOG_FILE "/tmp/cpu-x-daemon.log" typedef struct { pthread_t id; int fd; } Thread; typedef struct { pthread_mutex_t mutex; uint8_t count; uint8_t allocated; Thread *thread; } ThreadsInfo; #endif /* _DAEMON_H_ */ CPU-X-4.2.0/src/databases.h000066400000000000000000000266661403012130000152400ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE databases.h */ #ifndef _DATABASES_H_ #define _DATABASES_H_ /****************************** CPU Technology ******************************/ typedef struct { const int32_t cpu_model; const int32_t cpu_ext_model; const int32_t cpu_ext_family; const int process; } Technology_DB; const Technology_DB technology_unknown[] = { { -1, -1, -1, -1 } }; const Technology_DB technology_intel[] = { //Model E. Model E. Family Process { 0, 0, -1, 180 }, // P4 Willamette { 1, 1, 6, 350 }, // Pentium Pro { 1, 1, 15, 180 }, // P4 Willamette { 2, 2, -1, 130 }, // P4 Northwood / Gallatin { 3, 3, 5, 350 }, // PII Overdrive { 3, 3, 6, 350 }, // PII Klamath { 3, 3, 15, 90 }, // P4 Prescott { 4, 4, -1, 90 }, // P4 Prescott/Irwindale / PD Smithfield { 5, 5, 6, 250 }, // PII Deschutes / Tonga / Xeon Drake / Celeron Covington { 5, 37, -1, 32 }, // Westmere { 5, 53, -1, 32 }, // Atom Cloverview { 5, 69, -1, 22 }, // Haswell { 5, 85, -1, 14 }, // Skylake (Xeon Scalable) { 6, 6, 6, 250 }, // PII Dixon / Celeron Mendocino { 6, 6, 15, 65 }, // P4 Cedar Mill / PD Presler { 6, 22, -1, 65 }, // C2 Conroe-L { 6, 54, -1, 32 }, // Atom Cedarview { 6, 70, -1, 22 }, // Haswell (Crystalwell, L4 cache) { 6, 102, -1, 10 }, // Cannon Lake { 7, 7, -1, 250 }, // PIII Katmai { 7, 23, -1, 45 }, // C2 Wolfdale / Yorkfield / Penryn { 7, 55, -1, 22 }, // Atom Bay Trail { 7, 71, -1, 14 }, // Broadwell { 7, 167, -1, 14 }, // Rocket Lake { 8, 0, 0, 180 }, // PIII Coppermine-T { 8, 8, -1, 180 }, // PIII Coppermine { 9, 9, -1, 130 }, // Pentium M Banias { 10, 26, -1, 45 }, // Nehalem { 10, 30, -1, 45 }, // Nehalem { 10, 42, -1, 32 }, // Sandy Bridge { 10, 58, -1, 22 }, // Ivy Bridge { 10, 122, -1, 14 }, // Gemini Lake { 11, 11, -1, 130 }, // PIII Tualatine { 12, 28, -1, 45 }, // Atom Diamondville / Pineview / Silverthorne { 12, 44, -1, 32 }, // Westmere { 12, 60, -1, 22 }, // Haswell { 12, 76, -1, 14 }, // Atom Cherry Trail { 13, 13, -1, 90 }, // Pentium M Dothan { 13, 45, -1, 32 }, // Sandy Bridge-E { 13, 61, -1, 14 }, // Broadwell-U { 14, 14, -1, 65 }, // Yonah (Core Solo) { 14, 30, -1, 45 }, // Nehalem (Lynnfield) { 14, 62, -1, 22 }, // Ivy Bridge-E { 14, 78, -1, 14 }, // Skylake { 14, 94, -1, 14 }, // Skylake { 14, 126, -1, 10 }, // Ice Lake { 14, 142, -1, 14 }, // Kaby Lake / Coffee Lake / Comet Lake-U { 14, 158, -1, 14 }, // Kaby Lake / Coffee Lake { 14, 165, -1, 14 }, // Comet Lake { 15, 15, -1, 65 }, // C2 Conroe / Allendale / Kentsfield / Merom { 15, 63, -1, 22 }, // Haswell-E { 15, 79, -1, 14 }, // Broadwell-E { -2, -2, -2, -2 } //Model E. Model E. Family Process }; const Technology_DB technology_amd[] = { //Model E. Model E. Family Process { 0, 16, 21, 32 }, // Bulldozer (Piledriver: Trinity) { 0, 48, 21, 28 }, // Bulldozer (Steamroller: Kaveri) { 0, 112, 21, 28 }, // Bulldozer (Excavator: Stoney Ridge) { 0, -1, 22, 28 }, // Jaguar (Kabini/Mullins) { 1, -1, 18, 32 }, // K10 (Llano) { 1, -1, 20, 40 }, // Bobcat (Brazos Zacate) { 1, 1, 21, 32 }, // Bulldozer { 1, 96, 21, 28 }, // Bulldozer (Excavator: Carrizo) { 2, -1, 16, 65 }, // K10 (Kuma/Agena) { 2, -1, 20, 40 }, // Bobcat (Brazos Desna/Ontario) { 2, -1, 21, 32 }, // Bulldozer (Piledriver: Vishera) { 3, -1, 15, 90 }, // K8 (Toledo) { 3, -1, 21, 32 }, // Bulldozer (Piledriver: Richland) { 4, -1, 15, 90 }, // K8 (Lancaster) { 4, -1, 16, 45 }, // K10 (Deneb/Heka) { 5, -1, 16, 45 }, // K10 (Propus) { 5, -1, 21, 28 }, // Bulldozer (Excavator: Bristol Ridge) { 6, -1, 16, 45 }, // K10 (Champlain/Sargas/Regor) { 8, -1, 6, 130 }, // K7 (Thoroughbred/Applebred) { 8, -1, 15, 65 }, // K8 (Tyler) { 8, -1, 21, 28 }, // Bulldozer (Steamroller: Godavari) { 9, -1, 16, 45 }, // Magny-Cours (Opteron) { 10, -1, 6, 130 }, // K7 (Barton) { 10, -1, 16, 45 }, // K10 (Thuban) { 11, -1, 15, 65 }, // K8 (Brisbane) { 12, -1, 15, 90 }, // K8 (Venice/Sonora) { 15, 79, 15, 90 }, // K8 (Manila) { 15, 127, 15, 65 }, // K8 (Sparta) { -1, 1, 23, 14 }, // Zen (Summit Ridge/Whitehaven/Naples) { -1, 17, 23, 14 }, // Zen (Raven Ridge) { -1, 8, 23, 12 }, // Zen+ (Pinnacle Ridge/Colfax) { -1, 24, 23, 12 }, // Zen+ (Picasso) { -1, 49, 23, 7 }, // Zen 2 (Rome/Castle Peak) { -1, 96, 23, 7 }, // Zen 2 (Renoir) { -1, 113, 23, 7 }, // Zen 2 (Matisse) { -1, 33, 25, 7 }, // Zen 3 (Vermeer) { -1, 80, 25, 7 }, // Zen 3 (Cezanne) { -1, 1, 25, 7 }, // Zen 3 (Milan) { -2, -2, -2, -2 } //Model E. Model E. Family Process }; /****************************** CPU Package ******************************/ typedef struct { const char *codename; const char *model; const char *socket; } Package_DB; const Package_DB package_unknown[] = { { NULL, NULL, NULL } }; const Package_DB package_intel[] = { //Codename Model Socket { "Atom (Diamondville)", NULL, "BGA 437" }, { "Pentium D (SmithField)", NULL, "LGA 775" }, { "Pentium D (Presler)", NULL, "LGA 775" }, { "Bloomfield", NULL, "LGA 1366" }, { NULL, "Intel(R) Core(TM) i5-2520M CPU", "rPGA 988B" }, { NULL, "Intel(R) Xeon(R) CPU E31275", "LGA 1155" }, { NULL, "Intel(R) Core(TM) i7-2860QM CPU", "rPGA 988B" }, { NULL, "Intel(R) Core(TM) i7-3740QM CPU", "rPGA 988B" }, { NULL, "Intel(R) Core(TM) i5-4300U CPU", "BGA 1168" }, { NULL, "Intel(R) Core(TM) i7-5775C CPU", "LGA 1150" }, { NULL, "Intel(R) Core(TM) i7-6560U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i7-7300U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i7-8250U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i7-8350U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i7-8550U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i7-8650U CPU", "FCBGA 1356" }, { NULL, "Intel(R) Core(TM) i9-9900K CPU", "LGA 1151" }, { NULL, NULL, NULL } //Codename Model Socket }; const Package_DB package_amd[] = { //Codename Model Socket { "Athlon 64 FX X2 (Toledo)", NULL, "939 (PGA-ZIF)" }, { "Kabini X4", "Athlon", "AM1 (PGA-ZIF)" }, { "Kabini X4", "Sempron", "AM1 (PGA-ZIF)" }, { "Trinity X4", NULL, "FM2 (PGA-ZIF)" }, { "Turion X2", "TL", "S1g1 (PGA-ZIF)" }, { "Turion X2", "TK", "S1g1 (PGA-ZIF)" }, { "Deneb", "AMD Phenom(tm) II X4 945", "AM3 (PGA-938" }, { "Zambezi", NULL, "AM3+ (PGA-942)" }, { "Vishera", NULL, "AM3+ (PGA-942)" }, /* Zen */ { "Summit Ridge", NULL, "AM4 (PGA-1331)" }, { "Whitehaven", NULL, "SP3r2 (LGA-4094)" }, { "Naples", NULL, "SP3 (LGA-4094)" }, /* Zen+ */ { "Picasso", NULL, "FP5 (BGA)" }, { "Pinnacle Ridge", NULL, "AM4 (PGA-1331)" }, { "Colfax", NULL, "SP3r2 (LGA-4094)" }, /* Zen 2 */ { "Matisse", NULL, "AM4 (PGA-1331)" }, { "Castle Peak", NULL, "SP3r2 (LGA-4094)" }, { "Rome", NULL, "SP3 (LGA-4094)" }, { NULL, NULL, NULL } //Codename Model Socket }; #endif /* _DATABASES_H_ */ CPU-X-4.2.0/src/dmidecode/000077500000000000000000000000001403012130000150355ustar00rootroot00000000000000CPU-X-4.2.0/src/dmidecode/.hash000066400000000000000000000000511403012130000157550ustar00rootroot000000000000003c111e4f6134855580f20f8e01fee26eff455fff CPU-X-4.2.0/src/dmidecode/AUTHORS000066400000000000000000000032651403012130000161130ustar00rootroot00000000000000DEVELOPER AND MAINTAINER Jean Delvare ORIGINAL AUTHORS Alan Cox Jean Delvare CODE CONTRIBUTORS (IN CHRONOLOGICAL ORDER) Matt Domsch Arjan van de Ven Mark D. Studebaker Larry Lile Dave Johnson Petter Reinholdtsen Roberto Nibali John Cagle Jens Elkner Jarod Wilson Anton Arapov Roy Franz Tyler Bell Xie XiuQi Petr Oros MANY THANKS TO (IN CHRONOLOGICAL ORDER) Werner Heuser Alexandre Duret-Lutz Xavier Roche Pamela Huntley Gael Stephan Sebastian Henschel Richard Sharpe David Wilson Glen Foster Chad Smith Joshua Goldenhar Luc Van de Velde Mario Lang Hugues Lepesant Sergey Leonovich Mike Cooper Marc Rieffel Jeff Moyer Josef Moellers Zing Zing Shishak Rafael Avila de Espindola Roger Koot Martin Pool Doug Brenner Alex Williamson Durval Menezes Raphael Raimbault Raul Nunez de Arenas Coronado Francois Revol Dominik Klein Erwan Velu Don Howard Frans Pop Tomek Mateja Myke Olson Torsten Seemann Garry Belka Klaus Muth Antoine Fuselier Matthew Garrett Landry Breuil Luke Suchocki Attila Nagy Alex Iribarren Sebastien Douche William Lallemand Olivier Guerrier Pascal Terjan Stuart Hayes Sofian Brabez Vincent Pelletier Andreas Gruenbacher Lin Li Thomas Hiller Paul Flo Williams Olof Johansson Alexandre Lissy Michal Svec Vojtech Pavlik Murlin Wenzel Harald Mueller-Ney Lars Mueller Thomas Mingarelli Andrey Matveyev Stefan Tauner Naga Chumbalkar Jens Rosenboom CPU-X-4.2.0/src/dmidecode/CMakeLists.txt000066400000000000000000000010751403012130000176000ustar00rootroot00000000000000project(dmidecode VERSION "3.3.20201210" LANGUAGES C ) # Config (dmidecode) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wno-shift-count-overflow") message(STATUS "Using built-in ${PROJECT_NAME}, version ${PROJECT_VERSION}") # Build (dmidecode) add_definitions(-DVERSION="${PROJECT_VERSION}") add_library(dmidecode STATIC types.h util.c util.h dmiopt.h dmioem.c dmioem.h dmidecode.c dmidecode.h dmioutput.c dmioutput.h ) target_link_libraries(dmidecode) set(DMIDECODE_VERSION ${PROJECT_VERSION} PARENT_SCOPE) CPU-X-4.2.0/src/dmidecode/LICENSE000066400000000000000000000432541403012130000160520ustar00rootroot00000000000000 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. CPU-X-4.2.0/src/dmidecode/NEWS000066400000000000000000000157171403012130000155470ustar00rootroot00000000000000Version 3.3 (Wed Oct 14 2020) - [BUILD] Allow overriding build settings from the environment. - [COMPATIBILITY] Document how the UUID fields are interpreted. - [PORTABILITY] Don't use memcpy on /dev/mem on arm64. - [PORTABILITY] Only scan /dev/mem for entry point on x86. - Support for SMBIOS 3.3.0. This includes new processor names, new port connector types, and new memory device form factors, types and technologies. - Add bios-revision, firmware-revision and system-sku-number to -s option. - Use the most appropriate unit for cache size. - Decode system slot base bus width and peers. - Important bug fixes: Fix Redfish Hostname print length Fix formatting of TPM table output Fix System Slot Information for PCIe SSD Don't choke on invalid processor voltage - Use the most appropriate unit for cache size. Version 3.2 (Wed Sep 14 2018) - [COMPATIBILITY] The UUID is now displayed using lowercase letters, per RFC 4122 (#53569). You must ensure that any code parsing it is case-insensitive. - Support for SMBIOS 3.2.0. This includes new processor names, new socket and port connector types, new system slot state and property, and support for non-volatile memory (NVDIMM). - Support for Redfish management controllers. - A new command line option to query a specific structure by its handle. - A new command line option to query the system family string. - Support for 3 ThinkPad-specific structures (patch #9642). - Support for HPE's new company name. - Support UEFI on FreeBSD. - Important bug fixes: Fix firmware version of TPM device Fix the HPE UEFI feature flag check - (biosdecode) A new command line option to fully decode PIR information (support request #109339). Version 3.1 (Tue May 23 2017) - Support for SMBIOS 3.1.0 and 3.1.1. This includes new chassis types, new processor family names, new processor family upgrade names, and new slot types, as well as support of larger BIOS ROM sizes and cache sizes, and a new structure type (43, TPM Device.) - A new command line option to query OEM strings. - All error messages are now printed on stderr (#47274, #48158.) - Several bug fixes related to 64-bit entry points (#50037 and more.) - Important bug fixes: #46176 (Unexpected end of file error) #46066 (Crash with SIGBUS) - Various minor fixes, improvements and cleanups. Version 3.0 (Thu Sep 03 2015) - Support for SMBIOS 3.0. This includes new chassis types, new processor family names, new processor family upgrade names, new slot types, and new memory device types. - Support for the new 64-bit entry point (_SM3_) defined in SMBIOS 3.0. - Support for the new kernel interface (as of Linux v4.2) as an alternative to relying /dev/mem to access the entry point and DMI table. - Decoding of Acer-specific DMI type 170. - Decoding of HP-specific DMI types 212, 219 and 233. - Various minor fixes and output format cleanups. Version 2.12 (Wed Apr 17 2013) - Support of the SMBIOS 2.8.0 specification. Version 2.11 (Wed Jan 19 2011) - Support of the SMBIOS 2.7.0 specification: - UEFI support - Virtual machine flags in BIOS characteristics - Limited support for the Management Controller Host Interface - Various fixes that address stability. Version 2.10 (Sun Nov 23 2008) - Support for Solaris (x86 only, of course). - Possibility to dump the SMBIOS/DMI table to a small binary file (option --dump-bin). - Possibility to read the SMBIOS/DMI table from such binary files (option --from-dump). - Support for SMBIOS 2.6. This includes new chassis types, new processor family names, new processor family upgrade names, bus address for system slots, and a new entry type for on-board devices, amongst many other minor changes. - Support for DMI entry type 31 (Boot integrity services). - Many processor family names taken from the CIM Schema document. - (vpddecode) No longer ask users to report broken records. - (vpddecode) Fix --quiet option. Version 2.9 (Mon Feb 26 2007) - Support of the SMBIOS 2.5 specification. It adds many enumerated values for recent hardware, as well as CPU core and thread count reporting. - Decoding of 3 HP-specific entries. More vendor-specific entries can be supported later if vendors contribute code or documentation. - Run-time detection of EFI, so that a single binary can support Intel-based Macintosh machines and regular x86 machines. - Better IA-64 support. - Fixes to the decoding of individual fields, including the CPU signature of recent CPU models. - (biosdecode) Support of the FJKEYINF entry point type (for Fujitsu laptops). - (vpddecode) The product name look-up table was dropped. It was unreliable and a burden to maintain. - biosdecode, ownership and vpddecode are no longer built on IA-64. Version 2.8 (Sat Feb 04 2006) - Option --string has four additional keywords available: system-uuid, chassis-type, processor-family and processor-frequency. These needed additional work because, technically speaking, they are not DMI strings. - IPMI interface type SSIF was added. This is a new interface type defined by IPMI 2.0. - (vpddecode) New --string option, much similar in spirit to dmidecode's. Available keywords are bios-build-id, box-serial-number, motherboard-serial-number, machine-type-model and bios-release-date. - (vpddecode) 9 product names were added to the lookup table. - A few bug fixes, cleanups and minor improvements all around the place. Version 2.7 (Thu Aug 04 2005) - New command line interface. For example, it is now possible to limit the output of dmidecode to a given DMI type, or to extract a single string from the DMI table. The documentation has been updated accordingly. - The default output of dmidecode was slightly modified to be more easily readable by humans. This might break tools parsing its output. Such tools may benefit from the new command line interface, although this interface shouldn't be considered stable until version 2.8. - (vpddecode) New command line interface. - (vpddecode) 6 product names were added. Version 2.6 (Mon Feb 28 2005) - Fixes a 2 GB memory limit regression. - Basic command-line handling. - BeOS and Cygwin support. Version 2.5 (Thu Nov 11 2004) - Code cleanups. - Compatibility fixes. - Documentation updates. Version 2.4 (Fri Mar 19 2004) - Manual pages added. - (vpddecode) Many improvements. - A few fixes and minor improvements. Version 2.3 (Sun Oct 19 2003) - Support of x86_64 systems. - Support of systems with 2 GB and more memory. - Loads of bug fixes and corrections. - New tool "vpddecode" added. Version 2.2 (Fri Aug 08 2003) - Support of IA-64 systems. - Support of IBM and Fujitsu-Siemens laptops. - Many minor bug fixes. - New tool "ownership" added. Version 2.1 (Tue Jun 10 2003) - Support of the SMBIOS 2.3.4 specification. - Better support of IPMI. - Minor bugs fixed. - Documentation added. CPU-X-4.2.0/src/dmidecode/README000066400000000000000000000110521403012130000157140ustar00rootroot00000000000000** INTRODUCTION ** Dmidecode reports information about your system's hardware as described in your system BIOS according to the SMBIOS/DMI standard. This information typically includes system manufacturer, model name, serial number, BIOS version, asset tag as well as a lot of other details of varying level of interest and reliability depending on the manufacturer. This will often include usage status for the CPU sockets, expansion slots (e.g. AGP, PCI, ISA) and memory module slots, and the list of I/O ports (e.g. serial, parallel, USB). DMI data can be used to enable or disable specific portions of kernel code depending on the specific hardware. Thus, one use of dmidecode is for kernel developers to detect system "signatures" and add them to the kernel source code when needed. Beware that DMI data have proven to be too unreliable to be blindly trusted. Dmidecode does not scan your hardware, it only reports what the BIOS told it to. ** INSTALLATION ** The home web page for dmidecode is hosted on Savannah: http://www.nongnu.org/dmidecode/ You will find the latest version (including CVS) there, as well as fresh news and other interesting material, such as a list of related projects and articles. This program was first written for Linux, and has since been reported to work on FreeBSD, NetBSD, OpenBSD, BeOS and Solaris as well. There's no configure script, so simply run "make" to build dmidecode, and "make install" to install it. You also can use "make uninstall" to remove all the files you installed. By default, files are installed in /usr/local but you can change this behavior by editing the Makefile file and setting prefix to wherever you want. You may change the C compiler and the compilation flags as well. Optionally, you can run "make strip" prior to "make install" if you want smaller binaries. However, be aware that this will prevent any further attempt to debug the programs. Two parameters can be set in the Makefile file to make dmidecode work on non-i386 systems. They should be used if your system uses the big endian byte ordering (Motorola) or doesn't support unaligned memory accesses, respectively. For example, compiling for a SPARC processor would require both (but I am not aware of SPARC-based systems implementing SMBIOS). Compiling for an IA64 processor requires the memory alignment workaround, and it is enabled automatically. ** DOCUMENTATION ** Each tool has a manual page, found in the "man" subdirectory. Manual pages are installed by "make install". See these manual pages for command line interface details and tool specific information. For an history of the changes made to dmidecode, see the NEWS file. If you need help, your best chances are to visit the web page (see the INSTALLATION section above) or to get in touch with the developers directly. Have a look at the AUTHORS file and contact one of the maintainers. If you want to help with the development of dmidecode, please consider joining the dmidecode-devel discussion list: http://lists.nongnu.org/mailman/listinfo/dmidecode-devel ** COMMON PROBLEMS ** IA-64 Non-Linux systems are not yet supported. MMAP Note that mmap() is now used by default wherever possible, since this seems to solve a number of problems. This default behavior can be changed in config.h. Just to make sure this is clear, mmap() is not used for performance reasons but to increase the number of systems on which dmidecode can be successfully run. CYGWIN Dmidecode used to work under Cygwin. However the /dev/mem interface was removed at some point in time so it no longer works. ** MISCELLANEOUS TOOLS ** Three other tools come along with dmidecode: biosdecode, ownership and vpddecode. These tools are only useful on systems with a BIOS, so they are not built on IA-64 by default. BIOSDECODE This one prints all BIOS related information it can find in /dev/mem. It used to be part of dmidecode itself, but as dmidecode was growing, we felt that the non-DMI part had to be moved to a separate tool. OWNERSHIP This tool was written on a request by Luc Van de Velde for use with Novell tools in his company. It retrieves the "ownership tag" that can be set on most Compaq computers. Since it uses the same mechanisms dmidecode and biosdecode use, and could be of some use for other people as well, we decided to make it part of the project. VPDDECODE This tool prints the contents of the "vital product data" structure as found in most IBM and Lenovo computers. It used to have a lookup table for the machine name, but it was unreliable and hard to maintain so it was ultimately dropped. It has a command line interface. CPU-X-4.2.0/src/dmidecode/README.md000066400000000000000000000017221403012130000163160ustar00rootroot00000000000000# Dmidecode: Desktop Management Interface table related utilities Distributed under the terms of the [GNU GPL v2](https://github.com/X0rg/CPU-X/blob/master/src/dmidecode/LICENSE). ### CPU-X NOTE This sofware has been patched to be used within CPU-X. You can find the official web page of this project here: https://savannah.nongnu.org/projects/dmidecode/ This is based on dmidecode 3.3+[3c111e4](https://git.savannah.gnu.org/cgit/dmidecode.git/commit/?id=3c111e4f6134855580f20f8e01fee26eff455fff). This software is used to retrieve following data: - CPU tab - Package - Bus speed (fallback) - Motherboard tab - Motherboard manufacturer - Motherboard model - Motherboard revision - BIOS brand - BIOS version - BIOS date - BIOS ROM size You can reproduce the output of `dmidecode` command by using `cpu-x --dmidecode`. It will dump all DMI data on standard output. Note: you can increase dmidecode verbosity by using `cpu-x --verbose --dmidecode`. CPU-X-4.2.0/src/dmidecode/config.h000066400000000000000000000010451403012130000164530ustar00rootroot00000000000000/* * Configuration */ #ifndef CONFIG_H #define CONFIG_H /* Default memory device file */ #if defined(__BEOS__) || defined(__HAIKU__) #define DEFAULT_MEM_DEV "/dev/misc/mem" #else #ifdef __sun #define DEFAULT_MEM_DEV "/dev/xsvc" #else #define DEFAULT_MEM_DEV "/dev/mem" #endif #endif /* Use mmap or not */ #ifndef __BEOS__ #define USE_MMAP #endif /* Use memory alignment workaround or not */ #ifdef __ia64__ #define ALIGNMENT_WORKAROUND #endif /* Avoid unaligned memcpy on /dev/mem */ #ifdef __aarch64__ #define USE_SLOW_MEMCPY #endif #endif CPU-X-4.2.0/src/dmidecode/dmidecode.c000066400000000000000000004317031403012130000171260ustar00rootroot00000000000000/* * DMI Decode * * Copyright (C) 2000-2002 Alan Cox * Copyright (C) 2002-2020 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For the avoidance of doubt the "preferred form" of this code is one which * is in an open unpatent encumbered format. Where cryptographic key signing * forms part of the process of creating an executable the information * including keys needed to generate an equivalently functional executable * are deemed to be part of the source code. * * Unless specified otherwise, all references are aimed at the "System * Management BIOS Reference Specification, Version 3.2.0" document, * available from http://www.dmtf.org/standards/smbios. * * Note to contributors: * Please reference every value you add or modify, especially if the * information does not come from the above mentioned specification. * * Additional references: * - Intel AP-485 revision 36 * "Intel Processor Identification and the CPUID Instruction" * http://www.intel.com/support/processors/sb/cs-009861.htm * - DMTF Common Information Model * CIM Schema version 2.19.1 * http://www.dmtf.org/standards/cim/ * - IPMI 2.0 revision 1.0 * "Intelligent Platform Management Interface Specification" * http://developer.intel.com/design/servers/ipmi/spec.htm * - AMD publication #25481 revision 2.28 * "CPUID Specification" * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf * - BIOS Integrity Services Application Programming Interface version 1.0 * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm * - DMTF DSP0239 version 1.1.0 * "Management Component Transport Protocol (MCTP) IDs and Codes" * http://www.dmtf.org/standards/pmci * - "TPM Main, Part 2 TPM Structures" * Specification version 1.2, level 2, revision 116 * https://trustedcomputinggroup.org/tpm-main-specification/ * - "PC Client Platform TPM Profile (PTP) Specification" * Family "2.0", Level 00, Revision 00.43, January 26, 2015 * https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/ * - "RedFish Host Interface Specification" (DMTF DSP0270) * https://www.dmtf.org/sites/default/files/DSP0270_1.0.1.pdf */ #include #include #include #include #include #include #include #ifdef __FreeBSD__ #include #include #endif #include "config.h" #include "types.h" #include "util.h" #include "dmidecode.h" #include "dmiopt.h" #include "dmioem.h" #include "dmioutput.h" #include "../ipc.h" #define out_of_spec "" static const char *bad_index = ""; #define SUPPORTED_SMBIOS_VER 0x030300 #define STR_LEN 24 #define FLAG_NO_FILE_OFFSET (1 << 0) #define FLAG_STOP_AT_EOT (1 << 1) #define SYS_FIRMWARE_DIR "/sys/firmware/dmi/tables" #define SYS_ENTRY_FILE SYS_FIRMWARE_DIR "/smbios_entry_point" #define SYS_TABLE_FILE SYS_FIRMWARE_DIR "/DMI" /* Options are global */ static struct opt opt = { .type = NULL }; static DmidecodeData *cpux_data; /* * Type-independant Stuff */ /* Returns 1 if the buffer contains only printable ASCII characters */ int is_printable(const u8 *data, int len) { int i; for (i = 0; i < len; i++) if (data[i] < 32 || data[i] >= 127) return 0; return 1; } /* Replace non-ASCII characters with dots */ static void ascii_filter(char *bp, size_t len) { size_t i; for (i = 0; i < len; i++) if (bp[i] < 32 || bp[i] == 127) bp[i] = '.'; } static char *_dmi_string(const struct dmi_header *dm, u8 s, int filter) { char *bp = (char *)dm->data; bp += dm->length; while (s > 1 && *bp) { bp += strlen(bp); bp++; s--; } if (!*bp) return NULL; if (filter) ascii_filter(bp, strlen(bp)); return bp; } const char *dmi_string(const struct dmi_header *dm, u8 s) { char *bp; if (s == 0) return "Not Specified"; bp = _dmi_string(dm, s, 1); if (bp == NULL) return bad_index; return bp; } static const char *dmi_smbios_structure_type(u8 code) { static const char *type[] = { "BIOS", /* 0 */ "System", "Base Board", "Chassis", "Processor", "Memory Controller", "Memory Module", "Cache", "Port Connector", "System Slots", "On Board Devices", "OEM Strings", "System Configuration Options", "BIOS Language", "Group Associations", "System Event Log", "Physical Memory Array", "Memory Device", "32-bit Memory Error", "Memory Array Mapped Address", "Memory Device Mapped Address", "Built-in Pointing Device", "Portable Battery", "System Reset", "Hardware Security", "System Power Controls", "Voltage Probe", "Cooling Device", "Temperature Probe", "Electrical Current Probe", "Out-of-band Remote Access", "Boot Integrity Services", "System Boot", "64-bit Memory Error", "Management Device", "Management Device Component", "Management Device Threshold Data", "Memory Channel", "IPMI Device", "Power Supply", "Additional Information", "Onboard Device", "Management Controller Host Interface", "TPM Device", /* 43 */ }; if (code >= 128) return "OEM-specific"; if (code <= 43) return type[code]; return out_of_spec; } static int dmi_bcd_range(u8 value, u8 low, u8 high) { if (value > 0x99 || (value & 0x0F) > 0x09) return 0; if (value < low || value > high) return 0; return 1; } static void dmi_dump(const struct dmi_header *h) { static char raw_data[48]; int row, i; unsigned int off; char *s; pr_list_start("Header and Data", NULL); for (row = 0; row < ((h->length - 1) >> 4) + 1; row++) { off = 0; for (i = 0; i < 16 && i < h->length - (row << 4); i++) off += sprintf(raw_data + off, i ? " %02X" : "%02X", (h->data)[(row << 4) + i]); pr_list_item(raw_data); } pr_list_end(); if ((h->data)[h->length] || (h->data)[h->length + 1]) { pr_list_start("Strings", NULL); i = 1; while ((s = _dmi_string(h, i++, !(opt.flags & FLAG_DUMP)))) { if (opt.flags & FLAG_DUMP) { int j, l = strlen(s) + 1; off = 0; for (row = 0; row < ((l - 1) >> 4) + 1; row++) { for (j = 0; j < 16 && j < l - (row << 4); j++) off += sprintf(raw_data + off, j ? " %02X" : "%02X", (unsigned char)s[(row << 4) + j]); pr_list_item(raw_data); } /* String isn't filtered yet so do it now */ ascii_filter(s, l - 1); } pr_list_item("%s", s); } pr_list_end(); } } /* shift is 0 if the value is in bytes, 1 if it is in kilobytes */ static void dmi_print_memory_size(const char *attr, u64 code, int shift) { unsigned long capacity; u16 split[7]; static const char *unit[8] = { "bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB" }; int i; /* * We split the overall size in powers of thousand: EB, PB, TB, GB, * MB, kB and B. In practice, it is expected that only one or two * (consecutive) of these will be non-zero. */ split[0] = code.l & 0x3FFUL; split[1] = (code.l >> 10) & 0x3FFUL; split[2] = (code.l >> 20) & 0x3FFUL; split[3] = ((code.h << 2) & 0x3FCUL) | (code.l >> 30); split[4] = (code.h >> 8) & 0x3FFUL; split[5] = (code.h >> 18) & 0x3FFUL; split[6] = code.h >> 28; /* * Now we find the highest unit with a non-zero value. If the following * is also non-zero, we use that as our base. If the following is zero, * we simply display the highest unit. */ for (i = 6; i > 0; i--) { if (split[i]) break; } if (i > 0 && split[i - 1]) { i--; capacity = split[i] + (split[i + 1] << 10); } else capacity = split[i]; pr_attr(attr, "%lu %s", capacity, unit[i + shift]); } /* * 7.1 BIOS Information (Type 0) */ static void dmi_bios_runtime_size(u32 code) { const char *format; if (code & 0x000003FF) { format = "%u bytes"; } else { format = "%u kB"; code >>= 10; } pr_attr("Runtime Size", format, code); } static char *dmi_bios_runtime_size_str(u32 code) { static char size[STR_LEN] = ""; if (code & 0x000003FF) snprintf(size, STR_LEN, "%u @0B@", code); else snprintf(size, STR_LEN, "%u @KB@", code >> 10); return size; } static void dmi_bios_rom_size(u8 code1, u16 code2) { static const char *unit[4] = { "MB", "GB", out_of_spec, out_of_spec }; if (code1 != 0xFF) { u64 s = { .l = (code1 + 1) << 6 }; dmi_print_memory_size("ROM Size", s, 1); } else pr_attr("ROM Size", "%u %s", code2 & 0x3FFF, unit[code2 >> 14]); } static char *dmi_bios_rom_size_str(u8 code1, u16 code2) { static char size[STR_LEN] = ""; static const char *unit[4] = { "@MB@", "@GB@", "?B", "?B" }; if (code1 != 0xFF) snprintf(size, STR_LEN, "%u @KB@", (code1 + 1) << 6); else snprintf(size, STR_LEN, "%u %s", code2 & 0x3FFF, unit[code2 >> 14]); return size; } static void dmi_bios_characteristics(u64 code) { /* 7.1.1 */ static const char *characteristics[] = { "BIOS characteristics not supported", /* 3 */ "ISA is supported", "MCA is supported", "EISA is supported", "PCI is supported", "PC Card (PCMCIA) is supported", "PNP is supported", "APM is supported", "BIOS is upgradeable", "BIOS shadowing is allowed", "VLB is supported", "ESCD support is available", "Boot from CD is supported", "Selectable boot is supported", "BIOS ROM is socketed", "Boot from PC Card (PCMCIA) is supported", "EDD is supported", "Japanese floppy for NEC 9800 1.2 MB is supported (int 13h)", "Japanese floppy for Toshiba 1.2 MB is supported (int 13h)", "5.25\"/360 kB floppy services are supported (int 13h)", "5.25\"/1.2 MB floppy services are supported (int 13h)", "3.5\"/720 kB floppy services are supported (int 13h)", "3.5\"/2.88 MB floppy services are supported (int 13h)", "Print screen service is supported (int 5h)", "8042 keyboard services are supported (int 9h)", "Serial services are supported (int 14h)", "Printer services are supported (int 17h)", "CGA/mono video services are supported (int 10h)", "NEC PC-98" /* 31 */ }; int i; /* * This isn't very clear what this bit is supposed to mean */ if (code.l & (1 << 3)) { pr_list_item("%s", characteristics[0]); return; } for (i = 4; i <= 31; i++) if (code.l & (1 << i)) pr_list_item("%s", characteristics[i - 3]); } static void dmi_bios_characteristics_x1(u8 code) { /* 7.1.2.1 */ static const char *characteristics[] = { "ACPI is supported", /* 0 */ "USB legacy is supported", "AGP is supported", "I2O boot is supported", "LS-120 boot is supported", "ATAPI Zip drive boot is supported", "IEEE 1394 boot is supported", "Smart battery is supported" /* 7 */ }; int i; for (i = 0; i <= 7; i++) if (code & (1 << i)) pr_list_item("%s", characteristics[i]); } static void dmi_bios_characteristics_x2(u8 code) { /* 37.1.2.2 */ static const char *characteristics[] = { "BIOS boot specification is supported", /* 0 */ "Function key-initiated network boot is supported", "Targeted content distribution is supported", "UEFI is supported", "System is a virtual machine" /* 4 */ }; int i; for (i = 0; i <= 4; i++) if (code & (1 << i)) pr_list_item("%s", characteristics[i]); } /* * 7.2 System Information (Type 1) */ static void dmi_system_uuid(void (*print_cb)(const char *name, const char *format, ...), const char *attr, const u8 *p, u16 ver) { int only0xFF = 1, only0x00 = 1; int i; for (i = 0; i < 16 && (only0x00 || only0xFF); i++) { if (p[i] != 0x00) only0x00 = 0; if (p[i] != 0xFF) only0xFF = 0; } if (only0xFF) { if (print_cb) print_cb(attr, "Not Present"); else printf("Not Present\n"); return; } if (only0x00) { if (print_cb) print_cb(attr, "Not Settable"); else printf("Not Settable\n"); return; } /* * As of version 2.6 of the SMBIOS specification, the first 3 * fields of the UUID are supposed to be encoded on little-endian. * The specification says that this is the defacto standard, * however I've seen systems following RFC 4122 instead and use * network byte order, so I am reluctant to apply the byte-swapping * for older versions. */ if (ver >= 0x0206) { if (print_cb) print_cb(attr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); else printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", p[3], p[2], p[1], p[0], p[5], p[4], p[7], p[6], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); } else { if (print_cb) print_cb(attr, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); else printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); } } static const char *dmi_system_wake_up_type(u8 code) { /* 7.2.2 */ static const char *type[] = { "Reserved", /* 0x00 */ "Other", "Unknown", "APM Timer", "Modem Ring", "LAN Remote", "Power Switch", "PCI PME#", "AC Power Restored" /* 0x08 */ }; if (code <= 0x08) return type[code]; return out_of_spec; } /* * 7.3 Base Board Information (Type 2) */ static void dmi_base_board_features(u8 code) { /* 7.3.1 */ static const char *features[] = { "Board is a hosting board", /* 0 */ "Board requires at least one daughter board", "Board is removable", "Board is replaceable", "Board is hot swappable" /* 4 */ }; if ((code & 0x1F) == 0) pr_list_start("Features", "%s", "None"); else { int i; pr_list_start("Features", NULL); for (i = 0; i <= 4; i++) if (code & (1 << i)) pr_list_item("%s", features[i]); } pr_list_end(); } static const char *dmi_base_board_type(u8 code) { /* 7.3.2 */ static const char *type[] = { "Unknown", /* 0x01 */ "Other", "Server Blade", "Connectivity Switch", "System Management Module", "Processor Module", "I/O Module", "Memory Module", "Daughter Board", "Motherboard", "Processor+Memory Module", "Processor+I/O Module", "Interconnect Board" /* 0x0D */ }; if (code >= 0x01 && code <= 0x0D) return type[code - 0x01]; return out_of_spec; } static void dmi_base_board_handles(u8 count, const u8 *p) { int i; pr_list_start("Contained Object Handles", "%u", count); for (i = 0; i < count; i++) pr_list_item("0x%04X", WORD(p + sizeof(u16) * i)); pr_list_end(); } /* * 7.4 Chassis Information (Type 3) */ static const char *dmi_chassis_type(u8 code) { /* 7.4.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Desktop", "Low Profile Desktop", "Pizza Box", "Mini Tower", "Tower", "Portable", "Laptop", "Notebook", "Hand Held", "Docking Station", "All In One", "Sub Notebook", "Space-saving", "Lunch Box", "Main Server Chassis", /* CIM_Chassis.ChassisPackageType says "Main System Chassis" */ "Expansion Chassis", "Sub Chassis", "Bus Expansion Chassis", "Peripheral Chassis", "RAID Chassis", "Rack Mount Chassis", "Sealed-case PC", "Multi-system", "CompactPCI", "AdvancedTCA", "Blade", "Blade Enclosing", "Tablet", "Convertible", "Detachable", "IoT Gateway", "Embedded PC", "Mini PC", "Stick PC" /* 0x24 */ }; code &= 0x7F; /* bits 6:0 are chassis type, 7th bit is the lock bit */ if (code >= 0x01 && code <= 0x24) return type[code - 0x01]; return out_of_spec; } static const char *dmi_chassis_lock(u8 code) { static const char *lock[] = { "Not Present", /* 0x00 */ "Present" /* 0x01 */ }; return lock[code]; } static const char *dmi_chassis_state(u8 code) { /* 7.4.2 */ static const char *state[] = { "Other", /* 0x01 */ "Unknown", "Safe", "Warning", "Critical", "Non-recoverable" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return state[code - 0x01]; return out_of_spec; } static const char *dmi_chassis_security_status(u8 code) { /* 7.4.3 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", "None", "External Interface Locked Out", "External Interface Enabled" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return status[code - 0x01]; return out_of_spec; } static void dmi_chassis_height(u8 code) { if (code == 0x00) pr_attr("Height", "Unspecified"); else pr_attr("Height", "%u U", code); } static void dmi_chassis_power_cords(u8 code) { if (code == 0x00) pr_attr("Number Of Power Cords", "Unspecified"); else pr_attr("Number Of Power Cords", "%u", code); } static void dmi_chassis_elements(u8 count, u8 len, const u8 *p) { int i; pr_list_start("Contained Elements", "%u", count); for (i = 0; i < count; i++) { if (len >= 0x03) { const char *type; type = (p[i * len] & 0x80) ? dmi_smbios_structure_type(p[i * len] & 0x7F) : dmi_base_board_type(p[i * len] & 0x7F); if (p[1 + i * len] == p[2 + i * len]) pr_list_item("%s (%u)", type, p[1 + i * len]); else pr_list_item("%s (%u-%u)", type, p[1 + i * len], p[2 + i * len]); } } pr_list_end(); } /* * 7.5 Processor Information (Type 4) */ static const char *dmi_processor_type(u8 code) { /* 7.5.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Central Processor", "Math Processor", "DSP Processor", "Video Processor" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return type[code - 0x01]; return out_of_spec; } static const char *dmi_processor_family(const struct dmi_header *h, u16 ver) { const u8 *data = h->data; unsigned int i, low, high; u16 code; /* 7.5.2 */ static struct { int value; const char *name; } family2[] = { { 0x01, "Other" }, { 0x02, "Unknown" }, { 0x03, "8086" }, { 0x04, "80286" }, { 0x05, "80386" }, { 0x06, "80486" }, { 0x07, "8087" }, { 0x08, "80287" }, { 0x09, "80387" }, { 0x0A, "80487" }, { 0x0B, "Pentium" }, { 0x0C, "Pentium Pro" }, { 0x0D, "Pentium II" }, { 0x0E, "Pentium MMX" }, { 0x0F, "Celeron" }, { 0x10, "Pentium II Xeon" }, { 0x11, "Pentium III" }, { 0x12, "M1" }, { 0x13, "M2" }, { 0x14, "Celeron M" }, { 0x15, "Pentium 4 HT" }, { 0x18, "Duron" }, { 0x19, "K5" }, { 0x1A, "K6" }, { 0x1B, "K6-2" }, { 0x1C, "K6-3" }, { 0x1D, "Athlon" }, { 0x1E, "AMD29000" }, { 0x1F, "K6-2+" }, { 0x20, "Power PC" }, { 0x21, "Power PC 601" }, { 0x22, "Power PC 603" }, { 0x23, "Power PC 603+" }, { 0x24, "Power PC 604" }, { 0x25, "Power PC 620" }, { 0x26, "Power PC x704" }, { 0x27, "Power PC 750" }, { 0x28, "Core Duo" }, { 0x29, "Core Duo Mobile" }, { 0x2A, "Core Solo Mobile" }, { 0x2B, "Atom" }, { 0x2C, "Core M" }, { 0x2D, "Core m3" }, { 0x2E, "Core m5" }, { 0x2F, "Core m7" }, { 0x30, "Alpha" }, { 0x31, "Alpha 21064" }, { 0x32, "Alpha 21066" }, { 0x33, "Alpha 21164" }, { 0x34, "Alpha 21164PC" }, { 0x35, "Alpha 21164a" }, { 0x36, "Alpha 21264" }, { 0x37, "Alpha 21364" }, { 0x38, "Turion II Ultra Dual-Core Mobile M" }, { 0x39, "Turion II Dual-Core Mobile M" }, { 0x3A, "Athlon II Dual-Core M" }, { 0x3B, "Opteron 6100" }, { 0x3C, "Opteron 4100" }, { 0x3D, "Opteron 6200" }, { 0x3E, "Opteron 4200" }, { 0x3F, "FX" }, { 0x40, "MIPS" }, { 0x41, "MIPS R4000" }, { 0x42, "MIPS R4200" }, { 0x43, "MIPS R4400" }, { 0x44, "MIPS R4600" }, { 0x45, "MIPS R10000" }, { 0x46, "C-Series" }, { 0x47, "E-Series" }, { 0x48, "A-Series" }, { 0x49, "G-Series" }, { 0x4A, "Z-Series" }, { 0x4B, "R-Series" }, { 0x4C, "Opteron 4300" }, { 0x4D, "Opteron 6300" }, { 0x4E, "Opteron 3300" }, { 0x4F, "FirePro" }, { 0x50, "SPARC" }, { 0x51, "SuperSPARC" }, { 0x52, "MicroSPARC II" }, { 0x53, "MicroSPARC IIep" }, { 0x54, "UltraSPARC" }, { 0x55, "UltraSPARC II" }, { 0x56, "UltraSPARC IIi" }, { 0x57, "UltraSPARC III" }, { 0x58, "UltraSPARC IIIi" }, { 0x60, "68040" }, { 0x61, "68xxx" }, { 0x62, "68000" }, { 0x63, "68010" }, { 0x64, "68020" }, { 0x65, "68030" }, { 0x66, "Athlon X4" }, { 0x67, "Opteron X1000" }, { 0x68, "Opteron X2000" }, { 0x69, "Opteron A-Series" }, { 0x6A, "Opteron X3000" }, { 0x6B, "Zen" }, { 0x70, "Hobbit" }, { 0x78, "Crusoe TM5000" }, { 0x79, "Crusoe TM3000" }, { 0x7A, "Efficeon TM8000" }, { 0x80, "Weitek" }, { 0x82, "Itanium" }, { 0x83, "Athlon 64" }, { 0x84, "Opteron" }, { 0x85, "Sempron" }, { 0x86, "Turion 64" }, { 0x87, "Dual-Core Opteron" }, { 0x88, "Athlon 64 X2" }, { 0x89, "Turion 64 X2" }, { 0x8A, "Quad-Core Opteron" }, { 0x8B, "Third-Generation Opteron" }, { 0x8C, "Phenom FX" }, { 0x8D, "Phenom X4" }, { 0x8E, "Phenom X2" }, { 0x8F, "Athlon X2" }, { 0x90, "PA-RISC" }, { 0x91, "PA-RISC 8500" }, { 0x92, "PA-RISC 8000" }, { 0x93, "PA-RISC 7300LC" }, { 0x94, "PA-RISC 7200" }, { 0x95, "PA-RISC 7100LC" }, { 0x96, "PA-RISC 7100" }, { 0xA0, "V30" }, { 0xA1, "Quad-Core Xeon 3200" }, { 0xA2, "Dual-Core Xeon 3000" }, { 0xA3, "Quad-Core Xeon 5300" }, { 0xA4, "Dual-Core Xeon 5100" }, { 0xA5, "Dual-Core Xeon 5000" }, { 0xA6, "Dual-Core Xeon LV" }, { 0xA7, "Dual-Core Xeon ULV" }, { 0xA8, "Dual-Core Xeon 7100" }, { 0xA9, "Quad-Core Xeon 5400" }, { 0xAA, "Quad-Core Xeon" }, { 0xAB, "Dual-Core Xeon 5200" }, { 0xAC, "Dual-Core Xeon 7200" }, { 0xAD, "Quad-Core Xeon 7300" }, { 0xAE, "Quad-Core Xeon 7400" }, { 0xAF, "Multi-Core Xeon 7400" }, { 0xB0, "Pentium III Xeon" }, { 0xB1, "Pentium III Speedstep" }, { 0xB2, "Pentium 4" }, { 0xB3, "Xeon" }, { 0xB4, "AS400" }, { 0xB5, "Xeon MP" }, { 0xB6, "Athlon XP" }, { 0xB7, "Athlon MP" }, { 0xB8, "Itanium 2" }, { 0xB9, "Pentium M" }, { 0xBA, "Celeron D" }, { 0xBB, "Pentium D" }, { 0xBC, "Pentium EE" }, { 0xBD, "Core Solo" }, /* 0xBE handled as a special case */ { 0xBF, "Core 2 Duo" }, { 0xC0, "Core 2 Solo" }, { 0xC1, "Core 2 Extreme" }, { 0xC2, "Core 2 Quad" }, { 0xC3, "Core 2 Extreme Mobile" }, { 0xC4, "Core 2 Duo Mobile" }, { 0xC5, "Core 2 Solo Mobile" }, { 0xC6, "Core i7" }, { 0xC7, "Dual-Core Celeron" }, { 0xC8, "IBM390" }, { 0xC9, "G4" }, { 0xCA, "G5" }, { 0xCB, "ESA/390 G6" }, { 0xCC, "z/Architecture" }, { 0xCD, "Core i5" }, { 0xCE, "Core i3" }, { 0xCF, "Core i9" }, { 0xD2, "C7-M" }, { 0xD3, "C7-D" }, { 0xD4, "C7" }, { 0xD5, "Eden" }, { 0xD6, "Multi-Core Xeon" }, { 0xD7, "Dual-Core Xeon 3xxx" }, { 0xD8, "Quad-Core Xeon 3xxx" }, { 0xD9, "Nano" }, { 0xDA, "Dual-Core Xeon 5xxx" }, { 0xDB, "Quad-Core Xeon 5xxx" }, { 0xDD, "Dual-Core Xeon 7xxx" }, { 0xDE, "Quad-Core Xeon 7xxx" }, { 0xDF, "Multi-Core Xeon 7xxx" }, { 0xE0, "Multi-Core Xeon 3400" }, { 0xE4, "Opteron 3000" }, { 0xE5, "Sempron II" }, { 0xE6, "Embedded Opteron Quad-Core" }, { 0xE7, "Phenom Triple-Core" }, { 0xE8, "Turion Ultra Dual-Core Mobile" }, { 0xE9, "Turion Dual-Core Mobile" }, { 0xEA, "Athlon Dual-Core" }, { 0xEB, "Sempron SI" }, { 0xEC, "Phenom II" }, { 0xED, "Athlon II" }, { 0xEE, "Six-Core Opteron" }, { 0xEF, "Sempron M" }, { 0xFA, "i860" }, { 0xFB, "i960" }, { 0x100, "ARMv7" }, { 0x101, "ARMv8" }, { 0x104, "SH-3" }, { 0x105, "SH-4" }, { 0x118, "ARM" }, { 0x119, "StrongARM" }, { 0x12C, "6x86" }, { 0x12D, "MediaGX" }, { 0x12E, "MII" }, { 0x140, "WinChip" }, { 0x15E, "DSP" }, { 0x1F4, "Video Processor" }, { 0x200, "RV32" }, { 0x201, "RV64" }, { 0x202, "RV128" }, }; /* * Note to developers: when adding entries to this list, check if * function dmi_processor_id below needs updating too. */ /* Special case for ambiguous value 0x30 (SMBIOS 2.0 only) */ if (ver == 0x0200 && data[0x06] == 0x30 && h->length >= 0x08) { const char *manufacturer = dmi_string(h, data[0x07]); if (strstr(manufacturer, "Intel") != NULL || strncasecmp(manufacturer, "Intel", 5) == 0) return "Pentium Pro"; } code = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06]; /* Special case for ambiguous value 0xBE */ if (code == 0xBE) { if (h->length >= 0x08) { const char *manufacturer = dmi_string(h, data[0x07]); /* Best bet based on manufacturer string */ if (strstr(manufacturer, "Intel") != NULL || strncasecmp(manufacturer, "Intel", 5) == 0) return "Core 2"; if (strstr(manufacturer, "AMD") != NULL || strncasecmp(manufacturer, "AMD", 3) == 0) return "K7"; } return "Core 2 or K7"; } /* Perform a binary search */ low = 0; high = ARRAY_SIZE(family2) - 1; while (1) { i = (low + high) / 2; if (family2[i].value == code) return family2[i].name; if (low == high) /* Not found */ return out_of_spec; if (code < family2[i].value) high = i; else low = i + 1; } } static void dmi_processor_id(const struct dmi_header *h) { /* Intel AP-485 revision 36, table 2-4 */ static const char *flags[32] = { "FPU (Floating-point unit on-chip)", /* 0 */ "VME (Virtual mode extension)", "DE (Debugging extension)", "PSE (Page size extension)", "TSC (Time stamp counter)", "MSR (Model specific registers)", "PAE (Physical address extension)", "MCE (Machine check exception)", "CX8 (CMPXCHG8 instruction supported)", "APIC (On-chip APIC hardware supported)", NULL, /* 10 */ "SEP (Fast system call)", "MTRR (Memory type range registers)", "PGE (Page global enable)", "MCA (Machine check architecture)", "CMOV (Conditional move instruction supported)", "PAT (Page attribute table)", "PSE-36 (36-bit page size extension)", "PSN (Processor serial number present and enabled)", "CLFSH (CLFLUSH instruction supported)", NULL, /* 20 */ "DS (Debug store)", "ACPI (ACPI supported)", "MMX (MMX technology supported)", "FXSR (FXSAVE and FXSTOR instructions supported)", "SSE (Streaming SIMD extensions)", "SSE2 (Streaming SIMD extensions 2)", "SS (Self-snoop)", "HTT (Multi-threading)", "TM (Thermal monitor supported)", NULL, /* 30 */ "PBE (Pending break enabled)" /* 31 */ }; const u8 *data = h->data; const u8 *p = data + 0x08; u32 eax, edx; int sig = 0; u16 type; type = (data[0x06] == 0xFE && h->length >= 0x2A) ? WORD(data + 0x28) : data[0x06]; /* * This might help learn about new processors supporting the * CPUID instruction or another form of identification. */ pr_attr("ID", "%02X %02X %02X %02X %02X %02X %02X %02X", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); if (type == 0x05) /* 80386 */ { u16 dx = WORD(p); /* * 80386 have a different signature. */ pr_attr("Signature", "Type %u, Family %u, Major Stepping %u, Minor Stepping %u", dx >> 12, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF); return; } if (type == 0x06) /* 80486 */ { u16 dx = WORD(p); /* * Not all 80486 CPU support the CPUID instruction, we have to find * whether the one we have here does or not. Note that this trick * works only because we know that 80486 must be little-endian. */ if ((dx & 0x0F00) == 0x0400 && ((dx & 0x00F0) == 0x0040 || (dx & 0x00F0) >= 0x0070) && ((dx & 0x000F) >= 0x0003)) sig = 1; else { pr_attr("Signature", "Type %u, Family %u, Model %u, Stepping %u", (dx >> 12) & 0x3, (dx >> 8) & 0xF, (dx >> 4) & 0xF, dx & 0xF); return; } } else if ((type >= 0x100 && type <= 0x101) /* ARM */ || (type >= 0x118 && type <= 0x119)) /* ARM */ { u32 midr = DWORD(p); /* * The format of this field was not defined for ARM processors * before version 3.1.0 of the SMBIOS specification, so we * silently skip it if it reads all zeroes. */ if (midr == 0) return; pr_attr("Signature", "Implementor 0x%02x, Variant 0x%x, Architecture %u, Part 0x%03x, Revision %u", midr >> 24, (midr >> 20) & 0xF, (midr >> 16) & 0xF, (midr >> 4) & 0xFFF, midr & 0xF); return; } else if ((type >= 0x0B && type <= 0x15) /* Intel, Cyrix */ || (type >= 0x28 && type <= 0x2F) /* Intel */ || (type >= 0xA1 && type <= 0xB3) /* Intel */ || type == 0xB5 /* Intel */ || (type >= 0xB9 && type <= 0xC7) /* Intel */ || (type >= 0xCD && type <= 0xCF) /* Intel */ || (type >= 0xD2 && type <= 0xDB) /* VIA, Intel */ || (type >= 0xDD && type <= 0xE0)) /* Intel */ sig = 1; else if ((type >= 0x18 && type <= 0x1D) /* AMD */ || type == 0x1F /* AMD */ || (type >= 0x38 && type <= 0x3F) /* AMD */ || (type >= 0x46 && type <= 0x4F) /* AMD */ || (type >= 0x66 && type <= 0x6B) /* AMD */ || (type >= 0x83 && type <= 0x8F) /* AMD */ || (type >= 0xB6 && type <= 0xB7) /* AMD */ || (type >= 0xE4 && type <= 0xEF)) /* AMD */ sig = 2; else if (type == 0x01 || type == 0x02) { const char *version = dmi_string(h, data[0x10]); /* * Some X86-class CPU have family "Other" or "Unknown". In this case, * we use the version string to determine if they are known to * support the CPUID instruction. */ if (strncmp(version, "Pentium III MMX", 15) == 0 || strncmp(version, "Intel(R) Core(TM)2", 18) == 0 || strncmp(version, "Intel(R) Pentium(R)", 19) == 0 || strcmp(version, "Genuine Intel(R) CPU U1400") == 0) sig = 1; else if (strncmp(version, "AMD Athlon(TM)", 14) == 0 || strncmp(version, "AMD Opteron(tm)", 15) == 0 || strncmp(version, "Dual-Core AMD Opteron(tm)", 25) == 0) sig = 2; else return; } else /* neither X86 nor ARM */ return; /* * Extra flags are now returned in the ECX register when one calls * the CPUID instruction. Their meaning is explained in table 3-5, but * DMI doesn't support this yet. */ eax = DWORD(p); edx = DWORD(p + 4); switch (sig) { case 1: /* Intel */ pr_attr("Signature", "Type %u, Family %u, Model %u, Stepping %u", (eax >> 12) & 0x3, ((eax >> 20) & 0xFF) + ((eax >> 8) & 0x0F), ((eax >> 12) & 0xF0) + ((eax >> 4) & 0x0F), eax & 0xF); break; case 2: /* AMD, publication #25481 revision 2.28 */ pr_attr("Signature", "Family %u, Model %u, Stepping %u", ((eax >> 8) & 0xF) + (((eax >> 8) & 0xF) == 0xF ? (eax >> 20) & 0xFF : 0), ((eax >> 4) & 0xF) | (((eax >> 8) & 0xF) == 0xF ? (eax >> 12) & 0xF0 : 0), eax & 0xF); break; } edx = DWORD(p + 4); if ((edx & 0xBFEFFBFF) == 0) pr_list_start("Flags", "None"); else { int i; pr_list_start("Flags", NULL); for (i = 0; i <= 31; i++) if (flags[i] != NULL && edx & (1 << i)) pr_list_item("%s", flags[i]); } pr_list_end(); } static void dmi_processor_voltage(const char *attr, u8 code) { /* 7.5.4 */ static const char *voltage[] = { "5.0 V", /* 0 */ "3.3 V", "2.9 V" /* 2 */ }; int i; if (code & 0x80) pr_attr(attr, "%.1f V", (float)(code & 0x7f) / 10); else if ((code & 0x07) == 0x00) pr_attr(attr, "Unknown"); else { char voltage_str[18]; int off = 0; for (i = 0; i <= 2; i++) { if (code & (1 << i)) { /* Insert space if not the first value */ off += sprintf(voltage_str + off, off ? " %s" :"%s", voltage[i]); } } if (off) pr_attr(attr, voltage_str); } } static void dmi_processor_frequency(const char *attr, const u8 *p) { u16 code = WORD(p); if (code) { if (attr) pr_attr(attr, "%u MHz", code); else printf("%u MHz\n", code); } else { if (attr) pr_attr(attr, "Unknown"); else printf("Unknown\n"); } } /* code is assumed to be a 3-bit value */ static const char *dmi_processor_status(u8 code) { static const char *status[] = { "Unknown", /* 0x00 */ "Enabled", "Disabled By User", "Disabled By BIOS", "Idle", /* 0x04 */ out_of_spec, out_of_spec, "Other" /* 0x07 */ }; return status[code]; } static const char *dmi_processor_upgrade(u8 code) { /* 7.5.5 */ static const char *upgrade[] = { "Other", /* 0x01 */ "Unknown", "Daughter Board", "ZIF Socket", "Replaceable Piggy Back", "None", "LIF Socket", "Slot 1", "Slot 2", "370-pin Socket", "Slot A", "Slot M", "Socket 423", "Socket A (Socket 462)", "Socket 478", "Socket 754", "Socket 940", "Socket 939", "Socket mPGA604", "Socket LGA771", "Socket LGA775", "Socket S1", "Socket AM2", "Socket F (1207)", "Socket LGA1366", "Socket G34", "Socket AM3", "Socket C32", "Socket LGA1156", "Socket LGA1567", "Socket PGA988A", "Socket BGA1288", "Socket rPGA988B", "Socket BGA1023", "Socket BGA1224", "Socket BGA1155", "Socket LGA1356", "Socket LGA2011", "Socket FS1", "Socket FS2", "Socket FM1", "Socket FM2", "Socket LGA2011-3", "Socket LGA1356-3", "Socket LGA1150", "Socket BGA1168", "Socket BGA1234", "Socket BGA1364", "Socket AM4", "Socket LGA1151", "Socket BGA1356", "Socket BGA1440", "Socket BGA1515", "Socket LGA3647-1", "Socket SP3", "Socket SP3r2", "Socket LGA2066", "Socket BGA1392", "Socket BGA1510", "Socket BGA1528", "Socket LGA4189", "Socket LGA1200" /* 0x3E */ }; if (code >= 0x01 && code <= 0x3E) return upgrade[code - 0x01]; return out_of_spec; } static void dmi_processor_cache(const char *attr, u16 code, const char *level, u16 ver) { if (code == 0xFFFF) { if (ver >= 0x0203) pr_attr(attr, "Not Provided"); else pr_attr(attr, "No %s Cache", level); } else pr_attr(attr, "0x%04X", code); } static void dmi_processor_characteristics(const char *attr, u16 code) { /* 7.5.9 */ static const char *characteristics[] = { "64-bit capable", /* 2 */ "Multi-Core", "Hardware Thread", "Execute Protection", "Enhanced Virtualization", "Power/Performance Control", "128-bit Capable", "Arm64 SoC ID" /* 9 */ }; if ((code & 0x00FC) == 0) pr_attr(attr, "None"); else { int i; pr_list_start(attr, NULL); for (i = 2; i <= 9; i++) if (code & (1 << i)) pr_list_item("%s", characteristics[i - 2]); pr_list_end(); } } /* * 7.6 Memory Controller Information (Type 5) */ static const char *dmi_memory_controller_ed_method(u8 code) { /* 7.6.1 */ static const char *method[] = { "Other", /* 0x01 */ "Unknown", "None", "8-bit Parity", "32-bit ECC", "64-bit ECC", "128-bit ECC", "CRC" /* 0x08 */ }; if (code >= 0x01 && code <= 0x08) return method[code - 0x01]; return out_of_spec; } static void dmi_memory_controller_ec_capabilities(const char *attr, u8 code) { /* 7.6.2 */ static const char *capabilities[] = { "Other", /* 0 */ "Unknown", "None", "Single-bit Error Correcting", "Double-bit Error Correcting", "Error Scrubbing" /* 5 */ }; if ((code & 0x3F) == 0) pr_attr(attr, "None"); else { int i; pr_list_start(attr, NULL); for (i = 0; i <= 5; i++) if (code & (1 << i)) pr_list_item("%s", capabilities[i]); pr_list_end(); } } static const char *dmi_memory_controller_interleave(u8 code) { /* 7.6.3 */ static const char *interleave[] = { "Other", /* 0x01 */ "Unknown", "One-way Interleave", "Two-way Interleave", "Four-way Interleave", "Eight-way Interleave", "Sixteen-way Interleave" /* 0x07 */ }; if (code >= 0x01 && code <= 0x07) return interleave[code - 0x01]; return out_of_spec; } static void dmi_memory_controller_speeds(const char *attr, u16 code) { /* 7.6.4 */ const char *speeds[] = { "Other", /* 0 */ "Unknown", "70 ns", "60 ns", "50 ns" /* 4 */ }; if ((code & 0x001F) == 0) pr_attr(attr, "None"); else { int i; pr_list_start(attr, NULL); for (i = 0; i <= 4; i++) if (code & (1 << i)) pr_list_item("%s", speeds[i]); pr_list_end(); } } static void dmi_memory_controller_slots(u8 count, const u8 *p) { int i; pr_list_start("Associated Memory Slots", "%u", count); for (i = 0; i < count; i++) pr_list_item("0x%04X", WORD(p + sizeof(u16) * i)); pr_list_end(); } /* * 7.7 Memory Module Information (Type 6) */ static void dmi_memory_module_types(const char *attr, u16 code, int flat) { /* 7.7.1 */ static const char *types[] = { "Other", /* 0 */ "Unknown", "Standard", "FPM", "EDO", "Parity", "ECC", "SIMM", "DIMM", "Burst EDO", "SDRAM" /* 10 */ }; if ((code & 0x07FF) == 0) pr_attr(attr, "None"); else if (flat) { char type_str[68]; int i, off = 0; for (i = 0; i <= 10; i++) { if (code & (1 << i)) { /* Insert space if not the first value */ off += sprintf(type_str + off, off ? " %s" :"%s", types[i]); } } if (off) pr_attr(attr, type_str); } else { int i; pr_list_start(attr, NULL); for (i = 0; i <= 10; i++) if (code & (1 << i)) pr_list_item("%s", types[i]); pr_list_end(); } } static void dmi_memory_module_connections(u8 code) { if (code == 0xFF) pr_attr("Bank Connections", "None"); else if ((code & 0xF0) == 0xF0) pr_attr("Bank Connections", "%u", code & 0x0F); else if ((code & 0x0F) == 0x0F) pr_attr("Bank Connections", "%u", code >> 4); else pr_attr("Bank Connections", "%u %u", code >> 4, code & 0x0F); } static void dmi_memory_module_speed(const char *attr, u8 code) { if (code == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "%u ns", code); } static void dmi_memory_module_size(const char *attr, u8 code) { const char *connection; /* 7.7.2 */ if (code & 0x80) connection = " (Double-bank Connection)"; else connection = " (Single-bank Connection)"; switch (code & 0x7F) { case 0x7D: pr_attr(attr, "Not Determinable%s", connection); break; case 0x7E: pr_attr(attr, "Disabled%s", connection); break; case 0x7F: pr_attr(attr, "Not Installed"); return; default: pr_attr(attr, "%u MB%s", 1 << (code & 0x7F), connection); } } static void dmi_memory_module_error(u8 code) { static const char *status[] = { "OK", /* 0x00 */ "Uncorrectable Errors", "Correctable Errors", "Correctable and Uncorrectable Errors" /* 0x03 */ }; if (code & (1 << 2)) pr_attr("Error Status", "See Event Log"); else pr_attr("Error Status", "%s", status[code & 0x03]); } /* * 7.8 Cache Information (Type 7) */ static const char *dmi_cache_mode(u8 code) { static const char *mode[] = { "Write Through", /* 0x00 */ "Write Back", "Varies With Memory Address", "Unknown" /* 0x03 */ }; return mode[code]; } /* code is assumed to be a 2-bit value */ static const char *dmi_cache_location(u8 code) { static const char *location[4] = { "Internal", /* 0x00 */ "External", out_of_spec, /* 0x02 */ "Unknown" /* 0x03 */ }; return location[code]; } static void dmi_cache_size_2(const char *attr, u32 code) { u64 size; if (code & 0x80000000) { code &= 0x7FFFFFFFLU; size.l = code << 6; size.h = code >> 26; } else { size.l = code; size.h = 0; } /* Use a more convenient unit for large cache size */ dmi_print_memory_size(attr, size, 1); } static void dmi_cache_size(const char *attr, u16 code) { dmi_cache_size_2(attr, (((u32)code & 0x8000LU) << 16) | (code & 0x7FFFLU)); } static void dmi_cache_types(const char *attr, u16 code, int flat) { /* 7.8.2 */ static const char *types[] = { "Other", /* 0 */ "Unknown", "Non-burst", "Burst", "Pipeline Burst", "Synchronous", "Asynchronous" /* 6 */ }; if ((code & 0x007F) == 0) pr_attr(attr, "None"); else if (flat) { char type_str[70]; int i, off = 0; for (i = 0; i <= 6; i++) { if (code & (1 << i)) { /* Insert space if not the first value */ off += sprintf(type_str + off, off ? " %s" :"%s", types[i]); } } if (off) pr_attr(attr, type_str); } else { int i; pr_list_start(attr, NULL); for (i = 0; i <= 6; i++) if (code & (1 << i)) pr_list_item("%s", types[i]); pr_list_end(); } } static const char *dmi_cache_ec_type(u8 code) { /* 7.8.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "None", "Parity", "Single-bit ECC", "Multi-bit ECC" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return type[code - 0x01]; return out_of_spec; } static const char *dmi_cache_type(u8 code) { /* 7.8.4 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Instruction", "Data", "Unified" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return type[code - 0x01]; return out_of_spec; } static const char *dmi_cache_associativity(u8 code) { /* 7.8.5 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Direct Mapped", "2-way Set-associative", "4-way Set-associative", "Fully Associative", "8-way Set-associative", "16-way Set-associative", "12-way Set-associative", "24-way Set-associative", "32-way Set-associative", "48-way Set-associative", "64-way Set-associative", "20-way Set-associative" /* 0x0E */ }; if (code >= 0x01 && code <= 0x0E) return type[code - 0x01]; return out_of_spec; } /* * 7.9 Port Connector Information (Type 8) */ static const char *dmi_port_connector_type(u8 code) { /* 7.9.2 */ static const char *type[] = { "None", /* 0x00 */ "Centronics", "Mini Centronics", "Proprietary", "DB-25 male", "DB-25 female", "DB-15 male", "DB-15 female", "DB-9 male", "DB-9 female", "RJ-11", "RJ-45", "50 Pin MiniSCSI", "Mini DIN", "Micro DIN", "PS/2", "Infrared", "HP-HIL", "Access Bus (USB)", "SSA SCSI", "Circular DIN-8 male", "Circular DIN-8 female", "On Board IDE", "On Board Floppy", "9 Pin Dual Inline (pin 10 cut)", "25 Pin Dual Inline (pin 26 cut)", "50 Pin Dual Inline", "68 Pin Dual Inline", "On Board Sound Input From CD-ROM", "Mini Centronics Type-14", "Mini Centronics Type-26", "Mini Jack (headphones)", "BNC", "IEEE 1394", "SAS/SATA Plug Receptacle", "USB Type-C Receptacle" /* 0x23 */ }; static const char *type_0xA0[] = { "PC-98", /* 0xA0 */ "PC-98 Hireso", "PC-H98", "PC-98 Note", "PC-98 Full" /* 0xA4 */ }; if (code <= 0x23) return type[code]; if (code >= 0xA0 && code <= 0xA4) return type_0xA0[code - 0xA0]; if (code == 0xFF) return "Other"; return out_of_spec; } static const char *dmi_port_type(u8 code) { /* 7.9.3 */ static const char *type[] = { "None", /* 0x00 */ "Parallel Port XT/AT Compatible", "Parallel Port PS/2", "Parallel Port ECP", "Parallel Port EPP", "Parallel Port ECP/EPP", "Serial Port XT/AT Compatible", "Serial Port 16450 Compatible", "Serial Port 16550 Compatible", "Serial Port 16550A Compatible", "SCSI Port", "MIDI Port", "Joystick Port", "Keyboard Port", "Mouse Port", "SSA SCSI", "USB", "Firewire (IEEE P1394)", "PCMCIA Type I", "PCMCIA Type II", "PCMCIA Type III", "Cardbus", "Access Bus Port", "SCSI II", "SCSI Wide", "PC-98", "PC-98 Hireso", "PC-H98", "Video Port", "Audio Port", "Modem Port", "Network Port", "SATA", "SAS" /* 0x21 */ }; static const char *type_0xA0[] = { "8251 Compatible", /* 0xA0 */ "8251 FIFO Compatible" /* 0xA1 */ }; if (code <= 0x21) return type[code]; if (code >= 0xA0 && code <= 0xA1) return type_0xA0[code - 0xA0]; if (code == 0xFF) return "Other"; return out_of_spec; } /* * 7.10 System Slots (Type 9) */ static const char *dmi_slot_type(u8 code) { /* 7.10.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "ISA", "MCA", "EISA", "PCI", "PC Card (PCMCIA)", "VLB", "Proprietary", "Processor Card", "Proprietary Memory Card", "I/O Riser Card", "NuBus", "PCI-66", "AGP", "AGP 2x", "AGP 4x", "PCI-X", "AGP 8x", "M.2 Socket 1-DP", "M.2 Socket 1-SD", "M.2 Socket 2", "M.2 Socket 3", "MXM Type I", "MXM Type II", "MXM Type III", "MXM Type III-HE", "MXM Type IV", "MXM 3.0 Type A", "MXM 3.0 Type B", "PCI Express 2 SFF-8639 (U.2)", "PCI Express 3 SFF-8639 (U.2)", "PCI Express Mini 52-pin with bottom-side keep-outs", "PCI Express Mini 52-pin without bottom-side keep-outs", "PCI Express Mini 76-pin", "PCI Express 4 SFF-8639 (U.2)", "PCI Express 5 SFF-8639 (U.2)", "OCP NIC 3.0 Small Form Factor (SFF)", "OCP NIC 3.0 Large Form Factor (LFF)", "OCP NIC Prior to 3.0" /* 0x28 */ }; static const char *type_0x30[] = { "CXL FLexbus 1.0" /* 0x30 */ }; static const char *type_0xA0[] = { "PC-98/C20", /* 0xA0 */ "PC-98/C24", "PC-98/E", "PC-98/Local Bus", "PC-98/Card", "PCI Express", "PCI Express x1", "PCI Express x2", "PCI Express x4", "PCI Express x8", "PCI Express x16", "PCI Express 2", "PCI Express 2 x1", "PCI Express 2 x2", "PCI Express 2 x4", "PCI Express 2 x8", "PCI Express 2 x16", "PCI Express 3", "PCI Express 3 x1", "PCI Express 3 x2", "PCI Express 3 x4", "PCI Express 3 x8", "PCI Express 3 x16", out_of_spec, /* 0xB7 */ "PCI Express 4", "PCI Express 4 x1", "PCI Express 4 x2", "PCI Express 4 x4", "PCI Express 4 x8", "PCI Express 4 x16", "PCI Express 5", "PCI Express 5 x1", "PCI Express 5 x2", "PCI Express 5 x4", "PCI Express 5 x8", "PCI Express 5 x16", "PCI Express 6+", "EDSFF E1", "EDSFF E3" /* 0xC6 */ }; /* * Note to developers: when adding entries to these lists, check if * function dmi_slot_id below needs updating too. */ if (code >= 0x01 && code <= 0x28) return type[code - 0x01]; if (code == 0x30) return type_0x30[code - 0x30]; if (code >= 0xA0 && code <= 0xC6) return type_0xA0[code - 0xA0]; return out_of_spec; } static const char *dmi_slot_bus_width(u8 code) { /* 7.10.2 */ static const char *width[] = { "", /* 0x01, "Other" */ "", /* "Unknown" */ "8-bit ", "16-bit ", "32-bit ", "64-bit ", "128-bit ", "x1 ", "x2 ", "x4 ", "x8 ", "x12 ", "x16 ", "x32 " /* 0x0E */ }; if (code >= 0x01 && code <= 0x0E) return width[code - 0x01]; return out_of_spec; } static const char *dmi_slot_current_usage(u8 code) { /* 7.10.3 */ static const char *usage[] = { "Other", /* 0x01 */ "Unknown", "Available", "In Use", "Unavailable" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return usage[code - 0x01]; return out_of_spec; } static const char *dmi_slot_length(u8 code) { /* 7.10.4 */ static const char *length[] = { "Other", /* 0x01 */ "Unknown", "Short", "Long", "2.5\" drive form factor", "3.5\" drive form factor" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return length[code - 0x01]; return out_of_spec; } static void dmi_slot_id(u8 code1, u8 code2, u8 type) { /* 7.10.5 */ switch (type) { case 0x04: /* MCA */ pr_attr("ID", "%u", code1); break; case 0x05: /* EISA */ pr_attr("ID", "%u", code1); break; case 0x06: /* PCI */ case 0x0E: /* PCI */ case 0x0F: /* AGP */ case 0x10: /* AGP */ case 0x11: /* AGP */ case 0x12: /* PCI-X */ case 0x13: /* AGP */ case 0x1F: /* PCI Express 2 */ case 0x20: /* PCI Express 3 */ case 0x21: /* PCI Express Mini */ case 0x22: /* PCI Express Mini */ case 0x23: /* PCI Express Mini */ case 0xA5: /* PCI Express */ case 0xA6: /* PCI Express */ case 0xA7: /* PCI Express */ case 0xA8: /* PCI Express */ case 0xA9: /* PCI Express */ case 0xAA: /* PCI Express */ case 0xAB: /* PCI Express 2 */ case 0xAC: /* PCI Express 2 */ case 0xAD: /* PCI Express 2 */ case 0xAE: /* PCI Express 2 */ case 0xAF: /* PCI Express 2 */ case 0xB0: /* PCI Express 2 */ case 0xB1: /* PCI Express 3 */ case 0xB2: /* PCI Express 3 */ case 0xB3: /* PCI Express 3 */ case 0xB4: /* PCI Express 3 */ case 0xB5: /* PCI Express 3 */ case 0xB6: /* PCI Express 3 */ case 0xB8: /* PCI Express 4 */ case 0xB9: /* PCI Express 4 */ case 0xBA: /* PCI Express 4 */ case 0xBB: /* PCI Express 4 */ case 0xBC: /* PCI Express 4 */ case 0xBD: /* PCI Express 4 */ pr_attr("ID", "%u", code1); break; case 0x07: /* PCMCIA */ pr_attr("ID", "Adapter %u, Socket %u", code1, code2); break; } } static void dmi_slot_characteristics(const char *attr, u8 code1, u8 code2) { /* 7.10.6 */ static const char *characteristics1[] = { "5.0 V is provided", /* 1 */ "3.3 V is provided", "Opening is shared", "PC Card-16 is supported", "Cardbus is supported", "Zoom Video is supported", "Modem ring resume is supported" /* 7 */ }; /* 7.10.7 */ static const char *characteristics2[] = { "PME signal is supported", /* 0 */ "Hot-plug devices are supported", "SMBus signal is supported", "PCIe slot bifurcation is supported", "Async/surprise removal is supported", "Flexbus slot, CXL 1.0 capable", "Flexbus slot, CXL 2.0 capable" /* 6 */ }; if (code1 & (1 << 0)) pr_attr(attr, "Unknown"); else if ((code1 & 0xFE) == 0 && (code2 & 0x07) == 0) pr_attr(attr, "None"); else { int i; pr_list_start(attr, NULL); for (i = 1; i <= 7; i++) if (code1 & (1 << i)) pr_list_item("%s", characteristics1[i - 1]); for (i = 0; i <= 6; i++) if (code2 & (1 << i)) pr_list_item("%s", characteristics2[i]); pr_list_end(); } } static void dmi_slot_segment_bus_func(u16 code1, u8 code2, u8 code3) { /* 7.10.8 */ if (!(code1 == 0xFFFF && code2 == 0xFF && code3 == 0xFF)) pr_attr("Bus Address", "%04x:%02x:%02x.%x", code1, code2, code3 >> 3, code3 & 0x7); } static void dmi_slot_peers(u8 n, const u8 *data) { char attr[16]; int i; for (i = 1; i <= n; i++, data += 5) { sprintf(attr, "Peer Device %hhu", (u8)i); pr_attr(attr, "%04x:%02x:%02x.%x (Width %u)", WORD(data), data[2], data[3] >> 3, data[3] & 0x07, data[4]); } } /* * 7.11 On Board Devices Information (Type 10) */ static const char *dmi_on_board_devices_type(u8 code) { /* 7.11.1 and 7.42.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Video", "SCSI Controller", "Ethernet", "Token Ring", "Sound", "PATA Controller", "SATA Controller", "SAS Controller" /* 0x0A */ }; if (code >= 0x01 && code <= 0x0A) return type[code - 0x01]; return out_of_spec; } static void dmi_on_board_devices(const struct dmi_header *h) { u8 *p = h->data + 4; u8 count = (h->length - 0x04) / 2; int i; for (i = 0; i < count; i++) { if (count == 1) pr_handle_name("On Board Device Information"); else pr_handle_name("On Board Device %d Information", i + 1); pr_attr("Type", "%s", dmi_on_board_devices_type(p[2 * i] & 0x7F)); pr_attr("Status", "%s", p[2 * i] & 0x80 ? "Enabled" : "Disabled"); pr_attr("Description", "%s", dmi_string(h, p[2 * i + 1])); } } /* * 7.12 OEM Strings (Type 11) */ static void dmi_oem_strings(const struct dmi_header *h) { char attr[11]; u8 *p = h->data + 4; u8 count = p[0x00]; int i; for (i = 1; i <= count; i++) { sprintf(attr, "String %hhu", (u8)i); pr_attr(attr, "%s",dmi_string(h, i)); } } /* * 7.13 System Configuration Options (Type 12) */ static void dmi_system_configuration_options(const struct dmi_header *h) { char attr[11]; u8 *p = h->data + 4; u8 count = p[0x00]; int i; for (i = 1; i <= count; i++) { sprintf(attr, "Option %hhu", (u8)i); pr_attr(attr, "%s",dmi_string(h, i)); } } /* * 7.14 BIOS Language Information (Type 13) */ static void dmi_bios_languages(const struct dmi_header *h) { u8 *p = h->data + 4; u8 count = p[0x00]; int i; for (i = 1; i <= count; i++) pr_list_item("%s", dmi_string(h, i)); } static const char *dmi_bios_language_format(u8 code) { if (code & 0x01) return "Abbreviated"; else return "Long"; } /* * 7.15 Group Associations (Type 14) */ static void dmi_group_associations_items(u8 count, const u8 *p) { int i; for (i = 0; i < count; i++) { pr_list_item("0x%04X (%s)", WORD(p + 3 * i + 1), dmi_smbios_structure_type(p[3 * i])); } } /* * 7.16 System Event Log (Type 15) */ static const char *dmi_event_log_method(u8 code) { static const char *method[] = { "Indexed I/O, one 8-bit index port, one 8-bit data port", /* 0x00 */ "Indexed I/O, two 8-bit index ports, one 8-bit data port", "Indexed I/O, one 16-bit index port, one 8-bit data port", "Memory-mapped physical 32-bit address", "General-purpose non-volatile data functions" /* 0x04 */ }; if (code <= 0x04) return method[code]; if (code >= 0x80) return "OEM-specific"; return out_of_spec; } static void dmi_event_log_status(u8 code) { static const char *valid[] = { "Invalid", /* 0 */ "Valid" /* 1 */ }; static const char *full[] = { "Not Full", /* 0 */ "Full" /* 1 */ }; pr_attr("Status", "%s, %s", valid[(code >> 0) & 1], full[(code >> 1) & 1]); } static void dmi_event_log_address(u8 method, const u8 *p) { /* 7.16.3 */ switch (method) { case 0x00: case 0x01: case 0x02: pr_attr("Access Address", "Index 0x%04X, Data 0x%04X", WORD(p), WORD(p + 2)); break; case 0x03: pr_attr("Access Address", "0x%08X", DWORD(p)); break; case 0x04: pr_attr("Access Address", "0x%04X", WORD(p)); break; default: pr_attr("Access Address", "Unknown"); } } static const char *dmi_event_log_header_type(u8 code) { static const char *type[] = { "No Header", /* 0x00 */ "Type 1" /* 0x01 */ }; if (code <= 0x01) return type[code]; if (code >= 0x80) return "OEM-specific"; return out_of_spec; } static const char *dmi_event_log_descriptor_type(u8 code) { /* 7.16.6.1 */ static const char *type[] = { NULL, /* 0x00 */ "Single-bit ECC memory error", "Multi-bit ECC memory error", "Parity memory error", "Bus timeout", "I/O channel block", "Software NMI", "POST memory resize", "POST error", "PCI parity error", "PCI system error", "CPU failure", "EISA failsafe timer timeout", "Correctable memory log disabled", "Logging disabled", NULL, /* 0x0F */ "System limit exceeded", "Asynchronous hardware timer expired", "System configuration information", "Hard disk information", "System reconfigured", "Uncorrectable CPU-complex error", "Log area reset/cleared", "System boot" /* 0x17 */ }; if (code <= 0x17 && type[code] != NULL) return type[code]; if (code >= 0x80 && code <= 0xFE) return "OEM-specific"; if (code == 0xFF) return "End of log"; return out_of_spec; } static const char *dmi_event_log_descriptor_format(u8 code) { /* 7.16.6.2 */ static const char *format[] = { "None", /* 0x00 */ "Handle", "Multiple-event", "Multiple-event handle", "POST results bitmap", "System management", "Multiple-event system management" /* 0x06 */ }; if (code <= 0x06) return format[code]; if (code >= 0x80) return "OEM-specific"; return out_of_spec; } static void dmi_event_log_descriptors(u8 count, u8 len, const u8 *p) { /* 7.16.1 */ char attr[16]; int i; for (i = 0; i < count; i++) { if (len >= 0x02) { sprintf(attr, "Descriptor %d", i + 1); pr_attr(attr, "%s", dmi_event_log_descriptor_type(p[i * len])); sprintf(attr, "Data Format %d", i + 1); pr_attr(attr, "%s", dmi_event_log_descriptor_format(p[i * len + 1])); } } } /* * 7.17 Physical Memory Array (Type 16) */ static const char *dmi_memory_array_location(u8 code) { /* 7.17.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", "System Board Or Motherboard", "ISA Add-on Card", "EISA Add-on Card", "PCI Add-on Card", "MCA Add-on Card", "PCMCIA Add-on Card", "Proprietary Add-on Card", "NuBus" /* 0x0A */ }; static const char *location_0xA0[] = { "PC-98/C20 Add-on Card", /* 0xA0 */ "PC-98/C24 Add-on Card", "PC-98/E Add-on Card", "PC-98/Local Bus Add-on Card", "CXL Flexbus 1.0" /* 0xA4 */ }; if (code >= 0x01 && code <= 0x0A) return location[code - 0x01]; if (code >= 0xA0 && code <= 0xA4) return location_0xA0[code - 0xA0]; return out_of_spec; } static const char *dmi_memory_array_use(u8 code) { /* 7.17.2 */ static const char *use[] = { "Other", /* 0x01 */ "Unknown", "System Memory", "Video Memory", "Flash Memory", "Non-volatile RAM", "Cache Memory" /* 0x07 */ }; if (code >= 0x01 && code <= 0x07) return use[code - 0x01]; return out_of_spec; } static const char *dmi_memory_array_ec_type(u8 code) { /* 7.17.3 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "None", "Parity", "Single-bit ECC", "Multi-bit ECC", "CRC" /* 0x07 */ }; if (code >= 0x01 && code <= 0x07) return type[code - 0x01]; return out_of_spec; } static void dmi_memory_array_error_handle(u16 code) { if (code == 0xFFFE) pr_attr("Error Information Handle", "Not Provided"); else if (code == 0xFFFF) pr_attr("Error Information Handle", "No Error"); else pr_attr("Error Information Handle", "0x%04X", code); } /* * 7.18 Memory Device (Type 17) */ static void dmi_memory_device_width(const char *attr, u16 code) { /* * If no memory module is present, width may be 0 */ if (code == 0xFFFF || code == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "%u bits", code); } static void dmi_memory_device_size(u16 code) { if (code == 0) pr_attr("Size", "No Module Installed"); else if (code == 0xFFFF) pr_attr("Size", "Unknown"); else { u64 s = { .l = code & 0x7FFF }; if (!(code & 0x8000)) s.l <<= 10; dmi_print_memory_size("Size", s, 1); } } static char *dmi_memory_device_size_str(u16 code) { static char size[STR_LEN] = ""; if (code == 0) strncpy(size, "Empty", STR_LEN); else if (code == 0xFFFF) strncpy(size, "Unknown", STR_LEN); else { if (code & 0x8000) snprintf(size, STR_LEN, "%u @KB@", code & 0x7FFF); else snprintf(size, STR_LEN, "%u @MB@", code); } return size; } static void dmi_memory_device_extended_size(u32 code) { code &= 0x7FFFFFFFUL; /* * Use the greatest unit for which the exact value can be displayed * as an integer without rounding */ if (code & 0x3FFUL) pr_attr("Size", "%lu MB", (unsigned long)code); else if (code & 0xFFC00UL) pr_attr("Size", "%lu GB", (unsigned long)code >> 10); else pr_attr("Size", "%lu TB", (unsigned long)code >> 20); } static char *dmi_memory_device_extended_size_str(u32 code) { static char size[STR_LEN] = ""; code &= 0x7FFFFFFFUL; /* * Use the greatest unit for which the exact value can be displayed * as an integer without rounding */ if (code & 0x3FFUL) snprintf(size, STR_LEN, "%lu @MB@", (unsigned long)code); else if (code & 0xFFC00UL) snprintf(size, STR_LEN, "%lu @GB@", (unsigned long)code >> 10); else snprintf(size, STR_LEN, "%lu @TB@", (unsigned long)code >> 20); return size; } static void dmi_memory_voltage_value(const char *attr, u16 code) { if (code == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, code % 100 ? "%g V" : "%.1f V", (float)code / 1000); } static const char *dmi_memory_device_form_factor(u8 code) { /* 7.18.1 */ static const char *form_factor[] = { "Other", /* 0x01 */ "Unknown", "SIMM", "SIP", "Chip", "DIP", "ZIP", "Proprietary Card", "DIMM", "TSOP", "Row Of Chips", "RIMM", "SODIMM", "SRIMM", "FB-DIMM", "Die" /* 0x10 */ }; if (code >= 0x01 && code <= 0x10) return form_factor[code - 0x01]; return out_of_spec; } static void dmi_memory_device_set(u8 code) { if (code == 0) pr_attr("Set", "None"); else if (code == 0xFF) pr_attr("Set", "Unknown"); else pr_attr("Set", "%u", code); } static const char *dmi_memory_device_type(u8 code) { /* 7.18.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "DRAM", "EDRAM", "VRAM", "SRAM", "RAM", "ROM", "Flash", "EEPROM", "FEPROM", "EPROM", "CDRAM", "3DRAM", "SDRAM", "SGRAM", "RDRAM", "DDR", "DDR2", "DDR2 FB-DIMM", "Reserved", "Reserved", "Reserved", "DDR3", "FBD2", "DDR4", "LPDDR", "LPDDR2", "LPDDR3", "LPDDR4", "Logical non-volatile device", "HBM", "HBM2", "DDR5", "LPDDR5" /* 0x23 */ }; if (code >= 0x01 && code <= 0x23) return type[code - 0x01]; return out_of_spec; } static void dmi_memory_device_type_detail(u16 code) { /* 7.18.3 */ static const char *detail[] = { "Other", /* 1 */ "Unknown", "Fast-paged", "Static Column", "Pseudo-static", "RAMBus", "Synchronous", "CMOS", "EDO", "Window DRAM", "Cache DRAM", "Non-Volatile", "Registered (Buffered)", "Unbuffered (Unregistered)", "LRDIMM" /* 15 */ }; char list[172]; /* Update length if you touch the array above */ if ((code & 0xFFFE) == 0) pr_attr("Type Detail", "None"); else { int i, off = 0; list[0] = '\0'; for (i = 1; i <= 15; i++) if (code & (1 << i)) off += sprintf(list + off, off ? " %s" : "%s", detail[i - 1]); pr_attr("Type Detail", list); } } static void dmi_memory_device_speed(const char *attr, u16 code1, u32 code2) { if (code1 == 0xFFFF) { if (code2 == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "%lu MT/s", code2); } else { if (code1 == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "%u MT/s", code1); } } static void dmi_memory_technology(u8 code) { /* 7.18.6 */ static const char * const technology[] = { "Other", /* 0x01 */ "Unknown", "DRAM", "NVDIMM-N", "NVDIMM-F", "NVDIMM-P", "Intel Optane DC persistent memory" /* 0x07 */ }; if (code >= 0x01 && code <= 0x07) pr_attr("Memory Technology", "%s", technology[code - 0x01]); else pr_attr("Memory Technology", "%s", out_of_spec); } static void dmi_memory_operating_mode_capability(u16 code) { /* 7.18.7 */ static const char * const mode[] = { "Other", /* 1 */ "Unknown", "Volatile memory", "Byte-accessible persistent memory", "Block-accessible persistent memory" /* 5 */ }; char list[99]; /* Update length if you touch the array above */ if ((code & 0xFFFE) == 0) pr_attr("Memory Operating Mode Capability", "None"); else { int i, off = 0; list[0] = '\0'; for (i = 1; i <= 5; i++) if (code & (1 << i)) off += sprintf(list + off, off ? " %s" : "%s", mode[i - 1]); pr_attr("Memory Operating Mode Capability", list); } } static void dmi_memory_manufacturer_id(const char *attr, u16 code) { /* 7.18.8 */ /* 7.18.10 */ /* LSB is 7-bit Odd Parity number of continuation codes */ if (code == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "Bank %d, Hex 0x%02X", (code & 0x7F) + 1, code >> 8); } static void dmi_memory_product_id(const char *attr, u16 code) { /* 7.18.9 */ /* 7.18.11 */ if (code == 0) pr_attr(attr, "Unknown"); else pr_attr(attr, "0x%04X", code); } static void dmi_memory_size(const char *attr, u64 code) { /* 7.18.12 */ /* 7.18.13 */ if (code.h == 0xFFFFFFFF && code.l == 0xFFFFFFFF) pr_attr(attr, "Unknown"); else if (code.h == 0x0 && code.l == 0x0) pr_attr(attr, "None"); else dmi_print_memory_size(attr, code, 0); } /* * 7.19 32-bit Memory Error Information (Type 18) */ static const char *dmi_memory_error_type(u8 code) { /* 7.19.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "OK", "Bad Read", "Parity Error", "Single-bit Error", "Double-bit Error", "Multi-bit Error", "Nibble Error", "Checksum Error", "CRC Error", "Corrected Single-bit Error", "Corrected Error", "Uncorrectable Error" /* 0x0E */ }; if (code >= 0x01 && code <= 0x0E) return type[code - 0x01]; return out_of_spec; } static const char *dmi_memory_error_granularity(u8 code) { /* 7.19.2 */ static const char *granularity[] = { "Other", /* 0x01 */ "Unknown", "Device Level", "Memory Partition Level" /* 0x04 */ }; if (code >= 0x01 && code <= 0x04) return granularity[code - 0x01]; return out_of_spec; } static const char *dmi_memory_error_operation(u8 code) { /* 7.19.3 */ static const char *operation[] = { "Other", /* 0x01 */ "Unknown", "Read", "Write", "Partial Write" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return operation[code - 0x01]; return out_of_spec; } static void dmi_memory_error_syndrome(u32 code) { if (code == 0x00000000) pr_attr("Vendor Syndrome", "Unknown"); else pr_attr("Vendor Syndrome", "0x%08X", code); } static void dmi_32bit_memory_error_address(const char *attr, u32 code) { if (code == 0x80000000) pr_attr(attr, "Unknown"); else pr_attr(attr, "0x%08X", code); } /* * 7.20 Memory Array Mapped Address (Type 19) */ static void dmi_mapped_address_size(u32 code) { if (code == 0) pr_attr("Range Size", "Invalid"); else { u64 size; size.h = 0; size.l = code; dmi_print_memory_size("Range Size", size, 1); } } static void dmi_mapped_address_extended_size(u64 start, u64 end) { if (start.h == end.h && start.l == end.l) pr_attr("Range Size", "Invalid"); else dmi_print_memory_size("Range Size", u64_range(start, end), 0); } /* * 7.21 Memory Device Mapped Address (Type 20) */ static void dmi_mapped_address_row_position(u8 code) { if (code == 0) pr_attr("Partition Row Position", "%s", out_of_spec); else if (code == 0xFF) pr_attr("Partition Row Position", "Unknown"); else pr_attr("Partition Row Position", "%u", code); } static void dmi_mapped_address_interleave_position(u8 code) { if (code != 0) { if (code == 0xFF) pr_attr("Interleave Position", "Unknown"); else pr_attr("Interleave Position", "%u", code); } } static void dmi_mapped_address_interleaved_data_depth(u8 code) { if (code != 0) { if (code == 0xFF) pr_attr("Interleaved Data Depth", "Unknown"); else pr_attr("Interleaved Data Depth", "%u", code); } } /* * 7.22 Built-in Pointing Device (Type 21) */ static const char *dmi_pointing_device_type(u8 code) { /* 7.22.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Mouse", "Track Ball", "Track Point", "Glide Point", "Touch Pad", "Touch Screen", "Optical Sensor" /* 0x09 */ }; if (code >= 0x01 && code <= 0x09) return type[code - 0x01]; return out_of_spec; } static const char *dmi_pointing_device_interface(u8 code) { /* 7.22.2 */ static const char *interface[] = { "Other", /* 0x01 */ "Unknown", "Serial", "PS/2", "Infrared", "HIP-HIL", "Bus Mouse", "ADB (Apple Desktop Bus)" /* 0x08 */ }; static const char *interface_0xA0[] = { "Bus Mouse DB-9", /* 0xA0 */ "Bus Mouse Micro DIN", "USB" /* 0xA2 */ }; if (code >= 0x01 && code <= 0x08) return interface[code - 0x01]; if (code >= 0xA0 && code <= 0xA2) return interface_0xA0[code - 0xA0]; return out_of_spec; } /* * 7.23 Portable Battery (Type 22) */ static const char *dmi_battery_chemistry(u8 code) { /* 7.23.1 */ static const char *chemistry[] = { "Other", /* 0x01 */ "Unknown", "Lead Acid", "Nickel Cadmium", "Nickel Metal Hydride", "Lithium Ion", "Zinc Air", "Lithium Polymer" /* 0x08 */ }; if (code >= 0x01 && code <= 0x08) return chemistry[code - 0x01]; return out_of_spec; } static void dmi_battery_capacity(u16 code, u8 multiplier) { if (code == 0) pr_attr("Design Capacity", "Unknown"); else pr_attr("Design Capacity", "%u mWh", code * multiplier); } static void dmi_battery_voltage(u16 code) { if (code == 0) pr_attr("Design Voltage", "Unknown"); else pr_attr("Design Voltage", "%u mV", code); } static void dmi_battery_maximum_error(u8 code) { if (code == 0xFF) pr_attr("Maximum Error", "Unknown"); else pr_attr("Maximum Error", "%u%%", code); } /* * 7.24 System Reset (Type 23) */ /* code is assumed to be a 2-bit value */ static const char *dmi_system_reset_boot_option(u8 code) { static const char *option[] = { out_of_spec, /* 0x0 */ "Operating System", /* 0x1 */ "System Utilities", "Do Not Reboot" /* 0x3 */ }; return option[code]; } static void dmi_system_reset_count(const char *attr, u16 code) { if (code == 0xFFFF) pr_attr(attr, "Unknown"); else pr_attr(attr, "%u", code); } static void dmi_system_reset_timer(const char *attr, u16 code) { if (code == 0xFFFF) pr_attr(attr, "Unknown"); else pr_attr(attr, "%u min", code); } /* * 7.25 Hardware Security (Type 24) */ static const char *dmi_hardware_security_status(u8 code) { static const char *status[] = { "Disabled", /* 0x00 */ "Enabled", "Not Implemented", "Unknown" /* 0x03 */ }; return status[code]; } /* * 7.26 System Power Controls (Type 25) */ static void dmi_power_controls_power_on(const u8 *p) { char time[15]; int off = 0; /* 7.26.1 */ if (dmi_bcd_range(p[0], 0x01, 0x12)) off += sprintf(time + off, "%02X", p[0]); else off += sprintf(time + off, "*"); if (dmi_bcd_range(p[1], 0x01, 0x31)) off += sprintf(time + off, "-%02X", p[1]); else off += sprintf(time + off, "-*"); if (dmi_bcd_range(p[2], 0x00, 0x23)) off += sprintf(time + off, " %02X", p[2]); else off += sprintf(time + off, " *"); if (dmi_bcd_range(p[3], 0x00, 0x59)) off += sprintf(time + off, ":%02X", p[3]); else off += sprintf(time + off, ":*"); if (dmi_bcd_range(p[4], 0x00, 0x59)) off += sprintf(time + off, ":%02X", p[4]); else off += sprintf(time + off, ":*"); pr_attr("Next Scheduled Power-on", time); } /* * 7.27 Voltage Probe (Type 26) */ static const char *dmi_voltage_probe_location(u8 code) { /* 7.27.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", "Processor", "Disk", "Peripheral Bay", "System Management Module", "Motherboard", "Memory Module", "Processor Module", "Power Unit", "Add-in Card" /* 0x0B */ }; if (code >= 0x01 && code <= 0x0B) return location[code - 0x01]; return out_of_spec; } static const char *dmi_probe_status(u8 code) { /* 7.27.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", "OK", "Non-critical", "Critical", "Non-recoverable" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return status[code - 0x01]; return out_of_spec; } static void dmi_voltage_probe_value(const char *attr, u16 code) { if (code == 0x8000) pr_attr(attr, "Unknown"); else pr_attr(attr, "%.3f V", (float)(i16)code / 1000); } static void dmi_voltage_probe_resolution(u16 code) { if (code == 0x8000) pr_attr("Resolution", "Unknown"); else pr_attr("Resolution", "%.1f mV", (float)code / 10); } static void dmi_probe_accuracy(u16 code) { if (code == 0x8000) pr_attr("Accuracy", "Unknown"); else pr_attr("Accuracy", "%.2f%%", (float)code / 100); } /* * 7.28 Cooling Device (Type 27) */ static const char *dmi_cooling_device_type(u8 code) { /* 7.28.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Fan", "Centrifugal Blower", "Chip Fan", "Cabinet Fan", "Power Supply Fan", "Heat Pipe", "Integrated Refrigeration" /* 0x09 */ }; static const char *type_0x10[] = { "Active Cooling", /* 0x10 */ "Passive Cooling" /* 0x11 */ }; if (code >= 0x01 && code <= 0x09) return type[code - 0x01]; if (code >= 0x10 && code <= 0x11) return type_0x10[code - 0x10]; return out_of_spec; } static void dmi_cooling_device_speed(u16 code) { if (code == 0x8000) pr_attr("Nominal Speed", "Unknown Or Non-rotating"); else pr_attr("Nominal Speed", "%u rpm", code); } /* * 7.29 Temperature Probe (Type 28) */ static const char *dmi_temperature_probe_location(u8 code) { /* 7.29.1 */ static const char *location[] = { "Other", /* 0x01 */ "Unknown", "Processor", "Disk", "Peripheral Bay", "System Management Module", "Motherboard", "Memory Module", "Processor Module", "Power Unit", "Add-in Card", "Front Panel Board", "Back Panel Board", "Power System Board", "Drive Back Plane" /* 0x0F */ }; if (code >= 0x01 && code <= 0x0F) return location[code - 0x01]; return out_of_spec; } static void dmi_temperature_probe_value(const char *attr, u16 code) { if (code == 0x8000) pr_attr(attr, "Unknown"); else pr_attr(attr, "%.1f deg C", (float)(i16)code / 10); } static void dmi_temperature_probe_resolution(u16 code) { if (code == 0x8000) pr_attr("Resolution", "Unknown"); else pr_attr("Resolution", "%.3f deg C", (float)code / 1000); } /* * 7.30 Electrical Current Probe (Type 29) */ static void dmi_current_probe_value(const char *attr, u16 code) { if (code == 0x8000) pr_attr(attr, "Unknown"); else pr_attr(attr, "%.3f A", (float)(i16)code / 1000); } static void dmi_current_probe_resolution(u16 code) { if (code == 0x8000) pr_attr("Resolution", "Unknown"); else pr_attr("Resolution", "%.1f mA", (float)code / 10); } /* * 7.33 System Boot Information (Type 32) */ static const char *dmi_system_boot_status(u8 code) { static const char *status[] = { "No errors detected", /* 0 */ "No bootable media", "Operating system failed to load", "Firmware-detected hardware failure", "Operating system-detected hardware failure", "User-requested boot", "System security violation", "Previously-requested image", "System watchdog timer expired" /* 8 */ }; if (code <= 8) return status[code]; if (code >= 128 && code <= 191) return "OEM-specific"; if (code >= 192) return "Product-specific"; return out_of_spec; } /* * 7.34 64-bit Memory Error Information (Type 33) */ static void dmi_64bit_memory_error_address(const char *attr, u64 code) { if (code.h == 0x80000000 && code.l == 0x00000000) pr_attr(attr, "Unknown"); else pr_attr(attr, "0x%08X%08X", code.h, code.l); } /* * 7.35 Management Device (Type 34) */ /* * Several boards have a bug where some type 34 structures have their * length incorrectly set to 0x10 instead of 0x0B. This causes the * first 5 characters of the device name to be trimmed. It's easy to * check and fix, so do it, but warn. */ static void dmi_fixup_type_34(struct dmi_header *h, int display) { u8 *p = h->data; /* Make sure the hidden data is ASCII only */ if (h->length == 0x10 && is_printable(p + 0x0B, 0x10 - 0x0B)) { if (!(opt.flags & FLAG_QUIET) && display) fprintf(stderr, "Invalid entry length (%u). Fixed up to %u.\n", 0x10, 0x0B); h->length = 0x0B; } } static const char *dmi_management_device_type(u8 code) { /* 7.35.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "LM75", "LM78", "LM79", "LM80", "LM81", "ADM9240", "DS1780", "MAX1617", "GL518SM", "W83781D", "HT82H791" /* 0x0D */ }; if (code >= 0x01 && code <= 0x0D) return type[code - 0x01]; return out_of_spec; } static const char *dmi_management_device_address_type(u8 code) { /* 7.35.2 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "I/O Port", "Memory", "SMBus" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return type[code - 0x01]; return out_of_spec; } /* * 7.38 Memory Channel (Type 37) */ static const char *dmi_memory_channel_type(u8 code) { /* 7.38.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "RamBus", "SyncLink" /* 0x04 */ }; if (code >= 0x01 && code <= 0x04) return type[code - 0x01]; return out_of_spec; } static void dmi_memory_channel_devices(u8 count, const u8 *p) { char attr[18]; int i; for (i = 1; i <= count; i++) { sprintf(attr, "Device %hhu Load", (u8)i); pr_attr(attr, "%u", p[3 * i]); if (!(opt.flags & FLAG_QUIET)) { sprintf(attr, "Device %hhu Handle", (u8)i); pr_attr(attr, "0x%04X", WORD(p + 3 * i + 1)); } } } /* * 7.39 IPMI Device Information (Type 38) */ static const char *dmi_ipmi_interface_type(u8 code) { /* 7.39.1 and IPMI 2.0, appendix C1, table C1-2 */ static const char *type[] = { "Unknown", /* 0x00 */ "KCS (Keyboard Control Style)", "SMIC (Server Management Interface Chip)", "BT (Block Transfer)", "SSIF (SMBus System Interface)" /* 0x04 */ }; if (code <= 0x04) return type[code]; return out_of_spec; } static void dmi_ipmi_base_address(u8 type, const u8 *p, u8 lsb) { if (type == 0x04) /* SSIF */ { pr_attr("Base Address", "0x%02X (SMBus)", (*p) >> 1); } else { u64 address = QWORD(p); pr_attr("Base Address", "0x%08X%08X (%s)", address.h, (address.l & ~1) | lsb, address.l & 1 ? "I/O" : "Memory-mapped"); } } /* code is assumed to be a 2-bit value */ static const char *dmi_ipmi_register_spacing(u8 code) { /* IPMI 2.0, appendix C1, table C1-1 */ static const char *spacing[] = { "Successive Byte Boundaries", /* 0x00 */ "32-bit Boundaries", "16-byte Boundaries", /* 0x02 */ out_of_spec /* 0x03 */ }; return spacing[code]; } /* * 7.40 System Power Supply (Type 39) */ static void dmi_power_supply_power(u16 code) { if (code == 0x8000) pr_attr("Max Power Capacity", "Unknown"); else pr_attr("Max Power Capacity", "%u W", (unsigned int)code); } static const char *dmi_power_supply_type(u8 code) { /* 7.40.1 */ static const char *type[] = { "Other", /* 0x01 */ "Unknown", "Linear", "Switching", "Battery", "UPS", "Converter", "Regulator" /* 0x08 */ }; if (code >= 0x01 && code <= 0x08) return type[code - 0x01]; return out_of_spec; } static const char *dmi_power_supply_status(u8 code) { /* 7.40.1 */ static const char *status[] = { "Other", /* 0x01 */ "Unknown", "OK", "Non-critical", "Critical" /* 0x05 */ }; if (code >= 0x01 && code <= 0x05) return status[code - 0x01]; return out_of_spec; } static const char *dmi_power_supply_range_switching(u8 code) { /* 7.40.1 */ static const char *switching[] = { "Other", /* 0x01 */ "Unknown", "Manual", "Auto-switch", "Wide Range", "N/A" /* 0x06 */ }; if (code >= 0x01 && code <= 0x06) return switching[code - 0x01]; return out_of_spec; } /* * 7.41 Additional Information (Type 40) * * Proper support of this entry type would require redesigning a large part of * the code, so I am waiting to see actual implementations of it to decide * whether it's worth the effort. */ static void dmi_additional_info(const struct dmi_header *h) { u8 *p = h->data + 4; u8 count = *p++; u8 length; int i, offset = 5; for (i = 0; i < count; i++) { pr_handle_name("Additional Information %d", i + 1); /* Check for short entries */ if (h->length < offset + 1) break; length = p[0x00]; if (length < 0x05 || h->length < offset + length) break; pr_attr("Referenced Handle", "0x%04x", WORD(p + 0x01)); pr_attr("Referenced Offset", "0x%02x", p[0x03]); pr_attr("String", "%s", dmi_string(h, p[0x04])); switch (length - 0x05) { case 1: pr_attr("Value", "0x%02x", p[0x05]); break; case 2: pr_attr("Value", "0x%04x", WORD(p + 0x05)); break; case 4: pr_attr("Value", "0x%08x", DWORD(p + 0x05)); break; default: pr_attr("Value", "Unexpected size"); break; } p += length; offset += length; } } /* * 7.43 Management Controller Host Interface (Type 42) */ static const char *dmi_management_controller_host_type(u8 code) { /* DMTF DSP0239 (MCTP) version 1.1.0 */ static const char *type[] = { "KCS: Keyboard Controller Style", /* 0x02 */ "8250 UART Register Compatible", "16450 UART Register Compatible", "16550/16550A UART Register Compatible", "16650/16650A UART Register Compatible", "16750/16750A UART Register Compatible", "16850/16850A UART Register Compatible" /* 0x08 */ }; if (code >= 0x02 && code <= 0x08) return type[code - 0x02]; if (code <= 0x3F) return "MCTP"; if (code == 0x40) return "Network"; if (code == 0xF0) return "OEM"; return out_of_spec; } /* * 7.43.2: Protocol Record Types */ static const char *dmi_protocol_record_type(u8 type) { const char *protocol[] = { "Reserved", /* 0x0 */ "Reserved", "IPMI", "MCTP", "Redfish over IP", /* 0x4 */ }; if (type <= 0x4) return protocol[type]; if (type == 0xF0) return "OEM"; return out_of_spec; } /* * DSP0270: 8.6: Protocol IP Assignment types */ static const char *dmi_protocol_assignment_type(u8 type) { const char *assignment[] = { "Unknown", /* 0x0 */ "Static", "DHCP", "AutoConf", "Host Selected", /* 0x4 */ }; if (type <= 0x4) return assignment[type]; return out_of_spec; } /* * DSP0270: 8.6: Protocol IP Address type */ static const char *dmi_address_type(u8 type) { const char *addressformat[] = { "Unknown", /* 0x0 */ "IPv4", "IPv6", /* 0x2 */ }; if (type <= 0x2) return addressformat[type]; return out_of_spec; } /* * DSP0270: 8.6 Protocol Address decode */ static const char *dmi_address_decode(u8 *data, char *storage, u8 addrtype) { if (addrtype == 0x1) /* IPv4 */ return inet_ntop(AF_INET, data, storage, 64); if (addrtype == 0x2) /* IPv6 */ return inet_ntop(AF_INET6, data, storage, 64); return out_of_spec; } /* * DSP0270: 8.5: Parse the protocol record format */ static void dmi_parse_protocol_record(u8 *rec) { u8 rid; u8 rlen; u8 *rdata; char buf[64]; u8 assign_val; u8 addrtype; u8 hlen; const char *addrstr; const char *hname; char attr[38]; /* DSP0270: 8.5: Protocol Identifier */ rid = rec[0x0]; /* DSP0270: 8.5: Protocol Record Length */ rlen = rec[0x1]; /* DSP0270: 8.5: Protocol Record Data */ rdata = &rec[0x2]; pr_attr("Protocol ID", "%02x (%s)", rid, dmi_protocol_record_type(rid)); /* * Don't decode anything other than Redfish for now * Note 0x4 is Redfish over IP in 7.43.2 * and DSP0270: 8.5 */ if (rid != 0x4) return; /* * Ensure that the protocol record is of sufficient length * For RedFish that means rlen must be at least 91 bytes * other protcols will need different length checks */ if (rlen < 91) return; /* * DSP0270: 8.6: Redfish Over IP Service UUID * Note: ver is hardcoded to 0x311 here just for * convenience. It could get passed from the SMBIOS * header, but that's a lot of passing of pointers just * to get that info, and the only thing it is used for is * to determine the endianness of the field. Since we only * do this parsing on versions of SMBIOS after 3.1.1, and the * endianness of the field is always little after version 2.6.0 * we can just pick a sufficiently recent version here. */ dmi_system_uuid(pr_subattr, "Service UUID", &rdata[0], 0x311); /* * DSP0270: 8.6: Redfish Over IP Host IP Assignment Type * Note, using decimal indices here, as the DSP0270 * uses decimal, so as to make it more comparable */ assign_val = rdata[16]; pr_subattr("Host IP Assignment Type", "%s", dmi_protocol_assignment_type(assign_val)); /* DSP0270: 8.6: Redfish Over IP Host Address format */ addrtype = rdata[17]; addrstr = dmi_address_type(addrtype); pr_subattr("Host IP Address Format", "%s", addrstr); /* DSP0270: 8.6 IP Assignment types */ /* We only use the Host IP Address and Mask if the assignment type is static */ if (assign_val == 0x1 || assign_val == 0x3) { /* DSP0270: 8.6: the Host IPv[4|6] Address */ sprintf(attr, "%s Address", addrstr); pr_subattr(attr, "%s", dmi_address_decode(&rdata[18], buf, addrtype)); /* DSP0270: 8.6: Prints the Host IPv[4|6] Mask */ sprintf(attr, "%s Mask", addrstr); pr_subattr(attr, "%s", dmi_address_decode(&rdata[34], buf, addrtype)); } /* DSP0270: 8.6: Get the Redfish Service IP Discovery Type */ assign_val = rdata[50]; /* Redfish Service IP Discovery type mirrors Host IP Assignment type */ pr_subattr("Redfish Service IP Discovery Type", "%s", dmi_protocol_assignment_type(assign_val)); /* DSP0270: 8.6: Get the Redfish Service IP Address Format */ addrtype = rdata[51]; addrstr = dmi_address_type(addrtype); pr_subattr("Redfish Service IP Address Format", "%s", addrstr); if (assign_val == 0x1 || assign_val == 0x3) { u16 port; u32 vlan; /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Address */ sprintf(attr, "%s Redfish Service Address", addrstr); pr_subattr(attr, "%s", dmi_address_decode(&rdata[52], buf, addrtype)); /* DSP0270: 8.6: Prints the Redfish IPv[4|6] Service Mask */ sprintf(attr, "%s Redfish Service Mask", addrstr); pr_subattr(attr, "%s", dmi_address_decode(&rdata[68], buf, addrtype)); /* DSP0270: 8.6: Redfish vlan and port info */ port = WORD(&rdata[84]); vlan = DWORD(&rdata[86]); pr_subattr("Redfish Service Port", "%hu", port); pr_subattr("Redfish Service Vlan", "%u", vlan); } /* DSP0270: 8.6: Redfish host length and name */ hlen = rdata[90]; /* * DSP0270: 8.6: The length of the host string + 91 (the minimum * size of a protocol record) cannot exceed the record length * (rec[0x1]) */ hname = (const char *)&rdata[91]; if (hlen + 91 > rlen) { hname = out_of_spec; hlen = strlen(out_of_spec); } pr_subattr("Redfish Service Hostname", "%.*s", hlen, hname); } /* * DSP0270: 8.3: Device type ennumeration */ static const char *dmi_parse_device_type(u8 type) { const char *devname[] = { "USB", /* 0x2 */ "PCI/PCIe", /* 0x3 */ }; if (type >= 0x2 && type <= 0x3) return devname[type - 0x2]; if (type >= 0x80) return "OEM"; return out_of_spec; } static void dmi_parse_controller_structure(const struct dmi_header *h) { int i; u8 *data = h->data; /* Host interface type */ u8 type; /* Host Interface specific data length */ u8 len; u8 count; u32 total_read; /* * Minimum length of this struct is 0xB bytes */ if (h->length < 0xB) return; /* * Also need to ensure that the interface specific data length * plus the size of the structure to that point don't exceed * the defined length of the structure, or we will overrun its * bounds */ len = data[0x5]; total_read = len + 0x6; if (total_read > h->length) return; type = data[0x4]; pr_attr("Host Interface Type", "%s", dmi_management_controller_host_type(type)); /* * The following decodes are code for Network interface host types only * As defined in DSP0270 */ if (type != 0x40) return; if (len != 0) { /* DSP0270: 8.3 Table 2: Device Type */ type = data[0x6]; pr_attr("Device Type", "%s", dmi_parse_device_type(type)); if (type == 0x2 && len >= 5) { /* USB Device Type - need at least 6 bytes */ u8 *usbdata = &data[0x7]; /* USB Device Descriptor: idVendor */ pr_attr("idVendor", "0x%04x", WORD(&usbdata[0x0])); /* USB Device Descriptor: idProduct */ pr_attr("idProduct", "0x%04x", WORD(&usbdata[0x2])); /* * USB Serial number is here, but its useless, don't * bother decoding it */ } else if (type == 0x3 && len >= 9) { /* PCI Device Type - Need at least 8 bytes */ u8 *pcidata = &data[0x7]; /* PCI Device Descriptor: VendorID */ pr_attr("VendorID", "0x%04x", WORD(&pcidata[0x0])); /* PCI Device Descriptor: DeviceID */ pr_attr("DeviceID", "0x%04x", WORD(&pcidata[0x2])); /* PCI Device Descriptor: PCI SubvendorID */ pr_attr("SubVendorID", "0x%04x", WORD(&pcidata[0x4])); /* PCI Device Descriptor: PCI SubdeviceID */ pr_attr("SubDeviceID", "0x%04x", WORD(&pcidata[0x6])); } else if (type == 0x4 && len >= 5) { /* OEM Device Type - Need at least 4 bytes */ u8 *oemdata = &data[0x7]; /* OEM Device Descriptor: IANA */ pr_attr("Vendor ID", "0x%02x:0x%02x:0x%02x:0x%02x", oemdata[0x0], oemdata[0x1], oemdata[0x2], oemdata[0x3]); } /* Don't mess with unknown types for now */ } /* * DSP0270: 8.2 and 8.5: Protocol record count and protocol records * Move to the Protocol Count. */ data = &data[total_read]; /* * We've validated up to 0x6 + len bytes, but we need to validate * the next byte below, the count value. */ total_read++; if (total_read > h->length) { fprintf(stderr, "Total read length %d exceeds total structure length %d (handle 0x%04hx)\n", total_read, h->length, h->handle); return; } /* Get the protocol records count */ count = data[0x0]; if (count) { u8 *rec = &data[0x1]; for (i = 0; i < count; i++) { /* * Need to ensure that this record doesn't overrun * the total length of the type 42 struct. Note the +2 * is added for the two leading bytes of a protocol * record representing the type and length bytes. */ total_read += rec[1] + 2; if (total_read > h->length) { fprintf(stderr, "Total read length %d exceeds total structure length %d (handle 0x%04hx, record %d)\n", total_read, h->length, h->handle, i + 1); return; } dmi_parse_protocol_record(rec); /* * DSP0270: 8.6 * Each record is rec[1] bytes long, starting at the * data byte immediately following the length field. * That means we need to add the byte for the rec id, * the byte for the length field, and the value of the * length field itself. */ rec += rec[1] + 2; } } } /* * 7.44 TPM Device (Type 43) */ static void dmi_tpm_vendor_id(const u8 *p) { char vendor_id[5]; int i; /* ASCII filtering */ for (i = 0; i < 4 && p[i] != 0; i++) { if (p[i] < 32 || p[i] >= 127) vendor_id[i] = '.'; else vendor_id[i] = p[i]; } /* Terminate the string */ vendor_id[i] = '\0'; pr_attr("Vendor ID", "%s", vendor_id); } static void dmi_tpm_characteristics(u64 code) { /* 7.1.1 */ static const char *characteristics[] = { "TPM Device characteristics not supported", /* 2 */ "Family configurable via firmware update", "Family configurable via platform software support", "Family configurable via OEM proprietary mechanism" /* 5 */ }; int i; /* * This isn't very clear what this bit is supposed to mean */ if (code.l & (1 << 2)) { pr_list_item("%s", characteristics[0]); return; } for (i = 3; i <= 5; i++) if (code.l & (1 << i)) pr_list_item("%s", characteristics[i - 2]); } /* * Main */ static void dmi_decode(const struct dmi_header *h, u16 ver) { const u8 *data = h->data; /* * Note: DMI types 37 and 42 are untested */ switch (h->type) { case 0: /* 7.1 BIOS Information */ pr_handle_name("BIOS Information"); if (h->length < 0x12) break; pr_attr("Vendor", "%s", dmi_string(h, data[0x04])); pr_attr("Version", "%s", dmi_string(h, data[0x05])); pr_attr("Release Date", "%s", dmi_string(h, data[0x08])); /* * On IA-64, the BIOS base address will read 0 because * there is no BIOS. Skip the base address and the * runtime size in this case. */ if (WORD(data + 0x06) != 0) { pr_attr("Address", "0x%04X0", WORD(data + 0x06)); dmi_bios_runtime_size((0x10000 - WORD(data + 0x06)) << 4); } dmi_bios_rom_size(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18)); pr_list_start("Characteristics", NULL); dmi_bios_characteristics(QWORD(data + 0x0A)); pr_list_end(); if (h->length < 0x13) break; dmi_bios_characteristics_x1(data[0x12]); if (h->length < 0x14) break; dmi_bios_characteristics_x2(data[0x13]); if (h->length < 0x18) break; if (data[0x14] != 0xFF && data[0x15] != 0xFF) pr_attr("BIOS Revision", "%u.%u", data[0x14], data[0x15]); if (data[0x16] != 0xFF && data[0x17] != 0xFF) pr_attr("Firmware Revision", "%u.%u", data[0x16], data[0x17]); break; case 1: /* 7.2 System Information */ pr_handle_name("System Information"); if (h->length < 0x08) break; pr_attr("Manufacturer", "%s", dmi_string(h, data[0x04])); pr_attr("Product Name", "%s", dmi_string(h, data[0x05])); pr_attr("Version", "%s", dmi_string(h, data[0x06])); pr_attr("Serial Number", "%s", dmi_string(h, data[0x07])); if (h->length < 0x19) break; dmi_system_uuid(pr_attr, "UUID", data + 0x08, ver); pr_attr("Wake-up Type", "%s", dmi_system_wake_up_type(data[0x18])); if (h->length < 0x1B) break; pr_attr("SKU Number", "%s", dmi_string(h, data[0x19])); pr_attr("Family", "%s", dmi_string(h, data[0x1A])); break; case 2: /* 7.3 Base Board Information */ pr_handle_name("Base Board Information"); if (h->length < 0x08) break; pr_attr("Manufacturer", "%s", dmi_string(h, data[0x04])); pr_attr("Product Name", "%s", dmi_string(h, data[0x05])); pr_attr("Version", "%s", dmi_string(h, data[0x06])); pr_attr("Serial Number", "%s", dmi_string(h, data[0x07])); if (h->length < 0x09) break; pr_attr("Asset Tag", "%s", dmi_string(h, data[0x08])); if (h->length < 0x0A) break; dmi_base_board_features(data[0x09]); if (h->length < 0x0E) break; pr_attr("Location In Chassis", "%s", dmi_string(h, data[0x0A])); if (!(opt.flags & FLAG_QUIET)) pr_attr("Chassis Handle", "0x%04X", WORD(data + 0x0B)); pr_attr("Type", "%s", dmi_base_board_type(data[0x0D])); if (h->length < 0x0F) break; if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; if (!(opt.flags & FLAG_QUIET)) dmi_base_board_handles(data[0x0E], data + 0x0F); break; case 3: /* 7.4 Chassis Information */ pr_handle_name("Chassis Information"); if (h->length < 0x09) break; pr_attr("Manufacturer", "%s", dmi_string(h, data[0x04])); pr_attr("Type", "%s", dmi_chassis_type(data[0x05])); pr_attr("Lock", "%s", dmi_chassis_lock(data[0x05] >> 7)); pr_attr("Version", "%s", dmi_string(h, data[0x06])); pr_attr("Serial Number", "%s", dmi_string(h, data[0x07])); pr_attr("Asset Tag", "%s", dmi_string(h, data[0x08])); if (h->length < 0x0D) break; pr_attr("Boot-up State", "%s", dmi_chassis_state(data[0x09])); pr_attr("Power Supply State", "%s", dmi_chassis_state(data[0x0A])); pr_attr("Thermal State", "%s", dmi_chassis_state(data[0x0B])); pr_attr("Security Status", "%s", dmi_chassis_security_status(data[0x0C])); if (h->length < 0x11) break; pr_attr("OEM Information", "0x%08X", DWORD(data + 0x0D)); if (h->length < 0x13) break; dmi_chassis_height(data[0x11]); dmi_chassis_power_cords(data[0x12]); if (h->length < 0x15) break; if (h->length < 0x15 + data[0x13] * data[0x14]) break; dmi_chassis_elements(data[0x13], data[0x14], data + 0x15); if (h->length < 0x16 + data[0x13] * data[0x14]) break; pr_attr("SKU Number", "%s", dmi_string(h, data[0x15 + data[0x13] * data[0x14]])); break; case 4: /* 7.5 Processor Information */ pr_handle_name("Processor Information"); if (h->length < 0x1A) break; pr_attr("Socket Designation", "%s", dmi_string(h, data[0x04])); pr_attr("Type", "%s", dmi_processor_type(data[0x05])); pr_attr("Family", "%s", dmi_processor_family(h, ver)); pr_attr("Manufacturer", "%s", dmi_string(h, data[0x07])); dmi_processor_id(h); pr_attr("Version", "%s", dmi_string(h, data[0x10])); dmi_processor_voltage("Voltage", data[0x11]); dmi_processor_frequency("External Clock", data + 0x12); dmi_processor_frequency("Max Speed", data + 0x14); dmi_processor_frequency("Current Speed", data + 0x16); if (data[0x18] & (1 << 6)) pr_attr("Status", "Populated, %s", dmi_processor_status(data[0x18] & 0x07)); else pr_attr("Status", "Unpopulated"); pr_attr("Upgrade", "%s", dmi_processor_upgrade(data[0x19])); if (h->length < 0x20) break; if (!(opt.flags & FLAG_QUIET)) { dmi_processor_cache("L1 Cache Handle", WORD(data + 0x1A), "L1", ver); dmi_processor_cache("L2 Cache Handle", WORD(data + 0x1C), "L2", ver); dmi_processor_cache("L3 Cache Handle", WORD(data + 0x1E), "L3", ver); } if (h->length < 0x23) break; pr_attr("Serial Number", "%s", dmi_string(h, data[0x20])); pr_attr("Asset Tag", "%s", dmi_string(h, data[0x21])); pr_attr("Part Number", "%s", dmi_string(h, data[0x22])); if (h->length < 0x28) break; if (data[0x23] != 0) pr_attr("Core Count", "%u", h->length >= 0x2C && data[0x23] == 0xFF ? WORD(data + 0x2A) : data[0x23]); if (data[0x24] != 0) pr_attr("Core Enabled", "%u", h->length >= 0x2E && data[0x24] == 0xFF ? WORD(data + 0x2C) : data[0x24]); if (data[0x25] != 0) pr_attr("Thread Count", "%u", h->length >= 0x30 && data[0x25] == 0xFF ? WORD(data + 0x2E) : data[0x25]); dmi_processor_characteristics("Characteristics", WORD(data + 0x26)); break; case 5: /* 7.6 Memory Controller Information */ pr_handle_name("Memory Controller Information"); if (h->length < 0x0F) break; pr_attr("Error Detecting Method", "%s", dmi_memory_controller_ed_method(data[0x04])); dmi_memory_controller_ec_capabilities("Error Correcting Capabilities", data[0x05]); pr_attr("Supported Interleave", "%s", dmi_memory_controller_interleave(data[0x06])); pr_attr("Current Interleave", "%s", dmi_memory_controller_interleave(data[0x07])); pr_attr("Maximum Memory Module Size", "%u MB", 1 << data[0x08]); pr_attr("Maximum Total Memory Size", "%u MB", data[0x0E] * (1 << data[0x08])); dmi_memory_controller_speeds("Supported Speeds", WORD(data + 0x09)); dmi_memory_module_types("Supported Memory Types", WORD(data + 0x0B), 0); dmi_processor_voltage("Memory Module Voltage", data[0x0D]); if (h->length < 0x0F + data[0x0E] * sizeof(u16)) break; dmi_memory_controller_slots(data[0x0E], data + 0x0F); if (h->length < 0x10 + data[0x0E] * sizeof(u16)) break; dmi_memory_controller_ec_capabilities("Enabled Error Correcting Capabilities", data[0x0F + data[0x0E] * sizeof(u16)]); break; case 6: /* 7.7 Memory Module Information */ pr_handle_name("Memory Module Information"); if (h->length < 0x0C) break; pr_attr("Socket Designation", "%s", dmi_string(h, data[0x04])); dmi_memory_module_connections(data[0x05]); dmi_memory_module_speed("Current Speed", data[0x06]); dmi_memory_module_types("Type", WORD(data + 0x07), 1); dmi_memory_module_size("Installed Size", data[0x09]); dmi_memory_module_size("Enabled Size", data[0x0A]); dmi_memory_module_error(data[0x0B]); break; case 7: /* 7.8 Cache Information */ pr_handle_name("Cache Information"); if (h->length < 0x0F) break; pr_attr("Socket Designation", "%s", dmi_string(h, data[0x04])); pr_attr("Configuration", "%s, %s, Level %u", WORD(data + 0x05) & 0x0080 ? "Enabled" : "Disabled", WORD(data + 0x05) & 0x0008 ? "Socketed" : "Not Socketed", (WORD(data + 0x05) & 0x0007) + 1); pr_attr("Operational Mode", "%s", dmi_cache_mode((WORD(data + 0x05) >> 8) & 0x0003)); pr_attr("Location", "%s", dmi_cache_location((WORD(data + 0x05) >> 5) & 0x0003)); if (h->length >= 0x1B) dmi_cache_size_2("Installed Size", DWORD(data + 0x17)); else dmi_cache_size("Installed Size", WORD(data + 0x09)); if (h->length >= 0x17) dmi_cache_size_2("Maximum Size", DWORD(data + 0x13)); else dmi_cache_size("Maximum Size", WORD(data + 0x07)); dmi_cache_types("Supported SRAM Types", WORD(data + 0x0B), 0); dmi_cache_types("Installed SRAM Type", WORD(data + 0x0D), 1); if (h->length < 0x13) break; dmi_memory_module_speed("Speed", data[0x0F]); pr_attr("Error Correction Type", "%s", dmi_cache_ec_type(data[0x10])); pr_attr("System Type", "%s", dmi_cache_type(data[0x11])); pr_attr("Associativity", "%s", dmi_cache_associativity(data[0x12])); break; case 8: /* 7.9 Port Connector Information */ pr_handle_name("Port Connector Information"); if (h->length < 0x09) break; pr_attr("Internal Reference Designator", "%s", dmi_string(h, data[0x04])); pr_attr("Internal Connector Type", "%s", dmi_port_connector_type(data[0x05])); pr_attr("External Reference Designator", "%s", dmi_string(h, data[0x06])); pr_attr("External Connector Type", "%s", dmi_port_connector_type(data[0x07])); pr_attr("Port Type", "%s", dmi_port_type(data[0x08])); break; case 9: /* 7.10 System Slots */ pr_handle_name("System Slot Information"); if (h->length < 0x0C) break; pr_attr("Designation", "%s", dmi_string(h, data[0x04])); pr_attr("Type", "%s%s", dmi_slot_bus_width(data[0x06]), dmi_slot_type(data[0x05])); pr_attr("Current Usage", "%s", dmi_slot_current_usage(data[0x07])); pr_attr("Length", "%s", dmi_slot_length(data[0x08])); dmi_slot_id(data[0x09], data[0x0A], data[0x05]); if (h->length < 0x0D) dmi_slot_characteristics("Characteristics", data[0x0B], 0x00); else dmi_slot_characteristics("Characteristics", data[0x0B], data[0x0C]); if (h->length < 0x11) break; dmi_slot_segment_bus_func(WORD(data + 0x0D), data[0x0F], data[0x10]); if (h->length < 0x13) break; pr_attr("Data Bus Width", "%u", data[0x11]); pr_attr("Peer Devices", "%u", data[0x12]); if (h->length - 0x13 >= data[0x12] * 5) dmi_slot_peers(data[0x12], data + 0x13); break; case 10: /* 7.11 On Board Devices Information */ dmi_on_board_devices(h); break; case 11: /* 7.12 OEM Strings */ pr_handle_name("OEM Strings"); if (h->length < 0x05) break; dmi_oem_strings(h); break; case 12: /* 7.13 System Configuration Options */ pr_handle_name("System Configuration Options"); if (h->length < 0x05) break; dmi_system_configuration_options(h); break; case 13: /* 7.14 BIOS Language Information */ pr_handle_name("BIOS Language Information"); if (h->length < 0x16) break; if (ver >= 0x0201) { pr_attr("Language Description Format", "%s", dmi_bios_language_format(data[0x05])); } pr_list_start("Installable Languages", "%u", data[0x04]); dmi_bios_languages(h); pr_list_end(); pr_attr("Currently Installed Language", "%s", dmi_string(h, data[0x15])); break; case 14: /* 7.15 Group Associations */ pr_handle_name("Group Associations"); if (h->length < 0x05) break; pr_attr("Name", "%s", dmi_string(h, data[0x04])); pr_list_start("Items", "%u", (h->length - 0x05) / 3); dmi_group_associations_items((h->length - 0x05) / 3, data + 0x05); pr_list_end(); break; case 15: /* 7.16 System Event Log */ pr_handle_name("System Event Log"); if (h->length < 0x14) break; pr_attr("Area Length", "%u bytes", WORD(data + 0x04)); pr_attr("Header Start Offset", "0x%04X", WORD(data + 0x06)); if (WORD(data + 0x08) - WORD(data + 0x06)) pr_attr("Header Length", "%u byte%s", WORD(data + 0x08) - WORD(data + 0x06), WORD(data + 0x08) - WORD(data + 0x06) > 1 ? "s" : ""); pr_attr("Data Start Offset", "0x%04X", WORD(data + 0x08)); pr_attr("Access Method", "%s", dmi_event_log_method(data[0x0A])); dmi_event_log_address(data[0x0A], data + 0x10); dmi_event_log_status(data[0x0B]); pr_attr("Change Token", "0x%08X", DWORD(data + 0x0C)); if (h->length < 0x17) break; pr_attr("Header Format", "%s", dmi_event_log_header_type(data[0x14])); pr_attr("Supported Log Type Descriptors", "%u", data[0x15]); if (h->length < 0x17 + data[0x15] * data[0x16]) break; dmi_event_log_descriptors(data[0x15], data[0x16], data + 0x17); break; case 16: /* 7.17 Physical Memory Array */ pr_handle_name("Physical Memory Array"); if (h->length < 0x0F) break; pr_attr("Location", "%s", dmi_memory_array_location(data[0x04])); pr_attr("Use", "%s", dmi_memory_array_use(data[0x05])); pr_attr("Error Correction Type", "%s", dmi_memory_array_ec_type(data[0x06])); if (DWORD(data + 0x07) == 0x80000000) { if (h->length < 0x17) pr_attr("Maximum Capacity", "Unknown"); else dmi_print_memory_size("Maximum Capacity", QWORD(data + 0x0F), 0); } else { u64 capacity; capacity.h = 0; capacity.l = DWORD(data + 0x07); dmi_print_memory_size("Maximum Capacity", capacity, 1); } if (!(opt.flags & FLAG_QUIET)) dmi_memory_array_error_handle(WORD(data + 0x0B)); pr_attr("Number Of Devices", "%u", WORD(data + 0x0D)); break; case 17: /* 7.18 Memory Device */ pr_handle_name("Memory Device"); if (h->length < 0x15) break; if (!(opt.flags & FLAG_QUIET)) { pr_attr("Array Handle", "0x%04X", WORD(data + 0x04)); dmi_memory_array_error_handle(WORD(data + 0x06)); } dmi_memory_device_width("Total Width", WORD(data + 0x08)); dmi_memory_device_width("Data Width", WORD(data + 0x0A)); if (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) dmi_memory_device_extended_size(DWORD(data + 0x1C)); else dmi_memory_device_size(WORD(data + 0x0C)); pr_attr("Form Factor", "%s", dmi_memory_device_form_factor(data[0x0E])); dmi_memory_device_set(data[0x0F]); pr_attr("Locator", "%s", dmi_string(h, data[0x10])); pr_attr("Bank Locator", "%s", dmi_string(h, data[0x11])); pr_attr("Type", "%s", dmi_memory_device_type(data[0x12])); dmi_memory_device_type_detail(WORD(data + 0x13)); if (h->length < 0x17) break; /* If no module is present, the remaining fields are irrelevant */ if (WORD(data + 0x0C) == 0) break; dmi_memory_device_speed("Speed", WORD(data + 0x15), h->length >= 0x5C ? DWORD(data + 0x54) : 0); if (h->length < 0x1B) break; pr_attr("Manufacturer", "%s", dmi_string(h, data[0x17])); pr_attr("Serial Number", "%s", dmi_string(h, data[0x18])); pr_attr("Asset Tag", "%s", dmi_string(h, data[0x19])); pr_attr("Part Number", "%s", dmi_string(h, data[0x1A])); if (h->length < 0x1C) break; if ((data[0x1B] & 0x0F) == 0) pr_attr("Rank", "Unknown"); else pr_attr("Rank", "%u", data[0x1B] & 0x0F); if (h->length < 0x22) break; dmi_memory_device_speed("Configured Memory Speed", WORD(data + 0x20), h->length >= 0x5C ? DWORD(data + 0x58) : 0); if (h->length < 0x28) break; dmi_memory_voltage_value("Minimum Voltage", WORD(data + 0x22)); dmi_memory_voltage_value("Maximum Voltage", WORD(data + 0x24)); dmi_memory_voltage_value("Configured Voltage", WORD(data + 0x26)); if (h->length < 0x34) break; dmi_memory_technology(data[0x28]); dmi_memory_operating_mode_capability(WORD(data + 0x29)); pr_attr("Firmware Version", "%s", dmi_string(h, data[0x2B])); dmi_memory_manufacturer_id("Module Manufacturer ID", WORD(data + 0x2C)); dmi_memory_product_id("Module Product ID", WORD(data + 0x2E)); dmi_memory_manufacturer_id("Memory Subsystem Controller Manufacturer ID", WORD(data + 0x30)); dmi_memory_product_id("Memory Subsystem Controller Product ID", WORD(data + 0x32)); if (h->length < 0x3C) break; dmi_memory_size("Non-Volatile Size", QWORD(data + 0x34)); if (h->length < 0x44) break; dmi_memory_size("Volatile Size", QWORD(data + 0x3C)); if (h->length < 0x4C) break; dmi_memory_size("Cache Size", QWORD(data + 0x44)); if (h->length < 0x54) break; dmi_memory_size("Logical Size", QWORD(data + 0x4C)); break; case 18: /* 7.19 32-bit Memory Error Information */ pr_handle_name("32-bit Memory Error Information"); if (h->length < 0x17) break; pr_attr("Type", "%s", dmi_memory_error_type(data[0x04])); pr_attr("Granularity", "%s", dmi_memory_error_granularity(data[0x05])); pr_attr("Operation", "%s", dmi_memory_error_operation(data[0x06])); dmi_memory_error_syndrome(DWORD(data + 0x07)); dmi_32bit_memory_error_address("Memory Array Address", DWORD(data + 0x0B)); dmi_32bit_memory_error_address("Device Address", DWORD(data + 0x0F)); dmi_32bit_memory_error_address("Resolution", DWORD(data + 0x13)); break; case 19: /* 7.20 Memory Array Mapped Address */ pr_handle_name("Memory Array Mapped Address"); if (h->length < 0x0F) break; if (h->length >= 0x1F && DWORD(data + 0x04) == 0xFFFFFFFF) { u64 start, end; start = QWORD(data + 0x0F); end = QWORD(data + 0x17); pr_attr("Starting Address", "0x%08X%08Xk", start.h, start.l); pr_attr("Ending Address", "0x%08X%08Xk", end.h, end.l); dmi_mapped_address_extended_size(start, end); } else { pr_attr("Starting Address", "0x%08X%03X", DWORD(data + 0x04) >> 2, (DWORD(data + 0x04) & 0x3) << 10); pr_attr("Ending Address", "0x%08X%03X", DWORD(data + 0x08) >> 2, ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); } if (!(opt.flags & FLAG_QUIET)) pr_attr("Physical Array Handle", "0x%04X", WORD(data + 0x0C)); pr_attr("Partition Width", "%u", data[0x0E]); break; case 20: /* 7.21 Memory Device Mapped Address */ pr_handle_name("Memory Device Mapped Address"); if (h->length < 0x13) break; if (h->length >= 0x23 && DWORD(data + 0x04) == 0xFFFFFFFF) { u64 start, end; start = QWORD(data + 0x13); end = QWORD(data + 0x1B); pr_attr("Starting Address", "0x%08X%08Xk", start.h, start.l); pr_attr("Ending Address", "0x%08X%08Xk", end.h, end.l); dmi_mapped_address_extended_size(start, end); } else { pr_attr("Starting Address", "0x%08X%03X", DWORD(data + 0x04) >> 2, (DWORD(data + 0x04) & 0x3) << 10); pr_attr("Ending Address", "0x%08X%03X", DWORD(data + 0x08) >> 2, ((DWORD(data + 0x08) & 0x3) << 10) + 0x3FF); dmi_mapped_address_size(DWORD(data + 0x08) - DWORD(data + 0x04) + 1); } if (!(opt.flags & FLAG_QUIET)) { pr_attr("Physical Device Handle", "0x%04X", WORD(data + 0x0C)); pr_attr("Memory Array Mapped Address Handle", "0x%04X", WORD(data + 0x0E)); } dmi_mapped_address_row_position(data[0x10]); dmi_mapped_address_interleave_position(data[0x11]); dmi_mapped_address_interleaved_data_depth(data[0x12]); break; case 21: /* 7.22 Built-in Pointing Device */ pr_handle_name("Built-in Pointing Device"); if (h->length < 0x07) break; pr_attr("Type", "%s", dmi_pointing_device_type(data[0x04])); pr_attr("Interface", "%s", dmi_pointing_device_interface(data[0x05])); pr_attr("Buttons", "%u", data[0x06]); break; case 22: /* 7.23 Portable Battery */ pr_handle_name("Portable Battery"); if (h->length < 0x10) break; pr_attr("Location", "%s", dmi_string(h, data[0x04])); pr_attr("Manufacturer", "%s", dmi_string(h, data[0x05])); if (data[0x06] || h->length < 0x1A) pr_attr("Manufacture Date", "%s", dmi_string(h, data[0x06])); if (data[0x07] || h->length < 0x1A) pr_attr("Serial Number", "%s", dmi_string(h, data[0x07])); pr_attr("Name", "%s", dmi_string(h, data[0x08])); if (data[0x09] != 0x02 || h->length < 0x1A) pr_attr("Chemistry", "%s", dmi_battery_chemistry(data[0x09])); if (h->length < 0x16) dmi_battery_capacity(WORD(data + 0x0A), 1); else dmi_battery_capacity(WORD(data + 0x0A), data[0x15]); dmi_battery_voltage(WORD(data + 0x0C)); pr_attr("SBDS Version", "%s", dmi_string(h, data[0x0E])); dmi_battery_maximum_error(data[0x0F]); if (h->length < 0x1A) break; if (data[0x07] == 0) pr_attr("SBDS Serial Number", "%04X", WORD(data + 0x10)); if (data[0x06] == 0) pr_attr("SBDS Manufacture Date", "%u-%02u-%02u", 1980 + (WORD(data + 0x12) >> 9), (WORD(data + 0x12) >> 5) & 0x0F, WORD(data + 0x12) & 0x1F); if (data[0x09] == 0x02) pr_attr("SBDS Chemistry", "%s", dmi_string(h, data[0x14])); pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x16)); break; case 23: /* 7.24 System Reset */ pr_handle_name("System Reset"); if (h->length < 0x0D) break; pr_attr("Status", "%s", data[0x04] & (1 << 0) ? "Enabled" : "Disabled"); pr_attr("Watchdog Timer", "%s", data[0x04] & (1 << 5) ? "Present" : "Not Present"); if (!(data[0x04] & (1 << 5))) break; pr_attr("Boot Option", "%s", dmi_system_reset_boot_option((data[0x04] >> 1) & 0x3)); pr_attr("Boot Option On Limit", "%s", dmi_system_reset_boot_option((data[0x04] >> 3) & 0x3)); dmi_system_reset_count("Reset Count", WORD(data + 0x05)); dmi_system_reset_count("Reset Limit", WORD(data + 0x07)); dmi_system_reset_timer("Timer Interval", WORD(data + 0x09)); dmi_system_reset_timer("Timeout", WORD(data + 0x0B)); break; case 24: /* 7.25 Hardware Security */ pr_handle_name("Hardware Security"); if (h->length < 0x05) break; pr_attr("Power-On Password Status", "%s", dmi_hardware_security_status(data[0x04] >> 6)); pr_attr("Keyboard Password Status", "%s", dmi_hardware_security_status((data[0x04] >> 4) & 0x3)); pr_attr("Administrator Password Status", "%s", dmi_hardware_security_status((data[0x04] >> 2) & 0x3)); pr_attr("Front Panel Reset Status", "%s", dmi_hardware_security_status(data[0x04] & 0x3)); break; case 25: /* 7.26 System Power Controls */ pr_handle_name("System Power Controls"); if (h->length < 0x09) break; dmi_power_controls_power_on(data + 0x04); break; case 26: /* 7.27 Voltage Probe */ pr_handle_name("Voltage Probe"); if (h->length < 0x14) break; pr_attr("Description", "%s", dmi_string(h, data[0x04])); pr_attr("Location", "%s", dmi_voltage_probe_location(data[0x05] & 0x1f)); pr_attr("Status", "%s", dmi_probe_status(data[0x05] >> 5)); dmi_voltage_probe_value("Maximum Value", WORD(data + 0x06)); dmi_voltage_probe_value("Minimum Value", WORD(data + 0x08)); dmi_voltage_probe_resolution(WORD(data + 0x0A)); dmi_voltage_probe_value("Tolerance", WORD(data + 0x0C)); dmi_probe_accuracy(WORD(data + 0x0E)); pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x10)); if (h->length < 0x16) break; dmi_voltage_probe_value("Nominal Value", WORD(data + 0x14)); break; case 27: /* 7.28 Cooling Device */ pr_handle_name("Cooling Device"); if (h->length < 0x0C) break; if (!(opt.flags & FLAG_QUIET) && WORD(data + 0x04) != 0xFFFF) pr_attr("Temperature Probe Handle", "0x%04X", WORD(data + 0x04)); pr_attr("Type", "%s", dmi_cooling_device_type(data[0x06] & 0x1f)); pr_attr("Status", "%s", dmi_probe_status(data[0x06] >> 5)); if (data[0x07] != 0x00) pr_attr("Cooling Unit Group", "%u", data[0x07]); pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x08)); if (h->length < 0x0E) break; dmi_cooling_device_speed(WORD(data + 0x0C)); if (h->length < 0x0F) break; pr_attr("Description", "%s", dmi_string(h, data[0x0E])); break; case 28: /* 7.29 Temperature Probe */ pr_handle_name("Temperature Probe"); if (h->length < 0x14) break; pr_attr("Description", "%s", dmi_string(h, data[0x04])); pr_attr("Location", "%s", dmi_temperature_probe_location(data[0x05] & 0x1F)); pr_attr("Status", "%s", dmi_probe_status(data[0x05] >> 5)); dmi_temperature_probe_value("Maximum Value", WORD(data + 0x06)); dmi_temperature_probe_value("Minimum Value", WORD(data + 0x08)); dmi_temperature_probe_resolution(WORD(data + 0x0A)); dmi_temperature_probe_value("Tolerance", WORD(data + 0x0C)); dmi_probe_accuracy(WORD(data + 0x0E)); pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x10)); if (h->length < 0x16) break; dmi_temperature_probe_value("Nominal Value", WORD(data + 0x14)); break; case 29: /* 7.30 Electrical Current Probe */ pr_handle_name("Electrical Current Probe"); if (h->length < 0x14) break; pr_attr("Description", "%s", dmi_string(h, data[0x04])); pr_attr("Location", "%s", dmi_voltage_probe_location(data[5] & 0x1F)); pr_attr("Status", "%s", dmi_probe_status(data[0x05] >> 5)); dmi_current_probe_value("Maximum Value", WORD(data + 0x06)); dmi_current_probe_value("Minimum Value", WORD(data + 0x08)); dmi_current_probe_resolution(WORD(data + 0x0A)); dmi_current_probe_value("Tolerance", WORD(data + 0x0C)); dmi_probe_accuracy(WORD(data + 0x0E)); pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x10)); if (h->length < 0x16) break; dmi_current_probe_value("Nominal Value", WORD(data + 0x14)); break; case 30: /* 7.31 Out-of-band Remote Access */ pr_handle_name("Out-of-band Remote Access"); if (h->length < 0x06) break; pr_attr("Manufacturer Name", "%s", dmi_string(h, data[0x04])); pr_attr("Inbound Connection", "%s", data[0x05] & (1 << 0) ? "Enabled" : "Disabled"); pr_attr("Outbound Connection", "%s", data[0x05] & (1 << 1) ? "Enabled" : "Disabled"); break; case 31: /* 7.32 Boot Integrity Services Entry Point */ pr_handle_name("Boot Integrity Services Entry Point"); if (h->length < 0x1C) break; pr_attr("Checksum", "%s", checksum(data, h->length) ? "OK" : "Invalid"); pr_attr("16-bit Entry Point Address", "%04X:%04X", DWORD(data + 0x08) >> 16, DWORD(data + 0x08) & 0xFFFF); pr_attr("32-bit Entry Point Address", "0x%08X", DWORD(data + 0x0C)); break; case 32: /* 7.33 System Boot Information */ pr_handle_name("System Boot Information"); if (h->length < 0x0B) break; pr_attr("Status", "%s", dmi_system_boot_status(data[0x0A])); break; case 33: /* 7.34 64-bit Memory Error Information */ pr_handle_name("64-bit Memory Error Information"); if (h->length < 0x1F) break; pr_attr("Type", "%s", dmi_memory_error_type(data[0x04])); pr_attr("Granularity", "%s", dmi_memory_error_granularity(data[0x05])); pr_attr("Operation", "%s", dmi_memory_error_operation(data[0x06])); dmi_memory_error_syndrome(DWORD(data + 0x07)); dmi_64bit_memory_error_address("Memory Array Address", QWORD(data + 0x0B)); dmi_64bit_memory_error_address("Device Address", QWORD(data + 0x13)); dmi_32bit_memory_error_address("Resolution", DWORD(data + 0x1B)); break; case 34: /* 7.35 Management Device */ pr_handle_name("Management Device"); if (h->length < 0x0B) break; pr_attr("Description", "%s", dmi_string(h, data[0x04])); pr_attr("Type", "%s", dmi_management_device_type(data[0x05])); pr_attr("Address", "0x%08X", DWORD(data + 0x06)); pr_attr("Address Type", "%s", dmi_management_device_address_type(data[0x0A])); break; case 35: /* 7.36 Management Device Component */ pr_handle_name("Management Device Component"); if (h->length < 0x0B) break; pr_attr("Description", "%s", dmi_string(h, data[0x04])); if (!(opt.flags & FLAG_QUIET)) { pr_attr("Management Device Handle", "0x%04X", WORD(data + 0x05)); pr_attr("Component Handle", "0x%04X", WORD(data + 0x07)); if (WORD(data + 0x09) != 0xFFFF) pr_attr("Threshold Handle", "0x%04X", WORD(data + 0x09)); } break; case 36: /* 7.37 Management Device Threshold Data */ pr_handle_name("Management Device Threshold Data"); if (h->length < 0x10) break; if (WORD(data + 0x04) != 0x8000) pr_attr("Lower Non-critical Threshold", "%d", (i16)WORD(data + 0x04)); if (WORD(data + 0x06) != 0x8000) pr_attr("Upper Non-critical Threshold", "%d", (i16)WORD(data + 0x06)); if (WORD(data + 0x08) != 0x8000) pr_attr("Lower Critical Threshold", "%d", (i16)WORD(data + 0x08)); if (WORD(data + 0x0A) != 0x8000) pr_attr("Upper Critical Threshold", "%d", (i16)WORD(data + 0x0A)); if (WORD(data + 0x0C) != 0x8000) pr_attr("Lower Non-recoverable Threshold", "%d", (i16)WORD(data + 0x0C)); if (WORD(data + 0x0E) != 0x8000) pr_attr("Upper Non-recoverable Threshold", "%d", (i16)WORD(data + 0x0E)); break; case 37: /* 7.38 Memory Channel */ pr_handle_name("Memory Channel"); if (h->length < 0x07) break; pr_attr("Type", "%s", dmi_memory_channel_type(data[0x04])); pr_attr("Maximal Load", "%u", data[0x05]); pr_attr("Devices", "%u", data[0x06]); if (h->length < 0x07 + 3 * data[0x06]) break; dmi_memory_channel_devices(data[0x06], data + 0x07); break; case 38: /* 7.39 IPMI Device Information */ /* * We use the word "Version" instead of "Revision", conforming to * the IPMI specification. */ pr_handle_name("IPMI Device Information"); if (h->length < 0x10) break; pr_attr("Interface Type", "%s", dmi_ipmi_interface_type(data[0x04])); pr_attr("Specification Version", "%u.%u", data[0x05] >> 4, data[0x05] & 0x0F); pr_attr("I2C Slave Address", "0x%02x", data[0x06] >> 1); if (data[0x07] != 0xFF) pr_attr("NV Storage Device Address", "%u", data[0x07]); else pr_attr("NV Storage Device", "Not Present"); dmi_ipmi_base_address(data[0x04], data + 0x08, h->length < 0x11 ? 0 : (data[0x10] >> 4) & 1); if (h->length < 0x12) break; if (data[0x04] != 0x04) { pr_attr("Register Spacing", "%s", dmi_ipmi_register_spacing(data[0x10] >> 6)); if (data[0x10] & (1 << 3)) { pr_attr("Interrupt Polarity", "%s", data[0x10] & (1 << 1) ? "Active High" : "Active Low"); pr_attr("Interrupt Trigger Mode", "%s", data[0x10] & (1 << 0) ? "Level" : "Edge"); } } if (data[0x11] != 0x00) { pr_attr("Interrupt Number", "%u", data[0x11]); } break; case 39: /* 7.40 System Power Supply */ pr_handle_name("System Power Supply"); if (h->length < 0x10) break; if (data[0x04] != 0x00) pr_attr("Power Unit Group", "%u", data[0x04]); pr_attr("Location", "%s", dmi_string(h, data[0x05])); pr_attr("Name", "%s", dmi_string(h, data[0x06])); pr_attr("Manufacturer", "%s", dmi_string(h, data[0x07])); pr_attr("Serial Number", "%s", dmi_string(h, data[0x08])); pr_attr("Asset Tag", "%s", dmi_string(h, data[0x09])); pr_attr("Model Part Number", "%s", dmi_string(h, data[0x0A])); pr_attr("Revision", "%s", dmi_string(h, data[0x0B])); dmi_power_supply_power(WORD(data + 0x0C)); if (WORD(data + 0x0E) & (1 << 1)) pr_attr("Status", "Present, %s", dmi_power_supply_status((WORD(data + 0x0E) >> 7) & 0x07)); else pr_attr("Status", "Not Present"); pr_attr("Type", "%s", dmi_power_supply_type((WORD(data + 0x0E) >> 10) & 0x0F)); pr_attr("Input Voltage Range Switching", "%s", dmi_power_supply_range_switching((WORD(data + 0x0E) >> 3) & 0x0F)); pr_attr("Plugged", "%s", WORD(data + 0x0E) & (1 << 2) ? "No" : "Yes"); pr_attr("Hot Replaceable", "%s", WORD(data + 0x0E) & (1 << 0) ? "Yes" : "No"); if (h->length < 0x16) break; if (!(opt.flags & FLAG_QUIET)) { if (WORD(data + 0x10) != 0xFFFF) pr_attr("Input Voltage Probe Handle", "0x%04X", WORD(data + 0x10)); if (WORD(data + 0x12) != 0xFFFF) pr_attr("Cooling Device Handle", "0x%04X", WORD(data + 0x12)); if (WORD(data + 0x14) != 0xFFFF) pr_attr("Input Current Probe Handle", "0x%04X", WORD(data + 0x14)); } break; case 40: /* 7.41 Additional Information */ if (h->length < 0x0B) break; if (opt.flags & FLAG_QUIET) return; dmi_additional_info(h); break; case 41: /* 7.42 Onboard Device Extended Information */ pr_handle_name("Onboard Device"); if (h->length < 0x0B) break; pr_attr("Reference Designation", "%s", dmi_string(h, data[0x04])); pr_attr("Type", "%s", dmi_on_board_devices_type(data[0x05] & 0x7F)); pr_attr("Status", "%s", data[0x05] & 0x80 ? "Enabled" : "Disabled"); pr_attr("Type Instance", "%u", data[0x06]); dmi_slot_segment_bus_func(WORD(data + 0x07), data[0x09], data[0x0A]); break; case 42: /* 7.43 Management Controller Host Interface */ pr_handle_name("Management Controller Host Interface"); if (ver < 0x0302) { if (h->length < 0x05) break; pr_attr("Interface Type", "%s", dmi_management_controller_host_type(data[0x04])); /* * There you have a type-dependent, variable-length * part in the middle of the structure, with no * length specifier, so no easy way to decode the * common, final part of the structure. What a pity. */ if (h->length < 0x09) break; if (data[0x04] == 0xF0) /* OEM */ { pr_attr("Vendor ID", "0x%02X%02X%02X%02X", data[0x05], data[0x06], data[0x07], data[0x08]); } } else dmi_parse_controller_structure(h); break; case 43: /* 7.44 TPM Device */ pr_handle_name("TPM Device"); if (h->length < 0x1B) break; dmi_tpm_vendor_id(data + 0x04); pr_attr("Specification Version", "%d.%d", data[0x08], data[0x09]); switch (data[0x08]) { case 0x01: /* * We skip the first 2 bytes, which are * redundant with the above, and uncoded * in a silly way. */ pr_attr("Firmware Revision", "%u.%u", data[0x0C], data[0x0D]); break; case 0x02: pr_attr("Firmware Revision", "%u.%u", DWORD(data + 0x0A) >> 16, DWORD(data + 0x0A) & 0xFFFF); /* * We skip the next 4 bytes, as their * format is not standardized and their * usefulness seems limited anyway. */ break; } pr_attr("Description", "%s", dmi_string(h, data[0x12])); pr_list_start("Characteristics", NULL); dmi_tpm_characteristics(QWORD(data + 0x13)); pr_list_end(); if (h->length < 0x1F) break; pr_attr("OEM-specific Information", "0x%08X", DWORD(data + 0x1B)); break; case 126: /* 7.44 Inactive */ pr_handle_name("Inactive"); break; case 127: /* 7.45 End Of Table */ pr_handle_name("End Of Table"); break; default: if (dmi_decode_oem(h)) break; if (opt.flags & FLAG_QUIET) return; pr_handle_name("%s Type", h->type >= 128 ? "OEM-specific" : "Unknown"); dmi_dump(h); } pr_sep(); } static void dmi_decode_cpux(const struct dmi_header *h) { const u8 *data = h->data; switch (h->type) { case 0: /* 7.1 BIOS Information */ snprintf(cpux_data->motherboard[BRAND], MAXSTR, "%s", dmi_string(h, data[0x04])); snprintf(cpux_data->motherboard[BIOSVERSION], MAXSTR, "%s", dmi_string(h, data[0x05])); snprintf(cpux_data->motherboard[DATE], MAXSTR, "%s", dmi_string(h, data[0x08])); snprintf(cpux_data->motherboard[ROMSIZE], MAXSTR, "%s / %s", dmi_bios_runtime_size_str((0x10000 - WORD(data + 0x06)) << 4), dmi_bios_rom_size_str(data[0x09], h->length < 0x1A ? 16 : WORD(data + 0x18))); break; case 2: /* 7.3 Base Board Information */ snprintf(cpux_data->motherboard[MANUFACTURER], MAXSTR, "%s", dmi_string(h, data[0x04])); snprintf(cpux_data->motherboard[MBMODEL], MAXSTR, "%s", dmi_string(h, data[0x05])); snprintf(cpux_data->motherboard[REVISION], MAXSTR, "%s", dmi_string(h, data[0x06])); break; case 4: /* 7.5 Processor Information */ cpux_data->bus_freq = (double) WORD(data + 0x12); snprintf(cpux_data->cpu_package, MAXSTR, "%s", dmi_string(h, data[0x04])); break; case 17: /* 7.18 Memory Device */ if(cpux_data->dimm_count < LASTMEMORY) { if((strstr(dmi_string(h, data[0x17]), "Empty") != NULL) || (strstr(dmi_string(h, data[0x17]), "Not Specified") != NULL) || (WORD(data + 0x0C) == 0)) snprintf(cpux_data->memory[cpux_data->dimm_count], MAXSTR, "- - - - - - - - - - - - - - - - - - -"); else { memset(cpux_data->memory[cpux_data->dimm_count], '\0', MAXSTR); if(h->length >= 0x1B) { const char *manufacturer = dmi_string(h, data[0x17]); const char *part_number = dmi_string(h, data[0x1A]); if((strlen(manufacturer) > 0) || (strlen(part_number) > 0)) snprintf(cpux_data->memory[cpux_data->dimm_count], MAXSTR, "%s %s, ", manufacturer, part_number); } char specs[MAXSTR]; char *size = (h->length >= 0x20 && WORD(data + 0x0C) == 0x7FFF) ? dmi_memory_device_extended_size_str(DWORD(data + 0x1C)) : dmi_memory_device_size_str(WORD(data + 0x0C)); snprintf(specs, MAXSTR, "%s @ %u MHz (%s %s)", size, (WORD(data + 0x15)), dmi_memory_device_form_factor(data[0x0E]), dmi_memory_device_type(data[0x12])); strncat(cpux_data->memory[cpux_data->dimm_count], specs, MAXSTR); } cpux_data->dimm_count++; } break; default: MSG_ERROR("internal error in dmi_decode_cpux(): type %u is not supported.", h->type); break; } } static void to_dmi_header(struct dmi_header *h, u8 *data) { h->type = data[0]; h->length = data[1]; h->handle = WORD(data + 2); h->data = data; } static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver) { int key; u8 offset = opt.string->offset; if (opt.string->type == 11) /* OEM strings */ { if (h->length < 5 || offset > data[4]) { fprintf(stderr, "No OEM string number %u\n", offset); return; } if (offset) printf("%s\n", dmi_string(h, offset)); else printf("%u\n", data[4]); /* count */ return; } if (offset >= h->length) return; key = (opt.string->type << 8) | offset; switch (key) { case 0x015: /* -s bios-revision */ if (data[key - 1] != 0xFF && data[key] != 0xFF) printf("%u.%u\n", data[key - 1], data[key]); break; case 0x017: /* -s firmware-revision */ if (data[key - 1] != 0xFF && data[key] != 0xFF) printf("%u.%u\n", data[key - 1], data[key]); break; case 0x108: dmi_system_uuid(NULL, NULL, data + offset, ver); break; case 0x305: printf("%s\n", dmi_chassis_type(data[offset])); break; case 0x406: printf("%s\n", dmi_processor_family(h, ver)); break; case 0x416: dmi_processor_frequency(NULL, data + offset); break; default: printf("%s\n", dmi_string(h, data[offset])); } } static void dmi_table_dump(const u8 *buf, u32 len) { if (!(opt.flags & FLAG_QUIET)) pr_comment("Writing %d bytes to %s.", len, opt.dumpfile); write_dump(32, len, buf, opt.dumpfile, 0); } static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags) { u8 *data; int i = 0; data = buf; while ((i < num || !num) && data + 4 <= buf + len) /* 4 is the length of an SMBIOS structure header */ { u8 *next; struct dmi_header h; int display; to_dmi_header(&h, data); display = ((opt.type == NULL || opt.type[h.type]) && (opt.handle == ~0U || opt.handle == h.handle) && !((opt.flags & FLAG_QUIET) && (h.type == 126 || h.type == 127)) && !opt.string); /* * If a short entry is found (less than 4 bytes), not only it * is invalid, but we cannot reliably locate the next entry. * Better stop at this point, and let the user know his/her * table is broken. */ if (h.length < 4) { if (!(opt.flags & FLAG_QUIET)) { fprintf(stderr, "Invalid entry length (%u). DMI table " "is broken! Stop.\n\n", (unsigned int)h.length); opt.flags |= FLAG_QUIET; } break; } i++; /* In quiet mode, stop decoding at end of table marker */ if ((opt.flags & FLAG_QUIET) && h.type == 127) break; if (display && (!(opt.flags & FLAG_QUIET) || (opt.flags & FLAG_DUMP))) pr_handle(&h); /* Look for the next handle */ next = data + h.length; while ((unsigned long)(next - buf + 1) < len && (next[0] != 0 || next[1] != 0)) next++; next += 2; /* Make sure the whole structure fits in the table */ if ((unsigned long)(next - buf) > len) { if (display && !(opt.flags & FLAG_QUIET)) pr_struct_err(""); pr_sep(); data = next; break; } /* assign vendor for vendor-specific decodes later */ if (h.type == 1 && h.length >= 6) dmi_set_vendor(_dmi_string(&h, data[0x04], 0), _dmi_string(&h, data[0x05], 0)); /* Fixup a common mistake */ if (h.type == 34) dmi_fixup_type_34(&h, display); if (display) { if (opt.flags & FLAG_DUMP) { dmi_dump(&h); pr_sep(); } else { if(cpux_data != NULL) dmi_decode_cpux(&h); else dmi_decode(&h, ver); } } else if (opt.string != NULL && opt.string->type == h.type) dmi_table_string(&h, data, ver); data = next; /* SMBIOS v3 requires stopping at this marker */ if (h.type == 127 && (flags & FLAG_STOP_AT_EOT)) break; } /* * SMBIOS v3 64-bit entry points do not announce a structures count, * and only indicate a maximum size for the table. */ if (!(opt.flags & FLAG_QUIET)) { if (num && i != num) fprintf(stderr, "Wrong DMI structures count: %d announced, " "only %d decoded.\n", num, i); if ((unsigned long)(data - buf) > len || (num && (unsigned long)(data - buf) < len)) fprintf(stderr, "Wrong DMI structures length: %u bytes " "announced, structures occupy %lu bytes.\n", len, (unsigned long)(data - buf)); } } static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem, u32 flags) { u8 *buf; if (ver > SUPPORTED_SMBIOS_VER && !(opt.flags & FLAG_QUIET)) { pr_comment("SMBIOS implementations newer than version %u.%u.%u are not", SUPPORTED_SMBIOS_VER >> 16, (SUPPORTED_SMBIOS_VER >> 8) & 0xFF, SUPPORTED_SMBIOS_VER & 0xFF); pr_comment("fully supported by this version of dmidecode."); } if (!(opt.flags & FLAG_QUIET)) { if (opt.type == NULL) { if (num) pr_info("%u structures occupying %u bytes.", num, len); if (!(opt.flags & FLAG_FROM_DUMP)) pr_info("Table at 0x%08llX.", (unsigned long long)base); } pr_sep(); } if ((flags & FLAG_NO_FILE_OFFSET) || (opt.flags & FLAG_FROM_DUMP)) { /* * When reading from sysfs or from a dump file, the file may be * shorter than announced. For SMBIOS v3 this is expcted, as we * only know the maximum table size, not the actual table size. * For older implementations (and for SMBIOS v3 too), this * would be the result of the kernel truncating the table on * parse error. */ size_t size = len; buf = read_file(flags & FLAG_NO_FILE_OFFSET ? 0 : base, &size, devmem); if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len) { fprintf(stderr, "Wrong DMI structures length: %u bytes " "announced, only %lu bytes available.\n", len, (unsigned long)size); } len = size; } else buf = mem_chunk(base, len, devmem); if (buf == NULL) { fprintf(stderr, "Failed to read table, sorry.\n"); #ifndef USE_MMAP if (!(flags & FLAG_NO_FILE_OFFSET)) fprintf(stderr, "Try compiling dmidecode with -DUSE_MMAP.\n"); #endif return; } if (opt.flags & FLAG_DUMP_BIN) dmi_table_dump(buf, len); else dmi_table_decode(buf, len, num, ver >> 8, flags); free(buf); } /* * Build a crafted entry point with table address hard-coded to 32, * as this is where we will put it in the output file. We adjust the * DMI checksum appropriately. The SMBIOS checksum needs no adjustment. */ static void overwrite_dmi_address(u8 *buf) { buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32; buf[0x08] = 32; buf[0x09] = 0; buf[0x0A] = 0; buf[0x0B] = 0; } /* Same thing for SMBIOS3 entry points */ static void overwrite_smbios3_address(u8 *buf) { buf[0x05] += buf[0x10] + buf[0x11] + buf[0x12] + buf[0x13] + buf[0x14] + buf[0x15] + buf[0x16] + buf[0x17] - 32; buf[0x10] = 32; buf[0x11] = 0; buf[0x12] = 0; buf[0x13] = 0; buf[0x14] = 0; buf[0x15] = 0; buf[0x16] = 0; buf[0x17] = 0; } static int smbios3_decode(u8 *buf, const char *devmem, u32 flags) { u32 ver; u64 offset; /* Don't let checksum run beyond the buffer */ if (buf[0x06] > 0x20) { fprintf(stderr, "Entry point length too large (%u bytes, expected %u).\n", (unsigned int)buf[0x06], 0x18U); return 0; } if (!checksum(buf, buf[0x06])) return 0; ver = (buf[0x07] << 16) + (buf[0x08] << 8) + buf[0x09]; if (!(opt.flags & FLAG_QUIET)) pr_info("SMBIOS %u.%u.%u present.", buf[0x07], buf[0x08], buf[0x09]); offset = QWORD(buf + 0x10); if (!(flags & FLAG_NO_FILE_OFFSET) && offset.h && sizeof(off_t) < 8) { fprintf(stderr, "64-bit addresses not supported, sorry.\n"); return 0; } dmi_table(((off_t)offset.h << 32) | offset.l, DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT); if (opt.flags & FLAG_DUMP_BIN) { u8 crafted[32]; memcpy(crafted, buf, 32); overwrite_smbios3_address(crafted); if (!(opt.flags & FLAG_QUIET)) pr_comment("Writing %d bytes to %s.", crafted[0x06], opt.dumpfile); write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1); } return 1; } static int smbios_decode(u8 *buf, const char *devmem, u32 flags) { u16 ver; /* Don't let checksum run beyond the buffer */ if (buf[0x05] > 0x20) { fprintf(stderr, "Entry point length too large (%u bytes, expected %u).\n", (unsigned int)buf[0x05], 0x1FU); return 0; } if (!checksum(buf, buf[0x05]) || memcmp(buf + 0x10, "_DMI_", 5) != 0 || !checksum(buf + 0x10, 0x0F)) return 0; ver = (buf[0x06] << 8) + buf[0x07]; /* Some BIOS report weird SMBIOS version, fix that up */ switch (ver) { case 0x021F: case 0x0221: if (!(opt.flags & FLAG_QUIET)) fprintf(stderr, "SMBIOS version fixup (2.%d -> 2.%d).\n", ver & 0xFF, 3); ver = 0x0203; break; case 0x0233: if (!(opt.flags & FLAG_QUIET)) fprintf(stderr, "SMBIOS version fixup (2.%d -> 2.%d).\n", 51, 6); ver = 0x0206; break; } if (!(opt.flags & FLAG_QUIET)) pr_info("SMBIOS %u.%u present.", ver >> 8, ver & 0xFF); dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C), ver << 8, devmem, flags); if (opt.flags & FLAG_DUMP_BIN) { u8 crafted[32]; memcpy(crafted, buf, 32); overwrite_dmi_address(crafted + 0x10); if (!(opt.flags & FLAG_QUIET)) pr_comment("Writing %d bytes to %s.", crafted[0x05], opt.dumpfile); write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1); } return 1; } static int legacy_decode(u8 *buf, const char *devmem, u32 flags) { if (!checksum(buf, 0x0F)) return 0; if (!(opt.flags & FLAG_QUIET)) pr_info("Legacy DMI %u.%u present.", buf[0x0E] >> 4, buf[0x0E] & 0x0F); dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C), ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8), devmem, flags); if (opt.flags & FLAG_DUMP_BIN) { u8 crafted[16]; memcpy(crafted, buf, 16); overwrite_dmi_address(crafted); if (!(opt.flags & FLAG_QUIET)) pr_comment("Writing %d bytes to %s.", 0x0F, opt.dumpfile); write_dump(0, 0x0F, crafted, opt.dumpfile, 1); } return 1; } /* * Probe for EFI interface */ #define EFI_NOT_FOUND (-1) #define EFI_NO_SMBIOS (-2) static int address_from_efi(off_t *address) { #if defined(__linux__) FILE *efi_systab; const char *filename; char linebuf[64]; #elif defined(__FreeBSD__) char addrstr[KENV_MVALLEN + 1]; #endif const char *eptype; int ret; *address = 0; /* Prevent compiler warning */ #if defined(__linux__) /* * Linux up to 2.6.6: /proc/efi/systab * Linux 2.6.7 and up: /sys/firmware/efi/systab */ if ((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { /* No EFI interface, fallback to memory scan */ return EFI_NOT_FOUND; } ret = EFI_NO_SMBIOS; while ((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { char *addrp = strchr(linebuf, '='); *(addrp++) = '\0'; if (strcmp(linebuf, "SMBIOS3") == 0 || strcmp(linebuf, "SMBIOS") == 0) { *address = strtoull(addrp, NULL, 0); eptype = linebuf; ret = 0; break; } } if (fclose(efi_systab) != 0) perror(filename); if (ret == EFI_NO_SMBIOS) fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); #elif defined(__FreeBSD__) /* * On FreeBSD, SMBIOS anchor base address in UEFI mode is exposed * via kernel environment: * https://svnweb.freebsd.org/base?view=revision&revision=307326 */ ret = kenv(KENV_GET, "hint.smbios.0.mem", addrstr, sizeof(addrstr)); if (ret == -1) { if (errno != ENOENT) perror("kenv"); return EFI_NOT_FOUND; } *address = strtoull(addrstr, NULL, 0); eptype = "SMBIOS"; ret = 0; #else ret = EFI_NOT_FOUND; #endif if (ret == 0 && !(opt.flags & FLAG_QUIET)) pr_comment("%s entry point at 0x%08llx", eptype, (unsigned long long)*address); return ret; } int dmidecode(int quiet, void *cpux_pdata) { int ret = 0; /* Returned value */ int found = 0; off_t fp; size_t size; int efi; u8 *buf = NULL; char *argv[] = { "dmidecode (built-in with CPU-X)", NULL }; cpux_data = (DmidecodeData *)cpux_pdata; if(cpux_pdata != NULL) { opt.type = (u8 *)calloc(256, sizeof(u8)); if (opt.type == NULL) { perror("calloc"); return 255; } opt.type[0] = 1; opt.type[2] = 1; opt.type[4] = 1; opt.type[17] = 1; } /* * We don't want stdout and stderr to be mixed up if both are * redirected to the same file. */ setlinebuf(stdout); setlinebuf(stderr); if (sizeof(u8) != 1 || sizeof(u16) != 2 || sizeof(u32) != 4 || '\0' != 0) { fprintf(stderr, "%s: compiler incompatibility\n", argv[0]); return 255; } /* Set default option values */ opt.devmem = DEFAULT_MEM_DEV; opt.flags = 0; opt.handle = ~0U; if(quiet) opt.flags |= FLAG_QUIET; #if 0 if (parse_command_line(argc, argv)<0) { ret = 2; goto exit_free; } if (opt.flags & FLAG_HELP) { print_help(); goto exit_free; } if (opt.flags & FLAG_VERSION) { printf("%s\n", VERSION); goto exit_free; } #endif if (cpux_data == NULL) pr_comment("%s %s\n", argv[0], VERSION); /* Read from dump if so instructed */ if (opt.flags & FLAG_FROM_DUMP) { if (!(opt.flags & FLAG_QUIET)) pr_info("Reading SMBIOS/DMI data from file %s.", opt.dumpfile); if ((buf = mem_chunk(0, 0x20, opt.dumpfile)) == NULL) { ret = 1; goto exit_free; } if (memcmp(buf, "_SM3_", 5) == 0) { if (smbios3_decode(buf, opt.dumpfile, 0)) found++; } else if (memcmp(buf, "_SM_", 4) == 0) { if (smbios_decode(buf, opt.dumpfile, 0)) found++; } else if (memcmp(buf, "_DMI_", 5) == 0) { if (legacy_decode(buf, opt.dumpfile, 0)) found++; } goto done; } /* * First try reading from sysfs tables. The entry point file could * contain one of several types of entry points, so read enough for * the largest one, then determine what type it contains. */ size = 0x20; if (!(opt.flags & FLAG_NO_SYSFS) && (buf = read_file(0, &size, SYS_ENTRY_FILE)) != NULL) { if (!(opt.flags & FLAG_QUIET)) pr_info("Getting SMBIOS data from sysfs."); if (size >= 24 && memcmp(buf, "_SM3_", 5) == 0) { if (smbios3_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) found++; } else if (size >= 31 && memcmp(buf, "_SM_", 4) == 0) { if (smbios_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) found++; } else if (size >= 15 && memcmp(buf, "_DMI_", 5) == 0) { if (legacy_decode(buf, SYS_TABLE_FILE, FLAG_NO_FILE_OFFSET)) found++; } if (found) goto done; if (!(opt.flags & FLAG_QUIET)) pr_info("Failed to get SMBIOS data from sysfs."); } /* Next try EFI (ia64, Intel-based Mac, arm64) */ efi = address_from_efi(&fp); switch (efi) { case EFI_NOT_FOUND: goto memory_scan; case EFI_NO_SMBIOS: ret = 1; goto exit_free; } if (!(opt.flags & FLAG_QUIET)) pr_info("Found SMBIOS entry point in EFI, reading table from %s.", opt.devmem); if ((buf = mem_chunk(fp, 0x20, opt.devmem)) == NULL) { ret = 1; goto exit_free; } if (memcmp(buf, "_SM3_", 5) == 0) { if (smbios3_decode(buf, opt.devmem, 0)) found++; } else if (memcmp(buf, "_SM_", 4) == 0) { if (smbios_decode(buf, opt.devmem, 0)) found++; } goto done; memory_scan: #if defined __i386__ || defined __x86_64__ if (!(opt.flags & FLAG_QUIET)) pr_info("Scanning %s for entry point.", opt.devmem); /* Fallback to memory scan (x86, x86_64) */ if ((buf = mem_chunk(0xF0000, 0x10000, opt.devmem)) == NULL) { ret = 1; goto exit_free; } /* Look for a 64-bit entry point first */ for (fp = 0; fp <= 0xFFE0; fp += 16) { if (memcmp(buf + fp, "_SM3_", 5) == 0) { if (smbios3_decode(buf + fp, opt.devmem, 0)) { found++; goto done; } } } /* If none found, look for a 32-bit entry point */ for (fp = 0; fp <= 0xFFF0; fp += 16) { if (memcmp(buf + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) { if (smbios_decode(buf + fp, opt.devmem, 0)) { found++; goto done; } } else if (memcmp(buf + fp, "_DMI_", 5) == 0) { if (legacy_decode(buf + fp, opt.devmem, 0)) { found++; goto done; } } } #endif done: if (!found && !(opt.flags & FLAG_QUIET)) pr_comment("No SMBIOS nor DMI entry point found, sorry."); free(buf); exit_free: free(opt.type); opt.type = NULL; return ret; } CPU-X-4.2.0/src/dmidecode/dmidecode.h000066400000000000000000000021111403012130000171160ustar00rootroot00000000000000/* * This file is part of the dmidecode project. * * Copyright (C) 2005-2020 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DMIDECODE_H #define DMIDECODE_H #include "types.h" struct dmi_header { u8 type; u8 length; u16 handle; u8 *data; }; int is_printable(const u8 *data, int len); const char *dmi_string(const struct dmi_header *dm, u8 s); #endif CPU-X-4.2.0/src/dmidecode/dmioem.c000066400000000000000000000363761403012130000164720ustar00rootroot00000000000000/* * Decoding of OEM-specific entries * This file is part of the dmidecode project. * * Copyright (C) 2007-2020 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "types.h" #include "util.h" #include "dmidecode.h" #include "dmioem.h" #include "dmioutput.h" /* * Globals for vendor-specific decodes */ enum DMI_VENDORS { VENDOR_UNKNOWN, VENDOR_ACER, VENDOR_HP, VENDOR_HPE, VENDOR_IBM, VENDOR_LENOVO, }; static enum DMI_VENDORS dmi_vendor = VENDOR_UNKNOWN; static const char *dmi_product = NULL; /* * Remember the system vendor for later use. We only actually store the * value if we know how to decode at least one specific entry type for * that vendor. */ void dmi_set_vendor(const char *v, const char *p) { const struct { const char *str; enum DMI_VENDORS id; } vendor[] = { { "Acer", VENDOR_ACER }, { "HP", VENDOR_HP }, { "Hewlett-Packard", VENDOR_HP }, { "HPE", VENDOR_HPE }, { "Hewlett Packard Enterprise", VENDOR_HPE }, { "IBM", VENDOR_IBM }, { "LENOVO", VENDOR_LENOVO }, }; unsigned int i; size_t len; /* * Often DMI strings have trailing spaces. Ignore these * when checking for known vendor names. */ len = v ? strlen(v) : 0; while (len && v[len - 1] == ' ') len--; for (i = 0; i < ARRAY_SIZE(vendor); i++) { if (strlen(vendor[i].str) == len && strncmp(v, vendor[i].str, len) == 0) { dmi_vendor = vendor[i].id; break; } } dmi_product = p; } /* * Acer-specific data structures are decoded here. */ static int dmi_decode_acer(const struct dmi_header *h) { u8 *data = h->data; u16 cap; switch (h->type) { case 170: /* * Vendor Specific: Acer Hotkey Function * * Source: acer-wmi kernel driver * * Probably applies to some laptop models of other * brands, including Fujitsu-Siemens, Medion, Lenovo, * and eMachines. */ pr_handle_name("Acer Hotkey Function"); if (h->length < 0x0F) break; cap = WORD(data + 0x04); pr_attr("Function bitmap for Communication Button", "0x%04hx", cap); pr_subattr("WiFi", "%s", cap & 0x0001 ? "Yes" : "No"); pr_subattr("3G", "%s", cap & 0x0040 ? "Yes" : "No"); pr_subattr("WiMAX", "%s", cap & 0x0080 ? "Yes" : "No"); pr_subattr("Bluetooth", "%s", cap & 0x0800 ? "Yes" : "No"); pr_attr("Function bitmap for Application Button", "0x%04hx", WORD(data + 0x06)); pr_attr("Function bitmap for Media Button", "0x%04hx", WORD(data + 0x08)); pr_attr("Function bitmap for Display Button", "0x%04hx", WORD(data + 0x0A)); pr_attr("Function bitmap for Others Button", "0x%04hx", WORD(data + 0x0C)); pr_attr("Communication Function Key Number", "%d", data[0x0E]); break; default: return 0; } return 1; } /* * HPE-specific data structures are decoded here. * * Code contributed by John Cagle and Tyler Bell. */ static void dmi_print_hp_net_iface_rec(u8 id, u8 bus, u8 dev, const u8 *mac) { /* Some systems do not provide an id. nic_ctr provides an artificial * id, and assumes the records will be provided "in order". Also, * using 0xFF marker is not future proof. 256 NICs is a lot, but * 640K ought to be enough for anybody(said no one, ever). * */ static u8 nic_ctr; char attr[8]; if (id == 0xFF) id = ++nic_ctr; sprintf(attr, "NIC %hhu", id); if (dev == 0x00 && bus == 0x00) pr_attr(attr, "Disabled"); else if (dev == 0xFF && bus == 0xFF) pr_attr(attr, "Not Installed"); else { pr_attr(attr, "PCI device %02x:%02x.%x, " "MAC address %02X:%02X:%02X:%02X:%02X:%02X", bus, dev >> 3, dev & 7, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } } typedef enum { G6 = 6, G7, G8, G9, G10, G10P } dmi_hpegen_t; static int dmi_hpegen(const char *s) { struct { const char *name; dmi_hpegen_t gen; } table[] = { { "Gen10 Plus", G10P }, { "Gen10", G10 }, { "Gen9", G9 }, { "Gen8", G8 }, { "G7", G7 }, { "G6", G6 }, }; unsigned int i; if (!strstr(s, "ProLiant") && !strstr(s, "Apollo") && !strstr(s, "Synergy") && !strstr(s, "Edgeline")) return -1; for (i = 0; i < ARRAY_SIZE(table); i++) { if (strstr(s, table[i].name)) return(table[i].gen); } return (dmi_vendor == VENDOR_HPE) ? G10P : G6; } static int dmi_decode_hp(const struct dmi_header *h) { u8 *data = h->data; int nic, ptr; u32 feat; const char *company = (dmi_vendor == VENDOR_HP) ? "HP" : "HPE"; int gen; gen = dmi_hpegen(dmi_product); if (gen < 0) return 0; switch (h->type) { case 204: /* * Vendor Specific: HPE ProLiant System/Rack Locator */ pr_handle_name("%s ProLiant System/Rack Locator", company); if (h->length < 0x0B) break; pr_attr("Rack Name", "%s", dmi_string(h, data[0x04])); pr_attr("Enclosure Name", "%s", dmi_string(h, data[0x05])); pr_attr("Enclosure Model", "%s", dmi_string(h, data[0x06])); pr_attr("Enclosure Serial", "%s", dmi_string(h, data[0x0A])); pr_attr("Enclosure Bays", "%d", data[0x08]); pr_attr("Server Bay", "%s", dmi_string(h, data[0x07])); pr_attr("Bays Filled", "%d", data[0x09]); break; case 209: case 221: /* * Vendor Specific: HPE ProLiant NIC MAC Information * * This prints the BIOS NIC number, * PCI bus/device/function, and MAC address * * Type 209: * Offset | Name | Width | Description * ------------------------------------- * 0x00 | Type | BYTE | 0xD1, MAC Info * 0x01 | Length | BYTE | Length of structure * 0x02 | Handle | WORD | Unique handle * 0x04 | Dev No | BYTE | PCI Device/Function No * 0x05 | Bus No | BYTE | PCI Bus * 0x06 | MAC | 6B | MAC addr * 0x0C | NIC #2 | 8B | Repeat 0x04-0x0B * * Type 221: is deprecated in the latest docs */ pr_handle_name("%s %s", company, h->type == 221 ? "BIOS iSCSI NIC PCI and MAC Information" : "BIOS PXE NIC PCI and MAC Information"); nic = 1; ptr = 4; while (h->length >= ptr + 8) { dmi_print_hp_net_iface_rec(nic, data[ptr + 0x01], data[ptr], &data[ptr + 0x02]); nic++; ptr += 8; } break; case 212: /* * Vendor Specific: HPE 64-bit CRU Information * * Source: hpwdt kernel driver */ pr_handle_name("%s 64-bit CRU Information", company); if (h->length < 0x18) break; if (is_printable(data + 0x04, 4)) pr_attr("Signature", "0x%08x (%c%c%c%c)", DWORD(data + 0x04), data[0x04], data[0x05], data[0x06], data[0x07]); else pr_attr("Signature", "0x%08x", DWORD(data + 0x04)); if (DWORD(data + 0x04) == 0x55524324) { u64 paddr = QWORD(data + 0x08); paddr.l += DWORD(data + 0x14); if (paddr.l < DWORD(data + 0x14)) paddr.h++; pr_attr("Physical Address", "0x%08x%08x", paddr.h, paddr.l); pr_attr("Length", "0x%08x", DWORD(data + 0x10)); } break; case 219: /* * Vendor Specific: HPE ProLiant Information * * Source: hpwdt kernel driver */ pr_handle_name("%s ProLiant Information", company); if (h->length < 0x08) break; pr_attr("Power Features", "0x%08x", DWORD(data + 0x04)); if (h->length < 0x0C) break; pr_attr("Omega Features", "0x%08x", DWORD(data + 0x08)); if (h->length < 0x14) break; feat = DWORD(data + 0x10); pr_attr("Misc. Features", "0x%08x", feat); pr_subattr("iCRU", "%s", feat & 0x0001 ? "Yes" : "No"); pr_subattr("UEFI", "%s", feat & 0x1400 ? "Yes" : "No"); break; case 233: /* * Vendor Specific: HPE ProLiant NIC MAC Information * * This prints the BIOS NIC number, * PCI bus/device/function, and MAC address * * Offset | Name | Width | Description * ------------------------------------- * 0x00 | Type | BYTE | 0xE9, NIC structure * 0x01 | Length | BYTE | Length of structure * 0x02 | Handle | WORD | Unique handle * 0x04 | Grp No | WORD | 0 for single segment * 0x06 | Bus No | BYTE | PCI Bus * 0x07 | Dev No | BYTE | PCI Device/Function No * 0x08 | MAC | 32B | MAC addr padded w/ 0s * 0x28 | Port No| BYTE | Each NIC maps to a Port */ pr_handle_name("%s BIOS PXE NIC PCI and MAC Information", company); if (h->length < 0x0E) break; /* If the record isn't long enough, we don't have an ID * use 0xFF to use the internal counter. * */ nic = h->length > 0x28 ? data[0x28] : 0xFF; dmi_print_hp_net_iface_rec(nic, data[0x06], data[0x07], &data[0x08]); break; case 236: /* * Vendor Specific: HPE ProLiant HDD Backplane * * Offset | Name | Width | Description * --------------------------------------- * 0x00 | Type | BYTE | 0xEC, HDD Backplane * 0x01 | Length | BYTE | Length of structure * 0x02 | Handle | WORD | Unique handle * 0x04 | I2C Address| BYTE | Backplane FRU I2C Address * 0x05 | Box Number | WORD | Backplane Box Number * 0x07 | NVRAM ID | WORD | Backplane NVRAM ID * 0x09 | WWID | QWORD | SAS Expander WWID * 0x11 | Total Bays | BYTE | Total SAS Bays * 0x12 | A0 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA0 * 0x13 | A2 Bays | BYTE | (deprecated) Number of SAS drive bays behind port 0xA2 * 0x14 | Name | STRING| (deprecated) Backplane Name */ pr_handle_name("%s HDD Backplane FRU Information", company); pr_attr("FRU I2C Address", "0x%X raw(0x%X)", data[0x4] >> 1, data[0x4]); pr_attr("Box Number", "%d", WORD(data + 0x5)); pr_attr("NVRAM ID", "0x%X", WORD(data + 0x7)); if (h->length < 0x11) break; pr_attr("SAS Expander WWID", "0x%X", QWORD(data + 0x9)); if (h->length < 0x12) break; pr_attr("Total SAS Bays", "%d", data[0x11]); if (h->length < 0x15) break; if (gen < G10P) { pr_attr("A0 Bay Count", "%d", data[0x12]); pr_attr("A2 Bay Count", "%d", data[0x13]); pr_attr("Backplane Name", "%s", dmi_string(h, data[0x14])); } break; default: return 0; } return 1; } static int dmi_decode_ibm_lenovo(const struct dmi_header *h) { u8 *data = h->data; switch (h->type) { case 131: /* * Vendor Specific: ThinkVantage Technologies feature bits * * Source: Compal hel81 Service Manual Software Specification, * documented under "System Management BIOS(SM BIOS) * version 2.4 or greater" * * Offset | Name | Width | Description * ---------------------------------------------- * 0x00 | Type | BYTE | 0x83 * 0x01 | Length | BYTE | 0x16 * 0x02 | Handle | WORD | Varies * 0x04 | Version | BYTE | 0x01 * 0x05 | TVT Structure | BYTEx16 | Each of the 128 bits represents a TVT feature: * | | | - bit 127 means diagnostics (PC Doctor) is available * | | | (http://www.pc-doctor.com/company/pr-articles/45-lenovo-introduces-thinkvantage-toolbox) * | | | - the rest (126-0) are reserved/unknown * * It must also be followed by a string containing * "TVT-Enablement". There exist other type 131 records * with different length and a different string, for * other purposes. */ if (h->length != 0x16 || strcmp(dmi_string(h, 1), "TVT-Enablement") != 0) return 0; pr_handle_name("ThinkVantage Technologies"); pr_attr("Version", "%u", data[0x04]); pr_attr("Diagnostics", "%s", data[0x14] & 0x80 ? "Available" : "No"); break; case 135: /* * Vendor Specific: Device Presence Detection bits * * Source: Compal hel81 Service Manual Software Specification, * documented as "SMBIOS Type 135: Bulk for Lenovo * Mobile PC Unique OEM Data" under appendix D. * * Offset | Name | Width | Description * --------------------------------------------------- * 0x00 | Type | BYTE | 0x87 * 0x01 | Length | BYTE | 0x0A * 0x02 | Handle | WORD | Varies * 0x04 | Signature | WORD | 0x5054 (ASCII for "TP") * 0x06 | OEM struct offset | BYTE | 0x07 * 0x07 | OEM struct number | BYTE | 0x03, for this structure * 0x08 | OEM struct revision | BYTE | 0x01, for this format * 0x09 | Device presence bits | BYTE | Each of the 8 bits indicates device presence: * | | | - bit 0 indicates the presence of a fingerprint reader * | | | - the rest (7-1) are reserved/unknown * * Other OEM struct number+rev combinations have been * seen in the wild but we don't know how to decode * them. */ if (h->length < 0x0A || data[0x04] != 'T' || data[0x05] != 'P') return 0; /* Bail out if not the expected format */ if (data[0x06] != 0x07 || data[0x07] != 0x03 || data[0x08] != 0x01) return 0; pr_handle_name("ThinkPad Device Presence Detection"); pr_attr("Fingerprint Reader", "%s", data[0x09] & 0x01 ? "Present" : "No"); break; case 140: /* * Vendor Specific: ThinkPad Embedded Controller Program * * Source: some guesswork, and publicly available information; * Lenovo's BIOS update READMEs often contain the ECP IDs * which match the first string in this type. * * Offset | Name | Width | Description * ---------------------------------------------------- * 0x00 | Type | BYTE | 0x8C * 0x01 | Length | BYTE | * 0x02 | Handle | WORD | Varies * 0x04 | Signature | BYTEx6 | ASCII for "LENOVO" * 0x0A | OEM struct offset | BYTE | 0x0B * 0x0B | OEM struct number | BYTE | 0x07, for this structure * 0x0C | OEM struct revision | BYTE | 0x01, for this format * 0x0D | ECP version ID | STRING | * 0x0E | ECP release date | STRING | */ if (h->length < 0x0F || memcmp(data + 4, "LENOVO", 6) != 0) return 0; /* Bail out if not the expected format */ if (data[0x0A] != 0x0B || data[0x0B] != 0x07 || data[0x0C] != 0x01) return 0; pr_handle_name("ThinkPad Embedded Controller Program"); pr_attr("Version ID", "%s", dmi_string(h, 1)); pr_attr("Release Date", "%s", dmi_string(h, 2)); break; default: return 0; } return 1; } /* * Dispatch vendor-specific entries decoding * Return 1 if decoding was successful, 0 otherwise */ int dmi_decode_oem(const struct dmi_header *h) { switch (dmi_vendor) { case VENDOR_HP: case VENDOR_HPE: return dmi_decode_hp(h); case VENDOR_ACER: return dmi_decode_acer(h); case VENDOR_IBM: case VENDOR_LENOVO: return dmi_decode_ibm_lenovo(h); default: return 0; } } CPU-X-4.2.0/src/dmidecode/dmioem.h000066400000000000000000000017631403012130000164670ustar00rootroot00000000000000/* * Decoding of OEM-specific entries * This file is part of the dmidecode project. * * Copyright (C) 2007-2008 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ struct dmi_header; void dmi_set_vendor(const char *s, const char *p); int dmi_decode_oem(const struct dmi_header *h); CPU-X-4.2.0/src/dmidecode/dmiopt.c000066400000000000000000000231441403012130000165010ustar00rootroot00000000000000/* * Command line handling of dmidecode * This file is part of the dmidecode project. * * Copyright (C) 2005-2008 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include "config.h" #include "types.h" #include "util.h" #include "dmidecode.h" #include "dmiopt.h" /* Options are global */ struct opt opt; /* * Handling of option --type */ struct type_keyword { const char *keyword; const u8 *type; }; static const u8 opt_type_bios[] = { 0, 13, 255 }; static const u8 opt_type_system[] = { 1, 12, 15, 23, 32, 255 }; static const u8 opt_type_baseboard[] = { 2, 10, 41, 255 }; static const u8 opt_type_chassis[] = { 3, 255 }; static const u8 opt_type_processor[] = { 4, 255 }; static const u8 opt_type_memory[] = { 5, 6, 16, 17, 255 }; static const u8 opt_type_cache[] = { 7, 255 }; static const u8 opt_type_connector[] = { 8, 255 }; static const u8 opt_type_slot[] = { 9, 255 }; static const struct type_keyword opt_type_keyword[] = { { "bios", opt_type_bios }, { "system", opt_type_system }, { "baseboard", opt_type_baseboard }, { "chassis", opt_type_chassis }, { "processor", opt_type_processor }, { "memory", opt_type_memory }, { "cache", opt_type_cache }, { "connector", opt_type_connector }, { "slot", opt_type_slot }, }; static void print_opt_type_list(void) { unsigned int i; fprintf(stderr, "Valid type keywords are:\n"); for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) { fprintf(stderr, " %s\n", opt_type_keyword[i].keyword); } } static u8 *parse_opt_type(u8 *p, const char *arg) { unsigned int i; /* Allocate memory on first call only */ if (p == NULL) { p = (u8 *)calloc(256, sizeof(u8)); if (p == NULL) { perror("calloc"); return NULL; } } /* First try as a keyword */ for (i = 0; i < ARRAY_SIZE(opt_type_keyword); i++) { if (!strcasecmp(arg, opt_type_keyword[i].keyword)) { int j = 0; while (opt_type_keyword[i].type[j] != 255) p[opt_type_keyword[i].type[j++]] = 1; goto found; } } /* Else try as a number */ while (*arg != '\0') { unsigned long val; char *next; val = strtoul(arg, &next, 0); if (next == arg || (*next != '\0' && *next != ',' && *next != ' ')) { fprintf(stderr, "Invalid type keyword: %s\n", arg); print_opt_type_list(); goto exit_free; } if (val > 0xff) { fprintf(stderr, "Invalid type number: %lu\n", val); goto exit_free; } p[val] = 1; arg = next; while (*arg == ',' || *arg == ' ') arg++; } found: return p; exit_free: free(p); return NULL; } /* * Handling of option --string */ /* This lookup table could admittedly be reworked for improved performance. Due to the low count of items in there at the moment, it did not seem worth the additional code complexity though. */ static const struct string_keyword opt_string_keyword[] = { { "bios-vendor", 0, 0x04 }, { "bios-version", 0, 0x05 }, { "bios-release-date", 0, 0x08 }, { "bios-revision", 0, 0x15 }, /* 0x14 and 0x15 */ { "firmware-revision", 0, 0x17 }, /* 0x16 and 0x17 */ { "system-manufacturer", 1, 0x04 }, { "system-product-name", 1, 0x05 }, { "system-version", 1, 0x06 }, { "system-serial-number", 1, 0x07 }, { "system-uuid", 1, 0x08 }, /* dmi_system_uuid() */ { "system-sku-number", 1, 0x19 }, { "system-family", 1, 0x1a }, { "baseboard-manufacturer", 2, 0x04 }, { "baseboard-product-name", 2, 0x05 }, { "baseboard-version", 2, 0x06 }, { "baseboard-serial-number", 2, 0x07 }, { "baseboard-asset-tag", 2, 0x08 }, { "chassis-manufacturer", 3, 0x04 }, { "chassis-type", 3, 0x05 }, /* dmi_chassis_type() */ { "chassis-version", 3, 0x06 }, { "chassis-serial-number", 3, 0x07 }, { "chassis-asset-tag", 3, 0x08 }, { "processor-family", 4, 0x06 }, /* dmi_processor_family() */ { "processor-manufacturer", 4, 0x07 }, { "processor-version", 4, 0x10 }, { "processor-frequency", 4, 0x16 }, /* dmi_processor_frequency() */ }; /* This is a template, 3rd field is set at runtime. */ static struct string_keyword opt_oem_string_keyword = { NULL, 11, 0x00 }; static void print_opt_string_list(void) { unsigned int i; fprintf(stderr, "Valid string keywords are:\n"); for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++) { fprintf(stderr, " %s\n", opt_string_keyword[i].keyword); } } static int parse_opt_string(const char *arg) { unsigned int i; if (opt.string) { fprintf(stderr, "Only one string can be specified\n"); return -1; } for (i = 0; i < ARRAY_SIZE(opt_string_keyword); i++) { if (!strcasecmp(arg, opt_string_keyword[i].keyword)) { opt.string = &opt_string_keyword[i]; return 0; } } fprintf(stderr, "Invalid string keyword: %s\n", arg); print_opt_string_list(); return -1; } static int parse_opt_oem_string(const char *arg) { unsigned long val; char *next; if (opt.string) { fprintf(stderr, "Only one string can be specified\n"); return -1; } /* Return the number of OEM strings */ if (strcmp(arg, "count") == 0) goto done; val = strtoul(arg, &next, 10); if (next == arg || *next != '\0' || val == 0x00 || val > 0xff) { fprintf(stderr, "Invalid OEM string number: %s\n", arg); return -1; } opt_oem_string_keyword.offset = val; done: opt.string = &opt_oem_string_keyword; return 0; } static u32 parse_opt_handle(const char *arg) { u32 val; char *next; val = strtoul(arg, &next, 0); if (next == arg || *next != '\0' || val > 0xffff) { fprintf(stderr, "Invalid handle number: %s\n", arg); return ~0; } return val; } /* * Command line options handling */ /* Return -1 on error, 0 on success */ int parse_command_line(int argc, char * const argv[]) { int option; const char *optstring = "d:hqs:t:uH:V"; struct option longopts[] = { { "dev-mem", required_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { "quiet", no_argument, NULL, 'q' }, { "string", required_argument, NULL, 's' }, { "type", required_argument, NULL, 't' }, { "dump", no_argument, NULL, 'u' }, { "dump-bin", required_argument, NULL, 'B' }, { "from-dump", required_argument, NULL, 'F' }, { "handle", required_argument, NULL, 'H' }, { "oem-string", required_argument, NULL, 'O' }, { "no-sysfs", no_argument, NULL, 'S' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) switch (option) { case 'B': opt.flags |= FLAG_DUMP_BIN; opt.dumpfile = optarg; break; case 'F': opt.flags |= FLAG_FROM_DUMP; opt.dumpfile = optarg; break; case 'd': opt.devmem = optarg; break; case 'h': opt.flags |= FLAG_HELP; break; case 'q': opt.flags |= FLAG_QUIET; break; case 's': if (parse_opt_string(optarg) < 0) return -1; opt.flags |= FLAG_QUIET; break; case 'O': if (parse_opt_oem_string(optarg) < 0) return -1; opt.flags |= FLAG_QUIET; break; case 't': opt.type = parse_opt_type(opt.type, optarg); if (opt.type == NULL) return -1; break; case 'H': opt.handle = parse_opt_handle(optarg); if (opt.handle == ~0U) return -1; break; case 'u': opt.flags |= FLAG_DUMP; break; case 'S': opt.flags |= FLAG_NO_SYSFS; break; case 'V': opt.flags |= FLAG_VERSION; break; case '?': switch (optopt) { case 's': fprintf(stderr, "String keyword expected\n"); print_opt_string_list(); break; case 't': fprintf(stderr, "Type number or keyword expected\n"); print_opt_type_list(); break; } return -1; } /* Check for mutually exclusive output format options */ if ((opt.string != NULL) + (opt.type != NULL) + !!(opt.flags & FLAG_DUMP_BIN) + (opt.handle != ~0U) > 1) { fprintf(stderr, "Options --string, --type, --handle and --dump-bin are mutually exclusive\n"); return -1; } if ((opt.flags & FLAG_FROM_DUMP) && (opt.flags & FLAG_DUMP_BIN)) { fprintf(stderr, "Options --from-dump and --dump-bin are mutually exclusive\n"); return -1; } return 0; } void print_help(void) { static const char *help = "Usage: dmidecode [OPTIONS]\n" "Options are:\n" " -d, --dev-mem FILE Read memory from device FILE (default: " DEFAULT_MEM_DEV ")\n" " -h, --help Display this help text and exit\n" " -q, --quiet Less verbose output\n" " -s, --string KEYWORD Only display the value of the given DMI string\n" " -t, --type TYPE Only display the entries of given type\n" " -H, --handle HANDLE Only display the entry of given handle\n" " -u, --dump Do not decode the entries\n" " --dump-bin FILE Dump the DMI data to a binary file\n" " --from-dump FILE Read the DMI data from a binary file\n" " --no-sysfs Do not attempt to read DMI data from sysfs files\n" " --oem-string N Only display the value of the given OEM string\n" " -V, --version Display the version and exit\n"; printf("%s", help); } CPU-X-4.2.0/src/dmidecode/dmiopt.h000066400000000000000000000027531403012130000165110ustar00rootroot00000000000000/* * Command line handling of dmidecode * This file is part of the dmidecode project. * * Copyright (C) 2005-2008 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if !HAS_LIBPCI # include "types.h" #endif struct string_keyword { const char *keyword; u8 type; u8 offset; }; struct opt { const char *devmem; unsigned int flags; u8 *type; const struct string_keyword *string; char *dumpfile; u32 handle; }; #define FLAG_VERSION (1 << 0) #define FLAG_HELP (1 << 1) #define FLAG_DUMP (1 << 2) #define FLAG_QUIET (1 << 3) #define FLAG_DUMP_BIN (1 << 4) #define FLAG_FROM_DUMP (1 << 5) #define FLAG_NO_SYSFS (1 << 6) int parse_command_line(int argc, char * const argv[]); void print_help(void); CPU-X-4.2.0/src/dmidecode/dmioutput.c000066400000000000000000000050301403012130000172310ustar00rootroot00000000000000/* * Generic output functions * This file is part of the dmidecode project. * * Copyright (C) 2020 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "dmioutput.h" void pr_comment(const char *format, ...) { va_list args; printf("# "); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_info(const char *format, ...) { va_list args; va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_handle(const struct dmi_header *h) { printf("Handle 0x%04X, DMI type %d, %d bytes\n", h->handle, h->type, h->length); } void pr_handle_name(const char *format, ...) { va_list args; va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_attr(const char *name, const char *format, ...) { va_list args; printf("\t%s: ", name); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_subattr(const char *name, const char *format, ...) { va_list args; printf("\t\t%s: ", name); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_list_start(const char *name, const char *format, ...) { va_list args; printf("\t%s:", name); /* format is optional, skip value if not provided */ if (format) { printf(" "); va_start(args, format); vprintf(format, args); va_end(args); } printf("\n"); } void pr_list_item(const char *format, ...) { va_list args; printf("\t\t"); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } void pr_list_end(void) { /* a no-op for text output */ } void pr_sep(void) { printf("\n"); } void pr_struct_err(const char *format, ...) { va_list args; printf("\t"); va_start(args, format); vprintf(format, args); va_end(args); printf("\n"); } CPU-X-4.2.0/src/dmidecode/dmioutput.h000066400000000000000000000025521403012130000172440ustar00rootroot00000000000000/* * Generic output functions * This file is part of the dmidecode project. * * Copyright (C) 2020 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "dmidecode.h" void pr_comment(const char *format, ...); void pr_info(const char *format, ...); void pr_handle(const struct dmi_header *h); void pr_handle_name(const char *format, ...); void pr_attr(const char *name, const char *format, ...); void pr_subattr(const char *name, const char *format, ...); void pr_list_start(const char *name, const char *format, ...); void pr_list_item(const char *format, ...); void pr_list_end(void); void pr_sep(void); void pr_struct_err(const char *format, ...); CPU-X-4.2.0/src/dmidecode/types.h000066400000000000000000000025631403012130000163600ustar00rootroot00000000000000#ifndef TYPES_H #define TYPES_H #include "config.h" typedef unsigned char u8; typedef unsigned short u16; typedef signed short i16; typedef unsigned int u32; /* * You may use the following defines to adjust the type definitions * depending on the architecture: * - Define BIGENDIAN on big-endian systems. * - Define ALIGNMENT_WORKAROUND if your system doesn't support * non-aligned memory access. In this case, we use a slower, but safer, * memory access method. This should be done automatically in config.h * for architectures which need it. */ #ifdef BIGENDIAN typedef struct { u32 h; u32 l; } u64; #else typedef struct { u32 l; u32 h; } u64; #endif #if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN) static inline u64 U64(u32 low, u32 high) { u64 self; self.l = low; self.h = high; return self; } #endif /* * Per SMBIOS v2.8.0 and later, all structures assume a little-endian * ordering convention. */ #if defined(ALIGNMENT_WORKAROUND) || defined(BIGENDIAN) #define WORD(x) (u16)((x)[0] + ((x)[1] << 8)) #define DWORD(x) (u32)((x)[0] + ((x)[1] << 8) + ((x)[2] << 16) + ((x)[3] << 24)) #define QWORD(x) (U64(DWORD(x), DWORD(x + 4))) #else /* ALIGNMENT_WORKAROUND || BIGENDIAN */ #define WORD(x) (u16)(*(const u16 *)(x)) #define DWORD(x) (u32)(*(const u32 *)(x)) #define QWORD(x) (*(const u64 *)(x)) #endif /* ALIGNMENT_WORKAROUND || BIGENDIAN */ #endif CPU-X-4.2.0/src/dmidecode/util.c000066400000000000000000000141301403012130000161550ustar00rootroot00000000000000/* * Common "util" functions * This file is part of the dmidecode project. * * Copyright (C) 2002-2018 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * For the avoidance of doubt the "preferred form" of this code is one which * is in an open unpatent encumbered format. Where cryptographic key signing * forms part of the process of creating an executable the information * including keys needed to generate an equivalently functional executable * are deemed to be part of the source code. */ #include #include #include "config.h" #ifdef USE_MMAP #include #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif /* !MAP_FAILED */ #endif /* USE MMAP */ #include #include #include #include #include #include #include "types.h" #include "util.h" static int myread(int fd, u8 *buf, size_t count, const char *prefix) { ssize_t r = 1; size_t r2 = 0; while (r2 != count && r != 0) { r = read(fd, buf + r2, count - r2); if (r == -1) { if (errno != EINTR) { perror(prefix); return -1; } } else r2 += r; } if (r2 != count) { fprintf(stderr, "%s: Unexpected end of file\n", prefix); return -1; } return 0; } int checksum(const u8 *buf, size_t len) { u8 sum = 0; size_t a; for (a = 0; a < len; a++) sum += buf[a]; return (sum == 0); } /* * Reads all of file from given offset, up to max_len bytes. * A buffer of at most max_len bytes is allocated by this function, and * needs to be freed by the caller. * This provides a similar usage model to mem_chunk() * * Returns a pointer to the allocated buffer, or NULL on error, and * sets max_len to the length actually read. */ void *read_file(off_t base, size_t *max_len, const char *filename) { struct stat statbuf; int fd; u8 *p; /* * Don't print error message on missing file, as we will try to read * files that may or may not be present. */ if ((fd = open(filename, O_RDONLY)) == -1) { if (errno != ENOENT) perror(filename); return NULL; } /* * Check file size, don't allocate more than can be read. */ if (fstat(fd, &statbuf) == 0) { if (base >= statbuf.st_size) { fprintf(stderr, "%s: Can't read data beyond EOF\n", filename); p = NULL; goto out; } if (*max_len > (size_t)statbuf.st_size - base) *max_len = statbuf.st_size - base; } if ((p = malloc(*max_len)) == NULL) { perror("malloc"); goto out; } if (lseek(fd, base, SEEK_SET) == -1) { fprintf(stderr, "%s: ", filename); perror("lseek"); goto err_free; } if (myread(fd, p, *max_len, filename) == 0) goto out; err_free: free(p); p = NULL; out: if (close(fd) == -1) perror(filename); return p; } static void safe_memcpy(void *dest, const void *src, size_t n) { #ifdef USE_SLOW_MEMCPY size_t i; for (i = 0; i < n; i++) *((u8 *)dest + i) = *((const u8 *)src + i); #else memcpy(dest, src, n); #endif } /* * Copy a physical memory chunk into a memory buffer. * This function allocates memory. */ void *mem_chunk(off_t base, size_t len, const char *devmem) { void *p; int fd; #ifdef USE_MMAP struct stat statbuf; off_t mmoffset; void *mmp; #endif if ((fd = open(devmem, O_RDONLY)) == -1) { perror(devmem); return NULL; } if ((p = malloc(len)) == NULL) { perror("malloc"); goto out; } #ifdef USE_MMAP if (fstat(fd, &statbuf) == -1) { fprintf(stderr, "%s: ", devmem); perror("stat"); goto err_free; } /* * mmap() will fail with SIGBUS if trying to map beyond the end of * the file. */ if (S_ISREG(statbuf.st_mode) && base + (off_t)len > statbuf.st_size) { fprintf(stderr, "mmap: Can't map beyond end of file %s\n", devmem); goto err_free; } #ifdef _SC_PAGESIZE mmoffset = base % sysconf(_SC_PAGESIZE); #else mmoffset = base % getpagesize(); #endif /* _SC_PAGESIZE */ /* * Please note that we don't use mmap() for performance reasons here, * but to workaround problems many people encountered when trying * to read from /dev/mem using regular read() calls. */ mmp = mmap(NULL, mmoffset + len, PROT_READ, MAP_SHARED, fd, base - mmoffset); if (mmp == MAP_FAILED) goto try_read; safe_memcpy(p, (u8 *)mmp + mmoffset, len); if (munmap(mmp, mmoffset + len) == -1) { fprintf(stderr, "%s: ", devmem); perror("munmap"); } goto out; try_read: #endif /* USE_MMAP */ if (lseek(fd, base, SEEK_SET) == -1) { fprintf(stderr, "%s: ", devmem); perror("lseek"); goto err_free; } if (myread(fd, p, len, devmem) == 0) goto out; err_free: free(p); p = NULL; out: if (close(fd) == -1) perror(devmem); return p; } int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add) { FILE *f; f = fopen(dumpfile, add ? "r+b" : "wb"); if (!f) { fprintf(stderr, "%s: ", dumpfile); perror("fopen"); return -1; } if (fseek(f, base, SEEK_SET) != 0) { fprintf(stderr, "%s: ", dumpfile); perror("fseek"); goto err_close; } if (fwrite(data, len, 1, f) != 1) { fprintf(stderr, "%s: ", dumpfile); perror("fwrite"); goto err_close; } if (fclose(f)) { fprintf(stderr, "%s: ", dumpfile); perror("fclose"); return -1; } return 0; err_close: fclose(f); return -1; } /* Returns end - start + 1, assuming start < end */ u64 u64_range(u64 start, u64 end) { u64 res; res.h = end.h - start.h; res.l = end.l - start.l; if (end.l < start.l) res.h--; if (++res.l == 0) res.h++; return res; } CPU-X-4.2.0/src/dmidecode/util.h000066400000000000000000000023311403012130000161620ustar00rootroot00000000000000/* * This file is part of the dmidecode project. * * Copyright (C) 2003-2017 Jean Delvare * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "types.h" #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) int checksum(const u8 *buf, size_t len); void *read_file(off_t base, size_t *len, const char *filename); void *mem_chunk(off_t base, size_t len, const char *devmem); int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add); u64 u64_range(u64 start, u64 end); CPU-X-4.2.0/src/gui_gtk.c000066400000000000000000000757751403012130000147420ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE gui_gtk.c */ #include #include #include #include #include #include #include "cpu-x.h" #include "ipc.h" #include "gui_gtk.h" #include "gui_gtk_id.h" /************************* Public function *************************/ /* Load and apply settings from GSettings */ void load_settings() { settings = g_settings_new(PRGNAME_LOW); theme = g_settings_get_enum(settings, "gui-theme"); opts->refr_time = g_settings_get_uint(settings, "refresh-time"); opts->selected_page = g_settings_get_enum(settings, "default-tab"); opts->selected_core = g_settings_get_uint(settings, "default-cpu-core"); opts->bw_test = g_settings_get_uint(settings, "default-cache-test"); opts->selected_gpu = g_settings_get_uint(settings, "default-active-card"); opts->cpuid_decimal = g_settings_get_boolean(settings, "print-cpuid-decimal"); opts->with_daemon = g_settings_get_boolean(settings, "always-start-daemon"); g_settings_delay(settings); } /* Start CPU-X in GTK mode */ void start_gui_gtk(int *argc, char **argv[], Labels *data) { int i; GtkLabels glab; GThrd refr = { &glab, data }; GtkBuilder *builder = gtk_builder_new(); const gchar *ui_files[] = { "cpu-x-gtk-3.12.ui", NULL }; MSG_VERBOSE("%s", _("Starting GTK GUI…")); gtk_init(argc, argv); g_set_prgname(PRGNAME_LOW); /* Build UI from Glade file */ for(i = 0; (ui_files[i] != NULL) && (!gtk_builder_add_from_file(builder, data_path(ui_files[i]), NULL)); i++); if(ui_files[i] == NULL) { MSG_ERROR("%s", _("failed to import UI in GtkBuilder")); exit(EXIT_FAILURE); } /* Set widgets */ get_widgets(builder, &glab); g_object_unref(G_OBJECT(builder)); set_colors (&glab); set_logos (&glab, data); set_labels (&glab, data); set_signals(&glab, data, &refr); labels_free(data); /* Bind settings to get_widgets */ g_settings_bind(settings, "refresh-time", glab.refreshtime, "value", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "gui-theme", glab.theme, "active-id", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "default-tab", glab.defaulttab, "active-id", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "default-cpu-core", glab.defaultcore, "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "default-cache-test", glab.defaultcachetest, "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "default-active-card", glab.defaultcard, "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "print-cpuid-decimal", glab.cpuiddecimal, "active", G_SETTINGS_BIND_DEFAULT); g_settings_bind(settings, "always-start-daemon", glab.startdaemon, "active", G_SETTINGS_BIND_DEFAULT); g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, opts->refr_time, (gpointer)grefresh, &refr, modify_refresh_time); gtk_main(); if(data->reload) execvp((*argv)[0], *argv); } /************************* Private functions *************************/ /* Refresh dynamic values */ static gboolean grefresh(GThrd *refr) { int i; gboolean ret = true; Labels *(data) = refr->data; GtkLabels *(glab) = refr->glab; uint16_t new_refr_time = g_settings_get_uint(settings, "refresh-time"); static uint16_t old_refr_time = 0; opts->selected_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(glab->notebook)); do_refresh(data); switch(opts->selected_page) { case NO_CPU: gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][VOLTAGE]), data->tab_cpu[VALUE][VOLTAGE]); gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][TEMPERATURE]), data->tab_cpu[VALUE][TEMPERATURE]); gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][MULTIPLIER]), data->tab_cpu[VALUE][MULTIPLIER]); gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][CORESPEED]), data->tab_cpu[VALUE][CORESPEED]); gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][USAGE]), data->tab_cpu[VALUE][USAGE]); break; case NO_CACHES: for(i = L1SPEED; i < data->cache_count * CACHEFIELDS; i += CACHEFIELDS) gtk_label_set_text(GTK_LABEL(glab->gtktab_caches[VALUE][i]), data->tab_caches[VALUE][i]); break; case NO_SYSTEM: gtk_label_set_text(GTK_LABEL(glab->gtktab_system[VALUE][UPTIME]), data->tab_system[VALUE][UPTIME]); for(i = USED; i < LASTSYSTEM; i++) gtk_label_set_text(GTK_LABEL(glab->gtktab_system[VALUE][i]), data->tab_system[VALUE][i]); break; case NO_GRAPHICS: gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1PCIE]), data->tab_graphics[VALUE][GPU1PCIE + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1TEMPERATURE]), data->tab_graphics[VALUE][GPU1TEMPERATURE + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1USAGE]), data->tab_graphics[VALUE][GPU1USAGE + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1VOLTAGE]), data->tab_graphics[VALUE][GPU1VOLTAGE + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1POWERAVG]), data->tab_graphics[VALUE][GPU1POWERAVG + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1CORECLOCK]), data->tab_graphics[VALUE][GPU1CORECLOCK + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1MEMCLOCK]), data->tab_graphics[VALUE][GPU1MEMCLOCK + opts->selected_gpu * GPUFIELDS]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][GPU1MEMUSED]), data->tab_graphics[VALUE][GPU1MEMUSED + opts->selected_gpu * GPUFIELDS]); break; case NO_BENCH: for(i = PRIMESLOWSCORE; i <= PRIMEFASTSCORE; i += BENCHFIELDS) gtk_progress_bar_set_text(GTK_PROGRESS_BAR(glab->gtktab_bench[VALUE][i]), data->tab_bench[VALUE][i]); change_benchsensitive(glab, data); break; default: break; } /* Destroy current timeout when refresh time is updated Note: modify_refresh_time() will create a new timeout */ if(old_refr_time == 0) old_refr_time = new_refr_time; ret = (old_refr_time == new_refr_time); old_refr_time = new_refr_time; return ret; } /* Create new timeout when old one is destroyed */ static void modify_refresh_time(gpointer data) { opts->refr_time = g_settings_get_uint(settings, "refresh-time"); g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, opts->refr_time, (gpointer)grefresh, data, modify_refresh_time); } /* Show settings window */ static void open_settings_window(GtkWidget *__button, GtkLabels *glab) { UNUSED(__button); gtk_widget_show(GTK_WIDGET(glab->settingswindow)); } /* Hide settings window and revert changes */ static gboolean hide_settings_window(GtkWidget *widget, GdkEvent *event, GtkLabels *glab) { UNUSED(event); UNUSED(glab); g_settings_revert(settings); gtk_widget_hide(widget); return TRUE; } /* Hide settings window and revert changes */ static void close_settings_window(GtkWidget *__button, GtkLabels *glab) { UNUSED(__button); g_settings_revert(settings); gtk_widget_hide(GTK_WIDGET(glab->settingswindow)); } /* Hide settings window and apply changes */ static void save_settings(GtkWidget *__button, GtkLabels *glab) { UNUSED(__button); theme = g_settings_get_enum(settings, "gui-theme"); set_colors(glab); g_settings_apply(settings); gtk_widget_hide(GTK_WIDGET(glab->settingswindow)); } /* Start daemon and reload CPU-X */ static void reload_with_daemon(GtkWidget *button, GThrd *refr) { Labels *(data) = refr->data; GtkLabels *(glab) = refr->glab; gtk_widget_set_sensitive(button, false); const char *msg = start_daemon(true); if(msg == NULL) { data->reload = true; gtk_main_quit(); } else { GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(glab->mainwindow), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "%s", _(msg)); if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_CLOSE) gtk_widget_destroy(GTK_WIDGET(dialog)); gtk_widget_set_sensitive(button, true); } } /* Event in CPU tab when Core number is changed */ static void change_activecore(GtkComboBox *box, Labels *data) { const gint core = gtk_combo_box_get_active(GTK_COMBO_BOX(box)); if(0 <= core && core < data->cpu_count) opts->selected_core = core; } /* Event in Caches tab when Test number is changed */ static void change_activetest(GtkComboBox *box, Labels *data) { const gint test = gtk_combo_box_get_active(GTK_COMBO_BOX(box)); if(0 <= test && test < data->w_data->test_count) opts->bw_test = test; } /* Event in Graphics tab when graphic card is changed */ static void change_activecard(GtkComboBox *box, GThrd *refr) { int i, j; Labels *(data) = refr->data; GtkLabels *(glab) = refr->glab; const gint gpu = gtk_combo_box_get_active(GTK_COMBO_BOX(box)); if(0 <= gpu && gpu < data->gpu_count) { opts->selected_gpu = gpu; gtk_label_set_text(GTK_LABEL(glab->gtktrad[FRAMGPU1]), data->objects[FRAMGPU1 + opts->selected_gpu]); for(i = opts->selected_gpu * GPUFIELDS, j = 0; j < GPUFIELDS; i++, j++) gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][j]), data->tab_graphics[VALUE][i]); } } /* Events in Bench tab when a benchmark start/stop */ static void start_benchmark_bg(GtkSwitch *gswitch, GdkEvent *__event, GThrd *refr) { UNUSED(__event); Labels *data = refr->data; if(!data->b_data->run) { change_benchsensitive(refr->glab, data); data->b_data->fast_mode = !strcmp(gtk_widget_get_name(GTK_WIDGET(gswitch)), objectbench[PRIMEFASTRUN]); start_benchmarks(data); } else data->b_data->run = false; } /* Events in Bench tab when Duration/Threads SpinButtons are changed */ static void change_benchparam(GtkSpinButton *spinbutton, Labels *data) { const gint val = gtk_spin_button_get_value_as_int(spinbutton); if(!g_strcmp0(gtk_widget_get_name (GTK_WIDGET(spinbutton)), objectbench[PARAMDURATION])) data->b_data->duration = val; else if(!g_strcmp0(gtk_widget_get_name(GTK_WIDGET(spinbutton)), objectbench[PARAMTHREADS])) data->b_data->threads = val; gtk_spin_button_update(spinbutton); } /* Set/Unset widgets sensitive when a benchmark start/stop */ static void change_benchsensitive(GtkLabels *glab, Labels *data) { static gboolean skip = false; const enum EnTabBench indP = data->b_data->fast_mode ? PRIMEFASTSCORE : PRIMESLOWSCORE; const enum EnTabBench indS = data->b_data->fast_mode ? PRIMESLOWRUN : PRIMEFASTRUN; const enum EnTabBench indA = data->b_data->fast_mode ? PRIMEFASTRUN : PRIMESLOWRUN; if(data->b_data->run) { skip = false; #if GTK_CHECK_VERSION(3, 15, 0) gtk_switch_set_state(GTK_SWITCH(glab->gtktab_bench[VALUE][indA]), true); #endif /* GTK_CHECK_VERSION(3, 15, 0) */ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(glab->gtktab_bench[VALUE][indP]), (double) data->b_data->elapsed / (data->b_data->duration * 60)); gtk_widget_set_sensitive(glab->gtktab_bench[VALUE][indS], false); gtk_widget_set_sensitive(glab->gtktab_bench[VALUE][PARAMTHREADS], false); } else if(!data->b_data->run && !skip) { skip = true; #if GTK_CHECK_VERSION(3, 15, 0) gtk_switch_set_state(GTK_SWITCH(glab->gtktab_bench[VALUE][indA]), false); #endif /* GTK_CHECK_VERSION(3, 15, 0) */ gtk_switch_set_active(GTK_SWITCH(glab->gtktab_bench[VALUE][indA]), false); gtk_widget_set_sensitive(glab->gtktab_bench[VALUE][indS], true); gtk_widget_set_sensitive(glab->gtktab_bench[VALUE][PARAMTHREADS], true); } } /* Get label ID ('type' must be "lab" or "val") */ static gchar *get_id(const gchar *objectstr, gchar *type) { static gchar *buff = NULL; gchar **split; g_free(buff); split = g_strsplit(objectstr, "_", 2); buff = g_strconcat(split[0], "_", type, split[1], NULL); g_strfreev(split); return buff; } /* Search file location in standard paths */ static gchar *data_path(const gchar *file) { int i; gboolean file_exists = false; static gchar *path = NULL; const gchar *prgname = g_get_prgname(); const gchar *const *paths = g_get_system_data_dirs(); for(i = 0; (!file_exists) && (paths[i] != NULL); i++) { g_free(path); path = g_build_filename(paths[i], prgname, file, NULL); file_exists = g_file_test(path, G_FILE_TEST_EXISTS); } return path; } /* Retrieve widgets from GtkBuilder */ static void get_widgets(GtkBuilder *builder, GtkLabels *glab) { int i; glab->mainwindow = GTK_WIDGET(gtk_builder_get_object(builder, "mainwindow")); glab->settingsbutton = GTK_WIDGET(gtk_builder_get_object(builder, "settingsbutton")); glab->daemonbutton = GTK_WIDGET(gtk_builder_get_object(builder, "daemonbutton")); glab->labprgver = GTK_WIDGET(gtk_builder_get_object(builder, "labprgver")); glab->footer = GTK_WIDGET(gtk_builder_get_object(builder, "footer_box")); glab->notebook = GTK_WIDGET(gtk_builder_get_object(builder, "header_notebook")); glab->logocpu = GTK_WIDGET(gtk_builder_get_object(builder, "proc_logocpu")); glab->activecore = GTK_WIDGET(gtk_builder_get_object(builder, "trg_activecore")); glab->activetest = GTK_WIDGET(gtk_builder_get_object(builder, "test_activetest")); glab->activecard = GTK_WIDGET(gtk_builder_get_object(builder, "cards_activecard")); glab->logoprg = GTK_WIDGET(gtk_builder_get_object(builder, "about_logoprg")); glab->butcol = GTK_WIDGET(gtk_builder_get_object(builder, "colorbutton")); glab->settingswindow = GTK_WIDGET(gtk_builder_get_object(builder, "settingswindow")); glab->validatebutton = GTK_WIDGET(gtk_builder_get_object(builder, "validatebutton")); glab->cancelbutton = GTK_WIDGET(gtk_builder_get_object(builder, "cancelbutton")); glab->refreshtime = GTK_WIDGET(gtk_builder_get_object(builder, "refreshtime_val")); glab->theme = GTK_WIDGET(gtk_builder_get_object(builder, "theme_val")); glab->defaulttab = GTK_WIDGET(gtk_builder_get_object(builder, "defaulttab_val")); glab->defaultcore = GTK_WIDGET(gtk_builder_get_object(builder, "defaultcore_val")); glab->defaultcachetest = GTK_WIDGET(gtk_builder_get_object(builder, "defaultcachetest_val")); glab->defaultcard = GTK_WIDGET(gtk_builder_get_object(builder, "defaultcard_val")); glab->cpuiddecimal = GTK_WIDGET(gtk_builder_get_object(builder, "cpuiddecimal")); glab->startdaemon = GTK_WIDGET(gtk_builder_get_object(builder, "startdaemon")); gtk_widget_set_name(glab->footer, "footer_box"); gtk_notebook_set_current_page(GTK_NOTEBOOK(glab->notebook), opts->selected_page); /* Various labels to translate */ for(i = TABCPU; i < LASTOBJ; i++) glab->gtktrad[i] = GTK_WIDGET(gtk_builder_get_object(builder, trad[i])); /* Tab CPU */ for(i = VENDOR; i < LASTCPU; i++) { glab->gtktab_cpu[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectcpu[i], "lab"))); glab->gtktab_cpu[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectcpu[i], "val"))); gtk_widget_set_name(glab->gtktab_cpu[VALUE][i], "value"); } /* Tab Caches */ for(i = L1SIZE; i < LASTCACHES; i++) { glab->gtktab_caches[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectcache[i], "lab"))); glab->gtktab_caches[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectcache[i], "val"))); gtk_widget_set_name(glab->gtktab_caches[VALUE][i], "value"); } glab->gridcaches = GTK_WIDGET(gtk_builder_get_object(builder, "caches_grid")); /* Tab Motherboard */ for(i = MANUFACTURER; i < LASTMOTHERBOARD; i++) { glab->gtktab_motherboard[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectmb[i], "lab"))); glab->gtktab_motherboard[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectmb[i], "val"))); gtk_widget_set_name(glab->gtktab_motherboard[VALUE][i], "value"); } /* Tab RAM */ for(i = BANK0; i < LASTMEMORY; i++) { glab->gtktab_memory[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectram[i], "lab"))); glab->gtktab_memory[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectram[i], "val"))); gtk_widget_set_name(glab->gtktab_memory[VALUE][i], "value"); } glab->gridbanks = GTK_WIDGET(gtk_builder_get_object(builder, "memory_grid")); glab->scrollbanks = GTK_WIDGET(gtk_builder_get_object(builder, "memory_scrolledwindow")); /* Tab System */ for(i = KERNEL; i < LASTSYSTEM; i++) { glab->gtktab_system[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectsys[i], "lab"))); glab->gtktab_system[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectsys[i], "val"))); gtk_widget_set_name(glab->gtktab_system[VALUE][i], "value"); } for(i = BARUSED; i < LASTBAR; i++) { glab->bar[i] = GTK_WIDGET(gtk_builder_get_object(builder, objectsys_bar[i])); gtk_widget_set_name(GTK_WIDGET(glab->bar[i]), format("%i", i)); } /* Tab Graphics */ for(i = GPU1VENDOR; i < GPUFIELDS; i++) { glab->gtktab_graphics[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectgpu[i], "lab"))); glab->gtktab_graphics[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectgpu[i], "val"))); gtk_widget_set_name(glab->gtktab_graphics[VALUE][i], "value"); } glab->gridcards = GTK_WIDGET(gtk_builder_get_object(builder, "graphics_box")); /* Tab Bench */ for(i = PRIMESLOWSCORE; i < LASTBENCH; i++) { glab->gtktab_bench[NAME][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectbench[i], "lab"))); glab->gtktab_bench[VALUE][i] = GTK_WIDGET(gtk_builder_get_object(builder, get_id(objectbench[i], "val"))); gtk_widget_set_name(glab->gtktab_bench[VALUE][i], objectbench[i]); } /* Tab About */ for(i = DESCRIPTION; i < LASTABOUT; i++) glab->gtktab_about[i] = GTK_WIDGET(gtk_builder_get_object(builder, objectabout[i])); } static gboolean is_dark_theme(GtkLabels *glab) { gdouble contrast; GdkRGBA *fg, *bg; GtkStyleContext *context; if (theme != AUTO) return (theme == DARK); context = gtk_widget_get_style_context(GTK_WIDGET(glab->mainwindow)); gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_COLOR, &fg, GTK_STYLE_PROPERTY_BACKGROUND_COLOR, &bg, NULL); contrast = bg->red - fg->red + bg->green - fg->green + bg->blue - fg->blue; gdk_rgba_free(fg); gdk_rgba_free(bg); return (contrast < -1); } /* Set custom GTK theme */ static void set_colors(GtkLabels *glab) { gchar *filename = NULL; GtkCssProvider *provider = gtk_css_provider_new(); if(gtk_check_version(3, 19, 2) == NULL) // GTK 3.20 or newer filename = is_dark_theme(glab) ? g_strdup("cpu-x-gtk-3.20-dark.css") : g_strdup("cpu-x-gtk-3.20.css"); else // GTK 3.12 to 3.18 filename = is_dark_theme(glab) ? g_strdup("cpu-x-gtk-3.12-dark.css") : g_strdup("cpu-x-gtk-3.12.css"); gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_css_provider_load_from_path(provider, data_path(filename), NULL); g_free(filename); g_object_unref(provider); } /* Set CPU vendor logo and program logo */ static void set_logos(GtkLabels *glab, Labels *data) { int width, height, prg_size = 72; GdkPixbuf *cpu_pixbuf = NULL, *unknown_pixbuf = NULL, *prg_pixbuf = NULL; GError *error = NULL; width = gtk_widget_get_allocated_width(glab->gtktab_cpu[VALUE][SPECIFICATION]) - gtk_widget_get_allocated_width(glab->gtktab_cpu[VALUE][VENDOR]) - 6; height = (gtk_widget_get_allocated_height(glab->gtktab_cpu[VALUE][VENDOR]) + 4) * 4; cpu_pixbuf = gdk_pixbuf_new_from_file_at_scale(data_path(format("%s.png", data->tab_cpu[VALUE][VENDOR])), width, height, TRUE, &error); unknown_pixbuf = gdk_pixbuf_new_from_file_at_scale(data_path("Unknown.png"), width, height, TRUE, NULL); prg_pixbuf = gdk_pixbuf_new_from_file_at_scale(data_path("CPU-X.png"), prg_size, prg_size, TRUE, NULL); gtk_window_set_icon(GTK_WINDOW(glab->mainwindow), prg_pixbuf); gtk_image_set_from_pixbuf(GTK_IMAGE(glab->logocpu), cpu_pixbuf); gtk_image_set_from_pixbuf(GTK_IMAGE(glab->logoprg), prg_pixbuf); g_object_unref(cpu_pixbuf); g_object_unref(prg_pixbuf); if(error != NULL) gtk_image_set_from_pixbuf(GTK_IMAGE(glab->logocpu), unknown_pixbuf); g_object_unref(unknown_pixbuf); } /* Filling all labels */ static void set_labels(GtkLabels *glab, Labels *data) { int i, j; const int pkcheck = system(format("pkcheck --action-id org.freedesktop.policykit.exec --process %u > /dev/null 2>&1", getpid())); const gint width1 = gtk_widget_get_allocated_width(glab->gtktab_system[VALUE][COMPILER]); const gint width2 = width1 - gtk_widget_get_allocated_width(glab->gtktab_system[VALUE][USED]) - 6; GtkRequisition requisition; /* Footer label */ gtk_label_set_text(GTK_LABEL(glab->labprgver), data->tab_about[VERSIONSTR]); gtk_widget_set_sensitive(glab->daemonbutton, false); if(DAEMON_UP) gtk_widget_set_tooltip_text(glab->daemonbutton, _("Connected to daemon")); else if(WEXITSTATUS(pkcheck) > 2) gtk_widget_set_tooltip_text(glab->daemonbutton, _("No polkit authentication agent found")); else { gtk_widget_set_sensitive(glab->daemonbutton, true); gtk_widget_set_tooltip_text(glab->daemonbutton, _("Ask password to start daemon in background")); } /* Various labels to translate */ for(i = TABCPU; i < LASTOBJ; i++) gtk_label_set_text(GTK_LABEL(glab->gtktrad[i]), data->objects[i]); gtk_button_set_label(GTK_BUTTON(glab->daemonbutton), _("Start daemon")); /* Tab CPU */ for(i = VENDOR; i < LASTCPU; i++) { gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[NAME][i]), data->tab_cpu[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_cpu[VALUE][i]), data->tab_cpu[VALUE][i]); } for(i = 0; i < data->cpu_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->activecore), format(_("Core #%i"), i)); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->activecore), opts->selected_core); /* Tab Caches */ for(i = L1SIZE; i < LASTCACHES; i++) { gtk_label_set_text(GTK_LABEL(glab->gtktab_caches[NAME][i]), data->tab_caches[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_caches[VALUE][i]), data->tab_caches[VALUE][i]); } for(i = LASTCACHES / CACHEFIELDS; i > data->cache_count; i--) gtk_grid_remove_row(GTK_GRID(glab->gridcaches), i - 1); for(i = 0; i < data->w_data->test_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->activetest), data->w_data->test_name[i]); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->activetest), opts->bw_test); if(!data->cache_count) gtk_widget_hide(GTK_WIDGET(glab->gridcaches)); /* Tab Motherboard */ for(i = MANUFACTURER; i < LASTMOTHERBOARD; i++) { gtk_label_set_text(GTK_LABEL(glab->gtktab_motherboard[NAME][i]), data->tab_motherboard[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_motherboard[VALUE][i]), data->tab_motherboard[VALUE][i]); } /* Tab RAM */ for(i = BANK0; i < data->dimm_count; i++) { g_strdelimit(data->tab_memory[VALUE][i], ",", '\n'); gtk_label_set_text(GTK_LABEL(glab->gtktab_memory[NAME][i]), data->tab_memory[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_memory[VALUE][i]), data->tab_memory[VALUE][i]); } for(i = BANK7; i >= data->dimm_count; i--) gtk_grid_remove_row(GTK_GRID(glab->gridbanks), i); if(!data->dimm_count) gtk_widget_hide(GTK_WIDGET(glab->scrollbanks)); /* Tab System */ for(i = KERNEL; i < LASTSYSTEM; i++) { gtk_label_set_text(GTK_LABEL(glab->gtktab_system[NAME][i]), data->tab_system[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_system[VALUE][i]), data->tab_system[VALUE][i]); } for(i = BARUSED; i < LASTBAR; i++) { gtk_widget_get_preferred_size(glab->gtktab_system[VALUE][USED], NULL, &requisition); gtk_widget_set_size_request(glab->bar[i], width2, requisition.height); } /* Tab Graphics */ for(i = opts->selected_gpu * GPUFIELDS, j = 0; j < GPUFIELDS; i++, j++) { gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[NAME][j]), data->tab_graphics[NAME][i]); gtk_label_set_text(GTK_LABEL(glab->gtktab_graphics[VALUE][j]), data->tab_graphics[VALUE][i]); } gtk_label_set_text(GTK_LABEL(glab->gtktrad[FRAMGPU1]), data->objects[FRAMGPU1 + opts->selected_gpu]); if(data->gpu_count == 0) gtk_widget_hide(GTK_WIDGET(glab->gridcards)); for(i = 0; i < data->gpu_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->activecard), format("#%i: %s", i, data->tab_graphics[VALUE][GPU1MODEL + i * GPUFIELDS])); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->activecard), opts->selected_gpu); /* Tab Bench */ for(i = PRIMESLOWSCORE; i < LASTBENCH; i++) gtk_label_set_text(GTK_LABEL(glab->gtktab_bench[NAME][i]), data->tab_bench[NAME][i]); for(i = PRIMESLOWSCORE; i <= PRIMEFASTSCORE; i += BENCHFIELDS) { gtk_progress_bar_set_text(GTK_PROGRESS_BAR(glab->gtktab_bench[VALUE][i]), data->tab_bench[VALUE][i]); gtk_widget_set_size_request(glab->gtktab_bench[VALUE][i], width1, -1); } gtk_spin_button_set_increments(GTK_SPIN_BUTTON(glab->gtktab_bench[VALUE][PARAMDURATION]), 1, 60); gtk_spin_button_set_increments(GTK_SPIN_BUTTON(glab->gtktab_bench[VALUE][PARAMTHREADS]), 1, 1); gtk_spin_button_set_range (GTK_SPIN_BUTTON(glab->gtktab_bench[VALUE][PARAMDURATION]), 1, 60 * 24); gtk_spin_button_set_range (GTK_SPIN_BUTTON(glab->gtktab_bench[VALUE][PARAMTHREADS]), 1, data->cpu_count); /* Tab About */ for(i = DESCRIPTION; i < LASTABOUT; i++) gtk_label_set_text(GTK_LABEL(glab->gtktab_about[i]), data->tab_about[i]); /* Settings window */ gtk_spin_button_set_range (GTK_SPIN_BUTTON(glab->refreshtime), 1, G_MAXUSHORT); gtk_spin_button_set_increments(GTK_SPIN_BUTTON(glab->refreshtime), 1, 60); for (i = NO_CPU; i <= NO_ABOUT; i++) gtk_combo_box_text_insert(GTK_COMBO_BOX_TEXT(glab->defaulttab), i, nicktab[i], format(_("%s"), data->objects[i])); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->defaulttab), opts->selected_page); for(i = 0; i < data->cpu_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->defaultcore), format(_("Core #%i"), i)); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->defaultcore), opts->selected_core); for(i = 0; i < data->w_data->test_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->defaultcachetest), data->w_data->test_name[i]); for(i = 0; i < data->gpu_count; i++) gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(glab->defaultcard), format("#%i: %s", i, data->tab_graphics[VALUE][GPU1MODEL + i * GPUFIELDS])); gtk_combo_box_set_active(GTK_COMBO_BOX(glab->defaultcachetest), opts->bw_test); gtk_widget_set_sensitive(GTK_WIDGET(glab->defaultcachetest), data->cache_count > 0); } /* Call defined functions on signals */ static void set_signals(GtkLabels *glab, Labels *data, GThrd *refr) { int i; g_signal_connect(glab->mainwindow, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(glab->settingswindow, "delete-event", G_CALLBACK(hide_settings_window), NULL); g_signal_connect(glab->settingsbutton, "clicked", G_CALLBACK(open_settings_window), glab); g_signal_connect(glab->daemonbutton, "clicked", G_CALLBACK(reload_with_daemon), refr); g_signal_connect(glab->activecore, "changed", G_CALLBACK(change_activecore), data); g_signal_connect(glab->activetest, "changed", G_CALLBACK(change_activetest), data); g_signal_connect(glab->activecard, "changed", G_CALLBACK(change_activecard), refr); /* Tab Bench */ g_signal_connect(glab->gtktab_bench[VALUE][PRIMESLOWRUN], "button-press-event", G_CALLBACK(start_benchmark_bg), refr); g_signal_connect(glab->gtktab_bench[VALUE][PRIMEFASTRUN], "button-press-event", G_CALLBACK(start_benchmark_bg), refr); g_signal_connect(glab->gtktab_bench[VALUE][PARAMDURATION], "value-changed", G_CALLBACK(change_benchparam), data); g_signal_connect(glab->gtktab_bench[VALUE][PARAMTHREADS], "value-changed", G_CALLBACK(change_benchparam), data); /* Tab System */ for(i = BARUSED; i < LASTBAR; i++) g_signal_connect(G_OBJECT(glab->bar[i]), "draw", G_CALLBACK(fill_frame), refr); /* Settings window */ g_signal_connect(glab->validatebutton, "clicked", G_CALLBACK(save_settings), glab); g_signal_connect(glab->cancelbutton, "clicked", G_CALLBACK(close_settings_window), glab); } /* Draw bars in Memory tab */ void fill_frame(GtkWidget *widget, cairo_t *cr, GThrd *refr) { int i = USED, page; guint width, height; double before = 0, percent = 0; const gchar *widget_name; cairo_pattern_t *pat; PangoLayout *reflayout, *newlayout; Labels *(data) = refr->data; GtkLabels *(glab) = refr->glab; widget_name = gtk_widget_get_name(widget); width = gtk_widget_get_allocated_width(widget); height = gtk_widget_get_allocated_height(widget); page = atoi(widget_name); reflayout = gtk_label_get_layout(GTK_LABEL(glab->gtktab_system[VALUE][page + USED])); newlayout = pango_layout_copy(reflayout); if((page == BARSWAP && data->m_data->swap_total == 0) || (page != BARSWAP && data->m_data->mem_total == 0)) return; for(i = BARUSED; (i <= page) && (page != BARSWAP); i++) /* Get value to start */ { before += percent; percent = (double) data->m_data->mem_usage[i] / data->m_data->mem_total * 100; } if(page == BARSWAP) percent = (double) data->m_data->mem_usage[BARSWAP] / data->m_data->swap_total * 100; pat = cairo_pattern_create_linear(before / 100 * width, 0, percent / 100 * width, height); switch(page) /* Set differents level bar color */ { case BARUSED: // yellow pat = is_dark_theme(glab) ? cairo_pattern_create_rgba(0.01, 0.02, 0.37, 1.00) : cairo_pattern_create_rgba(1.00, 0.92, 0.23, 1.00); break; case BARBUFFERS: // blue pat = is_dark_theme(glab) ? cairo_pattern_create_rgba(0.01, 0.24, 0.54, 1.00) : cairo_pattern_create_rgba(0.13, 0.59, 0.95, 1.00); break; case BARCACHED: // purple pat = is_dark_theme(glab) ? cairo_pattern_create_rgba(0.00, 0.47, 0.71, 1.00) : cairo_pattern_create_rgba(0.61, 0.15, 0.69, 1.00); break; case BARFREE: // green pat = is_dark_theme(glab) ? cairo_pattern_create_rgba(0.00, 0.59, 0.78, 1.00) : cairo_pattern_create_rgba(0.30, 0.69, 0.31, 1.00); break; case BARSWAP: // red pat = is_dark_theme(glab) ? cairo_pattern_create_rgba(0.00, 0.71, 0.85, 1.00) : cairo_pattern_create_rgba(0.96, 0.26, 0.21, 1.00); break; } cairo_rectangle(cr, before / 100 * width, 0, percent / 100 * width, height); /* Print a colored rectangle */ cairo_set_source(cr, pat); cairo_fill(cr); cairo_pattern_destroy(pat); /* Print percentage */ if(is_dark_theme(glab)) cairo_set_source_rgb(cr, 0.8080, 0.8080, 0.0); else cairo_set_source_rgb(cr, 0.0, 0.0, 0.8080); cairo_move_to(cr, -40, 0); pango_layout_set_text(newlayout, format("%.2f%%", percent), -1); pango_cairo_show_layout(cr, newlayout); cairo_fill(cr); g_object_unref(newlayout); } CPU-X-4.2.0/src/gui_gtk.h000066400000000000000000000113171403012130000147250ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE gui_gtk.h */ #ifndef _GUI_GTK_H_ #define _GUI_GTK_H_ #include #include #include typedef struct { /* Common */ GtkWidget *mainwindow; GtkWidget *settingsbutton; GtkWidget *notebook; GtkWidget *footer; GtkWidget *labprgver; GtkWidget *daemonbutton; GtkWidget *gtktrad[LASTOBJ]; /* Settings */ GtkWidget *settingswindow; GtkWidget *validatebutton; GtkWidget *cancelbutton; GtkWidget *refreshtime; GtkWidget *theme; GtkWidget *defaulttab; GtkWidget *defaultcore; GtkWidget *defaultcachetest; GtkWidget *defaultcard; GtkWidget *cpuiddecimal; GtkWidget *startdaemon; /* Tab CPU */ GtkWidget *logocpu; GtkWidget *gtktab_cpu[2][LASTCPU]; GtkWidget *activecore; /* Tab Caches */ GtkWidget *gridcaches; GtkWidget *gtktab_caches[2][LASTCACHES]; GtkWidget *activetest; /* Tab Motherboard */ GtkWidget *gtktab_motherboard[2][LASTMOTHERBOARD]; /* Tab RAM */ GtkWidget *scrollbanks; GtkWidget *gridbanks; GtkWidget *gtktab_memory[2][LASTMEMORY]; /* Tab System */ GtkWidget *bar[LASTBAR]; GtkWidget *gtktab_system[2][LASTSYSTEM]; /* Tab Graphics */ GtkWidget *gridcards; GtkWidget *gtktab_graphics[2][GPUFIELDS]; GtkWidget *activecard; /* Tab Bench */ GtkWidget *gtktab_bench[2][LASTBENCH]; /* Tab About */ GtkWidget *logoprg; GtkWidget *butcol; GtkWidget *gtktab_about[LASTABOUT]; } GtkLabels; /* Useful GtkWidgets */ static enum { AUTO, LIGHT, DARK } theme = AUTO; typedef struct { GtkLabels *glab; Labels *data; } GThrd; /* Used to refresh GUI */ /********************************** GUI **********************************/ /* Load and apply settings from GSettings */ void load_settings(void); /* Start CPU-X in GTK mode */ void start_gui_gtk(int *argc, char **argv[], Labels *data); /* Refresh dynamic values */ static gboolean grefresh(GThrd *refr); /* Create new timeout when old one is destroyed */ static void modify_refresh_time(gpointer data); /* Show settings window */ static void open_settings_window(GtkWidget *button, GtkLabels *glab); /* Hide settings window and revert changes */ static gboolean hide_settings_window(GtkWidget *widget, GdkEvent *event, GtkLabels *glab); /* Hide settings window and revert changes */ static void close_settings_window(GtkWidget *button, GtkLabels *glab); /* Hide settings window and apply changes */ static void save_settings(GtkWidget *button, GtkLabels *glab); /* Start daemon and reload CPU-X */ static void reload_with_daemon(GtkWidget *button, GThrd *refr); /* Event in CPU tab when Core number is changed */ static void change_activecore(GtkComboBox *box, Labels *data); /* Event in Caches tab when Test number is changed */ static void change_activetest(GtkComboBox *box, Labels *data); /* Events in Bench tab when a benchmark start/stop */ static void start_benchmark_bg(GtkSwitch *gswitch, GdkEvent *event, GThrd *refr); /* Events in Bench tab when Duration/Threads SpinButtons are changed */ static void change_benchparam(GtkSpinButton *spinbutton, Labels *data); /* Set/Unset widgets sensitive when a benchmark start/stop */ static void change_benchsensitive(GtkLabels *glab, Labels *data); /* Get label ID ('type' must be "lab" or "val") */ static gchar *get_id(const gchar *objectstr, gchar *type); /* Search file location in standard paths */ static gchar *data_path(const gchar *file); /* Retrieve widgets from GtkBuilder */ static void get_widgets(GtkBuilder *builder, GtkLabels *glab); /* Set custom GTK theme */ static void set_colors(GtkLabels *glab); /* Set CPU vendor logo and program logo */ static void set_logos(GtkLabels *glab, Labels *data); /* Filling all labels */ static void set_labels(GtkLabels *glab, Labels *data); /* Call defined functions on signals */ static void set_signals(GtkLabels *glab, Labels *data, GThrd *refr); /* Draw bars in Memory tab */ void fill_frame(GtkWidget *widget, cairo_t *cr, GThrd *refr); #endif /* _GUI_GTK_H_ */ CPU-X-4.2.0/src/gui_gtk_id.h000066400000000000000000000071771403012130000154120ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE gui_gtk_id.h */ #ifndef _GUI_GTK_ID_H_ #define _GUI_GTK_ID_H_ static GSettings *settings = NULL; /* Translation */ static const char *trad[LASTOBJ] = { "cpulabel", "cacheslabel", "motherboardlabel", "ramlabel", "systemlabel", "graphicslabel", "benchlabel", "aboutlabel", "proc_lab", "clock_lab", "cache_lab", "l1cache_lab", "l2cache_lab", "l3cache_lab", "l4cache_lab", "test_lab", "motherboard_lab", "bios_lab", "chip_lab", "bank0_lab", "bank1_lab", "bank2_lab", "bank3_lab", "bank4_lab", "bank5_lab", "bank6_lab", "bank7_lab", "os_lab", "mem_lab", "card0_lab", "card0_lab", "card0_lab", "card0_lab", "card0_lab", "card0_lab", "card0_lab", "card0_lab", "cards_lab", "primeslow_lab", "primefast_lab", "param_lab", "about_lab", "license_lab" }; /* Tab CPU */ static const char *objectcpu[LASTCPU] = { "proc_vendor", "proc_cdename", "proc_pkg", "proc_tech", "proc_volt", "proc_spec", "proc_fam", "proc_extfam", "proc_mod", "proc_extmod", "proc_temp", "proc_step", "proc_instr", "clock_core", "clock_mult", "clock_bus", "clock_usage", "cache_l1d", "cache_l1i", "cache_l2", "cache_l3", "trg_sock", "trg_core", "trg_thrd" }; /* Tab Caches */ static const char *objectcache[LASTCACHES] = { "l1cache_size", "l1cache_speed", "l2cache_size", "l2cache_speed", "l3cache_size", "l3cache_speed", "l4cache_size", "l4cache_speed" }; /* Tab Motherboard */ static const char *objectmb[LASTMOTHERBOARD] = { "motherboard_manu", "motherboard_mod", "motherboard_rev", "bios_brand", "bios_vers", "bios_date", "bios_rom", "chip_vend", "chip_name" }; /* Tab RAM */ static const char *objectram[LASTMEMORY] = { "bank0_ref", "bank1_ref", "bank2_ref", "bank3_ref", "bank4_ref", "bank5_ref", "bank6_ref", "bank7_ref" }; /* Tab System */ static const char *objectsys[LASTSYSTEM] = { "os_kern", "os_distro", "os_host", "os_uptime", "os_comp", "mem_used", "mem_buff", "mem_cache", "mem_free", "mem_swap" }; static const char *objectsys_bar[LASTBAR] = { "mem_barused", "mem_barbuff", "mem_barcache", "mem_barfree", "mem_barswap" }; /* Tab Graphics */ static const char *objectgpu[GPUFIELDS] = { "card0_vend", "card0_driver", "card0_umd", "card0_mod", "card0_did_rid", "card0_pcie", "card0_temp", "card0_usage", "card0_gvolt", "card0_gpwr", "card0_gclk", "card0_mclk", "card0_vram_used" }; /* Tab Bench */ static const char *objectbench[LASTBENCH] = { "primeslow_score", "primeslow_run", "primefast_score", "primefast_run", "param_duration", "param_threads" }; /* Tab About */ static const char *objectabout[LASTABOUT] = { "about_descr", "about_version", "about_author", "about_site", "license_labcopyright", "license_lablicense", "license_nowarranty" }; static const char *nicktab[NO_ABOUT + 1] = { "cpu", "caches", "motherboad", "memory", "system", "graphics", "bench", "about" }; #endif /* _GUI_GTK_ID_H_ */ CPU-X-4.2.0/src/ipc.h000066400000000000000000000035331403012130000140500ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE ipc.h */ #ifndef _IPC_H_ #define _IPC_H_ #include "cpu-x.h" #ifdef __linux__ # define SOCKET_NAME "/run/cpu-x.sock" #else /* __linux__ */ # define SOCKET_NAME "/var/run/cpu-x.sock" #endif /* __linux__ */ #define DAEMON_UP (data->socket_fd >= 0) #define SEND_DATA(pfd, pdata, size) if(write(*pfd, pdata, size) != size) { MSG_ERRNO("%s", "write"); close(*pfd); *pfd = -1; return 1; } #define RECEIVE_DATA(pfd, pdata, size) if(read (*pfd, pdata, size) != size) { MSG_ERRNO("%s", "read"); close(*pfd); *pfd = -1; return 1; } typedef enum { LIBCPUID_MSR_STATIC, LIBCPUID_MSR_DYNAMIC, DMIDECODE, ACCESS_DEV_PCI, ACCESS_SYS_DEBUG, LOAD_MODULE, } DaemonCommand; typedef struct { int min_mult, max_mult, bclk; } MsrStaticData; typedef struct { int voltage, temp; } MsrDynamicData; typedef struct { int ret; uint8_t dimm_count; double bus_freq; char cpu_package[MAXSTR]; char motherboard[CHIPVENDOR][MAXSTR]; char memory[LASTMEMORY][MAXSTR]; } DmidecodeData; #endif /* _IPC_H_ */ CPU-X-4.2.0/src/main.c000066400000000000000000000732721403012130000142230ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE main.c */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include "cpu-x.h" #if HAS_GETTEXT # include #endif #define LOG_FILE "/tmp/cpu-x.log" Options *opts; /************************* Arrays management functions *************************/ /* Set labels name */ static void labels_setname(Labels *data) { int i, j; MSG_VERBOSE("%s", _("Setting label names")); /* CPU tab */ asprintf(&data->objects[TABCPU], _("CPU")); // Tab label asprintf(&data->objects[FRAMPROCESSOR], _("Processor")); // Frame label asprintf(&data->tab_cpu[NAME][VENDOR], _("Vendor")); asprintf(&data->tab_cpu[NAME][CODENAME], _("Code Name")); asprintf(&data->tab_cpu[NAME][PACKAGE], _("Package")); asprintf(&data->tab_cpu[NAME][TECHNOLOGY], _("Technology")); asprintf(&data->tab_cpu[NAME][VOLTAGE], _("Voltage")); asprintf(&data->tab_cpu[NAME][SPECIFICATION], _("Specification")); asprintf(&data->tab_cpu[NAME][FAMILY], _("Family")); asprintf(&data->tab_cpu[NAME][EXTFAMILY], _("Ext. Family")); asprintf(&data->tab_cpu[NAME][MODEL], _("Model")); asprintf(&data->tab_cpu[NAME][EXTMODEL], _("Ext. Model")); asprintf(&data->tab_cpu[NAME][TEMPERATURE], _("Temp.")); asprintf(&data->tab_cpu[NAME][STEPPING], _("Stepping")); asprintf(&data->tab_cpu[NAME][INSTRUCTIONS], _("Instructions")); asprintf(&data->objects[FRAMCLOCKS], _("Clocks")); // Frame label asprintf(&data->tab_cpu[NAME][CORESPEED], _("Core Speed")); asprintf(&data->tab_cpu[NAME][MULTIPLIER], _("Multiplier")); asprintf(&data->tab_cpu[NAME][BUSSPEED], _("Bus Speed")); asprintf(&data->tab_cpu[NAME][USAGE], _("Usage")); asprintf(&data->objects[FRAMCACHE], _("Cache")); // Frame label asprintf(&data->tab_cpu[NAME][LEVEL1D], _("L1 Data")); asprintf(&data->tab_cpu[NAME][LEVEL1I], _("L1 Inst.")); asprintf(&data->tab_cpu[NAME][LEVEL2], _("Level 2")); asprintf(&data->tab_cpu[NAME][LEVEL3], _("Level 3")); asprintf(&data->tab_cpu[NAME][SOCKETS], _("Socket(s)")); asprintf(&data->tab_cpu[NAME][CORES], _("Core(s)")); asprintf(&data->tab_cpu[NAME][THREADS], _("Thread(s)")); /* Caches tab */ asprintf(&data->objects[TABCACHES], _("Caches")); // Tab label for(i = L1SIZE; i < LASTCACHES; i += CACHEFIELDS) { j = i / CACHEFIELDS; asprintf(&data->objects[FRAML1CACHE + j], _("L%i Cache"), j + 1); // Frame label asprintf(&data->tab_caches[NAME][L1SIZE + i], _("Size")); asprintf(&data->tab_caches[NAME][L1SPEED + i], _("Speed")); } asprintf(&data->objects[FRAMTEST], _("Test")); /* Motherboard tab */ asprintf(&data->objects[TABMOTHERBOARD], _("Motherboard")); // Tab label asprintf(&data->objects[FRAMMOTHERBOARD], _("Motherboard")); // Frame label asprintf(&data->tab_motherboard[NAME][MANUFACTURER], _("Manufacturer")); asprintf(&data->tab_motherboard[NAME][MBMODEL], _("Model")); asprintf(&data->tab_motherboard[NAME][REVISION], _("Revision")); asprintf(&data->objects[FRAMBIOS], _("BIOS")); // Frame label asprintf(&data->tab_motherboard[NAME][BRAND], _("Brand")); asprintf(&data->tab_motherboard[NAME][BIOSVERSION], _("Version")); asprintf(&data->tab_motherboard[NAME][DATE], _("Date")); asprintf(&data->tab_motherboard[NAME][ROMSIZE], _("ROM Size")); asprintf(&data->objects[FRAMCHIPSET], _("Chipset")); // Frame label asprintf(&data->tab_motherboard[NAME][CHIPVENDOR], _("Vendor")); asprintf(&data->tab_motherboard[NAME][CHIPMODEL], _("Model")); /* Memory tab */ asprintf(&data->objects[TABMEMORY], _("Memory")); // Tab label for(i = BANK0; i < LASTMEMORY; i++) { asprintf(&data->objects[FRAMBANK0 + i], _("Bank %i"), i); asprintf(&data->tab_memory[NAME][i], _("Reference")); } /* System tab */ asprintf(&data->objects[TABSYSTEM], _("System")); // Tab label asprintf(&data->objects[FRAMOPERATINGSYSTEM], _("Operating System")); // Frame label asprintf(&data->tab_system[NAME][KERNEL], _("Kernel")); asprintf(&data->tab_system[NAME][DISTRIBUTION], _("Distribution")); asprintf(&data->tab_system[NAME][HOSTNAME], _("Hostname")); asprintf(&data->tab_system[NAME][UPTIME], _("Uptime")); asprintf(&data->tab_system[NAME][COMPILER], _("Compiler")); asprintf(&data->objects[FRAMMEMORY], _("Memory")); // Frame label asprintf(&data->tab_system[NAME][USED], _("Used")); asprintf(&data->tab_system[NAME][BUFFERS], _("Buffers")); asprintf(&data->tab_system[NAME][CACHED], _("Cached")); asprintf(&data->tab_system[NAME][FREE], _("Free")); asprintf(&data->tab_system[NAME][SWAP], _("Swap")); /* Graphics tab */ asprintf(&data->objects[TABGRAPHICS], _("Graphics")); // Tab label for(i = GPU1VENDOR; i < LASTGRAPHICS; i += GPUFIELDS) { j = i / GPUFIELDS; asprintf(&data->objects[FRAMGPU1 + j], _("Card %i"), j); // Frame label asprintf(&data->tab_graphics[NAME][GPU1VENDOR + i], _("Vendor")); asprintf(&data->tab_graphics[NAME][GPU1DRIVER + i], _("Driver")); asprintf(&data->tab_graphics[NAME][GPU1UMD + i], _("UMD Version")); asprintf(&data->tab_graphics[NAME][GPU1MODEL + i], _("Model")); asprintf(&data->tab_graphics[NAME][GPU1DIDRID + i], _("DeviceID")); asprintf(&data->tab_graphics[NAME][GPU1PCIE + i], _("Interface")); asprintf(&data->tab_graphics[NAME][GPU1TEMPERATURE + i], _("Temperature")); asprintf(&data->tab_graphics[NAME][GPU1USAGE + i], _("Usage")); asprintf(&data->tab_graphics[NAME][GPU1VOLTAGE + i], _("Core Voltage")); asprintf(&data->tab_graphics[NAME][GPU1POWERAVG + i], _("Power Avg")); asprintf(&data->tab_graphics[NAME][GPU1CORECLOCK + i], _("GPU clock")); asprintf(&data->tab_graphics[NAME][GPU1MEMCLOCK + i], _("Memory clock")); asprintf(&data->tab_graphics[NAME][GPU1MEMUSED + i], _("Memory Used")); } asprintf(&data->objects[FRAMCARDS], _("Cards")); // Frame label /* Bench tab */ asprintf(&data->objects[TABBENCH], _("Bench")); // Tab label asprintf(&data->objects[FRAMPRIMESLOW], _("Prime numbers (slow)")); // Frame label asprintf(&data->objects[FRAMPRIMEFAST], _("Prime numbers (fast)")); // Frame label for(i = PRIMESLOWSCORE; i < PARAMDURATION; i += BENCHFIELDS) { asprintf(&data->tab_bench[NAME][PRIMESLOWSCORE + i], _("Score")); asprintf(&data->tab_bench[NAME][PRIMESLOWRUN + i], _("Run")); } asprintf(&data->objects[FRAMPARAM], _("Parameters")); // Frame label asprintf(&data->tab_bench[NAME][PARAMDURATION], _("Duration")); asprintf(&data->tab_bench[NAME][PARAMTHREADS], _("Threads")); /* About tab */ asprintf(&data->objects[TABABOUT], _("About")); // Tab label asprintf(&data->tab_about[DESCRIPTION], _( "%s is a Free software that gathers information\n" "on CPU, motherboard and more."), PRGNAME); asprintf(&data->objects[FRAMABOUT], _("About")); // Frame label asprintf(&data->tab_about[VERSIONSTR], _("Version %s"), PRGVER); asprintf(&data->tab_about[AUTHOR], _("Author: %s"), PRGAUTH); asprintf(&data->tab_about[SITE], _("Site: %s"), PRGURL); asprintf(&data->objects[FRAMLICENSE], _("License")); // Frame label asprintf(&data->tab_about[COPYRIGHT], PRGCPRGHT); asprintf(&data->tab_about[LICENSE], _( "This software is distributed under the terms of %s"), PRGLCNS); asprintf(&data->tab_about[NOWARRANTY], _( "This program comes with ABSOLUTELY NO WARRANTY")); /* Initialize all values */ Arrays arrays[] = { { data->tab_cpu[NAME], data->tab_cpu[VALUE], LASTCPU }, { data->tab_caches[NAME], data->tab_caches[VALUE], LASTCACHES }, { data->tab_motherboard[NAME], data->tab_motherboard[VALUE], LASTMOTHERBOARD }, { data->tab_memory[NAME], data->tab_memory[VALUE], LASTMEMORY }, { data->tab_system[NAME], data->tab_system[VALUE], LASTSYSTEM }, { data->tab_graphics[NAME], data->tab_graphics[VALUE], LASTGRAPHICS }, { data->tab_bench[NAME], data->tab_bench[VALUE], LASTBENCH }, { NULL, NULL, 0 } }; for(i = 0; arrays[i].dim_names != NULL; i++) { for(j = 0; j < arrays[i].last; j++) casprintf(&arrays[i].dim_values[j], false, "%c", '\0'); } } /* Dump all data in stdout */ static void dump_data(Labels *data) { int i, j, k = 0; const char *col_start = opts->color ? BOLD_BLUE : ""; const char *col_end = opts->color ? DEFAULT : ""; const Arrays arrays[] = { { data->tab_cpu[NAME], data->tab_cpu[VALUE], LASTCPU }, { data->tab_caches[NAME], data->tab_caches[VALUE], data->cache_count * CACHEFIELDS }, { data->tab_motherboard[NAME], data->tab_motherboard[VALUE], LASTMOTHERBOARD }, { data->tab_memory[NAME], data->tab_memory[VALUE], data->dimm_count }, { data->tab_system[NAME], data->tab_system[VALUE], LASTSYSTEM }, { data->tab_graphics[NAME], data->tab_graphics[VALUE], data->gpu_count * GPUFIELDS }, { NULL, NULL, 0 } }; const struct { int tab_nb, lab_nb, frame_nb; } frames[] = { { NO_CPU, VENDOR, FRAMPROCESSOR }, { NO_CPU, CORESPEED, FRAMCLOCKS }, { NO_CPU, LEVEL1D, FRAMCACHE }, { NO_CPU, SOCKETS, -1 }, { NO_CACHES, L1SIZE, FRAML1CACHE }, { NO_CACHES, L2SIZE, FRAML2CACHE }, { NO_CACHES, L3SIZE, FRAML3CACHE }, { NO_CACHES, L4SIZE, FRAML4CACHE }, { NO_MOTHERBOARD, MANUFACTURER, FRAMMOTHERBOARD }, { NO_MOTHERBOARD, BRAND, FRAMBIOS }, { NO_MOTHERBOARD, CHIPVENDOR, FRAMCHIPSET }, { NO_MEMORY, BANK0, FRAMBANK0 }, { NO_MEMORY, BANK1, FRAMBANK1 }, { NO_MEMORY, BANK2, FRAMBANK2 }, { NO_MEMORY, BANK3, FRAMBANK3 }, { NO_MEMORY, BANK4, FRAMBANK4 }, { NO_MEMORY, BANK5, FRAMBANK5 }, { NO_MEMORY, BANK6, FRAMBANK6 }, { NO_MEMORY, BANK7, FRAMBANK7 }, { NO_SYSTEM, KERNEL, FRAMOPERATINGSYSTEM }, { NO_SYSTEM, USED, FRAMMEMORY }, { NO_GRAPHICS, GPU1VENDOR, FRAMGPU1 }, { NO_GRAPHICS, GPU2VENDOR, FRAMGPU2 }, { NO_GRAPHICS, GPU3VENDOR, FRAMGPU3 }, { NO_GRAPHICS, GPU4VENDOR, FRAMGPU4 }, { NO_GRAPHICS, GPU5VENDOR, FRAMGPU5 }, { NO_GRAPHICS, GPU6VENDOR, FRAMGPU6 }, { NO_GRAPHICS, GPU7VENDOR, FRAMGPU7 }, { NO_GRAPHICS, GPU8VENDOR, FRAMGPU8 } }; MSG_VERBOSE("%s", _("Dumping data…")); for(i = 0; arrays[i].dim_names != NULL; i++) { MSG_STDOUT(" %s>>>>>>>>>> %s <<<<<<<<<<%s", col_start, data->objects[i], col_end); while(frames[k].tab_nb != i) k++; for(j = 0; j < arrays[i].last; j++) { if(frames[k].tab_nb == i && frames[k].lab_nb == j) { MSG_STDOUT("\n\t%s***** %s *****%s", col_start, (frames[k].frame_nb >= 0) ? data->objects[frames[k].frame_nb] : "*", col_end); k++; } MSG_STDOUT("%16s: %s", arrays[i].dim_names[j], arrays[i].dim_values[j]); } MSG_STDOUT("%s", "\n"); } labels_free(data); } /* Free memory after display labels */ void labels_free(Labels *data) { /* Note: data->objects and data->tab_graphics[VALUE] are not freed: * values inside are still read when user change active graphic card */ int i, j; Arrays arrays[] = { { data->tab_cpu[NAME], data->tab_cpu[VALUE], LASTCPU }, { data->tab_caches[NAME], data->tab_caches[VALUE], data->cache_count * CACHEFIELDS }, { data->w_data->test_name, NULL, data->w_data->test_count }, { data->tab_motherboard[NAME], data->tab_motherboard[VALUE], LASTMOTHERBOARD }, { data->tab_memory[NAME], data->tab_memory[VALUE], data->dimm_count }, { data->tab_system[NAME], data->tab_system[VALUE], LASTSYSTEM }, { data->tab_graphics[NAME], NULL, data->gpu_count * GPUFIELDS }, { data->tab_bench[NAME], data->tab_bench[VALUE], LASTBENCH }, { data->tab_about, NULL, LASTABOUT }, { NULL, NULL, 0 } }; MSG_VERBOSE("%s", _("Freeing memory")); for(i = 0; arrays[i].dim_names != NULL; i++) { for(j = 0; j < arrays[i].last; j++) { free(arrays[i].dim_names[j]); arrays[i].dim_names[j] = NULL; if(arrays[i].dim_values != NULL) { free(arrays[i].dim_values[j]); arrays[i].dim_values[j] = NULL; } } } } /************************* Options-related functions *************************/ static const struct { const bool has_mod; const char short_opt; const char *long_opt; const int need_arg; char *description; } cpux_options[] = { { HAS_GTK, 'G', "gtk", no_argument, N_("Start graphical user interface (GUI) (default)") }, { HAS_NCURSES, 'N', "ncurses", no_argument, N_("Start text-based user interface (TUI)") }, { true, 'D', "dump", no_argument, N_("Dump all data on standard output and exit") }, { HAS_DMIDECODE, 'M', "dmidecode", no_argument, N_("Run embedded command dmidecode and exit") }, { HAS_BANDWIDTH, 'B', "bandwidth", no_argument, N_("Run embedded command bandwidth and exit") }, { true, 'r', "refresh", required_argument, N_("Set custom time between two refreshes (in seconds)") }, { true, 't', "tab", required_argument, N_("Set default tab (integer)") }, { HAS_LIBCPUID, 'c', "core", required_argument, N_("Select CPU core to monitor (integer)") }, { HAS_BANDWIDTH, 'b', "cachetest", required_argument, N_("Set custom bandwidth test for CPU caches speed (integer)") }, { HAS_LIBPCI, 'g', "gpu", required_argument, N_("Select default graphic card (integer)") }, { true, 'd', "daemon", no_argument, N_("Start and connect to daemon") }, { true, 'v', "verbose", no_argument, N_("Verbose output") }, { true, 'h', "help", no_argument, N_("Print help and exit") }, { true, 'V', "version", no_argument, N_("Print version and exit") }, { HAS_LIBCPUID, 0, "cpuid-decimal", no_argument, N_("Print CPUID values in decimal (default is hexadeximal)") }, { true, 0, "nocolor", no_argument, N_("Disable colored output") }, { true, 0, "debug", no_argument, N_("Print information for debugging") }, { true, 0, "issue-fmt", no_argument, N_("Print required information to paste in an issue") }, { HAS_NCURSES, 0, "keymap", required_argument, N_("Set key mapping for NCurses mode (a[rrows]|e[macs]|i[nverted-T]|v[im])") }, { true, 0, NULL, 0, NULL } }; static const struct { const bool has_mod; const char *var_name; char *description; } cpux_env_vars[] = { { true, "CPUX_ARGS", N_("Add default command line arguments") }, { true, "CPUX_BCLK", N_("Enforce the bus clock") }, { true, "CPUX_FORCE_FREQ_FALLBACK", N_("Ignore CPU frequency reported by libcpuid") }, { HAS_LIBCPUID, "CPUX_CPUID_RAW", N_("Read CPUID raw data from a given file") }, { HAS_LIBCPUID, "CPUX_DEBUG_DATABASE", N_("Only print a message if CPU is not present in the database") }, { true, NULL, NULL } }; /* Check for influenceable environment variables */ static void check_environment_variables(Labels *data) { if(getenv("CPUX_BCLK")) data->bus_freq = atof(getenv("CPUX_BCLK")); if(getenv("CPUX_FORCE_FREQ_FALLBACK")) opts->freq_fallback = ((atoi(getenv("CPUX_FORCE_FREQ_FALLBACK"))) > 0); if(getenv("CPUX_CPUID_RAW")) data->l_data->cpuid_raw_file = getenv("CPUX_CPUID_RAW"); if(getenv("CPUX_DEBUG_DATABASE")) opts->debug_database = ((atoi(getenv("CPUX_DEBUG_DATABASE"))) > 0); } /* This is help display with --help option */ static void help(char *binary_name) { int i; bool options_header = false; char buff[MAXSTR]; MSG_STDOUT(_("Usage: %s DISPLAY [OPTIONS]\n"), binary_name); MSG_STDOUT("%s", _("Available DISPLAY:")); for(i = 0; cpux_options[i].long_opt != NULL; i++) { if(!cpux_options[i].has_mod) continue; if(!options_header && islower(cpux_options[i].short_opt)) { options_header = true; MSG_STDOUT("\n%s", _("Available OPTIONS:")); } if(cpux_options[i].short_opt) snprintf(buff, MAXSTR, " -%c,", cpux_options[i].short_opt); else snprintf(buff, MAXSTR, " "); MSG_STDOUT("%s --%-14s %s", buff, cpux_options[i].long_opt, _(cpux_options[i].description)); } MSG_STDOUT("\n%s", _("Influenceable environment variables:")); for(i = 0; cpux_env_vars[i].var_name != NULL; i++) { if(!cpux_env_vars[i].has_mod) continue; MSG_STDOUT(" %-25s %s", cpux_env_vars[i].var_name, _(cpux_env_vars[i].description)); } } /* This is the --version option */ static void version(bool full_header) { int i; const struct { const bool has_mod; const char *lib, *version; } libs_ver[] = { { HAS_GTK, "GTK", GTK_VERSION }, { HAS_NCURSES, "NCURSES", NCURSES_VERSION }, { HAS_LIBCPUID, "LIBCPUID", LIBCPUID_VERSION }, { HAS_LIBPCI, "LIBPCI", LIBPCI_VERSION }, { HAS_LIBGLFW, "LIBGLFW", LIBGLFW_VERSION }, { HAS_LIBPROCPS, "LIBPROCPS", LIBPROCPS_VERSION }, { HAS_LIBSTATGRAB, "LIBSTATGRAB", LIBSTATGRAB_VERSION }, { HAS_DMIDECODE, "DMIDECODE", DMIDECODE_VERSION }, { HAS_BANDWIDTH, "BANDWIDTH", BANDWIDTH_VERSION }, { false, NULL, NULL } }; PRGINFO(stdout); if(full_header) { MSG_STDOUT("%s\n", PRGCPRGHT); MSG_STDOUT("%s", _("This is free software: you are free to change and redistribute it.")); MSG_STDOUT("%s", _("This program comes with ABSOLUTELY NO WARRANTY")); MSG_STDOUT(_("See the %s license: <%s>\n"), PRGLCNS, LCNSURL); } /* Print features version */ for(i = 0; libs_ver[i].lib != NULL; i++) { if(libs_ver[i].has_mod) MSG_STDOUT(_("-- %-9s version: %s"), libs_ver[i].lib, libs_ver[i].version); } } /* Add arguments from environment variable CPUX_ARGS */ static void environment_to_arguments(int *argc, char ***argv) { int err = 0; const char *args = getenv("CPUX_ARGS"); wordexp_t we; if(args == NULL) return; if((err = wordexp(args, &we, 0)) != 0) { MSG_ERROR(_("failed to call wordexp (%i)"), err); return; } *argc = we.we_wordc; *argv = malloc((we.we_wordc + 1) * sizeof(char *)); for(size_t i = 0; i < we.we_wordc; i++) { const size_t length = strlen(we.we_wordv[i]) + 1; (*argv)[i + 1] = malloc(length * sizeof(char)); memcpy((*argv)[i + 1], we.we_wordv[i], length); } wordfree(&we); } /* Parse arguments and set some flags */ #define OPTIONS_COUNT (sizeof(cpux_options) / sizeof(cpux_options[0])) #define SHORT_OPT_SIZE 3 #define SHORT_OPTS_SIZE (OPTIONS_COUNT * 2) static void parse_arguments(int argc_orig, char *argv_orig[]) { int i, j = 0, c, argc = 0, longindex, tmp_arg = -1; char shortopt[SHORT_OPT_SIZE], shortopts[SHORT_OPTS_SIZE] = ""; char **argv = NULL, **tmp = NULL; struct option longopts[OPTIONS_COUNT]; /* Inject arguments from environment */ environment_to_arguments(&argc, &argv); c = argc; argc += argc_orig; tmp = realloc(argv, argc * sizeof(char *)); ALLOC_CHECK(tmp); argv = tmp; for(i = 0; i < argc_orig; i++) { j = (i == 0) ? 0 : c + i; // Preserve argv[0], then append original argv at end of new array const size_t length = strlen(argv_orig[i]) + 1; argv[j] = malloc(length * sizeof(char)); memcpy(argv[j], argv_orig[i], length); } /* Fill longopts structure */ j = 0; for(i = 0; cpux_options[i].long_opt != NULL; i++) { while(!cpux_options[i].has_mod) i++; longopts[j++] = (struct option) { .name = cpux_options[i].long_opt, .has_arg = cpux_options[i].need_arg, .flag = 0, .val = cpux_options[i].short_opt }; snprintf(shortopt, SHORT_OPT_SIZE, "%c%c", cpux_options[i].short_opt, cpux_options[i].need_arg ? ':' : '\0'); strncat(shortopts, shortopt, SHORT_OPTS_SIZE - 1); } longopts[j] = (struct option) { 0, 0, 0, 0 }; /* Set the default mode */ if(HAS_GTK && (getenv("DISPLAY") != NULL || getenv("WAYLAND_DISPLAY") != NULL)) opts->output_type = OUT_GTK; else if(HAS_NCURSES) opts->output_type = OUT_NCURSES; else opts->output_type = OUT_DUMP; /* Parse options */ while((c = getopt_long(argc, argv, shortopts, longopts, &longindex)) != -1) { switch(c) { case 'G': opts->output_type = OUT_GTK; break; case 'N': opts->output_type = OUT_NCURSES; break; case 'D': opts->output_type = OUT_DUMP; break; case 'M': opts->output_type = OUT_DMIDECODE; break; case 'B': opts->output_type = OUT_BANDWIDTH; break; case 'r': tmp_arg = atoi(optarg); if(tmp_arg >= 1) opts->refr_time = tmp_arg; break; case 't': tmp_arg = atoi(optarg); if(NO_CPU < tmp_arg && tmp_arg <= NO_ABOUT) opts->selected_page = tmp_arg; break; case 'c': tmp_arg = atoi(optarg); if(tmp_arg >= 0) opts->selected_core = tmp_arg; break; case 'b': tmp_arg = atoi(optarg); if(tmp_arg >= 0) opts->bw_test = atoi(optarg); break; case 'g': tmp_arg = atoi(optarg); if(tmp_arg >= 0) opts->selected_gpu = tmp_arg; break; case 'd': opts->with_daemon = true; break; case 'v': opts->verbose = true; break; case 'h': help(argv[0]); exit(EXIT_SUCCESS); break; case 'V': version(true); exit(EXIT_SUCCESS); break; case 0: if(!strcmp(longopts[longindex].name, "cpuid-decimal")) { opts->cpuid_decimal = true; break; } else if(!strcmp(longopts[longindex].name, "nocolor")) { opts->color = false; break; } else if(!strcmp(longopts[longindex].name, "debug")) { opts->debug = true; break; } else if(!strcmp(longopts[longindex].name, "issue-fmt")) { opts->color = false; opts->verbose = true; opts->debug = true; opts->issue = true; opts->output_type = OUT_DUMP; setlocale(LC_ALL, "C"); setenv("CPUX_DAEMON_DEBUG", "1", 1); unlink(LOG_FILE); freopen(LOG_FILE, "a", stdout); setvbuf(stdout, NULL, _IONBF, 0); dup2(STDOUT_FILENO, STDERR_FILENO); version(false); break; } else if(!strcmp(longopts[longindex].name, "keymap")) { switch(optarg[0]) { case 'a': opts->keymap = ARROWS; break; case 'e': opts->keymap = EMACS; break; case 'i': opts->keymap = INVERTED_T; break; case 'v': opts->keymap = VIM; break; default: help(argv[0]); exit(EXIT_FAILURE); } break; } /* Fall through */ case '?': default: help(argv[0]); exit(EXIT_FAILURE); } } for(i = 0; i < argc; i++) free(argv[i]); free(argv); } #undef OPTIONS_COUNT #undef SHORT_OPT_SIZE #undef SHORT_OPTS_SIZE /************************* Main-related functions *************************/ /* Action on SIGSEV/SIGFPE */ static void sighandler(int signum) { int bt_size, i; char **bt_syms, *buff = NULL; void *bt[16]; /* Get the backtrace */ bt_size = backtrace(bt, 16); bt_syms = backtrace_symbols(bt, bt_size); /* Print the backtrace */ MSG_STDERR(_("\n%sOops, something was wrong! %s has received signal %d (%s) and has crashed.%s"), BOLD_RED, PRGNAME, signum, strsignal(signum), DEFAULT); MSG_STDERR("%s", "========================= Backtrace ========================="); PRGINFO(stderr); for(i = 1; i < bt_size; i++) { char *address = strtok(strrchr(strdup(bt_syms[i]), '[') + 1, "]"); popen_to_str(&buff, "addr2line %s -e /proc/%d/exe", address, getpid()); if(strstr(buff, "??") == NULL) MSG_STDERR("#%2i %s %s", i, strrchr(buff, '/') + 1, bt_syms[i]); else MSG_STDERR("#%2i %s", i, bt_syms[i]); free(buff); } MSG_STDERR("%s", "======================== End Backtrace =======================\n"); MSG_STDERR("%s", _("You can paste this backtrace by opening a new issue here:")); MSG_STDERR("%s", "https://github.com/X0rg/CPU-X/issues/new\n"); /* Stop program */ free(bt_syms); signal(signum, SIG_DFL); kill(getpid(), signum); } /* Enable internationalization support */ #if HAS_GETTEXT static int set_locales(void) { int err; char *TEXTDOMAINDIR = getenv("TEXTDOMAINDIR"); if(TEXTDOMAINDIR == NULL || TEXTDOMAINDIR[0] == '\0') TEXTDOMAINDIR = LOCALEDIR; /* Apply locale */ setlocale(LC_ALL, ""); err = bindtextdomain(GETTEXT_PACKAGE, TEXTDOMAINDIR) ? 0 : 1; err += bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8") ? 0 : 1; err += textdomain(GETTEXT_PACKAGE) ? 0 : 1; /* Check if something is wrong */ if(err) { MSG_ERROR("%s", _("an error occurred while setting locale")); return 1; } else return 0; } #endif /* HAS_GETTEXT */ int main(int argc, char *argv[]) { /* Init variables */ Labels *data = &(Labels) { .tab_cpu = { { NULL } }, .tab_caches = { { NULL } }, .tab_motherboard = { { NULL } }, .tab_memory = { { NULL } }, .tab_system = { { NULL } }, .tab_graphics = { { NULL } }, .tab_bench = { { NULL } }, .cpu_freq = 0, .socket_fd = -1, .cpu_count = 0, .cache_count = 0, .dimm_count = 0, .gpu_count = 0, .bus_freq = 0.0, .cpu_min_mult = 0.0, .cpu_max_mult = 0.0, .reload = false }; data->l_data = &(LibcpuidData) { .cpu_vendor_id = -1, .cpu_model = -1, .cpu_ext_model = -1, .cpu_ext_family = -1, .cpuid_raw_file = NULL }; data->w_data = &(BandwidthData) { .test_count = 0, .size = { 0 }, .speed = { 0 }, .test_name = NULL }; data->m_data = &(MemoryData) { .mem_usage = { 0 }, .mem_total = 0, .swap_total = 0 }; data->g_data = &(GraphicsData) { .gpu_driver = { GPUDRV_UNKNOWN }, .device_path = { NULL }, }; data->b_data = &(BenchData) { .run = false, .duration = 1, .threads = 1, .primes = 0, .start = 0, .elapsed = 0, .num = 0 }; opts = &(Options) { .cpuid_decimal = false, .color = true, .verbose = false, .debug = false, .issue = false, .with_daemon = false, .debug_database = false, .freq_fallback = false, .selected_page = 0, .selected_core = 0, .bw_test = 0, .selected_gpu = 0, .refr_time = 1, .keymap = ARROWS }; #if HAS_GETTEXT set_locales(); #endif /* HAS_GETTEXT */ signal(SIGSEGV, sighandler); signal(SIGFPE, sighandler); signal(SIGABRT, sighandler); /* Parse options */ #if HAS_GTK load_settings(); #endif /* HAS_GTK */ parse_arguments(argc, argv); check_environment_variables(data); if(opts->output_type > OUT_NO_CPUX) goto skip_init; /* Connect to daemon */ if(IS_ROOT || opts->with_daemon) start_daemon(false); if(daemon_is_alive()) connect_to_daemon(data); /* Retrieve data */ labels_setname(data); fill_labels (data); /* Show data */ if(HAS_GTK && (opts->output_type == OUT_GTK)) start_gui_gtk(&argc, &argv, data); if(HAS_NCURSES && (opts->output_type == OUT_NCURSES)) start_tui_ncurses(data); if(opts->output_type == OUT_DUMP) dump_data(data); skip_init: if(HAS_DMIDECODE && (opts->output_type == OUT_DMIDECODE)) return run_dmidecode(); if(HAS_BANDWIDTH && (opts->output_type == OUT_BANDWIDTH)) return run_bandwidth(); return EXIT_SUCCESS; } CPU-X-4.2.0/src/tui_ncurses.c000066400000000000000000000706211403012130000156350ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE tui_ncurses.c */ #include #include #include #include #include #include #include #include "cpu-x.h" #include "tui_ncurses.h" static void (*func_ptr[])(WINDOW*, const SizeInfo, Labels*) = { ntab_cpu, ntab_caches, ntab_motherboard, ntab_memory, ntab_system, ntab_graphics, ntab_bench, ntab_about }; static const Colors color[] = { { 0, 0, 0, 0 }, { DEFAULT_COLOR, COLOR_BLACK, COLOR_WHITE, A_NORMAL }, { TITLE_COLOR, COLOR_BLUE, COLOR_WHITE, A_BOLD }, { ACTIVE_TAB_COLOR, COLOR_WHITE, COLOR_BLUE, A_BOLD }, { INACTIVE_TAB_COLOR, COLOR_WHITE, COLOR_BLUE, A_NORMAL }, { LABEL_NAME_COLOR, COLOR_BLACK, COLOR_WHITE, A_NORMAL }, { LABEL_VALUE_COLOR, COLOR_BLUE, COLOR_WHITE, A_NORMAL }, { YELLOW_BAR_COLOR, COLOR_YELLOW, COLOR_YELLOW, A_NORMAL }, { BLUE_BAR_COLOR, COLOR_BLUE, COLOR_BLUE, A_NORMAL }, { MAGENTA_BAR_COLOR, COLOR_MAGENTA, COLOR_MAGENTA, A_NORMAL }, { GREEN_BAR_COLOR, COLOR_GREEN, COLOR_GREEN, A_NORMAL }, { RED_BAR_COLOR, COLOR_RED, COLOR_RED, A_NORMAL } }; /************************* Public function *************************/ /* Start CPU-X in NCurses mode */ void start_tui_ncurses(Labels *data) { int err = 0, ch = 0; const SizeInfo info = { .height = LINE_COUNT, .width = 70, .start = 1, .tb = 2, .tm = 26, .te = 48 }; NThrd refr = { .data = data, .info = info }; WINDOW *win; MSG_VERBOSE("%s", _("Starting NCurses TUI…")); if(!getenv("TERMINFO")) setenv("TERMINFO", TERMINFODIR, 0); freopen("/dev/null", "a", stderr); if(setupterm(NULL, STDOUT_FILENO, &err)) { if(err == -1) { MSG_ERROR("%s", _("FATAL ERROR: terminfo database could not be found (try to set TERMINFO environment variable)")); exit(255); } else { MSG_WARNING(_("Failed to set up %s terminal (err=%i); falling back to %s"), getenv("TERM"), err, DEFAULT_TERM); setenv("TERM", DEFAULT_TERM, 1); setupterm(DEFAULT_TERM, STDOUT_FILENO, &err); } } initscr(); cbreak(); noecho(); curs_set(0); halfdelay(0); nodelay(stdscr, TRUE); keypad(stdscr, TRUE); if(opts->color) { start_color(); opts->color = has_colors(); } if(opts->color) { enum EnColors pair; for(pair = DEFAULT_COLOR; pair < LAST_COLOR; pair++) init_pair(pair, color[pair].foreground, color[pair].background); } win = newwin(info.height, info.width, 0, 0); refr.win = win; if(resize_window(win, info)) { main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } while(ch != 'q') { ch = convert_char(getch()); switch(ch) { case KEY_LEFT: /* Switch to left tab */ if(opts->selected_page > NO_CPU) { opts->selected_page--; if(resize_window(win, info)) { main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } } break; case KEY_RIGHT: /* Switch to right tab */ if(opts->selected_page < NO_ABOUT) { opts->selected_page++; if(resize_window(win, info)) { main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } } break; case KEY_DOWN: if(opts->selected_page == NO_CPU && opts->selected_core > 0) { opts->selected_core--; print_activecore(win); } else if(opts->selected_page == NO_CACHES && opts->bw_test > 0) { opts->bw_test--; print_activetest(win, info, data); } else if(opts->selected_page == NO_GRAPHICS && opts->selected_gpu > 0) { opts->selected_gpu--; print_activecard(win, info, data); } else if(opts->selected_page == NO_BENCH && data->b_data->duration > 1) { data->b_data->duration--; print_paramduration(win, info, data); } break; case KEY_NPAGE: if(opts->selected_page == NO_BENCH && data->b_data->threads > 1 && !data->b_data->run) { data->b_data->threads--; print_paramthreads(win, info, data); } break; case KEY_UP: if(opts->selected_page == NO_CPU && (int) opts->selected_core < data->cpu_count - 1) { opts->selected_core++; print_activecore(win); } else if(opts->selected_page == NO_CACHES && (int) opts->bw_test < data->w_data->test_count - 1) { opts->bw_test++; print_activetest(win, info, data); } else if(opts->selected_page == NO_GRAPHICS && (int) opts->selected_gpu < data->gpu_count - 1) { opts->selected_gpu++; print_activecard(win, info, data); } else if(opts->selected_page == NO_BENCH && data->b_data->duration < 60 * 24) { data->b_data->duration++; print_paramduration(win, info, data); } break; case KEY_PPAGE: if(opts->selected_page == NO_BENCH && data->b_data->threads < data->cpu_count && !data->b_data->run) { data->b_data->threads++; print_paramthreads(win, info, data); } break; case 'f': if(opts->selected_page == NO_BENCH && !data->b_data->run) { data->b_data->fast_mode = true; start_benchmarks(data); } else if(opts->selected_page == NO_BENCH && data->b_data->run) data->b_data->run = false; break; case 's': if(opts->selected_page == NO_BENCH && !data->b_data->run) { data->b_data->fast_mode = false; start_benchmarks(data); } else if(opts->selected_page == NO_BENCH && data->b_data->run) data->b_data->run = false; break; case 'h': erase(); print_help(); if(resize_window(win, info)) { main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } break; case ERR: /* Refresh dynamic labels */ if(resize_window(win, info)) { nrefresh(&refr); main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } break; case KEY_RESIZE: /* Resize window */ if(resize_window(win, info)) { main_win(win, info, data); (*func_ptr[opts->selected_page])(win, info, data); } break; default: break; } } endwin(); labels_free(data); } /************************* Private functions *************************/ /* Convert keys when an alternative mapping is used */ #define ALT_CODE 27 #define ALT(x) (x & ALT_CODE) static int convert_char(int ch) { int i = 0; static int modifier = 0; const int ch_mod = modifier ? ch & modifier : ch; const int keymaps[][LASTKEYMAP] = { //Arrow Emacs Inverted-T Vim { KEY_LEFT, CTRL('b'), 'j', 'h' }, { KEY_RIGHT, CTRL('f'), 'l', 'l' }, { KEY_UP, CTRL('p'), 'i', 'k' }, { KEY_DOWN, CTRL('n'), 'k', 'j' }, { KEY_PPAGE, CTRL('v'), CTRL('b'), CTRL('b') }, { KEY_NPAGE, ALT('v'), CTRL('f'), CTRL('f') }, { 'h', '?', '?', '?' }, { ch_mod, ch_mod, ch_mod, ch_mod } // Sentinel value }; modifier = (ch == ALT_CODE) ? ch : 0; while(keymaps[i][opts->keymap] != ch_mod) i++; return keymaps[i][0]; } #undef ALT_CODE #undef ALT /* Put window in the center of the screen */ static bool resize_window(WINDOW *pwin, const SizeInfo info) { static int prev_lines = -1, prev_cols = -1; bool ret = true; const int starty = (LINES - info.height) / 2; const int startx = (COLS - info.width) / 2; if (prev_lines >= 0 && prev_lines == LINES && prev_cols >= 0 && prev_cols == COLS) return true; prev_lines = LINES; prev_cols = COLS; erase(); if((startx < 0) || (starty < 0)) { printw("%s\n", _("Window is too small!")); timeout(-1); ret = false; } else { wresize(pwin, info.height, info.width); mvwin(pwin, starty, startx); printw("%s\n", _("Press 'h' to see help.")); timeout(opts->refr_time * 1000); } refresh(); return ret; } /* Clean window */ static void wclrscr(WINDOW *pwin) { int y, x, maxy, maxx; getmaxyx(pwin, maxy, maxx); for(y = 0; y < maxy; y++) { for(x = 0; x < maxx; x++) mvwaddch(pwin, y, x, ' '); } } /* Similar to mvwprintw, but specify a color pair */ static int mvwprintwc(WINDOW *win, int y, int x, enum EnColors pair, const char *fmt, ...) { int ret; va_list args; va_start(args, fmt); wmove(win, y, x); if(opts->color) wattron(win, COLOR_PAIR(pair) | color[pair].attrs); ret = vwprintw(win, fmt, args); if(opts->color) wattroff(win, COLOR_PAIR(pair) | color[pair].attrs); va_end(args); return ret; } /* Similar to mvwprintw, but print first string in black and second string in blue */ static int mvwprintw2c(WINDOW *win, int y, int x, const char *fmt, ...) { int ret = 0; char *s1, *s2, *f1, *f2, *ptr = strdup(fmt); enum EnColors pair; va_list args; const size_t ptr_len = strlen(ptr) + 1; /* Retrive args */ va_start(args, fmt); f2 = strstr(fmt, ": ") + 1; f1 = strncat(strtok(ptr, ": "), ":", ptr_len); s1 = va_arg(args, char *); s2 = va_arg(args, char *); /* Print label name */ wmove(win, y, x); pair = LABEL_NAME_COLOR; if(opts->color) wattron(win, COLOR_PAIR(pair) | color[pair].attrs); ret += wprintw(win, f1, s1); free(f1); if(opts->color) wattroff(win, COLOR_PAIR(pair) | color[pair].attrs); /* Print label value */ pair = LABEL_VALUE_COLOR; if(opts->color) wattron(win, COLOR_PAIR(pair) | color[pair].attrs); ret += wprintw(win, f2, s2); if(opts->color) wattroff(win, COLOR_PAIR(pair) | color[pair].attrs); va_end(args); return ret; } /* Refresh dynamic values */ static void nrefresh(NThrd *refr) { int i, line = 0; WINDOW *(win) = refr->win; Labels *(data) = refr->data; SizeInfo info = refr->info; switch(opts->selected_page) { case NO_CPU: do_refresh(data); mvwprintw2c(win, LINE_4, info.tm, "%11s: %s", data->tab_cpu[NAME][VOLTAGE], data->tab_cpu[VALUE][VOLTAGE]); mvwprintw2c(win, LINE_6, info.te, "%9s: %s", data->tab_cpu[NAME][TEMPERATURE], data->tab_cpu[VALUE][TEMPERATURE]); mvwprintw2c(win, LINE_12, info.tb, "%14s: %s", data->tab_cpu[NAME][CORESPEED], data->tab_cpu[VALUE][CORESPEED]); mvwprintw2c(win, LINE_13, info.tb, "%14s: %s", data->tab_cpu[NAME][MULTIPLIER], data->tab_cpu[VALUE][MULTIPLIER]); mvwprintw2c(win, LINE_15, info.tb, "%14s: %s", data->tab_cpu[NAME][USAGE], data->tab_cpu[VALUE][USAGE]); break; case NO_CACHES: do_refresh(data); line = LINE_2; for(i = L1SPEED; i < data->cache_count * CACHEFIELDS; i += CACHEFIELDS) { mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_caches[NAME][i], data->tab_caches[VALUE][i]); line += CACHEFIELDS + 2; } break; case NO_SYSTEM: do_refresh(data); mvwprintw2c(win, LINE_4, info.tb, "%13s: %s", data->tab_system[NAME][UPTIME], data->tab_system[VALUE][UPTIME]); for(i = USED; i < LASTSYSTEM; i++) { mvwprintw2c(win, LINE_8 + line++, info.tb, "%13s: %s", data->tab_system[NAME][i], data->tab_system[VALUE][i]); draw_bar(win, info, data, i); } break; case NO_GRAPHICS: do_refresh(data); line = LINE_3; for(i = 0; i < data->gpu_count * GPUFIELDS; i += GPUFIELDS) { mvwprintw2c(win, line, info.tm, "%18s: %s", data->tab_graphics[NAME][GPU1DIDRID + i], data->tab_graphics[VALUE][GPU1DIDRID + i]); line++; mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_graphics[NAME][GPU1PCIE + i], data->tab_graphics[VALUE][GPU1PCIE + i]); line++; mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_graphics[NAME][GPU1TEMPERATURE + i], data->tab_graphics[VALUE][GPU1TEMPERATURE + i]); mvwprintw2c(win, line, info.tm, "%18s: %s", data->tab_graphics[NAME][GPU1USAGE + i], data->tab_graphics[VALUE][GPU1USAGE + i]); line++; mvwprintw2c(win, line, info.tm, "%18s: %s", data->tab_graphics[NAME][GPU1MEMUSED + i], data->tab_graphics[VALUE][GPU1MEMUSED + i]); line++; mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_graphics[NAME][GPU1CORECLOCK + i], data->tab_graphics[VALUE][GPU1CORECLOCK + i]); mvwprintw2c(win, line, info.tm, "%18s: %s", data->tab_graphics[NAME][GPU1MEMCLOCK + i], data->tab_graphics[VALUE][GPU1MEMCLOCK + i]); line++; mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_graphics[NAME][GPU1VOLTAGE + i], data->tab_graphics[VALUE][GPU1VOLTAGE + i]); mvwprintw2c(win, line, info.tm, "%18s: %s", data->tab_graphics[NAME][GPU1POWERAVG + i], data->tab_graphics[VALUE][GPU1POWERAVG + i]); line += LINE_3 - 1; } break; case NO_BENCH: do_refresh(data); mvwprintw2c(win, LINE_1, info.tb, "%13s: %s", data->tab_bench[NAME][PRIMESLOWSCORE], data->tab_bench[VALUE][PRIMESLOWSCORE]); mvwprintw2c(win, LINE_2, info.tb, "%13s: %s", data->tab_bench[NAME][PRIMESLOWRUN], data->tab_bench[VALUE][PRIMESLOWRUN]); mvwprintw2c(win, LINE_5, info.tb, "%13s: %s", data->tab_bench[NAME][PRIMEFASTSCORE], data->tab_bench[VALUE][PRIMEFASTSCORE]); mvwprintw2c(win, LINE_6, info.tb, "%13s: %s", data->tab_bench[NAME][PRIMEFASTRUN], data->tab_bench[VALUE][PRIMEFASTRUN]); break; default: return; } wrefresh(win); } /* Print how to use this TUI */ static void print_help() { timeout(-1); nodelay(stdscr, FALSE); printw(_("Welcome in %s NCurses help!\n"), PRGNAME); printw("%s\n", _("This help describes how to use this Text-based User Interface.")); printw("\n%s\n", _("Global keys:")); printw("\t%s\n", _("Press 'left' key to switch in left tab.")); printw("\t%s\n", _("Press 'right' key to switch in right tab.")); printw("\t%s\n", _("Press 'h' key to see this help.")); printw("\t%s\n", _("Press 'q' key to exit.")); printw("\n%s\n", _("CPU tab:")); printw("\t%s\n", _("Press 'down' key to decrease core number to monitor.")); printw("\t%s\n", _("Press 'up' key to increase core number to monitor.")); printw("\n%s\n", _("Caches tab:")); printw("\t%s\n", _("Press 'down' key to switch to previous test.")); printw("\t%s\n", _("Press 'up' key' to switch to next test.")); printw("\n%s\n", _("Bench tab:")); printw("\t%s\n", _("Press 'down' key to decrement benchmark duration.")); printw("\t%s\n", _("Press 'up' key to increment benchmark duration.")); printw("\t%s\n", _("Press 'next page' key to decrement number of threads to use.")); printw("\t%s\n", _("Press 'previous page' key to increment number of threads to use.")); printw("\t%s\n", _("Press 's' key to start/stop prime numbers (slow) benchmark.")); printw("\t%s\n", _("Press 'f' key to start/stop prime numbers (fast) benchmark.")); printw("\n%s\n", _("Graphics tab:")); printw("\t%s\n", _("Press 'down' key to switch to previous graphic card.")); printw("\t%s\n", _("Press 'up' key to switch to next graphic card.")); printw("\n%s\n", _("Press any key to exit this help.")); refresh(); getch(); nodelay(stdscr, TRUE); timeout(opts->refr_time * 1000); } /* The main window (title, tabs, footer) */ static void main_win(WINDOW *win, const SizeInfo info, Labels *data) { int i, cpt = 2; if(opts->color) { init_pair(DEFAULT_COLOR, COLOR_BLACK, COLOR_WHITE); wattrset(win, COLOR_PAIR(DEFAULT_COLOR)); } wclrscr(win); box(win, 0, 0); mvwprintwc(win, TITLE_LINE, info.width / 2 - strlen(PRGNAME) / 2, TITLE_COLOR, PRGNAME); mvwprintwc(win, HEADER_LINE, 2, DEFAULT_COLOR, PRGNAME); mvwprintwc(win, HEADER_LINE, info.width / 2, DEFAULT_COLOR, data->tab_about[VERSIONSTR]); for(i = 1; i < info.width - 1; i++) mvwprintwc(win, TABS_LINE, i, INACTIVE_TAB_COLOR, " "); for(i = NO_CPU; i <= NO_ABOUT; i++) { if(i == (int) opts->selected_page && opts->color) mvwprintwc(win, TABS_LINE, cpt, ACTIVE_TAB_COLOR, data->objects[i]); else if(i == (int) opts->selected_page && !opts->color) mvwprintw(win, TABS_LINE, cpt++, "[%s]", data->objects[i]); else mvwprintwc(win, TABS_LINE, cpt, INACTIVE_TAB_COLOR, data->objects[i]); cpt += strlen(data->objects[i]) + 2; } wrefresh(win); } /* Display active Core in CPU tab */ #define BUFF_SIZE 16 static void print_activecore(WINDOW *win) { char buff[BUFF_SIZE]; snprintf(buff, BUFF_SIZE, _("Core #%i"), opts->selected_core); mvwprintwc(win, LINE_18, 4, DEFAULT_COLOR, buff); } #undef BUFF_SIZE /* CPU tab */ static void ntab_cpu(WINDOW *win, const SizeInfo info, Labels *data) { int i, line; const int length = info.width - (info.tb + 18); const int middle = info.width - 38; int index = length - 1; /* Split Intructions label in two parts */ for(i = 0; i < length; i++) if(data->tab_cpu[VALUE][INSTRUCTIONS][i] == ',') index = i; data->tab_cpu[VALUE][INSTRUCTIONS][index + 1] = '\0'; /* Processor frame */ frame(win, LINE_0, info.start , LINE_10, info.width - 1, data->objects[FRAMPROCESSOR]); line = LINE_1; for(i = VENDOR; i < CORESPEED; i++) { switch(i) { case VOLTAGE: mvwprintw2c(win, LINE_4, info.tm, "%11s: %s", data->tab_cpu[NAME][VOLTAGE], data->tab_cpu[VALUE][VOLTAGE]); break; case MODEL: mvwprintw2c(win, LINE_6, info.tm, "%11s: %s", data->tab_cpu[NAME][MODEL], data->tab_cpu[VALUE][MODEL]); break; case EXTMODEL: mvwprintw2c(win, LINE_7, info.tm, "%11s: %s", data->tab_cpu[NAME][EXTMODEL], data->tab_cpu[VALUE][EXTMODEL]); break; case TEMPERATURE: mvwprintw2c(win, LINE_6, info.te, "%9s: %s", data->tab_cpu[NAME][TEMPERATURE], data->tab_cpu[VALUE][TEMPERATURE]); break; case STEPPING: mvwprintw2c(win, LINE_7, info.te, "%9s: %s", data->tab_cpu[NAME][STEPPING], data->tab_cpu[VALUE][STEPPING]); break; case INSTRUCTIONS: mvwprintw2c(win, line++, info.tb, "%14s: %s", data->tab_cpu[NAME][INSTRUCTIONS], data->tab_cpu[VALUE][INSTRUCTIONS]); mvwprintwc (win, line++, info.tb + 16, LABEL_VALUE_COLOR, &(data->tab_cpu[VALUE][INSTRUCTIONS][index + 2])); break; default: mvwprintw2c(win, line++, info.tb, "%14s: %s", data->tab_cpu[NAME][i], data->tab_cpu[VALUE][i]); } } /* Clocks frame */ frame(win, LINE_11, info.start, LINE_16, middle, data->objects[FRAMCLOCKS]); line = LINE_12; for(i = CORESPEED; i < LEVEL1D; i++) mvwprintw2c(win, line++, info.tb, "%14s: %s", data->tab_cpu[NAME][i], data->tab_cpu[VALUE][i]); /* Cache frame */ frame(win, LINE_11, middle, LINE_16, info.width - 1, data->objects[FRAMCACHE]); line = LINE_12; for(i = LEVEL1D; i < SOCKETS; i++) mvwprintw2c(win, line++, middle + 1, "%12s: %s", data->tab_cpu[NAME][i], data->tab_cpu[VALUE][i]); /* Last frame */ frame(win, LINE_17, info.start, LINE_19, info.width - 1, ""); print_activecore(win); mvwprintw2c(win, LINE_18, 18, "%s: %2s", data->tab_cpu[NAME][SOCKETS], data->tab_cpu[VALUE][SOCKETS]); mvwprintw2c(win, LINE_18, 36, "%s: %2s", data->tab_cpu[NAME][CORES], data->tab_cpu[VALUE][CORES]); mvwprintw2c(win, LINE_18, 54, "%s: %2s", data->tab_cpu[NAME][THREADS], data->tab_cpu[VALUE][THREADS]); wrefresh(win); } /* Display active Test in Caches tab */ static void print_activetest(WINDOW *win, const SizeInfo info, Labels *data) { const int line = LINE_1 + (CACHEFIELDS + 2) * data->cache_count; if(!data->cache_count) return; if(HAS_BANDWIDTH) mvwprintwc(win, line, info.tb + 1, DEFAULT_COLOR, "%s", data->w_data->test_name[opts->bw_test]); wrefresh(win); } /* Caches tab */ static void ntab_caches(WINDOW *win, const SizeInfo info, Labels *data) { int i, line = LINE_1, start = LINE_0, end = LINE_3; if(!data->cache_count) return; /* Cache frames */ for(i = L1SIZE; i < data->cache_count * CACHEFIELDS; i++) { if(i % CACHEFIELDS == 0) { frame(win, start, info.start, end, info.width - 1, data->objects[FRAML1CACHE + i / CACHEFIELDS]); start = end + 1; end += 4; if(i > 0) line += 2; } mvwprintw2c(win, line++, 2, "%13s: %s", data->tab_caches[NAME][i], data->tab_caches[VALUE][i]); } /* Test frame */ line++; frame(win, line, info.start , line + 2, info.width - 1, data->objects[FRAMTEST]); print_activetest(win, info, data); wrefresh(win); } /* Motherboard tab */ static void ntab_motherboard(WINDOW *win, const SizeInfo info, Labels *data) { int i, line; /* Motherboard frame */ frame(win, LINE_0, info.start , LINE_4, info.width - 1, data->objects[FRAMMOTHERBOARD]); line = LINE_1; for(i = MANUFACTURER; i < BRAND; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_motherboard[NAME][i], data->tab_motherboard[VALUE][i]); /* BIOS frame */ frame(win, LINE_5, info.start , LINE_10, info.width - 1, data->objects[FRAMBIOS]); line = LINE_6; for(i = BRAND; i < CHIPVENDOR; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_motherboard[NAME][i], data->tab_motherboard[VALUE][i]); /* Chipset frame */ frame(win, LINE_11, info.start , LINE_14, info.width - 1, data->objects[FRAMCHIPSET]); line = LINE_12; for(i = CHIPVENDOR; i < LASTMOTHERBOARD; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_motherboard[NAME][i], data->tab_motherboard[VALUE][i]); wrefresh(win); } /* Memory tab */ static void ntab_memory(WINDOW *win, const SizeInfo info, Labels *data) { int i, line = LINE_0; if(!data->dimm_count) return; /* Banks frame */ for(i = BANK0; i < data->dimm_count; i++) { frame(win, line, info.start, line + 2, info.width - 1, data->objects[FRAMBANK0 + i]); line++; mvwprintw2c(win, line, info.tb, "%13s: %s", data->tab_memory[NAME][i], data->tab_memory[VALUE][i]); line += 2; } wrefresh(win); } /* System tab */ static void ntab_system(WINDOW *win, const SizeInfo info, Labels *data) { int i, line; /* OS frame */ frame(win, LINE_0, info.start , LINE_6, info.width - 1, data->objects[FRAMOPERATINGSYSTEM]); line = LINE_1; for(i = KERNEL; i < USED; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_system[NAME][i], data->tab_system[VALUE][i]); /* Memory frame */ frame(win, LINE_7, info.start , LINE_13, info.width - 1, data->objects[FRAMMEMORY]); line = LINE_8; for(i = USED; i < LASTSYSTEM; i++) { mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_system[NAME][i], data->tab_system[VALUE][i]); draw_bar(win, info, data, i); } wrefresh(win); } /* Draw an usage bar in System tab */ static void draw_bar(WINDOW *win, const SizeInfo info, Labels *data, int bar) { int i, line, color, bar_count, adjust = 0; static int before = 0; const int val = 39, start = 46, end = info.width - 3, size = end - start; double percent; if((bar == SWAP && data->m_data->swap_total == 0) || (bar != SWAP && data->m_data->mem_total == 0)) return; line = bar - USED + LINE_8; color = YELLOW_BAR_COLOR + bar - USED; before = ((bar == USED) || (bar == SWAP)) ? 0 : before; percent = (double) data->m_data->mem_usage[bar - USED] / ((bar == SWAP) ? data->m_data->swap_total : data->m_data->mem_total); bar_count = (int) roundf(percent * (size - 1)); if(0.0 < percent && bar_count < 1) { bar_count = 1; adjust = 1; } /* Write percentage + delimiters */ mvwprintwc(win, line, val, LABEL_VALUE_COLOR, "%.2f%%", percent * 100); mvwprintwc(win, line, start, DEFAULT_COLOR, "["); mvwprintwc(win, line, end, DEFAULT_COLOR, "]"); /* Draw bar */ for(i = 0; i < bar_count; i++) { if(opts->color) mvwprintwc(win, line, start + 1 + before + i, color, " "); else mvwprintw(win, line, start + 1 + before + i, "|"); } before += bar_count - adjust; } /* Display active card in Graphics tab */ static void print_activecard(WINDOW *win, const SizeInfo info, Labels *data) { if(data->gpu_count == 0) return; mvwprintwc(win, LINE_12, info.tb + 1, DEFAULT_COLOR, "#%i: %s", opts->selected_gpu, data->tab_graphics[VALUE][GPU1MODEL + opts->selected_gpu * GPUFIELDS]); wrefresh(win); } /* Graphics tab */ static void ntab_graphics(WINDOW *win, const SizeInfo info, Labels *data) { int i, j, line, start = LINE_0, end = LINE_10; if(data->gpu_count == 0) return; /* Card frames */ line = LINE_1; frame(win, start, info.start, end, info.width - 1, data->objects[FRAMGPU1 + opts->selected_gpu]); for(i = opts->selected_gpu * GPUFIELDS, j = 0; j < GPUFIELDS; i++, j++) { switch(j) { case GPU1DRIVER: case GPU1USAGE: case GPU1MEMCLOCK: case GPU1POWERAVG: mvwprintw2c(win, line - 1, info.tm, "%18s: %s", data->tab_graphics[NAME][i], data->tab_graphics[VALUE][i]); break; case GPU1DIDRID: mvwprintw2c(win, line++, info.tm, "%18s: %s", data->tab_graphics[NAME][i], data->tab_graphics[VALUE][i]); break; default: mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_graphics[NAME][i], data->tab_graphics[VALUE][i]); } } /* Cards frame */ line++; frame(win, line, info.start , line + 2, info.width - 1, data->objects[FRAMCARDS]); print_activecard(win, info, data); wrefresh(win); } /* Display Duration parameter in Bench tab */ static void print_paramduration(WINDOW *win, const SizeInfo info, Labels *data) { casprintf(&data->tab_bench[VALUE][PARAMDURATION], true, _("%u mins"), data->b_data->duration); mvwprintw2c(win, LINE_9, info.tb, "%13s: %s", data->tab_bench[NAME][PARAMDURATION], data->tab_bench[VALUE][PARAMDURATION]); wrefresh(win); } /* Display Threads parameter in Bench tab */ static void print_paramthreads(WINDOW *win, const SizeInfo info, Labels *data) { casprintf(&data->tab_bench[VALUE][PARAMTHREADS], true, "%u", data->b_data->threads); mvwprintw2c(win, LINE_9, info.tm, "%13s: %s", data->tab_bench[NAME][PARAMTHREADS], data->tab_bench[VALUE][PARAMTHREADS]); wrefresh(win); } /* Bench tab */ static void ntab_bench(WINDOW *win, const SizeInfo info, Labels *data) { int i, line; /* Prime numbers (slow) frame */ frame(win, LINE_0, info.start , LINE_3, info.width - 1, data->objects[FRAMPRIMESLOW]); line = LINE_1; for(i = PRIMESLOWSCORE; i < PRIMEFASTSCORE; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_bench[NAME][i], data->tab_bench[VALUE][i]); /* Prime numbers (fast) frame */ frame(win, LINE_4, info.start , LINE_7, info.width - 1, data->objects[FRAMPRIMEFAST]); line = LINE_5; for(i = PRIMEFASTSCORE; i < PARAMDURATION; i++) mvwprintw2c(win, line++, info.tb, "%13s: %s", data->tab_bench[NAME][i], data->tab_bench[VALUE][i]); /* Parameters frame */ frame(win, LINE_8, info.start , LINE_10, info.width - 1, data->objects[FRAMPARAM]); print_paramduration(win, info, data); print_paramthreads (win, info, data); wrefresh(win); } /* About tab */ static void ntab_about(WINDOW *win, const SizeInfo info, Labels *data) { char *part2 = strdup(data->tab_about[DESCRIPTION]); const char *part1 = strsep(&part2, "\n"); /* About CPU-X frame */ frame(win, LINE_0, info.start, LINE_5, info.width - 1, ""); mvwprintwc(win, LINE_2, 4, DEFAULT_COLOR, "%s", part1); mvwprintwc(win, LINE_3, 4, DEFAULT_COLOR, "%s", part2); frame(win, LINE_6, info.start, LINE_10, info.width - 1, data->objects[FRAMABOUT]); mvwprintwc(win, LINE_7, 20, DEFAULT_COLOR, "%s", data->tab_about[VERSIONSTR]); mvwprintwc(win, LINE_8, 20, DEFAULT_COLOR, "%s", data->tab_about[AUTHOR]); mvwprintwc(win, LINE_9, 20, DEFAULT_COLOR, "%s", data->tab_about[SITE]); frame(win, LINE_11, info.start, LINE_16, info.width - 1, data->objects[FRAMLICENSE]); mvwprintwc(win, LINE_12, 20, DEFAULT_COLOR, "%s", data->tab_about[COPYRIGHT]); mvwprintwc(win, LINE_14, 6, DEFAULT_COLOR, "%s", data->tab_about[LICENSE]); mvwprintwc(win, LINE_15, 10, DEFAULT_COLOR, "%s", data->tab_about[NOWARRANTY]); wrefresh(win); } /* Draw a frame */ static void frame(WINDOW *win, int starty, int startx, int endy, int endx, char *label) { if(opts->color) { init_pair(DEFAULT_COLOR, COLOR_BLACK, COLOR_WHITE); wattron(win, COLOR_PAIR(DEFAULT_COLOR)); } /* Horizontal lines */ mvwhline(win, starty, startx, 0, endx - startx); mvwhline(win, endy, startx, 0, endx - startx); /* Vertical lines */ mvwvline(win, starty, startx, 0, endy - starty); mvwvline(win, starty, endx - 1, 0, endy - starty); /* Corners */ mvwhline(win, starty, startx, ACS_ULCORNER, 1); mvwhline(win, endy, startx, ACS_LLCORNER, 1); mvwhline(win, starty, endx - 1, ACS_URCORNER, 1); mvwhline(win, endy, endx - 1, ACS_LRCORNER, 1); /* Title */ mvwprintwc(win, starty, startx + 2, DEFAULT_COLOR, "%s", label); if(opts->color) wattroff(win, COLOR_PAIR(DEFAULT_COLOR)); } CPU-X-4.2.0/src/tui_ncurses.h000066400000000000000000000101301403012130000156270ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE tui_ncurses.h */ #ifndef _TUI_NCURSES_H_ #define _TUI_NCURSES_H_ #include #define DEFAULT_TERM "xterm" enum EnLines { WINDOW_TOP_LINE, TITLE_LINE, TABS_LINE, LINE_0, LINE_1, LINE_2, LINE_3, LINE_4, LINE_5, LINE_6, LINE_7, LINE_8, LINE_9, LINE_10, LINE_11, LINE_12, LINE_13, LINE_14, LINE_15, LINE_16, LINE_17, LINE_18, LINE_19, HEADER_LINE, WINDOW_BOTTOM_LINE, LINE_COUNT }; enum EnColors { DEFAULT_COLOR = 1, TITLE_COLOR, ACTIVE_TAB_COLOR, INACTIVE_TAB_COLOR, LABEL_NAME_COLOR, LABEL_VALUE_COLOR, YELLOW_BAR_COLOR, BLUE_BAR_COLOR, RED_BAR_COLOR, GREEN_BAR_COLOR, MAGENTA_BAR_COLOR, LAST_COLOR }; typedef struct { const short pair, foreground, background; const int attrs; } Colors; typedef struct { int height, width, start; int tb, tm, te; } SizeInfo; typedef struct { WINDOW *win; Labels *data; SizeInfo info; } NThrd; /********************************** TUI **********************************/ /* Convert keys when an alternative mapping is used */ static int convert_char(int ch); /* Put window in the center of the screen */ static bool resize_window(WINDOW *pwin, const SizeInfo info); /* Clean window */ static void wclrscr(WINDOW *pwin); /* Similar to mvwprintw, but specify a color pair */ static int mvwprintwc(WINDOW *win, int y, int x, enum EnColors pair, const char *fmt, ...); /* Similar to mvwprintw, but print first string in black and second string in blue */ static int mvwprintw2c(WINDOW *win, int y, int x, const char *fmt, ...); /* Refresh dynamic values */ static void nrefresh(NThrd *refr); /* Print how to use this TUI */ static void print_help(void); /* The main window (title, tabs, footer) */ static void main_win(WINDOW *win, const SizeInfo info, Labels *data); /* Display active Core in CPU tab */ static void print_activecore(WINDOW *win); /* CPU tab */ static void ntab_cpu(WINDOW *win, const SizeInfo info, Labels *data); /* Display active Test in Caches tab */ static void print_activetest(WINDOW *win, const SizeInfo info, Labels *data); /* Caches tab */ static void ntab_caches(WINDOW *win, const SizeInfo info, Labels *data); /* Motherboard tab */ static void ntab_motherboard(WINDOW *win, const SizeInfo info, Labels *data); /* Memory tab */ static void ntab_memory(WINDOW *win, const SizeInfo info, Labels *data); /* System tab */ static void ntab_system(WINDOW *win, const SizeInfo info, Labels *data); static void draw_bar(WINDOW *win, const SizeInfo info, Labels *data, int bar); /* Display active card in Graphics tab */ static void print_activecard(WINDOW *win, const SizeInfo info, Labels *data); /* Graphics tab */ static void ntab_graphics(WINDOW *win, const SizeInfo info, Labels *data); /* Display Duration parameter in Bench tab */ static void print_paramduration(WINDOW *win, const SizeInfo info, Labels *data); /* Display Threads parameter in Bench tab */ static void print_paramthreads(WINDOW *win, const SizeInfo info, Labels *data); /* Bench tab */ static void ntab_bench(WINDOW *win, const SizeInfo info, Labels *data); /* About tab */ static void ntab_about(WINDOW *win, const SizeInfo info, Labels *data); /* Draw a frame */ static void frame(WINDOW *local_win, int starty, int startx, int endy, int endx, char *label); #endif /* _TUI_NCURSES_H_ */ CPU-X-4.2.0/src/util.c000066400000000000000000000405621403012130000142500ustar00rootroot00000000000000/**************************************************************************** * Copyright © 2014-2021 Xorg * * 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 . * ****************************************************************************/ /* * PROJECT CPU-X * FILE util.c */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include /* glibc's stat.h has it but musl's does not. */ #ifndef ACCESSPERMS #define ACCESSPERMS (S_IRWXU|S_IRWXG|S_IRWXO) #endif #include #include "cpu-x.h" #include "ipc.h" /************************* Public function *************************/ /* An asprintf-like function, but which can clean some parts of 'str' if 'clean_str' is true * - It calls vasprintf if 'fmt' is a valid string * - If 'clean_str' is true, it removes "unvalid args" from 'str' until next "valid arg" E.g.: casprintf(&str, false, "%i nm", 0): str = "0 nm" casprintf(&str, true, "%i nm", 0): str = "" casprintf(&str, true, "%i nm", 32): str = "32 nm" casprintf(&str, true, "%i KB %i-way", -1, 12): str = "12-way" */ int casprintf(char **str, bool clean_str, const char *fmt, ...) { bool remove; int i, j, ret; char *tmp = NULL; va_list aptr; if(*str != NULL) { free(*str); *str = NULL; } if(fmt == NULL) return 0; va_start(aptr, fmt); ret = vasprintf(str, fmt, aptr); va_end(aptr); if(!clean_str) return ret; remove = (((*str)[0] == '0') && (atof(*str) == 0.0)) || (atoi(*str) < 0); j = remove ? -1 : 0; for(i = 1; (*str)[i] != '\0'; i++) { if(((((*str)[i] == '0') && (atof(*str + i) == 0.0)) || (atoi(*str + i) < 0)) && (isspace((*str)[i - 1]))) remove = true; if(!remove) (*str)[++j] = (*str)[i]; if((isspace((*str)[i])) && !(isdigit((*str)[i - 1]))) remove = false; } (*str)[++j] = '\0'; tmp = realloc(*str, j + 1); ALLOC_CHECK(tmp); *str = tmp; return j; } /* Return a formatted string */ #define BUFFER_COUNT 10 char *format(char *str, ...) { static unsigned count = 0; static char *buff[BUFFER_COUNT] = { NULL }; va_list aptr; count++; const unsigned index = count % BUFFER_COUNT; if(count >= BUFFER_COUNT) free(buff[index]); va_start(aptr, str); vasprintf(&buff[index], str, aptr); va_end(aptr); return buff[index]; } #undef BUFFER_COUNT /* Divide a number (in bytes) with the appropriate prefix */ void find_best_prefix(uint64_t value, enum EnMultipliers multiplier, bool use_si_prefixes, PrefixUnit *pu) { int i, d; struct Table { enum EnMultipliers multiplier; char *prefix; uint64_t divisor; }; const struct Table si_prefixes[] = { { MULT_NONE, UNIT_B, 1 }, { MULT_K, UNIT_KB, 1e3 }, { MULT_M, UNIT_MB, 1e6 }, { MULT_G, UNIT_GB, 1e9 }, { MULT_T, UNIT_TB, 1e12 }, { multiplier, "?B", 1 } }; const struct Table binary_prefixes[] = { { MULT_NONE, UNIT_B, 1ULL }, { MULT_K, UNIT_KIB, 1ULL << 10 }, { MULT_M, UNIT_MIB, 1ULL << 20 }, { MULT_G, UNIT_GIB, 1ULL << 30 }, { MULT_T, UNIT_TIB, 1ULL << 40 }, { multiplier, "?iB", 1ULL } }; const struct Table *prefixes = use_si_prefixes ? si_prefixes : binary_prefixes; const ssize_t table_len = (sizeof(si_prefixes) / sizeof(struct Table)) - 1; /* Find current multiplier */ for(i = 0; prefixes[i].multiplier != multiplier; i++); pu->init = true; pu->prefix = prefixes[i].prefix; pu->divisor = prefixes[0].divisor; if(i >= table_len - 1) { /* Due to the loop over an enum, this case is not possible */ MSG_ERROR("multiplier=%i, value=%llu", multiplier, value); return; } /* Find new prefix and new divisor */ for(i = i + 1, d = 1; (i < table_len) && (d < table_len) && ((value / prefixes[d].divisor) > 0); i++, d++) { pu->prefix = prefixes[i].prefix; pu->divisor = prefixes[d].divisor; } } #define TOKEN_LEN 4 /* Duplicate a string and set unit */ char *strdup_and_set_unit(char *str) { if(str == NULL) return NULL; const ssize_t len = MAXSTR; bool full = false; ssize_t i = 0, j = 0, free = len, written; char *ptr = malloc(len); ALLOC_CHECK(ptr); while((i < len) && !full) { if((str[i] == '@') && (i + TOKEN_LEN - 1 < len) && (str[i + TOKEN_LEN - 1] == '@')) { /* Set unit in destination string */ if(!strncmp(&str[i], "@0B@", TOKEN_LEN)) written = snprintf(&ptr[j], free, "%s", UNIT_B); else if(!strncmp(&str[i], "@KB@", TOKEN_LEN)) written = snprintf(&ptr[j], free, "%s", UNIT_KB); else if(!strncmp(&str[i], "@MB@", TOKEN_LEN)) written = snprintf(&ptr[j], free, "%s", UNIT_MB); else if(!strncmp(&str[i], "@GB@", TOKEN_LEN)) written = snprintf(&ptr[j], free, "%s", UNIT_GB); else if(!strncmp(&str[i], "@TB@", TOKEN_LEN)) written = snprintf(&ptr[j], free, "%s", UNIT_TB); else MSG_ERROR(_("cannot find unit in '%s' string at position %i"), str, i); i += TOKEN_LEN; } else { /* Copy one character */ ptr[j] = str[i]; written = 1; i += written; } if((written >= free) && (str[i - 1] != '\0')) { MSG_WARNING(_("String '%s' is too long, truncating…"), str); full = true; } else { j += written; free -= written; } } ptr[j - 1] = '\0'; return ptr; } #undef TOKEN_LEN /* Check is string is empty (e.g. contains only non printable characters) */ bool string_is_empty(char *str) { int i; if(str == NULL) return true; for(i = 0; (!isalnum(str[i])) && (str[i] != '\0'); i++); return (str[i] == '\0'); } /* Similar to format(), but string can be colorized */ char *colorized_msg(const char *color, const char *str, ...) { char fmt[MSG_BUFF_LEN]; static char buff[MSG_BUFF_LEN]; va_list aptr; va_start(aptr, str); if(opts->color) snprintf(fmt, MSG_BUFF_LEN, "%s%s%s\n", color, str, DEFAULT); else snprintf(fmt, MSG_BUFF_LEN, "%s\n", str); vsnprintf(buff, MSG_BUFF_LEN, fmt, aptr); va_end(aptr); return buff; } /* Open a file and put its content in a variable ('str' accept printf-like format) */ int fopen_to_str(char **buffer, char *str, ...) { char tmp[MAXSTR], error_str[MAXSTR] = "unknown"; char *file_str = NULL; FILE *file_descr = NULL; va_list aptr; va_start(aptr, str); vasprintf(&file_str, str, aptr); va_end(aptr); if(access(file_str, R_OK)) { free(file_str); return -1; } if((file_descr = fopen(file_str, "r")) == NULL) GOTO_ERROR("fopen"); if(fgets(tmp, MAXSTR, file_descr) == NULL) GOTO_ERROR("fgets"); tmp[strlen(tmp) - 1] = '\0'; asprintf(buffer, "%s", tmp); free(file_str); return fclose(file_descr); error: MSG_ERROR(_("an error occurred while opening file '%s' (%s)"), file_str, error_str); free(file_str); return (file_descr == NULL) ? 1 : 2 + fclose(file_descr); } /* Run a command and put output in a variable ('str' accept printf-like format) */ int popen_to_str(char **buffer, char *str, ...) { char tmp[MAXSTR], error_str[MAXSTR] = "unknown"; char *cmd_str = NULL; FILE *pipe_descr = NULL; va_list aptr; va_start(aptr, str); vasprintf(&cmd_str, str, aptr); va_end(aptr); if((pipe_descr = popen(cmd_str, "r")) == NULL) GOTO_ERROR("popen"); if(fgets(tmp, MAXSTR, pipe_descr) == NULL) GOTO_ERROR("fgets"); tmp[strlen(tmp) - 1] = '\0'; asprintf(buffer, "%s", tmp); free(cmd_str); return pclose(pipe_descr); error: MSG_ERROR(_("an error occurred while running command '%s' (%s)"), cmd_str, error_str); free(cmd_str); return (pipe_descr == NULL) ? 1 : 2 + pclose(pipe_descr); } /* Check if a command exists */ bool command_exists(char *cmd) { char buff[MAXSTR]; snprintf(buff, MAXSTR, "command -v %s > /dev/null", cmd); return !system(buff); } /* Load a kernel module */ int load_module(char *module, int *fd) { int ret = -1; char *check_cmd = NULL; const ssize_t len = strlen(module) + 1; const DaemonCommand cmd = LOAD_MODULE; #if defined (__linux__) asprintf(&check_cmd, "grep -wq %s /proc/modules 2> /dev/null", module); #elif defined (__DragonFly__) || defined (__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) asprintf(&check_cmd, "kldstat | grep %s > /dev/null", module); #else # error "Unsupported operating system" #endif ret = system(check_cmd); free(check_cmd); if((ret != 0) && (*fd >= 0)) { /* Send module name to daemon */ SEND_DATA(fd, &cmd, sizeof(DaemonCommand)); SEND_DATA(fd, &len, sizeof(ssize_t)); SEND_DATA(fd, module, len); /* Receive return value */ RECEIVE_DATA(fd, &ret, sizeof(int)); } return ret; } /* Search a sensor filename in a given directory corresponding to regex */ static int get_sensor_path(char *dir_path, regex_t *regex_filename, regex_t *regex_label, char **cached_path) { int err = 1; char *label = NULL; DIR *dp = NULL; struct dirent *dir; /* Open given directory */ if((dp = opendir(dir_path)) == NULL) { MSG_ERROR(_("failed to open %s directory"), dir_path); return 1; } while(((dir = readdir(dp)) != NULL) && err) { /* Ignore hidden files and files not mathing pattern */ if((dir->d_name[0] == '.') || regexec(regex_filename, dir->d_name, 0, NULL, 0)) continue; if(regex_label != NULL) { /* Open the label file */ if(fopen_to_str(&label, "%s/%s", dir_path, dir->d_name)) continue; /* Check if label matchs with pattern */ if(regexec(regex_label, label, 0, NULL, 0)) continue; } /* Try to open the corresponding file */ strtok(dir->d_name, "_"); casprintf(cached_path, false, "%s/%s_input", dir_path, dir->d_name); err = access(*cached_path, R_OK); } closedir(dp); free(label); return err; } /* Search a directory path corresponding to regex */ static int get_directory_path(char *dir_path, regex_t *regex_dirname, char **cached_path) { int err = regexec(regex_dirname, dir_path, 0, NULL, 0); if(!err) { casprintf(cached_path, false, "%s", dir_path); err = access(*cached_path, R_OK); } return err; } /* Get a filename located in a directory corresponding to given request */ int request_sensor_path(char *base_dir, char **cached_path, enum RequestSensor which) { int err = 1; char *sensor = NULL; char *path = NULL; DIR *dp = NULL; struct dirent *dir; regex_t regex_filename_temp_in, regex_filename_temp_lab, regex_filename_in_in, regex_dirname_cardN, regex_dirname_hwmonN; regex_t regex_label_coreN, regex_label_tdie, regex_label_other; if((dp = opendir(base_dir)) == NULL) { MSG_ERROR(_("failed to open %s directory"), base_dir); return 1; } if(regcomp(®ex_filename_temp_in, "temp1_input", REG_NOSUB) || regcomp(®ex_filename_temp_lab, "temp[[:digit:]]_label", REG_NOSUB) || regcomp(®ex_filename_in_in, "in0_input", REG_NOSUB) || regcomp(®ex_dirname_cardN, "card[[:digit:]]", REG_NOSUB) || regcomp(®ex_dirname_hwmonN, "hwmon[[:digit:]]", REG_NOSUB) || regcomp(®ex_label_coreN, format("Core[[:space:]]*%u", opts->selected_core), REG_NOSUB | REG_ICASE) || regcomp(®ex_label_tdie, "Tdie", REG_NOSUB | REG_ICASE) || regcomp(®ex_label_other, "CPU", REG_NOSUB | REG_ICASE)) { MSG_ERROR("%s", _("an error occurred while compiling regex")); return 2; } while(((dir = readdir(dp)) != NULL) && err) { /* Ignore hidden files */ if(dir->d_name[0] == '.') continue; /* Find sensor name */ if((which != RQT_GPU_DRM) && fopen_to_str(&sensor, "%s/%s/name", base_dir, dir->d_name)) continue; /* Ignore batteries */ if((sensor != NULL) && (strcasestr(sensor, "bat") != NULL)) continue; /* Browse files in directory */ casprintf(&path, false, "%s/%s", base_dir, dir->d_name); switch(which) { case RQT_CPU_TEMPERATURE: if(strstr(sensor, "coretemp") != NULL) /* 'sensors' output: Package id 0: +37.0°C (high = +80.0°C, crit = +98.0°C) Core 0: +33.0°C (high = +80.0°C, crit = +98.0°C) Core 1: +34.0°C (high = +80.0°C, crit = +98.0°C) Core 2: +36.0°C (high = +80.0°C, crit = +98.0°C) Core 3: +37.0°C (high = +80.0°C, crit = +98.0°C) */ err = get_sensor_path(path, ®ex_filename_temp_lab, ®ex_label_coreN, cached_path); else if(strstr(sensor, "k8temp") != NULL) /* 'sensors' output: Core0 Temp: +64.0°C Core0 Temp: +63.0°C Core1 Temp: +64.0°C Core1 Temp: +64.0°C */ err = get_sensor_path(path, ®ex_filename_temp_lab, ®ex_label_coreN, cached_path); else if(strstr(sensor, "k10temp") != NULL) { /* 'sensors' output with Ryzen CPUs since Linux 5.6: Tdie: +41.4°C */ if((err = get_sensor_path(path, ®ex_filename_temp_lab, ®ex_label_tdie, cached_path))) /* 'sensors' output for other cases: temp1: +29.5°C (high = +70.0°C, crit = +90.0°C, hyst = +87.0°C) */ err = get_sensor_path(path, ®ex_filename_temp_in, NULL, cached_path); } else if(strstr(sensor, "zenpower") != NULL) /* 'sensors' output: Tdie: +67.9°C (high = +95.0°C) */ err = get_sensor_path(path, ®ex_filename_temp_in, NULL, cached_path); break; case RQT_CPU_TEMPERATURE_OTHERS: err = get_sensor_path(path, ®ex_filename_temp_lab, ®ex_label_other, cached_path); break; case RQT_CPU_VOLTAGE: /* 'sensors' output: Vcore: +0.88 V (min = +0.80 V, max = +1.38 V) */ err = get_sensor_path(path, ®ex_filename_in_in, NULL, cached_path); break; case RQT_GPU_TEMPERATURE: err = get_sensor_path(path, ®ex_filename_temp_in, NULL, cached_path); break; case RQT_GPU_DRM: err = get_directory_path(path, ®ex_dirname_cardN, cached_path); break; case RQT_GPU_HWMON: err = get_directory_path(path, ®ex_dirname_hwmonN, cached_path); break; } } closedir(dp); free(sensor); free(path); regfree(®ex_filename_temp_in); regfree(®ex_filename_temp_lab); regfree(®ex_filename_in_in); regfree(®ex_dirname_cardN); regfree(®ex_dirname_hwmonN); regfree(®ex_label_coreN); regfree(®ex_label_tdie); regfree(®ex_label_other); MSG_DEBUG("request_sensor_path(base_dir=%s, cached_path=%s, which=%i) ==> %i", base_dir, *cached_path, which, err); return err; } const char *start_daemon(bool graphical) { int wstatus = -1; pid_t pid; char *msg = NULL; char *const appdir = getenv("APPDIR"); char *const daemon = (appdir == NULL) ? DAEMON_PATH : format("/tmp/%s", DAEMON_EXEC); char *const cmd1[] = { daemon, NULL }; char *const cmd2[] = { "pkexec", daemon, NULL }; char *const cmd3[] = { "pkexec", "--disable-internal-agent", daemon, NULL }; char *const *cmd = cmd2; if(appdir != NULL) { /* Hack to allow pkexec to run daemon (when running from AppImage) */ char *const cmdcopy = format("cp %s/%s %s", appdir, DAEMON_PATH, daemon); system(cmdcopy); } if(graphical) cmd = cmd3; else if(IS_ROOT) cmd = cmd1; pid = fork(); if(pid < 0) MSG_ERRNO("%s", "fork"); else if(pid == 0) execvp(cmd[0], cmd); else waitpid(pid, &wstatus, 0); switch(WEXITSTATUS(wstatus)) { case 0: msg = NULL; // Normal status code break; case 126: msg = N_("pkexec: authorization could not be obtained (dialog dismissed)"); break; case 127: msg = N_("pkexec: authorization could not be obtained (not authorized)"); break; case 255: msg = N_("pkexec: command not found"); break; default: msg = N_("pkexec: unexpected error code"); break; } if(msg != NULL) MSG_WARNING("%s", _(msg)); return msg; } bool daemon_is_alive() { struct stat statbuf; int ret = stat(SOCKET_NAME, &statbuf); return !ret && (statbuf.st_uid == 0) && S_ISSOCK(statbuf.st_mode) && (statbuf.st_mode & ACCESSPERMS); } CPU-X-4.2.0/tests/000077500000000000000000000000001403012130000134735ustar00rootroot00000000000000CPU-X-4.2.0/tests/CMakeLists.txt000066400000000000000000000003201403012130000162260ustar00rootroot00000000000000project(tests LANGUAGES NONE ) add_test(NAME test_awk_regex COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/awk/test_regex.sh") add_test(NAME test_grep_regex COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/grep/test_regex.sh") CPU-X-4.2.0/tests/awk/000077500000000000000000000000001403012130000142555ustar00rootroot00000000000000CPU-X-4.2.0/tests/awk/amdgpu_pm_info000066400000000000000000000024721403012130000171710ustar00rootroot00000000000000Clock Gating Flags Mask: 0x3fbcf Graphics Medium Grain Clock Gating: On Graphics Medium Grain memory Light Sleep: On Graphics Coarse Grain Clock Gating: On Graphics Coarse Grain memory Light Sleep: On Graphics Coarse Grain Tree Shader Clock Gating: Off Graphics Coarse Grain Tree Shader Light Sleep: Off Graphics Command Processor Light Sleep: On Graphics Run List Controller Light Sleep: On Graphics 3D Coarse Grain Clock Gating: Off Graphics 3D Coarse Grain memory Light Sleep: Off Memory Controller Light Sleep: On Memory Controller Medium Grain Clock Gating: On System Direct Memory Access Light Sleep: Off System Direct Memory Access Medium Grain Clock Gating: On Bus Interface Medium Grain Clock Gating: Off Bus Interface Light Sleep: On Unified Video Decoder Medium Grain Clock Gating: On Video Compression Engine Medium Grain Clock Gating: On Host Data Path Light Sleep: On Host Data Path Medium Grain Clock Gating: On Digital Right Management Medium Grain Clock Gating: Off Digital Right Management Light Sleep: Off Rom Medium Grain Clock Gating: On Data Fabric Medium Grain Clock Gating: Off GFX Clocks and Power: 1000 MHz (MCLK) 472 MHz (SCLK) 600 MHz (PSTATE_SCLK) 1000 MHz (PSTATE_MCLK) 950 mV (VDDGFX) 35.114 W (average GPU) GPU Temperature: 35 C GPU Load: 42 % UVD: Disabled VCE: Disabled CPU-X-4.2.0/tests/awk/aticonfig-odgc000066400000000000000000000004321403012130000170540ustar00rootroot00000000000000Adapter 1 - ATI Radeon HD 5700 Series Core (MHz) Memory (MHz) Current Clocks : 157 300 Current Peak : 900 1200 Configurable Peak Range : [500-1080] [1200-1450] GPU load : 77% CPU-X-4.2.0/tests/awk/aticonfig-odgt000066400000000000000000000001501403012130000170720ustar00rootroot00000000000000Default Adapter - ATI Mobility Radeon HD 5000 Series Sensor 0: Temperature - 48.50 C CPU-X-4.2.0/tests/awk/nvidia-settings-GPUCurrentClockFreqs000066400000000000000000000000101403012130000232500ustar00rootroot00000000000000135,405 CPU-X-4.2.0/tests/awk/nvidia-settings-GPUUtilization000066400000000000000000000000471403012130000221760ustar00rootroot00000000000000graphics=33, memory=8, video=0, PCIe=0 CPU-X-4.2.0/tests/awk/pp_dpm_mclk000066400000000000000000000000441403012130000164630ustar00rootroot000000000000000: 300Mhz * 1: 1000Mhz 2: 2235Mhz CPU-X-4.2.0/tests/awk/pp_dpm_sclk000066400000000000000000000001361403012130000164730ustar00rootroot000000000000000: 300Mhz 1: 600Mhz 2: 900Mhz * 3: 1145Mhz 4: 1215Mhz 5: 1257Mhz 6: 1300Mhz 7: 1420Mhz CPU-X-4.2.0/tests/awk/radeon_pm_info000066400000000000000000000001421403012130000171540ustar00rootroot00000000000000uvd vclk: 0 dclk: 0 power level 0 sclk: 37500 mclk: 150000 vddc: 950 vddci: 875 pcie gen: 3 CPU-X-4.2.0/tests/awk/test_regex.sh000077500000000000000000000037541403012130000167760ustar00rootroot00000000000000#!/bin/bash TEST_DIR="$(dirname "$(realpath "$0")")" # shellcheck disable=SC1090 source "$TEST_DIR/../common.sh" cd "$TEST_DIR" || exit 255 tmp_dir="$(mktemp --tmpdir --directory CPU-X.XXXXXX)" for awk in gawk mawk nawk; do $awk '/Sensor/ { print $5 }' aticonfig-odgt &> "$tmp_dir/aticonfig-odgt.$awk" $awk '/GPU Load/ { print $3 }' amdgpu_pm_info &> "$tmp_dir/amdgpu_pm_info.$awk" $awk -F '(: |Mhz)' '/\*/ { print $2 }' pp_dpm_sclk &> "$tmp_dir/pp_dpm_sclk.$awk" $awk -F '(: |Mhz)' '/\*/ { print $2 }' pp_dpm_mclk &> "$tmp_dir/pp_dpm_mclk.$awk" $awk '/GPU load/ { sub("%","",$4); print $4 }' aticonfig-odgc &> "$tmp_dir/aticonfig-odgc-load.$awk" $awk '/Current Clocks/ { print $4 }' aticonfig-odgc &> "$tmp_dir/aticonfig-odgc-sclk.$awk" $awk '/Current Clocks/ { print $5 }' aticonfig-odgc &> "$tmp_dir/aticonfig-odgc-mclk.$awk" $awk -F '(sclk: | mclk:)' 'NR==2 { print $2 }' radeon_pm_info &> "$tmp_dir/radeon_pm_info-sclk.$awk" $awk -F '(mclk: | vddc:)' 'NR==2 { print $2 }' radeon_pm_info &> "$tmp_dir/radeon_pm_info-mclk.$awk" $awk -F '(vddc: | vddci:)' 'NR==2 { print $2 }' radeon_pm_info &> "$tmp_dir/radeon_pm_info-vddc.$awk" $awk -F '[,= ]' '{ print $2 }' nvidia-settings-GPUUtilization &> "$tmp_dir/nvidia-settings-GPUUtilization.$awk" $awk -F '[,]' '{ print $1 }' nvidia-settings-GPUCurrentClockFreqs &> "$tmp_dir/nvidia-settings-GPUCurrentClockFreqs-sclk.$awk" $awk -F '[,]' '{ print $2 }' nvidia-settings-GPUCurrentClockFreqs &> "$tmp_dir/nvidia-settings-GPUCurrentClockFreqs-mclk.$awk" done cd "$tmp_dir" || exit 255 failed=0 for file1 in *.gawk; do file2=$(basename "$file1" .gawk) printf "%-41s: " "$file2" if diff -qu "$file1" "$file2.mawk" && diff -qu "$file1" "$file2.nawk"; then success "OK" else error "KO" "(got '$(< "$file2.mawk")'/'$(< "$file2.nawk")', wanted $(< "$file1")" ((failed++)) fi done summary "$failed" rm -rf "$tmp_dir" CPU-X-4.2.0/tests/common.sh000066400000000000000000000005401403012130000153160ustar00rootroot00000000000000#!/bin/bash success() { local msg="$1" local details="$2" echo -e "\033[1;32m$msg\033[0m $details" } error() { local msg="$1" local details="$2" echo -e "\033[1;31m$msg\033[0m $details" } summary() { local failed=$1 echo if [[ $failed -eq 0 ]]; then success "All tests passed!" else error "$failed tests failed." fi exit "$failed" } CPU-X-4.2.0/tests/grep/000077500000000000000000000000001403012130000144305ustar00rootroot00000000000000CPU-X-4.2.0/tests/grep/results/000077500000000000000000000000001403012130000161315ustar00rootroot00000000000000CPU-X-4.2.0/tests/grep/results/nouveau_pstate_first_core000066400000000000000000000000041403012130000233270ustar00rootroot00000000000000405 CPU-X-4.2.0/tests/grep/results/nouveau_pstate_first_memory000066400000000000000000000000041403012130000237070ustar00rootroot00000000000000838 CPU-X-4.2.0/tests/grep/results/nouveau_pstate_forced_core000066400000000000000000000000041403012130000234420ustar00rootroot00000000000000900 CPU-X-4.2.0/tests/grep/results/nouveau_pstate_forced_memory000066400000000000000000000000051403012130000240230ustar00rootroot000000000000004000 CPU-X-4.2.0/tests/grep/samples/000077500000000000000000000000001403012130000160745ustar00rootroot00000000000000CPU-X-4.2.0/tests/grep/samples/nouveau_pstate_first000066400000000000000000000002641403012130000222720ustar00rootroot0000000000000007: core 270-405 MHz memory 838 MHz 0a: core 270-900 MHz memory 1560 MHz 0e: core 270-900 MHz memory 4000 MHz 0f: core 270-900 MHz memory 5016 MHz AC: core 405 MHz memory 5016 MHz CPU-X-4.2.0/tests/grep/samples/nouveau_pstate_forced000066400000000000000000000002741403012130000224060ustar00rootroot0000000000000007: core 270-405 MHz memory 838 MHz 0a: core 270-900 MHz memory 1560 MHz 0e: core 270-900 MHz memory 4000 MHz AC DC * 0f: core 270-900 MHz memory 5016 MHz AC: core 405 MHz memory 5016 MHz CPU-X-4.2.0/tests/grep/test_regex.sh000077500000000000000000000014061403012130000171410ustar00rootroot00000000000000#!/bin/bash TEST_DIR="$(dirname "$(realpath "$0")")" # shellcheck disable=SC1090 source "$TEST_DIR/../common.sh" cd "$TEST_DIR" || exit 255 failed=0 for samplefile in samples/nouveau_pstate_*; do file=$(basename "$samplefile") pstate=$(grep '\*' "$samplefile" || sed -n 1p "$samplefile") samplecore=$(echo "$pstate" | grep -oP '(?<=core )[^ ]*' | cut -d- -f2) samplememory=$(echo "$pstate" | grep -oP '(?<=memory )[^ ]*') resultcore=$(< "results/${file}_core") resultmemory=$(< "results/${file}_memory") printf "%-41s: " "$file" if [[ "$samplecore" == "$resultcore" ]] && [[ "$samplememory" == "$resultmemory" ]]; then success "OK" else error "KO" "(got $samplecore/$samplememory, wanted $resultcore/$resultmemory)" ((failed++)) fi done summary "$failed" CPU-X-4.2.0/vagrant/000077500000000000000000000000001403012130000137735ustar00rootroot00000000000000CPU-X-4.2.0/vagrant/Vagrantfile000066400000000000000000000026451403012130000161670ustar00rootroot00000000000000VAGRANTFILE_API_VERSION = "2" VM_CPU = "2" VM_MEMORY = "2048" vms = { "ubuntu/xenial64" => { :name => "xenial", :bootstrap => "ubuntu" }, "ubuntu/focal64" => { :name => "focal", :bootstrap => "ubuntu" }, "generic/fedora33" => { :name => "fedora", :bootstrap => "fedora" } } Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| if Vagrant.has_plugin?("vagrant-vbguest") then config.vbguest.iso_path = "/usr/lib/virtualbox/additions/VBoxGuestAdditions.iso" config.vbguest.auto_update = false config.vbguest.no_remote = true end vms.each_with_index do |(box, info), index| config.vm.define info[:name] do |node| node.vm.box = box node.vm.hostname = info[:name] node.vm.synced_folder '../', '/home/vagrant/CPU-X' node.vm.provision :shell, reboot: true, env: {"HOST_LANG" => ENV['LANG']}, path: "bootstrap_" + info[:bootstrap] + ".sh" if Vagrant.has_plugin?("vagrant-proxyconf") node.proxy.http = ENV['HTTP_PROXY'] || ENV['http_proxy'] || "" node.proxy.https = ENV['HTTPS_PROXY'] || ENV['https_proxy'] || "" node.proxy.no_proxy = $no_proxy end node.vm.provider :virtualbox do |vb, override| vb.name = info[:name] vb.cpus = VM_CPU vb.memory = VM_MEMORY vb.gui = true vb.customize ["modifyvm", :id, "--vram", "128"] vb.customize ["setextradata", "global", "GUI/Customizations", "noMenuBar"] end end end end CPU-X-4.2.0/vagrant/bootstrap_fedora.sh000077500000000000000000000014361403012130000176730ustar00rootroot00000000000000#!/bin/bash # Install packages sudo dnf update -y sudo dnf group install -y "Fedora Workstation" --allowerasing sudo dnf install -y polkit-gnome gnome-tweak-tool virtualbox-guest-additions sudo usermod -a -G wheel,mock vagrant # Autologin to GDM sudo mkdir -pv "/etc/gdm/" cat | sudo tee "/etc/gdm/custom.conf" << EOF [daemon] AutomaticLogin=vagrant AutomaticLoginEnable=True EOF sudo systemctl set-default graphical.target # Vagrant user settings localectl set-keymap "${HOST_LANG//[_.]*/}" gsettings set org.gnome.desktop.input-sources sources '[]' gsettings set org.gnome.desktop.screensaver lock-enabled false gsettings set org.gnome.desktop.session idle-delay 0 gsettings set org.gnome.desktop.lockdown disable-lock-screen true echo "yes" > "/home/vagrant/.config/gnome-initial-setup-done" CPU-X-4.2.0/vagrant/bootstrap_ubuntu.sh000077500000000000000000000016751403012130000177620ustar00rootroot00000000000000#!/bin/bash # Install packages sudo apt update -y sudo apt upgrade -y sudo apt install -y --no-install-recommends ubuntu-desktop gnome-terminal firefox sudo apt install -y --no-install-recommends virtualbox-guest-dkms virtualbox-guest-utils virtualbox-guest-x11 # Autologin to LightDM sudo groupadd -r autologin sudo gpasswd -a vagrant autologin sudo mkdir -pv "/etc/lightdm/" cat | sudo tee "/etc/lightdm/lightdm.conf" << EOF [Seat:*] autologin-user=vagrant EOF # Vagrant user settings sudo sed -i 's/XKBLAYOUT=\"\w*"/XKBLAYOUT=\"'${HOST_LANG//[_.]*/}'\"/g' /etc/default/keyboard gsettings set org.gnome.desktop.input-sources sources '[]' gsettings set org.gnome.desktop.screensaver lock-enabled false gsettings set org.gnome.desktop.session idle-delay 0 gsettings set org.gnome.desktop.lockdown disable-lock-screen true cp /usr/share/applications/{firefox.desktop,gnome-terminal.desktop} /home/vagrant/Desktop/ chmod +x /home/vagrant/Desktop/*.desktop