pax_global_header00006660000000000000000000000064145103712670014520gustar00rootroot0000000000000052 comment=c5d632886dab084e6784cdfa7e685cda534ffe6a qnetload-1.3.6/000077500000000000000000000000001451037126700133365ustar00rootroot00000000000000qnetload-1.3.6/.github/000077500000000000000000000000001451037126700146765ustar00rootroot00000000000000qnetload-1.3.6/.github/workflows/000077500000000000000000000000001451037126700167335ustar00rootroot00000000000000qnetload-1.3.6/.github/workflows/ci.yml000066400000000000000000000005621451037126700200540ustar00rootroot00000000000000name: ci on: [push, pull_request] jobs: build: runs-on: ubuntu-22.04 steps: - name: Check out repository uses: actions/checkout@v4.1.0 - name: Install dependencies run: | sudo apt-get install cmake qt6-base-dev libgl1-mesa-dev - name: Build run: | mkdir build cd build cmake ../src make qnetload-1.3.6/.gitignore000066400000000000000000000000751451037126700153300ustar00rootroot00000000000000build-qnetload-Qt5-Debug/ build-qnetload-Qt5-Release/ build/ qnetload-1.3.6/LICENSE000066400000000000000000001045131451037126700143470ustar00rootroot00000000000000 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 . qnetload-1.3.6/README.md000066400000000000000000000100011451037126700146050ustar00rootroot00000000000000![ci](https://github.com/cpina/qnetload/workflows/ci/badge.svg) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) # qnetload ## Introduction In 2016 and 2017 I used again (after years) xnetload. The way that xnetload shows the information is extremely useful in some cases. Sadly xnetload was removed from Debian in 2010: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=595195 Thanks to R.F. Smith for programming the original xnetload! I've evaluated many similar packages but I wasn't happy with any of them, so I wrote an xnetload replacement. I've named it qnetload as a tribute to xnetload and because it's implemented using the Qt libraries. Since the initial implementation in 2017 I've added some new minor features: pause, restart, selection of interface using the user interface, etc. See the screenshots below xnetload (the original): ![xnetload](docs/images/xnetload.png) qnetload (this one): ![qnetload](docs/images/qnetload.png) ## Installation ### Debian and Ubuntu I've tested it on Ubuntu 22.04 (Jammy Jellyfish) and in Debian 12 (Bookworm). ``` # Ubuntu: sudo apt-get install git cmake qt6-base-dev libqt6widgets6 libgl1-mesa-dev # Debian: sudo apt-get install git cmake qt6-base-dev git clone https://github.com/cpina/qnetload.git cd qnetload mkdir build cd build cmake ../src make sudo make install ``` Then qnetload should be in your path (probably installed in /usr/local/bin) and can be executed just typing qnetload on the command line. If it doesn't work for you feel free to contact me (carles@pina.cat) or open a GitHub issue. Please include the output of the commands. ### Other distributions qnetload should work with any Linux distribution if git (to make it easier to fetch, or use the "Download" option on Github), cmake and Qt6 are available. Try using your package management to install Qt6 (some equivalent of "sudo apt-get install qt6-base-dev" and then follow the steps in the "Debian and Ubuntu" section. qnetload would work with any system providing that the file `/proc/net/dev` has the same structure as Linux. ## Screenshots ![qnetload](docs/images/qnetload-speed-tooltip.png) The estimated usage for the next hour is handy to estimate how much usage for streaming or a video conference is going to be. ![qnetload](docs/images/qnetload-font-sizes.png) Choose your font size. ![qnetload](docs/images/qnetload-started.png) You can toggle between the amount of time since qnetload was started, and what time it was when qnetload was started. ## Features These features were not available in the original xnetload but might be handy: * Right click in any place to change the name and font size of the interface. * Control+mouse wheel also changes the size of the font. * Clicking on the interface name changes the interface. * Click on some part of the graph to get information on the data used from that point to the current time. * Click "Reset" counter to reset totals. * Click "Pause" to temporarily pause qnetload recording the in/out/total. The speed is plotted in grey but it doesn't affect the total/in/out/maximum bandwidth. * Passing an interface name (e.g. "qnetload -i eth0") monitors the user interface regardless of the latest one used. * The first time that qnetload is executed (if it doesn't have any arguments), it will automatically choose a network interface. * The next time that qnetload is executed, it will try to use the most-recently monitored interface. ## TODO * Handle what happens if the monitored interface disappears. If you would like something else let me know (create an issue or drop me an email: carles@pina.cat) ## Acknowledgements Many thanks to R.F. Smith for xnetload: lots of inspiration from it. Many thanks to Jen Thomas for testing qnetload and helping with the manual page and texts. ## License Icons from: https://p.yusukekamiyamane.com (by Creative Commons Attribution 3.0 License whose full text can be found at http://creativecommons.org/licenses/by/3.0/) Software: GPLv3+. Carles Pina i Estany qnetload-1.3.6/docs/000077500000000000000000000000001451037126700142665ustar00rootroot00000000000000qnetload-1.3.6/docs/images/000077500000000000000000000000001451037126700155335ustar00rootroot00000000000000qnetload-1.3.6/docs/images/qnetload-font-sizes.png000066400000000000000000001676571451037126700221750ustar00rootroot00000000000000PNG  IHDR0=gAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME ''bJIDATxw|Uڀ%B(Q+U쮮{eXVD ^j 齗[gG{CB,ɽ3gΜ9EԑNC>|ÇTNv}Ç>NÇ>|a- o۶-qJZ">|I(..&;;7i`BCC9zpo)>| NyyzSYMXnS2 I44MCU^YY>#_>|/F``L$!2,h"[4:v,KCr8$It:%uЇ>|qBHNS @QVdZE||ر#'tsΡ}riiTUU%y -*IÇ>2@eeeb3!!!"22Rdffj[nbNF F||\ZZ*K555 \.r$uj,nO>|opx #,fE$fZnnm68A!DikN.**$-l6jJf-*[$$ݒLJ>|Cd(Br$ISDttرN@9B6l[d,nE!k&*KBIUU4M~#Bc;IeIQ>|ÇS/PVPEȲndY, @UE4MNh;4dz)Bv&ۭHȲ,I$i&ɲ,Hic|Ç?i]]$84MBUeU$bq;h۷o1-B Bǎ嬬,j.K9zEeBB(R=Ȳt$}F>|OK$t F$ 4M,k $IN'V]RR"iMӴ;v;xZiСo^dYm6IaB5MV (,BY![G,4mtf}>|$I^B$CDh UeUB8eYKB,tذ9m#iE4?MBn,52 HɀW|>|'Ad*%i$ ! h ,,ɲ\PѷDhBij I8p :tҤt*~1Ç>zFGfk!=ȝB8NrǎQUU۵kWI!l0b)##@l2(b$v:=> Ç>| I8p@QU5@e4MUE8N PʤaÆIiiiS!" ̈#jjj@FVE$IB(,eYȲ,9NW]I||si2}qp8zH(fML$5MSUUJ*++;O,Y2`h۶T\\fTU,t:%$V# Nc#}ޑx7Vɉ>< ۾Ip8N5f3v-9j##2,Iv%"9 v6mHX?F;v,C*--PUUH$5U FUq#P["9q|oP>| B`2ҥ t3f &L`޼yY支vի? =G4vᣅh;($ɒ$ɀ/͛jD fر*FwuBݒ$aX$-S/1G4hE@XPsH2ZFTǙ3vCc{0f1wfoh|M1L(>islꚚ!2fc}!tyB"*Dh4 KzGS E$Iu i!exx|8t҅+ā4h{w\}դNdd$7ndƍJxx8ƍk׮n6o̖-[ҥ &_ٳ*c>QU`.B$IݻUVQSSE]D߾}׳sN4MO>\r%82}I\.6ZV, UUUX,AlƼuOYhΤ&M 0a$l6L2iFU檡1*oBx 4e~^&k>կg[ر#)))==zPQQ@xx8}߿;Ү];:DII &Mbڵnv$IҰs)))K+2W_}5]vʍ7HHH_5!!!TVVRQQAСsر#f`|}8}(?Oڵkm6f͚uk_رc;w.ݺucȐ!+yi]=Ƭy1͒Bn)M' 0'iIiӅv# I*>ѼވWU8]._>0ZK.lݺ{3rp:\.n7|s=DGGЯ_?TUMDD{fΜ9 <fΜɡC0aPJ7roҧO/_ή]۷/TWWӵkWbccX,tЁ 2c ."^TU5ÇӃ-]r%N0p: 0qAFſ/lذJ\.ױ.ȡi- IWFG_EMM q\8iddW"Iyy9> g!;wFQ 8t֕B*++QUCCii)Q[[n7T\.~')**pv)**"//jTVVRSS(Ԑl|nX [n!22իWSZZdf#GHII]vF} U>|G7fwX,}L8FmQ|222gϞwy <Ʉvmtb "##2, ˗/'??JKK)--fDBB!\@{uNNݛ .N||QUK/ɲ/ƍ1^5MߟcۉCQvq&NȠAHJJ"22ڵ"C$ өI > 0:R`0p}oM>|yrrr?>&M⥗^"33O9Gߞ1c &OO>ix#5g_Y)++cg$QTT(͎UUILLh(l߾-JCE!==s2w\wΐ!Cu^8ŕyH=t28T2v= 4ըot:3g;wD$L&&DNj~mƁXd "..I(//'##MIMM%88|*++СCHĆ ͥM6HDvvq믿NΝTVVҦMq8|Ǭ]!%%%Ǔ9ć(BNN&m ̛7Kk&&&uVf3v"11tDRE:O`ti#nMJ#ХǑFBMdIF\}8+HDUU7nv3`, 2dgg'''~oUU9p3***ظqu$IƹB:DJJ =1fggs m޽y[θ[4WE$fISsֆ7xyR;dń[U=&KT YN*+*}oN>|t͋,˔3w\8FQ/M}Y' 'm8yӰ\_@4)Ɏ$q3>|ȲL~~>IÇ;'+^8Hc3ʇ|t٬2l-ì>|c)i`n7n|Ç=n)k{OIq\3GyDÇ>|$ojժS*=)\}H|Çd2rv50Ot>|@ldN`:9Ç>:HT9pͿʲDLXŽYxz< 'Ç]Z<nAY"BOu 7`114!^m›bN'EEEhh߆!- AAADDD0&N"ɠgDгWLB7gT շ9DrLzfm5Nflgy ?̦gǟIMi Ljq\.jbv,a61[-cѮt jn4i\XճRF40%Iu֡*z+wy'.-((`ƌlڴ={2etҢ5ڵkyw0BǎygOصkr5vIKKW_%''Yy뭷ׯYJKKG+;<)j=9|0\p~;ͶÇ5kw&(({X/fӦMՋ'xF˔$Z~G.\HYY'O榛nB4yؿ1]>|ˑj.ؙ~ݻÎ,I(Aj0Epx4}w"!:ZܚZZjit:B`2AlFUUl6n\.~~~%,SRRo͛ZHC;F% KEC""C$qVK`(Ulͥ!I&8Mӌrc=qX,f3. BHHMS{ СCvzAhh19V͛73vXZn24 xIhݺ5]t&663򩵹,|=z4۷UUiݺ5~~~͖ f?/???)88XTWWy 0]v%88ÇK'"*9s0j(h,Rvs73`/_~YL$IO>\pL&;ʈ 33A1j(YhÆ ^?fҥ}-ֈBwn6~eYfʔ)tݫBZnc=Ftt46m:ƍ)))!00#G2`/ڵ+eeeTVV2n8z$I$''f***梋.]v$%%n:l6zb̘1SQQ… )--%..QJ9dYlݺn[nz~[nFBзo_|MK/^U,\<"""젞兆/al63e&Olu I`".DO<Ӌ)HbA$]Ťم^[EfGյ8j4QS[KVUP[A+`VΝ;/xh/wM! ,,zj>Oԩrزe ۶ml6sӯ_?;w.+WnӺukuƎ;ضmqҭ[7.rۛ\[:{w]]s! K@￟o-ޢYln7|<ի4hcƌgϞ,p222HNNxP/TK1i$vyBK:u]veΝw;NIW dYl6L&s%66n-;vGa6c޼ycl6/{]vTTTEBB۷o穧ʗ_~?n>s}]E!>>.yf>ԩSHDqq1EEE׏(:tŋ!88Z^{5rssy'޽;Oll, .<СC|\{|^+ŋ5k^z)~;B߿fӰn7_|7ofx㍄+I"<$]y4D. *_SgΝ:"-$+ܙ8}Q]]m,vvRl6NBBBp\Z|%ϦXg}24McѢEkƲe9;vΨQc_rssY~=ӦM3 MQWW,n:mw3Krs6! --@:t`\ȑ#hFNߟ! 8;'JJJ())1TU%44T RdYl6K.E~tܙ"-Z Q.]=G+QPP}dž +eH~aRSSy7HOO[n\.xljA4jkkOhqwE$nV5pcmv3rH, ׯW^СCtEQڵ+o6_5Deѣ " ͂ HII_&.._|#GdbbbٷoW]ضmWgj9աidա*uuuFڷo^[gPCl6f͢]v\,XY$|lBݽꢫb2h߾=n:x'pY T0PvT#r ㌣ VZs&;;oAnnaҶm[iժYYYJyy9'}mY4/2L??δiӘ6m=zUUk0|̘1\㛼n9999|\~{lSNի{mrr\v̞=łݎjp!DGGuV.b ͺ`„ P6kx߻( Ic?AAAhacǎtR֭[GXXnN:5{nFFg&33Ayy9!WTTڵ˅0ѣʪJJJ_cذa<i-⮻"..Ƭ裏}vfn5dI)b>gB_HnsΔb|w*\$JJJϧC :jbcc6**Xduuu[5kPYYIyy1oKDOHdd$3f̠M6m6w/Ltt4<#̟?;k ]:EQ/lPOM=\Ew:tȸoY;0| >tWqZ!Cر!;w&11iX{UPL>;w?e p_Or',,0l pWrwR?iT?`:y~i[mۖ{wl^~e"ÁFex?~< ff>F Si5Ǹq8r~b;}TUU k#LQ%A&x7 **Pr"%%M6{mUUUDDDp饗rСu̐ ڵk3g?#}!..hƁXlP/mbx$%%%e[I_u>|-[ЦM/?"$kRpøV8X\|bB@` m0c7FQeX0+ec Z-DBD&n ;nUpŅ΍fhUUUWKs}M >l|7dvSn0̈́gF'%%a '00ۍ$IQZZzRѵ=z`ƍ|WTTTPZZJ 5<4McǎiӆZ2dCe^kc`` n:ZjE0MΟqqF$I"33 &pM71i$RSSILLSN ͑f;zq9rJfϞDe TRSS)))kҾ}{%9BCCԩEEE^ʯJff&0^›C'u\.ɲ,ɲ,5gbu4::kn#F駟2~x>3qBBB 7\܆4Pn6yq;(>>n''X v1~x-ZIJe˸+y۷/F?>o+`<;'AAAKr 7н{w>}:@sfgh׮999DEEѧOكn_~TUUgC6mp::t,իW V6yyyٳi<`l ??P[[K֭>aVvd_A V9am8/{Ϋ yQsecgKW}kx=g7z^S_ۚB޶z<(Oj}<g,[n`*NT9Vf c.yckhU4v+::ɓ'3p@#}5wMաvk̆ʹ'S? iFL&7hsUSP>1M]vY\BHvV;YO fkȮ$A~+TasV:4!M{L ;G%ieB Lza)-CZSTgl !~&XdYN@E!&Ȃ"hꉍ.cرvz--Z@Ј7en@VZl(ԜܼԼ𼦮w*sW%/M}Ԝ}2坔 0GN߈;4M#>>W^y1qfQUr]L,c blH_ǥ ̲(Rl!Ka $ T&I::x1n)%,K)at7mGAUo}c9T\Ǧr &sj8U k)uYф`w^5[2+pzh[AUUQ oQ1}u9ّlP=X٩hGl4}h ڶ%8.J|I5.M&8XT˹ aո. ;eu.̊l hE%s֫ &FIm,I\=ZJMAZIw+lͬKtNeU!ŸZ'C8Y@B'5Tܿik֬pz7tOx'8QNv4òذa {'Rv5O<׷8 9z+xְ ؖnx6^g5%zsj{67}y_ ;Q,:0Y-]l|ICu(G=-(yȮ2[ckfG㷤RTu,N.܄0@ރI (u?>BA{ sl>R*Nj'&"!8UE"q3*veu.eUZ=ʺuPoqƝ;o"۷Gy^x޽{tScє$X{1Yd YYY2vXn59r~ رcInn.o7_N޽EQصkK.宻:nƐ$?r7ҥKjkkٰa֭kq5*2ӧOg۶m^Y/B&L+ظq#mۖȏd/^e]ѣY`۷o禛nHG^ꪫ*G_ngҤIMJDyy9_|ݻwgر;˲L~~>.555у)Sozʙ3g]wE@@III,[]w].\Hjj*f#FpE޽{Yt)p%0dȐ&Ӥ(Y̦QnTUO>tH6&Kr#^Er_ : 4,aiJIv}=nr$5)SKYyY(Gt F ?+rփ-K)aIrROBTO4$I?ǟi`t+;2qDdUۍYg̵JKKٴit:)))K.̟?bbbXb6l?sΆUȑ#WICoݷ_XX?ʘ7oº{\r%mi&f3UUUTTTu]_|Arr2~~~OڵM4={0o `F_$ '|y-܂lfҥ|甔PVV"&550:駟x?~+)..fٲe| <OEAC}WD]E ,糲khI1pzDjsɰQ<ʖ.K @_Zx o8|_>|8mLWn۶\g,6,Ξ={9SKmŅ^Ȗ-[0Ll߾{#Gb66lC[n,^'x+V0j(-Zy駹l6;{壏>#''Ν;[ضn=cdHd޽l6"""0`aaa^CO옘mFdd$-ȑ#yZRi/">,,3m4 9tBHH/.ڵkTх :Djj*F^'w͊+x'],9.r^dKHHW^X, Xt)k׮o~&I_|1'N vZnHOQƌCnx7Zdi]tߦs$''3uT-[7Fͥ^JǎoxYfCY_-9# W! i^|vƶYBoi`oX|9UUUW^!ؼy3O=:tH-~W"2EEE̚5 EQ뮻귑BLEEcǎbлwo~K' Ʉ$k.E}rW8=i8j\.֬YCxxep^|ElBhh(ꫯr4Z,l޼ưa *$$1cưm۶2zG$ؽ{7ќs9Ȳ ~~~&i… 2bx2"&{l*..fժU\xᅆa{9jjjP.]oՋVXu]עmutXQQgf^yHL&s-ѦMF#=P(F4u4Y,Hf+vɏu娄snƦJV$;3nњ1n·g&hFDD< C駟ZhѣyYr%ǏG$***0tMMfl~۷/=z6^RR?^ @yy9999̛7$I_&O>S^^ĉȺl2ƏO֭HNNf֭\s5L0no UUIMMC^ jKD( {!%%k/={tRO߾}m!XVVXȑ#5s\z뭆7l,}vy OUVQUUc=F>}lFAtt4SSS"a~Fݒp:^z'ڮB2e )))$$$pma6?@PPcǎmZMĘ(I*Y|WíQeh4@_*p>~֍Z=c|||*Tݻ7!!!F = 'Ʈ]2eW(hYn?03̓O>I^kYf ^{5mҫW/Ǯ]2V^i\tEFz{̟?R.th$a۩! Ksv9۷oK.İ;ѷ<>p ^z]>}P;weƍGHH,YCӒ$ѫW/ϟχ~رc7n^BVhh꾥­~EEE|$$$믿RPP_e'κf={лwodYݻw6Cz|z@:v[UQn\G=G3{dYfM~v>|8uN۬wCWdDEEC4e˖СCX,^_}; Pܹ3:t &&Á4i UW]#<ŋ;Yb={fxb=\c{⋬ZM6SZZʔ)S]zfo,Cxc̺u0`a#IW^yǍe]f%:'|Ν;O`:FCHNN駟62\qX,l¢E_x6l r\RSSCee%= ,0qΜ9fzn摑{ӧs5`69s&-_W]u1i _ .gvGഎTH7|%d}Q|I***Z4qGk֬C 8ݿb }]E]DQQEEE!۷/v;wk.󉊊zoz撗gR-[5\%dɓyᇉ#11Vhv;^m_WAii)Gfp8x뭷8t萗FRR]t!p:]oۓImmm>66ÇL4ɡۍv?ҡC b&B8p <wy'ŤᠴL{"=Bڴi̙3Y|U֧O^((( ++ A]]Bϝw/bhCvҥKIMM%==J#PO?'|ȑ#ϧun(HÇc9mĆ xg(//?DPhHua2ZtMYٸq#~DFFիK.E 6m_~9˗/_D4ڵkg7,d21}tK*++iݺ5#Gpl2 KFexCUU9rd^ c۷؎KKK{a޽ʴiӘ={6}f֭8pI&`…DEE1d#dII /^zFz뭷?79I$F9ѭ[7xQUFi#F 223n8pS\\llGX,#vbo Z$ѣ6(({rYY,PŰ GUUZn͔)Sׯ6zʈ{͈#b޼y2rc""_|ńS\\jeРA1db׮]TUUq7XhUnC4V+pWӫW/s=׸֘1cs5oѼ꫔`2ڵ+{.fknݺy=0`jϸL-vzje]fTUUS^z5i[V>NFdСRjjt:`t*6ͤ(Eei,\~x5״{=⫎xŒnۡ2}É\MG=QUհ 6ՒM$a69]QZZJVVݺu;fJ vB>V^oMBB1<[*_Zxki[e,zeyQZZ?y[v?~(C=?խ[{fsi,iPUX,juufXD.]۷]vV#^MӚM]-Mvؔv w6DiHLZ!$1i$o,-ioj;dR<4ljJڵ i*)5aڶm{\%!QQQkkkIII!??߈w^gϞrHMM%''pzdeeexk:tLӧOO7EEElݺ#FЦM?)nڵ,]ɓ'Jhh kllh3Kas˗uh =_???Fcccv[(Yy]KTVV+Btt4qqqdeeqwS^^Nyy9}8pENyy9]wQQQw}7rss),,$%%m۲i&seҤIYHѦM/+hfϞMHHƞ1F={M%K.%::[Һuk.ҿ`Z֭[5\NVT9Sefi]}h!Dĥ^ʘ1cxg8t&55{ͬYӧ&L`޼y]/zvʺu4o ZZ 60b.]رck m믿N=0aׯg\veqӾ}F$%%̈́ ~;NrrrPUaʸ}-qmHhSO=Eyy97xٮa8wOVV 2BEE=}/i^ BaxSWWX[[k'''ټUU54): 3QRRb55 ^oGCt: ΣiӦwA߾}hnݚ~!2Vs9n͛`l!HJJ:#=>i`Ō17Sϙ37xiTTT4MJJgi~!PJnh߾=r uuun#r~HQQٴisߟhvax4Ӈmr뭷4M/g„ <3lذ 0 >}[9&޽{SZZf#77_E1jԨ*X|ݎlý}<ӬZu\'On}nzv6<>vcZj5NeZ1Lk???}Qn6jk, \s 111FbH*k׮_wy: c֬Yl޼&Omƌ3x0͌;֭[3w\v8SqUWwƄn{L&\_M>}|)`~'p lW$&&MӨ1lk׮sssٴir-yf>C}r=[o /`|.?'++ .RȤIBC=D@@wu)'BBBHHHEQbFC wѽ{wz)v;LPPmڴ瞣 ???x3lGDD`6yGp:q&,,76LHHg? SGHΝ ?UC`0+WdРAtزrk>9r9v;aРAٳ~%K0nܸFmUL&}^뮻cl6XBT :NJv=K<5Z[_xxW_l7VKk4$22Nąlc2(..YDX( wo+|O?ݻn7 رc$&&(ҥK$|l8l2HIIjWrss)//_X,4Mc޽@gM-$\vG,q|$''XM&3gd݄3yRRRBzz:믿9L( lvJ(ddd0{{D$N'ϧs Y3f ݺuCC3gŌ5 MPM6( W_pqFJKKq\SRR—_~Iff&_5[l[njՊdE(;;;9sx xzPfwDvv6P ؽ{7ׯ74HbnBV^ygMDGG3hРZ>˖-pjEaƍ@$I>|Ӊ5k֐RȲLFF);v8zV⧟~" W^yň$ѣ6m}֭33L|8PSStgφ ~/k֬9 fɒ%ܹle|3Ҷf͢m6~)neܗ,6M$I駟mEcvm?"n?Fvך?gtΝ|׬[/}物M믿ҩS'OEEofjժF?w:lݺ!Cs @ff&ra28pm=tPLRRk.nc Duz$F=7o&;;pqNMMfQUUŗ_~i.zzjrssIOOGUUL&{1M^^Po2{l}cQUU-Zd_PP… yB4͛w߄$In3vZnhl9NvI/[餦!!!!.RUU&((謺1EXXXTFFnټy3iii(dk׮/+P !Xr%䭷Ϗ?:!''E_N'6lSl!(9r N9n҅d2Q[[n7{I&@o8Nx z!l6Pȑ#-F={8qѶ#BL&k$FiTVVRWWgDzehժQYYĴe$I׽~?˗/'11hBjkk-Պp.++3bTss:4Ak2N{w\жm[# @II 6`{g{ =؆uovʨSNSNQQfˍMg=)-BYY999(?7N2q\XVl-cgdh_OAee%vdYf80ңG|:e˖ѦM|A***عs''OSᣏ>2cO:u*l߾1c'Ѝd߾}L:68:wl?0eʔb>Cjjj>۷\vueffrO?5A$nCxO>???Xh`(­jQ[oqS\\Ldd$SN=c}ꅗ^zϫرǀjRUUeuָn bb!??Ӊ,˄QSSCuu5&֭[#040*aaaR^^nMXX6:ý cCZ"$$ÇSQQAVs;]\q\q撜̅^$n$>3?Attq]`1`Æ tԩ[rW0w\꪿uZZ{=2q8^P(Bbbq]a<枑kɲ̣>Jffi{;)((8io"}TՅ$Q\\Lrrov5B8p"nQ]]TWW#2AAArر#v am۶J]]۷]vXVn76 UU!,,mR^^NUU.∌UUQU~ۨ,RUMCeA϶nJhh(;vmQ""" o=Auu5DFFGTT$ѦM#w||ᝣoL&bbbPEQX,ǨupC"IEQ$XqݴnݚOMС'NK6EUUZtmmM8mڴݣk!ufHyNUd2i&Íxv@n)))L4 Eee%+V[nv}B!1oJsq4iQn7o {޽X ;; رc'ND$dYf߾}v>#***b۶mz뭘L&Yt)EEE_T.0~q8|lڴQmMM ~IFFfjQ;iԩSQJvm*}/MҒ%Kr\Ӊi{MSv0`JuNxרeiӆ~f-I1$ɓ'7CUVkΕW^ `mۖ￟W^yW_}+!C*n>#G/̀KطoYL| )**j89SdF&Ν;sA Y_n7V3fȸq?~qg`O!&BRRRر#-.ȘL&iEQxᇹիriSO=ٳ'SYYIΝIJJ2NKKW_ߘk$IB~mm-t ķ~֭[yg{9rݻc2Xr% ,'0y].tiEᩧbŧT) 0Byk RjҶm[cŊh6mdggDGG(ˤe[111g~~~k׎z_~mc\pӧOgF]vqYΝ;!x'xwHOO'**.]; Ǐ?&nQV7>[r%555s9Fdy1{%,,͛7sfJJJسg!s=F˷~'|@ll,_5?]v_̙c8Anݚ~)SЫW/1c̙̝; ںu*&W~~>ӦM;sD~Acp<qS oi" N7uuugp8+++y7[l,I,Xɷ9sxʘ6m+Wd(b{uu L&vMTM'Nt:qOÿ4vpt: \ct8gǸ\.y~_[͕z &z=:emy~|M5o8^222}[zzO/^LFFwqq1qdbժU߿8o hIچ4v|cz 5G;FoyLƮgyaM!_[t$I0'0;;iӦ&BEv '|7|sJKKyW[Ųh?|Fl6GNN 2;NhFfffӽ{w#Ν;H$G~~>W^y%C EQ(,,$ EQ(**X2`&'cРATVVa$N:nGQ:vÇ*&&N:!2eeeзo_#OII ,ӭ[7dY}ѣGBCCQ׫W/:d| !qqqtЁ$#w^ ###bQU֭[H\\svvv准MFFݻw'99STT?]t1ꙙr\.{9Fz#Gb1[! Hѯ_?ٳU-'xкucdԩ$$$4{~]]WeÇTVVFAA-`ǎLIIWh嬧$^zʿ'n7eeeM~}v"##ԩqR{o>3O?>͡/\ 0xrnLQYYyJB੧B4MGuu5k׮jrzOt۷ogΜ9;r>c9;"##6l .4gSN(Ljkk裏ؾ};լ_tv͏?ٳKZZaaa|駼+F;TUUq}_k./سg'x>_~cDzm6MFVx駟0'|¼yHJJbm6y'EQxx;x饗x,?!!pB&NȜ9s3g{{1rH=Ì??!yyyvm^C˱X,ܹ &W_ѫW/ڷoϰaø۸ꪫر#k֬frJ8;4og,\celrss>|٫#W\\W_}Ÿq ~7n͔B]]߲e8 ȑ#s6[ŋr0S`\.;$ITWWt:f7Aωa޽̞=6'r|JJ w[nP'u UgMݟbgϞoߞ~[6Y,&Oc2f{ѩS'#Իo_~I/ !?#fٳgFkuu5a6lƶ~|Su=Ac3cƌ[d 93ko!x)))jE=p:S ##66w}G޽M˛G ..pl[O0MӌvrQ]]C=Ĝ9s$rnۈӧOjkk/0.ĦKMMccl߾5kx}vy6nHPP}W^y%3gDUU#a^SM@}ן^311Eqe[zԆe 62g-[fo'IIJeرc!4ٳg{ixn7UUUݻIOOgϞ;mdǽ,ˬ]0]5M3_Lmm-.3fld߹s'K.5znjٳ)++t駟GVVQ[[Kmmd4ӥKvEYYQQQlٲfe9rrdYfСܹK`ݻ_""":t(P/Oؐ!CJpp0Æ C$#$@0`䐓s|q璗:t5Jhh(JII ;vgϞ?S&=yf&Meȑ#ٱcQQQУG.]JvPU]RTTĮ]ZѶm[9bȐ!Đɶm۸ D5k0L9Dbcc I}}xĔ)SG}$>!)))6l.K\.q:B^,X@_^Ȳ6ӡCQUU%^JlذAdffYb֬Yb̘1K/ċ/h1j(}vqM7^{ML6M[j;w !;E||())6M*Ν+^|Eq @#r#;S:tH|^}bBeÆ B4QWW'*.BaM7$f̘qxKŰa믿.Ŝ9sE]$F->L>]ko| W^yE!7|Ӣ{BaۅwqHLLNS8N(L">e_ @_^\.vK @'_.ڵk'Ə/Ν+v)$I3g -nfѾ}{Q^^.8p07 Mă>("""D^^p8";;[8W^~~~"55U8QRRbj!,[\oٲV溺555lܸ[IJJ:577h nl /pM7q{u?M6fu8N'>hc$;;g}ى駟?+V4yl~ȑ#M]UUiժ:ucǎMXFWrr2>(wy'?I3i&>&_ҥKܪw:Df>Njk.Ba>#DcCѨə$//ى077mزe Ə4WĂ/#88.&Pe )O϶Փ)Bꫯ[$Im6\.>Bi3f/<_un7j7Y}jxZ25.&wy >*++yǍ cРAt4?'$u _~&4k,9l6̜9ӈ{m},\ 6駟6zĊ+ضm _RQvO?t2-:{9o/gyFzql+>9f-Zt12̙sZOxgΘq[WN>l6l2viܘ?>MǺΉ]ϙ3Y}8վ$&5=wAfΜIUU/nr;f̘UX~=~~~l޼u[GzMk޽KzϘ1Kҽ)O~WRvI4M3L5Dwoݼy3^eUU6l@$\.%%%$&& --+F {!55z{Ijup8df׮]^ഩuwܦ(,,ltPڪυQY4nIDATYilUWWrgqljD~kRRRq>U\.+V8cL߾}Yv-7|3III{gEUUIJJ(9nj| 6tc6yᇽT-O>\ve*++k2'ń{UU_']vqyel,XpL 55si۷m۶ѵb1BD]믿z[WWǚ5k >4cIJJbժUFL(vɆ jCjj1|G,\023351 2:7|Ctt4foΎ;(**bنիe~vERR1㯱ުU+Xjb!// /_n$nժ3$$Ll6/&88l4#99(v)--5n,KeXXEQjI\BUfMQt:|{"77K <%W =wQQQ)Iyy9BjkkqݬZ Lq4/f+Kyy!VUUa)..***+{ee1fRSQQek`stM>@*++Ok~=/g43tOUU ֐ =HuZ:MjNMNJm᳴cxxkT =1 UU  88??? ϫ')MjJDzzӏB[KS'=okH6v)//7fQTTDYY1~] _c㽪Bj>nCz;>5vu/;zz5,NSBRUݻs3yd, ,sW`69ݻ7\r ݯ_?x#db;e]F>}:u*qqq@qW_]vwy?I&y `dlzW\qufޥ^JHHi}X$qM7qu5~\|F6.踹FedQ=h׮i?"\r @.>o߾۷c i4Ř1cMѰL0 &Rу|+cqK(~lݺ;v0qSgsΡs'3"""R(mڴaԨQ^fƏozDGG3f?|c jÇӡCf4hݺu#&& .X}7L~߿?!!!^שS'N)kl?[o8v} /6jHHw6>{ʰayGQ=3{@ z tQT_ ~ןZ(JEP)P)@ 'nv7[fG&Dd^ϓΜ9)sΧEXXBBB0i$HR̙3XH""""'7Æ `T*X\tQqTN-L&զ' .""=(8@PP9hHDO@`DDDDzB# :(,..4*{yy9jkkVqU2UWW#>>.\@EE*++,W__'Ohl z~ʗ$bڊӧO (..FBBXEII DgffZ̷=aF}]j<1112dq,__NmQFAPeA4QF³ m>%BBB(*y^^^ HyaaaVK=ŠAп "}:ӧOr^H} nnn=^[.R)û|_dڧ5ڋ=өu{DdduՑ7F gg.O$((swB@߾}WWv}|Nܩ%U@@P2!&&94/'Fa#"" /44Æ #dF`` R)틐1 Ð';w.iEaԨQd( dAaј|8"##1sLHR!H0jԨbFD%^8ğo""&#"""UUU$H=x08ph$"rt W0W^%hR >cǎ02=&Pggg0 a T LF>; ...$a HTK\\N"o2P( H0 ɲ,y\.'yvrrj%0`n`0p)O>n]s $`4q)#&&?Rę3gP[[޽{#&&nnn 1EPT2d TӧO#''y 0wq4pA 4cǎEUU?P80ѣgEQCzz:OeY$&&h 'LBںȑ#+f͚OOOTTT -- P(1b"""wYVV/BV#,, puuEmm-T*e5/FABBjjj0m4ĉ0L;pibРAa y]7qcqM߾}OOv0puu~֣:0ǑcE7L w}/".]J( j9n ^O?Ř1ck.`,^wqA(TVV_?1_~%oߎkh4W^;Y>X|9;PZZ;S]nعs'DEEbz֭Cuu5fΜ)S 'NヒǠA_+V#G'|`|رchx ,Z:MhnnƷ~'O?Fb 0 /_5^pZ wy'4 RRR~`ƌv߻-I^=-hܨ4 y޽gΜAYYw"LoGcZWҿ9#5=5sjtSGP^梪l766"//jz˲ĵvv6i'usC=dqTF;wDmm->̙3ǥKP(h"/صkgTVVM\VrJ,"44ƍQ[[?NJv***|(J (L&ĉQ3gɓѻwo555شi./Ǝ;P\\l ҥKؿ?fΜu֡?z=^{5>} xWaÆ9<>|;v#< B"eY8rf̘;w;0AJJ |A(477#??999(++#GK'Ohıc,BPث[1fZ `YǏcٲeaZz?233XbQTT~?0v܉Pl۶ uuukҐ ZMX?yyy8vxVZ1cܐveʔ)x뭷O"""nCQZ-~G̛7w}7|I$$$a۷wPTTK߇Jʕ+[o֯_x;v0iؽ{7Zq0<3q & III< W^,Y#G"** tpb2c:u /"bbb Я_?DFFB.= ު*c̙˲O땙vBd\z%%%?~<׫WCyy9"""0k, ...pqq>hW/JDD1zDvQ[[{ӧOGCCmۆB<T &H#G}H7tdd `> .gmb***»ヒ,Y yxx qqq$.p䖝 JJ`ڴi yEqKL,0`ӧӧO'VdӦMohRβPq˗QXX <Dc@[fCӑpp)SiG4I&%(w+)Ц~9(JפrFFii)֬YL<&M¦Mo>דt+r!//鐝 RIY3XVa۳$Ǥeh JaZKKŵ?&tz?`Ŋ=b;yzaꫯbرF^*Q[[իWcذa&(HڵtǡO>_ lٲUUU`)))̙3 Gff&{9^v'I{-MӸz*RSSb¾j*<쳘5k,XBWWW s_Y.0Ʋeˈ! #FpH5L9s&/_r߿b77l2>|Ĭq0a"""w܁_~ذa/^gZ].EQ:t(N:[|Ѡu$DFFbɘ6m>ڵkd̝;gφ\.ԿpLSOaٲe,bРAؿ?Dm۶H=^^^PT())Aii?a4 L!!!0LHKKC>}D`烦ij444X NXa q!wܘ8F` ~$-{Mx_("??D޽҂O?.]›o|*a0qDHR={ -[F~L&@VGLL """g45k֠ _|N|mGLAPWWu0o<̛7'N5k.n'__.AʂBZSSC|UUUa߾}puu… HաhmmL&믣/2MӘ8q"r9~G:HMMMh4br;8FDDϣG=`ܸqxyfTVVb AXX\]]7a>}?.\Hm֯_h̙3Sa9s~! j/cСx1p@466テT*ٳpB+xgV1n89ؾ};L&>#||H8wy'={0(//?Z,̞=AAAEFFz-]KЫW/PV|||пAaGD"K |w8s z=s!,,apwwǘ1c,FѣGcƍعs'Z[[C"d2}Ǔ29ÿ/bذaiׯ?W Æ `C0l0 0B7%557nj5L&Kڰׯvڅ---tV\K>|8Z->c\|Jo&;4/3UALrss裏BT"77?]2""""5zLaYxwcTTT`xG J_|III8p Hm{DDVZǏCՒɍ8FDD #Gd?R)92e+rp]waڵ8z(c!((* wu %Y#X 83g΄tR,>FEEa̙۷/b 1c =:zsss=܃HPSbɒ%PpvvƽK ڊ#GrsfΜ a=B1cLJL&rJǂ4磠j›eO]G^:;JOp0i$;1"7k`l]/Rsε^<库H$#>j *E!((oEn-3 !Xu,ȭ=MR9Q.#00PNNNDJ'=~$"""w(w$X(O  ͍JkFHDz8Q6$lٲ555x1fDZcbndɒNp4j{gXd zEB^b׮]X`}]$&&BDD>#"""'B-[ 66sov5)p>*JtzAQrssIu 0F'Na.򷂦i;wH鶰7nFm,#Fѷ'`rJ[`/~J纏hD"1"s6=\ vxd'嶸5#n۲ļ!J"W_EQQ|A( ,PP,ћȍG\:$m*++AQ{?~ܡ{J%Ν;w.rM{I$յ?B!tƨj9sfg@`$+**3C]]Vccc|ٳ=2| p>Fƍm^ߙ˲ظq#4ͮےÇ֮]+=yk׮u7oFCC-!E999]VH$`Ylݺ/r9ҐD~-N:SaP(PUUիW#((>>>h4شi^xU(M(((Fʕ+1j(DEE8d2$$$ ,hg^0 3Mhhh}0i$Z[[_L&h$K(wkk+~7 :7oU0BI%mLFڍNCff_ MhllwPxGQQʌeY:tζ9K$8p ۔+0 g]`("e999㏻1lذ"h`޽{a2uVx{{#!!%%%h!(EQhhh@qq1ƌPj=z|Wpuuho$3Ƣ]455СCJz(--ELL JJJHxT*Ezz: F(9s/FLL $L&83f̀xGss30foS q_nwj2 1i\|@g9CXX&Nxr[{nhZխ9Cmm-ZZZi\riiipvv-?[P^tw灶 cرꫯŋ;O>7n68vLJ2m"##O'O#$bbb|'"?hii'0~x|7hmmE>}0w\lܸ,B*7ߴhXx1SO=> O?4=ɓ'[lt:$%%!77rWƐ!CXp!y`ԨQxnX=СC0` >QΜ9G"88χ'.]ڣqy@BBuQ8EQxѫW/<۷wFY˗M6ټfڵ'|wᆴ4Z˟1R;vqv+ ew^ m6vgW\Azzz8lذG0t|>#䀦i#\pTUU|6HIIc*yya.]k'OA`0W_dBII 4MG'4MhQ]] `4)))xniˮZ&JZZ>C3T*/_G}d˗R6EQHLL/|ꨲ/++GܤHR$$$`СHNNK  abذa裏`0NǕ+Wnvu89VT&=صk-vGvڅvF| zIbݺuP5 ^~eٳ*.EQ0L0 /QWWGvZZ-xhď?hQm'A *Mؽ{7)ڪK=ziiiO?aY쌮ԙذay]yZ۷on ^DEEaoРA@hh( TjY/n:RNeq)Y[n-ɄL.Mb+|:>:"saرcĈ| Gkkmٺ/U(qh;pD뮉8lٲo6|>ne>mB4}]rtBZZN8͛7[\c!x$%%O?fʕ(,,$p%{gk2~zlڴ YYY/O0Ũ$ϟ?|rҟ:|DN:--d<*jmm/L$??WZGŖ-[P___]ZF9996˙۷c߾}r+T*0 .n۷oӨQxbӇ2 g… 'zXMAA17Ǻu\zXLQJ%,Ȱj5ȼ\WW#GX,t:禦&8qfyaCbF^O|BCP`?k48"%%%Xz5Y},z˛ә Xz5H}2 gϢqqq6W,Hpi,իWSNEff&֬YT<}& ,"99YQ 0# hZ޽❥`͚5om1vDyy9݋jKh{n:8w]?Ʉ 6Z P.R$;*裏qUh[)S, ???P \|+V޽{1o<š{&&* zPYYs!==ΝqhiiAFFV^ HWWW >ǡ?^}U[>,ѷo_ߢO>q<0tP8HRby:;;cСpuudT*Enn.9h4_x-AmrHR 2,(L&~2p@;fL,Z k<,5PgNwx`Ib \Sp`̚5b|g,ļ1{lj899F{'V3f̰{AAΜ9ٳg;޷~k !,,|7dǏc|?ȑ}z&Vm n㻤x˲l; t&OlqRcǰk.j*>))Z\SQQN|ŅommmNQռ`0?.s8Fe w޽j\/G#G,sNbm6$l۶ SGu҂!!'RRR:wc#Sw-4 ^y ;>iׯ'd0 ._ӧOcϞ=$ x'qIҁu:9( ~i`>n;~cW۷#;;ؾ} Gy)))˗/#!!<>y0 pQ+sKHKKCll,q/8_T:u*{1̙3>!} Z[ 0zC!(S7NUVO>v0LxW{.^'N@*BV**33bБ:;;ۡ뻺jllK/ΡUL&Î;P(uLaa!F#R)VɠPYY˗P@ٶm[jAT zVBDDPt(,,$:b7J&p BVD%NիWm֡pd4{Ļ.MӨhgVm7aapU|<#55f0D,((@}}=QVVWU -++Cqq]3ؖ?ggg^zW^1bFqVDӑ#{{1͏z%_*~Î;wٻdBAA+`ݺu7:b4QTT0P'NG) c˲(((k---Ȩq%8bUUUhhhx7 WWW`30fOVRvv6Z[[m 6mBxxŪJPb18z(fΜI&LFyGccc'2^O333k.̝;#Gi{DDDǮ Domm0HNN&VK@#GP^^NBCO裏B&aɒ%M&Skt:bcc{Tyoviv;$%%!))!E4k#M(裏Rj4^qq<0 ())iWVZE;^|`yeΡC0f$$$j*nA&s|衇lf㏑K愒{ o.\(h툋#Fʕ+{XC3#D$,]<s>} 55|/IRAO?%PFgϞرc!HP(Ʉ!C^ 碂\.hq„mzh4")) E>}PWWBdh4Zzz:.] e-6## sN'ҥK> TUU!-- NNNCzz:L& OCT";;82 XbJ%Jj0_Q*jZS܌AhmsӦMe/(( f平755oxofW_YP9sgΜ!V& _~}.]’%K,v֯_$<,Yġ? ш?1y{`SrĉYt)("[}ˑjwoRÇ'ԳP7ϏmUUk7-hV ++ K,ٳgqUjCRѣ0L(//havӦMpi/k֬'R) !Oܹs(..&Biiiؽ{7w UUU~كW*ZUUE樳gϢ hllDnn.A~~>"00FJXd %ꤲK.ׯxǷ~rgΜA]]yH$tǎHII\.҂r̍Dee% l2զϝn eYDEEaxGq%L>=˗cŊXb&L .tʕ+Xx1V\W^yCE1h ۘ={6f͚+WbŊXl˗3fIk_555(,,D@@ƌ'NĠApE9QQQ8z(RSS1w\<8pSOa͚5P(0aF+Wbɒ%`Y2d㑙yAQQQ]ӧX[o&.]J (L4 s )SXuEƌ3ȹ;0x0tP'^ydhʔ)X-<<>>>=n9^]Ő}ם+>U_nnɷ\.Ǽy,V9G `޼ycŊnnnX`y^^|rDFFv{XJqv\SN8}GYҥKPT2d`ŊXp!gY3o|8̙cx !!!6mR)>xg0k,̚5 >,h9^maʕ?>bmΝd2ᡇŠ+ &(\K.Ett4bbbO`޼y( > oѷo_2>CxC 믿N\cm'EQ뮻RkaĈk˗g02e ZƎ BW^y+V /\'_Fɓ!Jxb<# OOk/%<wwwDDD <<E @MMn0pvvFMM  V 77ի[^^A"}իWq899e DDDQrwwGyy9 ggg444@Pի* D"ݻTP(pww'+~o` __v) ! Lr À8,JI[n%½{-9BPPB H54M#88b(BppކۅF0憖 2BUr=_~ F<8|ӡQXXh7Ljj*>[J3"##(d2x{{ݽGQˆoPP<<< 777deeO>AKK ...d̤( }A\\Ξ= d~5^mz`AAA'OOO aaa۷/<==퍾}"$$:ٳBJ% @Q"##-B\\pqqh^GIY1`x{{*!jǏGTTTmۣǜ  /^w(CE޽R_{n@*bϞ=8w~'0 F8vR)$ #==nP+CpR/qŋO-Ğy2xWVVM6H9hZ_˓D"},$yf G! N:}bi999(..Fcc#.\`7 qi24m1~CTvE)))3|$$$8~##0 .EҥKEm7Rww鑔8#BϟGMMM3i0n^={ô[ZZpԩJZ<#>>K *(3&$$!99٢XE\\J]aY#oj]> ɓ')w)qvhVKa[M|';7??\g9ɓ' 80(--EZZZw)BCCU׎`Bwqջv0H$|2::7oneNQ˱m۶z644t躿H$$&&J@[غukcǎҨ3\}Qwh6l6#"{Ǜ!y|W7]Q*ENNNEEE^uR`Wmzmjjƍ;`Y6lx4M;Z, h4lٲ"',c2W_i&b$=p@jhFIII.4Mc˖-֚:dff yY8{lMI&XQZZ occ#222ȋ-4:ٸ9,& ehnnnKRVVFŹ'.5--- "lQ5557ʭFEE䙞Nѯԭtc}ZY{*3eԄ`nnnNzUUU l7h4ՁyAPeY444@TB*"007 ۷oGTTzjlٲQSSCʰw^寗.{8UUUP*PT 9A@XXeQQQn=˲Fcc#T*{9[GQwu d=ZLLEnyySO=~Sg(̟?kӕys]awdҥt===OwY_kʔ)Xc>mY{*^kv]i7b|' !̟?9^~e$&&N`` ,Yf͚hcѢErӜ~ئp[1cƌP^sa͚5(ЫW/tcL4ɮV)YŐ!Cb b0 ,XLiӦaȑܐF˗SdDEA&a̛7Xr%(JQ,XP wqPL6 -?1c`.\haeav &|ld2( ^& XXEFDDDDDD[\s1Q%¦ KRŅ?|-;l;99Q#Fhj5R)E4qEi2,T*BJ}ydggy( -%%%ľ]P8'ɠpy悢(rTWWR瑕ȳkjj HPWWZ(JTUUȘHLLDUUyVEEEt:=dd0 Z ,]]] a.#BRr,˒(Boll$ֿ ex"WTdjwW__4ݣJ$bվQQQVkk]i/]dKee%QSS4z=.\@ƗR) {]4j ǎCkkkW\QYYFӖdhiiAee%+L&CUU wMMMq ACVFnh4BDlyرcHOOGyy9T*\ɄTbllw\Z;wCP(@Q*++Dܜ\pͨAvv6PTTDC(GSSQ__OM(30h4my(JYa8Nǹ˃-vZ1&5jN6 )ReFѣeL&/(Mˆ2LH$˲( ǵ3=k6$𙠼s-]?M0dTk$ X%>1r-D,KF#t9밮>9MӤ;'wFKubźڻƺ}ZY{*Es=mFò,fΜիW!_"]i$%%7Deee-D|Y 9|,7NX*k Xs4M>/)V?0w]L&<T D| qE?6 L:cY2 ¼o]Db{µĥBCC_J ôRe((JYąrO^ 87"SPJ4 EQee<;,NQ2haxДO]:Z?""".@En,BӉB yt7P 8N0ax7Rey^0(EQLXe9///3VC~/hhLFL&(dRH$9˲R$m.cheY%M /yO(q$Ͱ<ڦ p̓/O4ih3xgggԩS|aa! k4PL>vE4 JN@0""""""/EA&NNNpww6:xqqZn ׻UB1cЫW/a R)-zy0<)))F4r9x8999~c"ZDDDDDDDuL-3ĉJ%tEXtdate:create2020-05-10T10:39:39+02:00V %tEXtdate:modify2020-05-10T10:39:39+02:00 IENDB`qnetload-1.3.6/docs/images/qnetload-started.png000066400000000000000000001772321451037126700215300ustar00rootroot00000000000000PNG  IHDR0=gAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME ''bJIDATxw| $ޤ"*ZQ/^kׂz킊RDQ4%J${OdݐPݙ3眙s=y#2>>,("*h QUUNEQ$\wɴ !CkkkQEbPUըQQ/ 0(QUUl:DQmz1(hE-:"yM)h##FBAp:dl6V jӱ~3fl6P^^.#I,yAl4ΕtFq|C`$qƠX<+(`k׮L&;Fmm-]vr cÆ g|I^x'_Yx1n | .~z_OZZ!!!elق,˄0vXud۶ml߾]b0x'8p555|"2\zAHIIaݺuqӷo_|||gӦMٳEQӧW^y%6RLE|}}݄Áb9^^^L&jjj0Lx{{S__6F]6Ƽ5WY1gREQX,h piE!KD *6nMi7W جGßHc*{:uDZZFGTUUСCtԉ8)++c 0d0a P]]۹Q^^E믿qƑ,vm2|ӱcG)--e„ DDDp:uhODo$裏sNfΜukW\1c3g <7| 7˘5/FQPUUu:BK`W`\O4I( 6 ݁t"2DU4UqyP#^Yvbw8K/p88N'III|'>;3fmQ\YQQW^Iq:lڴcǎ^6MXFN7Wi mIW鏢(fVjk`liJjgƕj3,ٳ']t `0 2VU_-v,p8deeQQQdb@yy9X,IHHЅ hp#??޽{3zhV+۷A||}п$It׃ ȲyDQ7`˖- -ELJcZA$VIN.GXX<ɔ vNVlY_FKUN]lFq¨qB}O_7##kXvԚHEEW?$IjuȲLRRGQ$Ib׮]'hQ"IǎcΜ9̙3ݻ3x`-h[=6pNG;ǵ2,#;Ѯn"L>۷Grsss~mtjۓf/~CUUʈ%77Y=sM$<>c C@Р7o6 lLJJbǎFIJJ`00F]=$INǓMZrSQ(Qshq$4yEзP@QUDANE>zpNlقdL&$IBENMMСC߲,sa<ꪪزeu$ǎUUt177Ǐ+r6nܨ_СCmT=x_EFiSkh֦xyrNQ2eIz*(((N;UUM""̙3Çt:$M0hwKJIsNx4-#xX6ڪ)IdG'CD$ҙXDQzKפx 0!FI5 [0ͧr4'\`0MBB:t`޽Iaڞdd2yi{Z8άY>}:fŋS]]& `0sN^|E233lڴ EQ0#)) ooo^Z[6עA;F"">CUUL&A;iN,';V+۶mݻcǎ/++cٲe駟2VbA 33[rكfWQgڴior߯?3Kl6VÇS]]MPPvxT:8Z IP6J(N>&:6NjƱCnՐWQ}WVVR__nf鹹F#`2 lVFK$@`` ٤EPP>Hdr{w ۶m_䖠PA]vtڕ 7LE >bX&88oo^`ꫯrq9«JJJ/~VYQrssIJJ_%''5kְ{nJKKg޽ܹs:u)9Zl[pMӭ[78zp*3M8{l.7z8N]z/..fÆ dgg#}a ~*** %;; .K.J-[СCy뭷/Xr%> ;!(!I_~%ƍ#;;ٌngŬ[)** .ꫯ&''~ \p#FˋϟO= ??CΏ?ȡC_'<<󟄆rQ֮]Kyy9 \qbZYt)t EQNx-O x{{3~xFͤIȑ#ر;ロgy~f*}eԩ̝;˗eʲLRR=z`ڴi$%%,ߣ:[oѡCJJJx'ضmfh0}衇ooo>6<>ާf ^ ?E((m\ ˲Lee%fAp:( ,SWWok /P[[ĉaڴitEQp8l߾;wb49r$9svZV+1ڵn 11ݻwsNK/%11k׮5;mf3gM@Ѷ|In6oѬZ ԩSq8!((N'6 /-[PQQfc֭DGGsw/̾}믳rJ^xjjjHHH 77Ν;/[ F>}w樴Gxx8;vd@}}=o|8w}ǐσ? gXVj!H`EBN.XV˱X,vBCC pPYYk54\_k֬_EQXloQQQl߾Ǐ*w&$$K.̂ شii&>Cڵkj]fsgkƍٹs'{//0}tV\ȑ# joTU%33???:v_(±cǘ?>7x#-jSJBB6~p|||䉲20Ƿ), fYвG7O4Ѧ/]te˖i&zl6]vm=zoMQQ'Nd\s5HXX>,;vD555L2HEMt:9r$,^͛7s饗2e2e cƌg„ $v+DE$I}|DŽc6 eРA<0w\oe͚5< :ӧ?s7vZjkko祗^rf>dY Պ$Imzf3p֯_lFe]!2$##Z7-Ls+I;v, v?۷/,#Il߾ݻ[]]ϖ-[HLL{@||,^^^Ie˸Knv JC"##ݻݧwUUUoa[mm-=l޼Cq( CW_gϞnˋoxv/B~W_%,,Lv/_Θ1c|x\OYVtQҥ IIIvATTUU1}tSO=ELL >[tߦz'$$W__mvX,Hu]ǐ!Cc޽՝ !}G1qDxgNpg*n縖D5C'ҥK۷g͚5V^pp07p 7\;ޱcvm7&燗W^y%+V @@7L;V7s?Zy.96l!Cx9x W\q{D:u OZM&> L<{v$IGrr2uuum$$4 ^$ Áé/@jc4 oooP@tiө/Om\5m\-2/Æ `ǎL>-@;hqlv;O?[vIII$''3`};K.$$$F ( Y՝I8zn*!!!{a۶mlݺł(lܸ.Zcr7sq-Zn2{|RF$-AAws .jˉ4nJDD>>>UW]Ezzz@oٳYd }!&&M‹&  **++)..A`0`Ϟ=DFFV;[zuuuܹ8:uD=0L0x`HIIk׎7vZ)**ҷ$Iرc 7oh4r7S\\Ν;Z~zvJ||<]taѢEXVvň#]_xrrrx7ݻ7,Kff&9998nJ݉'&&LV\Ijj*@]ϹyG6mD=СCa4IMM%%%vqQoNΝOBUUȹIܚvF !r !5muAAo>V+!!!t:`Oу-[SUUEyy9ݻw'((HDRݻw zf3fȐ!lڴ燯/lܸh:vhlqlK/-[ r-q? ܹ3b˖- 8P4, S /k2k,v;(2p@t?GD?~<<>ѹsgJJJ>e{ÇumTkڜ>3'`|||Z((BkAaaaL&ڵkG=}1C#""Yx1z+#F/k믿fʔ)nZM( AAA䥗^bʔ)k׎{6g̙3;_O?ի;2e ŋy0 nkHѣٽ{7> :uoe},Zٳg#I ncL_|޽{s=$Y"33SnY0zh>Syp}a0k>|8,.{ :Tkee%ӧOB||&o!111S]]kY5myԱcGZ= =L2Auoӽ{w^|E"##yw0`Nn*???n>3&L@\\-"<}h߾=vtrrrW^n-a0شi?>(]v$&&[*Kzz:KUUbGVVՋ ԩ;w>!TCtI.WPP@ll,eee1x`A={`42dFQbˋ 1cOyyԻwo1wi111dggs &''!C4離 %\WgAe֭<)I:u"!!AߚizEEE>|Aݻ7nuQ۷c48p`NUUϏ RRRHHHjgѣVHNEćPZIbD2chA#V^^kЂVj6 Z0Oш?$ah߾}7\#MC=47i/ݦksiExM6}wKk v7w=9iL:\ߏsլAӾ7ILL|Q:U&sTUzMhRnz&Tn}86\y66mɮA`E(rW ~G-tdߵ̃g tT`ױ*驀@Lju(z#iTUݮkpmZ%::c-sksjsVssrK;s֮w9Tz|Z<7J wAmmrŮ$2mXt). r|l6l6?$rIFuowz7THH!!!m;]Nw5L#$ğC=a999l޼ .ݻ}J۷/K,i<"ښh'kf?7:0ydԖy=p~gK'뇶-Mݔn_]s};z?k? MT |8_~9~~~:t˗SPP?cƌaĈf>p_5ݺuc۷3rH3qWӣG$I_eٲeX,nv.3kpZxW9bԩwy[*W欳OZ555e…|rE[omQ( 6l`׏r-[l;p[}d ]Z4:Sv;_|<#TTT0o<=uݹ+T^vsVTTPSS` **IEٶm;<4ͻ9NVyQZZ|,Ktt 555,X__?N o~~|g\xy /j loCeec=z4 ./>㏼+ѽٶ lܸӡC1jϟOmm55|nc 0x`8v &&|}} u+sM8Y? o<ȑ#?~B xyZFr:8Np FQi؊UU4 MJj͍duv$Its԰rC9 ^Yl0'潦OӍz`Cnp]op0~L yf6MJ5ap`01zvLGEfx$uā9k-… Yz5555; UUٶm/;vVO-~u!"%%%̜9IxZ]ik+**.޽{ӳgOV^M}}I=R4f`0]ZZdx{{c٘7o_|^^^vn}Y$g(l۶ СCuq`` ]v;wlSGMfZl,_{f֮> LmKԯ*w林?oOEE8}#"RRRq[sm_|yf$Ib</2|駼딖UMӜk6!9ZQ)..f۶ ÁiL??~gy^{p`:Vͣ\ͤ #yȲ̴i8+ͦ m~fdϞ,X̥M͕%RPPLZQdYi-~dX,}tʬ_~pZ+Sbb:ӳp$?տ! {={SWWҥٻ0 ,wOݻ2w-|ߴ'+d{UUYp)99\2m6sDiiE ǜJ`00y&RUXXr%۷zZ8"jkk!((EQ(--eժU3vb#Gƍ)++#&&f<""JUUNyy9Jyy9Ǐ'88l6}999L8=zڄL"7О1dgy;i>c0HPWWlC@eeHDDd@***Xօb!XTT8sIII9_BCfc;0 5TU I!x{{c6[BEC1(Bee%x=~jjjj1 DD؉X dYja2 j4uPQQf'((@dYNhh0 lݺ뮻R, yWo&&&b :L&!Zm8NjjXt=#F $,,РFUeߟFn DGGpU# f`6[ȲBxx([ P //'Nr!3 A΂ M`h4FyyKEBBlYYv`|q:zgH͎fk,wf+,GuuMV7Pǒ$RVVөHPP": 0=jC_`FŋWa4&88j,kB*Qk6כYp9EҿXlWb46<{ ZoN 0͛7K/QYYI]]~)K,aĉi :6n܈``ĉ',$&&r 70m4~W뮻N*Hđ#G7nu]Gtt4k׮K/T~yv܉?\r%DDDu~|ruLrl6mūMll{2XnF]HvIN˲eXpGh4t* ؓ#Gf„=z8۶f"#x;h>M/瓙\y%7dg)**ˋ{rpՙ+ٳ %x{[oǷ.&55EQ⊋+ػ3f,B.+PPPM}_yN"-(=t|0R©A߾,^ v( F [e͚:E}.ػ7CqctҳgWF޽8p@br]Okؿ?SGs?}^t',,{Q\\FEE5>:A9p;wgz|RnjjjytCAA1}vT8…oZ@nn!&믿/XhJVDPPUpoÇΤ[UҫWz**dg7d>+1ߟ 6z٫Vmp8%~Emm$q}ر#^f0ܹGS7x>àA} f֬1-0iҽ8N>p&x3i:jc̣嗵ĠAׯYYy̛JO2NK/άY?{w QQxsx>~phUWk/cǎσqUUlG'D֭F~~1o ee _ogDD(Ol6;v`XjO=5>}QWg[3On lذk#L_nxq:1cFо} wqK-7t?|;6%k6luuDE⋏Q_oѣ1fHrŃ ~Q.N'Mff6%>_v:f_f۶d/{OkxՉcZ!ƃކ 1q;b6[:u gyrø+:t(VnԸbne?dݺmpX~^™='/^='f4W^y /ƭ>}йslyyE=Cmm=kOb0Hlܸ 7 __FocvΝ6l wu=?С*~-4a[1^;3 1$Fmu넿0qq!88vػ{ڵ/b%q`:iiG@QTVV7>f_FVVǏ瓐l! Xa #y$'De򊨬^F`2ү_Ovv/{B]xر==t;6 F=^DDS@^^>>` 88cRfΜ%nǷр7դfr`:UU @aa >>t$QlH7ѩSBtz22 vV׆ը*tޙt''*,XNvv>a(**eྍ|Эڷd2m[2At)8Nb)((feWqh{IIxtBtt$رp vϸq7n[[,V/@Z1*+k(--GF}ۋ:~,:Ajj&X,6K)..k}[-ZAhhᩧuu [^^F/&TwcxッXd^m4/`(,,&.v@b9Ŋ/KwDF=zt&~#I xwv6l /oouϗ>}ߟJMMɋRRS3޽3zzAjHlN~)/X!$$p1t؞:JΝ֭#V(/"4W3a$$t ++,A[S[[޽ȲС8~<*}}h*+E(*8p oo/.">Iii{wvp8TVVӥK>n:R\\FJJ:!!R]]KǎXp-[c4?sn,\ݻ|aÆ+ΕW^ /!q̝+WQUUߎh$99zez(<z >\kɓ˸⊆HFKc|͓g̙L0oͳ>xgyN3i$fϞ}}2|VHġC0aso>B=-8~Wȑ#ZÇ}4(8.7fΜ9 6LWiw5+4l'@ڵkln:2999%I`h=de4mp5Z^se5'lh綥^+h7&mנHѣGoHLLhr8v8;Fqq1IIITVV{n\Nuu^vUUIIInjlIHMM)++ KJJHNNF֭kcZ$-"+ἲ9HÇINNݻV'h4/$%% F !q館H2n ڏ]vQYYbۧs1m\\\Ç1n Kzz:m/fYsf޽{sJNhF#a_ w}GRRÆ ;a>ǎѣ> Im^[Ib֬YgMhp:,\xl6z+(2j(zlUFyy9~!#GDQ$Ib6[!FE󩬬d…ݻYl޼2dY̙Cvv6 .dΝtܙvqV삂fϞ6Af 4hfٰ͚a~(,_$~SUU_IxUUٲe $I$''e"##7oy$X1eӧSXXHQU.P1{lrrrbΜ9 PU۷S[[ @jjC̜}ϧ$Iz6Uccc{L0a~W1O=7ߨ<۹SLQ׬YsVs&o*Κ5Kܹ AAA9sg}V}'ԙ3g?j՛nIZĉ۷&MRǍ^qz_\uU^oӦM(jPPr-*>#q_}^F599٭,YUөr-jqqdU?eYU^?Tun?n%K ,P###U@]vUW] :TUUU^zKIIQEQTg̘:\in/_\}饗TjnRfj6#M-k̘1СCUY?Vs}+&O|qsQEQT,Xp,裏#FvԨQeK.$|Ĉcƌ7n_l ?8p@Uf9?to 4hk)_m:!`V(XիWzeffozLNN/x7'G~>gkFzzjvsw:+zMϡ\Y2Laaby饗;j+ym:V$z-RSSmJaaa8 t7od@iXu̖-[?wEL&saݺų͆h4?`3UUIMMeӦML2S\߿?3gf᳇f0k׮e׮]u[JKKOf_٢}uM#p3AiӦ}WCEf̘?k ӦM82 pB? @qq1| аxRϱ-(|8Zr^ 0*W38pN6l۷o?a"׼6LyFӧm۶SKqqq&຺:<E-[PXXHVVX_\7U\=wRUU8NkN:M6y9#/$Q9~8Ym6v}( Vä ,Xh4r!JKKh#dYF$]X0ٳrrrؾ};wq D\[n%;;[;z(R__ϼyHKKfQ\\l>B֭[DZctb駟!77t;^yjv6iii(BYY+W':Ν{W̤(B^>݆mܹ'Fݻw兯ikcwh4?h4w^N'7o=E9wN mǁX, Á,'<SۉdSYYIqq.:tlFɢE?~< `0E$L&' oߎngȑm4 `6EQl6ڵkԅ4))$~aΒ${jc~MSK+r|}}QUJvEil9E-(c0(//ǂ?X(h5N?~F#AX.=ژjfnVAIIއ`_TTf***x״=EEEWIZȲLIINFQJKKkWUUQ\\npP\\|Bjsf;iN\a1 iKK|Ҧ }q-֚C70mDQb80,ӣG&MtVXXȴiӚ¤IҷOF͓O> @QQ]vcƌYb;vL4MOezkRWWOjy'KN'۞P]]oqGiMX:i9ѢM5$Is(ӹɛoɒ%K:rnJAAt㳁``ǎ|7g#(??~ֵ9/VЃ0.Ȳ̡CN[uid21w\~Oԍ\9~8ޒ#$h| 7oֳ/QWWwNV,J~~>7n[&D}}=餧7WZSZZ궯 >|M[NVV߿M4 '-lzFBSyy9< ,p8ZD,~:(/l6[4В"0p@ "dddv]vdX $DQRW sOcbbz,g*H4}`` ƍcϞ=8p:99hbbbPUAϧݻk.dž9|0gСӿmưa̱˗/gРA$&&.6`]z.]Jbb":t`')FCm۶&`uCۛrzҥKX,xyy1x`kt (\qt:ٲe eeet֍RA`ȑ$I(z$S9A䩫ٌdh4ǨΝ;kAUU~w]׏^Qu~su$ YkvN'rw؁ :I>|8EEE 2D1Lۭv+Vڵ+۷hUW]uJq@AFhh(QQQ$$$( v]v1`$I2vM||<JQQzٳ_NLL nDFF޽{ +b`Z_2d]vEUUvލdҳR_~DEEgbccDA 772=6Ok}e***7nEFFy>>>7///֭[.88#Gw:rwꫯ&00UU1Gbوc 61cS{^;##]vq5>\@showEΝ m\ǟ$IٳTڵkǨQ܎Yv- ߿?={tmvx.2׷9СCtqX(J(fEQl,}||&IUL&ڵkWe׮]pFyEQbĉp&?ܢ^y]kyGtۋ.QFt:1 ݻx)S[o//Çs뭷ry&N믿\믿UUҥKٸq# /_Α#G0ak֬K/Ճ5ۛdzk׮xm`?ɓG~bÝwɎ;9|pfs3^'OS^^N.] eҤI 2n hx瓐ϥ^ÑeY/ _g̙$&&rWt:cɼFA //It;`2 ڤ -tɤ?/ۚF||<$^zѾ}{NJMM $&& 믿ΨQСC?_~~[5y۶mn̈#t'99I&ѣG6oy 6nܨ{sqWp8_W^3~x7M`^ছnbvnF=w#GZ 6~>cǎ\~ݻXy^x.2֭[7]w݅(|8/2aaa<?~Pٽ{7`0裏rx Eaʔ) 6U& W^y`nv7^y>3L̘1dyvJ}}=&M_… )//gܸqL:wy-fױcGz-Ӊ I///;vɘ1cuaϵls\IKK#!!A.7 ns=mF~PE:`0xHMM%11Q֒KQQ]vu`222/;wt 43,Y~_|TUfq1whdƍ̛7ɓ' Izz:ݻw?bR$^x˗Q9g$F6o̞={xJôo5Сg!!!DEE /:tU!!!@XXo:t耏nz$I"66 )**"66Q l(*d2澒$0i߾.skrEȶmӧ H>x:t 77P][5uTM6Gy///RRRXh}TUUq!Nڵk4|~z~w}j%..NW/Y +Brr2)))\@Cy_Ӯ];dY㣏>"22R^^⥗^]v-Wδi?~<111TWW3|k@%((Ϥvov܉ )hԟhbcchkJxx8@!韻͛+Nkxx>O>gy?7֞[M3w(gڴiL2/h cՄBIJJO4"'KϡS=nϴ&&&X}Ѿ}{}ȲLll,~~~oߞ_~1cϝ">>W^y^z: U>LjҞiӦǠꪫ6nHBB'7o6yyyҽ{wa{gժU\s5n[_DEE=7nD, :)))ܹ6n趈w@ee%k֬qKos6--mİpBq̚59s ,[￟>}aƌ|w΋N-pp"\:ES]E9턶8{O]PQQᅬjp/A jOA())aѢE- 9UUUeݺu8p@JҮ>VUUIHNNfӦM'4w_\ PRRBMM~-,`jADQdҥdee)Ogtٌ䫯mLZy}޼yy7n{=!e˚ܬ9fdd}gZO{8zjV^_t2gΜڷo,˭USm|W?OM硺:,Xu͛VhOU6zu6UU;wrc\у5'$]j݊6h}+I6lpӦYVϟ?̺uNwmZo枵sq{r5Ẃg?\'VXXȔ)SѶId׫g9Fm2y?4_SV+)))L6낀ngmTU%##EQi)55M]nؽ{EEE;{*$I2$I">j?Off&FRRRӧWfŊ[ ??ŲF#WfƌȲ̞={4QAt:O qʔ),\P&aB}g(ӚsСC'xeeek7AtYfcyfs>Cvء]QQɓO XVrrr}v?NNNǎW_Wڢ( n~rMk׮]+++ięn2dO~L / 駟nl6F999zj<555=i漼f'O?&5ju-kidTVVRPPptlX3%%%&K+eS 0NٴwnAKf>t:y饗xA d(OI9Y555gWn/bOٷo @}}=vرcdkZYv-cժUTUUW_rJ|}}Yd ?3\'R^^L^yÞ={iӦ}vjkkٱc_|n[PP@ii)'Ow}TN}}=k׮Ս5wnn^ƺu9s|PxWԗf߾}z~ -V~~>w寧JV:e쒒݋O>aʔ)fOXݴ$,7u]$ϧ~&Dh† EQϏj'35: ֯_Ϝ9seӦM|-b'BC8|) 4,SZZJuuu\7V^;?~d}L,[(嚳֭[;pQ='[\R(۶mcY8vѦXV炦+//?vܓe+Vi222܄?UUYj$77ힵĒ%KN96-C{iJ {n}O3ldb$$$бcG/_~*ҕ|>C$}裏ng >NeeiKY̜9~ ɏ?Hbb[رrl6NצEDD`6lnp[ԓZ{9f̘ bNS7 ҥ 3k,TUշVXAzz: ۓ_~e6l؀/~)ƍoѷgdqBrssսZRBá D{eɒ%9R'-ō1z`EVe>S-ZĊ+9r>n45kְtee%|A-Y݄UV0iBKSEe>C}*Osl|ѩS'>3{1TUpɽ۷~*LPCHܷo[laҥlٲ"$I=, (3- {X6oތb;A3XSS,;t?z}!wf3(pѨ:̞=B&##I&ӹsg=W_}E>} d2c;F޽1=c :vHvGK.\pv$IoaرkNjs=l6dYfܹ 4]-8q"?̠Aԟ~h-[ƻի SNncQ\ WoS=l8#7ǏZ[[׹sgt颫tkpB6,55ٱcG+ēرc9|n>rHPk 4r@RRR $$}d Cee% <???+h4""yyyTWWs{AuuujQQgso5**mgハppo+޽{5LSRRh$88Xhnˋ~J;h f\\Æ s[I1Ǐ4Î1t=Ctޝd eѺ{wk׏\***E!C&S^BBB2d$sS]pdeeða۷)..&//mC٠IKKm,4P= 4$R޽  2}/hhl}}IDATBCCO҄Ӯ];7{ ml1x`F#,sG~ضmÇ'77y&--AsNڵkGNغu+UZz\ILL_aaa֜?( YYY1d֭[GUUՋ[p8W^=z&3rHCXXՋUVF;wBwEלrssZ <(rssپ};#G$22EQظq##GdDFF9c뉏'%%E:t耢(ȲLTTYYYX,jjj0`n^ݻ7yyyTTT:{cǎ /ʌ bbb m۶>Q)))aƍz8v؁l``͚5 8N:[\r% IIIѣG][|!."|||l^뇪w^ 8pL2dfݻws(_F=))^z(l68@`` \uU`0$Iw$AMPvv ﯻ; N0!** ///N'6mk׮XVJKKs:utn# 8Px.pǍ5f#F^r%FK5jЈ#U?#UUU5##C=z~zpCPo6jVUbQ-G?cU$8:3<UW]nٲERW^31cƨƍS?3{Qz-ÇvRwU}u*Fu꣏>FFFŪjUeYV.\W^?^{ՖD}Ι3g_U;S]v˹s窡1W\qjZѣGxE馛NZ_:thܞ@]|i&USoQm׮z 7v]eY]h 111jyyϷx_o^}'ocKC=>CjBB:}tc$IR̙FFF]y/|By_|:ut7CUoVu] ٳհ0W*/V_u_;wj4ՠ u=MȓO>yB0@}_իzmvmq}^ٳg7[#FE{ӧ&MRkjjyWQm}73F { BiR,bUQ ( EKRHH{gf_&e̙^ZkvJJJ";v 5aB!G!֭ks|' !FbZɓO>IÉl&&őYCܹsjڔjs9 :,[Ջu]o% eY_A'{&d2 h;CA W^yb2Hqq1 ??Az-hH^^yL~RWWG |g>,[ѵ[/'O4ˉ^L&$%%D*++i|gW5k5٢̙3O:oĹ87MC̓Xݞ6n]2 CUtbCgAee%PTVV%FjSN6+& ToyuyBcsD:tnپ}u9FJ276i#RC!--^Ǘ_~I OSRw܉W_}A2 11nPr /]ٔCo߾=hb+++qҥ.GFF8C]]]-N9h4"33SHzX2FIIIzi攖tZs!// 0v~4j"00)))HNNRDFFJn1NLLě… 6OQ ^²,.Bw}c=eeeXr%=J'/RSNɓ]"88UԜSDGG#<<?L56fD:=5k`:t(b͚5Xf }YL<sV^O>$͓?#GG?~7nFuݻ.M/Y! 022222229dFFFFFFF/&QwLuu5}A֫W/ hwT*1p@xyyQ׿?cD~$Ѽ 2X,8q"~ϟҠgϞ=KgSA$M|h4zp@z߿?]w Kc@effJ׭[7ȑ#Zgob`Ʀf;z)J!;; (-- zI# `РA6ވ,bђLpss?XR?QQQݻ7XرcQ[[ Je4i, , .\ &:R*z* ???*`ĉ4,"$$cƌA^T*ѽ{w888\wp.`&NHO8qҞ={bСg&LƏ6mZyzzbȑkcǎAƌV?|pe?l0?~<Ξ=UT^ ggV?cĨQ 3߼L:...КҫW/yxw:\C4g ՞3uf9::b΃;F%Ʋ,釬3ƎK ўE]]1f, &-Bjj*XIxb|ZgoaĉlO,^ZƢEsaƢET*1x`B@ȑ#q&NhӇXٳi ;CF-\'O,ϟJ8::"00Ц~ǍG]M&g$887o3N>;S2OϘ3g h4 0*꺏.m`dddddddr_Y! 0222222294jGGGpG-9=RVCTBP@VBh48)⻜$׭V+4 J%J%T*V+ ͏oFcxt RI•J%j5T*5y}W%!1''va6i}9Ŧ6^i BZx㉘L&IcxSp !h44D#ǢnKD#/I?AHlGǬj ߴ|<1h?bw}l$0 ͇x8#fkG29::Ҳ5]K֏J08j ."Mߦ󀣣#sBbXh"Ŀq}ۡ)4 &q`0yd&##5͌ k698NŲZGeY,͛W_=G߄899AVZ'{{{ިd]Q0ݻ7 JJJ$'Jjy.ftޝْt=V OOOz,˂8X,* 6Aqxĉm->'}eYIB"lԃB0XoQpm) *˲`YN uuuvE쟎Jc8pe$QVVjBۃax{{h4eYjXB}XliB ooo^9+T*ʺ/hBibŴ !޽;==yl_kP*pww"ܑ^^^Nnݺi}m!l6tLuf熆xxx@mϞ=QRR^a$㯥GP(((m?|8,((P(ׯjjjP__OOOXV!//X,ZpvvFuu5@>}`28vvvF=PXXH]NCII  <<<`Zѭ[7TVVBR}N_yՕzH{T`aUUUTP*x{{KګP* ??xwqСaÆ=T*KAcYV/yURZVPTdȐ!BTTi&ϗ-[>jT@ӎTjkz F߾}%BLii)"""`20n8 >\f<F?~ sssøqh G>}GLiii www"::Z"5!W\Ajj*0i$۷\ SL ";iGn^<#88UUUXt)s0uT\|eee`Y...=z4 fS絵 ŨQ0p0իW1sL.,"..)S`̘1hhh@\\<|}}1a„V,0$''Kc[!222peT*L:>>>4sEFFbԨQ?~<␔ɓ'8hի&O WWW/"-- a…իu.7ZIW^O~Z*sK@[Ӟ:lzxM5-Y,kt @j~Oyy^=] wTg/Cgk֬ÇK80֤yh1UB@jj*y_K,};ؽ{aX0a|G>|MC444`ӦM(..;L&&N7b̘1Tq.^> 1 xdw%Ė-[T*q-eY={6mBf͚sҥKXn0 M͛7W^xא777@BB`20rH曘2e sQyf*ثsa{=XBsbիƎ"[\v-/_ޢڟ8gy iiiؿ?bbb޽{]vW:͏[zgWOsߚcon>6W{O[iU=n+ꡳך OKU^^PRRBjCd2!++ EEEy999HLLDJJ $Qg,K*qӧ|r/Vٳgk!88QQQY}}=;ӧcС h4"77)))! >>/_Ƽy !!! û ///eYOŞ={#22gϞmq[,ߞ={P(_b̘1طo0i$#44{1nܸvEeYѽ{wlF@@N>͛7#66<F9rǏǸq@}-%%YYYTsF!C0a?~%%%mڟ[oj~a>|{ ۇj?O_ƏB fϞ ___j_~~~~h hTQՁyddd ## @B׷؊ڛ'x9s&NJyСC1aBPPP?ݻ˿vV+ѭ[7O$aaa;v, B-ˑAJlc0ܞ={ja6%& N=ף5aTVVСC4hFA5 Xr%rrr9sHTGQ޽{ၵkBӡgϞe1l0hZzxY{hWk0g!44%%%776`ИL4 uP(pj|[WWҪѧ;qa 2AR?[lJBZZyʔ 蹑r@d6oތÇc׮]$oՊɓ'ĉ_j?P-йsafz{z+.\+V>gvH%_ ((SL֭[%65I:ѷo_L0AR '999Qo֬Yx70g 0 mۆǏ?+W)^82222]"޽{mbBPW^PT`YZUUU1^и}eY᫯‘#G߿h4DGGSaÆ$Rh *XV!44K, ͻ`Q駟?İapĉ.C!ډHTWWܹs8q" BI;;pGOO>O?D1l0$%%!''ݻ7sAh0o<,XYYY8uP[TҀP0(--E`` .\H=uh/>C|'8q"N>Nxzzv8pe&PVVFX<ضm$`̙eY1HNNFtt4T*ߦf~MY ufUUU]ddddnTaL4 ؼy3F޽ ggg|'޽M _~%BBBp]w{˲g}???,^ͭ1}t1۶mZᄏMBP $$wJJJPUUc +A3,]˱yft:8::"??SN( cǎExx8 1dZÃbł9 . 8yyy1zhyP(֭nlٲ?0qdL4  萱20Xt)ۇ~ SLRDll,xTTT/Μ9̞=JЭ[7ddd`ȑh4T×ev b>CRyc֬YpwwۑFHHaÆQjbԩpqq6GK.ř3gsd2aذa1cFykM{סVooo+###wC@v>>>ݻ7S]]<Ϩjyj,r (!Ja4 TUU>bĈn ,1chKbժUpqq7C~0zhL8zL& :G!Z=z4ڭ[71& Xr%͛ת<eѳgOa4`̙?9س & Xr%|||t2>|Æ Ø1c777w} Պb0 ٳgc͚5߿?UUU9r$MF4X,?>|IуUVVBMky pm ASmR{C8lݺcƌe$'˲0`VZӶ믡T*裏ٹUpDEE[bb,wqy~V\\ ̚5B஻l  ZիWcԨQ*,ӧ[n01cz7qD<7nZFvv6~8eddd1~YjjjI!&a,+J8b6 q$EEE())H~ y:XhnY{ۢVMɓ'1uT 4fLZExM6I@4*|TM۫vlo9ydJ{;믿b„ 1bDu._t~'pcժUSR>-[:uTi]۪#{ѾҼ^DP'N8y$:YfJ@FFF8 7F$ަ6!7}-=ۙ-GysxwUB\\\/#%%Eb$|=u-3em#LBrJvmmU4衇x{ڙ:hݲw<712227-R BWQq0z"jga 6 Æ {ވg͚[n$y|rWFFFfDFFFFFFF=5O1#######C`dddddddr_Y! 022222229ۏbCܜp' YKQ*tVX&######50 >łӧ>50m82222227 g=׽IJ, ED;"##f9"EFϠ+4x# ** eddn,f3V^?;+222`"""PUUggSl!BĦ&<<<^uXV+wߡΝChhbY"""p~YELL x `׮]vhZűcZGa cBA]]RSSs,4DEEaŊP( DFFV+^ _'ZA@˧T*q X,$&&֬Y{JYYY O<,yUUUxgnnn?|}}1qD݂ Љ̙3W,"77Ν_o8]Y{M#f"55~a JaPQQ'O"<<pss8`yǁ؎eYdffCI#'%%٨8TUU㈉) '''zǂ L!@P… 0ӧ\]]_EEE8p Ǐ_ ggg,\J 7F}EZZ>zFapqx{{8ӳKǂh>bcYӧJ888h4ÈFCC @.06󈈈ɓR$m'B|\znnn۷om0 ɓ'S!1 ?N:b| y0aPVV &ش0СC|v㣽zX,d2'|%2> 55*]~~~̪Uعs*n߮7o]gΜ5k֬޷zٳgO>}b//zt5/_& Ð̛7z6ld2ٳgwyMٵk={6).. o„ l6BIHH ,˒oё|7W^!s%yGN<HzMf̘AnJ.ry²,ٳgT@VK;x [HXX0a9sZ޽vjOg}tyw@mkג={{{BHUU /2Y|9@V^-y~w!Erh4{צ/XV|rRVV&[oÇ+111nɪU@J%ٻw/y'ȉ'HZZ'NB+bZO<jd׮].yߟEqq1qrr"oVqd„ jٕBz)7};g͚?s!f=sLӧΛ7oWr-ʹs*VZ1MeV8[lAxx8mZܹW\VYY١~UZeqvY^둕%b 4~0ϟ^}7iӦҥK-jT8CXX.+{WCa0Ltīڥfӧ4 SwY0/**B}}=N>Ν;qWWWhTVVaVШ|i>+++<ǎnGUWW^3 zw~JlUs)þSܰ 0ͥ5ʕ+-.<_O{ɡ@tiii(--VErr* |/R[Llܸ=Uj)=Ʉ5k@p,.kee%[Ustk[oEzjbڵHNNFzz:rrrbAnn.Ґ^z?11SLAEE zj@㜹w^3{^xjL.sҙܦs틒@ib`Ϟ=v;~II V CJN:YYYؾ}{󟓓{ qqqHNNn{l6h4b֭#PH~z?!n ~ƶ(f|tQlZ-fCKemJvv6?Qfs~ 15x%wGZv5F8zhuE=z ŋ%ejr0 hN bAXX>lcD*NX7/o)HGBWT{N;( Q ٌzlٲCuݑ5=sL0  ߓ 3`بc2p?t:lذCNVFj999x"AMMM!oZPP~} tl6رcm~%ɓ߂ P=o]:N!ԁ^x">sɵZI… bP-IGhhhhqmhhMNVU`U曨Vdd[HMMŗ_~b:푴k.H[nhEةwDy]]] kHkkk[Lc96mBiiiB8D0 =$Z8z &~8(((c?+$s< ôKhQoTeWaZʽ֭\BЪ/v VYYBɵ*]`Y騩6j/BX,HMMk.VD矗ƾ}`X@UM~V_~ϟ^~eD0pXB8J ͂_Kpł8(55ծ7|}qIB|6磌Cvv䚨HOO;#NM ھirA+W:=/\reY_eeem;aPZZ#44;H/>>XXn lF<EEEph fjˤ鐑asB3gڌTUUt>>ƍ0 5ꫯЫW/BP]]/bÆ ܹs_~8D CDt1-\ $''ё-//&ޱcZ4Fヒ@уNW#(( IIIx70  쌔W&** o6=/+&& ŋ͛7Cр8X+WC=|pssQiiiظq#!:v&M={b`Ν(//d”)S@ӧ1l0 0"((K.j똘DGGy Lep2d!(..Frr2]J%RRR0du5h ^2_rMD9uTI"33ؼy5 <==%`zh4(--Edd$^}U?#G`֭۷/Z-1zhر?0 ,Ə888Gtt4^z%5j233 >=z]]]1e8s m^/5kf̘ɄH@GEvǎ? awwwL4 zaȑPؽ{7cBB|rЭ8p0x` >j{ży0}t}PWWqơW^`...D@@V+8g};#*,, ׯGEEn P4hF ùs;ĉ6uC@]]]a0a3Z pwwRĨQpYL84h ?裏}d·~ݻ# 999mjXѣqYx{{Cl:ӧO* +ѿL4 jǴi`XP(#G8p T6/^ɓqJ%:Fo ?Duu5yyTUUaX,[nʕ+FpRSSl2|x饗&/ ƌ`0 $$pppиl߾SLq`Za;ROOODGGS7??trrB@@, L&$=BV*:xqw@f;XEa,+p8UjGo7˲o1Bi=/CV  ۷/[j0R06 jtݘhZtYYY4)Syݻvm EXX^}Uա>>>01bD,\"x-`„ U0p@{KpQF|G_ܹ6ږ1cظTTTСCbռiZ??3""", 0sE]]{=,Y6l+qaÆ/^Į]dBȑ# ÷~K|t=z4, #&M€矃'ND=z4ϟ:l߾/'|a0tP̟?z?3>uBjj*^u*ӧqԩSF߾}P(P^^ooo`Ȑ!?~<4i,Xعs'ԐwXp!裏W^y?>ܒáCc67/lٳg8]hj5qYXdӧOGqq1\]]1o<>} E=h ,\?3-ZDLCVGȑ#%)xqAq_0{l*Fr Ǝ  .3oSb̙>ܹsXf OHGnnn1biWQQ"XV,\QQQP*?><<VWW$''KhDzzz:=B!((oӧa4q-:8{,<JEo^O;w~)h!_mm-t:X`0@RWbq`ƍ6ϋF-}}=zz q`塶VRAAA|Y()X61=+Wʕ+8,~`Æ vm":h8moO"7q Bnn.8C}}Ď >|uuu>yd\=]vޮoA~駟:©Sp!444~D9 G}D Z-N:e_p(l6K4_J'OÇQRR͛7KZO]FMP ""iii(**BPP!8t-E|r쳚ߍjN8[oUb-[Hݾ};bbbߕظq'b2p!F"<СCTW__.]Bp6IǎCDDDߓ"?n;99hci#hZ"te˖.1jhNZ->I駟0&5=v[=|z]{+77?85eSNI{L&6o ł-[HT gϞEll,8@C~~>}^N͛]Y#Ǯ0T(صk@( ?ZV7^XXR f6ciޛz 6/b8~QXNJJB~~>N< ł֭(HEGG؆ tiPш_~Gh{扦ᅲԓhľ}$Sll,VXAՊ}ѾZ[[ 6H,F[u8..wᅬO?GQPPǏ[ennnjU8ApuIIII6'##ts8"##BFlv|ewX,:6ncGȠSTZ<#11V !!%%%XYȐL咺gFUbZj~6Dמ}jE]r& Jȑ#L&FFyyy())QZZF4huuuHHH˲0 tRdffBP s,";;hhh/;;[҇{7]/!''z*}oJJ 6mdPٸriiiFaad*l %%%m0L6lЪZSSq ݋#G୷pͳg⧟~Ш޽{7y6SNסAvxy/Yqݠz=Ξ=={tH#GZ"n;o{qtKd2᭷O?ӧO#;;۶m5ҦYxǗ_~iӦh a`x|ZX~ֶmۺDubb"o_v4*lffd{-fŲ, m6:NJqx:=6xmƠb%YEPPp9 #4MC~uV[r_^2w^I?ܸq#=%lق_x{{:t(<<<3f@Vl6DE޽Q^^'ނbY3f@AANa`Z L:5550LB}}=t:T(ˋFtqqwߍ$%%_~;w.=̙3[ ^Yf!&&KQPT6mBCC(zɢ4_<==1dɄ?e%4R? &`Ĉ8t6OoȑÇ[[nAxx8f31bɶIQո!7o,bɈĉ1fBMD>}pB,|||vZ899aڵPZZW^yǏGBB***0vX+puuիfFddd֭CϞ=1p@a̙xpyڵ 1b!Ø1c(XVDEEF1cwww<(++CRR W_}V{ř3gd@cԨQHLLZe˖!<< 0W 0Ǵi$LžgϞX`D7oN8Awwwqb̙XbΜ9C___L>W_}.\hSYlbcca6`#0 #/W;,@;o<@=czsRMɦM4.0Xr%ۇ2ddd`͚5/QTTGyjjǏǴiӰn:XV|HIIwߍDli8116!+ZMmP D^^Looof\r^^^:t(04h 0 |||RTWWc񨨨AЧOqz\]]1l08::8աGN<==777444W^'&OLRJC J={^1w___NqNB>}BP àO>8s !(--űcSpAЭ[784vv/C2󨋋 ˶w:BX,|ԕ8ٳ? q_NɓAŎ;) RfjTYڗDFFɓP(v19i5bKBhIMM0 sݮ,-1eKQ:;v!wl6c2=yujkk #*9v9ÿ+BCC~ | JJJVeeeؾ}ĸXr%=m׮]6ԩSo!$$ΝCyy9vAh荶`NA=|/ NCBB0x`l\\ CݺEoł?T#²,RSSv׍&( zvHmmꫯ}׬Yc .=VRRBCtM%Y^^nוƀ à/r3c6SξW\sšLlٳGrBԚ]x8pqq1BVV=8ݻ7oCv Ǐ?A {9j#a(++CJJ juϠrh2h`0l$\!F%jw%{[Ř WEllqt8 Alڲ Y:e ZRRҦkiKgh_xGJJuպ),,ݾյxzkbf^wBHdibL&jc2P\\ A"8]M|7w1p[QQJْZ-`XPVVw-//C\AœhZAPQQXhZ6--Fuͅhۄ366Fn:GJuu5 uuu(**\d2!...]¥KbK2ҥKDzz:Aš sZ JUvB Z4{!0L$55UNBlz+Vh 4裏J~뮻0f V\ eUVu| ϟ JK=^|'prr0x'eVZGᄏ=>{4ht |Iu۶mppp|Uygg/äIhѢ?b xyyaΜ9>}>}_qXjjv<gϞ9s&fΜ={'|A|Wxpboٲek>ޕJ%lق+V8! .ĺucƌΝ;1tP9K.ų>u}Qnɓѯ_?<6ٳ'oߎYfkxW*{}vl߾/iK燁b4MZP`ƍرcv؁M6aرcv܉;wGѿW^;۷o}۱c]wx!@B5OXFFFFFFS\S0tʍ8 IFFFFFF榄)eHaȵBu!N[a ÀeYL^ڴ_vBD-L!a:.j& l6#::]165%33Ũ<#**U褤$8qfDGG_WƿwiK58- 9qantl6ĉHJJw&$$GȴQ._ ^l:A@tt]=h\!Μ9XTWWt쏿y={f}=%!pTVVBT"%%& F#233QSSZga544ѣZq @#M&b 11<۝A@`` u~~>;&***©SЭ[7p(ĉtj(**±cǠT*<=kQhokS8/eHI&}f+eeeFZϧq`w%80۝=!ku!.))Arr$;pEqqqaiKgh_xGrrrk^֦nV1:hb6QUUe#F-Ɓ۬=WXXb8@B׃8I2$%%I05;!(,,>ւydeeIVt:( eYzeAAf3*++`7~XD8A@ii)=s-VQQQzzr4Ř7bXrTWWի^APWWd8;;eY梬 tCBBJ%#"<R ZCXB-Z.O<ϓ&G{zzbɒ%O)뮻$5k 4s=`Y{܍ťUۀ]g VOƞ7o֮] 0 ロݬj{ソKj___̙3-X{nд888`ڵ4hgY`֬Y#9}fdҥ֭۟ #GqnK,&MqI~ѣu8smt</^ OOOXh.\_~K.ܹsѻwo >\Rٳg㥗^7wBg}K,q6Ø1c0m4<7c߿?YfF." FBϞ=`zzz^?&wBsbݺuXnn#<ӧcݻ7n6( _SO=_~z9r$^x_|A̜9֭9r$^{5kx'$5պ>@ӧ1b >Dpss.ZF{Frr2mke1g V__tSZ1ٸqV,Q]]ѣGf\r'O˲ D~=T*Y `R*V;99`rCILP(`Z'bܸqL^^P(XPB?>S^^ձj!01& 1NNN8Yx|tTxQD///ۛ={3h ̜9`***XZ B 8::2FXddddddd0 F#z=qppj%& ނ !YYY@ ;k 8z+뙚F֑,######CcҰ, GGGGGGLNxK]vsm?aY0 0͌yy888UTteok4vJX^U 4aѧOvXT2roBţ, QiMGWH6P>|xx'######Dd2iJE"Zddddddduۘ*ߛit(%tEXtdate:create2020-05-10T10:39:39+02:00V %tEXtdate:modify2020-05-10T10:39:39+02:00 IENDB`qnetload-1.3.6/docs/images/qnetload.png000066400000000000000000001701731451037126700200610ustar00rootroot00000000000000PNG  IHDR0=gAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME ''bJIDATxw|?I-BeuD"_DTAd/Al2:{=n{{g|VAB!7999s0p=722222222׋,P7ҥ @HD2222222#AYY2:LqqqJBF緔-hDUUazSYQV!o/s2(BEBlWYY:WFFFFF_qww90 aY,膷hڣa,ĘL&aX,݆22222221l6NB8Zfj5#(**bpH7aFaQ0 #ۿ dVKXJŒ3 999 bnDaF???ct:C#, cXlsZfT*nO? d#T*(JT*I]]1 C,((###bWa ]=V'`YFQdY,K (baaum'Uan)**b !, ByaeYaFEeYGӔ gД$a EQ$eYa^R&xzzbTT!-^H2jX,ܵkU,*!!caA 2z಑k3 C$ `F HX, 0fj///g!ӪwRkZ&88lmm-ò,k0%!D)Dz,Ka% !uİ,=0qm; 0Hh@keYb!Y52 c!XT*o6lے(*Q5(:3)##a2**㔢(*EQA`DV VqÍHG.]2 FFR1fQ( i+IifO.C͘!##Ao @uuu0LRRF#z~d䚍 @yM`axgT*c2h4ߟ' z#f0LLEE 8/ ð׌s9*xX0 m Pb̰&B!/(( * ŤI#`֭8uTyÜ9spq޽4ovȴQ%aakgg\˛Zr 'O&ﷹG#Fru&PnaRYKL?EZEN 7 1`$Ke Mݚ1ϑ~S*x+V 8N=+SE, (J:=1B$yB `&" l ;)tk@a8ca% PrP5 m@d< ##s3ի^( $&&bСѿ̘1pss"""A憻 {8wΟ?{zBٳqD899;aPt:L2~;PWW3g 66(ba2PVVF) 022 0, CתjT*@RAѠfZ󖕄Xr&5]mVEQ*4B`, M '",/$k#F)Q&(~edBdz>@$''c„ ۷/nnn2d@t(//SO=#..x0 Z-s)//GEEVeY̘1ӧOGNNAc=gggl߾jƠAн{whZ矇RRRRI9Lq^{5tsdd$֯_/uk1uTL<7oFPPe˖Fj5fET2<Ӝ&ؚ&다$kE& fσ!ƒk[H߯axbt z… bРAXh, f3, xGtt4{?~< pwwGqF 6 XnRSS#sqqAP]]/+Vp1o jkkѻwo@R{8p֮])S7ހ 222- l+4 fs(HIIq0{lBV bsb}0` 4ǁy# Kc,O>ADDQaggAh4h4ObСt<<<ꫯ"..TafYc|=m`$$)*TaTUU!++ (bHKKjQPPT0 p //^ggϞ0jGRRL&~g>}yyyACddqwW(-n[hC6[ftt4.\R8DGGCP4֞H17Ix$-YE)$0t " a료Ma "" M/@_ ^TTy a(J(UJT`\z8Cl:rsuu5еkW0 AJii)jjj899Aj6+_<ֹz2JSr{¦֒٠ R&ii]u9Ib;hBэ0 Z-;AR cǎGaa!~̙3&KHHի'矇Geedd`|2PYY̙3pwwdz>c6XEaa!~WĀ;O?4˗#!!zf+##ӘZ3':\Od0`%0,pr€>=UuEj4-աSNE:f( R A`0aXhO,ˢ_|Ν;ZMݻc…ݻw &&OO@ł7bΝycǎa:ر֭SO=g}iTxOMy8p۶mqxgp]waڵ @ee%wg}ÇoVy7o֭[3{?p̛7Xn 0x`  6hj~9FZJeB 4 u.]ŋϷiiOSRAR;:ߥqf6lի{n|wjm "##h"W^ř3g "J%h4^ҳJmEz) ˲ؾ};~GBRh]Y7)= Inшsիx"233i/qAt:ؾ}{f ==gϞEJJ bcca2W۱j*@RR-[f0˗:/шDhZvvv7222/(EAQ 8c4J"oJcF %"h+"UUUldJ%DQJs2R"Q'''8;;#''PpqqqPT6k0P8w.]*T*\-]0 :w^z!--Fh/,"-- =իWa0 WWWh45죏>Bvv6RRRG!>>\t P Œ%K|-"Ǐ#77'N@LL PPP/زe VXq]^˄zh47 L޽䄌 zTg pƍ7n B;׎;} ؔqǏ#-- ;!81m4< (//Gzz:ЫW/<6mڄsax*W/|hD-[= N .>~ .i4QQQ www8;;bj%󁶌 ,^E#;; ƍ^ǎ;p8;;gΜʕ+ѹs뛜?[eY!22/-Zd(Xz59KmCAzz:н{wZ{Fmm-QPPxzz&nݺd2'lrC# Q...^g ٻ\S1M_ٳ'JKKqA9s3f̀dB^Zo߾Xl4 o"<<{/X~m/@ff&`XPSS (M[L0?88pyX``L<3f?3g8B0dX3gpweYp|w^; W^yزe ~ 'No#F`طo~a֭CAA-Zd#z:ڪԵ ߃^(HIIɓ'!|W"-- 6Z:8q뮻~,P(#,, ,22Ҙ7 Z06`a47 !- L& K.]`ggN:rssTUUo2~z-[3g޽{G~ʕ+rJ|۷/4 A<P*ؽ{7֮]5[5شi5 9RD=PVVd:t,bժU}6/%%[nEQQMf)Mb̘1֭J%\]]BAf`2Ʉ7b[\ܹ3FbtԉLQѩS'PհoBмѿ'ZƋ/jP2l̙3p$$$`ȑE#FG}nͦj<@TTߏ}<<<{A022n6T([,L(E~ )T닞={saP^^"tP[[ OOO:88PͶ^GXXN:V*VwDGGk׮^ٳg>}O>233;`ǎxlpa0l0p-[0h ̜9111 ŤIZ5`FZT,^R{n=\[CHݻw#={Dtt4f38s4Xz5bcc[ooMt߆z s~W,˶9`˲|\x:Ȳ,uoQ^^7|jo&UZwiJT2${7ѳgOZw8q6xd]6˲T@qqqj5n>|NNNpttFwu5~?P!bԩSҥKqUL:T B`` R+.mۆ_;wF@@83vBt222m@1 oyk`60JNNN(--FAVVDQ34F+U[rۖjApe|75j^~e\pW,k1Rf?nEGG#..1={DnݐF=JEQ` $Ƞv:R`20vXL0O:4h:w0tK8dff?3?Q)))HLLhDAAN<^z! ={Į]`41cޞ:.\Oп<#77gϞE>}___ȑ#HJJb3zۇ~ 3fka3gΠo߾CBBT*xt8<#k_dd"!EεX,8ޭlEɁ#2^VRK.h4 y 7\wOOOضmQQQ>}Ņz"uuu>|8q(,,DXX:uݻCT6;ĝwމ0 <#x'SO!-- ѣ!CЏoШ vލG}cƌ/+,Xggg+ݷa9(=-Z sxLΝ;ݻwǬYhz{{cʔ)?p1Cx{{/隐l<~G<ڵ+vOO&h4˲8:: _~%JJJ,7x5U!ӦMCxx8֭[a`ĉTc~yL&Gw"ѱ~*DQAAAM e L`wȐ!fX899f3 T,˪ !,:fߔx_}DQVťKݻʕ+Jyy9^ZcԨQ0 r jjjеkW +W`41p@ʕ+0`a6\xyy_~6ϭ :dddtAAAtK<`0[nQ]]+W`0k׮B@@JDGG#00=zhIu:^J}G GGGTVV")) Pҥ ipB4PMM bccT* R3F\x6뇀z\zUUU@^yÐ!CBLGQAAP %%h4ݻ7U*>}a")) UUUN:!((vvvjHMMEyy9Xuݨed|)47|]4()D>?PP 0n0 ?&}aR4qOpttrssQPPL&BZ 777vmEvv6:u||=x`8;wIj)ސ!C닜@9˨J¸qV?UDDuFy8[ntk򊋋aпx{{CfNNN WEJǣ[n0HNN ۷/0o<AAA+bQ,EQ4 `U*P[[+T*ҫW/1**H@ 0ҾB'am!"U Z y„tiOQZ,,7åԨ Xc]_Ala]_Z T36l~ReM*>Ԧ 3HVRȺ Z]Zj㆙˥kjﶥvb"]GPz8\Jx"h.'5cV ?$&8b4\Ry*J8::8L&qzi꡹ .YeF6MR=ΟmnkK[ʳZOva>Z뉵K}g,7((kL 0̑bԂڜ /Lk%F[߆mTMKKuֵ򮧜w\o}~2OAF9qs:cz`Y*dzJ^NJmIDVllFۣSNm:mTԜ\y홻m 9F֞!`I"##!X{ٳ'Nnrl[b\_Lɗ4HZ]֦crHю{QXX{>>>6[2Hж.mGLdunbÆ HJJ2KBa8NK[`mBh-=چkK}I-=ƴDvhRk,_m'xXaKj?1붵=U||֢gϞ _b00DDDGy>Ihh;vÇi шcΝ43<=XE~~>"""R`0P^^ɓ'7qA8::'O~5رcRRR0b߿[n7!زe ;;;9riBEa5gKI b8p`b`޽Pׯ&"8o^^^xc͚5(++C@@̙jaχ ?PXX#==۶mF?M R#F@vv66mڄ#88{˲ҥ N:'Obʕ>|8u!ݲe T*zv[a J԰WFFF-FHO8hF*ݻqyݻǏIhZ]V#F p `'ZxǤIp!|HKKR=%hʔ)֭G֭[qA4,<`Ĉڵ+hs=Oߦl6CTT.\@Iӱc;v sANNΞ=$Ґ GGG?ɓshdee?Mݻwc8s #G=9fСC1k,899Q)!!탛6̠A|r;MEXh?? QUU^z᫯ӧvZ4-wR ٌ$\|vvv]- f̘#G`Ÿ|2 "zٳg_poN]SFFKi`d;wıcPSS?~;w .DQ[[KS`YX~=8/Lg˲8rO/P@hooBAg5"QĨ(TWWcҤIP(={ fgO?ݤq^z.H* wqrrrhжRVa2pUBpwavvv4 TKHQj5<ݻ7 \ %LO)ѯ_?d.!! .Dff&舕+Wӧ?W_}Mu8 FsQf ޽{ԮR~#Gd2 ,;whyPH9zꅈnkUTr#m!pj5}Q222t#"ݱh"?ldÆ Ä "$$w7ߡT*O4MSeYcΝC5!4ɕc޽iӦjĪT*qQL82e ƎK=Ʉ={`Ȑ!۷/!(,,DHH_Z\ !Euu5zm|F2%NDDƌ]I6;{EN0nܸVӣ١[n mFI|Pը+BS3 LDGGc޼y=FEE!%%*NDxtvv?BCCQUUuݩAHHb ܹ7bTWW{pqqLmJKK1sL$''[nxT*[8C=pYj 2FV*صknf̘aÆ(",, yr122n:3FJJ°aп8;;Ӊ[}GղDQӧQq9<8lӫWFXX͛^^^F>}dL<Ԧ {Fhh(V\˗/ѱٯDjhڬjK㑞SlTVV/DNN,XnݺEC޽1tFҫW/1nnnyxÇ`GpppӨ PUUu]ds{n( dff"%%uuuNNҶf/^X:] @ee%\Ҫ!"|}}1` >-~ԩѳgO>e~Lm"##zXDN ÁK7?>z- Fvv6y|0ظq# mۆ[⥗^?b ~_~ @bȑ#޽; @;u{χbewх!bi[RYTf 9B5I0wywuWsQ1x`,_w_^~eY/"##vMII N:I&ˋ9r$>3̘1?>N8aSɨ-a ٳx*/4ٙud׶pBرwy'֬Yb[lܸ~~~Xz5 CکS'xm<AĉO?aٲe(//Ça0ooo|8%ޣFBΝ^YY|bba?~ `ԩ6AѵkWk3gX˗m<Ҥ-%kXlOOOCEErrr4[uuu 6yXţ> X,v_ga60 Xh?`޽x7mCYB7|tRI@8::ɓ4#G@#<+W8)J?~wy'jjj`ooСC4˲ˑ ZR<T:w/bذa>gƩS< pq|x0 qqL4&cǎ 4 t8rJJJfj$=w\-ޗn`/ҥKQ[[}"888z(&OL=Фw+V@PfԖڰYYY2dJj+dP(cj* 9VZBƏ˖-q]?NXEaa!.\GGG<ٳgxb13g%h-JǃRPhZҾobѥK@AAiqhl{0___̘1fnݺAP777+t^upfNI EXp!n6w ooo-[scCѠO>9r$JKK3fLJ~HNN`/&L#ԩSxg`gg{{{<#1b- L {A1h *BгgO{0aM|#F٧Yȑ#[\W_}]v pvvO? ///t -ruuѻwo߿6mMkBy桠 ào߾3f V,Xn9kcN=DQĴiЫW/&L`&jcӧO>Xl AA@@F ?~)ˡP(лwo5u];w3g87 ӦMCUUtyQ{;;;Æ cj8F}`ggJ##O8̟?GnPPJHE-˲zQM xJ%֊*K"qqq>WYfh*eKKséƧ)!zBI&f647Ҧ S7|7MQB^S7nO__V=yT*|Mٹ ۣTmͥog]7i$7ǥ`Y* x& :u3C`g}˗/j\.]«Rz#''i"F;wHMMEii)bcc\h%%%HNNnӹzkƷ~ .PlݺG{_X5&&7:2- 0V|ٯ4RUVɓ iVkc&UfZoӞ/_FbbZFmm-8BVeƖ-[6&===gOBlR]]j樭E]]]?ÿ㐐1cɓ7:2- 0Vl߾77LJJ x4(b`ݺu7oތ j!^[[M6۶m^o$ԄȞj7Hnn.^|Ee _o'8رc6\eY]˗/q?(WsHnѭMܨAEEbcc6_lM!E-++Cjj*l P(f 8ddd`ݺu n̂ 33EEEX,DII QUU8;;g=rՔHTWW#::ˑ8<._rw\ZZ80 PH& !zMDZ6m- 㐘8dggŋmRDnn.QYYh[ R4Q\\˗/d2l$%%t:PUU@OOff&.^H3'&&BTT*QXXd񒚚6^Ow$999x"XSRyHڲFJ999 BM6!::Fj4IH@ff& ##Cn?PQQ`8CVV6lpK,7عs'`2裏eYL0NJNNFEEV\ ϟgo,TUUaΝx"AlFxx8!***PZZ͛7#'';wDdd$M.7nRy@ݻLkRRRaիWq)z(8tE=y$ƌI`RKB"""PQQ|,p8DDDesI!8s AիQTTBPXXBrlܸ͛P(Q[[ ԽҥKJ[Zt>~VߋbANNl)))IIKKÑ#Glʓ``͛lK.APoqQpMg ==FXneYdeeuH0;)3df֬YIcǎUN>]=yd1c87s„ ~ƍ5a„acƌ3^#gjkky?Od͚5z[6.X8qf?ٰaѣ@\\\͛oMfϞM֯_Ox b6C=DF#y7 !̝;L>L:ŴiӚ,̙3eYBrrr!<#yWyk֬@J% y#ݔqqqai&zL"brJ <-w^0 ٱc&HHH}ڴi6}nĈB|Aү_?|eYvZzx~!hѢ6YՒzz{Wi=W\I9sL}hH/ኊ ۃ*X,TVVl6C6kn:Qo9aem򲈢:( TTT@V{IJ#>L+Vo.04 !ĦJc)L5 z#bf^S(MwIS\\x8X*--qjJkjjldDQDYY-%%%4QIIIjZ0P((++kӖMU(LXkRI moYXX`q`A@߾}1wܛ7LQQVZd.777̝;YYYtdĉ3g&Mɓ5ƅ ʕ+;wV x뭷 Nٳg_sTVV⧟~j4!jL>.]BEE |6l:b~&M? ZYfaǎػw/`;w.֮]Hϲ,~i <@җ_~cBARa޼yM!K.kOOϿָx"~a8<߿{Mȑ#ży-$ᅦbދcǎAY]]G\[oRI˦N^x#GGK]Z"** uuu3gDQD||<Ǝݻwslkf͂'ϟG؞,?|:44VFY5*),,ĩSн{fɄ0{ؼy3^<#7H߮{Z7M ;e#33þKKKrCcYyyyjW}$?;WϟMs鈢[vkի'_AFFF.U[.¿WJ[n_]4e˖2S* u$ω[p:S[[/ B(NBbb G\fMZߞU׿ԶL 裏%Tl+Z|Id#ӒV]]}$׷Z7_Ҝ"!"vt~TxDze˰w^L4 YYY7tgϢC†Q(p֭[סA:MyAH2/d&"nXui6URa˖-?ǼyZu#<@Ի7'0 ԿMP(e$''Cݔ/CA#]HMMe$'ODYYY۾ 11M[NF-c6q6SPO>iIRRR ̟? b8:tҎ}q6ۣ\OFzaٲe7oIa믿F^^^#F xv]ͥ<9ٳg;+P/wժ__D/^z%jՑuhϽlقmrfW\Addd4c:~i>O3(8&ͶGJ2d4l63NNNl 8˲jQYuX,?tׯ_RYB]EQlWG"77ߝ1}t1d:..:u/!`(//G>}ѣG0|2F 4ΝèQhCaذa .& f3A08pХKlW^ ¥KЩS'bڴiaɓݺu(0͈q4M{ ^^^ f=z4bcca41eҥKr}燋/ SN`h^zT*zʔ)All, a0 P^^NciFtttaP dJIIALL 8;;Bǀ4.222`2еkW\|FjyyyaɴJ}aiii½K˾@Se4նQQQѣ<<<͖8HJJBΝ1asBBB@ mf3O9f&;;.rssꫯ0 ÓO> .9zhf#==(**Byy9 =zoMobΜ9֭!@EEzI's"88=ݺuW_;ѣ!A/m۶K.{.hR*Ba^{ W\'|Q`5E K,+qXdMT*]qqq?>zꅺ:̝;/J%v܉ L>+Vn|޽;/_T aq, j56mڄHL<3f̠žg-Xnݺ B( {x0p@q[\\ ł.]@P?FRR@mm-P\\^z0iiiOaoo=zP*55:uz 4J%݋ӧO?#!0LD>}T*[wߥ<#55}bRu$a…8tP.{{{t/{tF1n˷Q(ХK8::cnnnP򲉍ggg]t*Z7770 899vvvҥ 쨭uNNN8~~~pqqxzz~~~`Y>˲h+FRݽmq<<>> iMdd$&'"J%#:u_| DN;885ԩSӓNWjW*t\KV OOO8::bժUX`~W;:u <<3}PsQ{6[_aaa(--%ggguR 777|Dk@UUN8a^> /@mrrΝ;oкbÆ ؼy3<^z  aڵشiS? )i{E ~tFت{/]PYY F.n[p àvjVٺu+^J]]]or JʗށuBhp89s@SźرH`СC4uP2eqdeeє %%%~<֬YCmL$5֭[uaaax%~i,l\>IW?Fb7PW*iyeeeիiɤ.\Hst:̛7I#^Ozsssxbڶ=OMM }'ͽ9??Iy̛7F0j h3ƛCkTUUɍ"jfJKK[Lz+q 0 Mi %3vy-/E.!{YԴ+lƇ~Ʉ~.]jt0ӧL:F`֭8z(f9rػw/{{{9ro&***bd"66F m0j*?p~gj[XX2_|$TWW7]]BBBˣ0L iAɦbɒ%mjD\tm &&tQ9zudR/ ,^GEEE#UhIAh2:q|2~!BN:ei~,kۇC">7ΤPP(pIl޼8s ~fcHS!?!!-2hf[EE7;&~}_|qqqtLT 6 Zɸ8?~Nxҗŋq)~ӱn:$ѯ{ͥ D/^޽{1~xNi`EVصk>q#8qht/iWUU믿nr.F:z(4 a‹ Xr%(\M&V\b믿B, /˸۩3 x%DDD@qq18f,vZz`ŋQSS???`0`ӦM4555W^EJJ   Yř3gǎ4^!;Կjkk3:t 11SLƍQXXHKvl:zj4m0PWWoO><(EDxkNuuuCVZwz=X&bjT*ƍQTTNF4̝;}zAxY T*.\Lߟkע{ܹ3ꫯgϞ:t(f38úup]wsT믿gd زe ^zx7AZƾ}0l0x{{~ ̄SN8x ;v  b鐰rӳkPPݳDvv6 L χ'U{{yyÃfWիU;88PkpBaYIIIptt'.\bk㮻Bbb"F?~>>6_~vvvY- Tnݺŋ6תT*J}~Z"--.@;nuu5;l0DGG>ߵkW5Kj̘1F~~>zc1c 55Gw}A\\***'R8p PYY e8n 8׭:t(`ggQFϣ[n2dJJJˆ#h6hggg$''f,6 PHO>6o 88.]SNHKΝ;lGKcÇR l0p@;wGF^^iԩ1l0DFFs ٳg!"j5mYDj5'OPP "`^^^ׯΞ= {{{06'ƏXxxxѣGQ|=PYYI]%g<F >>>>1~xx{{CEƏx{{]xpx*@.] "A`0PSS#))G~~>*++[?=<}zcƌq7n ƍk„ ƌsgάYb!fǓHb6` uuu&h4@L&]c67|k_~!g&:x"__M!$--L8nYV^MLvۛl޼>HmF'|___.lB9SN%FL8N y衇ZW_}EFlyl r!r²u̓>H:wLxb6 d׮]%o_ٳgs~r2sL2sLҭ[7zjs8#7o&wM/^~cǎ%+VhN?01byGZ|v777OaƍyɴiرcҥK#ٲe Q*ŅرvdžOo>2gΜF9x`W_׏<㤼Ȓ%K!ݻ|Ο !Hx' 9w1d2K.^z̛7={$$$9r[SSuso_0 pY;wK[ $j6響vkR͛QZZJϗRT4@Ti\KHmhT*QXX}Aswdjڦ,M-Wa9I:G96IKuRlƾjj霎Xuaj[A!:t(bccQ\\hСC3g6l؀#Gxw^ܱchXuIE'p̞=% xlnb5ڬL&TWWSUŋ>,^{5s׬YӧOiuiQK=<{%+..… [SݰLV[o5meY={v"'-^gX:ģeYO>ir͙3uuu~Дyh4"%%YCq)%KZͿe2h4v 0* ļy`4mBGDDPIO!11ѦaEQ ֍(e{$_QQѨT*֬Y`Xܢ@xxxn;EVV>cڦlvvvrZ*sz;'i˲tDo4f%!!l !4Wњjaa!0jNЊWUUbז6PeYEEES4 KG!fy2==քOaz9,]ݍAUUΟ?RsB6n܈~]me0;Pd2hZSQQQv-wш&ETÞ={Z-KޣѬ1tP>|ITE[HMMm;w'NU:4[z7ٸq#222R{nDDDP j]ǪUzU(8uTQ*B5kbq^={-Wn sks#HTbϞ=HIIjjjO?QBѣGozj믿o}EQp&u4ȕ8a׮]gϞ늇%m۶5u?ul)J **w#55xCmem^# t~CUU;xX,Xv-N:SNA ** t[HJ",qQXXh(< ۣ9[u`Yعsgc6Q^^ .Ut:9s*//G\\a6H% 56_j3gh4 Fll#B#kPWWf_~iii)!%%%j4^NCuu-I] [FE^xlj'Z\0! "ͽB ib9#?DQDYY._4pV&-pddApp{m4;o^IDATnHEo3DQQuk$mun=%MHHrrrޢP?N<$$&&BT"--F%o )NLLMӧO7|JZz(,ˢgϞ>ʍZ QՌ ,,˲0 Ba(NflJW_} ooo@Tȑ#tk_5t:|}}qQ|wHOO7ȩcF }U૯3Ξ= P_{\t zo fu$q%-!&<Μ9ÇˋEOիWqYPPL999-wW^ju#78!::"gggTWWSUvhbP')Q^|||ezyy!55=sΦ7#4 ~mHmyˣ R¿BBիHMMm2gA777dffbƍEHLLDdd$RRRKR111 CBBl58y$mò2])))4+ŋ eXDDDvvvCFFFpqqq駟o>ڼpqqAYYʐ[PTFTT***~zp '''$$$ܹs8w wi!)) ]vETTqUjt:h=<<s#BBT*El&푂~5VFAR!C+#MR Bh"nd2.,6Hq0LR= kꮹɁyLFjkki:)34D@۩ii z1&ﲩfu.h_۝,N ٖ'QWWg[ HA-n/-O4^Qqhu`D)XlFmm- xL7|M!PUUUy޿0 yzEBh55%ΦޟTbAEE] %0zeee44Ի FyfeY(m恊 t:tq4Jzt^8{5jڴi߿?͛g{`ڴi4;(cر{ڨnv~͖wR t0[uyw}7ܑ<#xGƍ96euҤI6;@׮]GF;nL:2j{{{{׽eׯ_? *o{c %%C$fsmƭ) i4Gzzz$˗/ݼOn2HkO"''2w4Tsu~nd1 .7S$&&R(^dffQؖWPPt:NBTT d|8}jxOLLDTTTO#558w Dg2\f ;;X,Cyy9jjjIۭ(BRR=&eЮEee%Μ9ӧOSodS^II "Ν; BK7F!eѣG{СCix Vݻwq#stt?ѯ_?///#uVm6.aEPPPY@VsܹIw[n4fGT*x^:ngC/ѵkVNҫW/۷]mF.IݩS'z^[)FƟZnG5H^h4yDq;3[4)"*쉕Xcbz3մ77v&fMnz-7bEA@Mw:38緻c29sΜ<U'NNNɺp7...pssL&3#ÍnMǟ>rHNO߰aDR)BCCD#GH$:t( [[[xyytiFƻ5 pL8xpIRRބ OOO4 6 :_F2/6r %b1c 44f2jÇc 3\:tP= ˛0a 7L2SL1ƎkYPPǏV   ? &;9d2z- 6\4\ĸq]LKdd$M/7j,^ߓ=z4zCGd~Ky}6660aBa7ng4M#<QQQ[0|pʨ~Xhgx %ϰ~#\(A*b„ =z4 J www <cǎ0 ir- % Xp!0yd =z4,X///i̛7cǎEPPЀע M(tM(t;D"!AXDLW)d2r $ accC2JKRYdkk NFC t% rѽ ½z=r9R)yRyfkkM3/_דIRd29TxVVVfӣkZHRb-JI[\4X%~ %O8QV%D{tNs:m\n'h`NQlllzm۰c\(';aڶXʵO>җ8h&kdM`Y\#Իc \N+Ahs Dz,Zh:t:p-4|E#@Ւ5QxaHlllH] nd( @.82ޅuTp5,Olll@Qb} q`BCC1i$իViV˨T* 0243go8;;PTpqqAee%T*(+FvvviR:Z'#K(͍yƆ\tXCR ---en /@yF@ί0{ڢqqqAkk+4 \\\HvSzǁiARNNNPThnnEQiLL=acS}M:Np^MFUWl% xVp( hhh 4MAcX>0dB8,˂i899}@`mm fT>)IJ{g8zppp@mm-8xj5,ă0~Ȑ!$;n4Mw<nnn o~W̵YP(,-5@t̫j=/J^014aؿpWKsF~+Hׯǒ%K:i7L;߆H$8~86o a3̝;z+*++ꫯܹs:R¿:t(TTT_T*5z=͛7|hQybcc1encZqؾ};H, Yt0b̞=xqe裏>+Nx Lxk׮EKK ^uUPX`xѣG'^\.ɓ?`:t(Z-kbѢEF 6m“O>"MK.aƍ]Azz:^z%{Ŕ)SP(j4hq<35[WDx^h8CHH̙&8r8Cdd$>cXF(W^رc_`޽rJ,\k֬-Q.Y֭3qQ8q|Əo1SM]WNfs#ۓ,ͽ̽{T-}gnnb sX>OOmN/j+1.))A^^666"??mmmh4(,,DEEXEqq1233ldeei&g=AC\\Ο?~NNN Mӈƕ+Wzj |{.;^ݻQYY{~;>$xxxѣѣGNu7)BCC>s444`˲pww}v455&h <g&AEErrrpU4661k,={=>Bzq=n vÇ~ ׮]t:.]sOPd2 66=֮],#Xw|AX~!4sΡ SN%:::"((ǂ JQ]] +++DFF"<<C AJJJ6$,"!!XlVX:@&aܸq$Rk oon_N>g}Fv5(Ә?>,bccrJ}Xb>3r}6mB||<=JKGPPƍGT!!!Xf w=j,yӧt:f͚{/ߏ1cWV>BL2ax1m4 1hFrr2JKKaDc޼y_qUb_Gv܉ 0 cA{ꩧp#//=֯_z#A?G'K/!!!=n݊Tr$% z'N-&O \Nbm݆G}4M Xv-nzq_|111Xv-N8ӧOȀ0" ^4TVV"77dimmmhhh0ܪCpݲe 8bE1114iFE~R b# !ٺ@QQ^^nv"d vAg֭[qFرcf!84hۡT*2OOOL4J%ñi&CP $$Bjnnƶm۰m6fرĽ9116l8.\R 4M#22K.E{{;K47B,kkkd2 JG%LEY6l-[xbǣQc)J$''CPhll$>IIIFBLkk+N<1c`}||/_Fzz:HvƑNw8ADDDĀP'"""6mΝ;QYY˗#G>St| |WҥKqwi?Ghh(-Z#AyƢ >>xlݺ=#p* 444(̟?<cYرcƴiHܓl{5 , {K(ThJ@mm-~mxyy ضm{9GQPPv qR)QTT0iFSS8Sje<󰲲N#PoVc̘1prrK/:7!rd2"jdggeڤR).\>k׮E\\\\\L^ w\\\_;sD"qƺiEQ=~o}666JKKq b̘1ptt4\!ؾݬ󈎎-TÇ0 ZZZ@QT(R(0G}tӾhN#114Mǁy|pqqA||< VFDss3 0yd2IP[[Ǐ}^\\ 8piZ[[qapŋcP*Fqq1BCCQ^^NSBףa$[ s= L2>,ٸ# 22׿?w>xJXL8۷o7ǎB'"##CՂeYHR+!)))>㣏>?ӧO#22_5V 99JX~=BBB׮]ҥKq]wXz8vF1c/ԩSpuuŊ+ SO h| 퍭[Bdo9x N>UV!++ /fϞ ;w.Z-pExzzbdŒǾ}ꫯ/^"hٳ1gѣGzgV(xGeʕ+#11\b dff⡇>@K/;v?ؼysmVyfh>=Jš5k?CT?4`Y:[lAuu5aiooصk6}AJJJ ;Yw^%Pf5;]ٴc׮]7 Ұ,Xכ63ִ[667zۿ?vI{ܹs]jD(2oţh/qIW@06gN4]?-zyrr2mfY_瑿 |(GEF8 Y-PTUU!//Gmf8&&[nL&#f5I}AV#??/2jkkO^SdBOsa֭F- ct͆ pUիWa+Wt*^eW_a˖-믿FLLL_RRbü|2.$%%*++q57HMM5_;==]zQVŋ/Hڤׯ7ڵkP(8s k477W^49t:{_gϞ>677#&&uuu`彎ӫv֭8sg2 };֣z̙3!1Y'NΝ;-ڹmذ7mmmF/=hll4;N Ԇ q$(RJ]2Z-a)**"RWWWZAF(RIڏ?nah4F6M!n@GXzu'zѰCFCXB8+ܰaM.'zlܸ,JΝCyy9 cGw,wy={6oC&!::uuu8x`mm aZAV#66֢V{n˗qFRUUUػw/j栽{1jjyem6Ԡĭ1T*s?#(µkאT eA4R0tP6GIIIX~=~7,[ gΜAYYN8A\[[[Vo.]BRR,T*qFŋd 8pRSSQSS˗(BTbڴi`Ya߾}X`@4PQQNG3dכݹ_v o;.\?hP]]\xo}Zm'MեKСCZW_}777jn* s90(,,O?9r$N:j4dee᭷2eGE`` Z g"`|x"N>>%%%8x ǎ^'8r|+W4j>{,"""0}t4s.]PSS`8|0l\b#DB,X'N444UD"Axx8믿bpuuśolaժUP*F)Sp1;uvvFDDhNûヒ(@~CLL }]0 DR4 apy9cǎũS~ЀgW^AAAiӦ! iii8tz!HRDFFb˖-ǣ> tǏGtt4>3rdeeǚ5k@P( Ɉ(>0h >^RD||<&NH:C֭[aee^z 4Mחwa,YĬVޞrNNNi!DDDŅ2dL!;;Ćlܸqꫯ OOOy9sy={MMMݎ#FD899uswwԩShH|B8qAAAJ¹s0ydd2H$!!!ĉyf@eGX1|v!+H9±3F(#Ji BbhhFPP͛GT?34  \.ٳg_bذapvvF@@Ǐc֭=H<كK߬ҨQ 777XYY 3f͂?T*v؁#Gb„ :O0{l`…0w\P2d.\={[nQFii)gyy9y79r$8wwwb:VVVرcXp!~̙39rQ9t-Caڴi #Cmm-Fجfee/X%ZVsH$2_ `\SNECC 22͛7Ylmmގ+Ww t%zjxyygȑ#hnnFss3o4]*>hFkk+q/muJj رcfW,ѣD=wߙu8m7p촯"%%Wy_|Ÿ78|0[$''3gZ J oĞ={[o677#;;/^ġC{\.GrrrnE!..}ۑi6gII 6mDvz}ڴo?ŋ? t:wz466BHq!<7t LG}D'-- IIIhii1|pqr9qi4MÉ'Hlt$''C"@"/$n}Eբ#GH'x4]x* FQSSpa˥v2Dvv66md{[=qc8,-- ׮]#htt4Z8L 4MΈi:ui~z MQQ.\` FgϞNÑ#G<9zbhԏzq٘6i̙8rFaFΜ9cƻaa>3-OMiRѓ'OqNqqq9n M1LlRRR+++={qZ_PشiWc.qE;wD3Sjj*{}4ɸTFj+ dgg#''ȵiȑ#(//6*^75#s_*"::Wn+eQXXef͚?k/z4 ^SN}']kKKKB,Cjjj=@Ǽ^\\LfTUUuP*ľS@Z+((0:h4XzuN# 7''S#544Z("+?qqqվѣGqĉ:("Hd:hp1$''#++q O\Fe{#i4DGGoݥvLPZAy^:A!lEE6oތ[v5(㝞@4bbbCVwtƍ{'p̙N*޿:wzpg6@KK x <͛7ɓψj\_mll,jΜ9=i$P__oVC!<%%%F;iJRRq)޽zѮIq !˲ظqcۘ[EaӦMHqI/pzz:ncc_Kׯ7zȑ#f]?Sdeek6ܹ/^r{n8qR:e9r[Ν;oG zknov8:::(0rlivjEEE_:;;{ FW^J"V<#66xe.2P Y% Acc#]`ccC"xzyy `رP*HMMŨQZ J4̘1P SgffDBBB4,hhh@XXrss OOO̝;E1cagg\z8::-!!!hii3i%K O-.] \Z_ǏG]]ݝ,L:D??^x0&O82FMriӦܹsDMDB4cԋ/_~wд<,\gϞN<EEEMӘ4i._l+ !͛Gz;L0׮]#nVXۦO˗/cPfs:M6 طo#0i$B@.c…(..T3<<>>hmmE||<'N$#,, `Ȑ!d8v(m݆8F̙3P(Err2NJD___444@{EhhhsY|2 GHHpFGGGrbW'J1|ph4:u QQQ^'aTThFUU;S ӧOGll,B(#22#F\.Dž PVV˗C*BP`߾}0a H;VVVh4طo0qDh4 99˗/#4 >#((W^qmёhҬɚWZZSNapss#?舌 DFFHHH3QF=+ɪ8ky^ɲy-=7zh38B~j`hFQQqF,Zn:+;v, f¬Ywy̓=L0>("""?AAA8y$qmGAtt4 rJ۰CDDn:9s cIo_{C='fjj*1fƺupwpQ9sf˖-"""dŋc޼y]>EXx5 ;3C[2 EQ;`cc)Su: deeZx:т 0gxxx 4+VOKxyy^CPPn6DFFW_=BCC1fyeEᮻEQ[Rkx1a,^=z40g0 Kb?Eaܹxg0x XSNr9/^<;֭CXXN n:<0a&O|Xbn6l _֭Xd ꫯ" d<䓠( gFkk+^z%R㥗^믿~3f̀B37t(xKRO?4t:aggСCYYYw0 sa it#y/@0R:88N"--G;;;(c Æ 3GgVr\edd@VĢ7Hjj*.]ԥ9;ٱQAVٹA,Z[[3g#Bt឴ OOOƂyr <27b2f888 )) ~!4 زB@@ɜIQXpO>hkkèQ@QÆ -cĈ9r$ wwwZ ;;;PLݻwc0hiiFRF d()) 7zhRz RMMMMprr"H$hoo)1o9+cРA\.'kAT*Q]]{ 0سg!ɰo>\p?1l[f 9B\!=s H$9s.\0[?o_Rpa ''ѝ jR);FTAt)x'ᡇ"6-NT555غu+q54ȑȟZg}ko+DC-mmmرcyNֈ@]]1μKo%F2}JetہyܹWQ7Rݻע-˲ؾ}{ղ?(HR:u .]N8ϣZ,?'SDt<D>|0RSS977?Y\ ;wqFt@B` F?Wp(iii$]z0 .\xr\t N"ݻe@B cSۡGv 3l_!lDW|ݶpj{4m4WR84<"kiiAJJEwiCg|{%t:!Ek!OUUUmd켼<Z*=F8(#66v+0 ]FOΞ=;sIII=>DJJ -&ŋ:˲8s挘oq8s̀̚#11 3gtk*rcxQP؈:={ [lC4? HH6段_uW_mxhnnƏ?إRsN2H$={b/!pDsNR?!z]~Lz4M !JJ~ FBxr455!33h.++#zuuuhmmJ":T(w xyy9QUTT! 0D0\mmm"Y[[ gRQQa|,^1577w0?M鮿"$돝VKK 2330 VۧTh* (/^/F]wEnӣDw}O<L ۱m6 :}g!˱j*P5uxq)Cz-P_/FWZDDDDDDyϱz,PH낌H8Snv<󼠅aYIIIt8)))())R'%%oj謬,֢Ȓ4R(/))-(?P`}?$.aLihh P͑e̚*AMM̀fm h4HJJ굛qiiiyOS/Ŵw W[***p455 sތes!Q*|rWPPF477w Zʲ,.])Eff$`8zގV8$''Ѹv]LZmT8p3tdl x;vxj>|yyyj|2qat:633ݦ'*ԩSFtapA0 C"/ Ƒ#G{^'suM gOt+0 7( : II<ϣ(.KSS222:ŁZ"*{i4-SDyX T*$]hmm5jϚ1 :b%Q`m*sӔKo1/ŝ<6zKKK 222.@GLz8ޠjI\P__6jTVV}g&RUUevj8zhhPQQAֹF Jֆ teee$ϓ Xt)f̘^{ Fܹsma<3gx:t(n:]ۓ^~e[oL&#sP²,b t+X4 :4M< 7(DE  dNt`(H$hmmL&-uW'z!JHoy8iMTxyD GNŝ!x;;;^"@**IJ:A9Z9JR#/JN?$BTB*(^", Z뀥(JQ#""""""7x<ϳqEq,˂8z١ݬSC s=J62 VVVL&E<`cn碧(J+ gmmKR֖?z-;̺ 4Zd U]]M+ ʊ tRt!tQ,bĉ|2XEXX8ՁiL8a BZlllp0j(@aa!h&ʛ8q"\V dggo'"++ J'NDnn4iK ݑ)A  kOSDDP]] 466_$73<#<<hmmvU,0rHH$\zl"HKӴ^]q˴i HۧX0&Mٳgaر$;r?;;;ܑ%8?T* +WfHII!!58Cpp0PWWGx(//G```8Aӡ>>>HOOGXXaTTT`ܸqHNNq)Spytu|}}, 'N@ G^^RѣGرc1bYo===N`hƜ9s܌D>>9s&N555Q~t$z-44MmllX胷T$ sΥgQ4M* Z0""""""\(L&㭭 (:xqIz> UP@G ///KA*RC GFy466B@Gr\t\{r(""""""t8Cnn.4uL3P*Q"""""""Smc"HDDDDDDDDDDDDDDDDh?1Sfb%tEXtdate:create2020-05-10T10:39:39+02:00V %tEXtdate:modify2020-05-10T10:39:39+02:00 IENDB`qnetload-1.3.6/docs/images/xnetload.png000066400000000000000000000773711451037126700200760ustar00rootroot00000000000000PNG  IHDR0A-gAMA a cHRMz&u0`:pQ<bKGD pHYs99VtIME ''bJbIDATxy ל3g{eRDDҪP~EV!DȒ-Y#v\wffw\x̙ygAAAAAAAAAAAAAAAAAAAAAAAAAAJpdd$EQn4s/ K$L&E?wcccK\ڝz[Z:FEEi>vAAn@$ٳg@JURJ*QF JCAAɄl&11 &%% .`2.{dd  ן$IdggiZ CE4TL S&54$AA'4튚)N5E-1 )yR4s#IBۅ]V/-5巣RqΛ?-m ͕1WT zd%J-#Yªyi I \ &@r2o.n Lk_4 T Th&s)BkP3X,㡯( _J=z46 ?2&ʅi1zh0LLTV5Zߟ~?+,@.m`riX%VR?&I2’ʕпI(*GT6K)(|nai׮UTd2qFN>Gr97C.]6nd-Zʅ ?S@! zQR%$,.^ȑ#G4ɲLiܸ1vMPlbcc9v/^44 J ]6saMB^/M4~) ^xJB4СV"99mRvm:Į]0ͅnJ~W\B$s0Wr~;xJX1p#<aZ9{,+V' 33o.[;`޽Ȳc=Fjx<={RSS$PnvZlI͚5 d2re߾}lڴ{xlt ___TiӦr-8pFUU*WL۶m[&00IHOOܹsٳ7r1Jen6|AmfffryvիxbnׯO@@MP?zK^/קsF}[t\l߾2(?:u2D.5j?m K{AQTECUTd.URFf֊&J`Dff&k׮%::vѶm[bbbHIIaÆoߞ,lš5kHKKC4<Q N-HJJB4TBZСgϞ%>>`ZlI=̙3XV#xIFFF1^2V+k֬aٲe$I\.nw]&11dPT ߠ 8$[h W/I!%%WF2pgҥҼysի… ,^۷AސVoâEHHH --W_}IvsEl65kDUU|||ԩ<! ^/AAADEE$Il\oBYYY$&&bQU\Ljj*SJ7ogϞEUU[6mJժUP\t Fdd$:u"::7X,J*c2رc˗/'==X4M}FF||`DXXf9_wIrrrvq:ȲLBB6(UdfBCC, ^׸DLz\H:#'o L}y3EPUM- KUUlC=D5X,X,9–-[,N&..\IL&Ϩs.pųAk%&&'''r$ ݎ@UUӧ> MTOf361h^FFiiiL&cyE 4Mח':X, :boACYKPJƏ?F~Ĕ)S }Ѹp chKkΠFV3[ 5d2xG^:iiiGʕܹ3SN^_MLOBBo6'N@_z*++ Áb!,,,4M#88xs:dffi~~~qȹcժU$&&ҽ{w/ 2~~~f,$FaٌߒN}ࡇq ee2l\.~mN<(e޺~n*!7oo}yEP6Ih#PL&M6{bŊX͛7ӢE {1:tmعs' lҥK'Yac&baɒ%lذ!wp2ol6K~4SNt:6m'11Ze [x)mN*D$ԿK`ĭIHD@@O?4jӬ_իWN&MZ*>,'N7If3GFs]wQZ5RSS?TX2c KDȲLǎ`,Zٳ_5jHNhذ!PZ5"##q:l۶7b6q::tVZa6֭:t ==|o}j*6mJXX5k֤O><(TUرc.TH/9t萱-YpΝ+p@T.gQw6tVUHGҥ wq~?tvN׮]o֕j74֯_o4l_>52333pvbƶE~ 00f͚mxb0n>x^j׮M6m>|UVqf3)))̟?Yiܸ17tqqq,\4ib>ˡC;w.iii4k֌:uMXnv[ ¿ɕ)Ź$IJv+FQ5R3$I.9ْW]ιrUAf(q4-WO$Œk{(yҷ&Uz& ŒkV5[nޡM&͏.g9&Uu_a$I#--,tC+˽'.DD"8$I*@ކz}l.UѳDVzQJSQԾ KsQ6A)1$ IP2Z9 +If$AA(@=ыMf*+&S[F ϧeԮ\8$I*h P209ʧ  RhlAA*S ((Aq:_-Zвe\  ,l۶۷i`20p7ӳgO\.AAn06 ֭[]Ka\.`AA(+Ź#Z,}wևYc5_Շa/|)inAn4z?xc-1L$%% ]-}YYYT@\yb1]$IHH@e*TPq{$I">>L .0m$HFF0/ Xlhf/һwovJΝٿ(x/֭SL0aݺuc*VSUǏӧOz͑#GrqFy^|EK{r1euƜ9srL8x3f9/  \k(BŊqivׯmڴaڵ\.>|]E*0ٳQF1}tf͚ŸqV#Gx.TDUӮ(  qƬ]F/4wy+V$ WK0̸9I2;+b)"캅m+߇ʕ+jժqFx nw.hV_}< ;fm6toQI^cPJl6/3x߿?]veǎl6, 7o7$%%HHKKf˖-̝;tv/_NN3fQ*r߿?6mߟUb6l 4׋n 5Qns!%''3zh8p cܹOk׎޽{(Jm", ۷ogʔ)F a6lժUcof!YB}]V+N2JtRUU9qD0f31117СC gʔ)رݻƌ30Fj孷ޢf͚hƊ+9}4ϟg="WL~ O6 :[r5j::u"--XQUHHHM6vm\p|/tIIIx< i8qh3NB$n7Æ cÆ ۗ;vyrPA!r)d[neƍ#2'N`׮]>|UU;d޽=z'O}G _HLL,d&t6md$~vٳgg֭=zvѶm[Ϙ1c믿0LTVFK֭ZrV+[pиqc#`)(tM4hРv+R~}jժ@hh(-[,6?M&o>GFzzze8q"$|@ ztR&OLŊ4iu-rMMaرdzw^N'O>$ v( fРA2`x =z4'Oȑ#HDDD}E?TΜ9\+RJ||4jԈcRJV+>^DKff&]taȐ!x<Mfje,_/QAAȯ\JHH}g̘1F'|s!^yyV+aaaL>+Wc1j(1L`Xf燦if 3z :Cn8y$cƌ)MvL:FA߾}9w8$:: h".\h|XV֬Y̙3tÇ'--Dms$Ib„ ڵݻqݘL&RSS>|8kbZx<4hЀ~!C0h HӦMy3gaaa׏gbۙ7o˖-СCFcr1u놪;Fp(Γ  \ j ru|ݻwƞb$I8<nݎ.툟Ӊf($ c,c9NIJzzzn`` ?CN:|FZ|9Çf͚̜9R5.vハMӈO>>u|G6ݞ+Koc)% l̚5ٳgcVو\Hd{iF;B4 R2wz@|;\˕d"(( .n;zz^4ij%<<3hȹOIPӦMvlU39C K< <;Җo. WC7+e %:M۶m/-kRfM2MaP\ګTb쫠懪$"]|A p-\٨oDNdd1QarV{5\m_ ByL V! qfAA(/"AsU.1"I 9ooҮ/SiO߮Ʋ)h0}_nQi/nҦkI^|-> \m<w=4ە~Ly|ߊ ;J$$$.כd"99T1i;wK X$ItglC\n֒$@FFpDDD1=:$$|7vMӸpn0|}}%3,X@׮]9rdYn>˗ӣGnLrog}]|I#mqY^xRSS9s&zkIdff2l0݋4oޜc ]OeK/Dxx8 ,0+;v,N'~)M4ɵ=ɓ'ٳ'vSR"n~ÇөS\HQ, [l_~Ȳl\SLQFn,XY bZ={6+W.24T^uΝ;n'--;2lذ"3Yx1SN57ߤG:uO???? If͢zXV̙cLGAz3gNf華:e M&>CΝ `e?^{Çd-[ҥKq8YW_}N@@gӦMXB'Io6?#ݺucٲe 8}ꫯ]EUUQUdzh"nV&N̙3[h`޼ytԉ7x#߹UU~+VǕ΋/Ⱦ}t<'111ݛ8xzyؼy3/=?</ړ$ EQp\dggEQVʼyϐeW_}]vY4<ٸ!V &Pn]FɢEp81cͣf͚L&N'|B֭Yx1ƍ#11޽{sܹB$L^|Eҥ K.eŖHĮ]xW"++3IxY/MAz{Ç2dɓ'[l]ڴ1+WPY9v: QbE^/Ǐl6cXp:X,333q:mUTP{ubX&UVQQQȺ9Z$4ӧ:t(wunCf~UU4h7n8hd"!!~q|j?dȐ!ƖjDT$%%Ы0rO;c^*=տ߾};o6L4 *jm9$I"<<͆%++TLsdd$FpPbE4b_ TU%!!*Ud:欒*_3<Sr}GXq%$$/>GAЕkr1bQݽ{w:t耦i:t' j^yZj(رÇc6߿?իWAȑ#Yb=z 66+V bbb5KFFT\؎,enSb20̈́)UILӃ'NzQL&~fϞmC`` %1cưi&}QwnTL&N'Æ cƍl߾͛7iVӧO3l0N8#9u1ᅬfь39reCNÆ j2vXv /`\޲,t:9wF`j٘2e [nd2*M65&~cǎeܹѽ{R®oGfL[je\|1Ȳ\vsB7LFz E)l6ӺukNʅ h۶-fEQHMMe8zse„ ꫴoߞZh#GX,~\Q#TXO>᧟~K.ٓoD{<n|I~G -4~'?(ԪU}x]͘1cgΝw}ԨQ^z]=4iK,M6ԬY/K !33~qM7zaǎ̜9^{5dYFUU&NȂ hݺ5m۶e˖-,\EQcGzz:&SR%1 %V,t҅Eq…tޝ *n:mi߾=UV^s=n⛚bժUdddCQN)B?RѣG7o6nݺ$Il4@eΞ=˗_~ڵky'x???t&^z Arr2fTaO?(tܙ*Uj6p6lRJt-Wl߿6mйsgΜ9S4L,\3fN:uKn"++3g?ЦM^y6lȆ ˁV j$n7,3}tΟ?O߾}yxS>C=dzUԺ=Ngb6K5.00ݻ`|fB Ƶ-qCfArovAjf4˹/,,plʕ?~xEQVo^aÆ ZN/uվ}{|M-[7o;w.QWlB߾}SΝcԮ]v7|Cpp0{& С̛7]vMTTz2}9sm۶ѴiS4h{UUYx1[nĉ૯jVr:n ^Rf 6mڄ,4oڜ, z+>|#Go͚5ĉF?\WF;w}Df |ȲL||<חf͚K(CJs@K.k.vO`2طo Kv đ#GʢC fժUT\f͚t:vmnvݻ9qvmHįiFSUU\2z+f+Wx~,sy=Jpp07|3( | Nbܸqw}deeQIbиqc<֭[T=@ksM7ꪮi7n$""w}۷3fCiӦoc֬Y>|7|Ν;YkB$zȲoFN@9E4, 111#3رc={u„ 2c㏳|r}]7n^MDDC#%%K2yd4i7t,SJvIll,Ol6Sz\#EUU;&55*UG}Dtt4ƍjۓe[S^=΋/oNÆ [n0->>3gN :uje,_KƍsC9px:Zqqqtԉ㚈믿櫯nݺ7jժJӧٳgQ}cۉ.QL`` ǏgԨQL<EQxu8px^*WL`` fb͚5<Jm4McY^zӵkW>S+7n$I;v  ,u]>|???Vf3KJJ?4ί$ITV ŋhѢ+Wt2c v͐!ChӦ .]Be*W\n;iii߿s!IիW7pF0,Pr `Ն Bzz:O??><@hh(!!!FCŠ |||p8Ȳ̞={?~<ͻ˴iJ-NηHUUq8vHXX}/2/^dѴmۖto 0J9&NHfXf f ..#F0k,BBB9r$,zj6l؀ncʔ)E4 Y  IYYYՋ~Gu<0i$틦i1}t*W\|z 4_M@@#FWEQn%;y=88___PdYb`XXh .5ӧ#2i馛2eJozBBBZL4_A`` $''ӯ_?4MfӨQ#~G8 6?bl2VZ⮻b„ fŋ9r$;89o22d&ɓ'ӬY3ѣGy嗍V+ӦMVZ̞=իW{nƏϤIcڴi̜9/l|I Rlf3A`HH XV:u}**T`ڴiTXĂ X|98ǂ yE\.W^x޽{E窪!lm61<ސ133ǃvUUپ};e֬YԬY9]NqSӪUza6_/_Έ#Y&3f ,,,כ>&VEQu+{vn7f>̽>ܾ>zY^ql6c ÑdMW4|}}X,(œ9s4i͛7gʔ)SP~>s^9ӦKԯ,\.WY9X,95ziJ7 sߍ?fĉ;w.:t`̘1F/Ιz`RqFr^zR닢(N{=fggJ~m b٘5kgf-E9#%.XL&+V,uOx}}=˘L&cJTTTZ4$WgY^<.11"## ~ʒ]Emk$ywْDRR1Uz-(_ K[y[Ǖ0ڈLA3yl&zëSU___c‚&Y,ﴖf呏屟~*+=\3/ʺ !44_yKٮ4A^$sRs\k7rD^b8A'=(k320zJ*&Z$ fԵWA+cۍZ(sp85SU ~vm;Y p8moxXz5o1c=ȑ#iܸN  \.7o^ ..|ٲe_\$ +_ŋt9Wӻ P^Hdee+fRSS tRY`! n]^He(rLx]N'qqqf#44IJ5A  IdL" \n7=zr{#e{s\..\@xx8 ,_ f__9/`aJdd$׿_.ٳK"-- &0c DJA2,@Zr9r$.]*DxhҤ */1/&A)&66Yft:1cW5[l!-- [,  )e;v0sL$I=9q#G$((ł/nLPfRgx<̛71G  baǎeSf3$99Dv}]>%%~ЬY3KݰV$J(ڟ  $Ic6˴~E^xט5k}駟ҪU2}vZjUj;PZ5#`4 Tr]BAn&Lnz2l,Z/WJQKNvv6:uG̛7z  ]Q#Rtiڵ<>ǓﳿA*+si?f 7MxꩧꫯJ.Ip\dee{zAA(\Y0/Tu rqZjRli, ?^. nݺ*JcA$Bjj*$]^/mڴj2mڴz֭[XL&V+}:0jԨrBB DEEihdAA_`XXb+Wbz20ФIQL6mҥKy^>bcclƢ( G-tӭ[71  .e[~z4i<\n3vXr^d PJ?СC,_o˅(2tPRSSwAA(e `L&1118\Ǝk{˖-lٲ庤#;;M6aٮw ?jeLvl.]tjRj+"& f. pmz!9N|M}8lݺU4ABl6ƍǸqTVUTB$`Ae}+[œ  u$AAn8eBZ,XEQw.^s=lIArcXX,ENvK=:j}Ml aXFU dYfժUڵy7n\윀,T xd7a2X60  pD#  ̍4EbT8FnOAI, ހ SF$.\=ʕ+f~ݐf3gϞA VIcccr2?+\*,xt%Q  (RZUUQخԊ\D  ךo$kzQ\.UU-ijU(J}@@%tZ,L&oE~lkIȲl.q̷Sa缰<+KyQc͛ҦGArM_NU|ue K[Ik(o\$ ŒkGAn\d2aZ4غd6dĉi&.]вeK6mĒ%Kr=l6ҥKn6nȏ?h<y嗱Z޸- gɓZG%;;dYf,]dbW^DGGӔo|x<}Y*VX.]6yw^^|Eɓ'yp:]ɔ+zz>x|||Xh7o]vtܹ}F:ŋꫯX,AAAE1^O?$z)6l,Q^f;… $ ˅$I<ԨQe˖A\Y,zIxx86k/p7ӥKTUE$f33g`oG)6oV+gΜ/4ΩjW^TZ5yI$ϟi߾}|x<̘1\AɭJ׮]q:dff2m4222wM6mJ P0=CJ }IRU_?&1͜f3OfӱcG$Ibʕ8N5k7zٌ#++zʕ+_q*-?'<<Bu 3gqqq|ͤwޙk%ieXbח}Wdl6eOp8eY|ѡCn7K,A4}Y*Ud,ddd0|v;ݺu#88RYYnݛ l6syϟcǎl6#߈^’ҥKeΝ;SjU֬Yg}_Ejj*?8rXt)_}գZjر#2wuWc/矹Xb.^zQFBd2믿yfСCܹsiӆ5j{nكj{uo8222_0$B)BVh۶myzcI@3חUʩS4i+Wj*޷X,={;wB۶m8f3/^d֬Y1p@T… ߨ[.o&͚5.?Xn7;v ##Yٺu+> cƌСC̜9:Zhuf֬Y#0vX&O̷~KJTʰa0,[[nu? @v D4f3&4T7{I3gϟ_~}dff%k֬?&%%%j?4;_'ҧOzԩS8q"v-[e~=̋*U{͛iӦ UVEQL&l6ڷoo3_eY_~l߾kҤI7on[I;r# 2))),^uѦMX~=7n$111yt:̚5zɃ>'|w}G =/,s,YB͚5>|8wfɒ%hт:u7iZFμ޽;?8}ƍcs=2d$I駟&..T)B!B =ٻw/YYYߕ+Wjժ$''s, bp!RRRjrAN'۶mLJkto3g+Wf|:~rr)\Cvv6իW'((+Rn](DD8jV`#2Νc̘18 Fdd$$q).^h,GK8y^GVVUV%(((3L8N6lѣNNN_E4, 4(vl!EQ0agΜ0ɓ'4i/fCDݺu F~u>>HѣGs F@ Kj׮;}!&&RrKYl1~;FחO?Gy O^dzTU`6lHjPUUUl6ÇX,ԨQ#׾򶫑$IDO@A+'(믣*\pxz#GгgO cرl߾7|@JJ cǎEe&MDڵ1/,Y?fڴi&i6J*ӧq\0d"55_Miܸ1ݺu#33#Gp$IRJi2\2qqq\pxIDdddcx"IYYY;wLJcOHH`lܸ(p8|'TV-WiD^$HHH`֬YqFƍ2dիWg 0}NLL .^D&O̭ޚ*j4g2tPN:ȑ#tr Qd"== .`2j%MӸx">&,,DVʄ 2JNrr2/f1bĈ+nE1qDTknGUU}]l66l(zLHH(z,|x<ZjE֭x<;wi\%>&l֬Y{G&M?~o;v$I"**J12d"))_|K.1vXV\ɣ>ʲe?~|$ v;PBk.\HjPSO=śofqL>T7łx^j׮ `Ȑ!+C.ihG[f ;wfTP3fU 4 ƌC5,K,᭷ĉ >ZV~>sHIIᥗ^̙3EV4Mp0vXUĉyYd woFGUU9x O=}%33 &pwݚ(,]w}&M0}tO6=z`ڵkǐ!Cj SnOV/1@ݴz$Iv|||rp5Mcǎ~X,|}}-#V7 e̙ԯ_f=|ƍGF8q"$\>%I"33^{Ǐp=0m4KdYf„ %zhDFF2k,f3}aȲL.]o1b5j`ƌFE᭷BUU.\b^cX\Aol!GzXoE׮];Zl6vq\zMjj*}wyg}שSO?4yȔ)Sh߾=| 'Ne˖L8hl2aܹfƍW1l߾_j\ozQ[nɓ'p8r0￟Yf1sLFI"?UJtz)^bEhhhUe*T@ #g)KRRbb0k,&NȭP_$1~eYrt:1͸\.^/\|TTG}Rdv???NJժU:t(֭~%!!{nݺq c]___ 1>+uPsaesb*InL&@l1肂1bK,#* :~_|\z522 *b\gŵ{=FDDcjjjL\jo1p@|}}>}:5k$<<تԼ233q:l|,@`` +bArU47Jjz7ѣ{Eev;O=#G,[ ={W_%---@X}1l0ItBڵ.9ay~Hdd$;v0J W̙3Yp![M>|8 "..gy{~, ϟGUUmcRyOΝ?ٳ9NLs,w[os_ݸIHHnS^=l6[(uݹsgyvɈ#&)o%goOOʬ~{ZQZ͚5y`޽9rS~}yVJ@@۷oȑ#_dggsm6m6;vȑ#lٲVZĪUٿ?Ohfo?ƍٰa 6O>o߾ 6pa>Lvv6ݻw禛n*QiDFFr!Kpp0knSF UFՉ~ ..vq7s1֬Yþ}Xv-gΜW^utRNʡC8uhY\2ڵs( >,-Z(̙33x`jժƍٺu++V$--7t:ٿ?k׮%&&>}p]w?ҪU+~|%';rl6ӽ{wjժeܸqlڴzG},I+WrQ~g֭Khh(qA~?LRR iӦ̜9ssNRRRd׮]ر-[Rre/>oƦMV}55uq=JDDk[́Xf WfŊTPUznL&?#gΜ{婧"++˗sy6mʲeHKK#66 6axWZ*=}-Zc~ L!_ ްmk޽Yddd<-q@zNΝq:ši> [[oSOEիWG47oRJԫW&MPbEzꅿ?>>>l6yRSSx###iܸ1wy'. DŊ2J7o.A(zo?Np_xKUiw*^wn9G܃7ټ9ѧvngΝ,Xh^~?d͈ҖsL&(9\pj*VZEfxgs=y+o(AR^zCX=mEmb*ix~ E/xzȲ+yLJ͛7dԩC>}MOI3mv ;%gqs;($9dAǙW)<Ȕ)SgϞԯ_ә|TL򞧂yӖw[p#ӇzX`A}[Ju=B罴)/=|7*}gqY,qQz sT͕W|g*S J/ɲWC91lTAA+i|PXo*Si!!!(  f].22Dl6Ʃ*2kݿ$Id yҔ$>՟lA=x"& E߾}ӧN  9oqqqϹQ}^$ 7-++իW-&&O>ÇŠAuf P?85k,r ͛_:ġC_x\ vѮ] lf޽̟?\n $%%;[ll,ÇncيoGAY,[Z2M%iZG}}}XL&7?~AA$I"99d$I6S \.yx\l߾VZ8aԬYz']AnX&L/S+i$%%|Nk  72Avv6<kfժURC{ AA 4M#!!DGƍiذ!oN  Oݨ;>SVj>jժٳg9{,_5wJ*̘1v' Je `V+/fΝd*a-2{e׮]>7׏rt:bZ..]ĥK'==] x' 0L:u*WGiy6Pn&$I"!!ӧxfjEQX|ydjW_߿q\r#2f}rrIK׮]"Y BdY&==_<wy'ҥK̜9e$ITX={Zu6o̱cǰ\xʈ#n" t&L/S?>|u;xŠAPU^zVri&7nׯniAʔ91Lx<;vMx7Q]teϞ=Ջ'O^ pl6/^L~1$I";;8*:uą wAA(e`\.YYY;ʨQ3f >,3f^啎kOAAvnw/d@GJvv6; 8NRSSB L&Eٳ%%u, +WFJ ?C$n>v3ȑ#w.]d;33 f͚ERRݻw'))隤#**/B d' Z||e LDGG|HΝcܸq8kZeiٲF- EX~}S \O|w;  31  7 p)Sd㢍G!X~h+ ZC>Cv{/s/$R~ $IǧL'DAWr;CF  pD#  G0  pT$2ׯnsEuX6r0aAA(,lٲ2Fz4M4- P8YF;p$I=Ad,[                          \+rR>zeXIfII*nt|(1 211GIMP 2.10.82020:04:20 23:03:33R iJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222R" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?k;9VCJ 2y>´?ƫhmQ% U#cDL s('%/"ڷ<"5k[xSsܨ? V{PF/"ڷ<"5QP/"ڷ<"5QP/"ڷ<"5QP/"ڷ<"5QP/"ڷ<"5uђQH7z'| F޽f\fI4kP2I&1 ȹMAP-j/^ߥ]f m K.א+E?1 9<*Z{hl;ߡ2 nMo^F[OW1% _v0L|vy/S^WY5$-lnX3(*7c+^kXew).N${۾GQ@)ctšj?7]ؿ6\yE!R#Wڮmk%M!P"K0{q=?گ kwMYauPZ4!ZBT@Z[a"v"GFuPW<}G@)ctšj?7]ྶ6q)AzW:g$:SFNIϭq=?گ kuxHrی3Яn#.zqֵy)ctšj?7^Ey)ctšj?7^Ey)ctšj?7^Ey)ctšj?7^Ey)ctšj?7^Ey)ctšj?7^Ey+id[PB2G_;I˼+ʾ4c}Mu _Ff9f<ӓOF[!yUq'gs/Em> $r3z[GbYod$΀>·mΫ36s1Y{KӮuREjrKB\ے<{_5Wz21t$Xos=# tM{\}FrebmpvROzgrjI< o%$/x= lhzuJ[?޾rOGúݎsX7貯1!iNg"12.$l# 3끚>=N9>or6rAh}??>WEaxGBKіtd|In,ja}Q-~H?P)@2 ?\~}?mN}85)R>|wqzH8y?>;g"ϳU@2oK}9Lo8fO>e<+j0d+c=UϳUG* $zqM0Jwp;`Jt=8Gk*2 0ui~}??>WEs Эch⻈#K|r3LӠ>oA oX?\~}?;[Ch-5cqQ (!m}vՏϳUG* c?ƏBV?>WEg"+>oA oX?\~}?;[Ch-5cqQ (!m}vՏϳUG* 7ao|?ܯdXS@MWŶtȗk, yP~u3l1wU+׮Eǫ(+I_4w1,Tmī(?᎜P6Rxi3-ځP$)猌qެ],O^0D*~g`8f=שZZZ(m0S\ )~ -hu iE#-.!S$:'φ4;\\'C(KsC2+6ѹ Yl'z9l:"=#÷4k+ vxYbd/~aUu=ω4x'Β`an3~rMsLULvr*l!!}^4k;5w4y7d#W=潤K##bod\`>>ҏť‹z׃o˱ۗqq[y!-n.fXȽB0ICq۞Ʀfy"BCeH &nT,ey$`G Zz{!0s`{R=7f$qn]-evP"KnT={Cl%:;J \C_#fdR_+?=@44pxt|ő`CerG5am;rlΪ/.3_γ?;H_Ěc$H.[GEO-Džfe~b#FVz?#ji%"O2+*pyu=*Ԭܪ޴M"sV{Aෙ&oFDY1^}CNh,-|3r{_JBJr~RwV^(u{iondX&nfo*ixo+ WGP6]|Ul?ܻ4 K4i_@|wTyr⪷hҿ*?*/ ѥTUYaQ˿^J?7CFQTg͇7Y^&K˿ j<2BVAʥ_*hҿ*?*I/xJmPB~ʿje}@|)mi#e%mFW %y>O5GuA'AGJ栻urM%ߑ G~1@oïk? /S9e"M_)_Ulտ篈?+4B-+Z|?HF6m'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?Malտ篈?+  :O /tt٫_~VF[z _qГM'I?վquymXcҾ-c}M{#/J]W#d^8ss@ EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPӝb%tEXtdate:create2020-05-10T10:39:39+02:00V %tEXtdate:modify2020-05-10T10:39:39+02:00 tEXtexif:BitsPerSample8, 8, 8>'!tEXtexif:DateTime2020:04:20 23:03:33ւ8tEXtexif:ImageLength162tEXtexif:ImageWidth502GxtEXtexif:SoftwareGIMP 2.10.8IDMIENDB`qnetload-1.3.6/src/000077500000000000000000000000001451037126700141255ustar00rootroot00000000000000qnetload-1.3.6/src/CMakeLists.txt000066400000000000000000000015411451037126700166660ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.25.1) include(GNUInstallDirs) enable_testing() project(qnetload) add_subdirectory(tests) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) find_package(Qt6Widgets REQUIRED) find_package(Qt6Network REQUIRED) set(QT6_LIBRARIES Qt6::Widgets Qt6::Network) set(TARGET ${CMAKE_PROJECT_NAME}) set(SOURCES main.cpp mainwindow.cpp networkinformationreader.cpp informationstorage.cpp formatnumber.cpp plot.cpp clickablelabel.cpp utils.cpp resources.qrc ) set(UI_SOURCES mainwindow.ui ) set(CMAKE_AUTORCC ON) qt6_wrap_ui(UI_GENERATED_HEADERS ${UI_SOURCES}) add_executable(${TARGET} ${SOURCES} ${UI_GENERATED_HEADERS}) target_link_libraries(${TARGET} ${QT6_LIBRARIES}) install(TARGETS qnetload DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES manual/qnetload.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) qnetload-1.3.6/src/clickablelabel.cpp000066400000000000000000000032111451037126700175370ustar00rootroot00000000000000#include "clickablelabel.h" // Copied and changed from: https://wiki.qt.io/Clickable_QLabel #include #include #include /* * Copyright 2017, 2020 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f) : QLabel(parent) , m_inside(false) { Q_UNUSED(f); } ClickableLabel::~ClickableLabel() { } void ClickableLabel::mousePressEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) { emit leftClicked(); } } void ClickableLabel::paintEvent(QPaintEvent* event) { QLabel::paintEvent(event); QPainter painter(this); painter.setPen(Qt::black); if (m_inside) { painter.drawRect(0, 0, width()-1, height()-1); } } void ClickableLabel::enterEvent(QEnterEvent* event) { Q_UNUSED(event); m_inside = true; update(); } void ClickableLabel::leaveEvent(QEvent* event) { Q_UNUSED(event); m_inside = false; update(); } qnetload-1.3.6/src/clickablelabel.h000066400000000000000000000025111451037126700172060ustar00rootroot00000000000000#pragma once // Copied and changed from https://wiki.qt.io/Clickable_QLabel #include #include /* * Copyright 2017, 2020 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class ClickableLabel : public QLabel { Q_OBJECT public: explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~ClickableLabel(); Q_SIGNALS: void leftClicked(); protected: void mousePressEvent(QMouseEvent* event) override; void leaveEvent(QEvent* event) override; void enterEvent(QEnterEvent* event) override; virtual void paintEvent(QPaintEvent* event) override; private: bool m_inside; }; qnetload-1.3.6/src/formatnumber.cpp000066400000000000000000000045041451037126700173350ustar00rootroot00000000000000#include "formatnumber.h" /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ QString FormatNumber::formatBytes(quint64 bytes, const QString& unitsPostfix) { double value = bytes; bool isBytes = true; int i; for (i = 0; value > 1024.0 && i < prefixes().count(); i++) { value /= 1024.0; isBytes = false; } int decimals; if (isBytes) { decimals = 0; } else { decimals = 2; } return QString("%1 %2%3").arg(QString::number(value, 'f', decimals)).arg(prefixes()[i], unitsPostfix); } QString FormatNumber::formatSpeed(quint64 bytesSecond) { return formatBytes(bytesSecond, "B/s"); } QString FormatNumber::formatTransfer(quint64 bytes) { return formatBytes(bytes, "B"); } QString FormatNumber::formatElapsedTime(quint64 milliseconds) { quint64 seconds = milliseconds / 1000; quint64 minutes = seconds / 60; seconds %= 60; quint64 hours = minutes / 60; minutes %= 60; return QString("%1:%2:%3").arg(hours).arg(padNumber(minutes)).arg(padNumber(seconds)); } QString FormatNumber::formatSeconds(quint64 totalSeconds) { if (totalSeconds > 59) { quint64 minutes = totalSeconds / 60; quint64 seconds = totalSeconds % 60; return QString("%1 min %2 secs").arg(minutes).arg(seconds); } else { return QString("%1 secs").arg(totalSeconds); } } QString FormatNumber::padNumber(quint64 number) { return QString("%1").arg(number, 2, 10, QChar('0')); } QStringList FormatNumber::prefixes() { static QStringList prefixList = (QStringList() << "" << "K" << "M" << "G" << "T" << "P" << "E"); return prefixList; } qnetload-1.3.6/src/formatnumber.h000066400000000000000000000023751451037126700170060ustar00rootroot00000000000000#pragma once #include #include /* * Copyright 2017, 2019 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class FormatNumber { public: static QString formatSpeed(quint64 bytesSecond); static QString formatTransfer(quint64 bytes); // Formats to hh:mm:ss static QString formatElapsedTime(quint64 milliseconds); // formats to M min S sec static QString formatSeconds(quint64 totalSeconds); private: static QString formatBytes(quint64 bytes, const QString& unitsPostfix); static QString padNumber(quint64 number); static QStringList prefixes(); }; qnetload-1.3.6/src/icons/000077500000000000000000000000001451037126700152405ustar00rootroot00000000000000qnetload-1.3.6/src/icons/arrow-circle-135-left.png000066400000000000000000000033741451037126700216040ustar00rootroot00000000000000PNG  IHDR7zTXtRaw profile type exifxڭWm& )r$`> rٷӆBUBq㟿K.9HSIK,Xu]-x>S6\_UqۏO,yo찿N/ xyJ>U>|r <)䯹sֽgwn{ҍmك-wt=덻9{s\1 SMVΞ8Be8%Y>$}>"w-6QA'DPa8M F"6 -Ƃ>&r(E&1asr Ax+On 4J]++Rn=K9voy߄ 4g` xV8uG>: E6 OxFd1>Ucx@mBH"NƵa8}2Ki!("M UĊ$8fɡJ#DL RLRjT3g.\s1SNs%ׂ%H K)ʢUBW]ţpătr&bJ{r{zCRiA# yQ 3Ni̳jmU?Ur߫[X<5rBK3Q #ƥ#.frE(-q:,D8iiR[? [ʹ%VzQ):S6qO[_VYu'hKi&~ۺ9ڙH#qzOEM"=^#a]n aӉ5lq& m%]},c%#mmp佲WÁƮntж)&!5?v֒N߫BY)FS! b~T| =)r anQT-O |Zj5sd3! w4 д$ɏc h+c, 8=^0vV B2$?[JBhPe`IENDB`qnetload-1.3.6/src/icons/control-pause.png000066400000000000000000000025331451037126700205440ustar00rootroot00000000000000PNG  IHDR7 zTXtRaw profile type exifx͗[( EEIp0z=>8@nTu}!k -;4D8\r3hǣ'뼱KxћC%q۴s@pSM(Oh;>3yHyoݗǙ'v:޻dT?aMH,q"3ta>O ;KtɝS/0Oԓ^+5oȔ7֣ Ra-Tl - U<ЊDlwrT)SvʨWn3d|N\x4$I5@;:M|"fK&8#xk;QD6\!.U0qP93g3_~+ g#0Pz֖vjANHVC֓(y9!|2"gq|r%FVƘ@-+?ZBK$SOp5UU4j;4B )(E>c9qla| &ŔRΘ4u >pG<ґ ʧŗPbI%WRXS͍JͷbK-wZvC=MBhRiԠa`b Fr&ƢP5@5b=QK93MrܾVFX#V:66e`?W/GRiS[eC-V {32e^fTئiN}8"nZ7KUV1Iup~RrX*qJ.Uki:~=6Sǝ$Xlizr5#oWlx$k ݧZ7&,q-AK׈-DdU-KŸ?$[oA)rUK퐈oBn/cC~TZ؞?-%.1rX56] /o{15C ˞c״vϽ<Ĭ56({ak-]s?Ƕ57׎߭/Er ()|L_SrbKGD̿ pHYs.#.#x?vtIME4_)IDAT(ϥ1N@FoUpH9 (Rn;HD86 ATOo~vBxJV࡛=ebAhE ^BVJωzFkuPR .F 4{%\ 7Mh wqxr-'Btf2:]EV=)IENDB`qnetload-1.3.6/src/icons/main-icon.png000066400000000000000000001701731451037126700176310ustar00rootroot00000000000000PNG  IHDR0=gAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME ''bJIDATxw|?I-BeuD"_DTAd/Al2:{=n{{g|VAB!7999s0p=722222222׋,P7ҥ @HD2222222#AYY2:LqqqJBF緔-hDUUazSYQV!o/s2(BEBlWYY:WFFFFF_qww90 aY,膷hڣa,ĘL&aX,݆22222221l6NB8Zfj5#(**bpH7aFaQ0 #ۿ dVKXJŒ3 999 bnDaF???ct:C#, cXlsZfT*nO? d#T*(JT*I]]1 C,((###bWa ]=V'`YFQdY,K (baaum'Uan)**b !, ByaeYaFEeYGӔ gД$a EQ$eYa^R&xzzbTT!-^H2jX,ܵkU,*!!caA 2z಑k3 C$ `F HX, 0fj///g!ӪwRkZ&88lmm-ò,k0%!D)Dz,Ka% !uİ,=0qm; 0Hh@keYb!Y52 c!XT*o6lے(*Q5(:3)##a2**㔢(*EQA`DV VqÍHG.]2 FFR1fQ( i+IifO.C͘!##Ao @uuu0LRRF#z~d䚍 @yM`axgT*c2h4ߟ' z#f0LLEE 8/ ð׌s9*xX0 m Pb̰&B!/(( * ŤI#`֭8uTyÜ9spq޽4ovȴQ%aakgg\˛Zr 'O&ﷹG#Fru&PnaRYKL?EZEN 7 1`$Ke Mݚ1ϑ~S*x+V 8N=+SE, (J:=1B$yB `&" l ;)tk@a8ca% PrP5 m@d< ##s3ի^( $&&bСѿ̘1pss"""A憻 {8wΟ?{zBٳqD899;aPt:L2~;PWW3g 66(ba2PVVF) 022 0, CתjT*@RAѠfZ󖕄Xr&5]mVEQ*4B`, M '",/$k#F)Q&(~edBdz>@$''c„ ۷/nnn2d@t(//SO=#..x0 Z-s)//GEEVeY̘1ӧOGNNAc=gggl߾jƠAн{whZ矇RRRRI9Lq^{5tsdd$֯_/uk1uTL<7oFPPe˖Fj5fET2<Ӝ&ؚ&다$kE& fσ!ƒk[H߯axbt z… bРAXh, f3, xGtt4{?~< pwwGqF 6 XnRSS#sqqAP]]/+Vp1o jkkѻwo@R{8p֮])S7ހ 222- l+4 fs(HIIq0{lBV bsb}0` 4ǁy# Kc,O>ADDQaggAh4h4ObСt<<<ꫯ"..TafYc|=m`$$)*TaTUU!++ (bHKKjQPPT0 p //^ggϞ0jGRRL&~g>}yyyACddqwW(-n[hC6[ftt4.\R8DGGCP4֞H17Ix$-YE)$0t " a료Ma "" M/@_ ^TTy a(J(UJT`\z8Cl:rsuu5еkW0 AJii)jjj899Aj6+_<ֹz2JSr{¦֒٠ R&ii]u9Ib;hBэ0 Z-;AR cǎGaa!~̙3&KHHի'矇Geedd`|2PYY̙3pwwdz>c6XEaa!~WĀ;O?4˗#!!zf+##ӘZ3':\Od0`%0,pr€>=UuEj4-աSNE:f( R A`0aXhO,ˢ_|Ν;ZMݻc…ݻw &&OO@ł7bΝycǎa:ر֭SO=g}iTxOMy8p۶mqxgp]waڵ @ee%wg}ÇoVy7o֭[3{?p̛7Xn 0x`  6hj~9FZJeB 4 u.]ŋϷiiOSRAR;:ߥqf6lի{n|wjm "##h"W^ř3g "J%h4^ҳJmEz) ˲ؾ};~GBRh]Y7)= Inшsիx"233i/qAt:ؾ}{f ==gϞEJJ bcca2W۱j*@RR-[f0˗:/шDhZvvv7222/(EAQ 8c4J"oJcF %"h+"UUUldJ%DQJs2R"Q'''8;;#''PpqqqPT6k0P8w.]*T*\-]0 :w^z!--Fh/,"-- =իWa0 WWWh45죏>Bvv6RRRG!>>\t P Œ%K|-"Ǐ#77'N@LL PPP/زe VXq]^˄zh47 L޽䄌 zTg pƍ7n B;׎;} ؔqǏ#-- ;!81m4< (//Gzz:ЫW/<6mڄsax*W/|hD-[= N .>~ .i4QQQ www8;;bj%󁶌 ,^E#;; ƍ^ǎ;p8;;gΜʕ+ѹs뛜?[eY!22/-Zd(Xz59KmCAzz:н{wZ{Fmm-QPPxzz&nݺd2'lrC# Q...^g ٻ\S1M_ٳ'JKKqA9s3f̀dB^Zo߾Xl4 o"<<{/X~m/@ff&`XPSS (M[L0?88pyX``L<3f?3g8B0dX3gpweYp|w^; W^yزe ~ 'No#F`طo~a֭CAA-Zd#z:ڪԵ ߃^(HIIɓ'!|W"-- 6Z:8q뮻~,P(#,, ,22Ҙ7 Z06`a47 !- L& K.]`ggN:rssTUUo2~z-[3g޽{G~ʕ+rJ|۷/4 A<P*ؽ{7֮]5[5شi5 9RD=PVVd:t,bժU}6/%%[nEQQMf)Mb̘1֭J%\]]BAf`2Ʉ7b[\ܹ3FbtԉLQѩS'PհoBмѿ'ZƋ/jP2l̙3p$$$`ȑE#FG}nͦj<@TTߏ}<<<{A022n6T([,L(E~ )T닞={saP^^"tP[[ OOO:88PͶ^GXXN:V*VwDGGk׮^ٳg>}O>233;`ǎxlpa0l0p-[0h ̜9111 ŤIZ5`FZT,^R{n=\[CHݻw#={Dtt4f38s4Xz5bcc[ooMt߆z s~W,˶9`˲|\x:Ȳ,uoQ^^7|jo&UZwiJT2${7ѳgOZw8q6xd]6˲T@qqqj5n>|NNNpttFwu5~?P!bԩSҥKqUL:T B`` R+.mۆ_;wF@@83vBt222m@1 oyk`60JNNN(--FAVVDQ34F+U[rۖjApe|75j^~e\pW,k1Rf?nEGG#..1={DnݐF=JEQ` $Ƞv:R`20vXL0O:4h:w0tK8dff?3?Q)))HLLhDAAN<^z! ={Į]`41cޞ:.\Oп<#77gϞE>}___ȑ#HJJb3zۇ~ 3fka3gΠo߾CBBT*xt8<#k_dd"!EεX,8ޭlEɁ#2^VRK.h4 y 7\wOOOضmQQQ>}Ņz"uuu>|8q(,,DXX:uݻCT6;ĝwމ0 <#x'SO!-- ѣ!CЏoШ vލG}cƌ/+,Xggg+ݷa9(=-Z sxLΝ;ݻwǬYhz{{cʔ)?p1Cx{{/隐l<~G<ڵ+vOO&h4˲8:: _~%JJJ,7x5U!ӦMCxx8֭[a`ĉTc~yL&Gw"ѱ~*DQAAAM e L`wȐ!fX899f3 T,˪ !,:fߔx_}DQVťKݻʕ+Jyy9^ZcԨQ0 r jjjеkW +W`41p@ʕ+0`a6\xyy_~6ϭ :dddtAAAtK<`0[nQ]]+W`0k׮B@@JDGG#00=zhIu:^J}G GGGTVV")) Pҥ ipB4PMM bccT* R3F\x6뇀z\zUUU@^yÐ!CBLGQAAP %%h4ݻ7U*>}a")) UUUN:!((vvvjHMMEyy9Xuݨed|)47|]4()D>?PP 0n0 ?&}aR4qOpttrssQPPL&BZ 777vmEvv6:u||=x`8;wIj)ސ!C닜@9˨J¸qV?UDDuFy8[ntk򊋋aпx{{CfNNN WEJǣ[n0HNN ۷/0o<AAA+bQ,EQ4 `U*P[[+T*ҫW/1**H@ 0ҾB'am!"U Z y„tiOQZ,,7åԨ Xc]_Ala]_Z T36l~ReM*>Ԧ 3HVRȺ Z]Zj㆙˥kjﶥvb"]GPz8\Jx"h.'5cV ?$&8b4\Ry*J8::8L&qzi꡹ .YeF6MR=ΟmnkK[ʳZOva>Z뉵K}g,7((kL 0̑bԂڜ /Lk%F[߆mTMKKuֵ򮧜w\o}~2OAF9qs:cz`Y*dzJ^NJmIDVllFۣSNm:mTԜ\y홻m 9F֞!`I"##!X{ٳ'Nnrl[b\_Lɗ4HZ]֦crHю{QXX{>>>6[2Hж.mGLdunbÆ HJJ2KBa8NK[`mBh-=چkK}I-=ƴDvhRk,_m'xXaKj?1붵=U||֢gϞ _b00DDDGy>Ihh;vÇi шcΝ43<=XE~~>"""R`0P^^ɓ'7qA8::'O~5رcRRR0b߿[n7!زe ;;;9riBEa5gKI b8p`b`޽Pׯ&"8o^^^xc͚5(++C@@̙jaχ ?PXX#==۶mF?M R#F@vv66mڄ#88{˲ҥ N:'Obʕ>|8u!ݲe T*zv[a J԰WFFF-FHO8hF*ݻqyݻǏIhZ]V#F p `'ZxǤIp!|HKKR=%hʔ)֭G֭[qA4,<`Ĉڵ+hs=Oߦl6CTT.\@Iӱc;v sANNΞ=$Ґ GGG?ɓshdee?Mݻwc8s #G=9fСC1k,899Q)!!탛6̠A|r;MEXh?? QUU^z᫯ӧvZ4-wR ٌ$\|vvv]- f̘#G`Ÿ|2 "zٳg_poN]SFFKi`d;wıcPSS?~;w .DQ[[KS`YX~=8/Lg˲8rO/P@hooBAg5"QĨ(TWWcҤIP(={ fgO?ݤq^z.H* wqrrrhжRVa2pUBpwavvv4 TKHQj5<ݻ7 \ %LO)ѯ_?d.!! .Dff&舕+Wӧ?W_}Mu8 FsQf ޽{ԮR~#Gd2 ,;whyPH9zꅈnkUTr#m!pj5}Q222t#"ݱh"?ldÆ Ä "$$w7ߡT*O4MSeYcΝC5!4ɕc޽iӦjĪT*qQL82e ƎK=Ʉ={`Ȑ!۷/!(,,DHH_Z\ !Euu5zm|F2%NDDƌ]I6;{EN0nܸVӣ١[n mFI|Pը+BS3 LDGGc޼y=FEE!%%*NDxtvv?BCCQUUuݩAHHb ܹ7bTWW{pqqLmJKK1sL$''[nxT*[8C=pYj 2FV*صknf̘aÆ(",, yr122n:3FJJ°aп8;;Ӊ[}GղDQӧQq9<8lӫWFXX͛^^^F>}dL<Ԧ {Fhh(V\˗/ѱٯDjhڬjK㑞SlTVV/DNN,XnݺEC޽1tFҫW/1nnnyxÇ`GpppӨ PUUu]ds{n( dff"%%uuuNNҶf/^X:] @ee%\Ҫ!"|}}1` >-~ԩѳgO>e~Lm"##zXDN ÁK7?>z- Fvv6y|0ظq# mۆ[⥗^?b ~_~ @bȑ#޽; @;u{χbewх!bi[RYTf 9B5I0wywuWsQ1x`,_w_^~eY/"##vMII N:I&ˋ9r$>3̘1?>N8aSɨ-a ٳx*/4ٙud׶pBرwy'֬Yb[lܸ~~~Xz5 CکS'xm<AĉO?aٲe(//Ça0ooo|8%ޣFBΝ^YY|bba?~ `ԩ6AѵkWk3gX˗m<Ҥ-%kXlOOOCEErrr4[uuu 6yXţ> X,v_ga60 Xh?`޽x7mCYB7|tRI@8::ɓ4#G@#<+W8)J?~wy'jjj`ooСC4˲ˑ ZR<T:w/bذa>gƩS< pq|x0 qqL4&cǎ 4 t8rJJJfj$=w\-ޗn`/ҥKQ[[}"888z(&OL=Фw+V@PfԖڰYYY2dJj+dP(cj* 9VZBƏ˖-q]?NXEaa!.\GGG<ٳgxb13g%h-JǃRPhZҾobѥK@AAiqhl{0___̘1fnݺAP777+t^upfNI EXp!n6w ooo-[scCѠO>9r$JKK3fLJ~HNN`/&L#ԩSxg`gg{{{<#1b- L {A1h *BгgO{0aM|#F٧Yȑ#[\W_}]v pvvO? ///t -ruuѻwo߿6mMkBy桠 ào߾3f V,Xn9kcN=DQĴiЫW/&L`&jcӧO>Xl AA@@F ?~)ˡP(лwo5u];w3g87 ӦMCUUtyQ{;;;Æ cj8F}`ggJ##O8̟?GnPPJHE-˲zQM xJ%֊*K"qqq>WYfh*eKKséƧ)!zBI&f647Ҧ S7|7MQB^S7nO__V=yT*|Mٹ ۣTmͥog]7i$7ǥ`Y* x& :u3C`g}˗/j\.]«Rz#''i"F;wHMMEii)bcc\h%%%HNNnӹzkƷ~ .PlݺG{_X5&&7:2- 0V|ٯ4RUVɓ iVkc&UfZoӞ/_FbbZFmm-8BVeƖ-[6&===gOBlR]]j樭E]]]?ÿ㐐1cɓ7:2- 0Vl߾77LJJ x4(b`ݺu7oތ j!^[[M6۶m^o$ԄȞj7Hnn.^|Ee _o'8رc6\eY]˗/q?(WsHnѭMܨAEEbcc6_lM!E-++Cjj*l P(f 8ddd`ݺu n̂ 33EEEX,DII QUU8;;g=rՔHTWW#::ˑ8<._rw\ZZ80 PH& !zMDZ6m- 㐘8dggŋmRDnn.QYYh[ R4Q\\˗/d2l$%%t:PUU@OOff&.^H3'&&BTT*QXXd񒚚6^Ow$999x"XSRyHڲFJ999 BM6!::Fj4IH@ff& ##Cn?PQQ`8CVV6lpK,7عs'`2裏eYL0NJNNFEEV\ ϟgo,TUUaΝx"AlFxx8!***PZZ͛7#'';wDdd$M.7nRy@ݻLkRRRaիWq)z(8tE=y$ƌI`RKB"""PQQ|,p8DDDesI!8s AիQTTBPXXBrlܸ͛P(Q[[ ԽҥKJ[Zt>~VߋbANNl)))IIKKÑ#Glʓ``͛lK.APoqQpMg ==FXneYdeeuH0;)3df֬YIcǎUN>]=yd1c87s„ ~ƍ5a„acƌ3^#gjkky?Od͚5z[6.X8qf?ٰaѣ@\\\͛oMfϞM֯_Ox b6C=DF#y7 !̝;L>L:ŴiӚ,̙3eYBrrr!<#yWyk֬@J% y#ݔqqqai&zL"brJ <-w^0 ٱc&HHH}ڴi6}nĈB|Aү_?|eYvZzx~!hѢ6YՒzz{Wi=W\I9sL}hH/ኊ ۃ*X,TVVl6C6kn:Qo9aem򲈢:( TTT@V{IJ#>L+Vo.04 !ĦJc)L5 z#bf^S(MwIS\\x8X*--qjJkjjldDQDYY-%%%4QIIIjZ0P((++kӖMU(LXkRI moYXX`q`A@߾}1wܛ7LQQVZd.777̝;YYYtdĉ3g&Mɓ5ƅ ʕ+;wV x뭷 Nٳg_sTVV⧟~j4!jL>.]BEE |6l:b~&M? ZYfaǎػw/`;w.֮]Hϲ,~i <@җ_~cBARa޼yM!K.kOOϿָx"~a8<߿{Mȑ#ży-$ᅦbދcǎAY]]G\[oRI˦N^x#GGK]Z"** uuu3gDQD||<Ǝݻwslkf͂'ϟG؞,?|:44VFY5*),,ĩSн{fɄ0{ؼy3^<#7H߮{Z7M ;e#33þKKKrCcYyyyjW}$?;WϟMs鈢[vkի'_AFFF.U[.¿WJ[n_]4e˖2S* u$ω[p:S[[/ B(NBbb G\fMZߞU׿ԶL 裏%Tl+Z|Id#ӒV]]}$׷Z7_Ҝ"!"vt~TxDze˰w^L4 YYY7tgϢC†Q(p֭[סA:MyAH2/d&"nXui6URa˖-?ǼyZu#<@Ի7'0 ԿMP(e$''Cݔ/CA#]HMMe$'ODYYY۾ 11M[NF-c6q6SPO>iIRRR ̟? b8:tҎ}q6ۣ\OFzaٲe7oIa믿F^^^#F xv]ͥ<9ٳg;+P/wժ__D/^z%jՑuhϽlقmrfW\Addd4c:~i>O3(8&ͶGJ2d4l63NNNl 8˲jQYuX,?tׯ_RYB]EQlWG"77ߝ1}t1d:..:u/!`(//G>}ѣG0|2F 4ΝèQhCaذa .& f3A08pХKlW^ ¥KЩS'bڴiaɓݺu(0͈q4M{ ^^^ f=z4bcca41eҥKr}燋/ SN`h^zT*zʔ)All, a0 P^^NciFtttaP dJIIALL 8;;Bǀ4.222`2еkW\|FjyyyaɴJ}aiii½K˾@Se4նQQQѣ<<<͖8HJJBΝ1asBBB@ mf3O9f&;;.rssꫯ0 ÓO> .9zhf#==(**Byy9 =zoMobΜ9֭!@EEzI's"88=ݺuW_;ѣ!A/m۶K.{.hR*Ba^{ W\'|Q`5E K,+qXdMT*]qqq?>zꅺ:̝;/J%v܉ L>+Vn|޽;/_T aq, j56mڄHL<3f̠žg-Xnݺ B( {x0p@q[\\ ł.]@P?FRR@mm-P\\^z0iiiOaoo=zP*55:uz 4J%݋ӧO?#!0LD>}T*[wߥ<#55}bRu$a…8tP.{{{t/{tF1n˷Q(ХK8::cnnnP򲉍ggg]t*Z7770 899vvvҥ 쨭uNNN8~~~pqqxzz~~~`Y>˲h+FRݽmq<<>> iMdd$&'"J%#:u_| DN;885ԩSӓNWjW*t\KV OOO8::bժUX`~W;:u <<3}PsQ{6[_aaa(--%ggguR 777|Dk@UUN8a^> /@mrrΝ;oкbÆ ؼy3<^z  aڵشiS? )i{E ~tFت{/]PYY F.n[p àvjVٺu+^J]]]or JʗށuBhp89s@SźرH`СC4uP2eqdeeє %%%~<֬YCmL$5֭[uaaax%~i,l\>IW?Fb7PW*iyeeeիiɤ.\Hst:̛7I#^Ozsssxbڶ=OMM }'ͽ9??Iy̛7F0j h3ƛCkTUUɍ"jfJKK[Lz+q 0 Mi %3vy-/E.!{YԴ+lƇ~Ʉ~.]jt0ӧL:F`֭8z(f9rػw/{{{9ro&***bd"66F m0j*?p~gj[XX2_|$TWW7]]BBBˣ0L iAɦbɒ%mjD\tm &&tQ9zudR/ ,^GEEE#UhIAh2:q|2~!BN:ei~,kۇC">7ΤPP(pIl޼8s ~fcHS!?!!-2hf[EE7;&~}_|qqqtLT 6 Zɸ8?~Nxҗŋq)~ӱn:$ѯ{ͥ D/^޽{1~xNi`EVصk>q#8qht/iWUU믿nr.F:z(4 a‹ Xr%(\M&V\b믿B, /˸۩3 x%DDD@qq18f,vZz`ŋQSS???`0`ӦM4555W^EJJ   Yř3gǎ4^!;Կjkk3:t 11SLƍQXXHKvl:zj4m0PWWoO><(EDxkNuuuCVZwz=X&bjT*ƍQTTNF4̝;}zAxY T*.\Lߟkע{ܹ3ꫯgϞ:t(f38úup]wsT믿gd زe ^zx7AZƾ}0l0x{{~ ̄SN8x ;v  b鐰rӳkPPݳDvv6 L χ'U{{yyÃfWիU;88PkpBaYIIIptt'.\bk㮻Bbb"F?~>>6_~vvvY- Tnݺŋ6תT*J}~Z"--.@;nuu5;l0DGG>ߵkW5Kj̘1F~~>zc1c 55Gw}A\\***'R8p PYY e8n 8׭:t(`ggQFϣ[n2dJJJˆ#h6hggg$''f,6 PHO>6o 88.]SNHKΝ;lGKcÇR l0p@;wGF^^iԩ1l0DFFs ٳg!"j5mYDj5'OPP "`^^^ׯΞ= {{{06'ƏXxxxѣGQ|=PYYI]%g<F >>>>1~xx{{CEƏx{{]xpx*@.] "A`0PSS#))G~~>*++[?=<}zcƌq7n ƍk„ ƌsgάYb!fǓHb6` uuu&h4@L&]c67|k_~!g&:x"__M!$--L8nYV^MLvۛl޼>HmF'|___.lB9SN%FL8N y衇ZW_}EFlyl r!r²u̓>H:wLxb6 d׮]%o_ٳgs~r2sL2sLҭ[7zjs8#7o&wM/^~cǎ%+VhN?01byGZ|v777OaƍyɴiرcҥK#ٲe Q*ŅرvdžOo>2gΜF9x`W_׏<㤼Ȓ%K!ݻ|Ο !Hx' 9w1d2K.^z̛7={$$$9r[SSuso_0 pY;wK[ $j6響vkR͛QZZJϗRT4@Ti\KHmhT*QXX}Aswdjڦ,M-Wa9I:G96IKuRlƾjj霎Xuaj[A!:t(bccQ\\hСC3g6l؀#Gxw^ܱchXuIE'p̞=% xlnb5ڬL&TWWSUŋ>,^{5s׬YӧOiuiQK=<{%+..… [SݰLV[o5meY={v"'-^gX:ģeYO>ir͙3uuu~Дyh4"%%YCq)%KZͿe2h4v 0* ļy`4mBGDDPIO!11ѦaEQ ֍(e{$_QQѨT*֬Y`Xܢ@xxxn;EVV>cڦlvvvrZ*sz;'i˲tDo4f%!!l !4Wњjaa!0jNЊWUUbז6PeYEEES4 KG!fy2==քOaz9,]ݍAUUΟ?RsB6n܈~]me0;Pd2hZSQQQv-wш&ETÞ={Z-KޣѬ1tP>|ITE[HMMm;w'NU:4[z7ٸq#222R{nDDDP j]ǪUzU(8uTQ*B5kbq^={-Wn sks#HTbϞ=HIIjjjO?QBѣGozj믿o}EQp&u4ȕ8a׮]gϞ늇%m۶5u?ul)J **w#55xCmem^# t~CUU;xX,Xv-N:SNA ** t[HJ",qQXXh(< ۣ9[u`Yعsgc6Q^^ .Ut:9s*//G\\a6H% 56_j3gh4 Fll#B#kPWWf_~iii)!%%%j4^NCuu-I] [FE^xlj'Z\0! "ͽB ib9#?DQDYY._4pV&-pddApp{m4;o^IDATnHEo3DQQuk$mun=%MHHrrrޢP?N<$$&&BT"--F%o )NLLMӧO7|JZz(,ˢgϞ>ʍZ QՌ ,,˲0 Ba(NflJW_} ooo@Tȑ#tk_5t:|}}qQ|wHOO7ȩcF }U૯3Ξ= P_{\t zo fu$q%-!&<Μ9ÇˋEOիWqYPPL999-wW^ju#78!::"gggTWWSUvhbP')Q^|||ezyy!55=sΦ7#4 ~mHmyˣ R¿BBիHMMm2gA777dffbƍEHLLDdd$RRRKR111 CBBl58y$mò2])))4+ŋ eXDDDvvvCFFFpqqq駟o>ڼpqqAYYʐ[PTFTT***~zp '''$$$ܹs8w wi!)) ]vETTqUjt:h=<<s#BBT*El&푂~5VFAR!C+#MR Bh"nd2.,6Hq0LR= kꮹɁyLFjkki:)34D@۩ii z1&ﲩfu.h_۝,N ٖ'QWWg[ HA-n/-O4^Qqhu`D)XlFmm- xL7|M!PUUUy޿0 yzEBh55%ΦޟTbAEE] %0zeee44Ի FyfeY(m恊 t:tq4Jzt^8{5jڴi߿?͛g{`ڴi4;(cر{ڨnv~͖wR t0[uyw}7ܑ<#xGƍ96euҤI6;@׮]GF;nL:2j{{{{׽eׯ_? *o{c %%C$fsmƭ) i4Gzzz$˗/ݼOn2HkO"''2w4Tsu~nd1 .7S$&&R(^dffQؖWPPt:NBTT d|8}jxOLLDTTTO#558w Dg2\f ;;X,Cyy9jjjIۭ(BRR=&eЮEee%Μ9ӧOSodS^II "Ν; BK7F!eѣG{СCix Vݻwq#stt?ѯ_?///#uVm6.aEPPPY@VsܹIw[n4fGT*x^:ngC/ѵkVNҫW/۷]mF.IݩS'z^[)FƟZnG5H^h4yDq;3[4)"*쉕Xcbz3մ77v&fMnz-7bEA@Mw:38緻c29sΜ<U'NNNɺp7...pssL&3#ÍnMǟ>rHNO߰aDR)BCCD#GH$:t( [[[xyytiFƻ5 pL8xpIRRބ OOO4 6 :_F2/6r %b1c 44f2jÇc 3\:tP= ˛0a 7L2SL1ƎkYPPǏV   ? &;9d2z- 6\4\ĸq]LKdd$M/7j,^ߓ=z4zCGd~Ky}6660aBa7ng4M#<QQQ[0|pʨ~Xhgx %ϰ~#\(A*b„ =z4 J www <cǎ0 ir- % Xp!0yd =z4,X///i̛7cǎEPPЀע M(tM(t;D"!AXDLW)d2r $ accC2JKRYdkk NFC t% rѽ ½z=r9R)yRyfkkM3/_דIRd29TxVVVfӣkZHRb-JI[\4X%~ %O8QV%D{tNs:m\n'h`NQlllzm۰c\(';aڶXʵO>җ8h&kdM`Y\#Իc \N+Ahs Dz,Zh:t:p-4|E#@Ւ5QxaHlllH] nd( @.82ޅuTp5,Olll@Qb} q`BCC1i$իViV˨T* 0243go8;;PTpqqAee%T*(+FvvviR:Z'#K(͍yƆ\tXCR ---en /@yF@ί0{ڢqqqAkk+4 \\\HvSzǁiARNNNPThnnEQiLL=acS}M:Np^MFUWl% xVp( hhh 4MAcX>0dB8,˂i899}@`mm fT>)IJ{g8zppp@mm-8xj5,ă0~Ȑ!$;n4Mw<nnn o~W̵YP(,-5@t̫j=/J^014aؿpWKsF~+Hׯǒ%K:i7L;߆H$8~86o a3̝;z+*++ꫯܹs:R¿:t(TTT_T*5z=͛7|hQybcc1encZqؾ};H, Yt0b̞=xqe裏>+Nx Lxk׮EKK ^uUPX`xѣG'^\.ɓ?`:t(Z-kbѢEF 6m“O>"MK.aƍ]Azz:^z%{Ŕ)SP(j4hq<35[WDx^h8CHH̙&8r8Cdd$>cXF(W^رc_`޽rJ,\k֬-Q.Y֭3qQ8q|Əo1SM]WNfs#ۓ,ͽ̽{T-}gnnb sX>OOmN/j+1.))A^^666"??mmmh4(,,DEEXEqq1233ldeei&g=AC\\Ο?~NNN Mӈƕ+Wzj |{.;^ݻQYY{~;>$xxxѣѣGNu7)BCC>s444`˲pww}v455&h <g&AEErrrpU4661k,={=>Bzq=n vÇ~ ׮]t:.]sOPd2 66=֮],#Xw|AX~!4sΡ SN%:::"((ǂ JQ]] +++DFF"<<C AJJJ6$,"!!XlVX:@&aܸq$Rk oon_N>g}Fv5(Ә?>,bccrJ}Xb>3r}6mB||<=JKGPPƍGT!!!Xf w=j,yӧt:f͚{/ߏ1cWV>BL2ax1m4 1hFrr2JKKaDc޼y_qUb_Gv܉ 0 cA{ꩧp#//=֯_z#A?G'K/!!!=n݊Tr$% z'N-&O \Nbm݆G}4M Xv-nzq_|111Xv-N8ӧOȀ0" ^4TVV"77dimmmhhh0ܪCpݲe 8bE1114iFE~R b# !ٺ@QQ^^nv"d vAg֭[qFرcf!84hۡT*2OOOL4J%ñi&CP $$Bjnnƶm۰m6fرĽ9116l8.\R 4M#22K.E{{;K47B,kkkd2 JG%LEY6l-[xbǣQc)J$''CPhll$>IIIFBLkk+N<1c`}||/_Fzz:HvƑNw8ADDDĀP'"""6mΝ;QYY˗#G>St| |WҥKqwi?Ghh(-Z#AyƢ >>xlݺ=#p* 444(̟?<cYرcƴiHܓl{5 , {K(ThJ@mm-~mxyy ضm{9GQPPv qR)QTT0iFSS8Sje<󰲲N#PoVc̘1prrK/:7!rd2"jdggeڤR).\>k׮E\\\\\L^ w\\\_;sD"qƺiEQ=~o}666JKKq b̘1ptt4\!ؾݬ󈎎-TÇ0 ZZZ@QT(R(0G}tӾhN#114Mǁy|pqqA||< VFDss3 0yd2IP[[Ǐ}^\\ 8piZ[[qapŋcP*Fqq1BCCQ^^NSBףa$[ s= L2>,ٸ# 22׿?w>xJXL8۷o7ǎB'"##CՂeYHR+!)))>㣏>?ӧO#22_5V 99JX~=BBB׮]ҥKq]wXz8vF1c/ԩSpuuŊ+ SO h| 퍭[Bdo9x N>UV!++ /fϞ ;w.Z-pExzzbdŒǾ}ꫯ/^"hٳ1gѣGzgV(xGeʕ+#11\b dff⡇>@K/;v?ؼysmVyfh>=Jš5k?CT?4`Y:[lAuu5aiooصk6}AJJJ ;Yw^%Pf5;]ٴc׮]7 Ұ,Xכ63ִ[667zۿ?vI{ܹs]jD(2oţh/qIW@06gN4]?-zyrr2mfY_瑿 |(GEF8 Y-PTUU!//Gmf8&&[nL&#f5I}AV#??/2jkkO^SdBOsa֭F- ct͆ pUիWa+Wt*^eW_a˖-믿FLLL_RRbü|2.$%%*++q57HMM5_;==]zQVŋ/Hڤׯ7ڵkP(8s k477W^49t:{_gϞ>677#&&uuu`彎ӫv֭8sg2 };֣z̙3!1Y'NΝ;-ڹmذ7mmmF/=hll4;N Ԇ q$(RJ]2Z-a)**"RWWWZAF(RIڏ?nah4F6M!n@GXzu'zѰCFCXB8+ܰaM.'zlܸ,JΝCyy9 cGw,wy={6oC&!::uuu8x`mm aZAV#66֢V{n˗qFRUUUػw/j栽{1jjyem6Ԡĭ1T*s?#(µkאT eA4R0tP6GIIIX~=~7,[ gΜAYYN8A\[[[Vo.]BRR,T*qFŋd 8pRSSQSS˗(BTbڴi`Ya߾}X`@4PQQNG3dכݹ_v o;.\?hP]]\xo}Zm'MեKСCZW_}777jn* s90(,,O?9r$N:j4dee᭷2eGE`` Z g"`|x"N>>%%%8x ǎ^'8r|+W4j>{,"""0}t4s.]PSS`8|0l\b#DB,X'N444UD"Axx8믿bpuuśolaժUP*F)Sp1;uvvFDDhNûヒ(@~CLL }]0 DR4 apy9cǎũS~ЀgW^AAAiӦ! iii8tz!HRDFFb˖-ǣ> tǏGtt4>3rdeeǚ5k@P( Ɉ(>0h >^RD||<&NH:C֭[aee^z 4Mחwa,YĬVޞrNNNi!DDDŅ2dL!;;Ćlܸqꫯ OOOy9sy={MMMݎ#FD899uswwԩShH|B8qAAAJ¹s0ydd2H$!!!ĉyf@eGX1|v!+H9±3F(#Ji BbhhFPP͛GT?34  \.ٳg_bذapvvF@@Ǐc֭=H<كK߬ҨQ 777XYY 3f͂?T*v؁#Gb„ :O0{l`…0w\P2d.\={[nQFii)gyy9y79r$8wwwb:VVVرcXp!~̙39rQ9t-Caڴi #Cmm-Fجfee/X%ZVsH$2_ `\SNECC 22͛7Ylmmގ+Ww t%zjxyygȑ#hnnFss3o4]*>hFkk+q/muJj رcfW,ѣD=wߙu8m7p촯"%%Wy_|Ÿ78|0[$''3gZ J oĞ={[o677#;;/^ġC{\.GrrrnE!..}ۑi6gII 6mDvz}ڴo?ŋ? t:wz466BHq!<7t LG}D'-- IIIhii1|pqr9qi4MÉ'Hlt$''C"@"/$n}Eբ#GH'x4]x* FQSSpa˥v2Dvv66md{[=qc8,-- ׮]#htt4Z8L 4MΈi:ui~z MQQ.\` FgϞNÑ#G<9zbhԏzq٘6i̙8rFaFΜ9cƻaa>3-OMiRѓ'OqNqqq9n M1LlRRR+++={qZ_PشiWc.qE;wD3Sjj*{}4ɸTFj+ dgg#''ȵiȑ#(//6*^75#s_*"::Wn+eQXXef͚?k/z4 ^SN}']kKKKB,Cjjj=@Ǽ^\\LfTUUuP*ľS@Z+((0:h4XzuN# 7''S#544Z("+?qqqվѣGqĉ:("Hd:hp1$''#++q O\Fe{#i4DGGoݥvLPZAy^:A!lEE6oތ[v5(㝞@4bbbCVwtƍ{'p̙N*޿:wzpg6@KK x <͛7ɓψj\_mll,jΜ9=i$P__oVC!<%%%F;iJRRq)޽zѮIq !˲ظqcۘ[EaӦMHqI/pzz:ncc_Kׯ7zȑ#f]?Sdeek6ܹ/^r{n8qR:e9r[Ν;oG zknov8:::(0rlivjEEE_:;;{ FW^J"V<#66xe.2P Y% Acc#]`ccC"xzyy `رP*HMMŨQZ J4̘1P SgffDBBB4,hhh@XXrss OOO̝;E1cagg\z8::-!!!hii3i%K O-.] \Z_ǏG]]ݝ,L:D??^x0&O82FMriӦܹsDMDB4cԋ/_~wд<,\gϞN<EEEMӘ4i._l+ !͛Gz;L0׮]#nVXۦO˗/cPfs:M6 طo#0i$B@.c…(..T3<<>>hmmE||<'N$#,, `Ȑ!d8v(m݆8F̙3P(Err2NJD___444@{EhhhsY|2 GHHpFGGGrbW'J1|ph4:u QQQ^'aTThFUU;S ӧOGll,B(#22#F\.Dž PVV˗C*BP`߾}0a H;VVVh4طo0qDh4 99˗/#4 >#((W^qmёhҬɚWZZSNapss#?舌 DFFHHH3QF=+ɪ8ky^ɲy-=7zh38B~j`hFQQqF,Zn:+;v, f¬Ywy̓=L0>("""?AAA8y$qmGAtt4 rJ۰CDDn:9s cIo_{C='fjj*1fƺupwpQ9sf˖-"""dŋc޼y]>EXx5 ;3C[2 EQ;`cc)Su: deeZx:т 0gxxx 4+VOKxyy^CPPn6DFFW_=BCC1fyeEᮻEQ[Rkx1a,^=z40g0 Kb?Eaܹxg0x XSNr9/^<;֭CXXN n:<0a&O|Xbn6l _֭Xd ꫯ" d<䓠( gFkk+^z%R㥗^믿~3f̀B37t(xKRO?4t:aggСCYYYw0 sa it#y/@0R:88N"--G;;;(c Æ 3GgVr\edd@VĢ7Hjj*.]ԥ9;ٱQAVٹA,Z[[3g#Bt឴ OOOƂyr <27b2f888 )) ~!4 زB@@ɜIQXpO>hkkèQ@QÆ -cĈ9r$ wwwZ ;;;PLݻwc0hiiFRF d()) 7zhRz RMMMMprr"H$hoo)1o9+cРA\.'kAT*Q]]{ 0سg!ɰo>\p?1l[f 9B\!=s H$9s.\0[?o_Rpa ''ѝ jR);FTAt)x'ᡇ"6-NT555غu+q54ȑȟZg}ko+DC-mmmرcyNֈ@]]1μKo%F2}JetہyܹWQ7Rݻע-˲ؾ}{ղ?(HR:u .]N8ϣZ,?'SDt<D>|0RSS977?Y\ ;wqFt@B` F?Wp(iii$]z0 .\xr\t N"ݻe@B cSۡGv 3l_!lDW|ݶpj{4m4WR84<"kiiAJJEwiCg|{%t:!Ek!OUUUmd켼<Z*=F8(#66v+0 ]FOΞ=;sIII=>DJJ -&ŋ:˲8s挘oq8s̀̚#11 3gtk*rcxQP؈:={ [lC4? HH6段_uW_mxhnnƏ?إRsN2H$={b/!pDsNR?!z]~Lz4M !JJ~ FBxr455!33h.++#zuuuhmmJ":T(w xyy9QUTT! 0D0\mmm"Y[[ gRQQa|,^1577w0?M鮿"$돝VKK 2330 VۧTh* (/^/F]wEnӣDw}O<L ۱m6 :}g!˱j*P5uxq)Cz-P_/FWZDDDDDDyϱz,PH낌H8Snv<󼠅aYIIIt8)))())R'%%oj謬,֢Ȓ4R(/))-(?P`}?$.aLihh P͑e̚*AMM̀fm h4HJJ굛qiiiyOS/Ŵw W[***p455 sތes!Q*|rWPPF477w Zʲ,.])Eff$`8zގV8$''Ѹv]LZmT8p3tdl x;vxj>|yyyj|2qat:633ݦ'*ԩSFtapA0 C"/ Ƒ#G{^'suM gOt+0 7( : II<ϣ(.KSS222:ŁZ"*{i4-SDyX T*$]hmm5jϚ1 :b%Q`m*sӔKo1/ŝ<6zKKK 222.@GLz8ޠjI\P__6jTVV}g&RUUevj8zhhPQQAֹF Jֆ teee$ϓ Xt)f̘^{ Fܹsma<3gx:t(n:]ۓ^~e[oL&#sP²,b t+X4 :4M< 7(DE  dNt`(H$hmmL&-uW'z!JHoy8iMTxyD GNŝ!x;;;^"@**IJ:A9Z9JR#/JN?$BTB*(^", Z뀥(JQ#""""""7x<ϳqEq,˂8z١ݬSC s=J62 VVVL&E<`cn碧(J+ gmmKR֖?z-;̺ 4Zd U]]M+ ʊ tRt!tQ,bĉ|2XEXX8ՁiL8a BZlllp0j(@aa!h&ʛ8q"\V dggo'"++ J'NDnn4iK ݑ)A  kOSDDP]] 466_$73<#<<hmmvU,0rHH$\zl"HKӴ^]q˴i HۧX0&Mٳgaر$;r?;;;ܑ%8?T* +WfHII!!58Cpp0PWWGx(//G```8Aӡ>>>HOOGXXaTTT`ܸqHNNq)Spytu|}}, 'N@ G^^RѣGرc1bYo===N`hƜ9s܌D>>9s&N555Q~t$z-44MmllX胷T$ sΥgQ4M* Z0""""""\(L&㭭 (:xqIz> UP@G ///KA*RC GFy466B@Gr\t\{r(""""""t8Cnn.4uL3P*Q"""""""Smc"HDDDDDDDDDDDDDDDDh?1Sfb%tEXtdate:create2020-05-10T10:39:39+02:00V %tEXtdate:modify2020-05-10T10:39:39+02:00 IENDB`qnetload-1.3.6/src/informationstorage.cpp000066400000000000000000000135321451037126700205470ustar00rootroot00000000000000#include "informationstorage.h" #include "utils.h" #include #include #include /* * Copyright 2017, 2020 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ InformationStorage::InformationStorage(QObject *parent) : QObject(parent) { initialize(); } void InformationStorage::initialize() { m_maximumInformation = 0; m_maximumSpeedIn = 0; m_maximumSpeedOut = 0; m_informations.clear(); m_startedBytes = NetworkInformationReader::NetworkBytesInOut(); m_latestBytes = NetworkInformationReader::NetworkBytesInOut(); m_timeStarted = QDateTime::currentDateTime().toString("hh:mm:ss"); setCapacity(4096); m_isPaused = false; m_pausedInBytes = 0; m_pausedOutBytes = 0; } void InformationStorage::pause() { m_isPaused = true; } void InformationStorage::unpause() { m_isPaused = false; } bool InformationStorage::isPaused() const { return m_isPaused; } void InformationStorage::setCapacity(int maximumInformation) { if (maximumInformation > m_maximumInformation) { m_informations.reserve(maximumInformation); } m_maximumInformation = maximumInformation; } quint64 InformationStorage::millisecondsSinceStart() const { return Utils::currentMSecsSinceEpoch() - m_startedBytes.milliSecondsSinceEpoch; } QString InformationStorage::timeStarted() const { return m_timeStarted; } quint64 InformationStorage::accumulatedTransfer(int position, InformationStorage::InOrOutType inOrOut) const { quint64 dataAccumulated = 0; for (int i = position; i < m_informations.count(); i++) { dataAccumulated += speed(i, inOrOut); } return dataAccumulated; } quint64 InformationStorage::secondsAgo(int position) { quint64 milliSecondsSinceEpoch = m_informations[position].milliSecondsSinceEpoch; return (Utils::currentMSecsSinceEpoch() - milliSecondsSinceEpoch) / 1000; } bool InformationStorage::wasPaused(int position) const { return m_informations[position].paused; } quint64 InformationStorage::speed(int position, InformationStorage::InOrOutType inOrOut) const { switch(inOrOut) { case InOrOutType::InType: return m_informations[position].in; case InOrOutType::OutType: return m_informations[position].out; case InOrOutType::UndefinedType: __builtin_unreachable(); } __builtin_unreachable(); } NetworkInformationReader::NetworkBytesInOut InformationStorage::currentSpeed() { if (m_informations.isEmpty()) { NetworkInformationReader::NetworkBytesInOut networkBytesInOut; return networkBytesInOut; } return m_informations.last(); } InformationStorage::NetworkBytesInOutPaused InformationStorage::calculateSpeed(const NetworkInformationReader::NetworkBytesInOut& before, const NetworkInformationReader::NetworkBytesInOut& after) { NetworkInformationReader::NetworkBytesInOut speed; double seconds_elapsed = (after.milliSecondsSinceEpoch-before.milliSecondsSinceEpoch)/1000.0; speed.in = quint64((after.in-before.in) / seconds_elapsed); speed.out = quint64((after.out-before.out) / seconds_elapsed); return speed; } void InformationStorage::addInformation(const NetworkInformationReader::NetworkBytesInOut& information) { if (m_startedBytes.milliSecondsSinceEpoch == 0) { // It hasn't been initialized yet m_startedBytes = information; return; } // Instead of doing this we could do a circular list (should avoid reallocations) if (m_informations.size() == m_maximumInformation) { m_informations.removeFirst(); } InformationStorage::NetworkBytesInOutPaused speed; // Information comes with total bytes, here we convert it into speed if (m_informations.isEmpty()) { // We use the initial transfer data speed = calculateSpeed(m_startedBytes, information); } else { speed = calculateSpeed(m_latestBytes, information); } speed.milliSecondsSinceEpoch = information.milliSecondsSinceEpoch; speed.paused = isPaused(); m_informations.append(speed); if (!isPaused()) { if (speed.in > m_maximumSpeedIn) { m_maximumSpeedIn = speed.in; } if (speed.out > m_maximumSpeedOut) { m_maximumSpeedOut = speed.out; } } else { m_pausedInBytes += information.in - m_latestBytes.in; m_pausedOutBytes += information.out - m_latestBytes.out; } m_latestBytes = information; } quint64 InformationStorage::maximumSpeedIn() const { return m_maximumSpeedIn; } quint64 InformationStorage::maximumSpeedOut() const { return m_maximumSpeedOut; } quint64 InformationStorage::transferredIn() const { if (m_informations.isEmpty()) { return 0; } return m_latestBytes.in - m_startedBytes.in - m_pausedInBytes; } quint64 InformationStorage::transferredOut() const { if (m_informations.isEmpty()) { return 0; } return m_latestBytes.out - m_startedBytes.out - m_pausedOutBytes; } QVector InformationStorage::informations() const { return m_informations; } qnetload-1.3.6/src/informationstorage.h000066400000000000000000000061141451037126700202120ustar00rootroot00000000000000#pragma once #include #include #include "networkinformationreader.h" /* * Copyright 2017, 2020 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class InformationStorage : public QObject { Q_OBJECT public: enum class InOrOutType { InType, OutType, UndefinedType }; struct NetworkBytesInOutPaused : public NetworkInformationReader::NetworkBytesInOut { bool paused; NetworkBytesInOutPaused() : NetworkInformationReader::NetworkBytesInOut(), paused(false) {} NetworkBytesInOutPaused(const NetworkInformationReader::NetworkBytesInOut& networkBytesInOut) : NetworkInformationReader::NetworkBytesInOut(networkBytesInOut), paused(false) {} }; explicit InformationStorage(QObject *parent = 0); void addInformation(const NetworkInformationReader::NetworkBytesInOut& information); quint64 maximumSpeedIn() const; quint64 maximumSpeedOut() const; quint64 transferredIn() const; quint64 transferredOut() const; quint64 millisecondsSinceStart() const; QString timeStarted() const; quint64 speed(int position, InOrOutType inOrOut) const; bool wasPaused(int position) const; void setCapacity(int maximumInformation); QList lastValues(int numberOfValues, InOrOutType type); NetworkInformationReader::NetworkBytesInOut currentSpeed(); QVector informations() const; quint64 accumulatedTransfer(int position, InformationStorage::InOrOutType inOrOut) const; quint64 secondsAgo(int position); bool isPaused() const; public slots: void initialize(); void pause(); void unpause(); private: InformationStorage::NetworkBytesInOutPaused calculateSpeed(const NetworkInformationReader::NetworkBytesInOut& before, const NetworkInformationReader::NetworkBytesInOut& after); int m_maximumInformation; QVector m_informations; quint64 m_maximumSpeedIn; quint64 m_maximumSpeedOut; InformationStorage::NetworkBytesInOutPaused m_startedBytes; InformationStorage::NetworkBytesInOutPaused m_latestBytes; QString m_timeStarted; quint64 m_pausedInBytes; quint64 m_pausedOutBytes; bool m_isPaused; InformationStorage::NetworkBytesInOutPaused m_pauseStartsNetworkBytesInOut; }; qnetload-1.3.6/src/main.cpp000066400000000000000000000042601451037126700155570ustar00rootroot00000000000000#include "mainwindow.h" #include #include #include #include /* * Copyright 2017, 2019, 2020, 2023 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ int main(int argc, char *argv[]) { QApplication app(argc, argv); QApplication::setOrganizationName("qnetload"); QApplication::setApplicationName("qnetload"); QApplication::setApplicationVersion("1.3.6"); QTextStream stdoutStream(stdout); stdoutStream << "qnetload version " + QApplication::applicationVersion() + " Copyright (C) 2017, 2019, 2020, 2021, 2023 Carles Pina i Estany " << Qt::endl; stdoutStream << "This program comes with ABSOLUTELY NO WARRANTY" << Qt::endl; stdoutStream << "This is free software, and you are welcome to redistribute it under certain conditions" << Qt::endl; stdoutStream << "License: GPLv3+" << Qt::endl; stdoutStream << "Icons from https://p.yusukekamiyamane.com" << Qt::endl; QCommandLineParser parser; parser.setApplicationDescription("Display traffic for a network interface."); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption interfaceOption(QStringList() << "i" << "interface", QObject::tr("Interface to monitor. Defaults to the one used previously."), "interface"); parser.addOption(interfaceOption); parser.process(app); QString interfaceName = parser.value(interfaceOption); MainWindow w(interfaceName); w.show(); return app.exec(); } qnetload-1.3.6/src/mainwindow.cpp000066400000000000000000000344571451037126700170220ustar00rootroot00000000000000#include "mainwindow.h" #include "ui_mainwindow.h" #include "formatnumber.h" #include #include #include #include #include #include #include #include #include /* * Copyright 2017, 2019, 2020, 2021 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ MainWindow::MainWindow(const QString& interfaceName, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_networkInformation(new NetworkInformationReader(this)), m_informationStorage(new InformationStorage(this)), m_timer(new QTimer(this)), m_resetWaitingForConfirmation(false), m_resetCountDown(0) { ui->setupUi(this); m_timeType = TimeType::millisecondsSinceStart; m_resetPixmap = QPixmap(":/icons/arrow-circle-135-left.png"); m_pausePixmap = QPixmap(":/icons/control-pause.png"); connect(ui->interface_name, &ClickableLabel::leftClicked, this, &MainWindow::selectNextInterface); connect(ui->time_running, &ClickableLabel::leftClicked, this, &MainWindow::toggleTime); QString interfaceSelectedName = interfaceName; setFontSize(readCurrentFontSize()); ui->reset_button->setToolButtonStyle(Qt::ToolButtonIconOnly); ui->pause_button->setToolButtonStyle(Qt::ToolButtonIconOnly); ui->message->setText(""); QSettings settings; restoreGeometry(settings.value("mainWindowGeometry").toByteArray()); restoreState(settings.value("mainWindowState").toByteArray()); m_timeType = settings.value("timeType").value(); connect(m_networkInformation, &NetworkInformationReader::interfaceNameChanged, m_informationStorage, &InformationStorage::initialize); connect(m_networkInformation, SIGNAL(interfaceNameChanged()), this, SLOT(interfaceNameChanged())); connect(ui->reset_button, &QAbstractButton::clicked, this, &MainWindow::reset); connect(ui->pause_button, &QAbstractButton::clicked, this, &MainWindow::togglePause); QStringList listOfInterfaces = m_networkInformation->listOfInterfaces(); if (listOfInterfaces.isEmpty()) { QString message = tr("qnetload cannot read any interface from %1").arg(m_networkInformation->procNetDev()); QMessageBox::critical(this, tr("qnetload"), message); exit(2); } if (interfaceSelectedName.isEmpty()) { interfaceSelectedName = chooseInterfaceName(); } if (!listOfInterfaces.contains(interfaceSelectedName)) { QString message1 = tr("Passed interface %1 not found in %2").arg(interfaceSelectedName) .arg(m_networkInformation->procNetDev()); QString message2 = tr("qnetload will choose another interface"); QMessageBox::warning(this, tr("qnetload"), message1 + "\n" + message2); interfaceSelectedName = chooseInterfaceName(); } m_networkInformation->setInterfaceName(interfaceSelectedName); setTooltips(); connect(m_timer, &QTimer::timeout, this, &MainWindow::updateInformation); m_timer->start(1000); // Speed to zero to start with setAllLabels(m_networkInformation->interfaceName(), 0, QString(), 0, 0, 0, 0, 0, 0, 0); ui->in_graph->setType(InformationStorage::InOrOutType::InType); ui->in_graph->setInformationStorage(m_informationStorage); ui->out_graph->setType(InformationStorage::InOrOutType::OutType); ui->out_graph->setInformationStorage(m_informationStorage); updateInformation(); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QWidget::customContextMenuRequested, this, &MainWindow::showContextualMenu); } void MainWindow::reset() { if (m_resetWaitingForConfirmation) { ui->message->setText(""); m_informationStorage->initialize(); updateInformation(); m_resetWaitingForConfirmation = false; m_resetCountDown = 0; } else { m_resetCountDown = 5; m_resetWaitingForConfirmation = true; resetCountDown(); } } void MainWindow::togglePause() { if (m_informationStorage->isPaused()) { m_informationStorage->unpause(); ui->message->setText(""); } else { m_informationStorage->pause(); ui->message->setText("Paused"); } } void MainWindow::resetCountDown() { if (m_resetCountDown == -1) { m_resetWaitingForConfirmation = false; m_resetCountDown = 0; ui->message->setText(""); return; } if (!m_resetWaitingForConfirmation) { return; } ui->message->setText(tr("%1 click again").arg(m_resetCountDown)); m_resetCountDown--; QTimer::singleShot(1000, this, &MainWindow::resetCountDown); } void MainWindow::interfaceNameChanged() { QSettings settings; settings.setValue("latestInterfaceName", m_networkInformation->interfaceName()); QTimer::singleShot(1, this, SLOT(updateInformation())); } void MainWindow::selectNextInterface() { QString currentInterface = m_networkInformation->interfaceName(); QStringList listOfInterfaces = m_networkInformation->listOfInterfaces(); int newIndex = (listOfInterfaces.indexOf(currentInterface) + 1) % listOfInterfaces.count(); QString newInterface = listOfInterfaces.at(newIndex); m_networkInformation->setInterfaceName(newInterface); } void MainWindow::toggleTime() { if (m_timeType == TimeType::timeStarted) { m_timeType = TimeType::millisecondsSinceStart; } else { m_timeType = TimeType::timeStarted; } updateInformation(); QSettings settings; settings.setValue("timeType", m_timeType); } void MainWindow::showContextualMenu(const QPoint& position) { QMenu* contextualMenu = new QMenu(this); QMenu* fontSizes = new QMenu(tr("Font Size"), contextualMenu); int currentFontSize = readCurrentFontSize(); for(int fontSize = 5; fontSize < 15; fontSize++) { QAction* fontSizeAction = fontSizes->addAction(QString::number(fontSize)); fontSizeAction->setCheckable(true); fontSizeAction->setChecked(currentFontSize == fontSize); connect(fontSizeAction, &QAction::triggered, this, [this, fontSize]{setFontSize(fontSize);} ); } contextualMenu->addMenu(fontSizes); QMenu* interfaces = new QMenu(tr("Interfaces"), contextualMenu); for(QString interface : m_networkInformation->listOfInterfaces()) { QAction* interfaceAction = interfaces->addAction(interface); interfaceAction->setCheckable(true); interfaceAction->setChecked(interface == m_networkInformation->interfaceName()); if (NetworkInformationReader::isNotableInterface(interface)) { QFont font = interfaceAction->font(); font.setBold(NetworkInformationReader::isNotableInterface(interface)); interfaceAction->setFont(font); } connect(interfaceAction, &QAction::triggered, this, [this, interface]{m_networkInformation->setInterfaceName(interface);} ); } contextualMenu->addMenu(interfaces); QAction* ip = contextualMenu->addAction(tr("IP: %1").arg(m_networkInformation->ip())); connect(ip, &QAction::triggered, this, &MainWindow::copyIp); QAction* version = contextualMenu->addAction(tr("Version: %1").arg(QApplication::applicationVersion())); version->setEnabled(false); contextualMenu->exec(mapToGlobal(position)); } void MainWindow::copyIp() { QClipboard *clipboard = QGuiApplication::clipboard(); clipboard->setText(m_networkInformation->ip()); QTimer::singleShot(100, this, &MainWindow::showCopiedTooltip); } void MainWindow::showCopiedTooltip() { QToolTip::showText(cursor().pos(), tr("IP Copied"), this); } void MainWindow::wheelEvent(QWheelEvent* event) { // Resizes fonts if (!(QApplication::keyboardModifiers() & Qt::ControlModifier)) { return; } int y = event->angleDelta().y(); int newFontSize; if (y>0) { newFontSize = readCurrentFontSize() + 1; } else { newFontSize = readCurrentFontSize() - 1; } if (newFontSize <= 0) { return; } int inGraphHeight = ui->in_graph->height(); setFontSize(newFontSize); // Easy way to force the labels to be drawn to get the differential QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); int graphDelta = inGraphHeight - ui->in_graph->height(); QSize newSize = size(); QSize oldSize = size(); newSize.setHeight(oldSize.height() + graphDelta * 2); newSize.setWidth(oldSize.width() + graphDelta * 2); resize(newSize); } int MainWindow::readCurrentFontSize() const { QSettings settings; if (settings.value("fontSize").isValid()) { return settings.value("fontSize").toInt(); } return 9; } void MainWindow::setFontSize(int fontSize) { for(QLabel* label : findChildren()) { QFont font = label->font(); font.setPointSize(fontSize); label->setFont(font); } QSettings settings; settings.setValue("fontSize", fontSize); int labelHeight = ui->out_current_speed->height(); ui->reset_button->setFixedSize(labelHeight, labelHeight); // Reset button resize int fontHeight = ui->interface_name->fontMetrics().height(); QPixmap resetPixmapResized = m_resetPixmap.scaledToHeight(fontHeight); QPixmap pausePixmapResized = m_pausePixmap.scaledToHeight(fontHeight); updateButtonIcon(ui->reset_button, resetPixmapResized); updateButtonIcon(ui->pause_button, pausePixmapResized); } void MainWindow::updateButtonIcon(QToolButton* toolButton, const QPixmap& pixmap) { toolButton->setIconSize(pixmap.size()); toolButton->setIcon(pixmap); toolButton->setFixedSize(pixmap.size()); } QString MainWindow::chooseInterfaceName() const { QSettings settings; if (settings.value("latestInterfaceName").isValid()) { return settings.value("latestInterfaceName").toString(); } else { return m_networkInformation->chooseInterfaceFromProcNetDevInterface(); } } void MainWindow::setTooltips() { ui->interface_name->setToolTip(tr("Monitored interface")); ui->time_running->setToolTip(tr("Time elapsed since/start time qnetload was started")); ui->in_current_speed->setToolTip(tr("Speed receiving data")); ui->in_maximum_speed->setToolTip(tr("Maximum speed receiving data (intervals of 1 second)")); ui->in_transferred->setToolTip(tr("Total amount of data received since qnetload was started")); ui->out_current_speed->setToolTip(tr("Speed sending data")); ui->out_maximum_speed->setToolTip(tr("Maximum speed sending data (intervals of 1 second)")); ui->out_transferred->setToolTip(tr("Total amount of data sent since qnetload was started")); ui->total_transferred->setToolTip(tr("Total (in and out) transferred data")); ui->reset_button->setToolTip(tr("Reset counters")); ui->pause_button->setToolTip(tr("Pause counters")); } void MainWindow::setAllLabels(const QString& interfaceName, quint64 millisecondsSinceStart, const QString& timeStarted, quint64 currentSpeedIn, quint64 maximumSpeedIn, quint64 transferredIn, quint64 currentSpeedOut, quint64 maximumSpeedOut, quint64 transferredOut, quint64 transferredTotal) { ui->interface_name->setText(interfaceName); switch(m_timeType) { case TimeType::millisecondsSinceStart: ui->time_running->setText(QString("Elapsed: %1").arg(FormatNumber::formatElapsedTime(millisecondsSinceStart))); break; case TimeType::timeStarted: ui->time_running->setText(QString("Started: %1").arg(timeStarted)); } ui->in_current_speed->setText(FormatNumber::formatSpeed(currentSpeedIn)); ui->in_maximum_speed->setText(QString("(%1)").arg(FormatNumber::formatSpeed(maximumSpeedIn))); ui->in_transferred->setText(QString("[%1]").arg(FormatNumber::formatTransfer(transferredIn))); ui->out_current_speed->setText(FormatNumber::formatSpeed(currentSpeedOut)); ui->out_maximum_speed->setText(QString("(%1)").arg(FormatNumber::formatSpeed(maximumSpeedOut))); ui->out_transferred->setText(QString("[%1]").arg(FormatNumber::formatTransfer(transferredOut))); ui->total_transferred->setText(QString("%1").arg(FormatNumber::formatTransfer(transferredTotal))); } void MainWindow::updateInformation() { NetworkInformationReader::NetworkBytesInOut information = m_networkInformation->readInformation(); m_informationStorage->addInformation(information); quint64 maximumSpeedIn = m_informationStorage->maximumSpeedIn(); quint64 maximumSpeedOut = m_informationStorage->maximumSpeedOut(); quint64 transferredIn = m_informationStorage->transferredIn(); quint64 transferredOut = m_informationStorage->transferredOut(); quint64 transferredTotal = transferredIn + transferredOut; NetworkInformationReader::NetworkBytesInOut currentSpeed = m_informationStorage->currentSpeed(); quint64 currentSpeedIn = currentSpeed.in; quint64 currentSpeedOut = currentSpeed.out; setAllLabels(m_networkInformation->interfaceName(), m_informationStorage->millisecondsSinceStart(), m_informationStorage->timeStarted(), currentSpeedIn, maximumSpeedIn, transferredIn, currentSpeedOut, maximumSpeedOut, transferredOut, transferredTotal); ui->in_graph->repaint(); ui->out_graph->repaint(); } MainWindow::~MainWindow() { QSettings settings; settings.setValue("mainWindowGeometry", saveGeometry()); settings.setValue("mainWindowState", saveState()); delete ui; } qnetload-1.3.6/src/mainwindow.h000066400000000000000000000046411451037126700164570ustar00rootroot00000000000000#pragma once #include #include #include "networkinformationreader.h" #include "informationstorage.h" class QToolButton; /* * Copyright 2017, 2019, 2021 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: enum TimeType { millisecondsSinceStart = 0, timeStarted = 1 }; Q_ENUM(TimeType); explicit MainWindow(const QString& interfaceName, QWidget *parent = 0); ~MainWindow(); protected: void wheelEvent(QWheelEvent* event) override; private Q_SLOTS: void updateInformation(); void selectNextInterface(); void toggleTime(); void showContextualMenu(const QPoint& position); void interfaceNameChanged(); void resetCountDown(); void togglePause(); void copyIp(); void showCopiedTooltip(); private: void reset(); int readCurrentFontSize() const; QString chooseInterfaceName() const; void setAllLabels(const QString& interfaceName, quint64 millisecondsSinceStart, const QString& timeStarted, quint64 currentSpeedIn, quint64 maximumSpeedIn, quint64 transferredIn, quint64 currentSpeedOut, quint64 maximumSpeedOut, quint64 transferredOut, quint64 transferredTotal); void setTooltips(); void setFontSize(int fontSize); void updateButtonIcon(QToolButton* toolButton, const QPixmap& pixmap); Ui::MainWindow *ui; NetworkInformationReader* m_networkInformation; InformationStorage* m_informationStorage; QTimer* m_timer; QPixmap m_resetPixmap; QPixmap m_pausePixmap; bool m_resetWaitingForConfirmation; int m_resetCountDown; TimeType m_timeType; }; qnetload-1.3.6/src/mainwindow.ui000066400000000000000000000337701451037126700166520ustar00rootroot00000000000000 MainWindow 0 0 390 110 0 0 350 0 qnetload :/icons/main-icon.png:/icons/main-icon.png 0 0 0 0 3 0 0 0 0 0 Monospace 7 75 true wlan0 0 3 0 0 Monospace 7 75 true 0 0 Monospace 7 75 true 20:45:43 0 0 Monospace 7 75 true a message 16 16 Monospace 7 75 true Total: Monospace 7 75 true 300 MB 0 3 0 0 Monospace 7 75 true in: 0 0 Monospace 7 75 true 1000 KB/s Qt::Horizontal QSizePolicy::Maximum 5 0 0 0 Monospace 7 75 true (1500 KB/s) 0 Qt::Horizontal QSizePolicy::Maximum 5 0 Monospace 7 75 true [150 MB] 0 0 0 0 3 0 0 Monospace 7 75 true out: 0 0 Monospace 7 75 true 1000 KB/s Qt::Horizontal QSizePolicy::Maximum 5 0 0 0 Monospace 7 75 true (1500 KB/s) 0 Qt::Horizontal QSizePolicy::Maximum 5 0 Monospace 7 75 true [150 MB] 0 0 0 Plot QWidget
plot.h
1
ClickableLabel QLabel
clickablelabel.h
qnetload-1.3.6/src/manual/000077500000000000000000000000001451037126700154025ustar00rootroot00000000000000qnetload-1.3.6/src/manual/qnetload.1000066400000000000000000000045101451037126700172730ustar00rootroot00000000000000.TH QNETLOAD 1 .SH NAME qnetload \- Graphically display network speed and usage .SH SYNOPSIS \fBqnetload .SH DESCRIPTION Graphically display network speed and usage. .TP \fB-i\fR, \fB\-\-interface=\fIINTERFACE\fR Display network INTERFACE. For example: eth0, wlan0. If unsure, do not specify. When running the interface can be changed by clicking on it. Right-click on the interface to list the available interfaces. .TP \fB-h\fR, \fB\-\-help\fR Display help for commandline options. .TP \fB-v\fR, \fB\-\-version\fR Display version information. .TP \fB\-\-help\-all\fR Display help including Qt-specific options. .PP .SH USING QNETLOAD Some features on qnetload might not obvious: .RS 2 .IP \(bu 2 Click on the interface to change it. .IP \(bu 2 Right-click anywhere on qnetload to display a contextual menu with the list of interfaces, the IP and the version. The most common interfaces are in bold (ethX, wlanX, etc.). .IP \(bu 2 There are two buttons: pause the accumulative counter of Downloaded and Uploaded data and reset the counter. To reset the counters, click twice. .IP \(bu 2 Clicking in the graph will display how much data has been downloaded and uploaded since the position of the click and a projection for the next hour's usage. .IP \(bu 2 Hover the mouse pointer over any of the numbers to display the meaning of the value. .SH ORIGINAL IDEA FROM XNETLOAD \fBqnetload\fR has the same look and feel as \fBxnetload\fR, which is no longer maintained. The \fIq\fP in the name is because \fBqnetload\fR is implemented using the Qt libraries. .SH FILES .TP .I ${HOME}/.config/qnetload/qnetload.conf The last-used interface is saved here. This will be used the next time \fBqnetload\fR is executed. .TP .I /proc/net/dev This file, provided by the kernel, contains details of the network usage and is read by qnetload to provide the displayed data. .SH BUG REPORTS .PP Bug tracker: .br Email: Carles Pina i Estany .SH SEE ALSO .BR ipmon (1) .BR ethstatus (1) .BR nload (1) .SH ACKNOWLEDGEMENTS Many thanks to R.F. Smith for xnetload: lots of inspiration from it. Many thanks to Jen Thomas for testing qnetload and helping with the manual page and texts. .SH COPYRIGHT AND LICENSE .PP Copyright \[co] 2017-2023 Carles Pina i Estany . License: GPLv3+: GNU GPL version 3 or later. qnetload-1.3.6/src/networkinformationreader.cpp000066400000000000000000000123401451037126700217530ustar00rootroot00000000000000#include "networkinformationreader.h" #include "utils.h" #include #include #include #include #include #include /* * Copyright 2017, 2021 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ NetworkInformationReader::NetworkInformationReader(QObject* parent) : QObject(parent) , m_procNetDev("/proc/net/dev") { } NetworkInformationReader::NetworkInformationReader(const QString& interfaceName, const QString& procNetDevFile, QObject* parent) : QObject(parent) , m_procNetDev(procNetDevFile) { setInterfaceName(interfaceName); } QString NetworkInformationReader::ip() const { QNetworkInterface interface = QNetworkInterface::interfaceFromName(interfaceName()); QList addresses = interface.addressEntries(); QStringList result; Q_FOREACH(const QNetworkAddressEntry& address, addresses) { if (address.ip().protocol() == QAbstractSocket::IPv4Protocol) { result.append(address.ip().toString()); } } if (result.count() == 0) { return "-"; } else { return result.join("-"); } } void NetworkInformationReader::setInterfaceName(const QString& interfaceName) { if (interfaceName != m_interfaceName) { m_interfaceName = interfaceName; emit interfaceNameChanged(); } } QString NetworkInformationReader::procNetDev() const { return m_procNetDev; } QString NetworkInformationReader::interfaceName() const { return m_interfaceName; } QStringList NetworkInformationReader::listOfInterfaces() const { QFile file(procNetDev()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return QStringList(); } QStringList listOfInterfaces; QString line; do { line = file.readLine(); QRegularExpressionMatch match = parseLine(line); if (match.hasMatch()) { listOfInterfaces.append(match.captured(1)); } } while (!line.isEmpty()); listOfInterfaces.sort(); return listOfInterfaces; } NetworkInformationReader::NetworkBytesInOut NetworkInformationReader::readProcNetDevInterface(const QString& interface) const { QFile file(procNetDev()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return NetworkInformationReader::NetworkBytesInOut(); } QString line; do { line = file.readLine(); QRegularExpressionMatch match = parseLine(line); if (match.hasMatch() && match.captured(1) == interface) { NetworkInformationReader::NetworkBytesInOut information; information.in = match.captured(2).toULong(); information.out = match.captured(3).toULong(); information.milliSecondsSinceEpoch = Utils::currentMSecsSinceEpoch(); return information; } } while(!line.isEmpty()); return NetworkInformationReader::NetworkBytesInOut(); } QRegularExpressionMatch NetworkInformationReader::parseLine(const QString& line) { QRegularExpression lineInformationRe(" *(.+): * (\\d+) +\\d+ +\\d+ +\\d+ +\\d+ +\\d+ +\\d+ +\\d+ +(\\d+).*"); QRegularExpressionMatch match = lineInformationRe.match(line); return match; } NetworkInformationReader::NetworkBytesInOut NetworkInformationReader::readInformation() const { NetworkInformationReader::NetworkBytesInOut information = readProcNetDevInterface(m_interfaceName); return information; } QString NetworkInformationReader::chooseInterfaceFromProcNetDevInterface() const { // Choose a valid interface name from a priority list QStringList prefixes; prefixes.append("wl"); // wlan0 (WirelessLAN, classic) or wlp4s0 (WireLess Pci 4... systemd/udev) prefixes.append("enp"); // enp0s20f0u3c2 (EtherNet Pci 0 Slot 2... systemd/udev) prefixes.append("eth"); // eth0 (ETHernet 0) QStringList interfaces = listOfInterfaces(); Q_ASSERT(!interfaces.isEmpty()); interfaces.sort(); Q_FOREACH(const QString& prefix, prefixes) { Q_FOREACH(const QString& interface, interfaces) { if (interface.startsWith(prefix)) { return interface; } } } return interfaces.first(); } bool NetworkInformationReader::isNotableInterface(const QString& interface) { return interface.startsWith("eth") || interface.startsWith("enp") || interface.startsWith("wlan") || interface.startsWith("wlp"); } qnetload-1.3.6/src/networkinformationreader.h000066400000000000000000000041721451037126700214240ustar00rootroot00000000000000#pragma once #include #include /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class NetworkInformationReader : public QObject { Q_OBJECT public: struct NetworkBytesInOut { quint64 in; quint64 out; quint64 milliSecondsSinceEpoch; NetworkBytesInOut() : in(0), out(0), milliSecondsSinceEpoch(0) {} NetworkBytesInOut(const NetworkBytesInOut& networkBytesInOut_) : in(networkBytesInOut_.in), out(networkBytesInOut_.out), milliSecondsSinceEpoch(networkBytesInOut_.milliSecondsSinceEpoch) {} }; NetworkInformationReader(QObject* parent=0); NetworkInformationReader(const QString &interfaceName, const QString& procNetDevPath, QObject* parent=0); void setInterfaceName(const QString& interfaceName); QString interfaceName() const; NetworkBytesInOut readInformation() const; void setProcNetDev(const QString& path); QString procNetDev() const; NetworkBytesInOut readProcNetDevInterface(const QString& interface) const; QStringList listOfInterfaces() const; QString chooseInterfaceFromProcNetDevInterface() const; QString ip() const; static bool isNotableInterface(const QString& interface); signals: void interfaceNameChanged(); private: static QRegularExpressionMatch parseLine(const QString &line); QString m_interfaceName; QString m_procNetDev; }; qnetload-1.3.6/src/plot.cpp000066400000000000000000000113711451037126700156120ustar00rootroot00000000000000#include "plot.h" #include "formatnumber.h" #include "networkinformationreader.h" #include #include #include #include #include #include /* * Copyright 2017, 2020, 2023 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ Plot::Plot(QWidget *parent) : QWidget(parent), m_type(InformationStorage::InOrOutType::UndefinedType), m_paintedInitial(0) { QPalette pal(palette()); pal.setColor(QPalette::Window, Qt::white); setAutoFillBackground(true); setPalette(pal); } quint64 Plot::maximumValue() { return std::max(m_informationStorage->maximumSpeedIn(), m_informationStorage->maximumSpeedOut()); } double Plot::maximumValueLog() { return log(maximumValue()); } void Plot::paintScale(QPainter* painter) { double logMaximum = maximumValueLog(); double space_between_horizontal_lines = height() / logMaximum; int line_number = 0; for (float y = height(); y > space_between_horizontal_lines/2; y-= space_between_horizontal_lines, line_number++) { if (space_between_horizontal_lines < 15 && line_number % 2 == 1) { continue; } painter->drawLine(QPoint(0, int(y)), QPoint(width(), int(y))); } } void Plot::paintBars(QPainter *painter) { QVector informations = m_informationStorage->informations(); double maximumValue = maximumValueLog(); int initial = qMax(0, informations.count()-width()); m_paintedInitial = initial; int x; for(int i=initial; i < informations.count(); i++) { double y; quint64 speed = m_informationStorage->speed(i, m_type); if (speed != 0) { y = (height() * log(speed)) / maximumValue; } else { y = 0; } y = height() - y; x = i - initial; if (m_informationStorage->wasPaused(i)) { painter->setPen(Qt::gray); } else { painter->setPen(Qt::black); } painter->drawLine(QPoint(x, int(height())), QPoint(x, int(y))); } } void Plot::paintEvent(QPaintEvent *event) { Q_UNUSED(event); quint64 maxValue = maximumValue(); if (maxValue == 0) { return; } QPainter painter(this); paintScale(&painter); paintBars(&painter); } void Plot::mousePressEvent(QMouseEvent* event) { int valuePosition = m_paintedInitial + event->position().x(); if (valuePosition > m_informationStorage->informations().count()) { return; } quint64 secondsAgo = m_informationStorage->secondsAgo(valuePosition); QString timeAgo = FormatNumber::formatSeconds(secondsAgo); quint64 accumulatedTransferIn = m_informationStorage->accumulatedTransfer(valuePosition, InformationStorage::InOrOutType::InType); quint64 accumulatedTransferOut = m_informationStorage->accumulatedTransfer(valuePosition, InformationStorage::InOrOutType::OutType); quint64 accumulatedTransfer = accumulatedTransferIn + accumulatedTransferOut; quint64 estimatedOneHourBytes = (accumulatedTransfer / secondsAgo) * 3600; QString information = QString("Last %1\n" "In: %2 Out: %3\n" "Total: %4 transferred\n" "Projected use 1 hour: %5") .arg(timeAgo) .arg(FormatNumber::formatTransfer(accumulatedTransferIn)) .arg(FormatNumber::formatTransfer(accumulatedTransferOut)) .arg(FormatNumber::formatTransfer(accumulatedTransfer)) .arg(FormatNumber::formatTransfer(estimatedOneHourBytes)); QToolTip::showText(event->globalPosition().toPoint(), information); } void Plot::setType(InformationStorage::InOrOutType inOrOutType) { m_type = inOrOutType; } void Plot::setInformationStorage(InformationStorage* informationStorage) { m_informationStorage = informationStorage; } qnetload-1.3.6/src/plot.h000066400000000000000000000027241451037126700152610ustar00rootroot00000000000000#pragma once #include #include "informationstorage.h" /* * Copyright 2017, 2020 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class Plot : public QWidget { Q_OBJECT public: explicit Plot(QWidget *parent = nullptr); void setType(InformationStorage::InOrOutType inOrOutType); void setInformationStorage(InformationStorage* informationStorage); void update(InformationStorage* informationStorage); quint64 maximumValue(); double maximumValueLog(); protected: void paintEvent(QPaintEvent *event); void mousePressEvent(QMouseEvent* event); signals: public slots: private: void paintScale(QPainter *painter); void paintBars(QPainter *painter); InformationStorage::InOrOutType m_type; InformationStorage* m_informationStorage; int m_paintedInitial; }; qnetload-1.3.6/src/resources.qrc000066400000000000000000000003041451037126700166430ustar00rootroot00000000000000 icons/arrow-circle-135-left.png icons/control-pause.png icons/main-icon.png qnetload-1.3.6/src/tests/000077500000000000000000000000001451037126700152675ustar00rootroot00000000000000qnetload-1.3.6/src/tests/CMakeLists.txt000066400000000000000000000015771451037126700200410ustar00rootroot00000000000000set(CMAKE_AUTOMOC ON) find_package(Qt6Test REQUIRED) find_package(Qt6Network REQUIRED) add_executable(testnetworkinformationreader testnetworkinformationreader.cpp ../networkinformationreader.cpp ../utils.cpp) add_executable(testformatnumber testformatnumber.cpp ../formatnumber.cpp) add_executable(testinformationstorage testinformationstorage.cpp ../informationstorage.cpp ../utils.cpp) add_test(testnetworkinformationreader testnetworkinformationreader) add_test(testformatnumber testformatnumber) add_test(testinformationstorage testinformationstorage) target_link_libraries(testnetworkinformationreader Qt6::Test Qt6::Network) target_link_libraries(testformatnumber Qt6::Test) target_link_libraries(testinformationstorage Qt6::Test) # Warning: files are not copied again if modified file(COPY proc_net_dev_files/example01.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/proc_net_dev_files) qnetload-1.3.6/src/tests/proc_net_dev_files/000077500000000000000000000000001451037126700211205ustar00rootroot00000000000000qnetload-1.3.6/src/tests/proc_net_dev_files/README.txt000066400000000000000000000000501451037126700226110ustar00rootroot00000000000000These files are used by the unit tests. qnetload-1.3.6/src/tests/proc_net_dev_files/example01.txt000066400000000000000000000014701451037126700234570ustar00rootroot00000000000000Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed tun0: 0 0 0 0 0 0 0 0 374759 2276 0 0 0 0 0 0 lo: 306704725 598211 0 0 0 0 0 0 306704725 598211 0 0 0 0 0 0 wlan0: 8333760727 7419320 0 0 0 0 0 0 736793930 5001088 0 0 0 0 0 0 docker0: 402297 7107 0 0 0 0 0 0 18335562 10855 0 0 0 0 0 0 eth1: 11546469 11811 0 0 0 0 0 373 1058947 9766 0 0 0 0 0 0 qnetload-1.3.6/src/tests/testformatnumber.cpp000066400000000000000000000053611451037126700214010ustar00rootroot00000000000000#include "testformatnumber.h" #include "../formatnumber.h" #include /* * Copyright 2017, 2023 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ TestFormatNumber::TestFormatNumber() { } void TestFormatNumber::testFormatElapsedTime_data() { QTest::addColumn("milliseconds"); QTest::addColumn("humanReadable"); QTest::newRow("num1") << 100*1000 << QString("0:01:40"); QTest::newRow("num2") << 25*3600*1000 << QString("25:00:00"); QTest::newRow("num3") << (25*3600+100)*1000 << QString("25:01:40"); } void TestFormatNumber::testFormatElapsedTime() { QFETCH(int, milliseconds); QFETCH(QString, humanReadable); QCOMPARE(FormatNumber::formatElapsedTime(milliseconds), humanReadable); } void TestFormatNumber::testFormatSpeed_data() { QTest::addColumn("bytesSecond"); QTest::addColumn("humanReadable"); QTest::newRow("num1") << quint64(10) << QString("10 B/s"); QTest::newRow("num2") << quint64(1023) << QString("1023 B/s"); QTest::newRow("num3") << quint64(1025) << QString("1.00 KB/s"); QTest::newRow("num4") << quint64(1024*1024*1024) << QString("1024.00 MB/s"); QTest::newRow("num5") << quint64(2)*1024*1024*1024 << QString("2.00 GB/s"); } void TestFormatNumber::testFormatSpeed() { QFETCH(quint64, bytesSecond); QFETCH(QString, humanReadable); QCOMPARE(FormatNumber::formatSpeed(bytesSecond), humanReadable); } void TestFormatNumber::testFormatTransfer_data() { QTest::addColumn("bytes"); QTest::addColumn("humanReadable"); QTest::newRow("num1") << quint64(10) << QString("10 B"); QTest::newRow("num2") << quint64(1023) << QString("1023 B"); QTest::newRow("num3") << quint64(1025) << QString("1.00 KB"); QTest::newRow("num4") << quint64(1024*1024*1024) << QString("1024.00 MB"); QTest::newRow("num5") << quint64(2)*1024*1024*1024 << QString("2.00 GB"); } void TestFormatNumber::testFormatTransfer() { QFETCH(quint64, bytes); QFETCH(QString, humanReadable); QCOMPARE(FormatNumber::formatTransfer(bytes), humanReadable); } QTEST_MAIN(TestFormatNumber) qnetload-1.3.6/src/tests/testformatnumber.h000066400000000000000000000020461451037126700210430ustar00rootroot00000000000000#include /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class TestFormatNumber : public QObject { Q_OBJECT public: TestFormatNumber(); private Q_SLOTS: void testFormatElapsedTime_data(); void testFormatElapsedTime(); void testFormatSpeed_data(); void testFormatSpeed(); void testFormatTransfer_data(); void testFormatTransfer(); }; qnetload-1.3.6/src/tests/testinformationstorage.cpp000066400000000000000000000060121451037126700226040ustar00rootroot00000000000000#include "testinformationstorage.h" #include /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ TestInformationStorage::TestInformationStorage() { } void TestInformationStorage::init() { m_informationStorage.reset(new InformationStorage); } void TestInformationStorage::testCurrentSpeed() { addData(10000, 400, 1000); addData(20000, 400, 2000); NetworkInformationReader::NetworkBytesInOut currentSpeed = m_informationStorage->currentSpeed(); QCOMPARE(currentSpeed.in, quint64(10000)); QCOMPARE(currentSpeed.out, quint64(0)); } void TestInformationStorage::testMaximumSpeedIn() { addData(10000, 400, 1000); addData(40000, 400, 2000); addData(50000, 10000, 3000); quint64 maximumSpeedIn = m_informationStorage->maximumSpeedIn(); QCOMPARE(maximumSpeedIn, quint64(30000)); } void TestInformationStorage::testMaximumSpeedOut() { addData(10000, 400, 1000); addData(40000, 400, 2000); addData(50000, 10000, 3000); quint64 maximumSpeedIn = m_informationStorage->maximumSpeedOut(); QCOMPARE(maximumSpeedIn, quint64(9600)); } void TestInformationStorage::testTransferredIn() { m_informationStorage->setCapacity(1); addData(10000, 400, 1000); addData(50000, 500, 1001); QCOMPARE(m_informationStorage->transferredIn(), quint64(40000)); } void TestInformationStorage::testTransferredOut() { m_informationStorage->setCapacity(1); addData(10000, 400, 1000); addData(50000, 500, 1001); QCOMPARE(m_informationStorage->transferredOut(), quint64(100)); } void TestInformationStorage::testMillisecondsSinceStart() { m_informationStorage->setCapacity(1); quint64 millisecondsTimestamp = QDateTime::currentMSecsSinceEpoch(); addData(1000, 400, millisecondsTimestamp); addData(1000, 400, millisecondsTimestamp); addData(1000, 400, millisecondsTimestamp); quint64 millisecondsSinceStart = m_informationStorage->millisecondsSinceStart(); QVERIFY(millisecondsSinceStart <= QDateTime::currentMSecsSinceEpoch() - millisecondsTimestamp); } void TestInformationStorage::addData(quint64 in, quint64 out, qint64 millisecondsSinceEpoch) { NetworkInformationReader::NetworkBytesInOut data; data.in = in; data.out = out; data.milliSecondsSinceEpoch = millisecondsSinceEpoch; m_informationStorage->addInformation(data); } QTEST_MAIN(TestInformationStorage) qnetload-1.3.6/src/tests/testinformationstorage.h000066400000000000000000000023621451037126700222550ustar00rootroot00000000000000#include #include "../informationstorage.h" /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class TestInformationStorage : public QObject { Q_OBJECT public: TestInformationStorage(); private Q_SLOTS: void init(); void testCurrentSpeed(); void testMaximumSpeedIn(); void testMaximumSpeedOut(); void testTransferredIn(); void testTransferredOut(); void testMillisecondsSinceStart(); private: void addData(quint64 in, quint64 out, qint64 millisecondsSinceEpoch); QScopedPointer m_informationStorage; }; qnetload-1.3.6/src/tests/testnetworkinformationreader.cpp000066400000000000000000000035531451037126700240230ustar00rootroot00000000000000#include "testnetworkinformationreader.h" #include /* * Copyright 2017, 2023 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ TestNetworkInformation::TestNetworkInformation() { } void TestNetworkInformation::testReadInformation() { m_networkInformationReader.reset(new NetworkInformationReader("eth1", "proc_net_dev_files/example01.txt")); quint64 before = QDateTime::currentMSecsSinceEpoch(); NetworkInformationReader::NetworkBytesInOut information = m_networkInformationReader->readInformation(); QCOMPARE(information.in, quint64(11546469)); QCOMPARE(information.out, quint64(1058947)); QVERIFY(information.milliSecondsSinceEpoch >= before); QVERIFY(information.milliSecondsSinceEpoch <= QDateTime::currentMSecsSinceEpoch()); } void TestNetworkInformation::testListOfInterfaces() { m_networkInformationReader.reset(new NetworkInformationReader("eth1", "proc_net_dev_files/example01.txt")); QStringList actual = m_networkInformationReader->listOfInterfaces(); QStringList expected = QStringList() << "tun0" << "lo" << "wlan0" << "docker0" << "eth1"; expected.sort(); QCOMPARE(m_networkInformationReader->listOfInterfaces(), expected); } QTEST_MAIN(TestNetworkInformation) qnetload-1.3.6/src/tests/testnetworkinformationreader.h000066400000000000000000000020451451037126700234630ustar00rootroot00000000000000#include #include "../networkinformationreader.h" /* * Copyright 2017 Carles Pina i Estany * This file is part of qnetload. * * qnetload 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. * * qnetload 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 qnetload. If not, see . */ class TestNetworkInformation : public QObject { Q_OBJECT public: TestNetworkInformation(); private Q_SLOTS: void testListOfInterfaces(); void testReadInformation(); private: QScopedPointer m_networkInformationReader; }; qnetload-1.3.6/src/utils.cpp000066400000000000000000000002731451037126700157730ustar00rootroot00000000000000#include #include #include "utils.h" namespace Utils { quint64 currentMSecsSinceEpoch() { return static_cast(QDateTime::currentMSecsSinceEpoch()); } } qnetload-1.3.6/src/utils.h000066400000000000000000000001301451037126700154300ustar00rootroot00000000000000#pragma once #include namespace Utils { quint64 currentMSecsSinceEpoch(); };